منابع ترجمه · Think Python · فصل ۱
برنامهنویسی بهعنوان راهی برای اندیشیدن (فصل ۱ Think Python)
منبع اصلی: Think Python, Chapter 1: Programming as a way of thinking — Allen B. Downey
💡 این صفحه مثل یک نوتبوک Jupyter است: متغیر و تابعی که در یک سلول تعریف شود، در سلولهای بعدی همین صفحه در دسترس است. سلولها را به ترتیب اجرا کنید، یا با «⏮ تا اینجا» همهٔ سلولهای قبلیِ اجرانشده را یکجا اجرا کنید.
هدف اول این کتاب آموزش برنامهنویسی به زبان پایتون است. اما یادگرفتن برنامهنویسی یعنی یادگرفتن یک شیوهی تازهی فکر کردن؛ بنابراین هدف دوم کتاب این است که به شما کمک کند مثل یک دانشمند علوم کامپیوتر فکر کنید. این شیوهی تفکر، بعضی از بهترین ویژگیهای ریاضیات، مهندسی و علوم طبیعی را کنار هم میآورد. مثل ریاضیدانها، دانشمندان علوم کامپیوتر برای بیان ایدهها – بهطور مشخص، محاسبات – از زبانهای صوری (formal languages) استفاده میکنند. مثل مهندسها، چیزها را طراحی میکنند، اجزا را کنار هم میگذارند تا سیستم بسازند و مزایا و معایب گزینههای مختلف را میسنجند. مثل دانشمندان، رفتار سیستمهای پیچیده را مشاهده میکنند، فرضیه میسازند و پیشبینیها را آزمایش میکنند.
کار را با ابتداییترین عناصر برنامهنویسی شروع میکنیم و کمکم جلو میرویم. در این فصل میبینیم پایتون اعداد، حروف و کلمات را چگونه نمایش میدهد و یاد میگیرید چگونه عملیات حسابی انجام دهید.
همچنین یادگیری واژگان برنامهنویسی را شروع میکنید؛ اصطلاحاتی مثل عملگر (operator)، عبارت (expression)، مقدار (value) و نوع (type). این واژگان مهماند: برای فهمیدن بقیهی کتاب، برای گفتگو با برنامهنویسهای دیگر و برای استفاده از دستیارهای مجازی و فهمیدن حرفهایشان به آنها نیاز خواهید داشت.
۱.۱. عملگرهای حسابی
عملگر حسابی (arithmetic operator) نمادی است که یک محاسبهی حسابی را نشان میدهد. برای مثال، علامت جمع، +، عمل جمع را انجام میدهد.
30 + 12
42
علامت منها، -، عملگری است که تفریق را انجام میدهد.
43 - 1
42
ستاره، *، ضرب را انجام میدهد.
6 * 7
42
و اسلش، /، تقسیم را انجام میدهد:
84 / 2
42.0
دقت کنید که نتیجهی تقسیم 42.0 است، نه 42. دلیلش این است که در پایتون دو نوع عدد وجود دارد:
-
عدد صحیح (integer): اعدادی که بخش کسری یا اعشاری ندارند، و
-
عدد اعشاری (floating-point): اعداد صحیح و اعدادی که ممیز (نقطهی اعشار) دارند.
اگر دو عدد صحیح را جمع، تفریق یا ضرب کنید، نتیجه عدد صحیح است. اما اگر دو عدد صحیح را بر هم تقسیم کنید، نتیجه عدد اعشاری است. پایتون عملگر دیگری هم دارد، //، که تقسیم صحیح (integer division) را انجام میدهد. نتیجهی تقسیم صحیح همیشه یک عدد صحیح است.
84 // 2
42
تقسیم صحیح را «تقسیم کفی» (floor division) هم میگویند، چون همیشه به پایین (به سمت «کف») گرد میکند.
85 // 2
42
سرانجام، عملگر ** توانرسانی را انجام میدهد؛ یعنی یک عدد را به یک توان میرساند:
7 ** 2
49
در بعضی زبانهای دیگر برای توانرسانی از علامت ^ (کِرت) استفاده میشود، اما در پایتون این علامت یک عملگر بیتی به نام XOR است. اگر با عملگرهای بیتی آشنا نباشید، نتیجه ممکن است غیرمنتظره باشد:
7 ^ 2
5
در این کتاب به عملگرهای بیتی نمیپردازم، اما میتوانید دربارهی آنها در http://wiki.python.org/moin/BitwiseOperators بخوانید.
۱.۲. عبارتها
مجموعهای از عملگرها و اعداد را عبارت (expression) مینامند. یک عبارت میتواند هر تعداد عملگر و عدد داشته باشد. برای مثال، این یک عبارت با دو عملگر است.
6 + 6 ** 2
42
دقت کنید که توانرسانی قبل از جمع انجام میشود. پایتون از ترتیب انجام عملیات (order of operations) پیروی میکند که احتمالاً در درس ریاضی یاد گرفتهاید: توانرسانی قبل از ضرب و تقسیم انجام میشود و ضرب و تقسیم قبل از جمع و تفریق.
در مثال زیر، ضرب قبل از جمع انجام میشود.
12 + 5 * 6
42
اگر میخواهید جمع اول انجام شود، میتوانید از پرانتز استفاده کنید.
(12 + 5) * 6
102
هر عبارت یک مقدار (value) دارد. برای مثال، عبارت 6 * 7 مقدارش 42 است.
۱.۳. توابع حسابی
علاوه بر عملگرهای حسابی، پایتون چند تابع (function) هم دارد که روی اعداد کار میکنند. برای مثال، تابع round یک عدد اعشاری میگیرد و آن را به نزدیکترین عدد صحیح گرد میکند.
round(42.4)
42
round(42.6)
43
تابع abs قدر مطلق (absolute value) یک عدد را حساب میکند. برای عدد مثبت، قدر مطلق خود عدد است.
abs(42)
42
برای عدد منفی، قدر مطلق مثبت است.
abs(-42)
42
وقتی اینطور از یک تابع استفاده میکنیم، میگوییم تابع را فراخوانی (call) میکنیم. عبارتی که یک تابع را فراخوانی میکند، یک فراخوانی تابع (function call) است.
هنگام فراخوانی تابع، پرانتزها الزامیاند. اگر آنها را حذف کنید، پیام خطا میگیرید.
abs 42
Cell In[17], line 1
abs 42
^
SyntaxError: invalid syntax
میتوانید خط اول این پیام را نادیده بگیرید؛ اطلاعاتی ندارد که فعلاً برای فهمیدن آن نیاز داشته باشیم. خط دوم، کدی است که خطا دارد و زیرش یک علامت ^ گذاشته شده تا نشان دهد خطا کجا کشف شده است.
خط آخر نشان میدهد که این یک خطای نحوی (syntax error) است؛ یعنی ساختار عبارت ایراد دارد. در این مثال، مشکل این است که فراخوانی تابع به پرانتز نیاز دارد.
ببینیم اگر پرانتزها و مقدار را حذف کنیم چه میشود.
abs
<function abs(x, /)>
نام یک تابع، بهتنهایی، یک عبارت معتبر است و مقدار دارد. وقتی این مقدار نمایش داده میشود، نشان میدهد که abs یک تابع است و اطلاعات اضافهای هم دارد که بعداً توضیح میدهم.
۱.۴. رشتهها
علاوه بر اعداد، پایتون میتواند دنبالهای از حروف را هم نمایش دهد. به این دنبالهها رشته (string) میگویند، چون حروف مثل مهرههای یک گردنبند به هم «رشته» شدهاند. برای نوشتن یک رشته، دنبالهای از حروف را داخل نقلقولهای ساده (straight quotes) قرار میدهیم.
'Hello'
'Hello'
استفاده از نقلقول دوتایی هم مجاز است.
"world"
'world'
نقلقول دوتایی نوشتن رشتهای را که آپوستروف دارد آسان میکند؛ آپوستروف همان نماد نقلقول ساده است.
"it's a small "
"it's a small "
رشتهها میتوانند فاصله، علائم نگارشی و ارقام هم داشته باشند.
'Well, '
'Well, '
عملگر + روی رشتهها هم کار میکند؛ دو رشته را به هم میچسباند و یک رشتهی واحد میسازد. به این کار الحاق (concatenation) میگویند.
'Well, ' + "it's a small " + 'world.'
"Well, it's a small world."
عملگر * هم روی رشتهها کار میکند؛ چند نسخه از یک رشته میسازد و آنها را به هم الحاق میکند.
'Spam, ' * 4
'Spam, Spam, Spam, Spam, '
بقیهی عملگرهای حسابی روی رشتهها کار نمیکنند.
پایتون تابعی به نام len دارد که طول یک رشته را حساب میکند.
len('Spam')
4
دقت کنید که len حروف بین نقلقولها را میشمارد، نه خود نقلقولها را.
هنگام ساختن رشته حتماً از نقلقول ساده استفاده کنید. نقلقول برعکس (back quote)، که به آن بکتیک (backtick) هم میگویند، خطای نحوی ایجاد میکند.
`Hello`
Cell In[26], line 1
`Hello`
^
SyntaxError: invalid syntax
نقلقولهای هوشمند (smart quotes)، که نقلقولهای خمیده (curly quotes) هم نامیده میشوند، نیز مجاز نیستند.
۱.۵. مقدار و نوع
تا اینجا سه نوع مقدار دیدهایم:
-
2یک عدد صحیح است، -
42.0یک عدد اعشاری است، و -
'Hello'یک رشته است.
هر دسته از مقدارها را یک نوع (type) مینامند. هر مقدار یک نوع دارد؛ یا گاهی میگوییم مقدار «به یک نوع تعلق دارد».
پایتون تابعی به نام type دارد که نوع هر مقدار را به شما میگوید. نوع عدد صحیح int است.
type(2)
int
نوع عدد اعشاری float است.
type(42.0)
float
و نوع رشته str است.
type('Hello, World!')
str
نوعهای int، float و str را میتوان بهعنوان تابع هم به کار برد. برای مثال، int میتواند یک عدد اعشاری را بگیرد و به عدد صحیح تبدیل کند (همیشه به پایین گرد میکند).
int(42.9)
42
و float میتواند یک عدد صحیح را به مقدار اعشاری تبدیل کند.
float(42)
42.0
حالا به چیزی میرسیم که ممکن است گیجکننده باشد. اگر دنبالهای از ارقام را داخل نقلقول بگذارید، چه میشود؟
'126'
'126'
شبیه عدد است، اما در واقع یک رشته است.
type('126')
str
اگر سعی کنید مثل عدد از آن استفاده کنید، ممکن است خطا بگیرید.
'126' / 3
TypeError: unsupported operand type(s) for /: 'str' and 'int'
این مثال یک TypeError تولید میکند؛ یعنی مقدارهای موجود در عبارت، که عملوند (operand) نامیده میشوند، نوع نادرستی دارند. پیام خطا میگوید عملگر / از نوع این مقدارها، یعنی str و int، پشتیبانی نمیکند.
اگر رشتهای دارید که ارقام دارد، میتوانید با int آن را به عدد صحیح تبدیل کنید.
int('126') / 3
42.0
اگر رشتهای دارید که ارقام و ممیز (نقطهی اعشار) دارد، میتوانید با float آن را به عدد اعشاری تبدیل کنید.
float('12.6')
12.6
وقتی عدد صحیح بزرگی مینویسید، ممکن است وسوسه شوید بین گروههای رقمها ویرگول بگذارید، مثل 1,000,000. این در پایتون عبارتی معتبر است، اما نتیجهاش عدد صحیح نیست.
1,000,000
(1, 0, 0)
پایتون 1,000,000 را دنبالهای از اعداد صحیح جداشده با ویرگول تفسیر میکند. بعداً دربارهی این نوع دنباله بیشتر یاد میگیریم.
برای خواناتر شدن اعداد بزرگ میتوانید از زیرخط (underscore) استفاده کنید.
1_000_000
1000000
۱.۶. زبانهای صوری و طبیعی
زبانهای طبیعی (natural languages) زبانهایی هستند که مردم با آنها حرف میزنند، مثل انگلیسی، اسپانیایی و فرانسوی. این زبانها را کسی طراحی نکرده است؛ بهطور طبیعی تکامل یافتهاند.
زبانهای صوری (formal languages) زبانهایی هستند که انسانها برای کاربردهای مشخص طراحی کردهاند. برای مثال، نمادگذاریای که ریاضیدانها به کار میبرند یک زبان صوری است که در نشان دادن رابطهی میان اعداد و نمادها بسیار خوب عمل میکند. به همین ترتیب، زبانهای برنامهنویسی زبانهای صوریای هستند که برای بیان محاسبات طراحی شدهاند.
هرچند زبانهای صوری و طبیعی ویژگیهای مشترکی دارند، تفاوتهای مهمی هم میانشان هست:
-
ابهام: زبانهای طبیعی پر از ابهاماند و آدمها با کمک سرنخهای بافتی (contextual clues) و اطلاعات دیگر با آن کنار میآیند. زبانهای صوری طوری طراحی شدهاند که تقریباً یا کاملاً بدون ابهام باشند؛ یعنی هر برنامه دقیقاً یک معنی دارد، صرفنظر از بافت.
-
افزونگی (redundancy): برای جبران ابهام و کم کردن سوءتفاهم، زبانهای طبیعی از افزونگی استفاده میکنند و در نتیجه اغلب پرگو هستند. زبانهای صوری افزونگی کمتری دارند و فشردهترند.
-
تحتاللفظی بودن: زبانهای طبیعی پر از اصطلاح و استعارهاند. زبانهای صوری دقیقاً همان را میگویند که نوشته شده است.
چون همهی ما با زبانهای طبیعی بزرگ میشویم، گاهی عادت کردن به زبانهای صوری سخت است. زبانهای صوری از زبانهای طبیعی چگالترند، پس خواندنشان بیشتر طول میکشد. ساختار هم مهم است، بنابراین همیشه بهترین کار این نیست که از بالا به پایین و از چپ به راست بخوانید. و سرانجام، جزئیات اهمیت دارند. خطاهای کوچک در املا و نقطهگذاری، که در زبانهای طبیعی میتوان از کنارشان گذشت، در زبان صوری میتوانند تفاوت بزرگی ایجاد کنند.
۱.۷. اشکالزدایی
برنامهنویسها اشتباه میکنند. به دلایلی شوخطبعانه، خطاهای برنامهنویسی را باگ (bug) مینامند و فرایند ردیابی آنها را اشکالزدایی (debugging).
برنامهنویسی، و بهویژه اشکالزدایی، گاهی احساسات شدیدی را برمیانگیزد. اگر با یک باگ سخت دستوپنجه نرم میکنید، ممکن است احساس خشم، غم یا شرمندگی کنید.
آماده شدن برای این واکنشها ممکن است به کنار آمدن با آنها کمک کند. یک راه این است که کامپیوتر را مثل کارمندی تصور کنید که نقاط قوتی دارد، مثل سرعت و دقت، و نقاط ضعف مشخصی، مثل نداشتن همدلی و ناتوانی در درک تصویر کلی.
کار شما این است که مدیر خوبی باشید: راههایی پیدا کنید که از نقاط قوت استفاده کنید و نقاط ضعف را کماثر کنید. و راههایی پیدا کنید که از احساساتتان برای درگیر شدن با مسئله استفاده کنید، بدون اینکه اجازه دهید واکنشهایتان در توانایی شما برای کار مؤثر اختلال ایجاد کند.
یاد گرفتن اشکالزدایی میتواند ناامیدکننده باشد، اما مهارتی ارزشمند است که در بسیاری از فعالیتها، فراتر از برنامهنویسی، به کار میآید. در پایان هر فصل بخشی مثل همین هست که پیشنهادهای من برای اشکالزدایی را در بر دارد. امیدوارم کمکتان کند!
۱.۸. واژهنامه
عملگر حسابی (arithmetic operator): نمادی مثل + و * که یک عمل حسابی مثل جمع یا ضرب را نشان میدهد.
عدد صحیح (integer): نوعی که اعداد بدون بخش کسری یا اعشاری را نمایش میدهد.
عدد اعشاری (floating-point): نوعی که اعداد صحیح و اعداد دارای بخش اعشاری را نمایش میدهد.
تقسیم صحیح (integer division): عملگری، //، که دو عدد را بر هم تقسیم میکند و به پایین، تا یک عدد صحیح، گرد میکند.
عبارت (expression): ترکیبی از متغیرها، مقدارها و عملگرها.
مقدار (value): یک عدد صحیح، یک عدد اعشاری یا یک رشته – یا یکی از انواع دیگر مقدارها که بعداً خواهیم دید.
تابع (function): دنبالهای نامدار از دستورها که عملی مفید انجام میدهد. توابع ممکن است آرگومان بگیرند یا نگیرند و ممکن است نتیجه تولید کنند یا نکنند.
فراخوانی تابع (function call): عبارتی – یا بخشی از یک عبارت – که یک تابع را اجرا میکند. از نام تابع و به دنبال آن فهرست آرگومانها داخل پرانتز تشکیل میشود.
خطای نحوی (syntax error): خطایی در برنامه که باعث میشود تجزیه (parse) آن ناممکن باشد – و در نتیجه اجرای آن هم ناممکن است.
رشته (string): نوعی که دنبالهای از نویسهها (characters) را نمایش میدهد.
الحاق (concatenation): چسباندن دو رشته بهدنبال هم.
نوع (type): یک دسته از مقدارها. نوعهایی که تا اینجا دیدهایم عبارتاند از اعداد صحیح (نوع int)، اعداد اعشاری (نوع float) و رشتهها (نوع str).
عملوند (operand): یکی از مقدارهایی که یک عملگر روی آنها عمل میکند.
زبان طبیعی (natural language): هر یک از زبانهایی که مردم با آنها صحبت میکنند و بهطور طبیعی تکامل یافتهاند.
زبان صوری (formal language): هر یک از زبانهایی که انسانها برای مقاصد مشخصی طراحی کردهاند، مثل نمایش ایدههای ریاضی یا برنامههای کامپیوتری. همهی زبانهای برنامهنویسی زبان صوریاند.
باگ (bug): خطا در یک برنامه.
اشکالزدایی (debugging): فرایند پیدا کردن و رفع خطاها.
۱.۹. تمرینها
این سلول به Jupyter میگوید هنگام بروز خطای زمان اجرا (runtime error) اطلاعات اشکالزدایی مفصل نمایش دهد. پیش از شروع تمرینها آن را اجرا کنید.
%xmode Verbose
Exception reporting mode: Verbose
۱.۹.۱. از یک دستیار مجازی بپرسید
در طول این کتاب چند راه برای استفاده از دستیار مجازی یا چتبات برای یادگیری وجود دارد.
-
اگر میخواهید دربارهی موضوعی از فصل بیشتر بدانید، یا چیزی روشن نیست، میتوانید از او توضیح بخواهید.
-
اگر در حل یکی از تمرینها مشکل دارید، میتوانید از او کمک بخواهید.
در هر فصل تمرینهایی پیشنهاد میکنم که میتوانید با دستیار مجازی انجام دهید، اما تشویقتان میکنم اول خودتان چیزها را امتحان کنید و ببینید چه چیزی برایتان جواب میدهد.
چند موضوع که میتوانید از دستیار مجازی دربارهشان بپرسید:
-
پیشتر از عملگرهای بیتی گفتم، اما توضیح ندادم چرا مقدار
7 ^ 2برابر ۵ است. بپرسید «عملگرهای بیتی در پایتون چه هستند؟» (What are the bitwise operators in Python?) یا «مقدار7 XOR 2چیست؟» (What is the value of7 XOR 2?) -
از ترتیب انجام عملیات هم حرف زدم. برای جزئیات بیشتر بپرسید «ترتیب انجام عملیات در پایتون چیست؟» (What is the order of operations in Python?)
-
تابع
round، که برای گرد کردن عدد اعشاری به نزدیکترین عدد صحیح به کار بردیم، میتواند آرگومان دوم هم بگیرد. بپرسید «آرگومانهای تابع round چیست؟» (What are the arguments of the round function?) یا «چطور عدد پی را تا سه رقم اعشار گرد کنم؟» (How do I round pi off to three decimal places?) -
یک عملگر حسابی دیگر هم هست که اسمش را نبردم؛ بپرسید «عملگر مدول (modulus) در پایتون چیست؟» (What is the modulus operator in Python?)
بیشتر دستیارهای مجازی پایتون را میشناسند و به چنین پرسشهایی کموبیش قابلاعتماد پاسخ میدهند. اما یادتان باشد که این ابزارها اشتباه میکنند. اگر از چتبات کدی گرفتید، آن را آزمایش کنید!
۱.۹.۲. تمرین
شاید بپرسید اگر عددی به 0.5 ختم شود، round چه میکند. پاسخ این است که گاهی به بالا گرد میکند و گاهی به پایین. این مثالها را امتحان کنید و ببینید میتوانید بفهمید از چه قاعدهای پیروی میکند.
round(42.5)
42
round(43.5)
44
اگر کنجکاوید، از یک دستیار مجازی بپرسید: «اگر عددی به 0.5 ختم شود، پایتون به بالا گرد میکند یا به پایین؟» (If a number ends in 0.5, does Python round up or down?)
۱.۹.۳. تمرین
وقتی با یک قابلیت تازه آشنا میشوید، باید آن را امتحان کنید و عمداً اشتباه کنید. اینطوری پیامهای خطا را یاد میگیرید و وقتی دوباره آنها را ببینید میدانید چه معنایی دارند. بهتر است حالا و عمداً اشتباه کنید تا بعداً و ناخواسته.
-
میتوانید با علامت منفی عدد منفی بسازید، مثل
-2. اگر قبل از یک عدد علامت مثبت بگذارید چه میشود؟2++2چطور؟ -
اگر دو مقدار بدون هیچ عملگری بینشان باشند، مثل
4 2، چه میشود؟ -
اگر تابعی مثل
round(42.5)را فراخوانی کنید، و یکی از پرانتزها یا هر دو را جا بیندازید، چه میشود؟
۱.۹.۴. تمرین
یادتان باشد که هر عبارت یک مقدار دارد، هر مقدار یک نوع دارد، و میتوانیم با تابع type نوع هر مقدار را پیدا کنیم.
نوع مقدار عبارتهای زیر چیست؟ برای هر کدام بهترین حدستان را بزنید و سپس با type بررسی کنید.
-
765 -
2.718 -
'2 pi' -
abs(-7) -
abs(-7.0) -
abs -
int -
type
۱.۹.۵. تمرین
پرسشهای زیر فرصتی برای تمرین نوشتن عبارتهای حسابیاند.
-
در ۴۲ دقیقه و ۴۲ ثانیه چند ثانیه وجود دارد؟
-
۱۰ کیلومتر چند مایل است؟ راهنمایی: هر مایل ۱.۶۱ کیلومتر است.
-
اگر مسابقهی ۱۰ کیلومتری را در ۴۲ دقیقه و ۴۲ ثانیه بدوید، میانگین سرعت دویدنتان (pace) چند ثانیه بر مایل است؟
-
میانگین pace شما چند دقیقه و چند ثانیه بر مایل است؟
-
میانگین سرعتتان چند مایل بر ساعت است؟
اگر از قبل با متغیرها آشنایید، میتوانید در این تمرین از آنها استفاده کنید. اگر آشنا نیستید، میتوانید بدون آنها هم تمرین را انجام دهید – و در فصل بعد با آنها آشنا میشویم.