منابع ترجمه · Think Python · فصل ۲

متغیرها و دستورها (فصل ۲ Think Python)

۱۴ دقیقه مطالعه · به‌روزرسانی ۲ آبان ۱۴۰۵

منبع اصلی: Think Python, Chapter 2: Variables and Statements — Allen B. Downey

💡 این صفحه مثل یک نوت‌بوک Jupyter است: متغیر و تابعی که در یک سلول تعریف شود، در سلول‌های بعدی همین صفحه در دسترس است. سلول‌ها را به ترتیب اجرا کنید، یا با «⏮ تا اینجا» همهٔ سلول‌های قبلیِ اجرانشده را یک‌جا اجرا کنید.

خروجی‌های نمایش‌داده‌شده‌ی زیر کدها را من با اجرای کدها به دست آورده‌ام.

در فصل قبل از عملگرها برای نوشتن عبارت‌هایی استفاده کردیم که محاسبات حسابی انجام می‌دهند.

در این فصل با متغیرها و دستورها، دستور import و تابع print آشنا می‌شوید. و واژگان بیشتری را که برای صحبت درباره‌ی برنامه‌ها به کار می‌بریم معرفی می‌کنم، از جمله «آرگومان» (argument) و «ماژول» (module).

۲.۱. متغیرها

متغیر (variable) نامی است که به یک مقدار اشاره می‌کند. برای ساختن یک متغیر می‌توانیم یک دستور انتساب (assignment statement) بنویسیم، مثل این:

n = 17

یک دستور انتساب سه بخش دارد: نام متغیر در سمت چپ، عملگر مساوی، =، و یک عبارت در سمت راست. در این مثال، عبارت یک عدد صحیح است. در مثال بعدی، عبارت یک عدد اعشاری است.

pi = 3.141592653589793

و در مثال بعدی، عبارت یک رشته است.

message = 'And now for something completely different'

وقتی یک دستور انتساب را اجرا می‌کنید، خروجی‌ای نمایش داده نمی‌شود. پایتون متغیر را می‌سازد و به آن مقدار می‌دهد، اما دستور انتساب اثر قابل‌مشاهده‌ای ندارد. با این حال، بعد از ساختن یک متغیر می‌توانید از آن به‌عنوان یک عبارت استفاده کنید. پس می‌توانیم مقدار message را این‌طور نمایش دهیم:

message
'And now for something completely different'

همچنین می‌توانید از یک متغیر به‌عنوان بخشی از یک عبارت با عملگرهای حسابی استفاده کنید.

n + 25
42
2 * pi
6.283185307179586

و می‌توانید هنگام فراخوانی یک تابع هم از متغیر استفاده کنید.

round(pi)
3
len(message)
42

۲.۲. نمودارهای حالت

یک راه رایج برای نمایش متغیرها روی کاغذ این است که نام متغیر را بنویسیم و یک فلش از آن به مقدارش بکشیم.

(در کتاب اصلی این‌جا شکلی رسم شده است: سه متغیر n با مقدار ۱۷، pi با مقدار ۳.۱۴۱۵۹… و message با مقدار رشته‌ی بالا، که هرکدام با یک فلش به مقدارشان وصل شده‌اند.)

به این نوع شکل نمودار حالت (state diagram) می‌گویند، چون نشان می‌دهد هر متغیر در چه «حالتی» است (آن را «حالت ذهنی» متغیر در نظر بگیرید). در سراسر کتاب از نمودارهای حالت استفاده می‌کنیم تا مدلی از چگونگی ذخیره شدن متغیرها و مقدارهایشان در پایتون را نشان دهیم.

۲.۳. نام متغیرها

نام متغیرها می‌تواند هر قدر که دوست دارید بلند باشد. می‌توانند هم حرف داشته باشند و هم عدد، اما نمی‌توانند با عدد شروع شوند. استفاده از حروف بزرگ مجاز است، اما قرارداد این است که برای نام متغیرها فقط از حروف کوچک استفاده شود.

تنها علامت نگارشی‌ای که در نام متغیر می‌تواند بیاید زیرخط (underscore)، _، است. این علامت اغلب در نام‌هایی که چند کلمه دارند به کار می‌رود، مثل your_name یا airspeed_of_unladen_swallow.

اگر به یک متغیر نام غیرمجاز بدهید، خطای نحوی می‌گیرید. نام million! غیرمجاز است چون علامت نگارشی دارد.

million! = 1000000
SyntaxError: invalid syntax

76trombones غیرمجاز است چون با عدد شروع می‌شود.

76trombones = 'big parade'
SyntaxError: invalid decimal literal

