آموزش پایتون به زبان ساده قسمت دوم

آموزش کار با زبان برنامه‌نویسی پایتون (بخش دوم)

آموزش پایتون به زبان ساده

در قسمت قبلی این مجموعه به طور خلاصه به معرفی زبان برنامه‌نویسی پایتون پرداختیم. در این قسمت با مفاهیم جدیدی آشنا خواهیم شد و برنامه به نسبت کاملی را پیاده‌سازی خواهیم کرد. این برنامه یک بازی بسیار ساده Tic-Tac-Toe را شبیه‌سازی می‌کند. اگرچه این بازی منطق پیچیده و خاصی ندارد، اما سیستم تفکیک کد، فراخوانی توابع، وارد کردن ماجول‌ها و… را به شما خواهد آموخت.

در قسمت قبلی این مجموعه به طور خلاصه به معرفی زبان برنامه‌نویسی پایتون پرداختیم. در این قسمت با مفاهیم جدیدی آشنا خواهیم شد و برنامه به نسبت کاملی را پیاده‌سازی خواهیم کرد. این برنامه یک بازی بسیار ساده Tic-Tac-Toe را شبیه‌سازی می‌کند. اگرچه این بازی منطق پیچیده و خاصی ندارد، اما سیستم تفکیک کد، فراخوانی توابع، وارد کردن ماجول‌ها و… را به شما خواهد آموخت.
این بازی از یک صفحه شطرنجی ۳ × ۳ تشکیل شده که بازیکنان به نوبت با حروف X یا O یکی از خانه‌های آن را اشغال می‌کنند. هدف هر بازیکن قرار دادن سه علامت در کنار هم به صورت سطری، ستونی یا قطری است. در بازی شبیه‌سازی شده ما بازیکن با حرف X در برابر کامپیوتر با حرف O بازی خواهد کرد.

