1-qism · Poydevor·04-bob
Boshqaruv oqimi: shartlar, sikllar va pattern matching
if/elif/else, mantiqiy operatorlarning qisqa tutashuvi, for va while sikllari, range, enumerate, zip, break/continue/else, match-case va walrus operatori.
Dastur — bu qarorlar va takrorlashlar. Bu bobda Python'da kod oqimini
boshqarishning barcha vositalarini ko'ramiz — va eng muhimi, ularni
"pythonic" uslubda, ya'ni Python dasturchilari kutganidek yozishni
o'rganamiz. Boshqa tildan kelganlar ko'pincha Python'da C uslubida yozadi
(for i in range(len(lst))) — bu ishlaydi, lekin professional ko'rinmaydi.
for va while sikllari, break/continue, range bilan ishlash. match-case va walrus operatori videoda yo'q — ular bobning 6–7-bo'limlarida.
1. if, elif, else#
ball = 78
if ball >= 90:
baho = "A"
elif ball >= 75:
baho = "B"
elif ball >= 60:
baho = "C"
else:
baho = "F"
print(baho) # BShartlar yuqoridan pastga tekshiriladi va birinchi to'g'ri kelganida
to'xtaydi. Shuning uchun tartib muhim: ball >= 60ni birinchi yozsangiz,
78 ham "C" bo'lib qoladi.
Taqqoslash operatorlari#
| Operator | Ma'no |
|---|---|
==, != | Teng, teng emas |
<, <=, >, >= | Katta-kichik |
is, is not | Bitta obyektmi (faqat None uchun) |
in, not in | Ichida bormi |
Zanjirli taqqoslash — Python'ning chiroyli xususiyati:
if 0 <= x < 10: # 0 <= x and x < 10 bilan bir xil
...
if a == b == c: # uchalasi teng
...Shartli ifoda (ternary)#
holat = "kattalar" if yosh >= 18 else "bolalar"Qisqa holatlar uchun yaxshi. Lekin ichma-ich ternary yozmang —
a if x else b if y else c o'qilmaydi; oddiy if/elif ishlating.
2. Mantiqiy operatorlar: and, or, not#
if yosh >= 18 and hujjat_bor:
...
if is_admin or is_owner:
...
if not ruxsat:
...Qisqa tutashuv (short-circuit)#
Python mantiqiy ifodani faqat natija aniq bo'lguncha hisoblaydi:
A and B— agarAyolg'on bo'lsa,Bumuman hisoblanmaydi;A or B— agarArost bo'lsa,Bhisoblanmaydi.
Bu xatodan himoyalanish uchun ishlatiladi:
if lst and lst[0] > 0: # lst bo'sh bo'lsa, lst[0] chaqirilmaydi — IndexError yo'q
...
if user is not None and user.is_active:
...and / or qiymat qaytaradi, bool emas#
Bu ko'pchilik bilmaydigan nozik tomon:
>>> 0 or "standart"
'standart' # birinchi truthy qiymat
>>> "" or None or []
[] # hammasi falsy — oxirgisi qaytadi
>>> 5 and "salom"
'salom' # hammasi truthy — oxirgisi
>>> 0 and "salom"
0 # birinchi falsyShuning uchun ism = kiritilgan or "Mehmon" ishlaydi. Lekin 2-bobda
aytilganidek, 0 yoki "" haqiqiy qiymat bo'lishi mumkin bo'lsa,
or ishlatmang.
Ustunlik tartibi#
not > and > or. a or b and c → a or (b and c). Shubha bo'lsa —
qavs qo'ying. Qavslar o'qilishni yaxshilaydi va hech narsaga zarar qilmaydi.
3. for sikli — iteratsiya, hisoblagich emas#
Python'ning for sikli C'dagi for (i=0; i<n; i++) emas. U har qanday
iterable (ro'yxat, satr, lug'at, fayl, generator...) elementlarini birma-bir
oladi:
mevalar = ["olma", "nok", "uzum"]
for meva in mevalar:
print(meva)
for harf in "salom":
print(harf)range — sonlar ketma-ketligi#
range(5) # 0, 1, 2, 3, 4
range(2, 6) # 2, 3, 4, 5
range(0, 10, 3) # 0, 3, 6, 9
range(5, 0, -1) # 5, 4, 3, 2, 1range xotirada ro'yxat yaratmaydi — u "dangasa" (lazy): range(10**12)
bir zumda yaratiladi va bir necha bayt egallaydi. Sonlar faqat so'ralganda
hisoblanadi.
enumerate — indeks kerak bo'lsa#
# ❌ C uslubi — ko'proq kod, ko'proq xato ehtimoli
for i in range(len(mevalar)):
print(i, mevalar[i])
# ✅ Pythonic
for i, meva in enumerate(mevalar):
print(i, meva)
for i, meva in enumerate(mevalar, start=1): # 1 dan sanash
print(f"{i}. {meva}")zip — bir nechta ketma-ketlikni parallel aylanish#
ismlar = ["Ali", "Vali", "Gani"]
ballar = [85, 92, 78]
for ism, ball in zip(ismlar, ballar):
print(f"{ism}: {ball}")zip eng qisqa ketma-ketlik tugaganda to'xtaydi — jim. Bu ML'da xavfli:
agar predictions va labels uzunligi farq qilsa, xato chiqmaydi, shunchaki
ba'zi elementlar tashlab yuboriladi. Python 3.10+ da strict=True qo'shing:
for pred, label in zip(predictions, labels, strict=True): # uzunlik farq qilsa — ValueError
...Lug'at bo'ylab aylanish#
narxlar = {"olma": 12000, "nok": 15000}
for meva in narxlar: # kalitlar
...
for narx in narxlar.values(): # qiymatlar
...
for meva, narx in narxlar.items(): # juftliklar — eng ko'p ishlatiladi
print(f"{meva}: {narx:,} so'm")Teskari va saralangan tartibda#
for x in reversed(lst): # teskari (nusxa yaratmaydi)
...
for x in sorted(lst): # saralangan (yangi ro'yxat)
...
for ism in sorted(ballar, key=ballar.get, reverse=True): # lug'atni qiymat bo'yicha
...Aylanish paytida ro'yxatni o'zgartirmang#
sonlar = [1, 2, 3, 4, 5, 6]
for x in sonlar:
if x % 2 == 0:
sonlar.remove(x) # XAVFLI: indekslar siljiydi, ba'zi elementlar o'tkazib yuboriladiTo'g'ri yo'l — yangi ro'yxat yaratish:
sonlar = [x for x in sonlar if x % 2 != 0]Lug'atni aylanish paytida kalit qo'shsangiz/o'chirsangiz, Python darhol
RuntimeError: dictionary changed size during iteration beradi. Yechim:
for k in list(d): — kalitlar nusxasi bo'ylab aylaning.
4. while sikli#
Shart rost ekan, takrorlaydi. Qachon tugashi oldindan ma'lum bo'lmaganda ishlatiladi:
urinish = 0
while urinish < 3:
javob = input("Parol: ")
if javob == "maxfiy":
print("Kirdingiz")
break
urinish += 1
else:
print("Urinishlar tugadi")Retry — AI muhandisining kundalik sikli#
API chaqiruvlari ba'zan muvaffaqiyatsiz bo'ladi (tarmoq, limit). Klassik "exponential backoff" sikli:
import random
import time
def call_with_retry(fn, max_attempts: int = 5):
delay = 1.0
attempt = 1
while True:
try:
return fn()
except ConnectionError:
if attempt == max_attempts:
raise # urinishlar tugadi — xatoni yuqoriga uzatamiz
sleep_for = delay + random.uniform(0, delay) # jitter — hamma bir vaqtda qayta urinmasin
print(f"{attempt}-urinish muvaffaqiyatsiz, {sleep_for:.1f}s kutamiz")
time.sleep(sleep_for)
delay *= 2 # 1, 2, 4, 8...
attempt += 1try/except 10-bobda, dekorator ko'rinishi 14-bobda. (Amalda Anthropic
va OpenAI SDK'lari retry'ni o'zi qiladi — lekin mexanizmni tushunish kerak.)
Cheksiz sikl xavfi#
i = 0
while i < 10:
print(i)
# i += 1 unutildi → cheksiz sikl. Ctrl+C bilan to'xtating.Agar sikl hisoblagich bilan bo'lsa — for + range ishlating, unda bu xato
bo'lmaydi.
5. break, continue va sikldagi else#
break— sikldan darhol chiqish;continue— joriy iteratsiyani tashlab, keyingisiga o'tish;else(sikl bilan) — siklbreaksiz tugasa bajariladi.
for qator in fayl_qatorlari:
qator = qator.strip()
if not qator or qator.startswith("#"):
continue # bo'sh va izoh qatorlarini o'tkazib yuborish
qayta_ishlash(qator)for...else — "topilmadi" holati uchun ideal:
def birinchi_tub_bo_luvchi(n: int) -> int | None:
for d in range(2, int(n ** 0.5) + 1):
if n % d == 0:
break
else:
return None # sikl break'siz tugadi → bo'luvchi topilmadi, n tub
return d
print(birinchi_tub_bo_luvchi(91)) # 7
print(birinchi_tub_bo_luvchi(97)) # None6. match / case — strukturaviy pattern matching#
Python 3.10'da qo'shilgan. Bu boshqa tillardagi switch emas — u ancha
kuchli: ma'lumot shaklini tekshiradi va qismlarini ajratib oladi.
Oddiy qiymatlar#
def http_status(code: int) -> str:
match code:
case 200 | 201:
return "OK"
case 400:
return "Noto'g'ri so'rov"
case 401 | 403:
return "Ruxsat yo'q"
case 429:
return "Juda ko'p so'rov — kuting"
case _: # qolgan hammasi (default)
return "Noma'lum"Shakl bo'yicha moslash va ajratib olish#
Bu yerda match haqiqiy kuchini ko'rsatadi. LLM API'lari turli tipdagi
"bloklar" qaytaradi — ularni qayta ishlash uchun ideal:
def render(block: dict) -> str:
match block:
case {"type": "text", "text": str(matn)}:
return matn
case {"type": "tool_use", "name": nom, "input": dict(args)}:
return f"[asbob chaqirildi: {nom}({', '.join(args)})]"
case {"type": "image", "source": {"media_type": mt}}:
return f"[rasm: {mt}]"
case {"type": tip}:
return f"[noma'lum blok: {tip}]"
case _:
raise ValueError(f"Blok emas: {block!r}")
print(render({"type": "text", "text": "Salom!"}))
print(render({"type": "tool_use", "name": "get_weather", "input": {"city": "Toshkent", "unit": "C"}}))
print(render({"type": "image", "source": {"media_type": "image/png", "data": "..."}}))Salom!
[asbob chaqirildi: get_weather(city, unit)]
[rasm: image/png]E'tibor bering:
- lug'at pattern'i
{"type": "text", ...}— lug'atda kamida shu kalitlar bo'lsa mos keladi (qo'shimcha kalitlar e'tiborsiz); str(matn)— qiymatstrtipida bo'lsa, unimatnnomiga bog'laydi;nomkabi oddiy nom — "har qanday qiymatni ushla va shu nomga bog'la".
Ketma-ketlik pattern'lari va shartlar (guard)#
def buyruq(qator: str) -> str:
match qator.split():
case ["chiq"] | ["exit"]:
return "Xayr!"
case ["salom", ism]:
return f"Salom, {ism}!"
case ["qo'sh", *sonlar] if all(s.isdigit() for s in sonlar):
return str(sum(int(s) for s in sonlar))
case ["qo'sh", *_]:
return "Faqat sonlarni qo'shaman"
case []:
return ""
case _:
return "Tushunmadim"
print(buyruq("salom Aziz")) # Salom, Aziz!
print(buyruq("qo'sh 2 3 5")) # 10
print(buyruq("qo'sh 2 uch")) # Faqat sonlarni qo'shaman7. Walrus operatori :=#
Python 3.8+. Ifoda ichida qiymat tayinlaydi va uni qaytaradi:
# Walrus'siz:
qator = f.readline()
while qator:
qayta_ishlash(qator)
qator = f.readline()
# Walrus bilan:
while (qator := f.readline()):
qayta_ishlash(qator)import re
if (m := re.search(r"(\d+) ta", matn)) is not None:
soni = int(m.group(1))Foydali, lekin ortiqcha ishlatmang — maqsad o'qilishni yaxshilash.
8. pass, ... va bo'sh bloklar#
Python bo'sh blokka ruxsat bermaydi. "Hozircha hech narsa" uchun:
def keyinroq_yozaman():
pass # yoki ...
class MaxsusXato(Exception):
pass
if shart:
... # Ellipsis — "bu yer hali tayyor emas" ma'nosida ko'p ishlatiladi9. Amaliyot: oddiy "chatbot" sikli#
Hamma narsani birlashtiramiz — LLM chatbot'ning skeleti (model o'rniga oddiy qoidalar):
def javob_ber(xabar: str) -> str:
match xabar.lower().split():
case []:
return "Biror narsa yozing."
case ["salom", *_] | ["assalomu", *_]:
return "Va alaykum assalom! Qanday yordam bera olaman?"
case [*_, "narx"] | [*_, "narxi"]:
return "Narxlar haqida ma'lumot uchun /narxlar buyrug'ini yozing."
case _:
return "Kechirasiz, tushunmadim. Boshqacha yozib ko'ring."
def main() -> None:
print("Chatbot. Chiqish uchun 'chiq' deb yozing.")
tarix: list[tuple[str, str]] = []
while True:
try:
xabar = input("Siz: ").strip()
except (EOFError, KeyboardInterrupt): # Ctrl+D / Ctrl+C
print()
break
if xabar.lower() in {"chiq", "exit", "quit"}:
break
javob = javob_ber(xabar)
tarix.append((xabar, javob))
print(f"Bot: {javob}")
print(f"Suhbat tugadi. {len(tarix)} ta xabar almashildi.")
if __name__ == "__main__":
main()23-bobda javob_ber ichini haqiqiy Claude API chaqiruvi bilan almashtiramiz
va tarix modelga kontekst sifatida yuboriladi.
Nima noto'g'ri ketishi mumkin#
| Holat | Natija | To'g'risi |
|---|---|---|
if x = 5: | SyntaxError | if x == 5: |
elif tartibi noto'g'ri | Kengroq shart torroqni "yutadi" | Torroq shartlarni yuqoriga |
for i in range(len(lst)) | Ishlaydi, lekin pythonic emas | enumerate(lst) |
zip uzunliklari farq qiladi | Elementlar jim tashlanadi | zip(..., strict=True) |
Aylanish paytida list.remove | Elementlar o'tkazib yuboriladi | Yangi ro'yxat yoki list(...) nusxasi bo'ylab |
while ichida hisoblagich unutilgan | Cheksiz sikl | for + range |
case KONSTANTA: | Hamma narsani ushlaydi | case Klass.KONSTANTA: |
if x == True: | Ishlaydi, lekin ortiqcha | if x: |
if len(lst) == 0: | Ishlaydi, lekin ortiqcha | if not lst: |
1. FizzBuzz — lekin to'g'ri
1 dan 100 gacha sonlarni chiqaring: 3 ga bo'linsa "Fizz", 5 ga — "Buzz",
ikkalasiga — "FizzBuzz". Ikki xil yechim yozing: if/elif bilan va
match (n % 3, n % 5): bilan.
Maslahatni ko'rsatish
15 ga bo'linishni birinchi tekshiring yoki satrni yig'ib boring: s = ''; if n % 3 == 0: s += 'Fizz' ...
2. Accuracy va xatolar ro'yxati
preds = [1, 0, 1, 1, 0, 1] va labels = [1, 0, 0, 1, 0, 0] berilgan.
Accuracy'ni (to'g'ri bashoratlar ulushi) hisoblang va noto'g'ri bashorat
qilingan indekslar ro'yxatini chiqaring. Uzunliklar farq qilsa, kod
xato berishi kerak.
Maslahatni ko'rsatish
zip(preds, labels, strict=True) va enumerate'ni birga ishlating: for i, (p, y) in enumerate(zip(...)).
3. API javobini qayta ishlash
Quyidagi "model javobi"dan barcha matnli bloklarni birlashtirib, chaqirilgan
asboblar nomlarini alohida ro'yxatga ajratib oling (match ishlating):
content = [
{"type": "thinking", "thinking": "..."},
{"type": "text", "text": "Ob-havoni tekshiraman."},
{"type": "tool_use", "id": "t1", "name": "get_weather", "input": {"city": "Samarqand"}},
{"type": "text", "text": "Bir daqiqa."},
]Maslahatni ko'rsatish
Har bir blok uchun match block: case {'type': 'text', 'text': t}: ... Natijalarni ro'yxatga yig'ib, oxirida join qiling.
4. Retry'ni sinash
call_with_retryni sinash uchun soxta funksiya yozing: u birinchi 3 marta
ConnectionError ko'tarsin, 4-chi marta "OK" qaytarsin. (Maslahat:
hisoblagichni ro'yxatda saqlang: holat = [0], funksiya ichida
holat[0] += 1.) max_attempts=3 bilan chaqirsangiz nima bo'ladi?
- 01if/elif yuqoridan pastga, birinchi mos kelganda to'xtaydi; zanjirli taqqoslash: 0 <= x < 10.
- 02and/or qisqa tutashadi va bool emas, operand qiymatini qaytaradi.
- 03for — iterable bo'ylab aylanish; indeks uchun enumerate, parallel uchun zip(..., strict=True).
- 04Aylanish paytida to'plamni o'zgartirmang — yangisini yarating.
- 05while — tugash nuqtasi noma'lum bo'lganda; retry va backoff — AI kodining kundalik sikli.
- 06for/while ... else — 'nobreak': sikl break'siz tugasa ishlaydi.
- 07match/case — qiymat emas, shakl bo'yicha moslaydi va qismlarni ajratib oladi; oddiy nom hamma narsani ushlaydi.
- 08Walrus := ifoda ichida tayinlaydi — o'qilishni yaxshilasa ishlating.
Mustahkamlash
Test va amaliy masalalar
Avval testni ishlang — har javobdan keyin izoh chiqadi. Keyin masalalarni shu yerning o'zida yechib, brauzerdagi haqiqiy Python bilan avtomatik tekshiring. Natijalaringiz kurs progressi sahifasida jamlanadi.
Bilimni tekshirish
Bob bo'yicha test
12 ta savol · har javobdan keyin to'g'ri yoki xatoligi va izoh ko'rsatiladi · oxirida natija foizda.
Amaliy masalalar
Kodni yozing va «Tekshirish»ni bosing (yoki Ctrl/⌘ + Enter). Kodingiz shu brauzerda saqlanib turadi.
01FizzBuzz ro'yxati
fizzbuzz(n) 1 dan n gacha elementlar ro'yxatini qaytarsin: 3 ga bo'linsa "Fizz", 5 ga — "Buzz", ikkalasiga — "FizzBuzz", aks holda sonning o'zi (int).
02Accuracy va xato indekslar
evaluate(preds, labels) → (accuracy, xato_indekslar) qaytarsin. Uzunliklar farq qilsa ValueError bo'lsin (zip(..., strict=True) ishlating). evaluate([1,0,1,1], [1,0,0,1]) → (0.75, [2]).
03Blok renderer (match)
render(block) — LLM javob bloklarini match bilan qayta ishlasin:
{"type": "text", "text": t}→t{"type": "tool_use", "name": n, ...}→"[tool: n]"- boshqa har qanday
{"type": x, ...}→"[x]"