class هم غیرمجاز است، اما شاید دلیلش بدیهی نباشد.

class = 'Self-Defence Against Fresh Fruit'
SyntaxError: invalid syntax

معلوم می‌شود که class یک کلمه‌ی کلیدی (keyword) است؛ یعنی کلمه‌ای خاص که برای مشخص کردن ساختار برنامه به کار می‌رود. کلمه‌های کلیدی را نمی‌توان به‌عنوان نام متغیر به کار برد.

فهرست کامل کلمه‌های کلیدی پایتون این است:

False      await      else       import     pass
None       break      except     in         raise
True       class      finally    is         return
and        continue   for        lambda     try
as         def        from       nonlocal   while
assert     del        global     not        with
async      elif       if         or         yield
from keyword import kwlist

len(kwlist)
35

لازم نیست این فهرست را حفظ کنید. در بیشتر محیط‌های توسعه، کلمه‌های کلیدی با رنگ متفاوتی نمایش داده می‌شوند؛ اگر سعی کنید از یکی‌شان به‌عنوان نام متغیر استفاده کنید، متوجه می‌شوید.

۲.۴. دستور import

برای استفاده از بعضی قابلیت‌های پایتون باید آن‌ها را وارد (import) کنید. برای مثال، دستور زیر ماژول math را وارد می‌کند.

import math

ماژول (module) مجموعه‌ای از متغیرها و توابع است. ماژول math متغیری به نام pi دارد که مقدار ثابت ریاضی π را در خود دارد. می‌توانیم مقدارش را این‌طور نمایش دهیم.

math.pi
3.141592653589793

برای استفاده از یک متغیر در یک ماژول، باید بین نام ماژول و نام متغیر از عملگر نقطه (dot operator)، .، استفاده کنید.

ماژول math توابعی هم دارد. برای مثال، sqrt ریشه‌ی دوم را حساب می‌کند.

math.sqrt(25)
5.0

و pow عدد اول را به توان عدد دوم می‌رساند.

math.pow(5, 2)
25.0

تا اینجا دو راه برای به توان رساندن یک عدد دیده‌ایم: می‌توانیم از تابع math.pow یا از عملگر توان‌رسانی، **، استفاده کنیم. هر دو خوب‌اند، اما عملگر بیشتر به کار می‌رود.

۲.۵. عبارت‌ها و دستورها

تا اینجا چند نوع عبارت دیده‌ایم. یک عبارت می‌تواند یک مقدار تنها باشد، مثل یک عدد صحیح، عدد اعشاری یا رشته. می‌تواند مجموعه‌ای از مقدارها و عملگرها هم باشد. و می‌تواند نام متغیرها و فراخوانی توابع را هم شامل شود. این یک عبارت است که چند تا از این عناصر را دارد.

19 + n + round(math.pi) * 2
42

چند نوع دستور هم دیده‌ایم. دستور (statement) واحدی از کد است که اثر دارد، اما مقدار ندارد. برای مثال، یک دستور انتساب متغیری می‌سازد و به آن مقدار می‌دهد، اما خود دستور مقداری ندارد.

n = 17

به همین ترتیب، یک دستور import هم اثر دارد – ماژولی را وارد می‌کند تا بتوانیم از متغیرها و توابعش استفاده کنیم – اما اثر قابل‌مشاهده‌ای ندارد.

import math

محاسبه‌ی مقدار یک عبارت را ارزیابی (evaluation) می‌نامند. اجرای یک دستور را اجرا (execution) می‌نامند.

۲.۶. تابع print

وقتی یک عبارت را ارزیابی می‌کنید، نتیجه نمایش داده می‌شود.

n + 1
18

اما اگر بیش از یک عبارت را ارزیابی کنید، فقط مقدار آخری نمایش داده می‌شود.

n + 2
n + 3
20

برای نمایش بیش از یک مقدار می‌توانید از تابع print استفاده کنید.

print(n+2)
print(n+3)
19
20

با اعداد اعشاری و رشته‌ها هم کار می‌کند.

print('The value of pi is approximately')
print(math.pi)
The value of pi is approximately
3.141592653589793

همچنین می‌توانید دنباله‌ای از عبارت‌ها را که با ویرگول از هم جدا شده‌اند به آن بدهید.

print('The value of pi is approximately', math.pi)
The value of pi is approximately 3.141592653589793

دقت کنید که تابع print بین مقدارها یک فاصله می‌گذارد.

۲.۷. آرگومان‌ها