تقسیم و غلبه (Divide & Conquer)
یکی از روش‌های بسیار پرکاربرد در حل مسئله و طراحی الگوریتم، روش تقسیم و غلبه است. در این روش هر مسئله به مسائلی ریزتر تقسیم می‌شود و این روند آن‌قدر ادامه می‌یابد تا به مسائلی بسیار ساده با راه‌حل آسان برسیم. حل هر مسئله ریز، به صورت جداگانه پیاده‌سازی شده و سپس از جمع آن‌ها راه‌حل نهایی به دست می‌آید. در برنامه‌نویسی پایتون این تقسیم‌بندی‌ها در مرحله نخست شامل تفکیک کل برنامه به تعدادی ماجول و سپس تفکیک ماجول‌ها به تعدادی شیء (Object) یا تابع (Function) است. ما مسئله بازی Tic-Tac-Toe را به صورتی مانند شکل۱ تفکیک می‌کنیم. 
ابتدا کل مسئله به سه بخش اساسی تقسیم می‌شود که عبارتند از: حلقه اصلی روند اجرای بازی، بخشی جهت تعامل با بازیکن (کاربر) و در نهایت بخشی برای کنترل و مدیریت صفحه بازی. هر یک از این بخش‌ها در فایل جداگانه‌ای به نام ماجول نوشته می‌شوند و وظایف مربوط به خود را از طریق تعدادی تابع به انجام می‌رسانند. فعلاً نگران این اصطلاحات نباشید. در پایتون همه چیز ساده‌تر از آن است که به نظر می‌رسد.
آموزش پایتون به زبان ساده
شکل۱- تفکیک بازی به قسمت‌های مختلف
ماژول مربوط به بازیکن
کد فهرست ۱ را در IDLE یا هر ویرایشگر متن دلخواهی نوشته و آن را با نام player.py ذخیره کنید. شماره‌های خطوط را وارد نکنید. ما از آن‌ها برای توضیحات بعدی استفاده کرده‌ایم.
خط ۱، یک توضیح یا Comment است. علامت # در هر کجای خط قرار بگیرد، پایتون عبارات بعد از آن را نادیده می‌گیرد. از توضیحات به طور معمول برای تقسیم‌کردن کد به بخش‌های قابل فهم برای انسان و شرح روند اجرای برنامه استفاده می‌شود تا مطالعه کد و ویرایش‌های بعدی آن ساده‌تر شود.
خط ۲ یک تابع را تعریف می‌کند. تابع یا function یکی از عناصر اساسی هر زبان برنامه‌نویسی است. حتی در زبان‌های برنامه‌نویسی شیء‌گرای کنونی نیز توابع یا روال‌ها (subroutine) وظیفه اصلی تقسیم‌بندی و تفکیک کد را انجام می‌دهند. تابع قسمتی از کد است که با گرفتن ورودی‌های مشخص، خروجی مشخصی را تولید می‌کند یا کاری را به انجام می‌رساند. تابع به خودی خود اجرا نمی‌شود. برای استفاده از یک تابع باید آن را صدا زد یا به اصطلاح فراخواند. در پایتون تعریف تابع (که دارای مقدار برگشتی است) با تعریف روال (که فاقد مقدار برگشتی است) تفاوتی ندارد. به‌طور کلی تعریف تابع در پایتون به شکل زیر انجام می‌شود:
def  <function_name> ( [list of arguments] ):
function body
return [List of values to return]
به تورفتگی بدنه تابع، اختیاری بودن آرگومان‌های ورودی و مقادیر خروجی توجه کنید. توجه داشته باشید که نام توابع و متغیرها نباید از بین کلمات کلیدی پایتون (فهرست ۲) انتخاب شود. همچنین استفاده از علامت‌های _ و __  (زیر خط تکی و زیرخط دوتایی) در ابتدای نام تابع یا متغیر، ویژگی‌های خاصی را به آن‌ها نسبت خواهد داد که بررسی آن در این مقاله نمی‌گنجد. 
همان‌گونه که از پرانتز خالی جلوی نام تابع Get_Player_Name مشخص است، این تابع آرگومان ورودی ندارد. ما از این تابع برای دریافت نام بازیکن و نمایش پیغام خوشامد استفاده خواهیم کرد.
در خط ۳ از فرمان raw_input برای گرفتن یک رشته یعنی نام کاربر استفاده شده است. در سری ۲.x پایتون برای گرفتن اعداد از ()input و برای گرفتن رشته‌ها از ()raw_input استفاده می‌شود. اما در سری ۳.x پایتون دستور raw_input حذف شده و تنها از دستور input استفاده می‌شود که در هر صورت یک رشته را برمی‌گرداند و تبدیل نوع داده ورودی به عدد یا سایر انواع باید توسط برنامه‌نویس صورت بگیرد. دستورات input و raw_input هر دو از توابع درونی پایتون هستند. این توابع یک آرگومان ورودی دارند که یک رشته است. این رشته به‌‌عنوان پیام برای کاربر نمایش داده شده و جواب کاربر مقدار برگشتی تابع است. در این جا مقدار برگشتی (یا همان پاسخ کاربر) به متغیر name نسبت داده می‌شود. پایتون تعداد زیادی تابع توکار یا درونی دارد که گستره وسیعی از عملیات پرکاربرد را به انجام می‌رسانند.
“ string   %<s|d|f|…>  string “   % ( <variable> [,variable , variable, . . .] )

یعنی هر عبارت بعد از علامت % بیرون رشته، به ترتیب جایگزین یکی از علامت‌های موجود در رشته خواهد شد. اگر مجموعه دستورات زیر را در نظر بگیریم:

