Giter Site home page Giter Site logo

saleh-programmer / python_tutorial_in_persian Goto Github PK

View Code? Open in Web Editor NEW

This project forked from niloofarmn/python_tutorial_in_persian

0.0 0.0 0.0 4 MB

در این ریپازیتوری میتوانید مطالب اولیه پایتون را بیاموزید.

Jupyter Notebook 100.00%

python_tutorial_in_persian's Introduction

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

معرفی درس و هدف درس

هدف از درس برنامه سازی (پایتون) توسعه و تعمیق دانش و مهارت دانشجویان در زمینه تفکر سیستمی، آلگوریتم و برنامه نویسی در محیط پایتون است. اهداف اصلی در این درس عبارتند از:
  • آشنائی با مبانی برنامه نویسی و ساختارهای برنامه سازی در پایتون
  • آشنائی با توابع و ساختارهای پیشرفته از جمله لیست، دیکشنری، کلاس و آبجکت و ساختار توابع بازگشتی
  • آشنائی با برنامه نویسی شی گرا، وراثت، برنامه های مرتب سازی و جستجو و مفهوم پیچیدگی محاسباتی
  • آشنائی با کتابخانه های پایتون Python, Numpy, Matplotlib …
  • پیاده سازی و کسب مهارت انجام پروژه‌های درسی

  1. مقدمه بر ساختار رایانه و مبانی زبان های برنامه نویسی
  2. ویژگی‌های زبان پایتون و برنامه سازی و نصب محیط ژوپیتر پایتون
  3. متغیر، عبارت (Expression) و دستور (Statement)، اولین برنامه
  4. ساختار کنترل شرطی if و چند نمونه برنامه
  5. ساختار کنترل حلقه while, for و چند نمونه برنامه
  6. تابع و انواع توابع، کتابخانه‌ای، ماجول و پکیج، تعریف تابع
  7. متغیر، عبارت عملگرهای محاسباتی و اعشاری
  8. متغیر، عبارترشته های حرفی (Strings)
  9. ساختارهای تاپل و لیست (List, Tuples) و ماتریس
  10. ماجول‌های محاسباتی، تصادفی و رسم نمودار
  11. کار با فایل‌ها و ذخیره و بازیابی داده در فایل
  12. توابع بازگشتی و ساختار مجموعه و دیکشنری (Set, Dictionary)
  13. مفهوم کلاس و برنامه سازی شی گرا
  14. الگوریتم جستجو و مرتب سازی
  15. محاسبات ماتریسی با کتابخانه Numpy و Scipy
  16. مروری بر مباحث


در این بخش با مطالب زیر آشنا می‌شویم:
  1. برنامه چیست
  2. زبان برنامه‌نویسی چیست
بازگشت به فهرست

برنامه یک سری فعالیت ها و دستورات است که شما را به هدف یا جوابی که می‌خواهید می‌رساند. برای یک برنامه ابتدا باید یک مسئله وجود داشته باشد. سپس برای آن مسئله یک برنامه نوشته می‌شود که بتواند شما را به جواب برساند. ممکن از یک جواب حدودی برای شما معیین شده باشد؛ اما در اکثر موارد جوابی در دست شما نیست و برنامه را به قصد یافتن جواب می‌نویسید.

زبان برنامه نویسی دستورات مد نظر شما در یک برنامه را به طوری تعریف می‌کند که برای یک سیستم قابل فهم باشد. برخی زبان‌ها بسیار پایه‌ای هستند و برخی زبان‌ها در سطح‌های بسیار بالا و قابل فهم‌تر برای انسان تعریف شده‌اند.
به طور کلی زبان‌ها شامل 2 دسته سطح بالا و سطح پایین می‌شوند. در زبان های سطح بالا کاربر یا برنامه‌نویس دخالتی در مدیریت حافظه ندارد و به زبان انسان بسیار نزدیکتر است. پایتون، جاوا، جاوا اسکریپت، c# و بسیاری از زبان‌های دیگر در این دسته از زبان‌ها قرار می‌گیرند. در زبان‌های سطح پایین زبان اسمبلی(assembly) جزو این دسته از زبان‌ها است. اما دسته دیگری از زبان‌ها موجود است که در بین این دو قرار دارد. هم ویژگی‌های زبان‌های سطح بالا را دارد و هم ویژگی‌های زبان‌های سطح پایین. زبان C و C++ در این دسته قرار می‌گیرند.
از طرفی دیگر زبان های سطح بالا خود دارای 2 نوع مختلف هستند: مفسری و کامپایلری.
در زبان های مفسری کد خط به خط به زبان سطح پایین تبدیل می‌شود و اگر آن خط ایرادی نداشته باشد توسط سیستم اجرا می‌شود تا زمانی که خطی دارای خطا باشد. در زبان‌های کامپایلری کل کد یکجا به زبان سطح پایین تبدیل شده و در صورت نداشتن خطا در هیچ یک از خط ها اجرا می‌شود.
اما زبان پایتون می‌تواند در هر دو دسته قرار بگیرد. بسته به تنظیمات می‌تواند به صورت مفسری و یا کامپایلری اجرا شود.

مقدمه

زبان پایتون یکی از محبوب‌ترین زبان‌های برنامه نویسی است. این زبان از سال 2017 در صدرجدول محبوب ترین زبان‌های برنامه‌نویسی دنیا قرار دارد. علت آن سادگی این زبان نسبت به زبان‌های محبوب و پرکاربرد دیگر مانند جاوا، سی و سی پلاس پلاس است. برای تولید برنامه اگر زبان انگیلیسی را به عنوان زبان گفتاری در نظر بگیرید، برنامه نوشتن با زبان پایتون مانند صحبت به این زبان است.
برنامه‌نویسی نیز نوعی از تفکر است که با آن می‌توان انجام کاری را به کامپیوتر یا سیستم تحت فرمان شما القا کرد. در آغاز درک این بخش می‌تواند یکی از سخت‌ترین قسمت‌های کد نویسی باشد زیرا درک چگونگی عملکرد مغز کامپیوتری در این بخش قرار دارد.
در ادامه با نصب محیط برنامه نویسی آناکندا و جزئیات بیشتر در مورد پایتون و درک زبان کامپیوتر آشنا می‌شویم:
فهرست این فصل:
  1. نصب آناکندا
  2. درک زبان کامپیوتر
  3. آشنایی مقدماتی با پایتون

بازگشت به فهرست

در پایین 3 مرحله دانلود آناکندا را مشاهده می‌کنید:


مرحله 1: سایت آناکندا

مرحله 2

مرحله 3

با توجه به سیستم خود نسخه مورد نظر را دانلود کنید. سپس با استفاده از مراحل زیر اقدام به نصب آناکندا کنید:


مرحله 1

مرحله 2

مرحله 3

مرحله 4

مرحله 5

مرحله 6

مرحله 7

مرحله 8

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

بازگشت به فهرست

برای برنامه نویسی نیاز است ابتدا هدف خود را مشخص کنید سپس آن را دسته بندی کنید. دسته بندی کار به صورت مرحله ای خواهد بود. هیچگاه نیاز نیست از ابتدای کار برنامه شما کامل و بدون ایراد باشد. برنامه کامل در ابتدا همیشه با آزمون و خطا به وجود می‌آید.
برای حل یک مسئله ابتدا باید مسئله را درک کرده، سپس یک راه حل اولیه برای آن در ذهن خود طراحی کنیم. پس از این مراحل نوبت به برنامه نویسی اولیه طرح ما می‌رسد. در نهایت برنامه را می‌آزماییم و در صورتی که نیاز به تغییرات داشت و یا خطایی در حین اجرای آن به وجود آمد، به مرحله قبل برمی‌گردیم و برنامه را بازنویسی می‌کنیم. در صورتی که در بازنویسی برنامه هیچ روند صعودی‌ای مشاهده نشود باید به مرحله قبل تر باز گشت و در طراحی اولیه بازبینی انجام شود.
برای مثال به نمونه زیر توجه کنید:
یک مسئله ساده روشن نشدن چراغ می‌تواند مثال خوبی از فهم روند کار باشد. اولین روشی که به ذهن میرسد بررسی اتصال به برق است. در صورت جدا بودن از برق آن را روشن می‌کنیم. در صورتی که اتصال برقرار باشد و همچنان برق روشن نشود، سوختگی لامپ را بررسی می‌کنیم. اگر سوخته باشد لامپ را تعویض می‌کنیم. در غیر این صورت نیاز به یک چراغ جدید است.
نمونه دیگری از برنامه که به کد نویسی و زبان کامپیوتر نزدیک تر است نمونه برنامه زیر است که اعداد بزرگتر از صفر را تشخیص می‌دهد:
ساده ترین کار برای تشخیص یک عدد مثبت استفاده از نماد ریاضی «بزرگتری» است. اگر عدد از صفر بزرگتر باشد به عنوان عدد بزرگتر از صفر یا مثبت اعلام می‌شود. در غیر این صورت هیچگونه اعلامی وجود ندارد.
اگر نیاز به اعلام عددهای کوچک تر از صفر بود به مراحل بالا چه چیزی اضافه می‌شد؟
کمی فراتر برویم. اگر بخواهیم 2 عدد را با هم جمع کنیم چه؟
ابتدا نیاز داریم 2 عدد را بگیریم (یا بخوانیم) سپس آن دو عدد را با هم جمع کنیم و در آخر مجموع را نمایش دهیم. فلوچارت این روند مشابه تصویر زیر خواهد بود:
حال فلوچارت بالا را به زبان خود توضیح دهید.
(یادگیری فلوچارت ضروری نیست و فقط برای درک بهتر از زبان کامپیوتر مورد استفاده قرار گرفته است)
حال روند مثال های زیر را به زبان خود بیان کنید:
  1. تبدیل دما از فارنهایت به درجه سانتیگراد
  2. عددی را به توان 2 رساندن
  3. به دست آوردن محیط یک مثلث

بازگشت به فهرست

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

برخی از کلمات خاص در زبان پایتون هستند که با آنها در آینده بیشتر آشنا می‌شویم.
برای مثال کلمه print از جمله این کلمات است که کاربرد آن نمایش هر آنچه درون آن نوشته شده است می‌باشد.
print("به کلاس پایتون خوش آمدید")
به کلاس پایتون خوش آمدید
print("مقدار شما میتواند عدد باشد: ")
print(123)
print(-5)
print(3.14)
مقدار شما میتواند عدد باشد: 
123
-5
3.14
print("شما میتوانید ابتدا عدد را به عنوان متغیر تعریف کنید و سپس آن را چاپ کنید")
a = 12
print(a)
شما میتوانید ابتدا عدد را به عنوان متغیر تعریف کنید و سپس آن را چاپ کنید
12
در واقع تابع print() برای خروجی در پایتون استفاده می‌شود.
برای گرفتن ورودی از کاربر برنامه از کلمه input همانند نمونه زیر استفاده می‌شود:
input()
12





'12'
برای نگهداری مقدار ورودی آن را در یک متغیر ذخیره می‌کنیم. در این حالت بعدا میتوانید از آن استفاده کنید.
برای درک بهتر مثال جمع دو عدد را در نظر بگیرید. آن را به صورت زیر پیاده سازی می‌کنیم:
number1 = input()
number2 = input('عدد دوم را وارد کنید ')
sum_of_2_numbers = number1+number2
print(sum_of_2_numbers)
2
عدد دوم را وارد کنید 3
23
با آن که راه حل ما درست به نظر می‌رسد اما جواب ما درست نیست. دلیل آن این است که ورودی ها در پایتون به صورت رشته هستند.
اما رشته چیست؟
تمام مقادیر در پایتون به شکلی تعریف می‌شوند. انواع متغیرها شامل رشته، اعداد(عدد صحیح، عدد اعشار و عدد مختلط) و انواع دیگری از مقادیر مانند لیست، دیکشنری و ... هستند.
با توجه به توضیحات برای آن که یک مقدار را به نوع دیگری از مقدار تبدیل کنیم نیاز به کَست کردن یا تبدیل یک نوع به نوع دیگر داریم.
number1 = input("enter first number: ")
number2 = input('enter second number: ')
n1 = int(number1)
n2 = int(number2)
sum_of_2_numbers = n1+n2
print("The sum is ",sum_of_2_numbers)
enter first number: 2
enter second number: 3
The sum is  5
بازگشت به فهرست

مقدمه

در فصل گذشته با تعدادی از متغیرها آشنا شدیم. در این فصل مثال‌های بیشتری از آنها می‌بینیم. سپس عبارات بیشتر و دستورهای بیشتری را مرور کرده و برنامه های ساده‌ای را می‌نویسیم.
فهرست این فصل:
  1. انواع متغیر
  2. عبارت و دستور
  3. برنامه‌های ساده

بازگشت به فهرست اصلی

همان طور که در فصل گذشته به آن اشاره شد، انواع متغیرها در پایتون شامل اعداد، رشته ها، لیست، تاپل و دیکشنری است. برخلاف برخی دیگر از زبان‌های برنامه نویسی مانند cو java ، در پایتون نیاز به مشخص کردن نوع متغیر هنگام تعریف آن نیست. بسته به مقداری که برای متغیر تعیین می‌شود، نوع متغیر برای زبان پایتون مشخص می‌شود. بنابراین در صورتی که به متغیر به طور مثال a مقدار 2 تعریف شود، پایتون نوع آن را int در نظر می‌گیرد که عدد صحیح است. اگر برای آن مقدار 2.1 در نظر گرفته شود، متغیر a به عنوان float در نظر گرفته می‌شود که به معنای اعداد اعشاری است. اگر به آن مقدار '2' داده شود، آن را به عنوان یک رشته در نظر می‌گیرد.
به مثال های زیر در مورد انواع متغیر ها توجه کنید:
a = 2
type(a) # عدد صحیح
int
a = 2.0
type(a) # عدد اعشار
float
a = '2'
type(a) # رشته
str

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

در برخی از توابع از پیش تعیین شده مانند print می‌توانید بیش از یک مقدار قرار دهید:
a = "a string"
b = 123
print(a,b)
print('a is',a , 'and b is', b)
a string 123
a is a string and b is 123

همچنین امکان کَست دو مقدار به هم (در صورت امکان تبدیل دو مثدار به هم) را نیز داریم. به این معنا که اگر عددی در غالب رشته باشد توانایی تبدیل آن به عدد را داریم. یا میتوانیم در صورت نیاز عددی را به رشته تبدیل کنیم.
همچنین در برخی موارد پیش می‌آید که نیاز داریم در یک عدد اعشار تنها از قسمت صحیح آن استفاده کنیم. این کار هم با استفاده از کَست قابل انجام است:
a = '2.3'
print(a,'before casting',type(a))
a = float(a)
print(a,'after casting',type(a))
2.3 before casting <class 'str'>
2.3 after casting <class 'float'>
a = 3.14
print(a,'before casting',type(a))
a = str(a)
print(a,'after casting',type(a))
a = float(a)
print(a,'after casting again',type(a))
a = int(a)
print(a,'after casting again from float to int',type(a))
3.14 before casting <class 'float'>
3.14 after casting <class 'str'>
3.14 after casting again <class 'float'>
3 after casting again from float to int <class 'int'>

به خاطر داشته باشید برخی از توابع در حالت عادی خروجی چاپی ندارند مانند type، به این معنا که اگر چند مورد از این توابع را پشت هم صدا کنید تنها آخرین عمل شما نمایش داده می‌شود. نمایش آخرین مقدار هم تنها به دلیل استفاده شما از ژوپیتر است زیرا ژوپیتر این امکان را به شما می‌دهد که خروجی یک تابع را بدون استفاده از تابع print ببینید. بنابراین برای مشاهده تمام خروجی‌ها حتما از print استفاده کنید.
a = "a string"
b = 123
type(a)
type(b)
int
print("a's type is",type(a))
print("b's type is", type(b))
a's type is <class 'str'>
b's type is <class 'int'>

انواع دیگری از متغیرها که بعدا با آنها بیشتر آشنا می‌شوید به صورت زیر هستند:
b = True #  بولین که دو مقدار درست و غلط را به خود میگیرد
print(b, type(b))
True <class 'bool'>
l = [1,2,3,4] #لیست
print(l, type(l))
[1, 2, 3, 4] <class 'list'>
t = (1,2,3,4) # تاپل
print(t, type(t))
(1, 2, 3, 4) <class 'tuple'>
st = {1,2,2,3,4,5} # مجموعه
print(st, type(st))
{1, 2, 3, 4, 5} <class 'set'>
d = {'key1':1, 'key2':2} # دیکشنری
print(d, type(d))
{'key1': 1, 'key2': 2} <class 'dict'>
بازگشت به فهرست

در پایتون و تمامی زبان‌های برنامه نویسی دیگر، برای نوشتن یک کد نیاز به مجموعه ای از عبارات و دستورات دارید. هر خطی از کد که نوشته می‌شود مجموعه‌ای از دستورات و عبارات است. برای مثال کلمه print یک دستور و مقادیری که درون پرانتز آن قرار می‌گیرند عبارت است.
تمامی کلمات کلیدی نوعی دستور هستند. برای مثال کلمه بررسی شرط یا if یک نوع دستور است که مسئولیت آن بررسی درستی عبارتی است که درون آن قرار می‌گیرد. برخی از عبارات را در ادامه با هم می‌بینیم:
1>2
False
1<2
True
1==1
True
2<=2
True
2<2
False

برخی عبارات بسیار ساده هستند. برای مثال عملیاتی مانند + و یا - برخی از عملگرهای ساده‌ای هستند که کار مشخص خود را انجام می‌دهند.
* عملگرمربوط به ضرب دو مقدار
/ عملگر مربوط به تقسیم
** عملگر مربوط به توان
% باقی مانده عدد اول نسبت به عدد دوم را نشان میدهد
// خارج قسمت عدد اول نسبت به عدد دوم را نشان میدهد

همچنین عملگرهای دیگری هم هستند که برای بررسی صحیح یا غلط بودنِ وضعیت دو مقدار نسبت به هم از آنها استفاده می‌شود. برای مثال:
== آیا دو مقدار با هم برابرند
=! آیا دو مقدار با هم برابر نیستند
< آیا مقدار اول بزرگتر از مقدار دوم است
> آیا مقدار اول کوچکتر از مقدار دوم است
=< آیا مقدار اول بزرگتر مساوی از مقدار دوم است
=> آیا مقدار اول کوچکتر مساوی از مقدار دوم است

از جمله برخی دستورات ساده می‌توان به دستورات شرطی و دستور حلقه اشاره کرد. دستور شرطی با عبارت ifشروع می‌شود. همانطور که در انگلیسی نیز از این کلمه استفاده می‌شود، در صورت استفاده از آن به دنبال درستی و یا نا درستی عبارت بعد آن هستیم:
برای مثال اگر عدد 1 بزرگتر از 2 باشد:
if 1>2:

همانطور که مشخص است منتظر یک عبار آنگاه هستیم ...
به عبارت بعد if عبارت شرطی می‌گویند که در صورت درست بودن آن وارد مرحله بعد در شرط می‌شود که همان عبارت آنگاه است و همچنین اگر عبارت شرطی درست نباشد، از دستورات داخل شرط صرف نظر می‌شود.
به مرور با این مطالب با مثال‌های متعدد بیشتر آشنا می‌شویم. به مثال‌های زیر توجه کنید:
a = 1
b = 1.1
if a>b: #عبارت شرطی درست نیست پس وارد عبارت آنگاه که پرینت است نمیشویم
    print('a is bigger than b')
if a<b:# عبارت شرطی درست است پس وارد آنگاه میشویم
    print('a is smaller than b')
    
a is smaller than b
بازگشت به فهرست

با دانستن اطلاعات بالا می‌توانیم برخی از برنامه‌های ساده را نوشته و اجرا کنیم.
# محاسبه مساحت دایره
pi = 3.14159 # تعریف عدد پی
radius = 2.2 # تعریف اندازه شعاع
area = pi*(radius**2) # محاسبه مساحت با فرمول مریوطه
print(area) # نمایش مقدار مساحت
15.205295600000001
# حال استفاده از مقادیر بالا که از قبل تعیین شده
radius = radius + 1 # افزودن 1 به مقدار قبلی
print(area)     # در حال حاضر مقدار مساحت تغییری نکرده است
area = pi*(radius**2) # مساحت را دوباره حساب میکنیم 
print(area) # حال مساحت تغییر میکند
15.205295600000001
32.169881600000004
#  جا به جایی دو متغیر با هم
x = input('Enter value of x: ')
y = input('Enter value of y: ')
temp = x
x = y
y = temp

print('The value of x after swapping: {}'.format(x)) # نوعی دیگر از روش های پرینت کردن
print('The value of y after swapping: {}'.format(y))
Enter value of x: 10
Enter value of y: 5
The value of x after swapping: 5
The value of y after swapping: 10
# نوعی دیگر از جا به جایی دو متغیر با هم
x = 5
y = 10

x, y = y, x
print("x =", x)
print("y =", y)
x = 10
y = 5
بازگشت به فهرست اصلی

مقدمه

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

به چند مثال ساده زیر توجه کنید:
if 1>2:
    print('یک محال')
if 2>1:
    print('یک اتفاق همیشگی')
یک اتفاق همیشگی
name = 'Niloofar'
if name=='Niloofar': # بررسی برابری عبارت با استفاده از دو مساوی
    print('Your name is Niloofar')
else: # در صورتی که عبارت شرطی برقرار نباشد وارد این قسمت میشود
    print('Your name in not Niloofar but '+name)# نوعی دیگر از چاپ
Your name is Niloofar