وقتی یک تابع را فراخوانی می‌کنید، عبارتی که داخل پرانتز است آرگومان (argument) نامیده می‌شود. معمولاً دلیل این نام‌گذاری را توضیح می‌دادم، اما در این مورد معنای فنی این واژه تقریباً هیچ ربطی به معنای رایج کلمه ندارد، پس حتی تلاشی هم نمی‌کنم.

بعضی از توابعی که تا اینجا دیده‌ایم فقط یک آرگومان می‌گیرند، مثل int.

int('101')
101

بعضی دو آرگومان می‌گیرند، مثل math.pow.

math.pow(5, 2)
25.0

بعضی می‌توانند آرگومان‌های اضافی اختیاری هم بگیرند. برای مثال، int می‌تواند آرگومان دومی بگیرد که مبنای عدد را مشخص می‌کند.

int('101', 2)
5

دنباله‌ی رقم‌های 101 در مبنای ۲ عدد ۵ را در مبنای ۱۰ نشان می‌دهد.

round هم یک آرگومان دوم اختیاری می‌گیرد که تعداد رقم‌های اعشاری برای گرد کردن را مشخص می‌کند.

round(math.pi, 3)
3.142

بعضی توابع می‌توانند هر تعداد آرگومان بگیرند، مثل print.

print('Any', 'number', 'of', 'arguments')
Any number of arguments

اگر تابعی را فراخوانی کنید و آرگومان‌های بیش از حد بدهید، TypeError می‌گیرید.

float('123.0', 2)
TypeError: float expected at most 1 argument, got 2

اگر آرگومان‌های کم‌تر از حد لازم بدهید هم TypeError می‌گیرید.

math.pow(2)
TypeError: pow expected 2 arguments, got 1

و اگر آرگومانی بدهید که نوعش را تابع نمی‌تواند مدیریت کند، آن هم TypeError است.

math.sqrt('123')
TypeError: must be real number, not str

این نوع بررسی ممکن است در ابتدای کار آزاردهنده باشد، اما به شما کمک می‌کند خطاها را پیدا و اصلاح کنید.

۲.۸. توضیحات (کامنت‌ها)

هرچه برنامه‌ها بزرگ‌تر و پیچیده‌تر شوند، خواندنشان دشوارتر می‌شود. زبان‌های صوری چگال‌اند و اغلب سخت است به یک تکه کد نگاه کنیم و بفهمیم چه می‌کند و چرا.

به همین دلیل، ایده‌ی خوبی است که به برنامه‌هایتان یادداشت‌هایی اضافه کنید تا با زبان طبیعی توضیح بدهند برنامه چه می‌کند. به این یادداشت‌ها توضیح یا کامنت (comment) می‌گویند و با نماد # شروع می‌شوند.

# number of seconds in 42:42
seconds = 42 * 60 + 42

در این مورد، کامنت در یک خط جدا آمده است. می‌توانید کامنت را در انتهای یک خط هم بگذارید:

miles = 10 / 1.61     # 10 kilometers in miles

هر چیزی از # تا انتهای خط نادیده گرفته می‌شود – هیچ اثری روی اجرای برنامه ندارد.

کامنت‌ها وقتی بیشترین فایده را دارند که ویژگی‌های غیرواضح کد را مستند کنند. منطقی است فرض کنیم خواننده می‌تواند بفهمد کد چه می‌کند؛ مفیدتر این است که توضیح بدهیم چرا.

این کامنت با خود کد افزونه است و بی‌فایده:

v = 8     # assign 8 to v

این کامنت اطلاعات مفیدی دارد که در کد نیست:

v = 8     # velocity in miles per hour 

نام‌های خوب برای متغیرها می‌توانند نیاز به کامنت را کم کنند، اما نام‌های بلند می‌توانند خواندن عبارت‌های پیچیده را سخت کنند، پس این یک بده‌بستان است.

۲.۹. اشکال‌زدایی