score = 86
field = “mathematic”
print “I got %d in %s” % (score , field)
خروجی آن برابر «I got 86 in mathematic» خواهد بود.
در نهایت، در خط ۶ توسط کلمه کلیدی return، مقدار متغیر name به صدا زننده تابع بازگردانده می‌شود.
خط ۸ تعریف یک تابع جدید است و همان‌گونه که از نام آن بر می‌آید، تعامل با بازیکن برای انجام یک نوبت از بازی را به عهده دارد. پرانتز پس از نام تابع نشان می‌دهد که این تابع دو مقدار ورودی دارد. ما این دو مقدار را به ترتیب صفحه بازی b و نام بازیکن player در نظر گرفته‌ایم. مقدار b به اصطلاح به تابع پاس شده است تا از روی آن، نقطه مورد نظر بازیکن با نقاط خالی صفحه مقایسه شود. نام بازیکن هم برای نمایش پیغام‌ها مورد استفاده قرار خواهد گرفت. 
در خط ۹ حلقه تعامل با کاربر آغاز می‌شود. این حلقه تا زمانی که کاربر یک نقطه مناسب (آزاد و در محدوده صفحه بازی) را انتخاب نکرده باشد، ادامه خواهد یافت. همان‌گونه که در قسمت قبل دیده‌اید یکی از راه‌های خروج از حلقه دستور break است که کنترل عملیات را به خط بعد از حلقه منتقل می‌کند. 
در خط ۱۱ محل مورد نظر کاربر پرسیده می‌شود. بازیکن باید محل را به صورت یک جفت عدد که با کاما (،) از یکدیگر جدا شده‌اند وارد کند. متغیر حاصل یعنی place از دید پایتون یک توپل (tuple) است. توپل در زبان پایتون بسیار شبیه  لیست است، اما تفاوت آن با لیست غیر قابل تغییر بودن آن است؛ یعنی عناصر یک  لیست را می‌توان ویرایش کرد، اما عناصر موجود در توپل را نمی‌توان تغییر داد. بعدها درباره توپل بیشتر صحبت خواهیم کرد. تنها نکته مهم این است که برای ارجاع به عناصر  لیست یا توپل از علامت [] در جلوی نام  لیست یا توپل استفاده می‌شود. توجه کنید که مانند غالب زبان‌های برنامه‌نویسی اندیس توپل‌ها و  لیست‌ها‌ از عدد صفر آغاز می‌شود.
بنابراین، در خط [۱۳، place[0 عضو نخست توپل را به‌عنوان x و [place[1 عضو دوم آن را به‌عنوان y جدا می‌کند. 
در خطوط ۱۴ تا ۱۹، مقادیر x و y کنترل می‌شوند تا در محدوده صفحه باشند. اگر اعداد در محدوده صفحه بازی (۳×۳) نباشد یک پیغام خطا چاپ شده و به کمک دستور continue حلقه گردش بعدی را انجام می‌دهد. در هر حلقه، چه از نوع for و چه از نوع while، دستور continue باعث می‌شود که روند فعلی حلقه قطع شده و کنترل دوباره به ابتدای بدنه حلقه بازگردد.
در خط ۲۰ کنترل می‌شود که آیا محل انتخاب شده (که اکنون مطمئن هستیم در محدوده صفحه بازی است) قبلاً اشغال شده یا خیر؟ اگر اشغال نشده باشد، علامت مختص بازیکن در آن ثبت شده و با دستور break از حلقه خارج می‌شویم. چون اندیس  لیست‌ها و توپل‌ها از صفر شروع می‌شود برای کنترل صفحه بازی از x و y یک واحد کم کرده‌ایم.
خط ۲۳ استفاده از دستور else را نشان می‌دهد. در صورتی‌که شرط if آخر درست نباشد، کنترل به دستور else منتقل می‌شود. در این حالت پیامی مبنی بر اشغال بودن نقطه مورد نظر چاپ شده و حلقه دوباره از ابتدا اجرا می‌شود.
همان‌طور که در خط ۲۵ مشاهده می‌کنید، این تابع مقدار برگشتی ندارد. نکته مهمی که همیشه باید به خاطر داشته باشید این است که در پایتون لیست‌های پاس شده به تابع نظیر b، به‌صورت «ارجاع به محل» یا By Reference مورد استفاده قرار خواهند گرفت و بنابراین هر تغییری در آن به طور مستقیم به متغیر اصلی (اینجا یعنی صفحه اصلی بازی board) اعمال خواهد شد و در نتیجه به مقدار بازگشتی نیازی نخواهد بود.
ماژول مربوط به صفحه بازی
در فهرست ۳، ماجول دوم که سازنده و کنترل کننده صفحه بازی است، نمایش داده شده است. این ماجول را تایپ کرده و با نام board.py ذخیره کنید. با یک نگاه کلی و با توجه به توضیحاتی که تا‌کنون داده‌ایم، مشخص می‌شود که این ماجول سه تابع برای ساخت صفحه نمایش، چاپ آن و کنترل برنده بازی تعریف می‌کند. در خط ۳ متغیری به نام b از نوع لیست تعریف می‌شود. این متغیر در این مرحله هیچ عضوی ندارد.
در خط ۴ با یک دستور for حلقه‌ای با سه بار تکرار تعریف می‌شود که در خط ۵ به کمک متد append یک  لیست تهی دیگر را به  لیست b اضافه می‌کند. در دو خط بعدی با یک حلقه for دیگر، به این  لیست داخلی، سه رشته با مقدار “ “ افزوده می‌شود. در نهایت متغیر b به فرم زیر در‌خواهد آمد:
b= [[“ “,“ “,“ “],[“ “,“ “,“ “],[“ “,“ “,“ “]]
آموزش پایتون به زبان ساده
شکل ۲- شبیه‌سازی صفحه بازی
همان‌طور که پیش‌تر توضیح دادیم برای دسترسی به عناصر داخل  لیست از اندیس‌ها و علامت [] استفاده می‌کنیم. بنابراین، [b[0 نخستین عضو b است که خود یک  لیست دیگر است و [b[1][2 به سومین عضو در دومین عضو b اشاره می‌کند. ما از این تجرید برای شبیه‌سازی مختصات یا همان x و y صفحه بازی استفاده کرده‌ایم. به عبارت دیگر، عنصر نخست b نماینده ستون نخست یا x=1 و به عنوان مثال، عنصر دوم نماینده ستون دوم خواهد بود. به همین شکل مقدار [b[2][1 نماینده محتویات نقطه‌ای با مختصات (۳،۲) خواهد بود.
 لیست‌ها که از قسمت قبل با تعریف آن‌ها آشنا شده‌اید، از پرکاربردترین انواع بنیادی پایتون هستند.  لیست در واقع چیزی شبیه آرایه در سایر زبان‌ها است، با این تفاوت که لازم نیست از ابتدا اندازه آن را مشخص کنید یا نوع داده آن را تعریف کنید و همچنین هنگام اجرای برنامه می‌توانید هم خود  لیست و هم عناصر آن را تغییر دهید. همان‌گونه که دیدید با متد append می‌توان هر چیزی را به  لیست اضافه کرد.
در خط ۱۰ تابع دیگری برای چاپ صفحه نمایش تعریف می‌شود. در خط ۱۱ متغیر s از نوع رشته و با مقدار تهی تعریف شده است. 
خط ۱۲ نمونه دیگری از کاربرد ()range را نشان می‌دهد. همان‌طور که به‌احتمال حدس زده‌اید، ()range هم یکی از توابع داخلی پایتون است. در این خط، تابع ()range سه آرگومان گرفته است که به ترتیب عدد شروع‌، عدد پایان و میزان تغییر در هر مرحله است. فرم کلی دستور() range مانند زیر است:
range ( [start ,] <stop> [,step] )
ماژول اصلی
فهرست ۴ ماجول اصلی یا کنترل کننده برنامه را نشان می‌دهد. این مجموعه کد را تایپ‌کرده و با نام main.py در کنار سایر فایل‌ها ذخیره کنید. به خط ۱ که با علامت #! شروع شده است، به اصطلاح شی‌بنگ یا shebang گفته می‌شود. این خط در محیط‌های لینوکسی به سیستم عامل اعلام می‌کند که برای اجرای این اسکریپت (در صورتی‌که به آن مجوز اجرا داده شده باشد) از چه مفسر یا مترجمی استفاده کند. در سیستم ویندوز یا سایر موارد این خط همانند یک توضیح یا comment دیده می‌شود.
اکنون می‌دانید که عبارت فوق یعنی آرگومان stop یا پایان  لیست تولیدی الزامی ولی آرگومان شروع و مقدار افزایش در هر مرحله اختیاری است. نتیجه خروجی (range(2,-1,-1 در اینجا لیستی با مقدار [ ۲ , ۱ , ۰ ] است. دلیل استفاده از این  لیست معکوس این است که هنگام چاپ،  لیست از بالا به پایین یعنی از خانه‌هایی به مختصات (۱,۳)، (۲,۳) و (۳,۳) چاپ می‌شود در حالی‌که مقادیر موجود در متغیر b به ترتیب از (۱,۱)، (۱,۲) و الی آخر شروع می‌شوند. مجموعه خطوط ۱۳ تا ۱۶ با ترکیب عناصر b و کاراکترهای “-“ و “|” جدول‌هایی شبیه شکل ۲ را برای بازی به وجود آورده و چاپ می‌کنند. به دلیل طولانی بودن تابع سوم ما از توضیح خط به خط آن صرف نظر می‌کنیم. این تابع به رغم ظاهر طولانی، منطقی بسیار ساده دارد. به طور خلاصه این‌که در خط ۲۱ حلقه‌ای تعریف می‌شود که تنها دوبار یک بار با مقدار X (نماینده بازیکن) و بار دیگر با مقدار O  (نماینده کامپیوتر) اجرا خواهد شد. در خطوط ۲۲ تا ۲۹، با یک سری حلقه‌ for امتیاز X یا O در همه سطرها محاسبه می‌شود که اگر تنها در یک سطر برابر ۳ بود، علامت X یا O با دستور return به عنوان برنده به صدا زننده تابع بازگردانده شده و عملکرد تابع تمام می‌شود. در خطوط ۳۱ تا ۳۷ همین کار برای ستون‌ها انجام می‌شود. در نهایت در خطوط ۳۹ تا ۴۶، قطرهای صفحه بازی کنترل می‌شود. رسیدن کنترل اجرا به خط ۴۸، به این معنی خواهد بود که بازی تاکنون هیچ برنده‌ای نداشته است. در این‌جا کل صفحه برای وجود خانه‌های خالی بررسی می‌شود که در‌صورت عدم، وجود بازی مساوی اعلام خواهد شد. در‌صورتی‌که صفحه بازی هنوز جای خالی داشته باشد، مقدار None یا هیچ، که از مقادیر از پیش تعریف شده پایتون است، برگشت داده می‌شود.

خطوط ۴ و ۵ و۶ ماجول‌ها و توابع مورد نظر  را بارگذاری می‌کنند. دستور import برای استفاده از ماجول‌ها به کار می‌رود. این دستور برای یافتن ماجول مورد نظر نواحی خاصی از سیستم را جست‌وجو می‌کند. یکی از این نواحی پوشه یا فولدری است که فایل import کننده در آن قرار دارد. ناحیه دیگر کتابخانه استاندارد یا Standard Library است. دستور import به دو صورت قابل اجرا است. روش اول به شکل زیر است:

import <module> [,module ,module , . . .]

روش دوم نیز مطابق نمونه زیر است:

from <module name> import <function|variable|class> [,function|variable|class, . . .]

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

 نکته:

در نوشتن فرم کلی دستورات علامت < > به معنای اجباری، [ ] به معنای اختیاری و علامت | به معنای یا است.


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

اشتراك گذاری نوشته

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *