نکات مقاله نویسی(article writing)

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

نکات مهم در انتخاب عنوان مقاله

معیارهای نویسندگی

کمیته بین المللی سردبیران مجلات پزشکی (ICMJE  ) ، نویسنده مقاله را چنین تعریف می‌کند: «کسی که در یک مقاله منتشر شده سهمی ‌اساسی از لحاظ فکری داشته باشد».
این کمیته موارد زیر را به عنوان معیارهای نویسندگی (authorship criteria  ) ذکر می‌کند:
داشتن سهمی ‌اساسی در ایده و طرح مطالعه یا جمع‌آوری داده‌ها یا تجزیه و تحلیل داده‌ها
تهیه دست نوشته مقاله یا بازنگری منتقدانه مقاله از لحاظ محتویات مهم
تأیید نهایی نسخه‌ای که قرار است چاپ شود.
این معیارها به نام معیارهای ونکوور (Vancouver criteria  ) معروف است. توجه کنید که وجود هر سه معیار به صورت همزمان ضروری است. در معیار اول تنها وجود یکی از سه مورد مذکور مشتمل بر مشارکت در ایده یا جمع‌آوری داده‌ها یا آنالیز داده‌ها کفایت می‌کند. اما عملاً در بسیاری از مقالات، لحاظ کردن این معیارها ساده نیست. مثلا در مطالعات چند مرکزی (multi-center  ) که هر مرکز بخشی از اجرای طرح را عهده‌دار است تهیه فهرست نویسندگان براساس معیارهای ونکوور دشوار به نظر می‌رسد.
برخی مجلات مانند Journal of American Medical Association- JAMA لازم می‌دانند که نویسندگان فرمهای مخصوصی را که در آنها معیارهای ونکوور مطرح شده است پر کنند تا بدین ترتیب در مورد احراز این معیارها توسط هر یک از نویسندگان اطمینان حاصل شود. بعضی دیگر از مجلات مانند BMJ -British Medical Journl و Lancet از هر یک از نویسندگان میخواهند که به طور دقیق سهم خود را در مقاله مشخص نمایند. اخیراً بنحو روز افزونی در مطالعات چند‌مرکزی نویسندگی مقاله به یک گروه نسبت داده می‌شود. در چنین مطالعاتی نیز آن دسته از افراد گروه که نامشان به عنوان نویسندگان مقاله ذکر می‌شود، باید معیارهای ونکوور را دارا باشند.
لازم به تأکید است که تنها فراهم کردن منابع مالی و امکانات مطالعه، جمع آوری داده‌ها یا نظارت کلی بر گروه تحقیقاتی، توجیهی برای نویسنده بودن نمی‌باشد.

ترتیب نویسندگان

نویسنده اول معمولاً همان کسی است که نسخه اولیه مقاله را البته با مشورت با سایر نویسندگان می‌نویسد. نویسنده اول همچنین مسؤول تجزیه و تحلیل داده‌ها یا نظارت بر آن است و باید از درستی داده‌ها و تفسیر نتایج اطمینان حاصل کند. نویسنده آخر معمولاً محقق ارشد گروه است (برخلاف آنچه در کشور ما معمول است) و غالباً همان کسی است که ایده اولیه مطالعه را مطرح کرده است. در فاصله بین نام نویسنده اول و آخر، نام سایر نویسندگان به ترتیب کاهش سهمشان ذکر می‌شود.
لازم به ذکر است که یک قانون فراگیر یا توافق عمومی در مورد ترتیب نام نویسنده‌ها وجود ندارد. به عنوان مثال در برخی مقالات، نویسنده آخر ممکن است کمترین نقش را داشته باشد و در بعضی مقالات نویسنده آخر ممکن است محقق ارشد گروه باشد. لذا همیشه از روی ترتیب نام نویسندگان نمی‌توان به سهم آنها در مقاله پی برد.
به هر حال ترتیب نام نویسندگان باید حاصل تصمیم جمعی آنها باشد. یکی از نویسندگان نیز باید به عنوان نویسنده مسؤول مکاتبات مشخص شود. این نویسنده، مسؤول ارتباط با مجله، پاسخگویی به درخواست‌های مربوط به نسخه چاپی مقاله و ارتباط با سایر پژوهشگران می‌باشد.
هر کدام از نویسندگان صرفنظر از ترتیب اسامی ‌باید قادر به ارائه نتایج، دفاع از تفسیر آن و بحث پیرامون محدودیت‌های مطالعه باشند. در واقع یکایک نویسندگان به لحاظ علمی ‌و اخلاقی در مورد محتوای مقاله مسؤول هستند.
یک روش عادلانه، تعیین سهم هر یک از نویسندگان (author’s contribution  ) در مقاله به صورت واضح و مشخص است. بسیاری از مجلات فرمی را برای نویسنده مسؤول مکاتبات می‌فرستند که درآن باید نقش هر یک از نویسندگان در مراحل مختلف انجام مطالعه و آماده‌سازی مقاله تعیین گردد. بدین ترتیب مشخص می‌شود که کدام نویسنده یا نویسندگان در طراحی مطالعه، جمع آوری داده‌ها، آنالیز آماری، تفسیر داده‌ها، آماده سازی دست نوشته مقاله، مرور متون و… نقش داشته‌اند. لذا در بسیاری از مقالات قسمتی تحت عنوان author’s contribution نیز به چشم میخورد.

چکیده

واژگان کلیدی

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

مقدمه

روشها (Methods)

در بخش مواد و روشها باید به سوالات زیر پاسخ داده شود
چه نوع مطالعه ای انجام شده (study design)
چه کسانی و در چه شرایطی مورد مطالعه قرار گرفته اند (subjects and setting)
آنچه مورد اندازه گیری قرار گرفته (measurements )
چگونه داده ها مورد تجزیه و تحلیل قرار گرفته اند (analysis)
بخش روشها و یافته ها با هم ارتباطی متقابل دارند. بدین ترتیب که اگر مطلبی را در بخش یافته ها ذکر کنید باید در بخش روشها توضیح داده باشید که چگونه آن را اندازه گرفته اید. به همین ترتیب، اگر مطلبی را در بخش روشها بیاورید، یافته های مربوط به آن را باید در بخش یافته ها ارائه کنید
در بخش  روشها برای بیان سازمان یافته تر مطالب میتوانید از عناوین مجزا استفاده کنید
بیشتر بدانید ...

ساخت یک وب سایت دینامیک با Django

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

فریم ورک های پایتون

تعداد وب فریم ورک های پایتون زیاد نیست، اما برخی از بهترین های انها عبارتند از

Django

جنگو پایتون یکی از بهترین ها برای طراحی وب با پایتون می باشد . سادگی در کار کردن با این فریم ورک و همچنین قدرت جنگو مثال زدنی نیست.

Grok

فریم ورک دیگری با مجموعه ای از ویژگی های که نزدیک به جنگو می باشد. اگر تصمیم بگیرید که جنگو را استفاده نکنید می توانید از این فریم ورک (GROK) استفاده کنید ، این یک جایگزین خوب است.

WebPy

یک فریم ورک ساده و سبک است که قابلیت های کمتری به نسبت جنگو دارد ولی میتوان به دلایلی از این فریم ورک هم استفاده کرد .

TurboGears

این فریم ورک در گذشته بسیار استفاده می شده است ولی بیشتر به درد صفحات سبک میخورد. البته بر روی این فریم ورک در چند ماهه اخیر ویرایش هایی انجام شده است که به شدت بهبود پیدا کرده است.

نصب جنگو

اکثر فعالیت ما در بخش ترمینال خواهد بود. کدهای ما در این بخش بر روی سیستم های لینوکس و مک قابلیت اجرا دارد اما درصورتی که از ویندوز استفاده می نمائید فرآیند تا حدودی تغییر خواهد داشت. آشنایی با command line در صورتی که شما تنها پایتون مینویسد ضروری نیست، اگرچه، درصورتی که در نظر دارید از جنگو استفاده کنید یا به طور کلی یک وب سایت دینامیک را اجرا نمائید، آموزش آن ارزشمند است.

آموزش کار با ترمینال

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

کدهای مورد استفاده برای نصب جنگو را مشاهده می نمائید. هرچند این دستورات با نسخه ۳ پایتون همخوانی ندارند، بنابراین شما نیازمند نصب نسخه ۷.۲ و یا پایین تر برای اجرای این دستورات می باشد.

سپس ما می توانیم فایل های نصب را پاک نمائیم.

حال آنرا آزمایش میکنیم.

باید ۱.۳.۱ مشاهده شود. در صورت مشاهده جنگو نصب شده است.

ساخت وبلاگ

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

در ابتدا ما باید یک پروژه جدید در جنگو ایجاد کنیم :

 

هر کدام از این فایل ها چه کاری انجام میدهند:

__init__.py

به پایتون اعلام میکند که فولدر مورد نظر یک پکیج پایتونی است. به این معنی که به پایتون اجازه میدهد تا تمام script های موجود درون فولدر را به عنوان یک ماژول منتقل نماید.

manage.py

درواقع جزئی از وب سایت شما نیست؛ یک اسکریپت ابزاری است که شما میتوانید از command line آنرا اجرا نمائید و شامل تمام آرایه های توابعی است که برای مدیریت سایت خود نیاز دارید.

settings.py

فایلی است که URLها را به یک دیگر متصل نماید می نماید. برای مثال، میتواند yourwebsite.com/about  را به صفحه About Us  متصل نماید.

urls.py

با استفاده از این دستور در واقع می توان صفحات وبسایتی که با پایتون ساخته ایم را به یکدیگر اضافه کنیم و مثلا میتواند صفحه اصلی  را به صفحه تماس با ما متصل کند .

این دستور برای لینک دهی استفاده می شود .

جنگو خود را به عنوان یک MTV framework معرفی میکند که در واقع به معنای Model Template View میباشد.

برنامه ها

با این حال، هیچ کدام از فایل های بالا به تنهایی نمیتوانند یک سایت فعال را ایجاد کنند. به همین دلیل ما نیاز به برنامه ها (Apps) داریم. برنامه ها محلی هستند که شما کدی را که باعث عمل نمودن وب سایت شما میشود در آن مینویسد، اما پیش از استفاده از آنها، باسد کمی درباره ضوابط طراحی جنگو بدانیم

نخست، جنگو یک فریم ورک MVC است، که به معنای Model View Controller می باشد. همچنین جنگو خود را به عنوان یک فریم ورک MTV می شناسد که به معنای Model Template View است که با فریم ورک MVC تفاوت ناچیز دارد. اما اساساً هردو شبیه به هم هستند. در هر حال، MVC یک الگوی وابسته به معماری است که روشی برای ساختاربندی پروژه شما ارائه میدهد. به این معنی که کدی را که برای پردازش داده استفاده شده است از کدی که برای مدیریت رابط کاربری استفاده شده است جدا می نماید.

جنگو بر اساس فلسفه DRY یا  ” خودت را دوباره تکرار نکن” عمل می کند.

ثانیاً، جنگو براساس فلسفه DRY یا ” خودت را دوباره تکرار نکن” عمل مینماید. که به این معنی است که، نباید یک کد که یک وظیفه مشخص را انجام میدهد را چندبار استفاده نمائید. برای مثال، اگر در بلاگی، این ویژگی را نوشته باشیم که مقاله ای را به صورت انتخابی از آرشیو انتخاب نماید، و این کدرا برای باقی صفحات نیز بخواهیم، تنها کافی است آنرا برای دیگر صفحات نیز استفاده کنیم و نیازی نیست که دوباره آنرا بنویسیم.

ممکن است سوال شود که برنامه ها چه مزیتی دارند؟ برنامه ها اجازه میدهند که وب سایت به شکل DRY نوشته شوند. هر پروژه ای، همانند آنچه ما اینجا داریم، میتواند شامل چندین برنامه شود. همچنین یک برنامه میتواند بخشی از چندیدن پروژه باشد. با توجه به مثالی که قبلا به ان اشاره شد، این به این معنی است که اگر ما در آینده سایتی ساختیم که نیاز به ویژگی گزینش انتخاب صفحات داشت، نیازی نیست که دوباره از ابتدا آنرا بنویسیم. ما به سادگی میتوانیم برنامه را از این پروژه منتقل کنیم. به همین دلیل، مهم است که هر برنامه، یک هدف مشخص را به سرانجام برساند. اگر تمام عملکر سایت خود را تنها بایک برنامه بنویسید و در اینده به بخشی از آن نیاز داشته باشید باید تمام آن را منتقل نمائید. برای مثال اگر در حال ساخت یک وب سایت فروش اینترنتی (eCommerce) بوده باشید، و نخواهید تمام ویژگی های بلاگ را منتقل نمائید. از سوی دیگر، اگر یک برنامه برای گزینش انتخابی و برنامه ای دیگر برای سیستم انتشارات بلاگ ساخته باشید، میتوانید هر بخشی از آن را که نیاز دارید انتخاب و منتقل نمائید. این همچنین به این معنی است که درون سایت کدها به خوبی دسته بندی شده اند. اگر شما بخواهید یک ویژگی را تغییر دهید، نیازی نیست که در تمام فایل به دنبال آن به جست و جو بپردازید؛ شما میتوانید به راحتی به برنامه مدنظر خود دسترسی داشته و آنرا بدون نگرانی از تداخل و تغییر در باقی موارد، تغییر دهید.

دوباره، ما یک فایل __init__.py  برای پکیج ساختن آن داریم و سه فایل دیگر: مدل ها، آزمایش ها و بازدیدها. در حال حاضر نیازی به بررسی آزمایشات نیست، اما دو مورد دیگر دارای اهمیت می باشند. مدل ها و بازدید ها بخش های M و V از MVC می باشند.در مدل، ما ساختار داده هایمان را تعریف می نمائیم.

در صورتی که پیش از این با PHP کار کرده باشید، ممکن است از PhpMyAdmin برای ساخت جداول MySQL خود استفاده کرده باشید، و سپس جستارهای SQL خود را به صورت دستی در متن PHP خود وارد کرده باشید. در جنگو این مسئله بسیار ساده تر است. ما تمام ساختار داده ای که برای مدل نیاز داریم تعریف کرده و یک دستور را اجرا میکنیم و تمام پایگاه داده های ضروری ساخته خواهند شد.

زمانی که شما نیاز به داشتن دسترسی به آن داده را دارید، شما به وسیله این مدل ها و با استفاده از فراخوانی روش بر روی آنها میتوانید به آنها دست یابد به جای آنکه جستار های خالی راجست و جو نمائید. این بسیار مفید است زیرا جنگو میتواند از چندین برنامه پایگاه داده استفاده نماید. برای مثال ما از MySQL استفاده خواهیم کرد، زیرا قویترین برنامه پایگاه داده بوده و قالب host ها پذیرای ان هستند.، اما اگر نیاز باشد که به پایگاه داده دیگری در آینده منتقل شویم،تمام کدها مجاز خواهند بود. در سایر زبان ها، اگر در پی تغییر به SQLite یا موردی دیگر بودید، نیاز بود تا دوباره تمام کدهای دسترسی به پایگاه داده را بازنویسی نمائید.

در فایل های مشاهده (view)، ما کدی را مینویسیم که در واقع صفحات وب را تولید می نماید و در واقع تمام بخش ها را به یکدیگر متصل می نماید. زمانی که یک کاربر یک URL تایپ میکند، توسط اسکریپت  urls  که ما پیشتر آنرا دیدیم، به اسکریپت  views فرستاده میشود، که سپس داده های مرتبط از مدل را میگیرد، آنرا پردازش کرده و آنرا با قالب پیش فرض ارسال می نماید که نهایتا به عنوان صفحه ای که کاربر میبند به نمایش در خواهد امد. ما نگاهی کوتاه به ان قالب های پیشفرض خواهیم داشت. آنها آسان ترین بخش هستند – غالبا HTML.

برای یک بلاگ، ما جدولی از ارسال ها نیاز خواهیم داشت، همراه با چندین بخش برای عنوان، نوشته بدنه، نویسنده، زمان نوشته شدن و علی آخر. یک بلاگ واقعی باید دارای بخش نظرات باشد، اما این موضوع خارج از آموزش ما می باشد.

MySQL