در یک برنامه سه نوع خطا ممکن است رخ دهد: خطای نحوی، خطای زمان اجرا و خطای معنایی. تشخیص فرق آن‌ها مفید است تا سریع‌تر ردیابی‌شان کنید.

  • خطای نحوی (syntax error): «نحو» به ساختار برنامه و قواعد مربوط به آن ساختار اشاره دارد. اگر در هر جای برنامه‌ی شما خطای نحوی باشد، پایتون برنامه را اجرا نمی‌کند. بلافاصله پیام خطا نمایش می‌دهد.

  • خطای زمان اجرا (runtime error): اگر برنامه‌ی شما خطای نحوی نداشته باشد، می‌تواند شروع به اجرا کند. اما اگر چیزی اشتباه پیش برود، پایتون پیام خطا نمایش می‌دهد و متوقف می‌شود. به این نوع خطا خطای زمان اجرا می‌گویند. به آن استثنا (exception) هم می‌گویند، چون نشان می‌دهد اتفاقی استثنایی رخ داده است.

  • خطای معنایی (semantic error): نوع سوم خطا «معنایی» است؛ یعنی مربوط به معنا. اگر برنامه‌ی شما خطای معنایی داشته باشد، بدون تولید هیچ پیام خطایی اجرا می‌شود، اما کاری را که قصدتان بود انجام نمی‌دهد. شناسایی خطاهای معنایی می‌تواند حیله‌گرانه باشد، چون لازم است به‌صورت معکوس کار کنید: به خروجی برنامه نگاه کنید و سعی کنید بفهمید برنامه چه می‌کند.

همان‌طور که دیدیم، نام غیرمجاز برای متغیر یک خطای نحوی است.

million! = 1000000
SyntaxError: invalid syntax

اگر از یک عملگر با نوعی که پشتیبانی نمی‌کند استفاده کنید، آن یک خطای زمان اجراست.

'126' / 3
TypeError: unsupported operand type(s) for /: 'str' and 'int'

و سرانجام، این هم مثالی از خطای معنایی. فرض کنید می‌خواهیم میانگین 1 و 3 را حساب کنیم، اما ترتیب انجام عملیات را فراموش می‌کنیم و این را می‌نویسیم:

1 + 3 / 2
2.5

وقتی این عبارت ارزیابی می‌شود، پیام خطایی تولید نمی‌کند، پس نه خطای نحوی داریم و نه خطای زمان اجرا. اما نتیجه میانگین 1 و 3 نیست، پس برنامه درست نیست. این یک خطای معنایی است، چون برنامه اجرا می‌شود اما کاری را که قصد شده انجام نمی‌دهد.

۲.۱۰. واژه‌نامه

متغیر (variable): نامی که به یک مقدار اشاره می‌کند.

دستور انتساب (assignment statement): دستوری که یک مقدار را به یک متغیر نسبت می‌دهد.

نمودار حالت (state diagram): نمایشی گرافیکی از مجموعه‌ای از متغیرها و مقدارهایی که به آن‌ها اشاره می‌کنند.

کلمه‌ی کلیدی (keyword): کلمه‌ای خاص که برای مشخص کردن ساختار برنامه به کار می‌رود.

دستور import (import statement): دستوری که فایل یک ماژول را می‌خواند تا بتوانیم از متغیرها و توابعی که دارد استفاده کنیم.

ماژول (module): فایلی که کد پایتون دارد، از جمله تعریف توابع و گاهی دستورهای دیگر.

عملگر نقطه (dot operator): عملگر . که برای دسترسی به یک تابع در ماژولی دیگر به کار می‌رود؛ با نوشتن نام ماژول، سپس یک نقطه و بعد نام تابع.

ارزیابی کردن (evaluate): انجام عملیات یک عبارت برای محاسبه‌ی یک مقدار.

دستور (statement): یک یا چند خط کد که یک فرمان یا عمل را نشان می‌دهند.

اجرا کردن (execute): اجرای یک دستور و انجام آنچه می‌گوید.

آرگومان (argument): مقداری که هنگام فراخوانی یک تابع به آن داده می‌شود.

توضیح یا کامنت (comment): متنی که در برنامه می‌آید و درباره‌ی برنامه اطلاعات می‌دهد اما روی اجرای آن اثری ندارد.

خطای زمان اجرا (runtime error): خطایی که باعث می‌شود برنامه پیام خطا نمایش دهد و خارج شود.

استثنا (exception): خطایی که هنگام اجرای برنامه شناسایی می‌شود.

خطای معنایی (semantic error): خطایی که باعث می‌شود برنامه کار اشتباهی انجام دهد، اما پیام خطایی نمایش ندهد.

۲.۱۱. تمرین‌ها

این سلول به Jupyter می‌گوید هنگام بروز خطای زمان اجرا اطلاعات اشکال‌زدایی مفصل نمایش دهد. پیش از شروع تمرین‌ها آن را اجرا کنید.

%xmode Verbose

۲.۱۱.۱. از یک دستیار مجازی بپرسید

دوباره تشویقتان می‌کنم از یک دستیار مجازی برای یادگیری بیشتر درباره‌ی هر یک از موضوعات این فصل استفاده کنید.

