شرط و حلقه
برنامهای که تصمیم میگیرد و تکرار میکند: if و elif و else، تورفتگی (indent) و دونقطه، حلقهی for با range و روی متن، حلقهی while، break و continue، حلقهی بیپایان و Ctrl+C؛ با بازی حدس عدد و FizzBuzz.
- حدود ۱۷ دقیقه مطالعه
- ۸ مثال اجراشده
- ۳ تمرین با جواب
- مقدماتی تا متوسط
- بهروزرسانی: ۲۹ مهر ۱۴۰۵
توی این درس یاد میگیری برنامه را تصمیمگیر و تکرارکننده کنی. با if، elif و else بسته به شرایط کار متفاوتی میکنی، و میفهمی چرا در پایتون دونقطه (:) و تورفتگی (فاصلهی ابتدای خط) اینقدر مهماند. با حلقهی for کاری را چند بار یا روی هر حرف یک متن انجام میدهی، با while تا وقتی شرطی برقرار است ادامه میدهی، و با break و continue حلقه را کنترل میکنی. در آخر یک بازی «حدس عدد» میسازی.
مسئله: برنامهای که همیشه یک کار میکند
Section titled “مسئله: برنامهای که همیشه یک کار میکند”برنامههای دو درس قبل از بالا به پایین اجرا میشدند و همیشه یک کار میکردند. ولی برنامهی واقعی باید تصمیم بگیرد («اگر رمز درست بود وارد شو، وگرنه خطا بده») و تکرار کند («برای هر فایل در این پوشه…»، «تا وقتی کاربر q نزده…»). این دو ابزار، یعنی شرط و حلقه، تقریباً در هر برنامهای هستند.
تشبیه: چراغ راهنمایی و دور زدن پیست
Section titled “تشبیه: چراغ راهنمایی و دور زدن پیست”شرط مثل چراغ راهنمایی است: اگر سبز بود برو، اگر زرد بود آهسته کن، وگرنه بایست. فقط یکی از این کارها انجام میشود. حلقه مثل دور زدن پیست است: for یعنی «دقیقاً ده دور بزن» (تعداد از قبل معلوم است) و while یعنی «تا وقتی بنزین داری دور بزن» (تعداد از قبل معلوم نیست).
مثالهای عملی
Section titled “مثالهای عملی”مثال ۱: اولین if
Section titled “مثال ۱: اولین if”age = int(input("سن: "))if age >= 18: print("میتوانی گواهینامه بگیری.") print("مبارک باشد!")print("پایان برنامه")سن: 20میتوانی گواهینامه بگیری.مبارک باشد!پایان برنامهسن: 15پایان برنامهسه چیز را با دقت ببین:
- بعد از شرط یک دونقطه (
:) آمده. - خطهایی که «مال»
ifهستند چهار فاصله جلوتر شروع شدهاند. به این تورفتگی (indentation) میگویند و به این خطها یک بلوک. print("پایان برنامه")دوباره از ستون اول شروع شده، پس دیگر جزوifنیست و همیشه اجرا میشود.
در خیلی از زبانها بلوک را با { } مشخص میکنند؛ در پایتون فقط با تورفتگی. برای همین فاصلهی ابتدای خط در پایتون معنی دارد. nano با زدن Tab چهار فاصله نمیگذارد؛ خودت چهار بار Space بزن (یا در درسهای بعد یک ویرایشگر کد مثل VS Code بگیر که خودش این کار را میکند).
مثال ۲: چند شاخه، elif و else
Section titled “مثال ۲: چند شاخه، elif و else”score = int(input("نمره (۰ تا ۲۰): "))if score >= 17: print("عالی")elif score >= 12: print("قبول")elif score >= 10: print("قبول، ولی با زحمت")else: print("مردود")نمره (۰ تا ۲۰): 18عالینمره (۰ تا ۲۰): 13قبولنمره (۰ تا ۲۰): 10قبول، ولی با زحمتنمره (۰ تا ۲۰): 4مردودپایتون شرطها را به ترتیب میسنجد و اولین شرط درست را اجرا میکند، بعد بقیه را رد میکند. برای همین با ۱۸ فقط «عالی» چاپ شد، با اینکه ۱۸ از ۱۲ و ۱۰ هم بزرگتر است. else (اختیاری) یعنی «اگر هیچکدام درست نبود». ترتیب مهم است: اگر score >= 10 را اول مینوشتی، ۱۸ هم «قبول، ولی با زحمت» میشد.
در یک if/elif/else با نمرهی ۱۸، چند شاخه اجرا میشود؟
جواب درست: فقط اولین شاخهای که شرطش درست است
پایتون از بالا میسنجد و با اولین شرط درست، بقیه را رد میکند.
مثال ۳: حلقهی for با range
Section titled “مثال ۳: حلقهی for با range”for یک بلوک را برای هر عضو از یک دنباله اجرا میکند. range(n) دنبالهی عددهای 0 تا n-1 است:
for i in range(5): print("دور", i)print("---")for i in range(1, 11, 3): print(i)print("---")for ch in "سلام": print(ch)دور 0دور 1دور 2دور 3دور 4---14710---سلام| شکل | عددها |
|---|---|
range(5) |
0، 1، 2، 3، 4 (پنج عدد، از صفر، بدون خود ۵) |
range(1, 6) |
1 تا 5 (شروع تا قبل از پایان) |
range(1, 11, 3) |
1، 4، 7، 10 (قدم ۳) |
range(10, 0, -1) |
10 تا 1 (رو به عقب) |
for روی هر دنبالهای کار میکند: روی متن، هر بار یک حرف؛ و در درس بعد روی لیست، هر بار یک عضو. اسم متغیر (i، ch) را خودت انتخاب میکنی.
مثال ۴: جمع کردن در حلقه
Section titled “مثال ۴: جمع کردن در حلقه”الگوی بسیار رایج: یک متغیر را قبل از حلقه صفر کن و داخل حلقه به آن اضافه کن:
total = 0for n in range(1, 101): total += nprint("جمع ۱ تا ۱۰۰:", total)
evens = 0for n in range(1, 21): if n % 2 == 0: evens += 1print("تعداد زوجها در ۱ تا ۲۰:", evens)جمع ۱ تا ۱۰۰: 5050تعداد زوجها در ۱ تا ۲۰: 10دومی یک if داخل یک for است، پس تورفتگیاش دو برابر (هشت فاصله) است. هر سطح تو در تو، چهار فاصلهی بیشتر.
مثال ۵: حلقهی while
Section titled “مثال ۵: حلقهی while”while تا وقتی شرطش درست است تکرار میکند:
count = 3while count > 0: print(f"{count}...") count -= 1print("پرتاب!")3...2...1...پرتاب!در هر دور، count یکی کم میشود؛ وقتی به صفر رسید، شرط count > 0 غلط میشود و حلقه تمام میشود. همیشه مطمئن شو چیزی داخل حلقه شرط را بالاخره غلط میکند (مثال ۸).
مثال ۶: break و continue
Section titled “مثال ۶: break و continue”for n in range(1, 10): if n == 3: continue if n == 6: break print(n)1245continue: بقیهی همین دور را رها کن و برو دور بعد (۳ چاپ نشد).break: کل حلقه را همینجا تمام کن (به ۶ که رسید، حلقه تمام شد و ۶ تا ۹ چاپ نشدند).
مثال ۷: بازی حدس عدد
Section titled “مثال ۷: بازی حدس عدد”همهی اینها با هم. import random یک ماژول آماده را میآورد (درس «خطا و ماژول») و random.randint(1, 10) یک عدد تصادفی بین ۱ و ۱۰ میدهد:
import randomsecret = random.randint(1, 10)tries = 0while True: guess = int(input("حدس بزن (۱ تا ۱۰): ")) tries += 1 if guess < secret: print("بزرگتر") elif guess > secret: print("کوچکتر") else: print(f"درست بود! با {tries} حدس.") breakحدس بزن (۱ تا ۱۰): 5بزرگترحدس بزن (۱ تا ۱۰): 9کوچکترحدس بزن (۱ تا ۱۰): 7درست بود! با 3 حدس.while True یعنی «برای همیشه»؛ تنها راه خروج break است که فقط با حدس درست اجرا میشود. این الگو («تا وقتی کاربر کار درست را نکرده، دوباره بپرس») خیلی رایج است.
مثال ۸: حلقهی بیپایان و Ctrl+C
Section titled “مثال ۸: حلقهی بیپایان و Ctrl+C”این برنامه یادش رفته n را زیاد کند:
n = 1while n < 5: print(n)n همیشه ۱ است، پس شرط همیشه درست است و برنامه تا ابد 1 چاپ میکند. با Ctrl+C متوقفش کن:
111^CTraceback (most recent call last): File "/home/ali/py/forever.py", line 3, in <module> print(n)KeyboardInterruptKeyboardInterrupt خطا نیست؛ یعنی «کاربر با کیبورد قطعش کرد». راهحل: داخل حلقه n += 1 بگذار.
پشت پرده: شرط فقط True یا False میخواهد
Section titled “پشت پرده: شرط فقط True یا False میخواهد”if و while در واقع فقط یک سؤال میپرسند: «این عبارت True است یا False؟». مقایسهها (age >= 18) مستقیم True/False میدهند، ولی هر مقدار دیگری هم کار میکند: پایتون آن را مثل bool() (درس قبل) تبدیل میکند. پس if name: یعنی «اگر متن خالی نیست» و if count: یعنی «اگر صفر نیست». و for در پشت صحنه از دنباله میخواهد «عضو بعدی را بده» تا وقتی دنباله بگوید «تمام شد»؛ برای همین روی متن، لیست، range و (در درس فایلها) روی خطهای یک فایل یکسان کار میکند.
جدولهای مرجع
Section titled “جدولهای مرجع”| ساختار | شکل |
|---|---|
| شرط ساده | if شرط: + بلوک تورفته |
| چند شاخه | if ...: / elif ...: / else: |
| حلقه روی دنباله | for x in دنباله: |
| حلقهی عددی | for i in range(شروع, پایان, قدم): |
| حلقهی شرطی | while شرط: |
| خروج از حلقه | break |
| رفتن به دور بعد | continue |
| خطا | معنی |
|---|---|
SyntaxError: expected ':' |
دونقطهی آخر if/for/while جا افتاده |
IndentationError: expected an indented block |
بعد از : خط تورفته نیامده |
IndentationError: unexpected indent |
تورفتگی بیدلیل |
KeyboardInterrupt |
کاربر Ctrl+C زد |
اشتباهات رایج
Section titled “اشتباهات رایج”۱) جا انداختن دونقطه
Section titled “۱) جا انداختن دونقطه”age = 20if age > 18 print("بزرگسال") File "/home/ali/py/bad.py", line 2 if age > 18 ^SyntaxError: expected ':'۲) جا انداختن تورفتگی
Section titled “۲) جا انداختن تورفتگی”age = 20if age > 18:print("بزرگسال") File "/home/ali/py/bad2.py", line 3 print("بزرگسال") ^IndentationError: expected an indented block after 'if' statement on line 2پایتون صریحاً میگوید بعد از if خط ۲ منتظر یک بلوک تورفته بوده. راهحل: چهار فاصله.
۳) قاطی کردن Tab و Space
Section titled “۳) قاطی کردن Tab و Space”اگر بعضی خطها را با Tab و بعضی را با Space تو ببری، ممکن است در ویرایشگر یکی به نظر برسند ولی پایتون TabError بدهد. راهحل: همیشه چهار Space.
۴) ترتیب اشتباه elifها
Section titled “۴) ترتیب اشتباه elifها”شرط کلیتر (score >= 10) قبل از شرط خاصتر (score >= 17) یعنی شرط خاص هیچوقت اجرا نمیشود. راهحل: از سختگیرانهترین شرط شروع کن.
۵) حلقهی while که هیچوقت تمام نمیشود
Section titled “۵) حلقهی while که هیچوقت تمام نمیشود”مثال ۸. راهحل: قبل از نوشتن while از خودت بپرس «چه چیزی داخل حلقه شرط را غلط میکند؟». و یادت باشد Ctrl+C همیشه راه فرار است.
۶) فراموش کردن اینکه range(1, 10) خود ۱۰ را ندارد
Section titled “۶) فراموش کردن اینکه range(1, 10) خود ۱۰ را ندارد”راهحل: برای ۱ تا ۱۰ بنویس range(1, 11).
برنامهای بنویس که یک عدد بگیرد و بگوید زوج است یا فرد. (راهنما: % در درس قبل.)
دیدن جواب
n = int(input("یک عدد: "))if n % 2 == 0: print(f"{n} زوج است")else: print(f"{n} فرد است")یک عدد: 77 فرد استتمرین اصلی (FizzBuzz، سؤال مصاحبهی معروف): برای عددهای ۱ تا ۱۵، اگر عدد بر ۳ و ۵ هر دو بخشپذیر بود FizzBuzz، اگر فقط بر ۳ Fizz، اگر فقط بر ۵ Buzz، وگرنه خود عدد را چاپ کن.
دیدن جواب
for n in range(1, 16): if n % 15 == 0: print("FizzBuzz") elif n % 3 == 0: print("Fizz") elif n % 5 == 0: print("Buzz") else: print(n)1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzzنکتهی کلیدی ترتیب است: اگر n % 3 == 0 را اول میگذاشتی، ۱۵ فقط Fizz میشد. بخشپذیری بر ۳ و ۵ هر دو یعنی بخشپذیری بر ۱۵.
جدول ضرب ۱ تا ۳ را با دو حلقهی تو در تو چاپ کن، هر سطر در یک خط. (راهنما: print(..., end=" ") بهجای رفتن به خط بعد، دو فاصله چاپ میکند؛ و یک print() خالی فقط به خط بعد میرود.)
دیدن جواب
for i in range(1, 4): for j in range(1, 4): print(f"{i}×{j}={i*j}", end=" ") print()1×1=1 1×2=2 1×3=32×1=2 2×2=4 2×3=63×1=3 3×2=6 3×3=9حلقهی بیرونی (i) سه بار اجرا میشود و در هر بار، حلقهی درونی (j) سه بار کامل. print() آخر داخل حلقهی بیرونی ولی بیرون از درونی است (تورفتگیاش را ببین)، پس بعد از هر سطر یک بار اجرا میشود.
آزمونک
Section titled “آزمونک”بلوک یک if در پایتون با چه چیزی مشخص میشود؟
جواب درست: تورفتگی (فاصلهی ابتدای خط)
بعد از : خطهای تورفته بلوکاند.
range(2, 6) چه عددهایی میدهد؟
جواب درست: 2، 3، 4، 5
از شروع تا قبل از پایان.
break چه میکند؟
جواب درست: کل حلقه را تمام میکند
continue فقط دور فعلی را رد میکند.
کی while بهتر از for است؟
جواب درست: وقتی فقط شرط توقف را میدانی (مثلاً تا وقتی کاربر q نزده)
for برای دنبالهی معلوم؛ while برای شرط.
خطای «expected an indented block» یعنی…
جواب درست: بعد از : خط تورفته نیامده
زیر if/for/while باید دستکم یک خط تورفته باشد.
برنامه در حلقهی بیپایان گیر کرده. چه کنی؟
جواب درست: Ctrl+C
KeyboardInterrupt برنامه را متوقف میکند.
جمعبندی
Section titled “جمعبندی”if شرط:+ بلوک تورفته؛elifبرای شاخههای بعدی؛elseبرای «هیچکدام». فقط اولین شاخهی درست اجرا میشود.- در پایتون دونقطه و چهار فاصلهی تورفتگی جزو قواعد زباناند.
for x in دنباله:رویrange، متن و (بعداً) لیست و فایل؛range(a, b)تا قبل ازb.while شرط:تا وقتی شرط درست است؛ مطمئن شو بالاخره غلط میشود؛Ctrl+Cراه فرار.breakحلقه را تمام میکند؛continueدور بعد.- الگوی «متغیر را قبل از حلقه صفر کن، داخل حلقه اضافه کن» برای جمع و شمارش.
| دستور | کاری که میکند |
|---|---|
if x > 0: | شرط (بلوک بعدی تورفته) |
elif x == 0: | شاخهی بعدی |
else: | هیچکدام |
for i in range(5): | ۰ تا ۴ |
for ch in "متن": | هر حرف |
while n < 10: | تا وقتی شرط درست است |
break / continue | تمام کردن حلقه / دور بعد |
while True: ... break | تکرار تا رسیدن به شرط خروج |
print(x, end=" ") | چاپ بدون رفتن به خط بعد |