این مدل ها تنها توضیح هستند. ما نیازمند هستیم تا یک پایگاه داده واقعی از آنها بسازیم. ابتدا، نیاز داریم تا MySQL بر روی سیستم ما اجرا شود. بر روی یک وب سرور واقعی، این موضوع مشکلی نخواهد بود زیرا آنها به طور پیش فرض آنرا نصب  کرده اند. خوشبختانه، با یک مدیریت پکیج، نصب ان اسان است. نخست. باید Homebrew  و Easy Install را نصب نمائید.

زمانی که شما ری استارت میکنید، MySQL اجرا نخواهد شد، پس هر زمانی در اینده که شما نیاز دارید تا server شروع به کار نماید باید،  mysqld  را اجرا نمائید. سپس شما میتوانید در یک زبانه جدید python2.6 manange.py runserver  را اجرا نمائید تا سرور توسعه را اجرا نماید. این دستور هنوز باعث اجرای سرور نخواهد شد، و تنها یک پیغام خطا را نشان خواهد داد. زیرا نیاز است تا تنظیمات پیکربندی شوند. به فایل    settings.py. توجه فرمایید. ابتدا لازم است که تنظیمات پایگاه داده تغییر یابد که از خط ۱۲ شروع میگردد.

در صورتی که sever را بار دیگر اجرا نمائید، باید به دستی عمل کند، به اعلام نماید که شما با موفقیت MySQL را نصب نمده اید. در صورتی که شما ۱۲۷.۰.۰.۱:۸۰۰ رت در مرورگر اینترنت خود جست و جو نمائید، باید صفحه پیشفرض جنگو را مشاهده کنید. حال به تغییر سایت جنگویی خود به یک بلاگ می پردازیم. ابتدا، نیاز است با استفاده از مدل ها جداولی را در پایگاه داده به وسیله اجرا کردن دستور زیر ایجاد نمائیم.

هر مرتبه که شما مدل های خود را تغییر دهید، باید این دستور را اجرا نمائید تا پایگاه داده را به روز نمائید. توجه داشته باشید که این موضوع باعث تغییر بخش های موجود نخواهد شد؛ تنها ممکن است مدل های بخش های جدید را اضافه نماید. بنابراین درصورتی که در پی پاک نمودن بخش ها هستنید، باید به صورت دستی و شبیه به PhpMyAdmin این عمل را انجام دهید. با توجه به اینکه بار اولی است که ما این دستور را اجرا میکنماییم، جنگو تمام جداول پیش ساخته را نصب خواهد کرد. تنها تایپ کنید “yes” و سپس جزئیات خود را وارد نمائید.

حال بیایید به نصب فایل urls.py   بپردازیم. خط اول در بخش مثال ها را از حالت comment خارج کرده و آنرا به   url(r’^$’, ‘FirstBlog.blog.views.home’, name=’home’) . تغییر دهید. حال، فایل های view را برای پاسخ به این درخواست ها ایجاد میکنیم.

قالب ها

این فایل index.html   هنوز وجود ندارد، پس باید ان را ساخت. پوشه ای ساخته، نام templates در برنامه  blog  را به آن داده و فایلی را به نام index.html در آن ذخیره میکنیم، که به سادگی میتواند شامل “Hello world” باشد. سپس نیاز است تا فایل تنظیمات را تغییر دهیم تا جنگو بداند که این قالب در کجا قرار دارد. خط ۱۰۵ محلی است که بخش مربوط به محل قرار گیری قالب ها شروع میشود؛ پس به صورت زیر ان را تغییر دهید:

اگر سرور را دوباره اجرا و صفحه را در مرورگر خود refresh نمائید، باید پیغام “Hello World” را مشاهده نمائید. حال ما میتوانیم بلاگ خود را منتشز نمائیم. ما چند کد متنی HTML را به صفحه خانه اضافه خواهیم کرد.

در صورتی که ذخیره سازی را انجام داده و صفحه را refresh نمائید، خواهید دید که صفحه با محتویات جدید به روز رسانی شده است. قدم بعدی افزودن محتوای دینامیک از پایگاه داده است. برای انجام این مهم، جنگو دارای یک زبان پیش فرض داراد که اجازه میدهد تا متغیر ها به وسیله پرانتز ها با یک دیگر ترکیب شوند. بخش میانی صفحه خود را تغییر دهید تا به شکل زیر تبدیل شود:

حال میتوانیم به این متغیرها از طریق فایل views.py   به وسیله ساخت یک dictionary از مقادیر، مقدار دهی نمائیم.

پس از ذخیره سازی و refresh، مشاهده خواهید کرد که محتوا را از طریق فایل view در یک غالب قرار داده اید. قدم نهایی این است که داده را از پایگاه داده گرفته و آن را جایگذاری نمائیم. خوشبختانه ما میتوانیم این کار را بدون نیاز به جستار های SQL،  با استفاده از مدل های جنگو انجام دهیم. نیاز است که برنامه  blog خود را به پروژه  FirstBlog  به وسیله تغییر یک تنظیم دیگر اضافه نمائیم. به خط ۱۱۲ INSTALLED_APPS   رفته و خط زیر را به لیست اضافه نمائید.

سپس، قالب را به روز رسانی نمائید تا به این داده ها دسترسی پیدا کنید.

حال، به تمام داده های موجود در جدولمان در فایل views.py  دسترسی داریم، سپس تنها ۱۰ ورودی ابتدایی را انتخاب میکنیم. این داده را در قالب قرار میدهیم،  حلقه ای برای ورودی ها ایجاد نموده، داده ها را با HTML سایت خود نشان خواهیم داد. این عمل هنوز عملی نخواهد شد، زیرا در پایگاه داده چیزی وجود ندارد. سرور را متوقف کرده و اجرا کنید:

جدولی جدید برای ارسال های ما در دیتا بیس ایجاد میکند. سپس، زبانه جدید باز کرده و تایپ کنید:

رمز عبور خود را تایپ کرده، دکمه enter را زده،  و اجرا نمائید:

به زبانه قبلی بازگشته و سرور را دوباره اجرا نمائید. صفحه را refresh نموده و باید یک ارسال وبلاگی را شماهده نمائید که به تازگی اضافه نموده اید. در صورتی که دستور MySQL را چند بار بیشتر اجرا نمائید، ارسال های بیشتری را بر روی فحه خواهید دید زمانی که آنرا refresh می نمائید.

سیستم مدیریت جنگو

آخرین نکته ای که باید به آن توجه شود، سیستم مدیریت جنگو است. این قابلیتی بسیار قدرتمند از سری قابلیت های جنگو می باشد که این امکان را فراهم می نماید تا بدون نوشتن هیچ کدی به مدیریت سایت پرداخت، در صورتی که اگر یک سایت از صفر ساخته شود برای مدیریت آن چنین عملی الزامی است. برای فعال سازی آن باید تعدادی از تنظیمات را تغییر دهینم. ابتدا خطوط ۴، ۵، ۱۳ و ۱۶ درون برنامه urls.py را از حالت Comment خارج کرده تا به صفحه مدیریت دسترسی پیدا کنیم. سپس به بخش INSTALLED_APPS از برنامه settings.py  رفته و ‘django.contrib.admin’,  و  ‘django.contrib.admindocs’, را از حالت comment خارج کنید. به منظور نظارت مدیر بر جدول  posts ، در پوشه blog  فایلی جدید به نام admin.py  اضافه نموده و خطوط زیر را اضافه نمائید.

بار دیگر python2.6 manage.py syncdb  را جرا کنید تا جداول برای بخش مدیر هم افزوده شوند، و سرور را ری استارت نمائید.

در صورتی که ۱۲۷.۰.۰.۱:۸۰۰۰/admin را در مرور گر خود مشاهده نمودید، باید صفحه ورد را مشاهده کنید. از جزئیاتی که پیشتر در زمان اجرای syncdb  انتخاب نموده بودید استفاده نمائید. باید بخشی را به عنوان بلاگ با زیر عنوانی برای  جدول posts  مشاهده نمائید. میتوانید به سادگی برای خلق، تغییر یا حذف ارسا های بلاگ استفاده نمائید.

تبریک شما یک بلاگ ساخته اید.

در انتها به نصب جنگو بر روی یک وب سرور می پردازیم.

نصب بر روی یک وب سرور

 دو نوع web hosting وجود دارد، و انتخاب شما بر استفاده از جنگو اثر گذار خواهد بود. در صورتی که یک host اشتراک گذاری شده دارید، host شما بسیار مناسب است.

بسیاری از host های ارزان قیمت از پایتون پشتیبانی  نمی کنند. در حالی که PHP کاملا تضمین شده است، حمایت از سایر زبان ها غالبا وجود ندارد. شما باید control panel را بررسی نمائید تا دریابید پیاتون (و جنگو) در دسترس هستند یا خیر. مسلما فرایند برای هر host متفاوت است. تقریبا تمام host ها بر روی Apache اجرا میشوند، و ما میتوانیم با استفاده از ماژول های mod_wsgi  یا mod_python  برای میزبانی جنگو اسفاده نمائیم.

اکثریت host ها متون را با استفاده از CGI به چندین زبان اجرا میکنند. جنگو میتواند بر روی FastCGi و به طور تئوری بر روی CGI اجرا شود، اما رسما این موضوع اعلام نشده است. بنابراین باید بررسی نمود که آیا این ها نصب شده اند یا خیر. معمولا در زیر بخش heading، برای مثال، “CGI and Scripting Language Support” یافت می شوند.

در صورتی که دارای VPS hosting می باشید، یا یک سرور اختصاصی دارید، کار بسیار راحت تر است. معمولا چنین سرورهایی از پیش دارای پایتون می باشند و بنابراین تنها نیاز به کپی کردن جنگو همانطور که در ایتدا توضیح داده شده می باشد. اما در صورتی که پایتون نصب نبود، با یک مدیریت پکیج می توانید آن را نصب نمائید.

به محض نصب جنگو بر روی سرورتان، سایتی که پیشتر ایجاد نمودید را به وسیله هر file transfer client مدنظر خود، بارگزاری نمائید. میتوانید این فایل ها را در هر محلی قرار دهید، اما آنها را ر پوشه  public  قرار ندهید، که در این صورت هر فردی میتواند کدهای اصلی سایت شما را مشاهده نماید.

سپس، یک پایگاه داده MySQL ساخته، نام آن را ‘firstblog’ گذاشته و syncdb  را دوباره اجرا نمائید. شما دوباره باید حساب کاربری خود را برای میز مدیریتی ایجاد نمائید، اما این تنها دفعه خواهد بود. با اجرای این فاسل با خطا مواجه خواهید شد، زیر تنظیمات سرور با تنظیمات کامپیوتر شخصی شما متفاوت است. ممکن است نیاز باشد تا رمز عبور خود را که درون settings.py قرار دارد تغییر دهید، اما با توجه به پیکر بندی سرور، ممکن است با مشکلات دیگری نیز برخورد نمائید. میتوانید از گوگل کمک بگیرید. این بار برای اجرای سرور ، دستور تا حدودی متفاوت است. شما باید یک آدرس IP مشخص و یک port معین را برای دسترسی به سایت بر روی نت، مشخص نمائید.

در صورتی که سایت خود را در یک مرورگر وب و بر روی پورت ۸۰۰۰ مشاهده کنید، سایت خود را خواهید دید.

بیشتر بدانید ...

تشخیص چهره به وسیله Open CV و Python

تشخیص چهره با استفاده از OpenCV: راهنمای گام به گام برای ساخت یک سیستم تشخیص چهره

هرگاه عبارت تشخیص چهره شنیده میشود، ناگهان به یاد دوربین های نظارتی می افتیم و هیچ گاه نمیتوان جمله معروف “شما تحت نطارت هستید. دولت یک سیستم پنهانی دارد، دستگاهی که هر ساعت از شبانه روز جاسوسی شما را میکند. من این را میدانم زیرا من آن را ساخته ام” که از فصل اول سریال تلویزیونی مظنون (person of interest) اقتباس شده است را فراموش نمود.

پیش از هرچیز:

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

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

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

نصب

ملزومات:

  • Python 3.3+ or Python 2.7
  • macOS or Linux (Windows not officially supported, but might work)
  • OpenCV
گزینه های نصب:

نصب بر روی Mac یا Linux
در ابتدا مطمئن شوید که dlib به همراه الحاقیات پایتون از پیش نصب شده است.

سپس این ماژول را از Pypi با استفاده از pip3 ( یا python 2 ) را نصب نمائید:

در صورتی که در نصب با مشکلی مواجه هستید، میتوانید pre-configured VM. را امتحان نمائید.

پس از اتمام نصب تمام وابسته ها، زمان آن فرا رسیده است تا به نوشتن کدی بپردازیم که سیستم تشخیص چهره شما را به وجود خواهد آورد.

تصاویری که من استفاده نموده ام:

و تمام. در صورتی که دقیقا همانند آنچه که اینجا به نمایش درآمد کدها را دنبال نمائید، دقیقا به انچه من دست یافته ام دست خواهید یافت.

بیشتر بدانید ...

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

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

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

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

آشنایی

کتابخانه Tkinter در اصل از زبان برنامه‌نویسی Tk گرفته شده است و مخفف عبارت Tk Interface است. ماجول Tkinter این امکان را برای ما فراهم می‌کند تا بدون نیاز به کتابخانه‌ها و ابزارهای جانبی و تنها با استفاده از قابلیت‌هایی که پایتون به‌صورت پیش‌فرض و در هنگام نصب استاندارد با خود به همراه دارد، به تولید رابط‌های بصری کاربر بپردازیم. 
این کار از طریق ابزارک‌هایی (widget) که Tkinter عرضه می‌کند، انجام خواهد شد. پنجره اصلی یا Toplevel container، دکمه‌ها (Button)، قاب‌ها (Frame)، ورودی متن (Text Entry)، دکمه‌های رادیویی (Radio Button) و بوم نقاشی (Canvas) نمونه‌هایی از این ابزارک‌ها هستند.

در حالت معمول، ما یک پنجره اصلی با نام Toplevel خواهیم داشت که به عنوان نگه‌دارنده‌ای (container) برای سایر ابزارک‌ها کار خواهد کرد. هر ابزارک دیگری به جز پنجره Toplevel یک ابزارک والد خواهد داشت و نمی‌تواند به تنهایی به وجود آید؛ اما لازم نیست والد آن حتماً Toplevel باشد. برای چیدن ابزارک‌های فرزند روی والد باید از سیستمی استفاده کنیم که به اصطلاح مدیریت هندسی (Geometry Management) نامیده می‌شود. برنامه‌نویسان به طور معمول این کار را به یکی از سه روش Packer، Grid یا Place management انجام می‌دهند. روش Packer بسیار زمخت و ابتدایی و شیوه Place management بسیار ریز و پر جزئیات است. در این قسمت، ما به سراغ روش Grid خواهیم رفت. برای درک بهتر یک صفحه شطرنجی را در نظر بگیرید که از تعدادی سطر و ستون تشکیل شده است و خانه‌های حاصل از این تقسیم‌بندی بر‌اساس شماره سطر و ستون آدرس‌دهی می‌شوند. در این تقسیم‌بندی، شماره‌گذاری سطرها و ستون‌ها از خانه بالا سمت چپ شروع شده و به راست و پایین ادامه می‌یابد. شماره سطرها و ستون‌ها همواره از صفر آغاز خواهد شد. برای کار با این شیوه، ابزارک والد تقسیم‌بندی شده و ابزارک‌های فرزند در این خانه‌های شطرنجی چیده خواهند شد. اگرچه این روش ممکن است در نگاه نخست بسیار محدود به نظر برسد، اما لازم است بدانید که ابزارک‌های فرزند می‌توانند شامل چندین خانه، چه سطری چه ستونی یا هر دو، باشند. بهتر است توضیحات بعدی را با یک مثال ادامه دهیم. پیش از شروع لازم است بدانید که برای کار با Tkinter در بعضی از توزیع‌های لینوکس لازم است بستهpython-tk را نصب کنید.

from Tkinter import *
mainWindow = Tk()
btnTest = Button(mainWindow,text=”Hello world!”).grid()
mainWindow.mainloop()
فهرست ۱- ایجاد یک پنجره ساده از طریق کتابخانه‌  Tkinter

شروع