در نمونه بالا عبارتی جدید مشاهده می‌کنید. در کل دستور if با دو عبارت elif و else همراه است. دستور elif به معنای "اگرنه" است و در صورتی بررسی می‌شود که عبارت شرطی قبلی درست نباشد. دستور else نیز حالتی است که هیچ یک از دستورات شرطی قبلی بر قرار نباشند و در نهایت به این دستور می‌رسیم. بنابراین بدون هیچ شرطی وارد این دستور می‌شود.
به خاطر داشته باشید که این دو دستور همیشه به دنبال دستور if می‌آیند و بدون آن بی معنی هستند.
به مثال‌های زیر توجه کنید:
n = input('Enter a number: ') #به خاطر داشته باشید عددی که وارد میکنید به صورت رشته است و باید به عدد تبدیل شود
n = int(n)
if n>0:
    print('Your number is positive')
elif n<0:
    print('Your number is negative')
else:
    print('Your number is 0')
Enter a number: 0
Your number is 0

در مثال بالا در صورتی که عدد مثبت وارد کنید، عبارت داخل if اجرا می‌شود و دیگر دستورات بعدی که elif و else هستند خوانده نمی‌شوند. اگر عدد وارد شده منفی باشد، دستور if بررسی می‌شود و چون برقرار نیست بدون وارد شدن به کد داخل آن به بررسی دستور بعدی می‌رود. از آنجایی که عدد منفی است و این شرط برقرار می‌شود برنامه های داخل آن خوانده می‌شوند و از دستورات شرطی بعدی صرف نظر می‌شود. در صورتی که عدد وارد شده صفر باشد، دستور if بررسی می‌شود سپس دستور elif بررسی می‌شود و در آخر بدون هیچ بررسی اضافه‌ای وارد else می‌شود و دستورات آن را اجرا می‌کند.
حال یک بازی میسازیم. در این بازی یک عدد به طور تصادفی توسط کامپیوتر بین 1 تا 10 انتخاب می‌شود. سپس از شما خواسته می‌شود که عدد را حدس بزنید. در نهایت حدس شما با حدس برنامه مقایسه می‌شود و نتیجه به شما اعلام می‌شود.
### این قسمت مربوط به حدس است و فعلا نیازی به یادگیری آن نیست ####
from numpy.random import randint
n = randint(1,11)
################################################################
guess = int(input('Enter your guess: ')) # عدد حدسی خود را وارد میکنید. این عدد همینجا تبدیل به اینت میشود

if guess==n:
    print('حدس شما درست بود')
elif guess<1 or guess>10:
    print('شما بین 1 تا 10 حدس نزدید')
elif guess>n:
    print('حدس شما بیشتر از عدد بود')
else:
    print('حدس شما کمتر از عدد بود')
    
print('The number was',n)
Enter your guess: 2
حدس شما کمتر از عدد بود
The number was  8

با استفاده از شرط‌های تو در تو می‌توان حالت های بیشتری را بررسی کرد.
شرط‌های تو در تو را می‌توان به طورت زیر پیاده‌سازی کرد:
### این قسمت مربوط به حدس است و فعلا نیازی به یادگیری آن نیست ####
from numpy.random import randint
n = randint(1,11)
################################################################
guess = int(input('Enter your guess: ')) # عدد حدسی خود را وارد میکنید. این عدد همینجا تبدیل به اینت میشود

if guess==n:
    print('حدس شما درست بود')
elif guess<1 or guess>10:
    print('شما بین 1 تا 10 حدس نزدید')
elif guess>n:
    print('حدس شما بیشتر از عدد بود')
    print("یک عدد دیگر بین 1 و  "+str(guess)+" انتخاب کنید")
    newguess = int(input('Enter your new guess: '))
    if guess==n:
        print('حدس شما درست بود')
    elif newguess<1 or newguess>10:
        print('شما بین 1 تا 10 حدس نزدید')
    elif newguess>n:
        print('حدس شما بیشتر از عدد بود')
    else:
        print('حدس شما کمتر از عدد بود')
else:
    print('حدس شما کمتر از عدد بود')
    print("یک عدد دیگر بین "+str(guess)+" و 10 انتخاب کنید")
    newguess = int(input('Enter your new guess: '))
    if guess==n:
        print('حدس شما درست بود')
    elif newguess<1 or newguess>10:
        print('شما بین 1 تا 10 حدس نزدید')
    elif newguess>n:
        print('حدس شما بیشتر از عدد بود')
    else:
        print('حدس شما کمتر از عدد بود')
    
print('The number was',n)
Enter your guess: 5
حدس شما کمتر از عدد بود
یک عدد دیگر بین 5 و 10 انتخاب کنید
Enter your new guess: 9
حدس شما بیشتر از عدد بود
The number was 7

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

مقدمه

در فصل قبل در مورد عبارت های شرطی صحبت کردیم و یک بازی نوشتیم که در آن باید یک عدد را که توسط کامپیوتر انتخاب شده بود را حدس می‌زدیم. پیش بردن این برنامه تنها با عبارت های شرطی بسیار زمانبر است. برای آنکه بتوانیم با شیوه بهتری کد بنویسیم نیازمند حلقه‌ها نیز هستیم.
حلقه‌ها در پیاده سازی برنامه‌ها به شدت به کمک برنامه نویس می‌آیند. یکی از استفاده‌های آنها(همانطور که گفته شد) در پیاده‌سازی برنامه‌هایی است که نیازمند تکرار یک سری کد هستند.
برای مثال فرض کنید می‌خواهید اعداد 1 تا 10 را به ترتیب چاپ کنید و یا یک دنباله را پیاده‌سازی کنید و یا کارهایی از این دست؛ در این حالت‌ها نیازمند استفاده از حلقه‌ها هستید.
برای نوشتن حلقه در پایتون می‌توان از دو مدل for و while استفاده کرد. هر یک از این حلقه‌ها، ویژگی مربوط به خود را دارند و بنا به این ویژگی و کاری که می‌خواهید در آن از این دو استفاده کنید می‌توانند گزینه بهتری برای کد شما باشند. در این فصل با هر دوی این نمونه‌ها آشنا می‌شویم.

حال با هم دو نمونه ساده از یک برنامه ساده جهت چاپ اعداد از 0 تا 9 را می‌بینیم و آنها را به دقت و ریز به ریز بررسی می‌کنیم:
for i in range(10):
    print(i)
0
1
2
3
4
5
6
7
8
9

در این کد بالا برای نوشتن اعداد از 0 تا 9 تنها از 2 خط کد استفاده شده است. در خط اول عبارت for را داریم. برای پیاده‌سازی حلقه for به چند قسمت نیاز داریم:
1. متغیری که آن را در حلقه جلو می‌بریم (در اینجا از i استفاده شده است)
2. یک ویژگی قابل جلو بردن، برای مثال یک لیست یا ماژول range* که یک ویژگی از پیش تعیین شده است و در آن می‌توان تکرار** را تعریف کرد.

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

* عبارت range یک تابع است (با توابع در ادامه درس بیشتر آشنا می‌شویم) که در آن می‌توانیم به چند روش پیش برویم. ساده‌ترین حالت استفاده از آن که در این کد از آن بهره گرفته شده است آوردن تنها مقدار پایانی است. برای مثال range(10) به این معنا است که از 0 شروع کن و تا یکی قبل از 10 پیش برو که همان 9 است. حالت بعدی زمانی است که هم شروع و هم پایان رو برای آن تعیین می‌کنیم. برای مثال range(1,11) که در این حالت عدد ما به جای شروع از 0، از 1 شروع می‌شود و تا 10 جلو می‌رود و دیگر به 11 نمی‌رسد. و در حالت آخر می‌توانیم قدم را هم برای آن مشخص کنیم. برای مثال می‌گوییم دوتا دوتا جلو برود. در این صورت داریم range(1,11,2) که در آن 2 عدد قدم است و بعد از 1، 3 و سپس 5 و ...، تا 9 را داریم و دیگر 11 اجرا نمی‌شود.
نکته: به خاطر داشته باشید که در range تنها اعداد صحیح قرار می‌گیرند و به محض اعشاری شدن، به شما خطا می‌دهد.
** منظور از تکرار کلمه iteration است. در iterator ها یک اتفاق به ترتیبی که در آن تعریف شده جلو می‌رود. range یک نوع iterator است.

در پایین همان برنامه بالا را با استفاده از حلقه while تعریف کرده‌ایم:
i = 0
while i<10:
    print(i)
    i=i+1
0
1
2
3
4
5
6
7
8
9

حلقه while مانند یک عبارت شرطی می‌ماند؛ با این تقاوت که تا زمانی که شرط آن برقرار نشود از محدوده آن بیرون نمی‌آید. بنابراین اگر بنویسید while(True): یا هر شرطی که هیچ وقت اتفاق نمی‌افتد را به عنوان شرط خروجی بگذارید، هیچگاه از این حلقه خارج نمی‌شود و رم شما بعد از مدتی پر شده و پیام خطا دریافت می‌کنید. به خاطر داشته باشید که این عبارت مانند if است و اگر عبارت غلطی در ورودی آن بگذارید وارد while نخواهد شد.
بنابراین برای تولید یک حلقه با استفاده از while تنها به یک شرط نیاز داریم؛ اما باید حواسمان باشد در داخل این حلقه طوری برنامه نوشته شود که به آن شرط برسیم. مثلا در برنامه بالا، شرط ما رساندن متغیر تعریف شده i به عدد 9 است ( از آنجایی که گفته‌ایم i اکید کوچکتر از 10 باشد). سپس با استفاده از عبارت i = i+1 در هر بار تکرار حلقه یک واحد به آن اضافه کردیم تا زمانی که به 10 برسد و حلقه دیگر ادامه پیدا نکند و قبل از چاپ از آن خارج شود.

حال چند مثال دیگر را با هم در زیر می‌بینیم:
ابتدا دنباله زیر را پیاده‌سازی می‌کنیم:
a(n) = 2*a(n-1), a(1) = 1
در دنباله بالا بنا به عددی که انتخاب می‌شود به همان تعداد 2 در مقدار قبلی ضرب می‌شود. به طور کلی 2 به توان عدد n می‌رسد.
# پیاده سازی با for
a = 1
n = 10
for i in range(n):
    a = 2*a
print(a)
1024
# پیاده سازی با while
a = 1
n = 10
i = 0
while i<n:
    a=2*a
    i+=1 #همان i=i+1
    # عبارت بالا نوعی دیگر برای پیاده سازی این نوع عبارت ها است و برای تمامی اعمال ریاضی کاربردی است
print(a)
1024

حال فرض کنید می‌خواهیم اعداد را با یک فاصله کنار هم چاپ کنیم. اینجا تنها مهارتی که لازم است نوع استفاده از print است:
# with for:
n=5
for i in range(n):
    print(i, end='\t')# اند مشخص میکند که پس از چاپ تابع چه کاری انجام دهد و ما به آن گفتیم که از تَب استفاده کند
    
0	1	2	3	4	
# with while:
n = 5
i = 0
while i<n:
    print(i, end = '\t')
    i+=1
0	1	2	3	4	

با دانستن مراحل بالا به سراغ چاپ یک ماتریس می‌رویم. همانطور که می‌دانید برای نوشتن یک ماتریس(منظور نوشتن اعداد به شکل ماتریسی است و نه خود ماتریس در پایتون) نیاز است تا اعداد به تعداد کنار هم و به تعدادی زیر هم نوشته شوند. در این حالت نیاز است از حلقه‌های تو در تو استفاده شود. در ادامه با استفاده از for یک نوشتار ماتریسی را پیاده سازی می‌کنیم.
# پیاده سازی نوشتاری یک ماتریس 3 در 3
for i in range(3):# تعداد سطر ها را مشخص میکند
    for j in range(3):# تعداد ستون ها را مشخص میکند
        print(1, end = '\t')
    print()#برای آن که در انتهای خط یک اینتر داشته باشیم و به خط بعد برویم
1	1	1	
1	1	1	
1	1	1	

با استفاده از مثال بالا یک ماتریس 4 در 4 بنویسید که درایه های آن از 1 تا 16 برود. (این مثال را خود پیاده سازی کنید)

حال بازی قبل را که حدس زدن عدد بود با استفاده از حلقه تکمیل می‌کنیم. من در اینجا از حلقه while استفاده می‌کنم.
### این قسمت مربوط به حدس است و فعلا نیازی به یادگیری آن نیست ####
from numpy.random import randint
n = randint(1,11)
################################################################
guess = int(input('Enter your guess: ')) # عدد حدسی خود را وارد میکنید. این عدد همینجا تبدیل به اینت میشود

while guess!=n: #تبدیل ایف به وایل
    if guess<1 or guess>10:
        print('شما بین 1 تا 10 حدس نزدید')
    elif guess>n:
        print('حدس شما بیشتر از عدد بود')
    else:
        print('حدس شما کمتر از عدد بود')
    guess = int(input('Enter your guess: ')) # گرفتن دوباره حدس قبل از تکرار دوباره حلقه
    

print('حدس شما درست بود')
print('The number was',n)
Enter your guess: 5
حدس شما کمتر از عدد بود
Enter your guess: 7
حدس شما درست بود
The number was 7

در پایان نیاز است در مورد عملگر break و کاربرد آن در حلقه ها نیز صحبت کنیم. در برخی موارد نمی‌توانیم شرط خاصی در ابتدا برای حلقه while تعیین کنیم و یا پس از اتفاقی می‌خواهیم به کار حلقه پایان بدهیم. در این صورت می‌توانیم با استفاده از عبارت شرطی if، اگر اتفاق مورد نظر افتاد به کار حلقه پایان بدهیم و این کار بدون در نظر گرفتن شرط while و ادامه تکرارهای for اتفاق می‌افتد. نمونه ای از این عملکرد را در زیر می‌بینیم:
# نمونه ای ساده در استفاده از برک در فور
for i in range(2,100000):
    print(i)
    if i%97==0:
        break
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# حال بازی خود را جوری طراحی میکنیم که اگر کاربر بین 1 تا 10 انتخاب نکرد جریمه شود
### این قسمت مربوط به حدس است و فعلا نیازی به یادگیری آن نیست ####
from numpy.random import randint
n = randint(1,11)
################################################################
guess = int(input('Enter your guess: ')) 

while guess!=n:
    if guess<1 or guess>10:# اگر کاربر قوانین بازی را رعایت نکند از بازی منع میشود
        print('شما بین 1 تا 10 حدس نزدید. از بازی خارج میشوید')
        break # در اینجا از حلقه خارج میشویم 
    elif guess>n:
        print('حدس شما بیشتر از عدد بود')
    else:
        print('حدس شما کمتر از عدد بود')
    guess = int(input('Enter your guess: ')) 

if guess == n: # به این شرط نیاز داریم تا اگر کاربر از قوانین سرپیچی کرد و از حلقه خارج شد چاپ پایین اجرا نشود
    print('حدس شما درست بود')

print('The number was',n)
Enter your guess: 3
حدس شما کمتر از عدد بود
Enter your guess: 11
شما بین 1 تا 10 حدس نزدید. از بازی خارج میشوید
The number was 7

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

مقدمه

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

برای تعریف یک تابع نیازمند چند بخش هستیم.
1. تعریف کلمه کلیدی def
2. نامی که برای آن تابع در نظر داریم
3. تعریف نام برای ورودی هایی که قرار است در تابع از آن ها استفاده کنیم
4. دو نقطه که در تمامی تعاریف ( همانطور که قبلا در شرط و حلقه هم دیدیم) باید حتما آورده شود
5. تعریف بدنه تابع یا همان عملیاتی که قرار است برروی ورودی انجام گیرد
6. و در نهایت برگرداندن خروجی مد نظر با استفاده از کلمه کلیدی return

تابع پرینت نیز یکی از همین انواع است. یک یا چند مقدار را به عنوان ورودی می‌گیرد و کار آن نمایش این ورودی‌ها در خروجی سیستم است. غیر از ورودی های نمایشی متغیرهای دیگری هم می‌تواند بگیرد که تنظیمات نمایش خروجی را تغییر می‌دهند؛ مانند تغییر کاراکتر پایانی از enter به tab و یا space و بسیاری ویژگی‌های دیگر که قابل تغییر هستند.
برای درک بهتر آنچه گفته شده به چند مثال ساده زیر توجه کنید:
# برنامه ای برای بازگرداندن جمع 3 عدد
def add3(a,b,c):
    s = a+b+c
    return s
add3(1,2,3)# توجه کنید که این خط نمایش داده نمیشود زیرا آن زا پرینت نکرده ایم و این باعث میشود نمایش داده نشود
add3(2,2,3)
7
print(add3(2,2,2))
print(add3(3,4,5))
6
12
# شما همچنین میتوانید خروجی را در یک متغیر ذخیره کنید و سپس از آن متغیر استفاده کنید
khoruji = add3(1,2,3)
print(khoruji)
6
# تابعی برای تبدیل کیلومتر به مایل

def KM2ML(kilometers):
    # conversion factor
    conv_fac = 0.621371
    # calculate miles
    miles = kilometers * conv_fac
    return miles

# مقدار کیلومتر را از کاربر میگیریم
kilometers = float(input("Enter value in kilometers: "))
# خروجی تابع را در متغیر زیر ذخیره میکنیم
ml = KM2ML(kilometers) # به خاطر داشته باشید که متغیری که در تابع تعریف میکنید میتواند هم نام متغیری باشد که به آن میفرستید
#                       اما این دو متغیر در حافظه دو متغیر جدا هستند و تنها نام مشابه دارند
# در نهایت آن ها را نمایش میدهیم
print('%0.2f kilometers is equal to %0.2f miles' %(kilometers,ml))
Enter value in kilometers: 12
12.00 kilometers is equal to 7.46 miles

حال شما یک برنامه بنویسید که برعکس کار بالا را انجام بدهد. به این معنا که مایل را به کیلومتر تغییر دهید:

تا اینجا به جز تابع print که بسیار از آن استفاده کردیم، توابع دیگری نیز بودند که بدون آن که بدانیم از آن ها استفاده کردیم. تابع type() یکی دیگر از این توابع است. همچنین تمامی کست ها با استفاده از نوعی تابع انجام می‌گیرند:
int, float, str
برخی توابع دیگر هم هستند که هنوز با آنها آشنا نشدیم و به صورت ویژگی‌هایی درون یک ویژگی دیگر قرار دارند. برای مثال وقتی یک رشته را تعریف می‌کنیم، توابعی از پیش تعیین شده برای آن وجود دارد که می‌تواند تغییراتی در آن به وجود بیاورد و یا بخش خاصی از آن را برگرداند. در لیست‌ها نیز این توابع وجود دارند. تابعی داخلی در لیست موجود است که آن را مرتب می‌کند و یا جایگاه یک مقدار را به شما می‌دهد.
از این دست توابع به وفور در کلاس‌های مختلف پایتون یافت می‌شوند. در فصل‌های آتی که با این کلاس‌های مختلف آشنا می‌شویم، با توابع آنها نیز بیشتر آشنا می‌شویم.
با هم چند مثال دیگر از برنامه‌های ترکیبی از مطالبی که تا اینجا خوانده ایم را ببینیم:
# در این برنامه میبینیم که آیا یک عدد زوج است یا نه:
def is_even(number):
    if number%2==0:
        return True
    return False #در این خط از اِلس استفاده نکردیم زیرا درصورتی که عبارت شرطی بالا درست باشد ریترن میشود و دیگر به این خط نمیرسد
print(is_even(2), is_even(3))
True False
# در این برنامه از برنامه بالا استفاده میکنیم و برای یک تعداد خاص پرینت میکنیم که آیا عدد فرد است یا زوج
def check_odd_even(n):
    for i in range(n):
        if is_even(i): # استفاده از تابع قبلی در درون این تابع
            print(i, 'زوج است')
        else:
            print(i, 'فرد است')
check_odd_even(10)
0 زوج است
1 فرد است
2 زوج است
3 فرد است
4 زوج است
5 فرد است
6 زوج است
7 فرد است
8 زوج است
9 فرد است
# چاپ کردن تمام فاکتور های یک عدد:
def print_factors(x):
    print("The factors of",x,"are:")
    for i in range(1, x + 1):
        if x % i == 0:
            print(i)
print_factors(10)
The factors of 10 are:
1
2
5
10

به جز توابعی که تا اینجا تعریف شدند، کلاس‌هایی وجود دارند که دارای توابع بسیاری هستند و برای کمک و راحت سازی برنامه‌نویسی در اختیار ما قرار داده شده‌اند. کتابخانه numpy و random از کتابخانه های بسیار اولیه هستند که هر برنامه‌نویسی در مقطعی به آنها نیاز پیدا می‌کند. کتابخانه numpy مربوط به عملیات ریاضی است و یک کتابخانه بسیار بزرگ و جامع شامل کلاس‌های بسیار است که هر کدام توابع مخصوص به خود را دارند. برای مثال برخی از توابع ریاضی به راحتی توسط نامپای قابل دسترسی هستند. نمونه های زیر را در نظر بگیرید:
# ابتدا نیاز داریم تا نامپای را صدا بزنیم و آن را فراخوانی کنیم تا بتوانیم از آن استفاده کنیم
import numpy
# حال میتوانیم از بخش های مختلف آن استفاده کنیم
print('sqrt(4) :', numpy.sqrt(4)) # تابع مربوط به جذر
print('abs(-10) :',numpy.abs(-10)) # قدرمطلق
print('sin(pi/2) :',numpy.sin(numpy.pi/2)) # محاسبه سینوس 90 درجه یا پی دوم
print('matrix zeros 2x2:', numpy.zeros((2,2))) # ساخت یک ماتریس صفر 2 در 2
sqrt(4) : 2.0
abs(-10) : 10
sin(pi/2) : 1.0
matrix zeros 2x2: [[0. 0.]
 [0. 0.]]

بنا به استفاده میتوانید با یک سرچ ساده از توابع بسیار متنوع نامپای استفاده کنید. همچنین کتابخانه رندم با آن که به صورت جداگانه قابل فراخوانی و استفاده است، در داخل نامپای نیز وجود دارد و میتوانید از آن نیز استفاده کنید. اما اگر بخواهیم random را فراخوانی کنیم به صورت زیر خواهد بود:
import random
for _ in range(10):
    print(random.randint(1,10))