اگر درباره‌ی هر یک از کلمه‌های کلیدی‌ای که فهرست کردم کنجکاوید، می‌توانید بپرسید «چرا class یک کلمه‌ی کلیدی است؟» (Why is class a keyword?) یا «چرا نام متغیرها نمی‌توانند کلمه‌ی کلیدی باشند؟» (Why can’t variable names be keywords?)

شاید متوجه شده باشید که int، float و str کلمه‌های کلیدی پایتون نیستند. آن‌ها متغیرهایی هستند که نوع‌ها را نشان می‌دهند و می‌توان از آن‌ها به‌عنوان تابع استفاده کرد. پس داشتن متغیر یا تابعی با یکی از این نام‌ها مجاز است، اما به‌شدت توصیه نمی‌شود. از یک دستیار بپرسید «چرا استفاده از int، float و str به‌عنوان نام متغیر بد است؟» (Why is it bad to use int, float, and str as variable names?)

همچنین بپرسید «توابع داخلی (built-in) پایتون کدام‌اند؟» (What are the built-in functions in Python?) اگر درباره‌ی هر یک از آن‌ها کنجکاو شدید، اطلاعات بیشتری بخواهید.

در این فصل ماژول math را وارد کردیم و از بعضی متغیرها و توابعی که فراهم می‌کند استفاده کردیم. از یک دستیار بپرسید «چه متغیرها و توابعی در ماژول math هستند؟» (What variables and functions are in the math module?) و «غیر از math، چه ماژول‌های دیگری جزو هسته‌ی پایتون به حساب می‌آیند؟» (Other than math, what modules are considered core Python?)

۲.۱۱.۲. تمرین

توصیه‌ی فصل قبل را تکرار می‌کنم: هر وقت با یک قابلیت تازه آشنا می‌شوید، باید عمداً اشتباه کنید تا ببینید چه اتفاقی می‌افتد.

  • دیدیم که n = 17 مجاز است. 17 = n چطور؟

  • x = y = 1 چطور؟

  • در بعضی زبان‌ها هر دستور با سمی‌کالن (;) تمام می‌شود. اگر در انتهای یک دستور پایتون سمی‌کالن بگذارید چه می‌شود؟

  • اگر در انتهای یک دستور نقطه بگذارید چه می‌شود؟

  • اگر اسم یک ماژول را اشتباه بنویسید و سعی کنید maath را import کنید چه اتفاقی می‌افتد؟

۲.۱۱.۳. تمرین

از مفسر (interpreter) پایتون به‌عنوان ماشین‌حساب استفاده کنید:

بخش ۱. حجم کره‌ای به شعاع $r$ برابر است با $\frac{4}{3} \pi r^3$. حجم کره‌ای به شعاع ۵ چقدر است؟ با یک متغیر به نام radius شروع کنید و سپس نتیجه را به متغیری به نام volume نسبت دهید. نتیجه را نمایش دهید. کامنت‌هایی اضافه کنید که نشان دهند radius بر حسب سانتی‌متر و volume بر حسب سانتی‌متر مکعب است.

# Solution goes here

بخش ۲. یک قاعده‌ی مثلثات می‌گوید برای هر مقدار $x$ داریم $(\cos x)^2 + (\sin x)^2 = 1$. ببینیم برای یک مقدار مشخص مثل ۴۲ درست است یا نه.

متغیری به نام x با این مقدار بسازید. سپس با math.cos و math.sin سینوس و کسینوس $x$ را حساب کنید و مجموع مربعاتشان را به دست آورید.

نتیجه باید نزدیک به ۱ باشد. ممکن است دقیقاً ۱ نباشد، چون حساب اعداد اعشاری دقیق نیست – فقط تقریباً درست است.

# Solution goes here

بخش ۳. علاوه بر pi، متغیر دیگری که در ماژول math تعریف شده e است که پایه‌ی لگاریتم طبیعی را نشان می‌دهد و در نمادگذاری ریاضی با $e$ نوشته می‌شود. اگر با این مقدار آشنا نیستید، از یک دستیار مجازی بپرسید «math.e چیست؟» (What is math.e?) حالا $e^2$ را به سه روش حساب کنیم:

  • از math.e و عملگر توان‌رسانی (**) استفاده کنید.

  • از math.pow برای به توان ۲ رساندن math.e استفاده کنید.

  • از math.exp استفاده کنید که یک مقدار، $x$، را به‌عنوان آرگومان می‌گیرد و $e^x$ را حساب می‌کند.

ممکن است متوجه شوید نتیجه‌ی آخری کمی با دو تای دیگر فرق دارد. ببینید می‌توانید بفهمید کدام درست است.

# Solution goes here
# Solution goes here
# Solution goes here