نخستین برنامه ما همانند فهرست ۱ تنها شامل ۴ خط کد خواهد بود. این کدها را وارد کرده، ذخیره و اجرا کنید. نتیجه باید چیزی شبیه شکل ۱ باشد. در خط ۱ ما ابتدا کل توابع و متغیرهای موجود در ماجول Tkinter را import کرده‌ایم. در خط ۲ نمونه‌ای از شیء Tk که همان پنجره اصلی یا Toplevel است را به‌وجود آورده و در متغیر mainWindow ذخیره کرده‌ایم. خط ۳ یک نمونه از شیء دکمه را به‌وجود آورده و در متغیر btnTest ذخیره می‌کند. برای این کار، نخستین آرگومانی که به تابع ()Button داده‌ایم، نام شیء والد دکمه است. پس از آن مقدار آرگومان text یا متن روی دکمه را تنظیم کرده ودر نهایت آن را روی Grid یا شبکه شطرنجی قرار داده‌ایم. همان‌گونه که در این خط می‌بینید آرگومان‌های تابع با نام‌شان مقداردهی شده‌اند. در فراخوانی تمام توابع در پایتون، اگر ترتیب آرگومان‌های مورد نیاز را نمی‌دانید، می‌توانید آن‌ها را با درج نامشان مقداردهی کنید. در نهایت در خط ۴ تابع اجرا‌کننده رابط بصری یعنی ()mainloop را فراخوانده‌ایم. در این مثال، کلیک دکمه‌ای که ایجاد کرده‌ایم هیچ کاری انجام نمی‌دهد چرا که ما دستوری را که باید با کلیک این دکمه اجرا شود به برنامه معرفی نکرده‌ایم. در مثال بعدی کمی بهتر عمل خواهیم کرد.

from Tkinter import *
class App:
    def __init__(self,parent):
        myFrame = Frame(parent)
        self.btnQuit = Button (myFrame,\
            text=”Quit”,fg=”red”,command=myFrame.quit)
        self.btnHello = Button (myFrame,\
            text=”Hello”,command= self.SayHello)
        self.lblText = Label (myFrame,text=”Second Tk Sample”)
        myFrame.grid(column=0,row=0)
        self.lblText.grid(column=0,row=0,columnspan=2)
        self.btnHello.grid(column=0,row=1)
        self.btnQuit.grid(column=1,row=1)
        
    def SayHello(self):
        print “Hello World!”
mainWindow=Tk()
mainWindow.geometry(‘۱۵۰×۷۵+۵۵۰+۱۵۰’)
app = App(mainWindow)
mainWindow.mainloop()
فهرست ۲ –  ایجاد و چیدن دکمه‌ها و یک برچسب متنی روی پنجره اصلی برنامه 

پیشرفت

در این مثال، می‌خواهیم جزئیات بیشتری را برای رابط بصری برنامه فراهم‌کنیم. کدهای فهرست ۲ را در ویرایشگر دلخواه‌تان وارد، ذخیره و اجرا کنید. نتیجه اجرا باید چیزی شبیه شکل ۲ باشد. در این برنامه، کلیک دکمه Quit باعث خروج از برنامه شده و کلیک دکمه Hello پیغامی را در خط فرمان چاپ خواهد کرد. در این مثال، ابتدا کلاسی را برای ساخت و چیدن ابزارک‌های مختلف تعریف کرده‌ایم. هنگام ایجاد یک نمونه شیء از روی این کلاس، تنها آرگومانی که باید به آن ارسال شود ابزارک والد است. این کار که با فراخوانی تابع ()__init__ صورت می‌گیرد، یک قاب یا Frame ایجاد می‌کند که این قاب والد کلیه ابزارک‌های بعدی است. والد این فریم همان‌طور که در خط‌۴ می‌بینید، همان پنجره اصلی یا Toplevel است. پس از آن یک برچسب (Label) و دو دکمه ایجاد کرده‌ایم. به خط ۵  که وظیفه ساخت دکمه Quit را برعهده دارد توجه کنید، به احتمال حدس زده‌اید که آرگومان fg رنگ پیش‌زمینه یا متن دکمه را تعریف می‌کند. همین‌طور آرگومان command تابعی را که باید هنگام کلیک‌شدن این دکمه اجرا شود، مشخص می‌کند. برای این دکمه، ما از تابع  ()quit که به‌صورت پیش‌فرض در شیء Frame تعریف شده است، استفاده کرده‌ایم. اما برای دکمه Hello ما تابع SayHello را معرفی کرده‌ایم که تعریف و عملیات این تابع در خطوط ۱۵ تا ۱۶ آورده شده است. 

دقت کنید که برای سادگی کار، این تابع فعلاً خروجی خود را به خط فرمان یا ترمینال ارسال می‌کند. اما می‌توان آن را برای تغییر برچسب دکمه‌ها یا مثلاً افزودن متنی به پنجره برنامه تغییر داد. پس از آن باید محل این ابزارک‌ها را روی والدشان (myFrame) معرفی کنیم. این کار با فراخوانی تابع ()grid انجام شده است که در آن آرگومان‌های column و row به ترتیب ستون و سطر محل قرارگیری را مشخص می‌کنند. اگر به خط ۱۱ و جایگذاری شیء برچسب توجه کنید، آرگومانی با نام columnspan مشاهده می‌کنید که این آرگومان تعیین می‌کند شیء برچسب باید به اندازه دو ستون گسترده شود. به همین شکل برای گسترده شدن در جهت عمودی شما می‌توانید از rowspan نیز استفاده کنید. دقت داشته باشید که تابع ()grid، محل هر ابزارک را بر‌اساس والد آن تنظیم می‌کند. بنابراین شیء myFrame در موقعیت صفر و صفر روی Toplevel قرار می‌گیرد و مثلاً دکمه quit در موقعیت ۱و۱ از myFrame قرا خواهد گرفت.

در آخر و در خطوط ۱۷ تا ۲۰ ما شیء Toplevel و یک نمونه از کلاس App را ایجاد کرده‌ایم و تابع نمایش‌دهنده پنجره اصلی را فراخوانده‌ایم. تنها نکته جدید خط ۱۸ است. در این خط ما به تعریف مختصات و ابعاد پنجره اصلی پرداخته‌ایم. در این حالت، بخش ۱۵۰×۷۵ آرگومان، سایز پنجره را تعریف کرده و قسمت +۵۵۰+۱۵۰ فاصله آن را از لبه چپ و لبه بالا تنظیم می‌کند. این اعداد و ارقام را باید بر‌اساس برنامه موردنظرتان با آزمایش و خطا به دست بیاورید.

نمایش

ابزارک‌های ماجول Tkinter هرچند نسبت به زبان‌های برنامه‌نویسی گرافیکی نظیر VB یا #C  یا حتی wxWidgets ساده و بدوی به نظر می‌رسند، اما با توجه به امکانات و قابلیت‌هایی که دارند، تمام نیاز شما را در پروژه‌های کوچک برآورده خواهند کرد. شاید مهم‌ترین مزیت کتابخانه Tkinter و رابط‌های ساخته شده براساس آن، این باشد که به هیچ کتابخانه و کد اضافی احتیاج ندارند و تنها به کمک نصب استاندارد پایتون قابل استفاده خواهند بود. برای آشنایی بیشتر با سایر نمونه‌های این ابزارک‌ها و مشاهده قابلیت‌ها و جلوه‌های مختلف آن‌ها می‌توانید فایل demo.py را از آدرس دانلود و اجرا کنید تا دیگر ابزارک‌های  Tkinter و جلوه‌های آن‌ها را مشاهده کنید. شکل شماره ۳ نتیجه حاصل از اجرای این برنامه را نشان می‌دهد.

ادامه راه

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

راهنماهای استاندارد پایتون

پایتون به هنگام نصب و به صورت پیش‌فرض مجموعه کاملی از راهنماها، توضیحات و حتی آموزش‌های گام به گام را نیز با خود به همراه می‌آورد. در ویندوز کافی است به منوی Start بخش All programs و پوشه مربوط به پایتون رفته و گزینه Python Manuals را کلیک کنید. در شکل ۴ نمونه‌ای از صفحه نخست این مجموعه را مشاهده می‌کنید. در لینوکس یا دیگر سکوها نیز در صورت نبود Python Manuals می‌توانید آن‌ها را به صورت آنلاین و از آدرس مشاهده کرده و مورد استفاده قرار دهید. این مستندات به حدی مهم است که برنامه‌نویسان پایتون ادعا می‌کنند باید آن‌ها را در زیر بالش خود هم داشته باشید. 

 یک بایت پایتون

آموزش گام به گام «یک بایت پایتون» به آدرس نیز یکی از مشهورترین خودآموزهای پایتون است که نسخه‌های جداگانه‌ای برای هر دو سری ۲.x و ۳.x را فراهم کرده است. اگرچه با توجه به مطالبی که تاکنون یاد گرفته‌اید، مطالب این راهنما به احتمال برای شما بسیار ساده خواهد بود.

شیرجه در پایتون

یکی دیگر از مهم‌ترین و شاید قدیمی‌ترین منابع آموزشی پایتون، کتاب‌های رایگان «شیرجه در پایتون» (Dive Into Python) است. این مجموعه که توسط مارک پیلگریم تهیه شده؛ و به نسبت منبع قبلی مباحث بسیار پیشرفته‌تری را عرضه می‌کند، نیز به صورت جداگانه سری ۲.x و سری ۳.x پایتون را شامل می‌شود. برای استفاده از نسخه مربوط به سری ۲.x به آدرس http://www.diveintopython.net مراجعه کنید. در این آدرس می‌توانید کل مجموعه را به صورت یک کتاب با فرمت‌های مختلف دریافت کنید. برای استفاده از نسخه مربوط به سری ۳.x نیز به آدرس http://diveintopython3.net مراجعه کنید. البته این نسخه تنها به صورت آنلاین قابل استفاده است و امکان دانلود آن وجود ندارد.

سخن آخر

به یاد داشته باشید که هیچ خودآموز و راهنمایی همانند تجربه به شما کمک نخواهد کرد. یادگرفتن صرف دستورات و قواعد نحوی یک زبان برنامه‌نویسی از شما یک برنامه‌نویس نخواهد ساخت. برای این کار هیچ میان‌بری وجود ندارد. تا برنامه‌های واقعی ننویسید و با مشکلات دنیای واقعی دست‌وپنجه نرم نکنید، هیچ‌گاه به موفقیت نخواهید رسید. به نوشته ارزشمند پیتر نورویگ در آدرس http://norvig.com/21-days.html مراجعه کنید تا ببینید در سه روز، یک هفته، یک ماه و یک سال چه اندازه یاد خواهید گرفت و درک کنید برای حرفه‌ای شدن چه مسیر طولانی را در پیش خواهید داشت. 

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

بیشتر بدانید ...

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

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

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

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

متادیتا

نخستین نکته‌ای که باید بدانید این است که فایل‌های mp3 می‌توانند اطلاعاتی را درباره خود فایل ذخیره کنند. اطلاعاتی نظیر عنوان آهنگ، عنوان آلبوم و نام خواننده از جمله این اطلاعات هستند. این اطلاعات در برچسب‌های ID3 ذخیره می‌شود که به اصطلاح فرا داده یا «متادیتا» نامیده می‌شوند. در نخستین روزهای ظهور فایل‌های mp3 تنها مقدار بسیار کمی از این اطلاعات در فایل‌های mp3 ذخیره می‌شد. در آن زمان این اطلاعات در قسمت پایانی فایل‌های mp3 ذخیره می‌شد و بلوکی متشکل از ۱۲۸ بایت بود. به‌واسطه حجم اندک این بلوک، تنها ۳۰ کاراکتر به هر یک از اطلاعاتی نظیر نام آهنگ و آلبوم و خواننده اختصاص داده شده بود. برای بسیاری از فایل‌ها همین مقدار کافی بود، اما اگر با آهنگی با نام طولانی، نام آلبومی طولانی و… روبه‌رو می‌شدیم، مشکل خودنمایی می‌کرد. این برچسب‌های ID3 تحت‌عنوان استاندارد ID3v1 طبقه‌بندی شدند و برای تکمیل آن نسخه جدیدی از این استاندارد با نام ID3v2 معرفی شد. این استاندارد جدید امکان ذخیره اطلاعاتی با طول‌های متغیر را آن هم در ابتدای فایل فراهم می‌آورد. با استفاده از این استاندارد، اطلاعات ID3v1 هنوز برای حفظ سازگاری با پخش‌کننده‌های قدیمی در انتهای فایل حفظ می‌شدند. به کمک این استاندارد جدید، متادیتا می‌توانست حجمی تا حداکثر ۲۵۶ مگابایت داشته باشد! در این استاندارد هر گروه از اطلاعات در یک چهارچوب یا فریم (Frame) نگه‌داری می‌شود و هر فریم یک معرف یا Identifier دارد. در نسخه فعلی (۲/۴) این استاندارد، طول این معرف چهار کاراکتر است.

import os , sys
from os.path import join , getsize , exists
from mutagen.mp3 import MP3
import apsw
def MakeDatabase():
pass
def S2HMS(t):
pass
def WalkThePath(musicpath):
pass
def error(message):
pass
def main():
pass
def usage():
pass
if __name__ == ‘__main__’:
main()

فهرست ۱-  چهارچوب اصلی برنامه

موتاژن 

پیش‌تر برای کار با این متادیتاها، باید فایل را به‌صورت باینری باز‌می‌کردیم و در آن‌ اطلاعات موردنظر را جست‌وجو می‌کردیم. این کار اگرچه ممکن و ساده بود، اما به زمان و کدنویسی بسیاری نیاز داشت. اما اکنون دیگر می‌توانیم از کتابخانه‌های متعددی که برای این کار تهیه شده‌اند، استفاده کنیم. ما از کتابخانه‌ای به نام موتاژن (Mutagen) در این پروژه استفاده خواهیم کرد. برای ادامه کار در اوبونتو در مدیر بسته Synaptic موتاژن را جست‌وجو کرده و آن را نصب کنید. اگر از سیستم‌های ویندوزی برای کدنویسی استفاده می‌کنید، می‌توانید این کتابخانه را از آدرس دریافت و نصب‌کنید. البته، موتاژن به غیر از فایل‌های mp3 قابلیت کار با فرمت‌های M4A ،Ogg Vorbis ، ASF و بسیاری فرمت‌های دیگر را هم دارد. در این پروژه علاوه بر موتاژن مانند دو قسمت قبل به کتابخانه apsw نیز برای کار با پایگاه‌های داده نیاز خواهیم داشت.

def usage():
message = (
‘====================================\n’
‘mCat finds all mp3 files in a folder\n’
‘and subfolders. Reads the ID3 tags and \n’
‘writes the information to a SQLite database.\n’
‘usage:\n’
‘\t %s <foldername>\n’
‘\t WHERE <foldername> is the path to the mp3 files.\n’
‘====================================\n’
) %sys.argv[0]
print type(sys.argv)
error(message)
sys.exit(1)
فهرست ۲-  کدهای مورد نیاز برای تکمیل تابع Usage

شروع

فایل جدیدی با نام mCat.py‌ ایجاد کنید و کدهای فهرست ۱ را که چهارچوب اصلی برنامه ما را می‌سازند، در آن وارد کنید. اگرچه این فایل در این وضعیت هیچ کاری انجام نمی‌دهد، اما با اجرای آن و در صورت عدم دریافت پیغام خطا می‌توانید مطمئن شوید که تمام کتابخانه‌های مورد نیاز را به درستی نصب‌کرده‌اید. 
در این فهرست ما اسکلت مربوط به توابع مورد نیاز را پیاده کرده‌ایم. تنها نکته عجیب شاید آخرین قسمت این کد یعنی خطوط ۱۷ و۱۸ باشد. هنگامی که یک کد به اجرا در می‌آید، چه به صورت مستقیم و چه با import شدن در سایر کدها، پایتون نامی را به آن نسبت می‌دهد و با آن همانند یک شیء رفتار می‌کند. زمانی که کد به تنهایی اجرا شود، نامی که به آن نسبت داده می‌شود __main__ است. با دستور if موجود در خط ۱۷ ما کنترل می‌کنیم که آیا این فایل به‌صورت مستقیم اجرا شده است یا خیر؟ اگر فایل به صورت مستقیم اجرا شده بود، تابع اصلی برنامه یعنی ()main اجرا خواهد شد. اما اگر فایل در یک کد دیگر import شده باشد، هیچ کدی به‌صورت مستقیم اجرا نخواهد شد و برنامه منتظر می‌ماند تا توابع موجود در آن توسط برنامه import کننده فراخوانده شود.

def main():
global connection
global cursor
if len(sys.argv) != 2:
usage()
else:
StartFolder = sys.argv[1]
if not exists(StartFolder):
print “Folder %s does not exist. Exiting.” %StartFolder
sys.exit(1)
else:
print “\nWorking on %s” %StartFolder
connection = apsw.Connection(“mCat.db3”)
cursor = connection.cursor()
MakeDataBase()
WalkThePath(StartFolder)
cursor.close()
connection.close()
print “\nFinished.”
فهرست ۳-  کدهای مورد نیاز برای تکمیل تابع main

def MakeDataBase():

    sql = ‘CREATE TABLE IF NOT EXISTS mp3 (pkID INTEGER PRIMARY KEY,’

    sql = sql + ‘ title TEXT, artist TEXT, album TEXT, bitrate TEXT, ‘

    sql = sql + ‘genre TEXT, playtime TEXT, track INTEGER, year TEXT,’

    sql = sql + ‘ filesize TEXT, path TEXT, filename TEXT);’

    cursor.execute(sql)

فهرست ۴-  کدهای مورد نیاز برای تکمیل تابع (Make Data Base(1

تعریف توابع

حال به تکمیل این توابع می‌پردازیم. در ابتدا به سراغ تابع ()usage می‌رویم. این تابع نحوه کار برنامه ما را برای کاربر توضیح خواهد داد. همچنین با اعلام بروز خطا اجرای برنامه را متوقف خواهد کرد. کدهای این تابع را در فهرست ۲ مشاهده می‌کنید.
در این کدها که باید جایگزین خطوط ۱۵ و‌۱۶ فایل اصلی (فهرست ۱) شوند، ابتدا رشته‌ای با نام message‌ در خطوط ۲ تا ۱۱ تعریف شده است. دو نکته کوچک در تعریف این متغیر وجود دارد. نخست این‌که اگر تعدادی رشته را بدون هیچ عملگری پشت سر‌هم ردیف کنیم، پایتون آن‌ها را به ترتیب به هم افزوده و یک رشته طولانی‌تر به‌وجود خواهد آورد؛ دوم این‌که در خط ۸ ما با s% جایی را برای درج یک رشته خالی گذاشته‌ایم. این جای خالی در خط ۱۲ و از طریق [sys.argv[0 % با نام فایل حاوی برنامه پر شده است. با import کردن ماجول sys ما به متغیری به نام argv دسترسی خواهیم داشت. این متغیر که از جنس لیست است، حاوی کل آرگومان‌هایی است که در هنگام اجرای برنامه از طریق خط فرمان وارد‌شده‌اند. برای نمونه، اگر برای اجرای فایل mCat در خط فرمان از دستور زیر استفاده شود:

python mCat.py /usr/Music Ali 1234

 مقدار [‘mCat.py’ , ‘/usr/Music’ , ‘Ali’ , ‘۱۲۳۴’]  در متغیر argv ذخیره خواهد داشت. در این متغیر آرگومان اول یا [argv[0همواره نام فایل اجرا شده خواهد بود. 
در خط ۱۳ ما تابع error را برای اطلاع‌دادن به کاربر فراخوانده‌ایم و پس از آن در خط ۱۴ با استفاده از (sys.exit(1 از برنامه خارج شده‌ایم. تابع exit از ماجول sys برای پایان بخشیدن به اجرای برنامه‌ها به کار می‌رود و در صورتی که مقدار ارسال شده به آن ۰ باشد، به سیستم اعلام می‌کند که اجرا با موفقیت به پایان رسیده است. در غیر این صورت مشخص خواهد شد که اجرای برنامه به‌واسطه خطا متوقف شده است.
حال نوبت به تعریف تابع error می‌رسد. برای تکمیل این تابع عبارت زیر را جایگزین کلمه pass در خط ۱۲ فهرست ۱ کنید.

print >> sys.stderr , message

در این دستور print، ما از قابلیت تغییر مسیر خروجی‌ استفاده‌ کرده‌ایم و پیغام را به خروجی استاندارد تعریف شده برای پیغام‌های خطا هدایت‌ کرده‌ایم. توضیح ضروری این‌که در سیستم‌عامل به‌صورت استاندارد، خروجی‌هایی برای چاپ اطلاعات معمول، اطلاعات مربوط به خطاها و ورودی اطلاعات کاربر در نظر گرفته می‌شود که به ترتیب stdout ، stderr و stdin نامیده می‌شوند. زمانی که شما از دستور print به‌صورت عادی استفاده می‌کنید، اطلاعات شما به‌صورت خودکار به stdout منتقل‌می‌شود که در پایتون این خروجی روی ترمینال‌تعریف شده است. خروجی stderr نیز به‌صورت پیش‌فرض روی همان ترمینال است، اما می‌توان آن را به محل‌های دیگری (مثلاً یک فایل متنی برای ذخیره کل پیغام‌های خطا) نیز هدایت کرد. از این خروجی‌ها و ورودی‌های متفاوت می‌توان برای تهیه logهای دقیق و کامل از اجرای نرم‌افزار استفاده کرد. 

اکنون باید به سراغ تابع اصلی یا main برویم. این تابع که کدهای آن را در فهرست ۳ مشاهده می‌کنید، ابتدا اتصال یا connection و مکان‌نما یا cursor مورد نیاز را برای کار با پایگاه داده تعریف کرده و پس از آن با کنترل آرگومان‌هایی که کاربر هنگام اجرای برنامه وارد کرده و در صورتی که آرگومان‌ها درست باشند،‌ اعمال اصلی برنامه را به انجام می‌رساند.
در اینجا همانند دو شماره پیشین، متغیرهای عمومی connection و cursor‌ را برای کار با پایگاه داده تعریف کرده‌ایم. پس از آن پارامترهایی را که کاربر در خط فرمان وارد کرده است، کنترل کرده‌ایم. ما ورودی کاربر را برای یافتن ۲ پارامتر کنترل می‌کنیم که نخستین مورد، نام برنامه اجرا‌شده و دومی آدرس پوشه موردنظر است. به خاطر داشته باشید که اگر آدرس شما حاوی کاراکتر فضای خالی (space) باشد، به عنوان دو پارامتر جدا در نظر گرفته شده و باعث بروز خطا می‌شود. در این حالت باید آدرس را در علامت‌های کوتیشن قرار دهید. اگر کاربر آدرس پوشه‌ای را وارد نکرده یا بیش از یک آدرس را وارد کرده باشد، با پیغام خطا روبه‌رو خواهد شد. اگر ورودی کاربر درست باشد، ابتدا در خط ۹ کنترل می‌کنیم که آیا چنین پوشه‌ای موجود است یا خیر. تابع exists() که از ماجول os آورده شده است، با گرفتن یک آدرس در سیستم فایلی کامپیوتر وجود یا عدم‌وجود آن را کنترل می‌کند.

پس از آن و در خط ۱۶ تابع ساخت پایگاه‌داده (MakeDataBase) فراخوانده شده است. این تابع که در فهرست ۴ آورده شده، درصورت عدم وجود جدول mp3  در فایلmCat.db3 آن را بامشخصات مورد نظر ایجاد می‌کند. پس از آن با فراخوانی تابع ()WalkThePath کل پوشه‌ داده شده بررسی و فایل‌های mp3 آن شناسایی شده و اطلاعات به پایگاه داده منتقل می‌شود. پس از آن هر دو شیء connection و cursor بسته شده‌اند. 

در این تابع ما ابتدا سه شمارنده برای ردگیری تعداد خطاها، پوشه‌ها و فایل‌ها ایجاد کرده‌ایم. پس از آن برای نگه‌داری سوابق خطاهای احتمالی، فایلی با نام errors.log ایجاد شده است. پس از آن به کمک تابعی که ماجول os در اختیار ما قرار می‌دهد، به بررسی پوشه‌ مورد نظر پرداخته‌ایم. سیستم کار تابع ()walk به این ترتیب است که کار را از پوشه‌ داده شده توسط کاربر شروع کرده و به تمام پوشه‌ها و زیرپوشه‌های موجود در آن به ترتیب وارد شده و این روند را برای هر یک از زیرپوشه‌ها نیز تکرار می‌کند. در هرکدام از زیرپوشه‌ها، ما به دنبال فایل‌هایی گشته‌ایم که پسوندشان mp3 باشد. پس از آن به سراغ هریک از فایل‌های یافت شده رفته‌ایم و ابتدا متغیرهای محلی مربوط به آن را از محتوای قبلی پاک کرده‌ایم. پس از آن از تابع ()join ماجول os.path استفاده کرده‌ایم و آدرس کامل فایل را برای موتاژن آماده کرده وآن را به عنوان آرگومان تابع ()MP3 موتاژن مورد استفاده قرار می‌دهیم تا وهله‌ای از شیء audio را برای ما ایجاد کند. پس از آن کل برچسب‌های ID3 آن را خوانده و برچسب‌های موردنظرمان را جدا کرده و در متغیرهای موقتی ذخیره می‌کنیم. آن‌گاه از این متغیرها برای ساختن دستور SQL و وارد کردن اطلاعات در پایگاه داده استفاده می‌کنیم. تنها نکته قابل توجه شاید فرم دستور SQL باشد. در اینجا نیز ما با فرمتی شبیه %s در دستور print، محل مقادیر را با ؟ مشخص کرده‌ایم و بعدتر هنگام اجرای دستور SQL این متغیرها را در محل موردنظر جایگذاری می‌کنیم. 

در انتها در قسمت کنترل خطاها با نوع دیگری از قالب‌بندی رشته‌ها و جایگذاری مقادیر مواجه می‌شوید که شاید کمی عجیب باشد. این syntax برنامه‌نویسی یکی از اجزای اجباری سری ۳.x پایتون است. در این شیوه مقادیر {۰} و {۱} . . . با مقادیر متناظر در پرانتز format جایگزین می‌شوند.
کدهای مربوط به تابع MakeDataBase را در فهرست ۴ مشاهده می‌کنید. در اینجا با توجه به نکته‌هایی که در دو شماره قبل درباره ایجاد پایگاه‌های‌داده‌گفتیم، نباید در درک روند انجام کار این تابع مشکلی وجود داشته باشد. در این مورد هم به سادگی یک دستور SQL برای ساخت یک جدول با فیلدهایی نظیر نام آلبوم، نام هنرمند، ژانر موسیقی و… ساخته و اجرا شده است.
 نکته مهمی که باید به آن توجه کنید این است که شما باید پیش از اجرای برنامه، فایل پایگاه داده را به‌شخصه ساخته و در پوشه‌ برنامه قرار دهید. کدهای این فهرست را جایگزین خطوط ۵ و ۶ فهرست ۱ کنید. البته می‌توانید به دلخواه خود کدهایی را به این تابع و تابع ()main   بیافزایید تا آدرس محل ذخیره پایگاه داده یا نام آن نیز از کاربر پرسیده شود و فایل موردنظر نیز درست همزمان با اجرای برنامه ایجاد شود.

def S2HMS(t):
    if t > 3600:
        h = int(t/3600)
        r = t-(h*3600)
        m = int(r / 60)
        s = int(r-(m*60))
        return ‘%d:%02d:%02d’.format(h,m,s)
    else:
        m = int(t / 60)
        s = int(t-(m*60))
        return ‘%d:%02d’.format(m,s)

فهرست ۵-  کدهای مورد نیاز برای تکمیل تابع S2HMS

در نهایت، به بررسی تابع S2HMS می‌پردازیم. این تابع که کدهای آن را در فهرست ۵ مشاهده می‌کنید، مدت هر آهنگ را که توسط موتاژن به صورت یک عدد اعشاری برگردانده می‌شود به فرمت ساعت:دقیقه:‌ثانیه تبدیل می‌کند. به نحوه مرتب کردن خروجی تابع در دستورات return در خطوط ۷ و‌۱۱ توجه کنید. با عبارت %۰۲dما از پایتون می‌خواهیم که عدد جایگزین را حتی اگر تک رقمی بود، دو رقمی منظور کند و به جای رقم نخست آن ۰ قرار دهد.

استفاده

با تکمیل آخرین تابع دیگر زمان استفاده از برنامه فرا رسیده است. حال می‌توانید با دستور زیر برنامه را اجرا کنید: 

python mCat.py <folder>

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

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

بیشتر بدانید ...

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

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

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

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

import apsw
import string
class CookBook:
def __init__(self):
pass
def All(self):
pass
def Search(self):
pass
def Show(self,which):
pass
def Add(self):
pass
def Delete(self,which):
pass
def Menu():
ckb= CookBook()
loop=True
while loop:
print “********************”
print “* Recipe Database *”
print “********************”
print “ ۱-Show all”
print “ ۲-Search for a recipe”
print “ ۳-Show a recipe”
print “ ۴-Add a recipe”
print “ ۵-Delete a recipe”
print “ ۰-Exit”
print “********************”
response= raw_input(“ Enter your selection: “)
if response == ‘۱’:
pass
elif response == ‘۲’:
pass
elif response == ‘۳’:
pass
elif response == ‘۴’:
pass
elif response == ‘۵’:
pass
elif response == ‘۰’:
print “\n\tGoodbye”
loop=False
else:
print “\nUnrecognized command. Try again.\n\n”
Menu()
فهرست ۱- چهارچوب کلی برنامه Cook Book

def __init__(self):
global connection
global cursor
self.totalCount=0
connection = apsw.Connection(“cookbook1.db3”)
cursor=connection.cursor()

فهرست ۲- کدهای تکمیل تابع راه‌اندازی کلاس Cook Book

def All(self):
print “\n\nNumber \tName \t\tServes \t\tSource”
print “-”*۵۵
sql = “SELECT * FROM Recipes”
cntr=0
for x in cursor.execute(sql):
cntr += 1
print “%s \t%s \t%s \t\t%s” %(x[0],x[1],x[2],x[3])
print “-”*۵۵
self.totalCount = cntr
print “Total number of items: %s” %cntr

فهرست ۳- کدهای تابع نمایش تمام موارد موجود در پایگاه داده

همچنین برای نگه‌داری روال‌های مربوط به پایگاه داده یک کلاس تعریف خواهیم کرد. چون این کد بسیار طولانی خواهد بود ما در ابتدا چهارچوب کلی آن را نوشته و سپس قسمت‌های مختلف را به تدریج به آن می‌افزاییم. برای شروع کار این چهارچوب را که در فهرست ۱ آورده شده، وارد کرده و آن را با نام CookBook.py ذخیره کنید.
همان‌طور که در این کد مشاهده می‌کنید، کلیت یک کلاس و تابعی برای ترسیم یک منو روی صفحه نمایش تعریف شده است. ما به تدریج این چهارچوب را برای رسیدن به برنامه نهایی تکمیل خواهیم کرد. اگر در وضعیت فعلی برنامه را اجرا کنید، شکلی همانند شکل ۱ را مشاهده خواهید کرد. در این حالت، تنها کلید ۰ برای خروج از برنامه کار خواهد کرد. اکنون به نوشتن روتین راه‌اندازی کلاس و سایر روتین‌های مربوط به اعمال نمایش‌کل اطلاعات، جست‌وجو، نمایش یک مورد، افزودن و حذف موارد پایگاه داده خواهیم پرداخت. از میان این روتین‌ها، روتین‌های نمایش کل اطلاعات، جست‌وجو و افزودن آیتم به هیچ آرگومان ورودی نیاز ندارند (البته همان‌طور که از بحث‌های کلاس‌ها و اشیاء به یاد دارید، به جزء آرگومان اجباری self). اما روتین‌های نمایش و حذف به پارامتری نیاز دارند که در این کدها آن را which نامیده‌ایم و این پارامتر تعیین می‌کند کدام آیتم باید نمایش داده‌شده یا حذف شود.

راه‌اندازی

در ابتدا باید روتین راه‌اندازی کلاس یا __init__ را کامل کنیم. کدهای مورد نیاز برای این روتین در فهرست ۲ آورده شده است. این کد را جایگزین خطوط ۵ و۶ فهرست ۱ کنید.
در اینجا ابتدا دو متغیر جهانی تعریف‌کرده‌ایم. این متغیرها به رغم این‌که در تعریف یک تابع آورده شده‌اند، به‌واسطه کلمه global، در تمام برنامه قابل استفاده‌خواهند بود. این کار را به این دلیل انجام می‌دهیم که پایگاه داده و مکان‌نمای مربوط به آن در تمام روتین‌های برنامه قابل دسترس باشند. برای کار با پایگاه داده‌ای که در قسمت قبل ایجاد کردید، باید این برنامه و فایل پایگاه‌داده را در یک پوشه و در کنار هم قرار دهید و در خط ۵، نام فایل پایگاه داده خود را جایگزین cookbook1.db3 کنید.

نمایش همه موارد

برای نمایش همه موارد از کد فهرست‌۳ استفاده خواهیم کرد. این کد را در کلاس CookBook فهرست‌۱ جایگزین خطوط ۷ و ۸ کنید. همین‌طور باید از خط ۳۴ فهرست ۳ کلمه pass را حذف و عبارت زیر را جایگزین آن کنید:

ckb.All()
temp = raw_input(“Press any key\ to continue…”)

در این تابع ما از cursor ساخته شده در روتین __init__ استفاده کرده‌ایم و تمام محتویات جدول Recipes را فراخوانی کرده‌ایم، سپس در یک حلقه تمام مقادیر را با قالب‌بندی‌های استفاده شده در دستور print (که قبلاً با آن آشنا شده‌اید) به‌صورت منظم چاپ کرده‌ایم. به یاد دارید که apsw مقادیر برگشتی جدول را به صورت توپل به ما باز‌می‌گرداند، به همین دلیل، ما از [x[0 و [x[1 و… استفاده کرده‌ایم. در انتهای این روتین و در خط ‌۱۱ تعداد کل آیتم‌های موجود در جدول Recipes را نیز اعلام کرده‌ایم.

جست‌وجو

برای بخش جست‌وجو، به دلیل کمبود فضا، تنها بخش جست‌وجوی نام دستورالعمل را پیاده‌سازی کرده‌ایم و جست‌وجو بر اساس محتویات و تعداد نفراتی را که با یک دستورالعمل سیر می‌شوند، به عهده شما گذاشته‌ایم. کدهای این روتین در فهرست ۴ آورده شده است. این کدها را جایگزین خطوط ۹ و ۱۰ فهرست کنید.
در این کد و در خط ۵ عبارت موردنظر از کاربر پرسیده شده و در خط ۶ با تعریف یک دستور sql عملیات جست‌وجو را روی پایگاه داده انجام‌داده‌ایم. شاید عبارت %%%s%% در این خط کد عجیب به نظربرسد. در زبان sql برای تعریف مشابهت از کلمه کلیدی like و فرم %term% استفاده می‌شود. در این حالت کلماتی که مشابه term باشند، برگردانده می‌شوند. اما چون در زبان پایتون از علامت % برای فرمت‌کردن رشته‌ها استفاده می‌شود، یک رشته نمی‌تواند به طور مستقیم شامل علامت % باشد. برای درج این علامت در یک رشته باید دوبار آن را پشت سر هم (%%) به‌کار ببریم. به این ترتیب، در خط ۷ جفت علامت‌های سمت راست و چپ به تک علامت‌های % و قسمت وسط (%s) نیز توسط عبارت term جایگزین‌می‌شود. در انتهای این روتین و در خط ۹ از تابع ()Show که آن را در قسمت بعد تعریف می‌کنیم، برای نمایش آیتم‌های مورد نظر استفاده کرده‌ایم. برای فعال شدن این بخش باید کلمه pass درخط ۳۶ فهرست ۱ با عبارت () ckb.Search جایگزین شود.

def Search(self):
print
print “=”*۵۵
print “Searching in recipes by name”
term = raw_input(“Enter name of the recipe: “)
sql = “SELECT pkID , name FROM Recipes WHERE name like\ ‘%%%s%%’” %term
for x in cursor.execute(sql):
self.Show(x[0])

فهرست ۴- کدهای تابع جست‌وجو در پایگاه داده براساس نام دستورالعمل

def Show(self,which):
sql = “SELECT * FROM Recipes WHERE pkID = %s” %str(which)
print “\n”
print “=”*۵۵
for x in cursor.execute(sql):
print “Title: %s \t Serves: %s \t Source: %s”\ %(x[1],x[2],x[3])

sql = “SELECT * FROM Ingredients WHERE pkID = %s” %str(which)
print “\nIngredients:”
for x in cursor.execute(sql):
print x[1]

sql = “SELECT * FROM Instructions WHERE pkID = %s” %str(which)
print “\nInstructions:”
for x in cursor.execute(sql):
print x[1]
print “=”*۵۵
print “\n”

فهرست ۵- کدهای تابع مورد نیاز برای نمایش یک آیتم از پایگاه داده

نمایش یک مورد

برای عملیاتی کردن این بخش، ابتدا با فراخوانی تابع ()All تمام موارد را به کاربر نشان خواهیم داد و از او خواهیم خواست که آیتم مورد نظر را انتخاب کند.برای این کار کلمه pass در خط ۳۸ فهرست ۱ را با کد‌های زیر جایگزین کنید:

ckb.All()
temp = raw_input(“What to show:”)
ckb.Show(temp)

پس از آن با فرستادن آیتم انتخاب شده به عنوان آرگومان which به روتین ()Show آن آیتم را به نمایش خواهیم گذاشت. کدهای مربوط به این روتین در فهرست ۵ آورده شده است. این کدها را جایگزین خطوط ۱۱ و ۱۲ فهرست ۱ کنید. در این کد، در خط ۲ دستور sql مورد نیاز را برای انتخاب آیتمی که شماره ردیف (pkID) آن با آرگومان which به تابع اعلام شده است، تعریف کرده‌ایم. پس از آن با تعریف دو دستور sql دیگر مقادیر متناظر را از جدول‌های Ingredients و Instructions استخراج کرده و با دستور print چاپ کرده‌ایم.

def Add(self):
ings = ““
lastid = 0
recipename=raw_input(‘Enter Recipe Title -> ‘)
recipesource=raw_input(“Enter Recipe Source -> “)
recipeserves=raw_input(“Enter number of servings -> “)
while True:
ing = raw_input(‘Enter Ingredient (“۰” to exit) -> ‘)
if ing != ‘۰’:
ings = ings + ing + “, “
else:
break
instructions = raw_input(‘Enter Instructions -> ‘)
print ‘=’*۵۵
print “Here›s what we have so far”
print “Title: %s” % recipename
print “Source: %s” % recipesource
print “Serves: %s” % recipeserves
print “Ingredients: %s” % ings
print “Instructions: %s” % instructions
print ‘=’*۵۵
resp = raw_input(“OK to save? (Y/n) -> “)
if resp.upper() != ‘N’:
#connection=apsw.Connection(“cookbook1.db3”)
#cursor=connection.cursor()
# Write the Recipe Record
sql = ‘INSERT INTO Recipes (name,serves,source) VALUES\ (“%s”,”%s”,”%s”)’ %(recipename,recipeserves,recipesource)
cursor.execute(sql)
# Get the new Recipe pkID
sql = “SELECT last_insert_rowid()”
cursor.execute(sql)
for x in cursor.execute(sql):
lastid = x[0]
print “last id = %s” % lastid
# Write the Instruction Record
sql = ‘INSERT INTO Ingredients (recipeID,ingredients)\ VALUES (%s,”%s”)’ % (lastid,x)
cursor.execute(sql)
# Write the Ingredients records
sql = ‘INSERT INTO Instructions (recipeID,instructions)\ VALUES( %s,»%s»)’ %(lastid,instructions)
cursor.execute(sql)
# Prompt the user that we are done
print ‘Done\n’
else:
print ‘Save aborted\n’

فهرست ۶- کدهای تابع افزودن آیتم جدید به پایگاه داده

افزودن

روتین مربوط به افزودن موارد، طولانی‌ترین روتین این مجموعه است که آن را در فهرست ۶ مشاهده می‌کنید، آن را جایگزین خطوط ۱۳ و۱۴ فهرست ۱ کنید. شروع این روتین و خط‌های ۲ تا ۶ متغیرهای ابتدایی مورد نیاز نظیر نام دستورالعمل، تعداد نفرات و… را تعریف و مقداردهی می‌کند. تنها موردی که شاید به توضیح نیاز داشته باشد، دریافت مواد لازم است که در یک حلقه while انجام شده است و هر ورودی کاربر به‌صورت رشته‌ای با جداکننده کاما (،) به انتهای متغیر ings افزوده شده است. این روند تا زمانی که کاربر۰ را وارد کند، ادامه می‌یابد. پس از آن در خطوط ۱۴ تا ۲۱ کل اطلاعات یک بار دیگر برای کاربر نمایش داده می‌شود تا از صحت آن اطمینان حاصل شود.
پس از گرفتن تأیید کاربر، در خطوط ۲۷ تا ۲۹ با تعریف دستورالعمل مورد نیاز، موارد ابتدایی را در جدول Recipes ذخیره می‌کنیم. در خطوط ۳۱ و ۳۲ همان‌گونه که در قسمت قبل دیده‌اید، شماره آخرین رکورد افزوده شده به جدول را استخراج کرده‌ایم. از این رکورد برای مرتبط کردن داده‌های جدول‌های Ingredients و Instructions به مقادیر وارد شده در جدول Recipes استفاده کرده‌ایم. ذخیره داده در دو جدول Ingredients و Instructions به ترتیب در خطوط ۳۶ تا ۳۹ و۴۰ تا ۴۳ انجام شده است. در نهایت، اتمام عملیات ذخیره‌سازی با یک پیغام به کاربر اطلاع داده شده است.فراموش نکنیدکه برای فعال شدن این بخش باید کلمه pass در خط ۴۰ فهرست ۱ را با ()ckb.Add جایگزین کنید.

حذف

در نهایت به روتین حذف موارد می‌رسیم. همان‌گونه که حدس می‌زنید، در این روتین نیز ابتدا با فراخوانی()ckb.All همه موارد به کاربر نشان داده شده و در نهایت از او خواسته می‌شود تا آیتم مورد نظر را برای حذف‌کردن انتخاب کند. این روتین در فهرست ۶ آورده شده است.آن را جایگزین خطوط ۱۵ و ۱۶ فهرست ۱ کنید و برای کار کردن این کد باید کلمه pass در خط۴۲ فهرست‌۱ با عبارت زیر جایگزین شود:

ckb.All()
temp = raw_input(“What to delete:”)
ckb.Delete(temp)

در این کد هم با استفاده از آرگومان which که شماره انحصاری آیتم را نشان می‌دهد، دستورات sql مورد نیاز را برای حذف آیتم‌ها از جدول‌های Recipes، Ingredients و Instructions تعریف و اجرا کرده‌ایم.دقت کنید که برای ساده‌تر‌شدن کار، ما از بسیاری از روتین‌های کنترل ورودی کاربر، مرتب‌سازی خروجی و بسیاری قابلیت‌های دیگر که می‌توانست چنین برنامه‌ای را کامل‌تر‌کند، صرف‌نظر‌کرده‌ایم. اگرچه وجود این قابلیت‌ها در غالب نرم‌افزارهای تجاری و حرفه‌ای الزامی است، اما پیاده‌سازی آن‌ها بسیار ساده و بدون مشکل خواهد بود. برای نمونه، در هنگام نمایش یا حذف یک مورد بهتر بود که ما شماره آیتم وارد‌شده توسط کاربر را بررسی کنیم تا در محدوده صحیحی قرار داشته باشد یا مثلاً کاربر به جای شماره از حروف استفاده نکرده باشد. که چنین مواردی با روال‌های معمول if قابل پیاده‌سازی است.

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

بیشتر بدانید ...

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

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

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

برنامه‌نویسی در دنیای امروز که لبریز از داده‌های‌متفاوتی است که روز به روز بر تنوع و حجم آن‌ها افزوده می‌شود، بدون آشنایی با پایگاه‌های داده و استفاده از قابلیت‌های آن‌ها غیرممکن خواهد بود. در این قسمت و قسمت بعدی مجموعه مقاله‌های برنامه‌نویسی پایتون، به معرفی نحوه کار با پایگاه‌های داده از طریق کدهای پایتون خواهیم پرداخت. در بخش کنونی بیشتر به معرفی دستور زبان و نحوه کار پایگاه‌های داده SQL خواهیم پرداخت و در بخش بعدی نحوه استفاده از این زبان را در کدهای پایتون فرا خواهیم گرفت. در این دو قسمت ما از پایگاه داده SQLite و کتابخانه توابع python-apsw در محیط لینوکس (اوبونتو) استفاده خواهیم کرد.

یک داستان

روزی روزگاری بود که دنیا به‌وسیله کاغذ اداره‌می‌شد. کاغذ، کاغذ و باز هم کاغذ. انسان‌ها مجبور بودند، به فکر ایجاد مکان‌های مناسبی برای نگه‌داری کاغذها باشند. این مکان‌ها را بایگانی می‌نامیدند و بایگانی کسب‌وکارهای بزرگ برای ذخیره تمام کاغذها، معمولاً چندین اتاق را اشغال می‌کرد. در هر بایگانی قفسه‌ها و کمدهایی وجود داشت که آن‌ها نیز به نوبه خود پر از پوشه‌های مختلف بودند. هر یک از این پوشه‌ها کاغذهای مربوط به یک موضوع خاص را نگه‌داری می‌کردند. اما پس از مدتی، ظرفیت همه آن‌ها به اتمام می‌رسید یا در اثر مرور زمان و باز و بسته شدن زیاد فرسوده شده و ازهم می‌پاشیدند. استفاده درست از این سیستم بایگانی نیازمند مدارک دانشگاهی بود و گاه یافتن کل پرونده‌ها و کاغذهای مربوط به یک موضوع به چندین روز زمان نیاز داشت. کسب‌وکارها و سازمان‌ها از این وضعیت در عذاب بودند و آن دوران، دورانی تاریک در تاریخ بشریت محسوب می‌شد!
ناگهان روزی، فرشته‌ای دوست‌داشتنی با بال‌هایی طلایی از بلندای کوهی ظاهر شد. نام او «سی‌کوئل» بود. فرشته ادعا کرد، می‌تواند مشکل کلنجار رفتن با این قفسه‌ها و پوشه‌ها را حل‌کند، البته، به شرطی که مردم به او و کامپیوترها اعتماد کنند. او این جادوی جدید را «پایگاه داده» نامید و گفت که پایگاه داده می‌تواند جایگزین تمام آن سیستم‌های بایگانی شود. 
اما استفاده از این جادوی جدید، پیش‌نیازهایی داشت. مردم باید زبان جدیدی را می‌آموختند. البته، این زبان بسیار شبیه زبان عادی مردم بود و بیشتر به نوع متفاوتی از جمله‌بندی نیاز داشت و افراد باید پیش از به کار بردن این جمله‌های جادویی به دقت فکر می‌کردند. آن‌ها باید ابتدا طرحی از ارتباط میان داده‌ها و اطلاعات خود ترسیم می‌کردند. برخی از مردم حرف‌های او را پذیرفتند و زندگی برای آن‌ها بسیار لذت‌بخش و ساده شد و دیگرانی که او را به سخره گرفتند، در میان کوه‌های کاغذ مدفون شدند. پایان!

شروع

اگرچه این داستان چندان واقعی نبود، اما استفاده از پایگاه‌های داده و SQL (بخوانید سی‌کوئل) زندگی ما را ساده‌تر خواهد کرد. پایگاه‌های داده همانند قفسه‌های بایگانی داستان بالا هستند. در این پایگاه‌های داده، جدول‌ها نقش پوشه‌ها را بازی می‌کنند و هر رکورد یا سطر این جدول‌ها در واقع حکم برگه‌های کاغذ در بایگانی‌های سنتی را دارند. هر تکه از اطلاعات یک فیلد نامیده‌می‌شود. برای کار با این سیستم ما از SQL (سرنام Structured Query language) یا «زبان پرس‌وجوی ساخت‌یافته» استفاده‌می‌کنیم. اگرچه این زبان از ابتدا برای ساده‌کردن کار با پایگاه‌های داده طراحی‌شده است، اما عبارت‌های مورد استفاده در آن می‌توانند بسیار پیچیده و طولانی شوند.

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

ما می‌توانستیم کل پایگاه داده را با یک جدول نیز سروسامان دهیم، اما چنین جدولی بسیار بزرگ می‌شد و پر از اطلاعات تکراری می‌شد. جدول‌های موردنظر ما شبیه شکل ۱ خواهند بود. 
همه این جدول‌ها یک فیلد به نام pkID دارند که همان کلید اولیه منحصر‌به‌فرد است. وجود این فیلد بسیار مهم است، زیرا باعث می‌شود جدول‌های ما اطلاعات کاملاً تکراری نداشته باشند وهمچنین ارتباط بین آن‌ها را فراهم می‌کند. این فیلد به‌صورت خودکار توسط موتور SQLite پر خواهد شد. در جدول Recipes ما از این فیلد برای استخراج اطلاعات مناسب از جدول‌های Instructions و Ingredients استفاده خواهیم کرد. 

جدول طرز تهیه (Instructions) به نسبت ساده است و حاوی متن‌های طولانی و طرز تهیه غذاهای مختلف است. اما جدول مواد لازم (Ingredients) کمی پیچیده‌تر است، زیرا که به همراه نام ماده لازم مقدار آن‌ها نیز باید ذخیره شود.

برنامه‌های مورد نیاز

ابتدا مطمئن شوید، SQLite و APSW را نصب کرده‌اید. به خاطر داشته باشید، مخازن Canonical Partners و Independent باید در تنظیمات اوبونتو فعال شده باشند. در این‌صورت برای نصب برنامه‌های  مورد نیاز در اوبونتو کافی است دستور زیر را در خط فرمان وارد کنید:

sudo apt-get install sqlite , python-apsw

مزیت SQLite این است که این موتور پایگاه داده برای اجرا به سرورهای جداگانه نیاز ندارد و به همین دلیل، برای برنامه‌های کوچک مناسب‌تر است. نکته مثبت دیگر این است که تعداد «انواع داده» یا Data Type‌های آن محدود و ساده است. این انواع عبارتند از Text (متن)، Numeric (عدد)، Blob (داده‌های دودویی) و Integer Primary Key  (کلیدهای اصلی که بعدها درباره آن‌ها توضیح خواهیم داد). مواد لازم، نام غذا و طرز تهیه همه داده‌هایی از نوع Text خواهند بود. اما Blobها نوعی از داده است که می‌تواند شامل هر داده دیجیتالی نظیر عکس و… باشد که ما در این مثال با این نوع کاری نخواهیم داشت. موتور SQLite به‌صورت خودکار یک عدد صحیح منحصر به فرد را به انواع داده Integer Primary Key نسبت خواهد داد. کتابخانه APSW (سرنام Another Python SQLite Wrapper) نیز روش‌هایی ساده برای ارتباط با SQLite را فراهم خواهد آورد.

کمی SQL

پیش از شروع کار باید اندکی درباره کار با زبان SQL بیشتر بدانیم. در این زبان برای دریافت یک رکورد (یک سطر جدول) از یک پایگاه داده از دستور SELECT استفاده می‌کنیم. قالب اجرای این دستور به شکل زیر است:

SELECT [what] FROM [table] WHERE [constrains]

در این قالب کلی، تمام کلماتی که با حروف بزرگ نوشته شده‌اند باید عیناً به همین فرم آورده شوند. عبارت‌های داخل کروشه به ترتیب تعیین‌کننده رکورد موردنظر (what)، جدولی یا جدول‌هایی که رکورد باید از آن‌ها استخراج شود (table) و شرایط انتخاب (constrains) هستند. مثلاً اگر بخواهیم همه فیلدهای جدول دستورالعمل‌ها را بدون هیچ شرطی استخراج کنیم، باید از دستوری به فرم زیر استفاده کنیم:

SELECT * FROM Recipes

و اگر بخواهیم رکوردی را تنها بر‌اساس شماره منحصربه‌فرد آن (مثلاً رکوردی با شماره ۲) استخراج کنیم، از عبارت زیر استفاده می‌کنیم:

SELECT * FROM Recipes WHERE pkID=2

یا به عنوان نمونه‌ای دیگر اگر بخواهیم از تمام دستورالعمل‌های موجود فقط نام غذا و مواد لازم را استخراج کنیم، باید از دستوری به فرم زیر استفاده کنیم:

SELECT name , instructions FROM Recipes

برای درج یا افزودن رکوردی تازه در یک جدول باید از دستور INSERT INTO استفاده کنیم. قالب کلی این دستور مانند زیر است:

INSERT INTO [table name] (field list) VALUES (values to insert)

به عنوان نمونه برای وارد‌کردن یک دستورالعمل جدید در جدول باید دستوری به فرم زیر را اجرا کرد:

INSERT INTO Recipes (name,servings,source) VALUES (“Tacos” , ۴ , “Greg”)

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

DELETE FROM [table] WHERE [constrains]

کدنویسی 

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

در خط ۱ ما ماجول apsw را import کرده‌ایم تا بتوانیم از توابع فراهم‌شده توسط آن استفاده کنیم. در خط ۳ یک اتصال یا کانکشن به پایگاه داده ساخته‌ایم. این کار باعث می‌شود، اگر پایگاه داده موجود باشد، برنامه آن را برای اجرای عملیات بعدی باز کند و در صورتی که چنین پایگاه داده‌ای موجود نباشد، apsw آن را تولید خواهد کرد. 
در مثال ما، چون این پایگاه داده وجود ندارد، apsw آن را در همان پوشه برنامه ایجاد خواهد کرد. پس از ایجاد پایگاه داده، ما به یک مکان‌نما (cursor) نیاز داریم. مکان‌نما شرایط و ابزار لازم را برای تعامل با پایگاه داده فراهم خواهد آورد. این مکان‌نما در خط ۴  ایجاد شده است. پس از آن نوبت به ایجاد جدول‌ها می‌رسد. 
برای ایجاد جدول دستورالعمل‌ها، در خط ۷ متغیری حاوی یک دستور SQL ایجاد کرده‌ایم و پس از آن در خط بعدی این دستور را اجرا کرده‌ایم. در خطوط بعدی سایر جدول‌ها را نیز به همین طریق ایجاد کرده‌ایم. پس از آن و در خطوط ۲۱ تا ۲۴ با دستور INSERT INTO تعدادی داده اولیه را در این جدول‌ وارد کرده‌ایم. 

import apsw
# Opening/Creating database
connection = apsw.Connection(“cookbook1.db3”)
cursor=connection.cursor()
 
# Creating tables
sql=’CREATE TABLE Recipes (pkID INTEGER PRIMARY\ KEY, name TEXT \
, serves TEXT, source TEXT)’
cursor.execute(sql)
sql=’CREATE TABLE Instructions (pkID INTEGER PRIMARY KEY, Instructions TEXT \
, recipeID NUMERIC)’
cursor.execute(sql)
sql=’CREATE TABLE Ingredients (pkID INTEGER PRIMARY KEY, ingredients TEXT \
, recipeID NUMERIC)’
cursor.execute(sql)
 
# Inserting sample data
sql=’INSERT INTO Recipes (name,serves,source) VALUES (“Spanish Rice” \
,۴,”Greg Walters”)’
cursor.execute(sql)
 
# Getting the last pkID
sql=’SELECT last_insert_rowid()’
cursor.execute(sql)
for x in cursor.execute(sql):
lastid=x[0]
print lastid
 
sql=’INSERT INTO Instructions\(recipeID,Instructions) VALUES \
(%s, “Brown hamburger. Stir in all other ingredi\ents. Bring to boil.\
Stir. Lower to simmer. Cover and cook for 20 min\utes or \
until all liquids absorbed.”)’ %lastid
cursor.execute(sql)
 
sql=’INSERT INTO Ingredients (recipeID , ingredients) VALUES \
(%s , “۱ cup parboiled Rice (uncooked)”)’ %lastid
cursor.execute(sql)
فهرست ۱- کدهای ساخت نخستین پایگاه داده

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

SELECT last_insert_rowid()

اما این عملیات ساده، در برنامه ما در خط‌های ۲۷ تا ۳۰ پیاده شده است. دلیل هم این است که ما مقادیر برگشتی جدول را از apsw دریافت می‌کنیم و apsw آن‌ها را به صورت توپل به ما باز می‌گرداند و ما باید عدد مورد نظر را از این توپل استخراج کنیم.  پس از به‌دست آوردن pkID آخرین رکورد وارد شده از آن برای درج مقادیر سایر جدول‌ها استفاده خواهیم کرد. 
تا اینجا ما پایگاه داده و اطلاعات اولیه آن را وارد کرده‌ایم. در قسمت بعدی، به معرفی نحوه کار با این پایگاه داده خواهیم پرداخت.

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

بیشتر بدانید ...

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

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

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

اگر سن شما به اندازه‌ای باشد که نخستین روزهای کامپیوترها را به یاد بیاورید، به یاد خواهید داشت که در آن دوران کامپیوترها اغلب مین‌فریم بودند و «ترمینال‌های گنگ» به عنوان دستگاه‌های ورودی و خروجی به آن‌ها متصل می‌شدند. شما می‌توانستید به هر تعداد ترمینال که می‌خواهید به یک مین‌فریم متصل کنید. مشکل این‌جا بود که ترمینال‌ها واقعاً گنگ بودند! در آن‌ها خبری از پنجره‌ها، رنگ و هیچ چیز دیگری نبود. تنها در بهترین حالت صفحه‌ای با ۲۴ سطر ۸۰ کاراکتری در اختیار شما قرار می‌گرفت. در نخستین روزهای DOS و CPM نیز اوضاع به همین منوال بود. زمانی که برنامه‌نویسان آن زمان روی صفحات زیبا و تجملی به‌ویژه برای ورود و خروج داده‌ها کار می‌کردند، از کاغذهای شطرنجی برای طراحی صفحه استفاده می‌کردند. هر مربع نشانه یک کاراکتر بود. اکنون نیز زمانی که شما با برنامه‌های پایتون در ترمینال کار می‌کنید (که بیشتر اوقات چنین خواهد بود) اوضاع به همان منوال است. اما هر مشکلی با پیش‌بینی و کسب آمادگی لازم قابل حل خواهد بود، پس کاغذهای شطرنجی‌تان را آماده کنید تا به سراغ نخستین برنامه Curses خودمان برویم.

کدهای فهرست ۱ را در ویرایشگر دلخواهتان وارد کرده، با نام Curse.py ذخیره و سپس اجرا کنید. خواهید دید که همانند شکل ۱ کادری در اطراف پنجره ترمینال ترسیم می‌شود و متن مورد نظر ما در سطر دوازدهم و از محل کاراکتر بیست و پنجم به نمایش در خواهد آمد. در خط ۱ ما کتابخانه curses را فراخوانده‌ایم. پس از آن و در خط ۲ شیء از نوع صفحات curses با نام myscreen ایجاد و برای استفاده آماده کرده‌ایم. این صفحه درواقع بوم نقاشی ما خواهد بود. پس از آن در خط‌۳ و با عبارت  (myscreen.border(0  کادری را در اطراف صفحه نمایش ترسیم کرده‌ایم. این کار الزامی نیست، اما ظاهر برنامه ما را زیباتر می‌کند. پس از آن و در خط ۴ با تابع ()addstr  و مشخص کردن مکان نقطه شروع متنی را به صفحه نمایش افزوده‌ایم. تابع ()addstr در واقع همانند دستور print عمل خواهد کرد. اما تا این لحظه هیچ‌کدام از اعمال انجام شده روی صفحه نمایش قابل مشاهده نخواهند بود

برای نمایش این تغییرات باید مانند خط ۶  از تابع ()Refresh استفاده کرد. پس از آن و در خط ۷ با تابع ()getch منتظر فشرده شدن یک کلید از سوی کاربر مانده‌ایم و در نهایت با تابع ()endwin صفحه نمایش را آزاد کرده‌ایم تا ترمینال ما به عملکرد عادی خود بازگردد. توجه داشته باشید که دستور endwin بسیار مهم است. اگر این تابع فراخوانده نشود، ترمینال شما دیگر قابل استفاده نخواهد بود، پس همواره مطمئن شوید که این تابع درست قبل از پایان برنامه شما فراخوانده شده است. نکته دیگری که به احتمال متوجه آن شده‌اید این است که کادر یا border ما حاشیه‌ای به عرض یک کاراکتر را اشغال خواهد کرد.

import curses
myscreen = curses.initscr()
myscreen.border(0)
myscreen.addstr(10,12,»This Is\
The Simple Test . . .»)
myscreen.refresh()
myscreen.getch()
curses.endwin()

فهرست ۱- نمونه ساده کار با کتابخانه curses

به یاد داشته  باشید شمارش سطرها و ستون‌های صفحه نیز همواره از صفر آغاز خواهد شد. به عبارت دیگر، بالاترین نقطه در سمت چپ صفحه مختصاتی برابر ۰,۰ خواهد داشت.
حال که با اصول کلی کار با curses آشنا شدیم، بیایید از این کتابخانه برای ایجاد پوسته ارتباطی یک برنامه فرضی دفتر تلفن استفاده کنیم. در این مثال ما عملاً از کدهای مربوط به منطق درونی برنامه که برای افزودن نام و شماره به دفتر تلفن، جست‌وجوی نام‌ها، حذف رکوردها و نحوه نگه‌داری و ذخیره‌سازی داده‌ها صرف‌نظر کرده و تنها روش پیاده‌سازی یک پوسته یا رابط کاربری ساده را با curses توضیح خواهیم داد. 

کدهای فهرست شماره ۲ را در ویرایشگر دلخواهتان وارد کرده و با نام PhonebookUI.py ذخیره و اجرا کنید. در این حالت با صفحه‌ای مشابه شکل ۲ مواجه خواهید شد که در واقع منوی اصلی برنامه دفتر تلفن را نمایش می‌دهد. در این مرحله با فشردن کلیدهای ۱، ۲ و ۳ می‌توانید به منوهای مربوط به هر بخش وارد شده و عملیات مورد نظر را انجام دهید یا با وارد کردن عدد ۰ از برنامه خارج شوید.
 کدهای فهرست ۲ از چهار بخش اساسی تشکیل شده است. در بخش نخست ما تنها import برنامه را برای استفاده از کتابخانه curses انجام داده‌ایم.

در بخش بعدی تابعی با نام MainMenu را تعریف کرده‌ایم. این تابع ابتدا در خط ۶ و با تابع ()erase صفحه نمایش (که قبلاً توسط curses تعریف شده است) را پاک می‌کند. حاشیه یا کادر در خط ۷ فعال می‌شود. پس از آن و با استفاده از چندین تابع ()addstr شکل منوی اصلی را روی صفحه نمایش ترسیم کرده‌ایم. در این بخش شما می‌توانید فرم کامل تابع ()addstr را مشاهده کنید. این تابع در حالت عادی ۴ آرگومان دریافت می‌کند. دو آرگومان نخست شماره سطر و ستون محل نوشته شدن متن هستند. آرگومان سوم، متن مورد نظر را تعریف می‌کند و در نهایت آرگومان چهارم رنگ متن را مشخص می‌کند. رنگ‌های مورد نظر برای استفاده در ()addstr به صورت جفت رنگ‌های پیش‌زمینه و پس‌زمینه هستند که در مورد نحوه تعریف آن‌ها کمی بعدتر توضیح خواهیم داد.

در بخش سوم تعریف تابع GetKey آورده شده است. ما از این تابع برای دریافت پاسخ کاربر و واکنش به آن استفاده می‌کنیم. در خط ۲۷ یک حلقه while تعریف شده است و تا زمانی که کاربر کلید ۰ را فشار ندهد، به کار خود ادامه خواهد داد. اگر کاربر کلید ۰ را بزند، این حلقه و در نتیجه اجرای تابع به پایان خواهد رسید و کنترل به بخش فراخواننده (در این مثال حلقه اصلی) بازگردانده می‌شود. همان‌طور که پیش‌تر هم گفتیم، در اینجا از پیاده‌سازی کامل برنامه صرف‌نظر کرده‌ایم و تنها محل‌هایی را که باید کدهای منطق برنامه آورده شوند (خط‌های ۳۴،۳۱ و ۳۷) مشخص کرده‌ایم. تنها نکته جدید در مورد تابع GetKey شاید استفاده از تابع ()ord باشد. تابع ()ord با دریافت یک رشته تک کاراکتری، عدد متناظر یونی‌کد آن را بازمی‌گرداند. استفاده از این تابع باعث می‌شود که برنامه بتواند فشرده شدن کلید ۱ را در همه آرایش‌های صفحه کلید (مثلاً فارسی یا عربی) درک کرده و به آن واکنش نشان دهد.بدنه اصلی بخش آخر کدهای ما است. در این بخش همانند مثال قبلی ابتدا در خط ۴۰ صفحه نمایش راه‌اندازی شده است. خط ۴۱ به curses اعلام می‌کند، ما قصد استفاده از رنگ در نوشتن متن‌ها را داریم. در صورت عدم استفاده از تابع ()start_color هر تلاشی برای نمایش متون رنگی روی صفحه نمایش بی نتیجه خواهد ماند. نکته مهم دیگر این است که این دستور باید بعد از ایجاد و آماده‌سازی صفحه نمایش توسط تابع ()initscr مورد استفاده قرار بگیرد.

همان‌گونه که پیش‌تر هم اشاره شد برای ایجاد متون رنگی ما باید از جفت رنگ‌های مخصوص curses استفاده کنیم. خطوط ۴۲ تا ۴۵ این کار را انجام می‌دهد. برای تعریف جفت‌های رنگی از تابع ()init_pair استفاده می‌کنیم که سه آرگومان را قبول می‌کند. آرگومان نخست شماره جفت رنگی را مشخص می‌کند. آرگومان دوم رنگ متن یا پیش‌زمینه را مشخص‌کرده و آرگومان سوم رنگ پس‌زمینه را تعیین می‌کند. برای معرفی این رنگ‌ها ما از ثابت‌های نام‌دار خود کتابخانه curses استفاده کرده‌ایم. همان‌گونه که مشاهده می‌شود، این ثابت‌ها از ترکیب curses.COLOR_ با نام رنگ مورد نظر (با حروف بزرگ) به وجود آمده‌اند.

تنها نکته جدید دیگر در این برنامه قالب try . . . except . . . finally است. این ساختار کنترلی معمولا برای جلوگیری از بوجود آمدن خطا در برنامه‌ها و متوقف شدن برنامه استفاده می‌شود. فرم ساده استفاده از این دستورات بدین صورت است که پس از کلمه کلیدی try مجموعه دستوراتی که ممکن است باعث بروز خطا شوند آورده می‌شود. مجموعه کدهای مدیریت کننده خطا نیز پس از کلمه کلیدی except نوشته می‌شود. در نهایت هم دستوراتی که در هر صورت (چه با بروز خطا و چه بدون آن) باید اجرا شوند پس از کلمه کلیدی finally آورده می‌شود. مثال زیر نمونه‌ای از کاربرد این دستور را نشان می‌دهد:

a=input()
b= input()
try:
    c=a/b
except:
    print “division by zero .”
    c=”Nothing”
finally:
    print c

در بخش‌های بعدی این مجموعه درباره این قالب به‌صورت مفصل توضیح خواهیم داد.

#! /usr/bin/env python
# ======= curses ========
import curses
# ======== Main Menu ============
def MainMenu():
myscreen.erase()
myscreen.border(0)
myscreen.addstr(8,10, “=====================================”)
myscreen.addstr(9,10, “         Phone Book Menu”)
myscreen.addstr(10,10, “=====================================”)
myscreen.addstr(11,10, “۱- Add new name to the book”,curses.color_pair(1))
myscreen.addstr(12,10, “۲- Search for a name in the book”,curses.color_pair(2))
myscreen.addstr(13,10, “۳- Delete a name from the book”,curses.color_pair(3))
myscreen.addstr(14,10, “۰- EXIT”,curses.color_pair(4))
myscreen.addstr(15,10, “=====================================»)
myscreen.addstr(16,10, “Your choice:   “)
myscreen.refresh()
# ======== Get Key ============
def GetKey():
key=”X”
while key != ord(‘۰’):
key = myscreen.getch(16,25)
#بخش کنترل کلید فشرده شده 
if key == ord(‘۱’):
## روال افزودن نام و شماره آورده شود
pass
if key == ord(‘۲’):
## روال جست‌وجو آورده شود
pass
if key == ord(‘۳’):
## روال حذف آورده شود
pass
# ======= Main Part ========
myscreen = curses.initscr()
curses.start_color()
curses.init_pair(1, curses.COLOR_BLUE,curses.COLOR_WHITE)
curses.init_pair(2, curses.COLOR_GREEN,curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_CYAN,curses.COLOR_MAGENTA)
curses.init_pair(4, curses.COLOR_RED,curses.COLOR_WHITE)
myscreen.border(0)
 
try:
MainMenu()
GetKey()
 
finally:
curses.endwin()
فهرست ۲- کدهایی برای نمایش منوی رنگی یک نرم‌افزار فرضی دفتر تلفن

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

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

بیشتر بدانید ...

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

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

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

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

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

در این قسمت قصد داریم به بررسی Pygame بپردازیم. درواقع Pygame مجموعه‌ای از ماجول‌ها است که با هدف ساده‌سازی روند توسعه بازی‌های ساده طراحی‌شده‌اند. این ماجول‌ها از سایت PyGame قابل دریافت هستند. به گفته توسعه‌دهندگان این مجموعه: «Pygame کتابخانه‌ای مستقل از پلتفرم است که برای ساده‌سازی توسعه نرم‌افزارهای مالتی‌مدیا نظیر، بازی‌ها، توسط زبان پایتون طراحی شده است. Pygame برای اجرا به زبان برنامه‌نویسی پایتون و کتابخانه مالتی‌مدیای SDL نیاز دارد.» برای نصب Pygame روی اوبونتو به سادگی می‌توانید با مراجعه به Synaptic بسته نرم‌افزاری آن را با نام python-pygame دانلود کنید یا در ترمینال دستور زیر را وارد کنید:

sudo apt-get install python-pygame

صفحه بازی

برای شروع کار، فهرست ۱ را در ویرایشگر متن دلخواهتان وارد کنید و با نام game1.py آن را ذخیره کنید. در خط ۳ این برنامه ما Pygame را import می‌کنیم تا توابع و مقادیر آن را در اختیار داشته باشیم. پس از آن و در خط ۵ ماجول os را وارد می‌کنیم. هدف اصلی از به‌کار بردن ماجول os در خط ۶ مشخص می‌شود. جایی که ما با مقداردهی یکی از مقادیر متغیر environment از ماجول os (که از جنس لیست است) تعیین می‌کنیم پنجره مربوط به برنامه بازی ما درست در وسط صفحه نمایش باز شود. پس از آن در خط ۸ کد Pygame را راه‌اندازی یا به اصطلاح initialize می‌کنیم. این کار باعث می‌شود، پنجره مربوط به بازی ما تولید شده و در وسط صفحه به نمایش درآید. در مرحله بعد و در خط شماره ۱۰ اندازه این پنجره را برابر ۸۰۰×۶۰۰ و در خط ۱۱ عنوان پنجره را برابر عبارت “Pygame Test 1” تنظیم می‌کنیم. در نهایت، با اجرای یک حلقه به انتظار یک رویداد (در اینجا فشرده شدن کلیدهای ماوس یا کلیدی از صفحه کلید) می‌نشینیم. نخستین برنامه‌ای که ما با کمک Pygame نوشته‌ایم، هیچ عملیات خاصی انجام نمی‌دهد و تنها هدف ما از آوردن این مثال آشنایی با روش راه‌اندازی و تنظیم خصوصیات ابتدایی پنجره برنامه نظیر اندازه و عنوان پنجره بود. آنچه در این‌جا مهم است درک شیء screen به عنوان یک «ظرف» یا Container است. در اصطلاح Pygame به آن سطح یا Surface گفته می‌شود. این شیء به نوعی نقش یک برگه کاغذ را بازی خواهد کرد که ما ترسیمات مورد نظرمان را روی آن انجام می‌دهیم.

#! /usr/bin/env python
# importing modules
import pygame
from pygame.locals import *
import os
os.environ[‹SDL_VIDEO_CENTERED›]=›۱›
# Initializing the game 
pygame.init()
# screen setup
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption(‹Pygame Test 1›)
doloop=1
while doloop:
    if pygame.event.wait().type in (KEYDOWN ,\ MOUSEBUTTONDOWN):
        break

فهرست ۱- کد ساده‌ای برای ایجاد یک صفحه Pygame

اکنون می‌توانیم به تدریج قابلیت‌ها و تنظیماتی را به این برنامه بیافزاییم. برای شروع از تغییر پس زمینه برنامه شروع می‌کنیم. برای تنظیم رنگ در ماجول‌های Pygame مجبور هستیم مقادیر RGB یا قرمز، سبز و آبی رنگ را تعیین کنیم. برای ساده‌تر شدن این کار می‌توانید از نرم‌افزاری به نام colorname استفاده کنید که از طریق مرکز نرم‌افزار اوبونتو قابل نصب است. به کمک این نرم‌افزار تعیین مقادیر RGB هر رنگ دلخواه از طریق یک چرخ رنگ به سادگی امکان‌پذیر خواهد شد. برای تنظیم رنگ پس‌زمینه کافی است، پس از دستور import خط زیر را اضافه کنید:

Background = 208 , 202 , 104

این کار رنگی آجری را به متغیر Background (که از جنس توپل است) نسبت خواهد داد. آن‌گاه پس از دستور  pygame.display.set_caption دو خط زیر را اضافه کنید:

screen.fill(Background)
screen.display.update()

متد ()screen.fill تنظیم رنگ صفحه را بر عهده دارد و متد ()update باعث اعمال تنظیم انجام شده به صفحه در حال نمایش خواهد شد. 

نمایش متن

اکنون زمان آن رسیده است که چند سطر متن را به پنجره برنامه اضافه کنیم. درست بعد از تعریف رنگ پس‌زمینه دستور زیر را برای تنظیم رنگ پیش‌زمینه به سفید وارد کنید:

FontForeground = 255 , 255 , 255

اگر برنامه را در این وضعیت اجرا کنید، اتفاق خاصی رخ نخواهد داد، زیرا ما تا‌کنون تنها رنگ متن را تعیین کرده‌ایم. برای نوشتن متن روی screen یا همان پنجره برنامه، خطوط زیر را بین دو دستور ()screen.fill  و ()pygame.display.update وارد کنید.

font = pygame.font.Font(None , 27)
text = font.render(‘Here is some text’ ,
True , FontForeground , Background)
textrect = text.get_rect()
screen.blit(text,textrect)

شکل 1- قراردادن متن روی یک صفحه Pygame

این برنامه را با عنوان game2.py ذخیره کرده و اجرا کنید. برنامه شما اکنون باید شبیه فهرست ۲ باشد. برای نوشتن متن ما ابتدا در خط ۱۵ متد Font را فراخوانده و ۲ آرگومان را به آن پاس کرده‌ایم. نخستین آرگومان نام فونت و دومی اندازه آن خواهد بود. در اینجا ما از None برای نام فونت استفاده کرده‌ایم که باعث می‌شود سیستم از فونت پیش‌فرض خود استفاده کند.
پس از آن و در خط ۱۶ متد ()font.render را به‌کار برده‌ایم که چهار آرگومان دارد. این چهار آرگومان به ترتیب عبارتند از متن موردنظر، استفاده یا عدم استفاده از anti-aliasing، رنگ پیش‌زمینه متن و در نهایت رنگ پس‌زمینه آن. برای قرار دادن متن روی screen از واسطی به نام مستطیل یا Rectangle استفاده می‌کنیم. در خط ۱۸ با استفاده از تابع ()text.get_rect مستطیل مربوط به متن را ایجاد کرده‌ایم. درک این روند بسیار مهم است، زیرا اغلب اشیایی که از این به بعد با آن‌ها سروکار خواهیم داشت، مستطیل خواهند بود.

پس از آن ما مستطیل حاوی متن را روی screen قرار داده (خط ۱۹) و تغییرات را اعمال کرد‌ه‌ایم. اما blit چیست و چرا از چنین نام عجیب و غریبی استفاده می‌شود؟ ریشه‌های این نام به سال‌های ۱۹۷۰ و دوران زیراکس پارک (جایی که بسیاری از تکنولوژی‌های امروزی را مدیون دانشمندان و نوآوران فعال در آن هستیم) باز می‌گردد. این اصطلاح در واقع خلاصه Bitmap Block Transfer است. وظیفه این دستور قرار دادن یک بلوک تصویری روی یک پس‌زمینه است.

#! /usr/bin/env python
# importing modules
import pygame
from pygame.locals import *
import os
os.environ[‹SDL_VIDEO_CENTERED›]=›۱›
Background = 208,202,104
FontForeground = 255,255,255
# Initializing the game 
pygame.init()
# screen setup
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption(‹Pygame Test 2›)
screen.fill(Background)
font=pygame.font.Font(None,27)
text=font.render(‹Here is some text›,True,\
FontForeground,Background)
textrect=text.get_rect()
screen.blit(text,textrect)
pygame.display.update()
doloop=1
while doloop:
    if pygame.event.wait().type in (KEYDOWN ,\ MOUSEBUTTONDOWN):
        break

فهرست ۲

اما اگر بخواهیم متن ما درست در وسط پنجره برنامه ظاهر شود، چه باید کرد؟ در چنین صورتی کافی است بین دستور ()text.get_rect (خط‌ ۱۸) و screen.blit (خط ۱۹) این دو خط را اضافه کنید:

textRect.centerx = screen.get_rect().centerx
textRect.centery = screen.get_rect().centery

همان‌گونه که مشاهده می‌کنید، خود screen هم در واقع یک مستطیل است که ما به کمک متد ()get_rect مشخصات آن و به ویژه x و y مرکز آن را استخراج کرده‌ایم و آن‌ها را به مختصات مرکز مستطیل متن نسبت داده‌ایم.
دوباره برنامه را اجرا کنید. این بار مشاهده خواهید کرد که همانند شکل‌۱ پس از اجرای آن، متن Here is some text درست در وسط پنجره برنامه ظاهر می‌شود. با استفاده از متدهای (set_bold(True و (set_italic(True درست پس از قسمت pygame.font.Font می‌توانید به متن حالت توپر یا مایل را نیز نسبت دهید.

اگر به خاطر داشته باشید، پیش‌تر گفتیم که برای تنظیم فونت متن از متد ()pygame.font.Font استفاده می‌کنیم که دو آرگومان فونت و اندازه را دریافت می‌کند. مشکل اینجا است که ما نمی‌توانیم از محل قرارگیری و نصب فونت‌های مختلف روی سیستم‌های متفاوت اطلاع پیدا کنیم یا درباره حالتی خاص مطمئن باشیم. خوشبختانه pygame این امکان را با پیش‌بینی متدی به نام match_font حل کرده است. در فهرست‌۳ شما قطعه کدی را مشاهده می‌کنید که می‌تواند به عنوان مثال، محل قرارگیری فونت Courier New را برای ما چاپ کند. این کد در سیستم نگارنده آدرس usr/share/fonts/truetype/freefont/FreeMono.ttf را باز‌می‌گرداند که ممکن است در سیستم شما مقدار دیگری باشد. اگر فونت Courier New روی سیستم نصب نشده باشد، این کد مقدار None را بازخواهد گرداند. اما اگر فرض کنیم این فونت روی سیستم نصب شده باشد، می‌توان مقدار برگشتی این تابع را مانند قطعه کد زیر برای تنظیم فونت برنامه به کار برد:

courier = pygame.font.match_font(‘Courier New’)
font = pygame.font.Font(courier , 27)

این دو خط را نیز می‌توانید به عنوان آخرین تغییرات به کد برنامه game3.py خود اعمال کنید. در هنگام ایجاد یک بازی واقعی نهایت کار آن است که از یک فونت مشخص که مطمئن هستید روی سیستم‌های هدف موجود است، استفاده کنید یا فونت موردنظر را به همراه بسته نصب بازی عرضه کنید. 

گرافیک

اگرچه متن‌ها زیبا هستند، اما گرافیک‌ها از آن‌ها زیباترند. در اینجا به توضیح نحوه کار اسپرایت‌ها (Sprite) در pygame خواهیم پرداخت. اسپرایت‌ها تصاویر دو بعدی ساده‌ای هستند که در نرم‌افزارهای گرافیکی برای نمایش اجزای بازی مورد استفاده قرار می‌گیرند. برای استفاده از گرافیک‌ها در برنامه بازی خودتان، توسط نرم‌افزاری نظیر GIMP یا ابزارهای مشابه تصویری شبیه یک آدمک را در یک فایل ۵۰ × ۵۰ پیکسل ترسیم کنید. رنگ پس‌زمینه تصویر را به حالت شفاف (Transparent) تغییر دهید و فایل را با نام stick.png در پوشه‌ای که فایل‌های کد برنامه در آن قرار دارند، ذخیره کنید. توجه کنید که حتماً حالت پس‌زمینه تصویر را روی Transparent تنظیم کنید تا هنگام نمایش و حرکت اسپرایت روی پس‌زمینه تنها تصویر آدمک دیده شود، نه یک مربع ۵۰ × ۵۰ سفید رنگ.

import pygame
from pygame.locals import *
print pygame.font.match_font(‹Courier New›)

فهرست ۳- کدی برای تعیین محل یک فونت خاص

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

#! /usr/bin/env python
# importing modules
import pygame
from pygame.locals import *
import os
import sys
os.environ[‹SDL_VIDEO_CENTERED›]=›۱›
Background = 0,255,127
FontForeground = 255,255,255
# Initializing the game 
pygame.init()
# screen setup
screen = pygame.display.set_mode((400,300))
pygame.display.set_caption(‹Pygame Sprite Test›)
screen.fill(Background)
class Sprite(pygame.sprite.Sprite):
    def __init__(self,position):
        pygame.sprite.Sprite.__init__(self)
        # get the screen rectangle
        self.screen = pygame.display.get_surface().get_rect()
        # Variable to store privious position
        self.oldsprite=(0,0,0,0)
        self.image=pygame.image.load(‹stick.png›)
        self.rect=self.image.get_rect()
        self.rect.x=position[0]
        self.rect.y=position[1]
     def update(self,amount):
        # make a copy of current rectangle
        self.oldsprite = self.rect
        # Moving the rectangle
        self.rect = self.rect.move(amount)
        # Check the border
        if self.rect.x <0:
            self.rect.x=0
        elif self.rect.x > (self.screen.width – self.rect.width):
            self.rect.x = self.screen.width – self.rect.width
        if self.rect.y < 0:
            self.rect.y=0
        elif self.rect.y > (self.screen.height – self.rect.height):
            self.rect.y = self.screen.height – self.rect.height
character = Sprite((screen.get_rect().x , screen.get_rect().y))
screen.blit(character.image,character.rect)
blank=pygame.Surface((character.rect.width,character.rect.height))
blank.fill(Background)
pygame.display.update()
doloop=1
while doloop:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                character.update([-10,0])
            elif event.key == pygame.K_UP:
                character.update([0,-10])
            elif event.key == pygame.K_RIGHT:
                character.update([10,0])
            elif event.key == pygame.K_DOWN:
                character.update([0,10])
            elif event.key == pygame.K_q:
                doloop=0
        # Erase old position
        screen.blit(blank,character.oldsprite)
        # Draw new
        screen.blit(character.image,character.rect)
        # Update modified positions
        pygame.display.update([character.oldsprite,character.rect])

فهرست ۴ – حرکت دادن یک کاراکترروی صفحه Pygame

شکل 2- صفحه بازی ایجاد شده توسط کد فهرست 4

تابع update که در خط ۲۷ تعریف شده است، وظیفه حرکت دادن اسپرایت و پرکردن محل قبلی آن با یک فضای خالی (پاک کردن اسپرایت) را برعهده خواهد داشت. این تابع همچنین عدم خروج اسپرایت از صفحه را کنترل می‌کند.  پس از پایان تعریف کلاس، ما نمونه‌ای از کلاس را در خط ۴۱ با نام character ایجاد کرده و با تابع blit روی صفحه نمایش داده‌ایم (خط‌۴۲). پس از آن شیء blank یا پاک کننده ایجاد شده و تابع update ماجول display  به اجرا در می‌آید. پس از آن در خطوط ۴۷ تا ۶۷ یک حلقه بی‌پایان ایجاد شده و با کنترل ورودی کاربر، آدمک ساخته شده روی صفحه نمایش به حرکت در خواهد آمد. کارهای بسیار پیچیده‌تری با pygame قابل انجام است  به عنوان مثال، این ماجول دارای توابعی برای کنترل برخورد اسپرایت‌ها (مثلاً برخورد گلوله با شخصیت بازی)، نگه‌داری امتیازها و افزودن جلوه‌های صوتی و‌… نیز دارد. اما هدف ما آشنا‌کردن شما با مبانی کار با این ماجول بود و امیدواریم که توانسته باشیم حس کنجکاوی شما را برای آگاهی بیشتر برانگیخته باشیم.

یک فایل جدید ایجاد کنید و محتویات فهرست ۴ را در آن وارد کرده و آن را با نام game4.py  ذخیره کنید. با اجرای این کد شما آدمک متحرک را روی پس‌زمینه‌ای به رنگ سبز تیره مشاهده خواهید کرد که به کلیدهای جهت‌نما واکنش نشان داده و به دستور شما حرکت خواهد کرد.  بخش اول این کد، شبیه مثال‌های قبلی و شامل خطوطی برای import ماجول‌های موردنیاز و تنظیم رنگ و عنوان صفحه بازی است. پس از آن در خط ۱۶ کلاسی را برای کنترل و مدیریت اسپرایت یا گرافیک دلخواهمان تعریف کرده‌ایم. در ابتدای کلاس و با تعریف تابع __init__ ما اسپرایت را راه‌اندازی می‌کنیم. غالب کارهای ساخت اسپرایت به کمک متد اصلی pygame.sprite.Sprite.__init__   که در خود pygame تعریف شده است (خط ۱۸) به انجام می‌رسد. پس از آن در خط ۲۰ سطح یا Surface بازی را تعریف کرده و آن را screen نامیده‌ایم. بعدها به کمک شیء screen می‌توانیم کنترل کنیم که اسپرایت از صفحه بازی خارج نشود. سپس در خط ۲۳ با تابع pygame.image.load فایل تصویر آدمک ساخته شده را به اسپرایت نسبت داده‌ایم. اگر فایل برنامه و فایل تصویر در یک پوشه نباشند، باید آدرس کامل فایل تصویری در این تابع قید شود. پس از آن در خط‌های ۲۵ و ۲۶ موقعیت x , y  اسپرایت توسط متغیر position که به تابع پاس شده است،تنظیم می‌شود.

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

بیشتر بدانید ...

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

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

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

سکون و ایستایی در دنیای نرم‌افزار مترادف مرگ است. همه نرم‌افزارها برای ادامه حیات‌ خود محتاج به روزآوری و افزوده شدن قابلیت‌ها و ویژگی‌های جدید هستند. در این میان با گسترش کاربرد و نفوذ کامپیوترها در جنبه‌های مختلف زندگی ما، زبان‌های برنامه‌نویسی بیش از سایر نرم‌افزارها به این پویایی و تحول نیاز دارند. بر همین اساس، زبان پایتون نیز به‌صورت مداوم در حال بازبینی و بهینه‌سازی است. در این مورد خاص و با توجه به حجم عظیم تغییرات ایجاد شده در نسخه X.3، بنیاد نرم‌افزار پایتون (Python Software Foundation) تصمیم گرفته، ارتقا به سری جدید را به تدریج انجام دهد‌، یعنی روند توسعه سری جدید در کنار سری جاری و به‌صورت همزمان انجام می‌پذیرد تا زمانی که بنیاد به این نتیجه برسد، بیشتر کاربران آمادگی انتقال به سری جدید را دارند. در این قسمت تصمیم گرفتیم، به معرفی مختصر خصوصیات و تفاوت‌های نسل جدید پایتون با نسل قبل بپردازیم.

نسل سوم

همان‌گونه که پیش‌تر اشاره شد، در حال‌حاضر توسعه پایتون در دو مسیر موازی در حال انجام است. گروه نخست توسعه‌دهندگان همچنان به کار روی سری دوم پایتون (۲.x) مشغول هستند که به‌دلیل قدمت و سابقه بیشتر، پرطرفدارتر است. در حال حاضر بیشتر فریم‌ورک‌ها و کتابخانه‌های رایج و پراستفاده برای این سری توسعه داده شده و پیاده‌سازی می‌شوند. تمام مثال‌ها و برنامه‌هایی که تا‌کنون معرفی کرده‌ایم نیز از همین سری استفاده می‌کنند.
 این نسل از زبان پایتون در اکتبر سال ۲۰۰۰ معرفی شد و اکنون به نسخه ۱/۷/۲رسیده است. گروه دوم توسعه‌دهندگان به کار روی نسل جدید این زبان، یعنی پایتون ۳.x می‌پردازند که تا‌کنون نسخه ۲/۳ آن نیز منتشر شده است. در این سری وان روسوم (Guido van Rossum) خالق پایتون، تصمیم گرفته به بازنگری اساسی در تمام جنبه‌های این زبان برنامه نویسی و حذف Backward Compatibility (پشتیبانی از اجرای کدهای نوشته شده با نسل دوم این زبان) بپردازد.

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

دستور PRINT

یکی از مهم‌ترین و پرکاربردترین بخش‌های پایتون که در این نسخه دستخوش تغییرات اساسی شده، دستور print است. در نسخه‌های ۲.x این زبان به راحتی می‌توانستیم آیتم مورد نظر را به فرم زیر چاپ کنیم:

print “This is a test”

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

print (“This is a test”)

هرچند این تغییر به ظاهر ساده است، اما در ادامه خواهیم دید که تغییرات دستور print به همین موارد خلاصه نخواهد شد.

قالب‌بندی و جای‌گذاری متغیرها

در نسخه قبلی پایتون ما از کدهایی برای قالب‌بندی و جای‌گذاری متغیرها در یک رشته استفاده می‌کردیم (همانند شکل۱). اگرچه این عبارت در پایتون ۲/۳ نیز به درستی کار خواهد کرد، اما این وضعیت در حال تغییر است، زیرا توابع قالب‌بندی %s و %d در نسخه‌های آینده حذف خواهند شد و سیستم نگارشی {x} جایگزین آن خواهد (شکل‌۲). در این روش عبارت‌های معرفی شده به عنوان آرگومان‌های متد format، به ترتیب جایگزین {x}ها خواهند شد. همان‌طور که مشاهده می‌کنید، خوانایی این روش جدید بسیار بیشتر از حالت قبلی ارجاع به متغیرها و قالب‌بندی آن‌ها است.

اعداد

در سری ۲.x پایتون عبارت ۰.۲/۵ حاصلی برابر با۵.۲ داشت. اما اگر از عبارتی مانند ۲/۵ استفاده می‌کردید، به‌واسطه تبدیل نتیجه به فرمت عدد صحیح (به‌واسطه عدد صحیح بودن هر دو عملوند عبارت ۲/۵) حاصلی برابر ۲ دریافت می‌کردید. در سری ۳.x پایتون استفاده از هر دو فرم قبلی نتیجه‌ای برابر با ۵.۲ ایجاد خواهد کرد. و در صورتی که نیاز داشته باشید تقسیم را به‌صورت صحیح و بدون اجزای اعشاری انجام دهید، باید از فرمت ۵//۲ استفاده کنید.

دستور INPUT 

در سری ۲.x  پایتون، دستور input  تنها ورودی‌های عددی را می‌پذیرفت و در صورت ورود رشته‌ها همانند شکل ۳ با پیغام خطا روبه‌رو می‌شدیم. برای دریافت رشته‌ها از کاربر مجبور بودیم از دستور raw_input استفاده کنیم. اما در سری ۳.x دستور input با تمام ورودی‌ها همانند رشته رفتار می‌کند و در صورتی که به دریافت اعداد نیاز داشته باشید، باید ورودی‌های دستور input را به صورت دستی به عدد تبدیل کنید.

نامساوی و شرطی‌ها

در سری ۲.x پایتون برای کنترل نامساوی‌بودن عبارت‌ها از عملگر <> استفاده می‌شد، اما این شیوه در سری ۳.x دیگر مجاز نیست و به جای آن باید از عملگر != استفاده کرد.  نکته دیگر این‌که در سری ۲.x در صورت مقایسه دو عملوند از نوع مختلف (مثلاً مقایسه یک رشته با یک عدد صحیح) همانند شکل ۴ نتیجه‌ای برابر با false یا نادرست بازگردانده می‌شد. به عبارت دیگر، خطایی رخ نمی‌داد. اما در سری ۳.x باید حتماً، از یکسان بودن (به عبارت کلی‌تر، قابل مقایسه بودن) عملگرها اطمینان حاصل کرد. در غیر این صورت، همانند شکل ۵ با خطای Type Error مواجه خواهیم شد.

سایر تغییرات

انواع داده بنیادین در پایتون نیز دستخوش تغییر شده‌اند. دو نوع داده int و long در قالب یک نوع داده، یعنی int ادغام شده‌اند و متدهای مربوط به دیکشنری‌ها نظیر ()dict.keys به جای بازگرداندن یک لیست، نوع جدیدی به نام view را باز می‌گردانند. تابعی نظیر ()range هم به جای یک لیست یک شمارنده یا Iterator را باز می‌گرداند. 
همچنین تغییرات فراوانی نیز در کتابخانه‌های استاندارد پایتون ایجاد شده است. به عنوان مثال، می‌توان به حذف توابع مربوط به گوفر (gopherlib) و جایگزین شدن md5 با hashlib اشاره کرد. البته، همان‌طور که در ابتدا نیز اشاره شد، تغییرات ایجاد شده بسیار زیاد بوده و توضیح  کامل همه آن‌ها در این مقاله نمی‌گنجد.

تبدیل برنامه‌ها به سری جدید

سری ۳.x  پایتون با ابزاری برای تبدیل کدهای سری‌های قبلی به سری جدید همراه شده است. اگرچه این ابزار در همه موارد به درستی عمل نمی‌کند، اما در بسیاری از موارد شما را به هدف بسیار نزدیک خواهد کرد. این ابزار نام معنی‌دار ۲to3 را یدک می‌کشد. در لینوکس برای استفاده از این ابزار از طریق ترمینال دستور زیر را وارد می‌کنیم:

۲to3 [-w] <input_file.py<

توجه داشته باشید که این دستور به شرطی عمل خواهد کرد که سری ۳.x  پایتون روی لینوکس نصب شده باشد. در اوبونتو برای نصب این سری جدید  از دستور زیر استفاده کنید:

sudo apt-get install python3

این ابزار در ماشین‌های ویندوزی با نام ۲to3.py در پوشه c:\Python3x\Tools\Scripts قرار دارد و برای استفاده از آن باید از خط فرمان و در پوشه گفته شده دستور زیر را صادر کرد:

<python.exe   ۲to3.py  [-w]  <input_file.py

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

آیا باید به سری ۳.x مهاجرت کنیم؟

تغییرات سینتکس در همه نسخه‌های جدید زبان‌های برنامه‌نویسی به چشم می‌خورد. میان‌برهایی نظیر += ممکن است به سادگی کار ما را در هنگام کدنویسی ساده‌تر کنند. اما همین تغییرات ساده سینتکس جنبه‌های منفی نیز در خود دارند. درباره زبان پایتون نیز به دلیل همین تغییرات (گاهی ساده) در سینتکس، بسیاری از ماجول‌ها و کدهایی که قبلاً استفاده می‌کردیم، در برنامه‌هایی که با سری ۳.x پایتون نوشته می‌شوند، قابل استفاده نیستند. به عنوان نمونه می‌توان به کتابخانه‌های ElementTree اشاره کرد که در بخش مربوط به xml از آن استفاده کردیم. اما با تمام این مشکلات نباید از مهاجرت به سری ۳.x پایتون نا امید شد.

خوشبختانه پایتون سری ۲.x (حداقل از نسخه ۶/۲ به بعد) در عین سازگاری با نسخه‌های قبلی، از تمام سینتکس‌های مورد نیاز برای نوشتن کد به سبک سری ۳.x پشتیبانی می‌کند (فهرست ۶). پیشنهاد می‌کنیم که از همین حالا نوشتن کد به سبک سری   ۳.x را آغاز کرده و اگر می‌توانید تنها به کتابخانه استاندارد پایتون بسنده کنید و به ماجول‌های دیگر رجوع نکنید، حتماً به  ۳.x  پایتون مهاجرت کنید. 

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

مطالعه بیشتر

برای آشنایی بیشتر با تغییرات و نحوه مهاجرت به این سری جدید می‌توانید به منابع زیر مراجعه کنید:

– http://wiki.python.org/moin/Python2orPython3
– http://docs.python.org/release/3.1.2/whatsnew/3.0.html
– http://docs.python.org/library/2to3.html 
– http://diveintopython3.org

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

بیشتر بدانید ...