4
2
7
9
3
9
8
7
1
10

در کد بالا برخی موارد متفاوت وجود دارند. ابتدا از for استفاده کردیم و به جای متغیر مربوط به شمارنده از _ استفاده کردیم. از آنجایی که نیاز به متغیر شمارنده نداریم، می‌توانیم به جای تعریف یک متغیر در این جایگاه از _ استفاده کنیم و آن را ندید بگیریم. در قسمت بعد از randint استفاده کرده‌ایم؛ به این معنی که یک عدد تصادفی صحیح می‌خواهیم و عدد 1 و 10 نیز بازه بسته مورد نظر ما برای این کار است. تابع random نیز خود یک عدد تصادفی بین 0 تا 1 در اختیار شما قرار می‌دهد:
random.random()
0.06604910926804664

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

مقدمه

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

در مثال زیر میخواهیم یک بهره وامی ساده را با استفاده از فرمول زیر محاسبه کنیم:
Simple Interest = (P x T x R)/100
که در آن P مقدار وامی که می‌گیرید، T مدت زمانی است که پول را باز می‌گردانید و در نهایت R درصد بهره است. اگر بخواهیم این مقادیر را به صورت ورودی به یک تابع بدهیم، کد مربوط به آن به صورت زیر خواهد بود:
p = float(input('Enter principle amount: ')) # آن را به عدد اعشار کست کردیم
t = int(input('Enter time(days): ')) # آن را به عدد صحیح کست کردیم
r = float(input('Enter rate: ')) # آن را به عدد اعشار کست کردیم

def cal_interest(p,t,r):
    return (p*t*r)/100

cal_interest(p,t,r)
Enter principle amount: 1000000
Enter time(days): 30
Enter rate: 8.5





2550000.0
حال اگر نوع بهره را به یک حالت پیچیده تر تبدیل کنیم، تابع را برای آن پیاده سازی کنید. فرمول آن به صورت زیر است:
A = P(1 + R/100)^t
Compound Interest = A – P
حال فرض کنید می‌خواهید نمرات یک کلاس را بگیرید و میانگین و واریانس آنها را حساب کنید.
این کار را به صورت زیر انجام می‌دهید:
# ابتدا فرض میکنیم کلاس شامل 5 نفر است و نمرات آن ها را با استفاده از فور میگیریم
n = 5
s = 0 # یک متغیر برای جمع تمامی نمرات تعریف میکنیم.
# میخواهیم نمرات را دانه دانه از افراد بپرسیم و بالافاصله جمع بزنیم
for _ in range(n):
    newScore = float(input('What is your score? '))
    s = s+newScore
# حال معدل کلاس را در زیر نمایش میدهیم
print('معدل کلاس برابر است با :', s/n)
What is your score? 10
What is your score? 15
What is your score? 17
What is your score? 14
What is your score? 9
معدل کلاس برابر است با : 13.0
یکم آن را پیچیده تر می‌کنیم. این بار واریانس را نیز حساب می‌کنیم برای آن به جای استفاده از فرمول معروف و اولیه، از فرمول زیر استفاده می‌کنیم که اثبات تبدیل از فرمول اولیه آن نیز قابل مشاهده است:
n = 5
s = 0
varInsideSum = 0 # متغیر اولیه برای محاسبه سام داخلی را نیز تغریف میکنیم
for _ in range(n):
    newScore = float(input('What is your score? '))
    s = s+newScore
    varInsideSum = varInsideSum+ newScore**2
# حال معدل کلاس را در زیر نمایش میدهیم
mean = s/n
print('معدل کلاس برابر است با :', mean)
print('واریانس کلاس برابر است با :', (varInsideSum/n) - mean**2)
What is your score? 20
What is your score? 15
What is your score? 16
What is your score? 13
What is your score? 17
معدل کلاس برابر است با : 16.2
واریانس کلاس برابر است با : 5.360000000000014
حال با دانستن این داده ها به سراغ مرحله بعد می‌رویم. این بار به جای آن که از for استفاده کنیم، از while استفاده می‌کنیم و می‌گوییم تا زمانی محاسبه را ادامه بدهد که عبارت ورودی برابر عدد -1 است.
آیا می‌توانید این برنامه را خود پیاده سازی کنید؟
در برنامه بعد یک تابع مینویسیم که با توجه به شعاع داده شده به آن، مساحت یک دایره را محاسبه کند:
def circle_area(r):
    import numpy as np # در اینجا به نامپای نام ان پی دادیم تا در صدا کردن آن راحت تر باشم
    return np.pi*r*r

radius = 10
circle_area(radius)
314.1592653589793
# حال برای محیط دایره مانند کد بالا پیاده سازی کنید:
def circle_perimeter(r):
    # در اینجا پَس را پاک کنید و کد خود را بنویسید
    pass 

radius = 10
circle_perimeter(radius)

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

مقدمه

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

در ادامه به سراغ انواع ترکیب رشته‌ها با هم می‌رویم:
s = "I'm here to learn how to code with Java."
s
"I'm here to learn how to code with Java."
#اندازه یک رشته را بر میگرداند 
len(s)
40
# میگوییم که اول تا اخر یک رشته را به ما بدهد
s[0:len(s)]
"I'm here to learn how to code with Java."
# همان عملکرد بالا را دارد که به زبان ساده تر بیان شده است
s[:]
"I'm here to learn how to code with Java."
# چک میکنیم که آیا با هم برابرند یا نه؟
s[0:len(s)]==s[:]
True
#حذف 5 کاراکتر آخر شامل جاوا و نقطه
s[:-5]
"I'm here to learn how to code with "
# حال به جای جاوا کلمه پایتون را جایگذاری میکنیم
s[:-5]+'python.'
# همانطور که میبینید در اینجا از جمع استفاده کردیم تا دو رشته را به هم بچسبانیم
"I'm here to learn how to code with python."
# حال این جایگذینی را ذخیره میکنیم و آن را نمایش میدهیم
new_s = s[:-5] + 'python.'
print(new_s)
I'm here to learn how to code with python.
# با دستور زیر تمامی حروف در رشته کوچک میشوند
s_lowered = new_s.lower()
s_lowered
"i'm here to learn how to code with python."
# با دستور زیر، تمامی حروف در رشته بزرگ میشوند
s_uppered = s_lowered.upper()
s_uppered
"I'M HERE TO LEARN HOW TO CODE WITH PYTHON."
#و در دستور زیر جمله به حالت اصلی خود برمیگردد، به این منظور که کلمه اول در جمله با حرف بزرگ آغاز میشود
s_cap = s_uppered.capitalize()
s_cap
"I'm here to learn how to code with python."
#در دستور زیر تعداد یک کاراکتر و یا یک زیر رشته در رشته اصلی شمرده و نمایش داده میشود
s.count('a')
3
# دستور زیر جایگاه شروع اولین اتفاق یک کاراکتر و یا زیررشته را نشان میدهد
s.index('to')
9
#حال در دستور زیر همان عملکرد جایگذینی بالا به صورت اتوماتیک توسط توابع آماده اتفاق می افتد.
new_s = s.replace('Java','python')
print(s)
print(new_s)
I'm here to learn how to code with Java.
I'm here to learn how to code with python.
# حال اگر بخواهیم یک رشته را چندین بار تکرار کنیم کافی است آن را ضرب کنیم
print('*--*'*10)
# در زیر به عنوان خروجی رشته بالا 10 بار پشت هم تکرار میشود. انگار رشته را 10 بار به خودش چسبانده ایم
*--**--**--**--**--**--**--**--**--**--*
# میتوانید به راحتی وجود یک کاراکتر یا زیر رشته را در یک رشته بررسی کنید
'am' in s
False
'Java' in s
True
#حتی اگر بخواهید ببینید آیا زیر رشته ای در یک رشته نیست نیز میتوانید از یک نات استفاده کنید
'python' not in s
True
حال برخی توابع رشته را بررسی میکنیم که خود بررسی کننده هستند. این توابع می‌توانند چک کنند که آیا یک رشته به صورت کامل عددی است، حرفی است و یا تمام کاراکترهای آن کوچک هستند:
'1234'.isnumeric()
True
'1d3df'.isnumeric()
False
'3.14'.isnumeric() # then you can not use them to identify float numbers
False
'1234'.isalpha()
False
'abc'.isalpha()
True
'abc'.islower()
True
'ABC'.isupper()
True
برخی دیگر از توابع نیز هستند که می‌توان از آنها استفاده کرد و کاربرد های خود را دارند:
'uberraschung ist schon'.split()
['uberraschung', 'ist', 'schon']
در دستور بالا تابع split را داریم که با استفاده از آن می‌توانیم یک جمله را به صورت کلمه کلمه و یا با استفاده از کاراکتر یا زیررشته دلخواه جدا کنیم. برای مثال جدا سازی کاراکتری به نمونه زیر توجه کنید:
"let's see what can we do with this sentence? what? what can we create?".split('what')
["let's see ", ' can we do with this sentence? ', '? ', ' can we create?']
حالت معمول برای استفاده از کاراکترها برای جدا سازی، قرار دادن کاراکترهای علامت‌های پایانی به عنوان کاراکتر جداسازی هست؛ ولی همانطور که در بالا دیدیم هر چیزی قابل استفاده است.
خروجی این تابع یک لیست است که تمام زیر رشته های جدا شده را در یک لیست به شما تحویل می‌دهد. با لیست ها در فصل بعد بیشتر آشنا می‌شویم.

حال وقت آن است که تعدادی مثال از رشته ها با هم حل کنیم:
1.یک رشته را به صورت برعکس چاپ کنیم:
s = 'abcdefg'
print('First approach: ')
for i in range(len(s)-1,-1,-1):
    print(s[i], end=' ')
print()
print('Second approach: ')
print(s[::-1]) # اینجا میگوییم تمام رشته را به از -1 به عقب برود که در واقع همان آخرین مقدار است
First approach: 
g f e d c b a 
Second approach: 
gfedcba
2. اندازه یک رشته را بدون استفاده از تابع len به دست بیاورید:
s = 'Python  Claassss !'
counter = 0
for ch in s:
    counter+=1 # same as --> counter=counter+1
print('length of String is '+str(counter))
length of String is 18
3. تابعی برای پیدا کردن تعداد یک کاراکتر خاص در رشته بدون استفاده از تابع آماده:
s = 'aaa, This is a sentence with a lot of a, aaaa.'
def countCharacter(char):
    counter = 0
    for ch in s:
        if ch==char:
            counter+=1 # same as --> counter=counter+1
    print('Count of character \''+char+'\' in this sentence is '+str(counter))
    # \' is a way to add ' in a string defined with ''
countCharacter('a')
Count of character 'a' in this sentence is 10
4. چک کنیم که یک رشته متقارن است یا خیر:
در راه حل زیر نوع پیچیده تری از برنامه نویسی را می‌بینید. برای بررسی متقارن بودن یا نبودن از یک بولین (boolean) استفاده شده است. برای چاپ نیز از یک روش یک خطی جهت بررسی بولین بالا استفاده شده است که if و else را یکجا در خود دارد. در حال حاضر نیاز به یادگیری این روش و فهم آن نیست اما بد نیست بدانیم روش‌های دیگری نیز برای کد زدن هستند.
snt = s = 'asdsa'

isPalindrome = True
while len(s)>1:
    if s[-1]!=s[0]:
        isPalindrome = False
        break
    s = s[1:-1]
print('"'+snt+'" is Palindrome') if isPalindrome else print('"'+snt+'" is not Palindrome')
        
"asdsa" is Palindrome
مثال های بسیاری در مورد رشته‌ها وجود دارند که می‌توانید خود آنها را حل کنید. با یک سرچ کوچک در گوگل می‌توانید به تعداد بسیاری منبع دسترسی پیدا کنید که در آنها مثال‌های حل شده یافت می‌شوند. در اینجا به همین چند مثال بسنده می‌کنیم.
در فصل آینده با لیست‌ها و تاپل‌ها آشنا می‌شویم و مثال‌های مختلف از آنها را می‌بینیم.
بازگشت به فهرست اصلی

مقدمه

در این فصل با مفهوم های پیچیده تری در زبان برنامه نویسی پایتون آشنا می‌شویم. لیست‌ها و تاپل‌ها کاربردهای بسیاری در برنامه نویسی دارند و در موارد مختلف از آنها استفاده می‌شود. در فصل قبل نیز مشاهده کردیم که برای جدا کردن اجزای یک جمله یا متن از متدی استفاده می‌شود که داده‌ها را در نهایت در یک لیست می‌ریزد.
در این فصل با زیر بخش‌های آشنا می‌شویم:
فهرست این فصل:
  1. لیست
  2. تاپل
  3. لیست و تاپل تودرتو و ماتریس

لیست‌ها یک کلاس از پیش تعریف شده در پایتون هستند که دارای ویژگی تکرار هستند. به این معنا که در یک لیست می‌توان تعداد زیادی متغیر از هر نوع داشت. برای تعریف آنها می‌توان از دو روش استفاده کرد که با هم در ادامه می‌بینیم.
این نکته را در خاطر داشته باشید که برای ذخیره لیست‌ها نیز، مانند هر متغیر دیگری نیاز به تعریف آنها با یک نام هست:
بازگشت به فهرست
l1 = [1,2,3,4]# روش معمول تر برای تعریف یک لیست از پایه
print('l1 is ',l1)
l2 = list(range(4))# اینجا رینج را تبدیل به یک لیست کرده ایم. رینج خود یک ویژگی جدا است و با لیست متفاوت است
print('l2 is ',l2)
l1 is  [1, 2, 3, 4]
l2 is  [0, 1, 2, 3]
# تعریف یک لیست خالی
l3 = []
print(l3)
[]
# حال به لیست حالی مقدار اضافه میکنیم
l3.append('an element')
l3.append('another element')
l3.append(2)
l3.append(13)
l3.append(1.618)
print(l3)
['an element', 'another element', 2, 13, 1.618]

تابع append برای اضافه کردن المان در لیست ساخته شده و به راحتی هر نوع متغیری را به لیست اضافه می‌کند. همانطور که در متغیرهای رشته ای نیز دیدیم، متغیرهای لیستی نیز دارای تعداد بسیاری توابع داخلی هستند که در ادامه با برخی از آنها آشنا می‌شویم:
این کار را با لیست l3 که در بالا تعریف کردیم ادامه می‌دهیم. توجه داشته باشید که پس از تعریف یک متغیر و اجرای آن در یک session، تا زمان بستن آن session و یا ری استارت کردن کرنل آن متغیر قابل استفاده است.
l3.remove(13) #حذف یک المان خاص از لیست
print(l3)
['an element', 'another element', 2, 1.618]
l3.remove(13) # اگر چیزی که در لیست نیست را حذف کنیم به ارور بر میخوریم
print(l3)
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-13-bc9b9c8fe723> in <module>
----> 1 l3.remove(13) #
      2 print(l3)


ValueError: list.remove(x): x not in list
print(l3.pop()) # این دستور اخرین مقدار لیست را از آن خارج میکند و به عنوان یک مقدار به شما میدهد
print(l3)
1.618
['an element', 'another element', 2]
l3.append(3.14)
l3.append(2)
l3.append(2)
print(l3)
# میتوانید تعداد یک مقدار را در لیست جست و جو کنید
print('There is',l3.count(2),'2s in l3.')
['an element', 'another element', 2, 3.14, 2, 2]
There is 3 2s in l3.
l3.index(2) # مقدار اولین بار دیده شدنِ المانی که در ورودی برای آن مشخص کرده اید را برمیگرداند
2

تا اینجا با برخی توابع داخلی لیست آشنا شدیم. دیگر توابع هستند که برخی از آنها را در ادامه می‌بینیم و باقی را می‌توانید خود با استفاده از کلید های کمکی در ژوپیتر ببینید و یا گوگل کنید.
کلید های کمکی به صورت زیر است.
نام مد نظر را می‌زنید برای مثال l3 و پس از گذاشتن . جلوی آن دکمه shift + tab را میزنید. در این حالت انتخاب هایی که دارید به شما نمایش داده می‌شود و توابعی که برای آن کلاس تعریف شده است به شما نمایش داده می‌شود.
حال اگر بخواهیم به یک لیست تعدادی بیشتر از یک مقدار را اضافه کنیم به صورت زیر عمل می‌کنیم:
l3.extend([1.618, 123, 56, 26])
print(l3)
['an element', 'another element', 2, 3.14, 2, 2, 1.618, 123, 56, 26]
# or you can go with this method
l3 = l3 + [1.618, 123, 56, 26]
print(l3)
['an element', 'another element', 2, 3.14, 2, 2, 1.618, 123, 56, 26, 1.618, 123, 56, 26]

اما تا اینجا صرفا با توابع لیست آشنا شدیم و همانطور که متوجه شدید بسیار مشابه با رشته است. در رشته ها هر یک از کارکترها یک المان از رشته کامل حساب می‌شوند. تفاوت اصلی رشته و لیست در قابلیت تغییر در المان ها پس از تعریف آن است. به این مفهوم mutability می‌گویند. یک رشته immutable است اما یک لیست mutable است.
حال جا دارد که دسترسی به یک عضو و چگونگی تغییر آن را ببینیم:
print('first element of l3 is:', l3[0])
print('The second one is:',l3[1])
first element of l3 is: an element
The second one is: another element

بنابراین تنها با نوشتن کروشه باز و بسته و قرار دادن عدد مکانی آنها می‌توانیم به متغیر مورد نظر دسترسی پیدا کنیم.
توجه کنید که درلیست ها، جایگاه از 0 شروع می‌شود. بنابراین عدد مکان مقدار اول برابر 0 است.
نکته دیگری که باید توجه شود توانایی استفاده از اعداد منفی برای دسترسی به داده از انتهای لیست است. به مثال زیر دقت کنید:
print(l3)
print('Last element is:',l3[-1])
['an element', 'another element', 2, 3.14, 2, 2, 1.618, 123, 56, 26, 1.618, 123, 56, 26]
Last element is: 26

همانطور که می‌بینید 1- مقدار آخر لیست است، به همین ترتیب باقی نیز از طریق اعداد منفی قابل دسترسی هستند.
اما اگر بخواهیم یک مقدار خاص در لیست را تغییر بدهیم کافی است بگوییم در جایگاهی که آن مقدار قرار دارن چیز دیگری جایگزین شود.
print('previous one: ',l3)
l3[2] = 'changing 2 to this'
print('after change: ',l3)
previous one:  ['an element', 'another element', 2, 3.14, 2, 2, 1.618, 123, 56, 26, 1.618, 123, 56, 26]
after change:  ['an element', 'another element', 'changing 2 to this', 3.14, 2, 2, 1.618, 123, 56, 26, 1.618, 123, 56, 26]

مرتب کردن و برعکس کردن نیز از توابعی است که به صورت پیش فرض برای لیست ها تعریف شده است:
l4 = [2,5,1,7,3,9,45]
l4.reverse()
print(l4)
[45, 9, 3, 7, 1, 5, 2]
l4.sort()
print(l4)
[1, 2, 3, 5, 7, 9, 45]

همانطور که می‌بینید این دو تابع برروی خود لیست تغییرات می‌دهد و اگر آنها را پرینت کنید ورودی null می‌دهند زیرا هیچ return ای برای آنها تعریف نشده است.
حال چند مثال را با هم حل می‌کنیم:
1. برنامه ای که مقدار اول و آخر یک لیست را با هم جا به جا کند:
l = [7,4,6,3,5,2,9,1]
temp = l[0]# مقدار اول را در یک متغیر موقت قرار میدهیم
l[0] = l[-1]# مقدار اخر را در مقدار اول میگذاریم
l[-1] = temp# مقدار موقت را در مقدار آخر میگذاریم
print(l)
[1, 4, 6, 3, 5, 2, 9, 7]
l = [7,4,6,3,5,2,9,1]
l[0],l[-1] = l[-1],l[0] # یکجا و قبل تغییر مقدار اول را در مقدار آخر و مقدار آخر را در مقدار اول میگذاریم
print(l)
[1, 4, 6, 3, 5, 2, 9, 7]

کد بالا با استفاده از ویژگی های پایتون امکان پذیر است و کد نویسی را بسیار راحت تر می‌کند.
2. اندازه گیری تعداد المان ها در یک لیست:
l = [7,4,6,3,5,2,9,1]
counter = 0
for x in l: # you can go into a list element by element like this
    counter= counter+1
print('Length of the list is',counter)
Length of the list is 8
# ! with defult defs:
len(l)
8

3.اعداد فرد در یک لیست را نمایش دهید:
l = [7,4,6,3,5,2,9,1]
for x in l:
    if x%2==1:
        print(x)
7
3
5
9
1
l = [7,4,6,3,5,2,9,1]
# دسترسی مستقیم به مقادیر با استفاده از حلقه زیر امکانپذیر است
for i in range(len(l)):
    if l[i]%2==1:
        print(l[i])
7
3
5
9
1


4. مقادیر لیست را یکی در میان منفی کنید:
l = [7,4,6,3,5,2,9,1]
for i in range(len(l)):
    if i%2==1:
        l[i] = -l[i]
print(l)
[7, -4, 6, -3, 5, -2, 9, -1]

اما پس از آشنایی با لیست، لازم است با تاپل ها نیز آشنا شویم. تاپل بسیار شبیه به لیست است اما تفاوتی که دارد این است که مانند رشته، پس از تعریف غیرقابل تغییر یا immutable است. برای تعریف آن از پرانتز استفاده می‌شود. مانند لیست می‌تواند شامل هر نوع متغیری درون خود باشد.
چند نمونه از تاپل و توابع آن را در زیر می‌بینیم:
بازگشت به فهرست
tup1 = (1,2,3,4)
print("tup1:", tup1)
tup2 = ('elem1', 'elem2','elem3')
print('tup2:',tup2)
tup3 = ('math',12,'science',18.25)
print('tup3:',tup3)
tup1: (1, 2, 3, 4)
tup2: ('elem1', 'elem2', 'elem3')
tup3: ('math', 12, 'science', 18.25)
# empty tuple:
tup4 = ()
print(type(tup4))
<class 'tuple'>
# tuple with one emelent: !do not do this
tup5 = (21)
print('type tup5:',type(tup5))

# do this
tup5 = (21,)
print('type tup5:',type(tup5))
type tup5: <class 'int'>
type tup5: <class 'tuple'>
#گرفتن بخش خاصی از تاپل
tup3 = ('math',12,'science',18.25)
print('tup[1:3]:', tup3[1:3])
tup[1:3]: (12, 'science')
# افزودن دو تاپل به هم
tup6 = tup1 + tup2
print('tup6 (tup1 + tup2):',tup6)
tup6 (tup1 + tup2): (1, 2, 3, 4, 'elem1', 'elem2', 'elem3')
#میتوانید به یک مقدار دسترسی پیدا کنید
tup6[0]
1
# اما نمیتوانید آن را تغییر دهید
tup6[0] = 2
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-11-68882d828b54> in <module>
      1 #
----> 2 tup6[0] = 2


TypeError: 'tuple' object does not support item assignment
# برگرداندن تعداد یک مقدار خاص که در تاپل موجود است.
tup6.count(2)
1
# برگرداندن اندیس یک مقدار که در تاپل وجود دارد
tup6.index(3)
2

در تاپل ها نمی‌توان مقداری را حذف کرد اما می‌توان همیشه با join دو تاپل به هم و ساخت تاپل جدید مقادیر را اضافه و کم کرد. اضافه کردن یک مقدار به میان یک تاپل به صورت زیر انجام می‌شود.
اما اگر بخواهیم با همین روش یک مقدار را حذف کنیم چه؟ پاسخ این پرسش با شما.
print('old tup6 :',tup6)
tup6 = tup6[:4]+(5,)+tup6[4:]
print('tup6 after adding 5 to it :', tup6)
old tup6 : (1, 2, 3, 4, 'elem1', 'elem2', 'elem3')
tup6 after adding 5 to it : (1, 2, 3, 4, 5, 'elem1', 'elem2', 'elem3')

بنابراین تاپل ها نیز به همین سادگی به پایان رسیدند.


پس از آشنایی با تاپل ها و لیست ها، نوبت به استفاده آن ها به صورت تودرتو می‌رسد. چند مثال زیر به عنوان نمونه برنامه هایی از لیست ها و تاپل های تو در تو است.
بازگشت به فهرست
#1 تعریف یک ماتریس:
mat1 = [[1,2,3],[4,5,6]]
print(mat1)
[[1, 2, 3], [4, 5, 6]]
#2 چاپ یک ماتریس تعریف شده:
mat1 = [[1,2,3],[4,5,6]]

print('First approach:')
for x in mat1:
    for y in x:
        print(y, end='\t')
    print()
    
print('-*-'*10)
print('Second approach:')
for i in range(len(mat1)):
    for j in range(len(mat1[i])):
        print(mat1[i][j], end='\t')
    print()
First approach:
1	2	3	
4	5	6	
-*--*--*--*--*--*--*--*--*--*-
Second approach:
1	2	3	
4	5	6	
#3 یک ماتریس تعریف کنید که اسم و معدل افراد را به صورت تاپل در خود داشته باشد
#آن را از کاربر بگیرید :

students = []
while True:
    inpt = input('Would you like to proceed: ')
    if inpt in ['No','no','','n']:
        break
    name = input('Enter person\'s name: ')
    score = float(input('Add the score: '))
    students.append((name,score))
print(students)
Would you like to proceed: yes
Enter person's name: Mohammad
Add the score: 10
Would you like to proceed: yes
Enter person's name: Yasaman
Add the score: 16.5
Would you like to proceed: yes
Enter person's name: Sasan
Add the score: 20
Would you like to proceed: y
Enter person's name: Mina
Add the score: 20
Would you like to proceed: y
Enter person's name: Sina
Add the score: 13.75
Would you like to proceed: no
[('Mohammad', 10.0), ('Yasaman', 16.5), ('Sasan', 20.0), ('Mina', 20.0), ('Sina', 13.75)]
#4 دو ماتریس را با هم جمع کنید :
m1 = [[1,1,1],[1,1,1]]
m2 = [[1,23,41],[65,12,9]]

# این کار را نکنید
m3 = m1+m2
print('m1+m2:',m3)

#از این روش یا هر روش مشابه استفاده کنید
m3 = []
for i in range(len(m1)):
    temp = []
    for j in range(len(m1[i])):
        temp.append(m1[i][j]+m2[i][j])
    m3.append(temp)
print('The right answer is:',m3)
    
m1+m2: [[1, 1, 1], [1, 1, 1], [1, 23, 41], [65, 12, 9]]
The right answer is: [[2, 24, 42], [66, 13, 10]]
#5 یک تابع بسازید که ماتریس مربعی با اندازه دلخواه بسازد :
def matn(n):
    mat = []
    for i in range(n):
        temp = []
        for j in range(n):
            inpt = float(input('you value for row %i, col %i : '%(i,j)))
            temp.append(inpt)
        mat.append(temp)
    return mat

n = int(input('Enter n for nxn matrix: '))
yourMat = matn(n)
print(yourMat)
Enter n for nxn matrix: 2
you value for row 0, col 0 : 1
you value for row 0, col 1 : 2
you value for row 1, col 0 : 3
you value for row 1, col 1 : 4
[[1.0, 2.0], [3.0, 4.0]]
### 6 مقادیر یک تاپل تو در تو را نشان دهید
# اینجا مقادیر منحصر به فرد مد نظر است بنابراین از مجموعه استفاده کنید :
tup = ((2,1),(2,4),(21,4),(32,65),(35,4),(6,12))

myNumbers = []
for x,y in tup:
    myNumbers = myNumbers + [x,y]
mySet = set(myNumbers)
print(mySet)
{32, 1, 2, 65, 4, 35, 6, 12, 21}
# نمونه دیگری از مثال بالا
tup = ((2,1),(2,4,21,4),(32,65),(35,46,12))

myNumbers = []
for t in tup:
    myNumbers = myNumbers + list(t)
mySet = set(myNumbers)
print(mySet)
{32, 1, 2, 65, 4, 35, 12, 46, 21}

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

بازگشت به فهرست اصلی

مقدمه

در این فصل با کتابخانه‌های numpy و random و مهمترین کتابخانه پس از این دو یا همان matplotlib آشنا می‌شویم. کتابخانه‌ها به ترتیب برای عملیات محاسباتی و ریاضی، استفاده از داده‌های تصادفی و در نهایت کشیدن انواع نمودار هستند.
به دلیل در هم تنیدگی مثال ها در این فصل قادر به جدا کردن آنها از هم نیستیم. بنابراین ابتدا آنها را به صورت جدا تعریف کرده و در نهایت مثالهای آنها را می‌بینیم.
فهرست این فصل:
  1. کتابخانه های numpy و random
  2. کتابخانه matplotlib
  3. مثال های این فصل

این دو کتابخانه، همانطور که قبلا هم به آن اشاره شد، دو کتابخانه اصلی در پایتون هستند و بسیاری از کارهای محاسباتی و ریاضی به صورت پایه ای با این دو کتابخانه و به خصوص با استفاده از numpy پیاده سازی می‌شود. تا حدودی در فصل 6 با این دو کتابخانه آشنا شدیم. وقت آن است که به صورت عمیق تری وارد آنها بشویم.
در ادامه به سراغ استفاده از numpy میرویم:
بازگشت به فهرست
import numpy as np

a = np.arange(15).reshape(3, 5) 
# ارینج تابعی مشابه رینج است که قابلیت های بیشتری را در خود دارد
# ریشیپ نیز قابلیتی است که میتوانید با استفاده از آن یه آرایه را به صورت خطی یا به صورت ماتریسی نمایش بدهید
# فقط به خاطر داشته باشید تعداد مقادیر با تعداد مقادیری که آن را تبدیل میکنید برابر باشد
# برای مثال در ماتریس بالا نمیتوان ریشیپ 4 و 4 را استفاده کرد زیرا تعداد ارقام ما 15 تاست و نه 16 تا
a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
# با استفاده از شیپ که یک تابع بسیار پرکاربردی است میتوانید ابعاد یک ماتریس یا آرایه را به دست بیاورید
a.shape
(3, 5)
a.ndim # دایمنشن یا بعد آرایه را به شما میدهد. برای مثال اینجا ماتریس ما دارای دو بعد است
2
# میتوانید آرایه خود را با استفاده از یک مارتریس یا لیست تعریف شده در پایتون بسازید
b = np.array([6, 7, 8]) 
b
array([6, 7, 8])

اما سوالی که اینجا پیش می‌آید این است که "فرق لیست معمولی و آرایه چیست؟" برای پاسخ به این سوال می‌توان گفت لیست یک کلاس از پیش تعریف شده در پایتون است و ویژگی های مربوط به خود را دارد. در صورتی که آرایه یک زیر مجموعه از کتابخانه numpy است و ویژگی های آن به مراتب بیشتر از لیست است. دلیل آن هم از استفاده های مختلف آرایه ها در ریاضیات نشأت می‌گیرد.
تقریبا در تمامی توابع و کلاس های تعریف شده در numpy از آرایه استفاده می‌شود. حتی اگر ورودی شما به صورت لیست باشد و ایرادی هم به شما وارد نشود، در نهایت خروجی شما آرایه است. این به آن معناست که در طی عملیات ورودی شما به آرایه تبدیل شده است. به مرور با ویژگی‌های مختلف آرایه آشنا می‌شویم.
برای ساخت ماتریس‌های تمام صفر، تمام یک و همانی می‌توان از توابع آماده استفاده کرد:
np.zeros((3, 4))
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
np.ones((2, 3, 4)) # یک ماتریس 3 بعدی
array([[[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]],

       [[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]]])
 np.eye(3)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
# همانطور که گفتم تابع ارنج از رینج قابلیت های بیشتری دارد:
np.arange(0, 2, 0.3)
array([0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])

می‌توانید به روش زیر یک تابع یا مقدار خاص تعریف شده را از یک کتابخانه به صورت جدا فراخوانی کنید و از آن استفاده کنید.
در مثال زیر تابع linspace را فراخوانی کرده ایم و از آن استفاده می‌کنیم. به این صورت از فراخوانی تمام کتابخانه تنها برای استفاده از یک تابع جلوگیری می‌کنیم:
(توجه داشته باشید که می‌توانیم چند مقدار مختلف را نیز فراخوانی کنیم)
from numpy import linspace

linspace(0, 2, 9)   # این تابع از 0 تا 2 پی، 100 مقدار تعریف میکند که فاصله یکسانی از هم دارند
array([0.  , 0.25, 0.5 , 0.75, 1.  , 1.25, 1.5 , 1.75, 2.  ])
from numpy import sin,pi

x = linspace(0, 2 * pi, 100)
# یکی از ویژگی های بسیار مورد استفاده در نامپای این است که یک تابع را میتوانید برروی یک آرایه پیاده سازی کنید و همه نتایج را یکجا بگیرد
f = sin(x)
print(f)
[ 0.00000000e+00  6.34239197e-02  1.26592454e-01  1.89251244e-01
  2.51147987e-01  3.12033446e-01  3.71662456e-01  4.29794912e-01
  4.86196736e-01  5.40640817e-01  5.92907929e-01  6.42787610e-01
  6.90079011e-01  7.34591709e-01  7.76146464e-01  8.14575952e-01
  8.49725430e-01  8.81453363e-01  9.09631995e-01  9.34147860e-01
  9.54902241e-01  9.71811568e-01  9.84807753e-01  9.93838464e-01
  9.98867339e-01  9.99874128e-01  9.96854776e-01  9.89821442e-01
  9.78802446e-01  9.63842159e-01  9.45000819e-01  9.22354294e-01
  8.95993774e-01  8.66025404e-01  8.32569855e-01  7.95761841e-01
  7.55749574e-01  7.12694171e-01  6.66769001e-01  6.18158986e-01
  5.67059864e-01  5.13677392e-01  4.58226522e-01  4.00930535e-01
  3.42020143e-01  2.81732557e-01  2.20310533e-01  1.58001396e-01
  9.50560433e-02  3.17279335e-02 -3.17279335e-02 -9.50560433e-02
 -1.58001396e-01 -2.20310533e-01 -2.81732557e-01 -3.42020143e-01
 -4.00930535e-01 -4.58226522e-01 -5.13677392e-01 -5.67059864e-01
 -6.18158986e-01 -6.66769001e-01 -7.12694171e-01 -7.55749574e-01
 -7.95761841e-01 -8.32569855e-01 -8.66025404e-01 -8.95993774e-01
 -9.22354294e-01 -9.45000819e-01 -9.63842159e-01 -9.78802446e-01
 -9.89821442e-01 -9.96854776e-01 -9.99874128e-01 -9.98867339e-01
 -9.93838464e-01 -9.84807753e-01 -9.71811568e-01 -9.54902241e-01
 -9.34147860e-01 -9.09631995e-01 -8.81453363e-01 -8.49725430e-01
 -8.14575952e-01 -7.76146464e-01 -7.34591709e-01 -6.90079011e-01
 -6.42787610e-01 -5.92907929e-01 -5.40640817e-01 -4.86196736e-01
 -4.29794912e-01 -3.71662456e-01 -3.12033446e-01 -2.51147987e-01
 -1.89251244e-01 -1.26592454e-01 -6.34239197e-02 -2.44929360e-16]

عملیات ساده ماتریسی به راحتی با استفاده از آرایه ها امکان پذیر است:
A = np.array([[1, 1],
              [0, 1]])
B = np.array([[2, 0],
              [3, 4]])
A * B # ضرب ارایه در ارایه
array([[2, 0],
       [0, 4]])
A + B 
array([[3, 1],
       [3, 5]])
A.dot(B) # ضرب ماتریسی
array([[5, 4],
       [3, 4]])

تمامی توابع رندم در numpy نیز یافت می‌شوند. در برخی موارد با نام های متفاوت و نوع استفاده متفاوت در دسترس هستند.
در اینجا برای استفاده از توابع رندم از توابع تعریف شده در کتابخانه numpy استفاده می‌کنیم.
# ساخت یک ماتریس رندم:
a = np.random.random((2,3))
a
array([[0.8579226 , 0.0089118 , 0.63352182],
       [0.53982644, 0.98585598, 0.36547568]])
# میتوانید تمامی مقادیر موجود را جمع کنید
a.sum()
3.391514328048655
# کمترین مقدار در تمامی مقادیر را بگیرید
a.min()
0.008911802854719708
# بیشترین مقدار در تمامی مقادیر:
a.max()
0.985855981384956

قبل از آنکه به سراغ توابع مختلف کتابخانه random برویم لازم است اشاره ای به بانک اطلاعات کتابخانه numpy در آدرس زیر بکنم.
https://numpy.org/doc/stable/user/quickstart.html
در اینجا می‌توانید با کتابخانه numpy به صورت کامل آشنا شوید و مطالب بسیاری در مورد این کتابخانه و قابلیت‌های آن بیاموزید.
حال نوبت به بررسی بیشتر کتابخانه random می‌رسد. ایجاد اعداد تصادفی در پایتون کاملا تصادفی نیست. این اعداد به روند خاصی تولید می‌شوند اما تعداد این روند‌های خاص آنقدر زیاد است که میتوان آنها را تصادفی در نظر گرفت. به همین دلیل به آن نام شبه تصادفی داده‌اند.
روند تولید این اعداد به این صورت است که یک عدد به عنوان پایه و شروع کنند در نظر گرفته می‌شود و اعداد تصادفی بعد از آن همیشه یک مقدار خاص هستند. این عدد به عنوان هسته یا seed نامیده می‌شود و در صف طولانی اعداد شبیه تصادفی به عنوان پایه آن است. برای مثال اگر هسته را 1 انتخاب کنیم روند به صورت زیر خواهد بود:
import random
random.seed(1)
print(random.random())
print(random.random())
print(random.random())
print(random.random())
print('-*-'*10)
random.seed(1)
print(random.random())
print(random.random())
print(random.random())
print(random.random())
0.13436424411240122
0.8474337369372327
0.763774618976614
0.2550690257394217
-*--*--*--*--*--*--*--*--*--*-
0.13436424411240122
0.8474337369372327
0.763774618976614
0.2550690257394217

همانطور که می‌بینید این روند تغییر نمی‌کند تا زمانی که برای آن seed مشخص می‌کنید. در واقع عدد بعد یک هسته همیشه یک مقدار خاص است.
اما اگر برای اعداد تصادفی هسته مشخص نکنید چه؟
در این صورت از زمان سیستم شما استفاده می‌شود. عدد این زمان به عنوان هسته در نظر گرفته می‌شود و به این صورت اعداد شما همیشه متفاوت خواهند بود.
print(random.random())
print(random.random())
print(random.random())
print(random.random())
0.49543508709194095
0.4494910647887381
0.651592972722763
0.7887233511355132
random.seed()
print(random.random())
print(random.random())
print(random.random())
print(random.random())
0.918528949834484
0.188264971272462
0.3241377292065952
0.5110727620015786

حال به سراغ انواع مختلف تولید داده می‌رویم و یکی یکی آنها را بررسی می‌کنیم:
# تابع زیر مانند انتخاب یک عدد در رینج یک سری اعداد است
# تنها یک عدد تولید میکند و در ورژنهای جدید این اعداد با شانس مساوی ایجاد میشود.
print(random.randrange(10))
print(random.randrange(0,10))
print(random.randrange(10,20))
print(random.randrange(2,6))
3
2
10
4
# تابع زیر مشابه بالایی است با این تفاوت که عدد پایانی نیز میتواند جزو انتخاب ها باشد
random.randint(10, 20)
13
# در تابع زیر میتوانیم در یک لیست یا یک مقدار تکرار شونده یکی را انتخاب کنیم
random.choice([2,5,7,9])
5
# با استفاده از تابع زیر میتوانید یک مقدار تکرار شونده مانند لیست را به هم بریزید
l = [1,2,3,4]
random.shuffle(l)
print(l)
[3, 1, 4, 2]
# یک مقدار را به صورت رندم از بین 0 تا 1 انتخاب میکند. 1 در این مقادیر هیچگاه ظاهر نمیشود
random.random()
0.4251803400480886
# تولید یک عدد با استفاده از توزیع یکنواخت
random.uniform(1,10)
1.701178533243477
# در تابع زیر مقدار تصادفی شما از توزیع گوسین با میانگین و واریانس تعیین شده تولید میشود
random.gauss(mu=10, sigma=3.5)
14.576503773085825
# در تابع زیر مقدار تصادفی شما از توزیع نرمال با میانگین و واریانس تعیین شده تولید میشود
random.normalvariate(mu=10, sigma=3.5)
8.648983407302723

باقی توزیع ها و انواع ایجاد مقادیر تصادفی در کتابخانه random را می‌توانید در سایت زیر بیابید:
https://docs.python.org/3/library/random.html
در بخش بعد با کتابخانه matplotlib آشنا می‌شویم و آن را بررسی می‌کنیم.

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

بازگشت به فهرست

در مثال های زیر به ترتیب کشیدن نمودار ها را میبینیم. اما اول باید یک سری نکات در مورد کشیدن نمودارها را بیان کنم.
برای کشیدن نمودارها نیاز به فراخوانی کلاس pyplot از کتابخانه matplotlib داریم. در این کلاس نمودارهای مختلف تعریف شده‌اند و می‌توانیم به راحتی از آنها استفاده کنیم.
نکته بعدی به نمایش نمودار باز می‌گردد. برای نمایش یک نمودار حتما باید از تابع show استفاده شود. در غیر این صورت در محیط های دیگر تابع خود را نمی‌بینید. این تابع در واقع کار print را برای نمودار انجام می‌دهد. (قابل ذکر است که مانند تمام خروجی های دیگر نمایش آخرین نمودار به عنوان خروجی در ژوپیتر نیز جزو ویژگی های این محیط است.)
#یک لیست تعریف میکنیم تا تمامی نمودار های را با استفاده از آن رسم کنیم
l = [1,2,3,1,2,7,1,2,9,1,5,7,5,9,3,5,7,4,2,8,7,4,2,4,7,4,3,2,5,6,7,8,9,8,6,5,4,3,3,2]
from matplotlib import pyplot as plt # تعریف کلاس پایپلات به عنوان پی ال تی
plt.plot(l)
# این تابع به ترتیب اعضای داخل لیست را برروی نمودار نقطه گذاری میکند
# در حالت دیفالت این تابع حالت خطی و رنگ آبی را برای نمایش لیست شما انتخاب میکند
plt.show()

png

# برای تغییر حالت نمودار از خطی به نقطه ای کافی است
# به عنوان آخرین ورودی به آن یک استرینگ بدهیم که شکل آن را مشخص کند
plt.plot(l,'.') # other formats: o , *, ^, +, x, v, p, d, h, -*, --, 1,2,3,4
plt.show()

png

# میتوانید رنگ را نیز تغییر دهید
plt.plot(l,'r') # other colors: b,g,k,w,c,m,y ... 
# and you can use some names like orange if using separately from pattern
plt.show()

png

# حال ترکیب دو دستور بالا
plt.plot(l, 'co')
plt.show()

png

#  در اینجا برای مقادیر ایکس نمودار نیز مقدار تعیین میکنیم:
x = range(2,2*len(l)+1,2)
print(list(x))
plt.plot(x,l,'m.')
plt.show()
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80]

png

با استفاده از تابع plot می‌توان بسیاری از موارد دلخواه را نمایش داد. تنظیمات دیگری نیز وجود دارد که پس از تعریف باقی نمودار ها به آن ها نیز می‌پردازیم.
# تعداد ایکس و لیست دوم باید برابر باشند زیرا لیست دوم بلندی اعضای لیست اول است
plt.bar(range(len(l)),l)
plt.show()

png

# نمودار زیر مانند پلاتی عمل میکند که پترن آن نقطه ای است
# تفاوتی که اینجا وچود دارد امکانات بیشتری است که این تابع به شما میدهد
plt.scatter(range(len(l)),l)
plt.show()

png

# در نموداری زیر، هیستوگرام یک لیست را میبینید.
# میتوانید تعداد ستون ها و یا فاصله ستون ها را نیز در آن مشخص کنید
plt.hist(l)
plt.show()

png

حال با داشتن آشنایی به باقی انواع نمودار، نوبت به اطلاعات بیشتر است.
در مثال زیر جزئیات بیشتر را در کشیدن یک نمودار میبینیم:
l.sort() # ابتدا لیست خود را مرتب میکنیم که نمای بهتری از آن را ببینیم
plt.figure(figsize=(10,5))  # مشخص کردن اندازه پلات : مقدار اول مربوط به محور افقی و مقدار دوم مربوط به محور عمودی است
plt.plot(l,'g--')
plt.title('This is a plot!') # نام کلی پلات
plt.xlabel('this is x axis') # نام محور ایکس
plt.ylabel('this is y axis') # نام محور وای
plt.xticks(range(0, len(l) ,2), rotation=45) # مقادیر روی محور ایکس
plt.grid(True, axis='x') # داشتن یا نداشتن گرید 

plt.show()

png

حال در زیر یاد می‌گیریم چگونه چند نمودار را همزمان و کنار هم رسم کنیم:
plt.figure(figsize=(9, 3))
# پلات مورد نظر با تنظیمات مورد نظر را انتخاب میکنیم
# در کد زیر تعدا پلات های ما 1 در 3 است
# یعنی یک سطر و 3 ستون
plt.subplot(131) # اولین پلات از 3 پلات: مقدار اول تعداد سطر، دوم تعداد ستون و اخرین عدد مربوط به پلات است
plt.bar(range(len(l)),l)
plt.xlabel('this is x label plot1')

plt.subplot(132) # پلات دوم از سری پلات
plt.scatter(range(len(l)),l)
plt.ylabel('this is y label plot2')

plt.subplot(133) # سومین پلات
plt.plot(l)
plt.title('this is plot3')
# مقدار زیر برای کل پلات هاست
plt.suptitle('Categorical Plotting')
plt.show()

png

همانطور که می‌بینید میتوان برای هر subplot تنظیمات مربوط به خودش را انجام داد
چند نکته مهم وجود دارد که باید به آنها اشاره شود. اول آن که عدد subplot ها از 1 شروع می‌شود و نه 0. به آن دقت کنید. دوم آنکه اگر شما 2 سطر و 3 ستون داشتید آنگاه در سطر 2 ستون 1، نمودار 4 ام قرار می‌گیرد و به همین ترتیب تا عدد 6 ام که سطر 2 و ستون 3 است.

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

بازگشت به فهرست
# در مثال زیر  که یک مثال از آموزش خود کتابخانه متپلاتلیب است میخواهیم 3 نمودار ایکس، دو ایکس و سه ایکس را ببینیم:
import numpy as np
from matplotlib import pyplot as plt 

t = np.arange(0., 5., 0.2)

# میتوان 3 نمودار را در یک جا نمایش داد
# به این ترتیب که 3 مقدار اول ایکس، ایگرگ و پترن نمودار اول، 3 مقدار دوم مربوط به نمودار 2 و 3 مقدار سوم مربوط به نمودار 3 است.
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()

png


# نمایش دو نمودار با استفاده از تابع کوسینوس و یک تابع تعریف شده
import numpy as np
from matplotlib import pyplot as plt 

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1) # تغریف نقاط مربوط به دایره های نمودار اول
t2 = np.arange(0.0, 5.0, 0.02)## تعریف نقطه برای خط نمودار اول

plt.figure()
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k') # نمودار اول

plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')  # نمودار دوم
plt.show()

png


#  نمایش هیستوگرام و تابع اصلی برای یک نمونه داده

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(19680801) # معرفی یک هسته خاص برای آنکه نمودار همیشه یک شکل باشد

# تعریف داده
mu = 100  # تعریف میانگین
sigma = 15  # تعریف انحراف معیار
# تعریف 437 مقدار در یک توزیع نرمال ک توسط میانگین و انحراف معیار دلخواه ما تغییر میکنند
x = mu + sigma * np.random.randn(437) 

# مشخص کردن تعداد ستون ها
num_bins = 50

# داده های هیستوگرام 3 دسته هستند که مقدار مورد نظر ما در بینز وجود دارد
n, bins, patches = plt.hist(x, num_bins, density=True)

# در زیر تابع مربوط به تعریف تابع نرمال با میانگین و انحراف معیار ما است
y = ((1 / (np.sqrt(2 * np.pi) * sigma)) * 
     np.exp(-0.5 * (1 / sigma * (bins - mu))**2))
plt.plot(bins, y, '--') # بینز به تنهایی دارای این ویژگی است که هیستوگرام را در پلات به صورت کامل نمایش بدهد
plt.xlabel('Smarts')
plt.ylabel('Probability density')
plt.title(r'Histogram of IQ: $\mu=100$, $\sigma=15$')

plt.show()

png


# فرض کنید چند نقطه دارید و میخواهید خطی میان آنها رسم کنید و سپس میزان خطای حدودی خود را نمایش دهید:
import numpy as np
import matplotlib.pyplot as plt

N = 21 
x = np.linspace(0, 10, 11) # یازده نقطه بین 0 و 10
y = [3.9, 4.4, 10.8, 10.3, 11.2, 13.1, 14.1,  9.9, 13.9, 15.1, 12.5] # مقادیر آن 11 نقطه به شرح زیر است

# fit a linear curve an estimate its y-values and their error.
a, b = np.polyfit(x, y, deg=1) # این تابع یک خط حدودی که نزدیک ترین به تمام نقاط شماست را به آنها فیت میکند
# مقادیر به دست آمده از تابع بالا مقادیر مربوط به یک پولی نومیال هستند که در مورد ما یک خط است
y_est = a * x + b # مقادیر خطی را در جای خود میگذاریم و در ایکس ضرب میکنیم تا ایگرگ را به ما بدهد
y_err = x.std() * np.sqrt(1/len(x) +
                          (x - x.mean())**2 / np.sum((x - x.mean())**2)) # مقدار خطا را با استفاده از این تابع محاسبه میکنیم

# نمودار اصلی را میکشید
plt.plot(x, y_est, '-')
# تابع زیر نمودار خطا را رسم میکند
plt.fill_between(x, y_est - y_err, y_est + y_err, alpha=0.2)
# حال وقت کشید نقاط اصلی است
plt.plot(x, y, 'o', color='tab:brown')
plt.show()

png

برای مثال های بیشتر به سایت زیر سر بزنید:

https://matplotlib.org/stable/gallery/index.html


مقدمه

فایل ها بخش جزء جدا نشدنی از برنامه نویسی هستند. در صورتی که بخواهید اطلاعات پایانی یک برنامه را ذخیره کنید و یا داده‌های آمده از جای دیگری را مورد ارزیابی و یا بررسی قرار دهید نیاز به خواندن و نوشتن فایل‌ها دارید.
در اینجا با قسمت کوچکی از کار با فایل ها آشنا می‌شویم.
یاد می‌گیریم چگونه داده ها را در فایل ذخیره کنیم، از فایل بخوانیم و خطاهای مربوط به فایل را کنترل کنیم.
پس به سراغ مثال های این فصل می‌رویم تا کار با فایل را به صورت عملی ببینیم:
در ابتدا نیاز است به این نکته اشاره کنم که در فراخوانی فایل نیاز است مُد آن را مشخص کنیم. در اینجا w به معنای نوشتن است و r به معنای خواندن. مد های دیگری هم هست که در صورت نیاز به مرور به آنها اشاره می‌شود.
s = 'I want to add this sentence in the file with name myfile.txt'
#ابتدا نیاز است فایل خود را باز کنید
f = open('myfile.txt','w')
# سپس در اینجا با استفاده از پرینت مقداری که میخواهیم را در فایل اضافه میکنیم:
print(s,file=f)
# در اینجا با استفاده از رایت این کار را انجام میدهیم:
f.write(s)
f.write('this is the end!')
# در نهایت حتما فایل خود را ببندید
f.close()
# حال وقت آن است که فایل خود را بخوانیم:

# این بار از یک روش دیگر برای باز کردن فایل استفاده میکنیم که کار را برای ما راحت تر کند
# با این شیوه نیاز به بستن فایل در خواندن نیست
with open('myfile.txt','r') as f:
    myContent = f.read()
    print(myContent)
I want to add this sentence in the file with name myfile.txt
I want to add this sentence in the file with name myfile.txtthis is the end!

در بالا میبینید که در خط دوم جمله مورد نظر به جمله دوم چسبیده است. این اتفاق به این دلیل افتاده است که بین write های متوالی هیچ اتفاقی رخ نمی‌دهد. به این معنا که در صورت استفاده از write اگر می‌خواهید جمله بعدی شما در خط بعد باشد در انتهای جمله خود یک n\ اضافه کنید. در غیر این صورت یک space قرار دهید که جمله بعد شما فاصله بگیرد و یا space را به صورت جداگانه write کنید.
به مثال زیر دقت کنید:
s = 'I want to add this sentence in the file with name myfile.txt'

with open('myfile.txt','w') as f:
    f.write(s)
    f.write('\n')
    f.write('Again, '+s)
f.close()

# حال فایل را میخوانیم تا ببینیم در آن چه اتفاقی افتاده است
with open('myfile.txt','r') as f:
    myContent = f.read()
    print(myContent)
I want to add this sentence in the file with name myfile.txt
Again, I want to add this sentence in the file with name myfile.txt

اگر دقت کرده باشید فایل myfile را بار دیگر صدا کردیم و در آن مقادیر جدید ریختیم اما چیزی که به ما نمایش داده می‌شود تنها مقادیر جدید است. دلیل آن به مد بر‌می‌گردند. در مد 'w' ما هربار که فایل را صدا می‌زنیم به چشم فایل جدید به آن نگاه می‌کند. اگر وجود داشته باشد از اول ذخیره می‌شود و اگر وجود نداشته باشد ساخته می‌شود.
در صورتی که می‌خواهید به فایل خود مقداری جدید اضافه کنید از مد a استفاده کنید که به معنای append است. در این حالت اگر فایل شما موجود نباشد به خطا برمی‌خورید. این اتفاق در خواندن فایل هم ممکن است رخ بدهد.
برای برطرف کردن این موضوع میتوان از متد های مختلفی در پایتون استفاده کرد. به مثال زیر دقت کنید:
with open('notmyfile.txt','r') as f:
    myContent = f.read()
    print(myContent)
---------------------------------------------------------------------------

FileNotFoundError                         Traceback (most recent call last)

<ipython-input-9-525b2de9464b> in <module>
----> 1 with open('notmyfile.txt','r') as f:
      2     myContent = f.read()
      3     print(myContent)


FileNotFoundError: [Errno 2] No such file or directory: 'notmyfile.txt'
# امتحان کردن یک دستور:
try:
    with open('notmyfile.txt','r') as f:
        myContent = f.read()
        print(myContent)
# در صورتی که دستور به خطا بر بخورد:
except Exception as e:
    # خطای ای دارای دو مقدار است. خط رخداد و اتفاق افتاده
    print("Oops! '", e.args[1], "' occurred in line",e.args[0])
Oops! ' No such file or directory ' occurred in line 2

بنابراین با در خط بالا استفاده از try و except را نیز دیدید.
اما تا اینجا ما فقط نام و فرمت فایل مد نظر را نوشتیم.
این فایل کجا ذخیره می‌شود؟
چگونه می‌توان فایل ها را از قسمت های دیگر خواند؟
جواب این سوالات به ترتیب این است:
این فایل در جایی ذخیره می‌شود که فایل ژوپیتر شما یا همان فایل .ipynb شما در آنجا قرار دارد.
در صورتی که می‌خواهید فایل را از یک جای دیگر بخوانید آدرس آن را کپی کنید و جای تمامی \ ها را با / تغییر دهید.
try:
    with open('C:/Users/Niloo/Documents/My Python Project/myfile.txt','r') as f:
        myContent = f.read()
        print(myContent)
except Exception as e:
    print("Oops! '", e.args[1], "' occurred in line",e.args[0])
I want to add this sentence in the file with name myfile.txt
Again, I want to add this sentence in the file with name myfile.txt

برخی دیگر از توابع هستند که در خطوط زیر با آنها نیز آشنا می‌شویم:
with open('myfile.txt','r') as f:
    # یک لاین را میخواند و فایل را سر خط بعدی نگه میدارد:
    myContent = f.readline()
    # خط بعدی را میخواند
    myContent2 = f.readline()
    print('first line:')
    print(myContent)
    print('second line:')
    print(myContent2)
first line:
I want to add this sentence in the file with name myfile.txt

second line:
Again, I want to add this sentence in the file with name myfile.txt
with open('myfile.txt','r') as f:
    #تمام خط ها را در مقادیر جدا میخواند و آنها را در لیست قرار میدهد:
    myContent = f.readlines()
    print(myContent)
['I want to add this sentence in the file with name myfile.txt\n', 'Again, I want to add this sentence in the file with name myfile.txt']
with open('myfile.txt','r') as f:
    #چند مقدار داخلی کلاس فایل:
    print("File name:",f.name)
    print('File mode:',f.mode)
    # چند تابع کلاس فایل:
    print('Is it readable? ',f.readable())
    print('Is it writable? ',f.writable())
    
File name: myfile.txt
File mode: r
Is it readable?  True
Is it writable?  False

حال چند مثال را با هم حل می‌کنیم:
اما قبل از آن که به سراغ حل مسائل برویم نیاز است یک فایل داشته باشیم تا بتوانیم مثال های خود را روی آن اعمال کنیم. بنابراین ابتدا این فایل را تعریف می‌کنیم:
\n\ هایی که در رشته می‌بینید جهت راحتی ما و فهم رشته تعریف شده است. \ در آخر هر خط به تنهایی می‌گوید که رشته در خط بعد ادامه دارد.
s = "Buddy, you're a boy, make a big noise\n\
Playing in the street, gonna be a big man someday\n\
You got mud on your face, you big disgrace\n\
Kicking your can all over the place, singin'\n\
We will, we will rock you\n\
We will, we will rock you\n\
Buddy, you're a young man, hard man\n\
Shouting in the street, gonna take on the world someday\n\
You got blood on your face, you big disgrace\n\
Waving your banner all over the place\n\
We will, we will rock you, sing it!\n\
We will, we will rock you, yeah\n\
Buddy, you're an old man, poor man\n\
Pleading with your eyes, gonna get you some peace someday\n\
You got mud on your face, big disgrace\n\
Somebody better put you back into your place, do it!\n\
We will, we will rock you, yeah, yeah, come on\n\
We will, we will rock you, alright, louder!\n\
We will, we will rock you, one more time\n\
We will, we will rock you\n\
Yeah"

with open('we will rock you.txt','w') as f:
    f.write(s)
f.close()    

with open('we will rock you.txt','r') as f:
    myContent = f.read()
    print(myContent)
Buddy, you're a boy, make a big noise
Playing in the street, gonna be a big man someday
You got mud on your face, you big disgrace
Kicking your can all over the place, singin'
We will, we will rock you
We will, we will rock you
Buddy, you're a young man, hard man
Shouting in the street, gonna take on the world someday
You got blood on your face, you big disgrace
Waving your banner all over the place
We will, we will rock you, sing it!
We will, we will rock you, yeah
Buddy, you're an old man, poor man
Pleading with your eyes, gonna get you some peace someday
You got mud on your face, big disgrace
Somebody better put you back into your place, do it!
We will, we will rock you, yeah, yeah, come on
We will, we will rock you, alright, louder!
We will, we will rock you, one more time
We will, we will rock you
Yeah

حال با داشتن فایل به سراغ مثال می‌رویم.
1. می‌خواهیم تعداد خط های فایل را به دست بیاوریم.
with open('we will rock you.txt','r') as f:
    myContent = f.readlines()
    print('We have',len(myContent),'line(s).')
We have 21 line(s).

برای مثال بالا می‌توان راه حل های دیگر هم داشت. اینجا این راه حل را برای آن انتخاب کردیم.
2. تعداد اتفاق کلمه will را در فایل به دست بیاورید.
with open('we will rock you.txt','r') as f:
    myContent = f.read()
    
words = myContent.split()
count = 0
for w in words:
    if w=='will':
        count+=1
print('Number of "will" occurrence is',count)
Number of "will" occurrence is 8

در مثال بالا انتظار میرود تعداد willها بسیار بیشتر از 8 باشد. اما دلیل این که ما عدد 8 را میبینیم چیست؟
به لیست زیر دقت کنید. تقریبا نیمی کلمه های will دارای یک ویرگول هستند که از کلمه جدا نشده‌اند. بنابراین در چک بالا لحاظ نمی‌شوند.
words
['Buddy,',
 "you're",
 'a',
 'boy,',
 'make',
 'a',
 'big',
 'noise',
 'Playing',
 'in',
 'the',
 'street,',
 'gonna',
 'be',
 'a',
 'big',
 'man',
 'someday',
 'You',
 'got',
 'mud',
 'on',
 'your',
 'face,',
 'you',
 'big',
 'disgrace',
 'Kicking',
 'your',
 'can',
 'all',
 'over',
 'the',
 'place,',
 "singin'",
 'We',
 'will,',
 'we',
 'will',
 'rock',
 'you',
 'We',
 'will,',
 'we',
 'will',
 'rock',
 'you',
 'Buddy,',
 "you're",
 'a',
 'young',
 'man,',
 'hard',
 'man',
 'Shouting',
 'in',
 'the',
 'street,',
 'gonna',
 'take',
 'on',
 'the',
 'world',
 'someday',
 'You',
 'got',
 'blood',
 'on',
 'your',
 'face,',
 'you',
 'big',
 'disgrace',
 'Waving',
 'your',
 'banner',
 'all',
 'over',
 'the',
 'place',
 'We',
 'will,',
 'we',
 'will',
 'rock',
 'you,',
 'sing',
 'it!',
 'We',
 'will,',
 'we',
 'will',
 'rock',
 'you,',
 'yeah',
 'Buddy,',
 "you're",
 'an',
 'old',
 'man,',
 'poor',
 'man',
 'Pleading',
 'with',
 'your',
 'eyes,',
 'gonna',
 'get',
 'you',
 'some',
 'peace',
 'someday',
 'You',
 'got',
 'mud',
 'on',
 'your',
 'face,',
 'big',
 'disgrace',
 'Somebody',
 'better',
 'put',
 'you',
 'back',
 'into',
 'your',
 'place,',
 'do',
 'it!',
 'We',
 'will,',
 'we',
 'will',
 'rock',
 'you,',
 'yeah,',
 'yeah,',
 'come',
 'on',
 'We',
 'will,',
 'we',
 'will',
 'rock',
 'you,',
 'alright,',
 'louder!',
 'We',
 'will,',
 'we',
 'will',
 'rock',
 'you,',
 'one',
 'more',
 'time',
 'We',
 'will,',
 'we',
 'will',
 'rock',
 'you',
 'Yeah']

برای آنکه این مسئله را حل کنیم نیاز است از ویژگی های رشته استفاده کنیم و ابتدا تمامی ویرگول ها را از آن حذف کنیم.
with open('we will rock you.txt','r') as f:
    myContent = f.read()
# به خط زیر دفت کنید:
myContent = myContent.replace(',','') # در ابتدا ویرگول ها با هیچی جایگزین میشوند

words = myContent.split()
count = 0
for w in words:
    if w=='will':
        count+=1
print('Number of "will" occurrence is',count)
Number of "will" occurrence is 16

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

مقدمه

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

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

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

مثال اول: می‌خواهیم برای n بار 2 را در خودش ضرب کنیم؛ در واقع 2 را به توان n برسانیم:
# تابع را تعریف میکنیم
def power2(n):
    # یک شرط برای تمام شدن تابع قرار میدهیم
    if n==1:
        return 2
    # بازگشت را برای آن تعریف میکنیم
    return 2*power2(n-1)
power2(3) # دو به توان 3 میرسد
8

در تابع بالا همانطور که می‌بینیم یک شرط وجود دارد که اگر مقدار ورودی یا همان توان برابر 1 بود تنها 2 را برگرداند. این تابع را می‌توان بهبود هم بخشید. برای مثال بگوییم اگر توان برابر صفر بود مقدار 1 را برگرداند. این برگرداندن زود موقع باعث می‌شود تابع به خطوط دیگر دسترسی نداشته باشد
اما قسمت اصلی در خط بعد قرار می‌گیرد. جایی که خود تابع را صدا می‌زنیم. این قسمت به دو بخش تقسیم می‌شود:
1. قسمت return
2. قسمت صدا کردن تابع
در قسمت اول یک بازگشت تعریف می‌کنیم که نتیجه ما را در نهایت بازگرداند و ما بتوانیم ان را ببینیم. همچنین هر باز مقدار برگردد تا بتوان آن را در 2 ضرب کرد و به مقدار بعدی برسیم. بنابراین اگر بخواهیم این تابع را برای n=4 نمایش بدهیم به صورت زیر خواهد بود:

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

مثال دوم فاکتوریل است. در تابع فاکتوریل داریم n! = n*(n-1)*...*3*2*1 . تا اینجا می‌دانیم چگونه می‌توان این تابع را به صورت تکراری و با استفاده از for پیاده سازی کرد. حال این تابع را به صورت بازگشتی در زیر پیاده سازی می‌کنیم.
def fact(n):
    # شرط پایانی برای تابع همانطور که در فاکتوریل وجود دارد
    if n==0 or n==1:
        return 1
    # حال هر بار فاکتوریل را در مقادیر قبلی ضرب میکنیم
    return n*fact(n-1)
fact(3)
6

کاری که در مثال بالا انجام می‌دهیم این است که می‌نویسیم n! = n*((n-1)!) .
سپس در مرحله بعد خواهیم داشت :
(n-1)! = (n-1)*(n-2)!
این کار تا زمانی ادامه دارد که به 1! برسیم. در این حالت دیگر تابع فراخوانی نمی‌شود و عدد 1 برمی‌گردد. سپس مانند مثال قبل تمام توابع باز شده یکی یکی مقادیر را برمی‌گردانند.

در مثال سوم محاسبه عدد nام فیبوناتچی را داریم.
تابع فیبوناتچی به صورت زیر است:
n if n = 0, n = 1
otherwise fib(n) = fib(n-1) + fib(n-2)
def fibo(n):
    if n==1 or n==0:
        return n
    return fibo(n-1)+fibo(n-2)

# حال مقادیر 1 تا 9 دنباله را میبینیم:
for i in range(1,10):
    print(fibo(i), end = '\t')
1	1	2	3	5	8	13	21	34	

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

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

شاید فکر کنید راحت است. اما پیچیدگی مسئله به آن قسمت برمی‌گردد که هر بار تنها می‌توانید یک حلقه را جابه‌جا کنید. بنا براین تابع ریاضی آن برای حداقل تعداد حرکت در این مسیر به صورت ریاضی در زیر تعریف شده است:
1 if n = 1
otherwise h(n) = 2*h(n-1)+1
در این تابع n تعداد حلقه هاست.
def hanoi(n):
    if n==1:
        return 1
    return 2*hanoi(n-1)+1


hanoi(4)
15

برای آن که روند را با هم ببینیم می‌توانید به گیف زیر دقت کنید و تعداد حرکات را بشمارید:


مسائل بسیاری از این دست وجود دارند. که برخی از آن ها را دیدیم.
به عنوان آخرین مثال فرض کنیم می‌خواهیم یک لیست را آن قدر تقسیم کنیم که تمامی داده های آن جدا شوند.
def devider(l):
    #اگر لیست شامل یک مقدار بود آن را چاپ کند:
    if len(l)<2:
        print(l)
        return # این فسمت برای پایان دادن به بازگشت است
    # عدد عنصر میانه ی لیست را میگیرد تا بتوانیم هر بار لیست را تفسیم کنیم
    mid = len(l)//2
    # حال بخش سمت راست را دوباره به تابع میفرستیم
    devider(l[:mid])
    # حال بخش سمت چپ را دوباره برای تقسیم میفرستیم
    devider(l[mid:])
    

    
l = [1,2,3,4,5,6,7]
devider(l)
[1]
[2]
[3]
[4]
[5]
[6]
[7]

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

بازگشت به فهرست این فصل

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

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

حال برای آن که این موارد را به طور کامل متوجه شویم نیاز به مثال است. ابتدا به سراغ مثال‌های مجموعه و سپس به سراغ مثال‌های دیکشنری می‌رویم:
st = {1,2,3,1,2,3,4,2,3,1,5}
print(st)
{1, 2, 3, 4, 5}
st = set([1,2,3,1,2,3,4,2,3,1,5]) # یک لیست را تبدیل به مجموعه میکند و یا یک مجموعه خالی میسازد
print(st)
{1, 2, 3, 4, 5}
# میخواهیم در لیست زیر تعداد اعضا و تعداد اعضای منحصر به فرد را بیابیم
l = [2,1,5,3,6,2,4,6,9,6,12,5,3,12,6,65,124,356,1,2,43,12,43,64,21]

print('Number of elements:', len(l))
print('Number of unique elements:',len(set(l)))
# همانطور که در زیر میبینید یک تابع از پیش تعریف شده در پایتون وجود دارد که همه ساختارهای تکراری را مرتب میکند
print('Unique elements are:', sorted(set(l)))
# برخلاف سورت لیست، این تابع یک کپی از ساخ÷تار تکراری را بازمیگرداند و نه خود ساختار را
Number of elements: 25
Number of unique elements: 14
Unique elements are: [1, 2, 3, 4, 5, 6, 9, 12, 21, 43, 64, 65, 124, 356]

حال چند مثال و تعریف از دیکشنری ببینیم:
# دیکشنری خالی:
dic = dict()
print(dic, type(dic))

# دیکشنری با تعریف داده در آن:
dic = {0:123, '1':'fist val', 2:'second val', '4th key': 3}
print('dic = ',dic)

# دسترسی به مقادیر با استفاده از کلید:
print("dic['1']: ",dic['1'])
print("dic[2]: ",dic[2])
print("dic['4th key']: ",dic['4th key'])

# تغییر یک مقدار از یک کلید:
dic['1'] = 43
print("dictionary after changing dic['1']: ",dic)

# اضافه کردن یک کلید و مقدار آن:
dic[534] = 'new val'
print("dictionary after adding new key and value: ",dic)

# حذف یک مقدار و کلید آن:
del(dic['1'])
print("dictionary after deleting dic['1']: ",dic)
{} <class 'dict'>
dic =  {0: 123, '1': 'fist val', 2: 'second val', '4th key': 3}
dic['1']:  fist val
dic[2]:  second val
dic['4th key']:  3
dictionary after changing dic['1']:  {0: 123, '1': 43, 2: 'second val', '4th key': 3}
dictionary after adding new key and value:  {0: 123, '1': 43, 2: 'second val', '4th key': 3, 534: 'new val'}
dictionary after deleting dic['1']:  {0: 123, 2: 'second val', '4th key': 3, 534: 'new val'}

اما اطلاعات دیگری هم هست که می‌توانید از دیکشنری بگیرید:
# از دیکشنری تعریف شده در بالا استفاده میکنیم:

print('dictionary keys: ',dic.keys()) #کلید های دیکشنری را بر میگرداند
print('dictionary values: ',dic.values()) # مقادیر دیکشنری را برمیگرداند
print('items: ',dic.items()) # تمام داده ها را به صورت لیستی از تاپل ها بازمیگرداند
print('pop last item: ', dic.popitem()) # اخرین تاپل کلید و مقدار را باز میگرداند
print('pop a  of a key',dic.pop(0))# مقدار یک کلید مشخص شده را بر میگرداند.
# اگر پاپ را به خاطر داشته باشید، بازگرداندن همراه با حذف آن مقدار است
dictionary keys:  dict_keys([0, 2, '4th key', 534])
dictionary values:  dict_values([123, 'second val', 3, 'new val'])
items:  dict_items([(0, 123), (2, 'second val'), ('4th key', 3), (534, 'new val')])
pop last item:  (534, 'new val')
pop a value 123
dic
{2: 'second val', '4th key': 3}

اما نوبت به حل چند مثال می‌رسد:

1. می‌خواهیم نمرات یک کلاس را در درس های متفاوت در یک دیکشنری ذخیره کنیم
dic = {'math':[10,14,20,19,15,17], 'art':[20,19,20,14,13,15], 'science':[20,19,18,19,16,20]}

# mean of every course:
for key in dic.keys():
    m = sum(dic[key])/len(dic[key]) # میانگین برای لیست هر کلید محاسبه میشود
    print("{} mean is {:.6f}".format(key,m)) # مقادیر میانگین تا 6 رقم رند میشوند
math mean is 15.833333
art mean is 16.833333
science mean is 18.666667



2.حال می‌خواهیم با استفاده از فایل یک متن را بخوانیم و تعداد کلمات یونیک یا منحصر به فرد را به استفاده از دیکشنری ذخیره کنیم:
# از فایل ذخیره شده در فصل قبل استفاده میکنیم:
with open('we will rock you.txt','r') as f:
    myContent = f.read()
myContent = myContent.replace(',','')
words = myContent.split()
# تا اینجا از اطلاعات فصل قبل استفاده کردیم
# حال به سراغ ذخیره تعداد هر کلمه یونیک در لیست بالا میرویم:
# برای این کار دو روش داریم.
# 1. میتوانیم ابتدا از مجموعه استفاده کنیم و سپس تعداد را با استفاده از حلقه بشماریم:

# مجموعه و دیکشنری خود را میسازیم
uniqueWords = set(words)
wordDict1 = dict()

for w in uniqueWords:
    wordDict1[w] = 0 # برای تمام کلمات موجود یک کلید میسازیم با مقدار 0
# حال زمان محاسبه تعداد است
for w in words:
    wordDict1[w]+=1 # هر کلمه ای که میبینیم، یک عدد به مقدار آن کلمه در دیکشنری اضافه میکنیم.

print('Our dictionary in first method:\n ', wordDict1)        


# البته روش بالا هزینه بر است.
# زیرا هم از مجموعه و هم از دیکشنری استفاده شده است. بنابراین به سراغ روش دوم میرویم:
# 2. برای کم کردن هزینه تنها استفاده از دیکشنری کافی است:

# این بار تنها دیکشنری را میسازیم
wordDict2 = dict()

for w in words:
    if w in wordDict2.keys():
        wordDict2[w]+=1 # اگر آن کلمه در کلید وجود داشت به مقدار آن یکی اضافه شود
    else:
        wordDict2[w]=1 # اگر کلمه برای اولین بار دیده میشود و هنوز در کلید نیست آن را با مقدار یک اضافه کن

print('Our dictionary in second method:\n ', wordDict2)    
Our dictionary in first method:
  {'in': 2, 'hard': 1, 'on': 5, 'it!': 2, 'one': 1, 'Yeah': 1, 'noise': 1, 'we': 8, 'take': 1, 'Buddy': 3, 'peace': 1, 'some': 1, 'time': 1, 'mud': 2, 'old': 1, 'with': 1, 'Waving': 1, 'alright': 1, 'Playing': 1, 'poor': 1, "singin'": 1, 'street': 2, 'will': 16, 'the': 5, 'Somebody': 1, 'back': 1, 'banner': 1, 'your': 7, 'more': 1, 'put': 1, 'be': 1, 'do': 1, 'man': 5, 'an': 1, 'young': 1, 'Pleading': 1, 'You': 3, 'got': 3, 'boy': 1, 'face': 3, 'you': 12, 'make': 1, 'disgrace': 3, 'Shouting': 1, 'louder!': 1, 'yeah': 3, "you're": 3, 'a': 4, 'big': 5, 'into': 1, 'get': 1, 'better': 1, 'Kicking': 1, 'We': 8, 'come': 1, 'can': 1, 'sing': 1, 'gonna': 3, 'eyes': 1, 'world': 1, 'blood': 1, 'all': 2, 'someday': 3, 'rock': 8, 'over': 2, 'place': 3}
Our dictionary in second method:
  {'Buddy': 3, "you're": 3, 'a': 4, 'boy': 1, 'make': 1, 'big': 5, 'noise': 1, 'Playing': 1, 'in': 2, 'the': 5, 'street': 2, 'gonna': 3, 'be': 1, 'man': 5, 'someday': 3, 'You': 3, 'got': 3, 'mud': 2, 'on': 5, 'your': 7, 'face': 3, 'you': 12, 'disgrace': 3, 'Kicking': 1, 'can': 1, 'all': 2, 'over': 2, 'place': 3, "singin'": 1, 'We': 8, 'will': 16, 'we': 8, 'rock': 8, 'young': 1, 'hard': 1, 'Shouting': 1, 'take': 1, 'world': 1, 'blood': 1, 'Waving': 1, 'banner': 1, 'sing': 1, 'it!': 2, 'yeah': 3, 'an': 1, 'old': 1, 'poor': 1, 'Pleading': 1, 'with': 1, 'eyes': 1, 'get': 1, 'some': 1, 'peace': 1, 'Somebody': 1, 'better': 1, 'put': 1, 'back': 1, 'into': 1, 'do': 1, 'come': 1, 'alright': 1, 'louder!': 1, 'one': 1, 'more': 1, 'time': 1, 'Yeah': 1}
# ممکن است در خطوط بالا یکسانی دو دیکشنری دیده نشود
# بنابراین در خطوط پایین آن ها را از بیشترین مقدار اتفاق تا کمترین مرتب میکنیم تا مقایسه راحت شود:

print('Our dictionary in first method after sort:\n ',
      dict(sorted(wordDict1.items(),key=lambda i: i[1], reverse=True)))
print('Our dictionary in second method after sort:\n ',
      dict(sorted(wordDict2.items(),key=lambda i: i[1], reverse=True)))
#! نیاز نیست کد های مربوط به مرتب سازی را یاد بگیرید
Our dictionary in first method after sort:
  {'will': 16, 'you': 12, 'we': 8, 'We': 8, 'rock': 8, 'your': 7, 'on': 5, 'the': 5, 'man': 5, 'big': 5, 'a': 4, 'Buddy': 3, 'You': 3, 'got': 3, 'face': 3, 'disgrace': 3, 'yeah': 3, "you're": 3, 'gonna': 3, 'someday': 3, 'place': 3, 'in': 2, 'it!': 2, 'mud': 2, 'street': 2, 'all': 2, 'over': 2, 'hard': 1, 'one': 1, 'Yeah': 1, 'noise': 1, 'take': 1, 'peace': 1, 'some': 1, 'time': 1, 'old': 1, 'with': 1, 'Waving': 1, 'alright': 1, 'Playing': 1, 'poor': 1, "singin'": 1, 'Somebody': 1, 'back': 1, 'banner': 1, 'more': 1, 'put': 1, 'be': 1, 'do': 1, 'an': 1, 'young': 1, 'Pleading': 1, 'boy': 1, 'make': 1, 'Shouting': 1, 'louder!': 1, 'into': 1, 'get': 1, 'better': 1, 'Kicking': 1, 'come': 1, 'can': 1, 'sing': 1, 'eyes': 1, 'world': 1, 'blood': 1}
Our dictionary in second method after sort:
  {'will': 16, 'you': 12, 'We': 8, 'we': 8, 'rock': 8, 'your': 7, 'big': 5, 'the': 5, 'man': 5, 'on': 5, 'a': 4, 'Buddy': 3, "you're": 3, 'gonna': 3, 'someday': 3, 'You': 3, 'got': 3, 'face': 3, 'disgrace': 3, 'place': 3, 'yeah': 3, 'in': 2, 'street': 2, 'mud': 2, 'all': 2, 'over': 2, 'it!': 2, 'boy': 1, 'make': 1, 'noise': 1, 'Playing': 1, 'be': 1, 'Kicking': 1, 'can': 1, "singin'": 1, 'young': 1, 'hard': 1, 'Shouting': 1, 'take': 1, 'world': 1, 'blood': 1, 'Waving': 1, 'banner': 1, 'sing': 1, 'an': 1, 'old': 1, 'poor': 1, 'Pleading': 1, 'with': 1, 'eyes': 1, 'get': 1, 'some': 1, 'peace': 1, 'Somebody': 1, 'better': 1, 'put': 1, 'back': 1, 'into': 1, 'do': 1, 'come': 1, 'alright': 1, 'louder!': 1, 'one': 1, 'more': 1, 'time': 1, 'Yeah': 1}



3. به عنوان آخرین مثال می‌خواهیم دو دیکشنری را با هم ترکیب کنیم. ابتدا دو دیکشنری از تعداد کلمات می‌سازیم، سپس این دو را یکی می‌کنیم:
hotelCalifornia = " On a dark desert highway, cool wind in my hair \
Warm smell of colitas, rising up through the air \
Up ahead in the distance, I saw a shimmering light \
My head grew heavy and my sight grew dim \
I had to stop for the night \
There she stood in the doorway; \
I heard the mission bell \
And I was thinking to myself, \
\"This could be Heaven or this could be Hell\" \
Then she lit up a candle and she showed me the way \
There were voices down the corridor, \
I thought I heard them say... \
Welcome to the Hotel California \
Such a lovely place (Such a lovely place) \
Such a lovely face \
Plenty of room at the Hotel California \
Any time of year (Any time of year) \
You can find it here \
Her mind is Tiffany-twisted, she got the Mercedes bends \
She got a lot of pretty, pretty boys she calls friends \
How they dance in the courtyard, sweet summer sweat. \
Some dance to remember, some dance to forget \
So I called up the Captain, \
\"Please bring me my wine\" \
He said, \"We haven't had that spirit here since nineteen sixty nine\" \
And still those voices are calling from far away, \
Wake you up in the middle of the night \
Just to hear them say... \
Welcome to the Hotel California \
Such a lovely place (Such a lovely place)\
Such a lovely face \
They livin' it up at the Hotel California\
What a nice surprise (what a nice surprise)\
Bring your alibis\
Mirrors on the ceiling,\
The pink champagne on ice\
And she said \"We are all just prisoners here, of our own device\" \
And in the master's chambers, \
They gathered for the feast \
They stab it with their steely knives, \
But they just can't kill the beast \
Last thing I remember, I was \
Running for the door \
I had to find the passage back \
To the place I was before \
Relax,  said the night man, \
We are programmed to receive . \
You can check-out any time you like, \
But you can never leave!"


weWillRockYou = "Buddy, you're a boy, make a big noise\n\
Playing in the street, gonna be a big man someday\n\
You got mud on your face, you big disgrace\n\
Kicking your can all over the place, singin'\n\
We will, we will rock you\n\
We will, we will rock you\n\
Buddy, you're a young man, hard man\n\
Shouting in the street, gonna take on the world someday\n\
You got blood on your face, you big disgrace\n\
Waving your banner all over the place\n\
We will, we will rock you, sing it!\n\
We will, we will rock you, yeah\n\
Buddy, you're an old man, poor man\n\
Pleading with your eyes, gonna get you some peace someday\n\
You got mud on your face, big disgrace\n\
Somebody better put you back into your place, do it!\n\
We will, we will rock you, yeah, yeah, come on\n\
We will, we will rock you, alright, louder!\n\
We will, we will rock you, one more time\n\
We will, we will rock you\n\
Yeah"

# علائم نگارشی را حذف میکنیم:
for p in '.,"\'!;()':
    hotelCalifornia = hotelCalifornia.replace(p,'')
    weWillRockYou = weWillRockYou.replace(p,'')
#کلمات را جدا میکنیم
wordsWWRY = weWillRockYou.split()
wordsHC = hotelCalifornia.split()

#دیکشنری را برای هر کدام به صورت جدا میسازیم
dictWWRY = dict()
dictHC = dict()
for w in wordsWWRY:
    if w in dictWWRY.keys():
        dictWWRY[w]+=1
    else:
        dictWWRY[w]=1

for w in wordsHC:
    if w in dictHC.keys():
        dictHC[w]+=1
    else:
        dictHC[w]=1

#------------------------------------------------------        
# حال وقت ترکیب دو دیکشنری است
#حال داده ها را با هم مخلوط میکنیم
# من در اینجا تصمیم گرفتم داده های دیکشنری وی ویل راک یو را در هتل کالیفورنیا بریزم

for (k,v) in dictWWRY.items():
    if k in dictHC.keys():
        dictHC[k]+=dictWWRY[k]
    else:
        dictHC[k]=dictWWRY[k]
print(dictHC)
{'On': 1, 'a': 16, 'dark': 1, 'desert': 1, 'highway': 1, 'cool': 1, 'wind': 1, 'in': 8, 'my': 3, 'hair': 1, 'Warm': 1, 'smell': 1, 'of': 7, 'colitas': 1, 'rising': 1, 'up': 5, 'through': 1, 'the': 29, 'air': 1, 'Up': 1, 'ahead': 1, 'distance': 1, 'I': 11, 'saw': 1, 'shimmering': 1, 'light': 1, 'My': 1, 'head': 1, 'grew': 2, 'heavy': 1, 'and': 2, 'sight': 1, 'dim': 1, 'had': 3, 'to': 9, 'stop': 1, 'for': 3, 'night': 3, 'There': 2, 'she': 6, 'stood': 1, 'doorway': 1, 'heard': 2, 'mission': 1, 'bell': 1, 'And': 3, 'was': 3, 'thinking': 1, 'myself': 1, 'This': 1, 'could': 2, 'be': 3, 'Heaven': 1, 'or': 1, 'this': 1, 'Hell': 1, 'Then': 1, 'lit': 1, 'candle': 1, 'showed': 1, 'me': 2, 'way': 1, 'were': 1, 'voices': 2, 'down': 1, 'corridor': 1, 'thought': 1, 'them': 2, 'say': 2, 'Welcome': 2, 'Hotel': 4, 'California': 3, 'Such': 5, 'lovely': 6, 'place': 7, 'face': 5, 'Plenty': 1, 'room': 1, 'at': 2, 'Any': 2, 'time': 4, 'year': 2, 'You': 5, 'can': 4, 'find': 2, 'it': 5, 'here': 3, 'Her': 1, 'mind': 1, 'is': 1, 'Tiffany-twisted': 1, 'got': 5, 'Mercedes': 1, 'bends': 1, 'She': 1, 'lot': 1, 'pretty': 2, 'boys': 1, 'calls': 1, 'friends': 1, 'How': 1, 'they': 2, 'dance': 3, 'courtyard': 1, 'sweet': 1, 'summer': 1, 'sweat': 1, 'Some': 1, 'remember': 2, 'some': 2, 'forget': 1, 'So': 1, 'called': 1, 'Captain': 1, 'Please': 1, 'bring': 1, 'wine': 1, 'He': 1, 'said': 3, 'We': 11, 'havent': 1, 'that': 1, 'spirit': 1, 'since': 1, 'nineteen': 1, 'sixty': 1, 'nine': 1, 'still': 1, 'those': 1, 'are': 3, 'calling': 1, 'from': 1, 'far': 1, 'away': 1, 'Wake': 1, 'you': 15, 'middle': 1, 'Just': 1, 'hear': 1, 'placeSuch': 1, 'They': 3, 'livin': 1, 'CaliforniaWhat': 1, 'nice': 2, 'surprise': 1, 'what': 1, 'surpriseBring': 1, 'your': 8, 'alibisMirrors': 1, 'on': 7, 'ceilingThe': 1, 'pink': 1, 'champagne': 1, 'iceAnd': 1, 'all': 3, 'just': 2, 'prisoners': 1, 'our': 1, 'own': 1, 'device': 1, 'masters': 1, 'chambers': 1, 'gathered': 1, 'feast': 1, 'stab': 1, 'with': 2, 'their': 1, 'steely': 1, 'knives': 1, 'But': 2, 'cant': 1, 'kill': 1, 'beast': 1, 'Last': 1, 'thing': 1, 'Running': 1, 'door': 1, 'passage': 1, 'back': 2, 'To': 1, 'before': 1, 'Relax': 1, 'man': 6, 'programmed': 1, 'receive': 1, 'check-out': 1, 'any': 1, 'like': 1, 'never': 1, 'leave': 1, 'Buddy': 3, 'youre': 3, 'boy': 1, 'make': 1, 'big': 5, 'noise': 1, 'Playing': 1, 'street': 2, 'gonna': 3, 'someday': 3, 'mud': 2, 'disgrace': 3, 'Kicking': 1, 'over': 2, 'singin': 1, 'will': 16, 'we': 8, 'rock': 8, 'young': 1, 'hard': 1, 'Shouting': 1, 'take': 1, 'world': 1, 'blood': 1, 'Waving': 1, 'banner': 1, 'sing': 1, 'yeah': 3, 'an': 1, 'old': 1, 'poor': 1, 'Pleading': 1, 'eyes': 1, 'get': 1, 'peace': 1, 'Somebody': 1, 'better': 1, 'put': 1, 'into': 1, 'do': 1, 'come': 1, 'alright': 1, 'louder': 1, 'one': 1, 'more': 1, 'Yeah': 1}

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

بازگشت به فهرست اصلی

مقدمه

برنامه نویسی شیء گرا یا Object Oriented Programming جزء مطالبی است که خیلی به گوش شما می‌خورد اما ممکن است مفهوم آن هیچگاه برای شما واضح نباشد. برای آن که این مفهوم برای شما جا بیافتد نیاز است به آن به چشم ساده تری نگاه کنید.
در پایتون به محض تعریف کردن کلاس و موارد وابسته به آن، شما با برنامه نویسی شیء گرا رو به رو هستید. بنابراین حتی ممکن است از این که از روش OOP استفاده می‌کنید مطلع هم نباشید.
بگذارید در این فصل این نام را کنار بگذاریم و به چشم ساده به مطالب نگاه کنیم. تنها لازم است به خاطر داشته باشید در ادامه هر مطلبی که به کلاس و اجزای آن مرتبت است جزء برنامه نویسی شیء گرا تلقی می‌شود.
شاید از قبل بدانید که یک کتابخانه از تعداد متعددی کلاس تشکیل شده است؛ و یا تمامی ویژگی هایی که در پایتون از آن ها استفاده می‌کنید یک کلاس هستند. برای مثال لیست در پایتون به صورت کلاس تعریف شده است. رشته، عدد، مجموعه و دیکشنری نیز کلاس های متفاوتی هستند به صورت از پیش تعیین شده در پایتون وجود دارند. اگر دقت کرده باشید زمانی که از type استفاده می‌کنیم از عبارت class استفاده می‌کند.
وقت آن است که به سراغ تعریف کلاس و چند مثال برویم:
class name_of_your_class(): # در پرانتز ارث بری را خواهیم داشت که بعدا در مورد آن صحبت میکنیم
    def __init__(self): # *
        print('In the initial defenition!')
    
myclass = name_of_your_class() #**
In the initial defenition!

* در بالا یک تابع اولیه است که در تمامی کلاس ها وجود دارد. در آن یک ورودی self هست که حتما باید در تابع اولیه باشد. self یک مقدار اولیه است که با استفاده از آن می‌توان از ویژگی های از پیش تعیین شده کلاس استفاده کرد. به مرور با این ویژگی ها آشنا می‌شویم.
در تابع اولیه یک پرینت گذاشته ایم. همان طور که در ** می‌بینید ما تنها از کلاس یک مقدار تعریف کردیم. به محض تعریف کلاس تابع اولیه اجرا می‌شود. به همین دلیل پرینت اجرا شده است.
حال به مثال خود می افزاییم:
class name_of_your_class():
    def __init__(self): 
        print('In the initial defenition!')
    
    def myPrint(self, val):
        print(str(val))
        
myclass = name_of_your_class()
myclass.myPrint('print this.')
In the initial defenition!
print this.

در بالا یک تابع دیگر نیز به کلاس اضافه کردیم. در ورودی دو مقدار گرفته است. یکی همان self که مقدار اولیه است و اجازه استفاده از ویژگی های کلاس را به ما می‌دهد. دومی مقداری که قرار است در پرینت از آن استفاده شود.
استفاده از SELF برای این است که می‌خواهیم در خارج از کلاس از این تابع استفاده کنیم.
پس از تعریف کلاس در خط آخر (9) از تابع پرینت استفاده کردیم و یک مقدار را برای آن ارسال کردیم تا پرینت کند.
حال به مثال زیر توجه کنید. اگر خود کلاس را پرینت کنیم چه می‌شود؟
class name_of_your_class():
    def __init__(self): 
        print('In the initial defenition!')
    
    def myPrint(self, val):
        print(str(val))
        
myclass = name_of_your_class()
print(myclass)
In the initial defenition!
<__main__.name_of_your_class object at 0x000001E60C4A9B08>

فرض کنید می‌خواهیم در صورت پرینت کلاس اطلاعات خاصی را به شما نشان دهد. در آن صورت از تابع زیر استفاده می‌کنیم که ویژگی های آن باز هم از پیش تعیین شده هستند
class name_of_your_class():
    def __init__(self): 
        print('In the initial defenition!')
    
    def myPrint(self, val):
        print(str(val))
        
    def __str__(self):
        return 'This is class name_of_your_class'
        
myclass = name_of_your_class()
print(myclass)
In the initial defenition!
This is class name_of_your_class

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

اما بیایید کلاسی تعریف کنیم که در آن اطلاعات یک انسان را ثبت کنیم. به این معنا که هر انسان یک کلاس باشد.
class person():
    def __init__(self, name): # در مرحله اول نام فرد را به عنوان ورودی میگیریم
        self.name = name # در اینجا نام را به عنوان یک متغیر داخل کلاس تعریف میکنیم که آن را نگهداری کنیم
        self.age = None # یک متغیر سن نیز تعریف میکنیم تا بعدا آن را مقدار دهی کنیم
        
    # در تابع زیر سن را مشخص میکنیم
    def set_age(self, age): 
        self.age = age
    # در زیر نیز سن را بر میگردانیم   
    def get_age(self):
        return self.age
    
    # اضافه کردن دو کلاس به هم این تابع را صدا میکند
    # به خط 34 دقت کنید
    def __add__(self, otherPerson):
        return self.age + otherPerson.age
        
    def __str__(self):
        return "This person's name is "+self.name+" and they are "+str(self.age)+" year(s) old."

    
# حال زمان آن رسیده است که یک فرد را تعریف کنیم:
person1 = person('Niloofar')
print(person1)
person1.set_age(26)
print(person1)

# نفر دوم را معرفی میکنیم:
person2 = person('Your Name')
person2.set_age(20)
print(person2)

# حال دو نفر را با هم جمع میکنیم
print('add two peaple: ', person2+person1)
This person's name is Niloofar and they are None year(s) old.
This person's name is Niloofar and they are 26 year(s) old.
This person's name is Your Name and they are 20 year(s) old.
add two peaple:  46

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

می‌توانیم با همین روش اطلاعات دیگری را نیز به کلاس خود اضافه کنیم. این بار یک ساز را تعریف می‌کنیم:
class instrument():
    def __init__(this, name_of_instrument, voice_of_instrument = None, age_of_instrument=None, type_of = None):
        this.name = name_of_instrument
        this.voice = voice_of_instrument
        this.age = age_of_instrument
        this.type = type_of
        
    def set_voice(this,voice_of_instrument):
        this.voice = voice_of_instrument
        
    def set_age(this, age_of_instrument):
        this.age = age_of_instrument 
    
    def set_type(this, type_of):
        this.type = type_of
        
    def __add__(this, other):
        return str(this.voice)+' and '+str(other.voice)
    def __str__(this):
        return str(this.voice)
    
#
ins1 = instrument('Guitar',voice_of_instrument='ring ring')
ins2 = instrument('Piano', 'ding dong')
print(ins1)
print(ins2)
print(ins1+ins2)
print(ins2+ins1)
ring ring
ding dong
ring ring and ding dong
ding dong and ring ring

در تابع ابتدایی کلاس بالا نوع دیگری از تعریف متغیر ها را می‌بینید. می‌توانید به این صورت اجازه تعریف متغیر در اول کار یا بعدا را به کاربر بدهید. اگر نام ورودی ها را بیان کنید می‌توانید به هر ترتیبی ورودی های خود را بدهید. اما اگر نام ورودی ها را وارد نکنید حتما باید به ترتیب داخل تابع ورودی ها را وارد کنید.
برای مثال اگر بخواهید تنها سن ساز را مشخص کنید و نه صدای آن را؛ نیاز است بنویسید age_of_instrument=1 که به این ترتیب از انتخاب مقدار صدا صرف نظر کرده اید.
نکته دیگری که در کلاس بالا وجود دارد استفاده از کلمه this به جای کلمه self است. با این روش به شما نشان داده شد که نام برای این متغیر اهمیتی ندارد و هر نامی به عنوان اولین متغیر تعریف شود متغیر مربوط به کلاس برای استفاده از ویژگی های آن است.

حال در زیر یک کلاس تعریف می‌کنیم برای یک کلاس درس که در آن می‌توانیم شماره دانشجویی افراد را به همراه نمره آنان تعریف کنیم:
class math():
    def __init__(self):
        self.classDict = dict()
        
    def add_score(self, stdID, score):
        if stdID in self.classDict.keys():
            print('This ID is already in the list.')
        else:
            self.classDict[stdID] = score
        
    def change_score(self, stdID, score):
        if stdID not in self.classDict.keys():
            print('This student ID is not in the class yet. please try adding the score.')
            print('Current scudents are ', list(self.classDict.keys()))
        else:
            self.classDict[stdID] = score
    
    def mean_of_class(self):
        return sum(self.classDict.values())/len(self.classDict)
    
    def __sub__(self, stdID):
        if stdID in self.classDict.keys():
            self.classDict.pop(stdID)
        else:
            print('No such student ID in list.')
    
    def __str__(self):
        return str(self.classDict)
            
myMath = math()
myMath.add_score('10',20)
myMath.add_score('12',19)
myMath.add_score('11',12)
myMath.add_score('20',18)
myMath.add_score('18',20)

#افزودن مقداری که قبلا در دیکشنری وجود داشته
myMath.add_score('11',15)

# تغییر مقدار بالا
myMath.change_score('11',15)

# تغییر مقداری که در کلید های دیکشنری نیست
myMath.change_score('111',16)

print('Mean of class:',myMath.mean_of_class())

# حذف یک کلید با مقدار آن
myMath-'10'
print(myMath)
This ID is already in the list.
This student ID is not in the class yet. please try adding the score.
Current scudents are  ['10', '12', '11', '20', '18']
Mean of class: 18.4
{'12': 19, '11': 15, '20': 18, '18': 20}

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

حال با یادگیری کلاس و دیدن چند نمونه از آن به سراغ مفهوم ارث بری می‌رویم.
ارث بری در کلاس مفهوم جدیدی نیست. چرا؟ زیرا حتی زمانی که یک کلاس را به صورت معمولی تعریف می‌کنید از مفهوم ارث بری استفاده می‌کنید. به مثال زیر دقت کنید:
class name_of_your_class(object):
    def __init__(self): 
        print('In the initial defenition!')
    
myclass = name_of_your_class()
In the initial defenition!

کلاس بالا را در ابتدای این فصل دیدید. اما در اینجا کلاس از object ارث برده است. دلیل نداشتن تفاوت آن با کلاس اول این است که پایتون این امکان را می‌دهد که کلاس ها ارث بری پنهان از ویژگی های اولیه داشته باشند. به همین دلیل نیاز به نوشتن object نداریم.

اما با این مثال متوجه شدیم که برای ارث بری کافی است نام کلاس قبلی (که از آن ارث برده میشود و کلاس پدر نام دارد) را هنگام تعریف کلاس در پرانتز بنویسیم. حال می‌خواهیم یک کلاس دانشجو تعریف کنیم که از کلاس انسان که بالا تر تعریف شده است ارث ببرد:
# کلاس انسان که قبلا تعریف شده بود:
class person():
    def __init__(self, name):
        self.name = name
        self.age = None
    
    def set_age(self, age): 
        self.age = age
    def get_age(self):
        return self.age
    def __add__(self, otherPerson):
        return self.age + otherPerson.age
    def __str__(self):
        return "This person's name is "+self.name+" and they are "+str(self.age)+" year(s) old."

# کلاس دانشجو:
class student(person):
    def __init__(self, name, stdID):
        # ابتدا اطلاعاتی که در کلاس پدر وجود دارند و نیاز به تعریف دوباره ندارند را به کلاس پدر باز میگردانیم
        person.__init__(self,name) 
        self.stdid = stdID
        
    def __str__(self):
        return self.name+' '+self.stdid

std1 = student('Asta','10')
std1.set_age(16) # تابعی در کلاس پدر که به آن دسترسی داریم
print('age: ',std1.get_age()) # باز هم تابعی در کلاس پدر
print(std1)
age:  16
Asta 10

با مثال بالا به راحتی از ارث بری استفاده کردیم و راحتی کار با آن را دیدیم.

به مثال زیر نیز توجه کنید:
# کلاس ساز که قبلا پیاده سازی شده بود:
class instrument():
    def __init__(this, name_of_instrument, voice_of_instrument = None, age_of_instrument=None, type_of = None):
        this.name = name_of_instrument
        this.voice = voice_of_instrument
        this.age = age_of_instrument
        this.type = type_of
        
    def set_voice(this,voice_of_instrument):
        this.voice = voice_of_instrument
        
    def set_age(this, age_of_instrument):
        this.age = age_of_instrument 
    
    def set_type(this, type_of):
        this.type = type_of
        
    def __add__(this, other):
        return str(this.voice)+' and '+str(other.voice)
    def __str__(this):
        return str(this.voice)

    
# کلاس ساز سیمی را پیاده سازی میکنیم:
class string_instrument(instrument):
    def __init__(self, name_of_instrument, age_of_instrument=None):
        instrument.__init__(self, name_of_instrument, 'ring ring', 
                            age_of_instrument = age_of_instrument, type_of='string')
        self.material_of_body = 'wood'
        
    def set_material_of_body(self, material):
        self.material_of_body = material


# تعریف دو مقدار از کلاس
guitarC = string_instrument('guitar')
print(guitarC)

guitarE = string_instrument('guitar El')
guitarE.set_material_of_body('metal')
print(guitarE)
ring ring
ring ring

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

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

مقدمه

به طور کلی الگوریتم های بسیار متفاوتی در طول زمان برای مرتب سازی به وجود آمده‌اند. تفاوت آنها در روند و زمان مرتب‌سازی است. برخی از دیگری بهینه‌تر هستند. برای مثال الگوریتم استفاده شده در توابع از پیش تعریف شدۀ مرتب سازی در عموم زبان‌های برنامه نویسی، بهینه ترین حالت مرتب سازی است.
در اینجا با برخی از این الگوریتم‌ها از جمله مرتب سازی حبابی (bubble sort)، مرتب سازی انتخابی (selction sort)، و مرتب سازی ادغامی (merge sort) آشنا می‌شویم.
سپس به سراغ چند نوع از روش جستوجو می‌رویم و آنها را با هم مرور می‌کنیم.

می‌دانیم که اگر یک تعداد کارت شامل عدد را به تعداد بی نهایت بار به هم بریزیم بالاخره در جایی به ترتیبی بر می‌خوریم که در آن کارت ها به صورت مرتب چیده شده‌اند. اما زندگی این زمان را به ما نمی‌دهد. :)
بنابراین به سراغ روش‌های هوشمندانه تر می‌رویم. یکی از این روش ها مرتب سازی حبابی است که روند آن به صورت زیر است:

با توجه به تصویر، هر دو مقدار به صورت دوتا دوتا با هم مقایسه می‌شوند و تا آخر لیست می‌رود. بار دیگر از ابتدای لیست شروع می‌کنیم و این کار را آن قدر انجام می‌دهیم تا تمام لیست مرتب شود و دیگر هیچ عنصری جا به جا نشود. آن موقع است که مرتب سازی به پایان رسیده است.
اما توضیح تا اینجا کافی است. وقت آن است که به سراغ کد برویم.
def bubble_sort(L):
    swap = True
    while swap:                         # تا زمانی که جا به جایی انجام میشود در داخل حلقه میمانیم
        print('bubble sort: ' + str(L)) # هر مرحله را به شما نشان میدهد
        swap =False                     # فرض میکنیم جا به جایی نداریم
        for j in range(1, len(L)):      # هر بار از عنصر دوم شروع میکنیم تا آخر میرویم
            if L[j-1] > L[j]:           # اگر عنصری که روی آن هستیم از عنصر قبل خودش کوچکتر بود آنها را جا به جا میکنیم
                swap = True
                L[j-1],L[j] = L[j],L[j-1]
testList = [1,3,5,7,2,6,25,18,13]

print(bubble_sort(testList)) # چیزی باز نمیگرداند زیرا در تابع ریترن تعریف نشده است
print(testList)# همان لیست اصلی مرتب شده است
bubble sort: [1, 3, 5, 7, 2, 6, 25, 18, 13]
bubble sort: [1, 3, 5, 2, 6, 7, 18, 13, 25]
bubble sort: [1, 3, 2, 5, 6, 7, 13, 18, 25]
bubble sort: [1, 2, 3, 5, 6, 7, 13, 18, 25]
None
[1, 2, 3, 5, 6, 7, 13, 18, 25]

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

در مرتب سازی انتخابی، از ابتدای لیست شروع می‌کنیم. آن را به عنوان عضو مقایسه شوند در نظر می‌گیریم و دانه دانه با باقی داده ها مقایسه می‌کنیم. اگر در طول مقایسه عضو کوچکتری یافت شد آن را به عنوان جایگزین در نظر می‌گیریم و باز هم جلوتر می‌رویم. اگر تا اخر لیست عضو کوچکتری یافت شد آن جایگزین می‌کنیم.
این توضیحات مربوط به الگوریتم اصلی است که در تصویر هم می‌بینید. اما از آنجا که پیاده سازی آن کمی سخت تر است، در پیاده سازی زیر روشی را می‌بینیم که در طول مقایسه هرگاه به مقدار کوچکتر رسید آن را جایگزین می‌کند و سپس مقایسه را با آن مقدار کوچکتر انجام می‌دهد:
def selection_sort(L):
    suffixSt = 0                           # شمارنده انتخابی جایگاه
    while suffixSt != len(L):              # تازمانی که به ته لیست نرسیده ایم
        print('selection sort: ' + str(L)) # جهت دیدن لیست در هر مرحله
        for i in range(suffixSt, len(L)):  # از جایگاه انتخابی به بعد را با آن جایگاه مقایسه میکنیم
            if L[i] < L[suffixSt]:         # هربار هنصر جایگاه انتخابی بزرگتر از عنصر جایگاه مقایسه ای بود وارد این شرط میشود
                L[suffixSt], L[i] = L[i], L[suffixSt] # جای دو عنصر را عوض میکند
        suffixSt += 1                      # جایگاه انتخابی را یکی به جلو میبریم
    
testList = [1,3,5,7,2,6,25,18,13]

print(selection_sort(testList)) # باز هم اطلاعاتی باز نمیگرداند زیرا مرتب سازی روی لیست اولیه انجام میگیرد
print(testList)
selection sort: [1, 3, 5, 7, 2, 6, 25, 18, 13]
selection sort: [1, 3, 5, 7, 2, 6, 25, 18, 13]
selection sort: [1, 2, 5, 7, 3, 6, 25, 18, 13]
selection sort: [1, 2, 3, 7, 5, 6, 25, 18, 13]
selection sort: [1, 2, 3, 5, 7, 6, 25, 18, 13]
selection sort: [1, 2, 3, 5, 6, 7, 25, 18, 13]
selection sort: [1, 2, 3, 5, 6, 7, 25, 18, 13]
selection sort: [1, 2, 3, 5, 6, 7, 13, 25, 18]
selection sort: [1, 2, 3, 5, 6, 7, 13, 18, 25]
None
[1, 2, 3, 5, 6, 7, 13, 18, 25]

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

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

در مرحله اول دو لیست کوچک را به صورت دستی مقایسه کردیم و روش انسانی را دیدیم. در مرحله بعد از روش کامپیوتری استفاده کردیم و i و j را به جلو بردیم و داده ها را در لیست بزرگتر قرار دادیم.
برای آن که مرحله دوم بهتر جا بیافتد به صورت نوشته مراحل را توضیح می‌دهم:

1. ابتدا شمارنده i بر روی 3 قرار دارد و شمارنده j برروی 9. 3 از 9 کوچکتر است پس 3 نوشته می‌شود و شمارنده ی i یکی به جلو می‌رود.
2. حال شمانده i برروی27 قرار دارد و شمارنده j همچنان برروی 9 است. این بار 9 نوشته می‌شود و شمارنده j یکی به جلو می‌رود.
3. در مرحله بعد باز هم 10 از 27 کوچکتر است پس شمارنده i همچنان در جای خود است و شمارنده j یکی به جلو می‌رود.
4. حال شمارنده j به 82 می‌رسد. جون از 27 بزرگتر است این بار شمارنده i به جلو می‌رود.
5. در مرحله بعد باز هم 38 از 82 کوچکتر است بنابراین باز هم شمارنده i به جلو می‌روند و شمارنده j تکان نمی‌خورد.
6. در مرحله بعدی نیز بار دیگر 43 کوچکتر از 82 است. پس لیست اول به اتمام می‌رسد و از لیست دوم مقادیری می‌ماند.
7. در این مرحله هر چه از لیست دوم مانده را به ته لیست بزرگ اضافه می‌کنیم.
# در تابع زیر اعضای جدا شده با هم مقایسه میشود.
# بنابراین ورودی یک لیست در چپ و یک لیست در راست است
def merge(left, right):
    result = []
    i,j = 0,0
    while i < len(left) and j < len(right): # تا زمانی که میتوان بین دوتا مقایسه کرد انجام میشود
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    # به خاطر داشته باشید که پس از اتمام حلقه بالا تنها یکی از حلقه های پایین رخ میدهد
    while (i < len(left)): # اگر داده های از لیست چپ مانده بود همه را اضافه میکند
        result.append(left[i])
        i += 1
    while (j < len(right)): # اگر داده از لیست راست مانده بود آنها را اضافه میکند
        result.append(right[j])
        j += 1
    print('merge: ' + str(left) + '&' + str(right) + ' to ' +str(result)) # چاپ هر مرحله
    return result

# در زیر  لیست بزرگ تا زمانی که دارای یک مقدار یکی باشد به صورت کپی  از هم جدا میشود
# و پس از باز شدن توسط تابع بالا مرتب میشود
def merge_sort(L):
    print('merge sort: ' + str(L)) # برای آن که هر مرحله ببینیم چه اتفاقی می افتد
    if len(L) < 2: # اگر اندازه لیست کمتر از 2 بود خود لیست عددی را بر میگرداند
        return L[:] # لیستی از یک عدد
    else:
        middle = len(L)//2 # میانه ی لیست را در نظر میگیریم
        left = merge_sort(L[:middle]) # شما چپ لیست را دوباره باز میگردانیم و آن را در چپ ذخیره میکنیم
        right = merge_sort(L[middle:]) # سمت راس را دوباره برای تکه شدن بر میگردانیم و آن را در راست ذخیره میکنیم
        return merge(left, right) # در نهایت راست و چپ را برای اتصال به هم به تابع بالا میفرستیم
testList = [1,3,5,7,2,6,25,18,13]

print(merge_sort(testList)) # اینجا در نهایت یک لیست بازگردانده میشود
merge sort: [1, 3, 5, 7, 2, 6, 25, 18, 13]
merge sort: [1, 3, 5, 7]
merge sort: [1, 3]
merge sort: [1]
merge sort: [3]
merge: [1]&[3] to [1, 3]
merge sort: [5, 7]
merge sort: [5]
merge sort: [7]
merge: [5]&[7] to [5, 7]
merge: [1, 3]&[5, 7] to [1, 3, 5, 7]
merge sort: [2, 6, 25, 18, 13]
merge sort: [2, 6]
merge sort: [2]
merge sort: [6]
merge: [2]&[6] to [2, 6]
merge sort: [25, 18, 13]
merge sort: [25]
merge sort: [18, 13]
merge sort: [18]
merge sort: [13]
merge: [18]&[13] to [13, 18]
merge: [25]&[13, 18] to [13, 18, 25]
merge: [2, 6]&[13, 18, 25] to [2, 6, 13, 18, 25]
merge: [1, 3, 5, 7]&[2, 6, 13, 18, 25] to [1, 2, 3, 5, 6, 7, 13, 18, 25]
[1, 2, 3, 5, 6, 7, 13, 18, 25]


با این توضیحات مرتب سازی به پایان میرسد و به سراغ جستوجو می‌رویم.
ساده ترین الگوریتم جستوجویی که می‌توانیم پیاده سازی کنیم الگوریتم جستوجوی خطی است. به این صورت که می‌توانیم یکی یکی اعضای یک لیست را جلو برویم و به دنبال هدف مورد نظر باشیم.
پیاده سازی آن را در زیر می‌بینیم:
def linear_search(l, element):
    place = -1 # اگر  المان هیچگاه پیدا نشد مقدار -1 میدهد
    for i in range(len(l)):
        if l[i]==element: #اگر پیدا شد عدد مکان
            place=i
            break
    return place


testList = [1,3,5,7,2,6,25,18,13]
we_search_for = 18
print(linear_search(testList,we_search_for))
7


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

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

اما کد بازگشتی این جستوجو به صورت زیر است:
# مقادیر لیست، المانی که دنبال آن هستیم، بخش شروع و پایان را برای تابع میفرستیم.
# در ابتدا شروع و پایان ابتدا و انتهای لیست هستند
def binary_search_recursive(array, element, start, end):
    # شزط پایانی بازگشتی
    if start > end: # اگر عدد شروع بزرگتر از عدد پایان شد کار را به اتمام میرسانیم
        return -1
    print('Now we are in this part: ',array[start:end])
    # برای باقی حالات ابتدا میانه را برای شروع و پایان به دست می آوریم
    mid = (start + end) // 2
    # اگر مقدار همان چیزی بود که دنبالس هستیم آن را بر میگردانیم
    if element == array[mid]:
        return mid
    # اگر میانه از مقدار مورد نظر بزرگتر بود به سمت چپ میرویم
    if element < array[mid]:
        return binary_search_recursive(array, element, start, mid-1)
    # اگر میانه از مقدار مورد نظر  کوچکتر بود به سمت راست میرویم
    else:
        return binary_search_recursive(array, element, mid+1, end)
test_list = [1,3,4,5,6,7,12,14,24,45,67]
elem = 45
binary_search_recursive(test_list, elem, 0, len(test_list))
Now we are in this part:  [1, 3, 4, 5, 6, 7, 12, 14, 24, 45, 67]
Now we are in this part:  [12, 14, 24, 45, 67]
Now we are in this part:  [45, 67]
Now we are in this part:  []





9

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

مقدمه

کتابخانه scipy برپایه کتابخانه numpy تولید شده است و برای برنامه نویسی خطی مورد استفاده قرار می‌گیرد. این برنامه به طور کلی برای بهینه سازی است. بنابراین در این فصل تنها اشاره کوچکی به آن خواهیم داشت.
به عنوان یک معرفی کلی از کتابخانه scipy، می‌توان به برخی از زیر بخش های آن در پایین اشاره کرد:
برخی توابع خاص (scipy.special)
انتگرال گیری (scipy.integrate)
بهینه سازی (scipy.optimize)
جبر خطی (scipy.linalg)
محاسبات آماری (scipy.stats)
و بسیاری دیگر که در اینجا به آنها اشاره نشده است.
به عنوان شروع به سراغ برخی توابع خاص می‌رویم:
import numpy as np
import scipy.special as sc
import matplotlib.pyplot as plt

x= np.linspace(0, 1, 50)


def binary_entropy(x):
    return -(sc.xlogy(x, x) + sc.xlog1py(1 - x, -x))/np.log(2)


be = binary_entropy(x)
plt.plot(x,be)
plt.show()

png

# با استفاده از کد زیر میتوانید به تمامی تابع های مختلفی که در اسپشال تعریف شده اند دسترسی پیدا کنید
#و به هر کدام نیاز داشتید آن را  مورد استفاده قرار بدهید
help(sc)

توابع بسیاری در این بخش وجود دارند و برای محاسبات پیچیده ریاضی، بسیار به کار می آیند. در بالا بخشی از این توابع را دیدیم. در قسمت help نیز تمامی توابع را می‌توانید ببینید. البته تعداد این توابع بسیار زیاد هستند.
در ادامه به سراغ بخش جبر خطی می‌رویم . قسمتی از توابع آن را با هم مرور می‌کنیم:
import numpy as np
from scipy import linalg
A = np.array([[1,2],[3,4]])
print(A)

print('1. inv: \n', linalg.inv(A))


b = np.array([[5,6]]) 
print('b 2d:', b) #به صورت ماتریسی ترانهاده میشود

print('2. transpose:\n',b.T)

print('3. A*b:\n', A*b)

print('4. A.bT:\n',A.dot(b.T))

b = np.array([5,6])
print('b 1d:', b) # حالت ماتریسی نیست اما نوعی ترانهاده است

print('5. b 1d transpose: \n',b.T)

print('6. A.bT:\n',A.dot(b.T))
[[1 2]
 [3 4]]
1. inv: 
 [[-2.   1. ]
 [ 1.5 -0.5]]
b 2d: [[5 6]]
2. transpose:
 [[5]
 [6]]
3. A*b:
 [[ 5 12]
 [15 24]]
4. A.bT:
 [[17]
 [39]]
b 1d: [5 6]
5. b 1d transpose: 
 [5 6]
6. A.bT:
 [17 39]
import numpy as np
from scipy import linalg
A = np.array([[1,3,5],[2,5,1],[2,3,8]])
print('A:\n',A)

print('A^(-1):\n',linalg.inv(A))

print('A*A^(-1):\n',A.dot(linalg.inv(A)) )
A:
 [[1 3 5]
 [2 5 1]
 [2 3 8]]
A^(-1):
 [[-1.48  0.36  0.88]
 [ 0.56  0.08 -0.36]
 [ 0.16 -0.12  0.04]]
A*A^(-1):
 [[ 1.00000000e+00 -1.11022302e-16  4.85722573e-17]
 [ 3.05311332e-16  1.00000000e+00  7.63278329e-17]
 [ 2.22044605e-16 -1.11022302e-16  1.00000000e+00]]

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

در مثال زیر می‌خواهیم معادله Ax+b=0 را محاسبه کنیم و مقدار x را به دست بیاوریم. این کار را با استفاده از روش دستی و روش تعریف شده در linalg محاسبه می‌کنیم:
import numpy as np
from scipy import linalg
import time
A = np.array([[1, 2], [3, 4]])
b = np.array([[5], [6]])

t1 = time.time()
result = linalg.inv(A).dot(b)
tm = time.time() - t1
print('slow ('+str(round(tm*1000,6))+'ms) version:\n', result) 

print('check:\n',A.dot(linalg.inv(A).dot(b)) - b)  
slow (4.985809ms) version:
 [[-4. ]
 [ 4.5]]
check:
 [[0.]
 [0.]]
t1 = time.time()
result = np.linalg.solve(A, b)
tm = time.time() - t1
print('fast ('+str(round(tm*1000,6))+'ms) version: \n', result)

print('check:\n',A.dot(np.linalg.solve(A, b)) - b)
fast (0.0ms) version: 
 [[-4. ]
 [ 4.5]]
check:
 [[0.]
 [0.]]

همانطور که می‌بینید حل با استفاده از توابع از پیش تعیین شده linalg بسیار سریعتر است.

اما فرض کنید می‌خواهیم یک معادله درجه n را حل کنیم. برای این کار نمی‌توانیم به راحتی بالا تبدیل ها را خود انجام دهیم. در اینجا کتابخانه numpy به کمک ما می‌آید و سریع ترین حل معادله درجه n را در اختیار ما قرار می‌دهد.
import numpy as np
# ضریب های هر درجه:
# y = 𝑥^3 + 4𝑥^2 − 2𝑥 + 3
p = np.array([1, 4, -2, 3])
ys = np.polyval(p, [1, 2, 3])
print('y for these [1, 2, 3] xs is', ys)
 # for y=0 x is:
roots = np.roots(p)
print('roots are: ',roots)

# محاسبه انتگرال تابع بالا:
intgr = np.polyint(p)
print(intgr)
print('the integrate is %fx^4 +(%f)x^3 +(%f)x^2 +(%f)x +(%f) '%tuple(intgr)) 

# مشتق آن نیز به صورت زیر است:
der  = np.polyder(p)
print('the derivation is %fx^2 +(%f)x +(%f) '%tuple(der)) 
y for these [1, 2, 3] xs is [ 6 23 60]
roots are:  [-4.5797401 +0.j          0.28987005+0.75566815j  0.28987005-0.75566815j]
[ 0.25        1.33333333 -1.          3.          0.        ]
the integrate is 0.250000x^4 +(1.333333)x^3 +(-1.000000)x^2 +(3.000000)x +(0.000000) 
the derivation is 3.000000x^2 +(8.000000)x +(-2.000000) 

در تابع بالا تنها 1 ریشه از روی خط x=0 رد شده است و آن هم ریشه اولی است. 2 ریشه دیگر بر اساس فضای i+j تعریف شده‌اند.

در ادامه تابع نرم را داریم. می‌توانید انواع نرم را با استفاده از این تابع بدست بیاورید:
import numpy as np
from scipy import linalg
A=np.array([[1,2],[3,4]])

print(linalg.norm(A))
print(linalg.norm(A,'fro')) # نرم فروبنیوس یا نرم 2

print()
print('L1:',linalg.norm(A,1))

print('Linf:',linalg.norm(A,np.inf)) # نرم بینهایت
5.477225575051661
5.477225575051661

L1: 6.0
Linf: 7.0
help(linalg)

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

همچنین در زیربخش stats می‌توانید به برخی توابع ارزیابی پیچیده دسترسی پیدا کنید که بیشتر به مباحث آماری در سطح های بالاتر مربوط می‌شوند.
from scipy import stats
help(stats)

جا دارد در اینجا کمی بیشتر در مورد کتابخانه numpy و کارهایی که میتوان با استفاده از آن برروی چند جمله ای ها انجام داد صحبت کنیم.
در بالاتر با محاسبه مقدار، محاسبه ریشه، انتگرال و مشتق گیری توابع چند جمله ای آشنا شدیم.
در زیر با برخی ویژگی های دیگر numpy برای چند جمله ای ها نیز آشنا می‌شویم.
p = np.array([1, 4, -2, 3])
q = np.array([2, 7]) # 2x + 7

# افزودن دو چند جمله ای به هم:
print('addition:', np.polyadd(p, q) )
# کم کردن دو چند جمله ای از هم:
print('subtraction: ',np.polysub(p, q) )
addition: [ 1  4  0 10]
subtraction:  [ 1  4 -4 -4]
p = np.array([1, 4, -2, 3])
q = np.array([2, 7]) # 2x + 7

# ضرب دو چند جمله ای در هم:
print('multiplication: ',np.polymul(p, q) )
# تقسیم دو چند جمله ای:
print('division: ', np.polydiv(p, q) )
multiplication:  [ 2 15 24 -8 21]
division:  (array([ 0.5  ,  0.25 , -1.875]), array([16.125]))

اما فرض کنید چند نقطه دارید. می‌خواهید نزدیک ترین چند جمله ای را به آن فیت کنید.
در این حالت از ویژگی زیر در numpy استفاده می‌کنید.
x = [1, 2, 3, 4, 5, 6, 7, 8]
y = [0, 2, 1, 3, 7, 10, 11, 19]
np.polyfit(x, y, 2)
array([ 0.375     , -0.88690476,  1.05357143])
import numpy as np
import matplotlib.pyplot as plt
size = 1000 # تعدادی نقطه در نظر میگیریم
x = np.linspace(-2 * np.pi, 2 * np.pi, size) # به آن تعداد بین منقی 2پی و 2پی نقطخ تعریف میکنیم
y = np.sin(x) + np.random.randn(size) # مقدار ایگرگ آن ها را توسط سینوس و اضافه کردن نویز به دست میاوریم
degree = 5
p = np.polyfit(x, y, degree) # یک چندجمله ای با درجه 5 به آن فیت میکنیم
z = np.polyval(p, x) # مقادیر ایکس را در آن چند جمله ای میگذاریم تا ایگرگ را به دست بیاوریم
plt.plot(x, y, '.') # مقادیر نویزی سینوسی را میکشیم
plt.plot(x, z)# مقادیر چند جمله ای را میکشیم
plt.legend(['sin', 'poly']) # برای نمایش لیبل از این دستور استفاده میکنیم
plt.show()

png

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

در این فصل به سراغ حل یک سری از مسائل می‌رویم:


1.سه عدد را با هم مقایسه کنید و بزرگترین آن ها را برگردانید؟
num1 = 10
num2 = 14
num3 = 12
# میتوانید اعداد را به صورت ورودی بگیرید
#num1 = float(input("Enter first number: "))
#num2 = float(input("Enter second number: "))
#num3 = float(input("Enter third number: "))

if (num1 >= num2) and (num1 >= num3):
    largest = num1
elif (num2 >= num1) and (num2 >= num3):
    largest = num2
else:
    largest = num3

print("The largest number is", largest)
The largest number is 14


2.حال این کار را برای یافتن بزرگترین مقدار در یک لیست انجام دهید.
l = [2,1,5,2,6,4,7,2,8,12,8,5,23,53,7,4,5]

maxNum = l[0]
for x in l:
    if maxNum<x:
        maxNum = x
print('The largest is',maxNum)
The largest is 53


3. یک تابع بنویسید که مقدار جذر اعداد را محاسبه کند.
def sqareRoot(n):
    return n**(.5)

sqareRoot(8)
2.8284271247461903


4. برنامه ای بنویسید که جدول ضرب را برای عدد 23 نمایش دهد:
num = 23

# اگر میخواهید از کاربر بگیرید
# num = int(input("Display multiplication table of? "))


for i in range(1, 11):
    print(num, 'x', i, '=', num*i)
23 x 1 = 23
23 x 2 = 46
23 x 3 = 69
23 x 4 = 92
23 x 5 = 115
23 x 6 = 138
23 x 7 = 161
23 x 8 = 184
23 x 9 = 207
23 x 10 = 230


5. محاسبه توان 2 چند عدد طبیعی: Σn^2
def squaresum(n) :
    sm = 0
    for i in range(1, n+1) :
        sm = sm + (i * i)
      
    return sm
  
n = 4
print(squaresum(n))
  
30


6. محاسبه توان 3 چند عدد طبیعی: Σn^3
(این کد را خود بزنید.)


7. محاسبه کنید آیا یک عدد اول است یا خیر:
def is_prime(n):
    for i in range(2,n):
        if(n % i==0):
            print(n,'is not prime.')
            break
    else:
        print(n, ' is prime.')
        
is_prime(10)
is_prime(7)
10 is not prime.
7  is prime.


8. حال تمامی اعداد در یک رینج که اول هستند را چاپ کنید:
def is_prime(n):
    for i in range(2,n):
        if(n % i==0):
            return False
    else:
        return True
        
def all_prime(first, last):
    for i in range(first,last+1):
        if is_prime(i):
            print(i)

all_prime(11,20)
11
13
17
19


9. یک ماشین حساب ساده بسازید.
def add(x, y):
    return x + y

def subtract(x, y):
    return x - y

def multiply(x, y):
    return x * y

def divide(x, y):
    return x / y


print("Select operation.")
print("1.Add")
print("2.Subtract")
print("3.Multiply")
print("4.Divide")

while True:
    choice = input("Enter choice(1/2/3/4): ")

    if choice in ('1', '2', '3', '4'):
        num1 = float(input("Enter first number: "))
        num2 = float(input("Enter second number: "))

        if choice == '1':
            print(num1, "+", num2, "=", add(num1, num2))

        elif choice == '2':
            print(num1, "-", num2, "=", subtract(num1, num2))

        elif choice == '3':
            print(num1, "*", num2, "=", multiply(num1, num2))

        elif choice == '4':
            print(num1, "/", num2, "=", divide(num1, num2))
        
        next_calculation = input("Let's do next calculation? (yes/no): ")
        if next_calculation == "no":
            break
    
    else:
        print("Invalid Input")
Select operation.
1.Add
2.Subtract
3.Multiply
4.Divide
Enter choice(1/2/3/4): 1
Enter first number: 23
Enter second number: 32
23.0 + 32.0 = 55.0
Let's do next calculation? (yes/no): yes
Enter choice(1/2/3/4): 2
Enter first number: 23
Enter second number: 12
23.0 - 12.0 = 11.0
Let's do next calculation? (yes/no): y
Enter choice(1/2/3/4): 3
Enter first number: 12
Enter second number: 3
12.0 * 3.0 = 36.0
Let's do next calculation? (yes/no): y
Enter choice(1/2/3/4): 4
Enter first number: 34
Enter second number: 5
34.0 / 5.0 = 6.8
Let's do next calculation? (yes/no): no


10. یک برنامه بنویسید که اعداد برپایه 10 یا دسیمال را به مبنای باینری یا برپایه 2 ببرد.
def convertToBinary(n):
    b = ''
    while n>1:
        b = str(n%2)+b
        n = n//2
    b = str(n)+b
    return b

dec = 34
convertToBinary(dec)
'100010'


11. مثال بالا را به صورت بازگشتی پیاده سازی کنید:
def convertToBinary(n):
    if n > 1:
        convertToBinary(n//2)
    print(n % 2,end = '')

# decimal number
dec = 34

convertToBinary(dec)
100010


12. فرض کنید با استفاده از یک دستگاه می‌خواهید خرید کنید. مبلغ به شما نمایش داده می‌شود. شما پول را پرداخت می‌کنید و باقی آن به علاوه محصول را دریافت می‌کنید. فرض کنید سکه های زیر را داریم:
1 , 2 , 5 cent
10, 20, 50 cent
1, 2 euro
و اسکناس های زیر را: 5,10,20,50 euro
و هر 100 سنت یک یورو است.
حال ماشینی طراحی کنید که مبلغ خواسته شده و مبلغ ورودی را بگیرد و کمترین تعداد سکه و پول نقد را برگرداند:
def changeCalculator(income, price):
    listOfChanges = [50,20,10,5,2,1,.50,.20,.10,.05,.02,.01]
    change = income-price
    outcome = []
    
    while round(change,3)>0: # روند کردن در اینجا یک رکن اساسی است زیرا در صورت نبود آن هیچگاه صفر نخواهیم داشت
        print(change) # خرده هایی که در ادامه اعشار دیده میشود به دلیل محاسبات کامپیوتری بر پایه 0 و 1 ایجاد شده است
        for ch in listOfChanges:
            if change-ch>=0:
                change -= ch
                outcome.append(ch)
                break
    return outcome

changeCalculator(50,34.65)
15.350000000000001
5.350000000000001
0.3500000000000014
0.1500000000000014
0.050000000000001404





[10, 5, 0.2, 0.1, 0.05]


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

بازگشت به منوی اصلی

python_tutorial_in_persian's People

Contributors

niloofarmn avatar thealbatrosscodes avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.