Mundarija (23)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Asosiy sintaksis
- 2.2. Cheksiz sikl
- 2.3. while True + break
- 2.4. Morj operatori bilan
- 2.5. while / else
- 2.6. break va continue
- 2.7. Qachon while, qachon for
- 2.8. Tipik while naqshlari
- 2.9. Tezlik va optimizatsiya
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Cheksiz sikl sabablari
- Misol 2 — while True naqshlari
- Misol 3 — while/else
- Misol 4 — Amaliy algoritmlar
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
5.5-dars: while sikli
5-QISM — BOSHQARUV OQIMI · 5-dars
1. Kirish va motivatsiya
Shu paytgacha kodimiz har bir qatorni bir marta bajarardi. Endi takrorlashni o'rganamiz.
while — "shart rost ekan, takrorla":
hisob = 0
while hisob < 5:
print(hisob)
hisob += 1Sodda ko'rinadi. Lekin while — eng xavfli boshqaruv tuzilmasi, chunki u hech qachon tugamasligi mumkin:
hisob = 0
while hisob < 5:
print(hisob) # ❌ hisob o'zgarmaydi — cheksiz siklVa bir necha nozik jihat bor:
while True: # ← qachon to'g'ri?
...
while royxat: # ← ro'yxat bo'sh bo'lgunicha
royxat.pop()
while (qator := f.readline()): # ← morj operatori
...
while shart:
...
else: # ← while da `else`?!
...Bu darsda:
whilesintaksisi va bajarilish tartibi- Cheksiz sikl — sabablari va oldini olish
while True+breaknaqshiwhile/else— kam ma'lum, lekin foydali- Morj operatori bilan
- Qachon
while, qachonfor
2. Nazariya — chuqur tushuntirish
2.1. Asosiy sintaksis
while <shart>:
<blok>Bajarilish tartibi:
1. <shart> hisoblanadi
2. Yolg'on bo'lsa → sikl tugaydi
3. Rost bo'lsa → <blok> bajariladi
4. 1-qadamga qaytiladihisob = 0
while hisob < 3:
print(f" hisob = {hisob}")
hisob += 1
print(f" Sikldan keyin: {hisob}") hisob = 0
hisob = 1
hisob = 2
Sikldan keyin: 3Shart har iteratsiyadan OLDIN tekshiriladi:
hisob = 10
while hisob < 3:
print("Bu bajarilmaydi") # sikl umuman ishlamaydiBa'zi tillarda do...while bor — u kamida bir marta bajariladi. Pythonda yo'q:
# do...while emulyatsiyasi
while True:
ishla()
if not shart:
breakUch element:
- Boshlang'ich holat — sikldan oldin
- Shart — qachon davom etish
- O'zgarish — blok ichida
hisob = 0 # 1. boshlang'ich
while hisob < 5: # 2. shart
print(hisob)
hisob += 1 # 3. o'zgarish ← BUNI UNUTMANG2.2. Cheksiz sikl
Eng ko'p uchraydigan xato — o'zgarishni unutish:
hisob = 0
while hisob < 5:
print(hisob) # ❌ hisob hech qachon o'zgarmaydiBu — cheksiz sikl. Dastur to'xtamaydi.
To'xtatish: Ctrl + C (2.4-dars).
Boshqa sabablar:
# 1. Noto'g'ri yo'nalish
i = 10
while i > 0:
i += 1 # ❌ o'sib boryapti
# 2. Shart hech qachon yolg'on bo'lmaydi
while 1 == 1: # ❌
while x: # ❌ x o'zgarmasa
# 3. Kasr sonlar bilan (3.4-dars)
x = 0.0
while x != 1.0:
x += 0.1 # ❌ hech qachon aynan 1.0 bo'lmaydi
# 4. Ichkarida qayta o'rnatish
hisob = 0
while hisob < 5:
hisob = 0 # ❌
hisob += 1Kasr sonlar tuzog'i — batafsil:
x = 0.0
for _ in range(11):
print(f" {x!r}")
x += 0.1 0.0
0.1
0.2
0.30000000000000004 ← xato boshlandi
0.4
0.5
0.6
0.7
0.7999999999999999
0.8999999999999999
0.9999999999999999 ← 1.0 EMAS!Shuning uchun while x != 1.0 cheksiz ishlaydi.
To'g'ri usullar:
# 1. Butun sonlar bilan sanash
i = 0
while i < 10:
x = i / 10
i += 1
# 2. Taqqoslash operatori
x = 0.0
while x < 1.0: # ✅ != emas, <
x += 0.1
# 3. isclose (3.4-dars)
import math
while not math.isclose(x, 1.0):
...Himoya — maksimal iteratsiya:
MAX_ITERATSIYA = 10_000
hisob = 0
while shart() and hisob < MAX_ITERATSIYA:
ishla()
hisob += 1
if hisob >= MAX_ITERATSIYA:
raise RuntimeError("Sikl juda uzoq ishladi")Bu — tashqi ma'lumotga bog'liq sikllarda muhim.
2.3. while True + break
Ba'zan shart sikl o'rtasida tekshiriladi. Unda while True ishlatiladi:
while True:
kirish = input("Buyruq: ").strip()
if kirish == "chiqish":
break
ishla(kirish)Bu — idiomatik Python. Muqobil variantlar chirkinroq:
# ❌ Takrorlanish
kirish = input("Buyruq: ").strip()
while kirish != "chiqish":
ishla(kirish)
kirish = input("Buyruq: ").strip() # takrorlandi
# ❌ Bayroq o'zgaruvchisi
davom = True
while davom:
kirish = input("Buyruq: ").strip()
if kirish == "chiqish":
davom = False
else:
ishla(kirish)Klassik naqshlar:
# 1. Foydalanuvchi kiritmasini tekshirish (3.13-dars)
while True:
try:
yosh = int(input("Yosh: "))
break
except ValueError:
print("Son kiriting")
# 2. Menyu
while True:
korsat_menyu()
tanlov = input("> ")
if tanlov == "0":
break
bajar(tanlov)
# 3. Qayta urinish
urinish = 0
while True:
try:
natija = sorov()
break
except TimeoutError:
urinish += 1
if urinish >= 3:
raise
time.sleep(2 ** urinish)Oxirgisi — eksponensial kutish (exponential backoff), tarmoq bilan ishlashda standart naqsh.
while True — break shart:
while True:
ishla() # ❌ break yo'q — cheksizRuff bunday holatni topmaydi. Diqqat bilan yozing.
2.4. Morj operatori bilan
3.12-darsda tanishgandik. while bilan u ayniqsa foydali:
# ❌ Takrorlanish
qator = fayl.readline()
while qator:
ishla(qator)
qator = fayl.readline()
# ✅ Morj bilan
while (qator := fayl.readline()):
ishla(qator)Boshqa misollar:
# Foydalanuvchi kiritmasi
while (kirish := input("Buyruq: ").strip()) != "chiqish":
ishla(kirish)
# Navbatdan olish
while (vazifa := navbat.get()) is not None:
bajar(vazifa)
# Bo'laklarni o'qish
while (bolak := manba.read(1024)):
qayta_ishla(bolak)
# Regex qidiruv (15-qism)
while (moslik := naqsh.search(matn, pozitsiya)):
ishla(moslik)
pozitsiya = moslik.end()Qavs — deyarli doim kerak:
while qator := f.readline(): # ✅ ishlaydi
while (qator := f.readline()): # ✅ aniqroq
while n := len(x) > 5: # ❌ n = (len(x) > 5)
while (n := len(x)) > 5: # ✅2.5. while / else
Bu — Pythonning noyob imkoniyati va ko'pchilik uni bilmaydi.
while <shart>:
<blok>
else:
<else_blok> # sikl NORMAL tugaganda bajariladielse qachon bajariladi:
- Sikl shart yolg'on bo'lgani uchun tugaganda
breakbilan chiqilganda
i = 0
while i < 3:
print(f" i = {i}")
i += 1
else:
print(" else: sikl normal tugadi") i = 0
i = 1
i = 2
else: sikl normal tugadii = 0
while i < 3:
print(f" i = {i}")
if i == 1:
break
i += 1
else:
print(" else: bajarilmaydi") i = 0
i = 1 Nom chalkash. else bu yerda "aks holda" emas, "nobreak" degani. Guido van Rossum o'zi ham "bu nom xato edi" degan.
Qachon foydali — qidiruv naqshi:
# ❌ Bayroq bilan
topildi = False
i = 0
while i < len(royxat):
if royxat[i] == qidiruv:
topildi = True
break
i += 1
if not topildi:
print("Topilmadi")
# ✅ else bilan
i = 0
while i < len(royxat):
if royxat[i] == qidiruv:
print(f"Topildi: {i}")
break
i += 1
else:
print("Topilmadi")Yana bir misol — tekshiruv:
def tub_sonmi(n: int) -> bool:
if n < 2:
return False
bolvchi = 2
while bolvchi * bolvchi <= n:
if n % bolvchi == 0:
return False
bolvchi += 1
return TrueBu yerda else kerak emas, chunki return ishlatilgan. else — bayroq o'zgaruvchisi kerak bo'lgan holatda foydali.
Kam ishlatiladi. Ko'p dasturchi uni bilmaydi, shuning uchun izoh yozing:
while ...:
...
else:
# Sikl break siz tugadi — ya'ni topilmadi
...2.6. break va continue
10-darsda batafsil ko'ramiz. Qisqacha:
# break — sikldan butunlay chiqish
while True:
if tugadi():
break
ishla()
# continue — keyingi iteratsiyaga o'tish
i = 0
while i < 10:
i += 1
if i % 2 == 0:
continue # juftlarni o'tkazib yuborish
print(i) continue bilan tuzoq — o'zgarishni unutish:
i = 0
while i < 10:
if i % 2 == 0:
continue # ❌ i o'zgarmadi — cheksiz sikl!
print(i)
i += 1To'g'ri:
i = 0
while i < 10:
i += 1 # ✅ continue dan OLDIN
if i % 2 == 0:
continue
print(i)Bu — while da continue ning eng katta xavfi. for da bunday muammo yo'q.
2.7. Qachon while, qachon for
for — ma'lum to'plam bo'ylab:
for x in royxat: # ✅
for i in range(10): # ✅
for kalit in lugat: # ✅while — shart bo'yicha:
while not tugadi(): # ✅ nechta iteratsiya noma'lum
while ulanish.faol(): # ✅
while navbat: # ✅ for ni while bilan almashtirish — anti-naqsh:
# ❌ C uslubi
i = 0
while i < len(royxat):
print(royxat[i])
i += 1
# ✅ Python
for element in royxat:
print(element)
# ✅ Indeks kerak bo'lsa
for i, element in enumerate(royxat):
print(i, element)Qaror jadvali:
| Vaziyat | Tuzilma |
|---|---|
| To'plam bo'ylab | for |
| Ma'lum son marta | for i in range(n) |
| Shart rost ekan | while |
| Kamida bir marta | while True + break |
| Fayl qatorlari | for qator in fayl |
| Foydalanuvchi kiritmasi | while True + break |
| Konvergensiya (yaqinlashish) | while |
| Navbat/stek bo'shalguncha | while |
2.8. Tipik while naqshlari
1. Hisoblagich:
i = 0
while i < n:
ishla(i)
i += 1 Bu — deyarli doim for i in range(n) bo'lishi kerak.
2. To'plamni bo'shatish:
while stek:
element = stek.pop()
ishla(element)
while navbat:
element = navbat.popleft()
ishla(element)3. Konvergensiya:
# Nyuton usuli bilan kvadrat ildiz
def ildiz(n: float, aniqlik: float = 1e-10) -> float:
x = n / 2
while abs(x * x - n) > aniqlik:
x = (x + n / x) / 2
return x
print(ildiz(2)) # 1.4142135623730954. Ikkilik qidiruv:
def ikkilik_qidiruv(royxat: list[int], qidiruv: int) -> int:
chap, ong = 0, len(royxat) - 1
while chap <= ong:
orta = (chap + ong) // 2
if royxat[orta] == qidiruv:
return orta
if royxat[orta] < qidiruv:
chap = orta + 1
else:
ong = orta - 1
return -131-qismda algoritmlarni batafsil o'rganamiz.
5. Holat mashinasi:
holat = "boshlash"
while holat != "tugash":
if holat == "boshlash":
holat = "ishlash"
elif holat == "ishlash":
holat = "tekshirish" if ishla() else "xato"
elif holat == "tekshirish":
holat = "tugash"
elif holat == "xato":
holat = "boshlash"6. Qayta urinish:
import time
def qayta_urinish(f, urinishlar: int = 3, kutish: float = 1.0):
urinish = 0
while True:
try:
return f()
except Exception:
urinish += 1
if urinish >= urinishlar:
raise
time.sleep(kutish * 2 ** (urinish - 1))2.9. Tezlik va optimizatsiya
while for dan sekinroq:
import time
N = 1_000_000
boshlandi = time.perf_counter()
i = 0
jami = 0
while i < N:
jami += i
i += 1
vaqt_while = time.perf_counter() - boshlandi
boshlandi = time.perf_counter()
jami = 0
for i in range(N):
jami += i
vaqt_for = time.perf_counter() - boshlandi
print(f" while: {vaqt_while * 1000:>7.1f} ms")
print(f" for: {vaqt_for * 1000:>7.1f} ms")Nega? for da range iteratori C darajasida ishlaydi. while da har iteratsiyada:
- Shart hisoblanadi (Python bytecode)
i += 1bajariladi (Python bytecode)
Eng tez — ichki funksiyalar:
print(sum(range(N))) # C darajasidaOptimizatsiya maslahatlari:
# ❌ Har iteratsiyada len() chaqiruvi
i = 0
while i < len(royxat):
...
i += 1
# ✅ Bir marta hisoblash
n = len(royxat)
i = 0
while i < n:
...
i += 1
# ✅✅ Yoki umuman for
for element in royxat:
...Erta optimizatsiya qilmang. Avval to'g'ri va o'qiladigan kod yozing.
3. Tez ma'lumotnoma
Sintaksis
while <shart>:
<blok>
else: # ixtiyoriy — break BO'LMASA bajariladi
<else_blok>Uch element
hisob = 0 # 1. boshlang'ich holat
while hisob < 5: # 2. shart
...
hisob += 1 # 3. o'zgarish ← UNUTMANGCheksiz sikl sabablari
1. O'zgarish yo'q
2. Noto'g'ri yo'nalish (i += 1 o'rniga i -= 1)
3. Kasr sonlar bilan != taqqoslash
4. continue dan oldin o'zgarish yo'q
5. while True da break yo'qNaqshlar
while True: do-while emulyatsiyasi
ishla()
if shart: break
while (x := f()): morj operatori
while stek: to'plamni bo'shatish
while chap <= ong: ikkilik qidiruvwhile vs for
for — to'plam bo'ylab, ma'lum son marta
while — shart bo'yicha, iteratsiya soni noma'lumHimoya
MAX = 10_000
hisob = 0
while shart() and hisob < MAX:
...
hisob += 14. Batafsil misollar
Misol 1 — Cheksiz sikl sabablari
"""Cheksiz sikl — sabablari va yechimlari."""
import math
print("=== 1. ❌ O'zgarish yo'q ===")
print("""
hisob = 0
while hisob < 5:
print(hisob) # hisob hech qachon o'zgarmaydi
✅ Yechim: hisob += 1
""")
print("=== 2. ❌ Noto'g'ri yo'nalish ===")
print("""
i = 10
while i > 0:
i += 1 # o'sib boryapti
✅ Yechim: i -= 1
""")
print("=== 3. ⭐ Kasr sonlar tuzog'i ===")
x = 0.0
qadamlar = []
for _ in range(11):
qadamlar.append(x)
x += 0.1
print(" x = 0.0; x += 0.1 (11 marta):")
for i, q in enumerate(qadamlar):
belgi = " ← 1.0 EMAS!" if i == 10 else ""
print(f" {i:>2}: {q!r}{belgi}")
print(f"\n qadamlar[10] == 1.0 → {qadamlar[10] == 1.0}")
print(f" math.isclose(...) → {math.isclose(qadamlar[10], 1.0)}")
print("""
❌ while x != 1.0: → CHEKSIZ
✅ while x < 1.0: → ishlaydi
✅ Butun sonlar bilan sanash
""")
print(" Uch yechim:")
# 1. < bilan
x = 0.0
n = 0
while x < 1.0:
x += 0.1
n += 1
print(f" < bilan: {n} iteratsiya, x = {x!r}")
# 2. Butun sonlar
i = 0
while i < 10:
x = i / 10
i += 1
print(f" Butun sonlar: {i} iteratsiya, x = {x!r}")
# 3. isclose
x = 0.0
n = 0
while not math.isclose(x, 1.0) and n < 100:
x += 0.1
n += 1
print(f" isclose bilan: {n} iteratsiya, x = {x!r}")
print("\n\n=== 4. ❌ continue tuzog'i ===")
print("""
i = 0
while i < 10:
if i % 2 == 0:
continue # i o'zgarmadi → CHEKSIZ
print(i)
i += 1
✅ Yechim: i += 1 ni continue dan OLDIN qo'ying
""")
i = 0
natija = []
while i < 10:
i += 1 # ✅ oldin
if i % 2 == 0:
continue
natija.append(i)
print(f" To'g'ri versiya natijasi: {natija}")
print("\n\n=== 5. ✅ Himoya: maksimal iteratsiya ===")
def xavfsiz_sikl(shart_f, ishla_f, max_iter: int = 1000):
"""Cheksiz sikldan himoyalangan."""
hisob = 0
while shart_f() and hisob < max_iter:
ishla_f()
hisob += 1
if hisob >= max_iter:
raise RuntimeError(
f"Sikl {max_iter} iteratsiyadan oshdi — cheksiz bo'lishi mumkin"
)
return hisob
# Normal holat
sanoq = [0]
natija = xavfsiz_sikl(
lambda: sanoq[0] < 5,
lambda: sanoq.__setitem__(0, sanoq[0] + 1),
)
print(f" Normal sikl: {natija} iteratsiya")
# Cheksiz holat
try:
xavfsiz_sikl(lambda: True, lambda: None, max_iter=100)
except RuntimeError as x:
print(f" Cheksiz sikl ushlandi: {x}")
print("\n\n=== 6. Konvergensiya — xavfsiz variant ===")
def ildiz_xavfsiz(n: float, aniqlik: float = 1e-10,
max_iter: int = 100) -> float:
"""Nyuton usuli — iteratsiya cheklovi bilan."""
if n < 0:
raise ValueError("Manfiy sondan ildiz olinmaydi")
if n == 0:
return 0.0
x = n / 2
for i in range(max_iter):
yangi = (x + n / x) / 2
if abs(yangi - x) < aniqlik:
return yangi
x = yangi
raise RuntimeError(f"{max_iter} iteratsiyada yaqinlashmadi")
print(f" {'Son':>10} {'Ildiz':>18} {'math.sqrt':>18} {'Farq':>10}")
print(" " + "─" * 60)
for n in [2, 16, 100, 0.5, 1e10]:
natija = ildiz_xavfsiz(n)
haqiqiy = math.sqrt(n)
print(f" {n:>10} {natija:>18.10f} {haqiqiy:>18.10f} "
f"{abs(natija - haqiqiy):>10.2e}")Natijaning muhim qismi:
=== 3. ⭐ Kasr sonlar tuzog'i ===
x = 0.0; x += 0.1 (11 marta):
0: 0.0
1: 0.1
2: 0.2
3: 0.30000000000000004
4: 0.4
...
10: 0.9999999999999999 ← 1.0 EMAS!
qadamlar[10] == 1.0 → False
math.isclose(...) → True
=== 6. Konvergensiya — xavfsiz variant ===
Son Ildiz math.sqrt Farq
────────────────────────────────────────────────────────────
2 1.4142135624 1.4142135624 2.22e-16
16 4.0000000000 4.0000000000 0.00e+00
100 10.0000000000 10.0000000000 0.00e+00
0.5 0.7071067812 0.7071067812 1.11e-16
10000000000.0 100000.0000000000 100000.0000000000 0.00e+00Nima ko'rsatdi: 2.2, 2.6-bo'limlar.
Misol 2 — while True naqshlari
"""Amaliy while True qo'llanishlari."""
import time
import random
print("=== 1. Foydalanuvchi kiritmasi (simulyatsiya) ===")
KIRISHLAR = iter(["abc", "-5", "200", "25", "chiqish"])
def soxta_input(savol: str) -> str:
"""input() o'rniga — namoyish uchun."""
javob = next(KIRISHLAR)
print(f" {savol}{javob}")
return javob
def yosh_sora() -> int | None:
while True:
kirish = soxta_input("Yosh: ").strip()
if kirish == "chiqish":
return None
try:
yosh = int(kirish)
except ValueError:
print(" ⚠️ Son kiriting")
continue
if not 1 <= yosh <= 120:
print(" ⚠️ 1-120 oralig'ida bo'lishi kerak")
continue
return yosh
natija = yosh_sora()
print(f" Natija: {natija}")
print("\n\n=== 2. Qayta urinish (exponential backoff) ===")
urinishlar_soni = [0]
def beqaror_sorov():
"""3-urinishda muvaffaqiyatli bo'ladigan soxta so'rov."""
urinishlar_soni[0] += 1
if urinishlar_soni[0] < 3:
raise TimeoutError(f"Urinish #{urinishlar_soni[0]} — vaqt tugadi")
return f"✅ Muvaffaqiyat (urinish #{urinishlar_soni[0]})"
def qayta_urinish(f, max_urinish: int = 5, asos: float = 0.1):
"""Eksponensial kutish bilan qayta urinish."""
urinish = 0
while True:
try:
return f()
except (TimeoutError, ConnectionError) as xato:
urinish += 1
if urinish >= max_urinish:
raise RuntimeError(f"{max_urinish} urinishdan keyin ham xato") from xato
kutish = asos * (2 ** (urinish - 1))
print(f" {xato} — {kutish:.2f}s kutish...")
time.sleep(kutish)
natija = qayta_urinish(beqaror_sorov)
print(f" {natija}")
print("\n\n=== 3. Menyu ===")
TANLOVLAR = iter(["1", "3", "2", "9", "0"])
MENYU = {
"1": ("Ma'lumot ko'rish", lambda: print(" → Ma'lumot ko'rsatildi")),
"2": ("Ma'lumot qo'shish", lambda: print(" → Ma'lumot qo'shildi")),
"3": ("Hisobot", lambda: print(" → Hisobot yaratildi")),
"0": ("Chiqish", None),
}
def menyu():
while True:
print("\n ┌─ MENYU")
for kalit, (nom, _) in MENYU.items():
print(f" │ {kalit}. {nom}")
print(" └─")
tanlov = next(TANLOVLAR)
print(f" > {tanlov}")
if tanlov == "0":
print(" Xayr!")
break
element = MENYU.get(tanlov)
if element is None:
print(" ⚠️ Noto'g'ri tanlov")
continue
_, funksiya = element
funksiya()
menyu()
print("\n\n=== 4. do...while emulyatsiyasi ===")
print(" Pythonda do...while yo'q. Emulyatsiya:")
print("""
while True:
ishla() # kamida bir marta
if not shart:
break
""")
hisob = 0
while True:
hisob += 1
print(f" Iteratsiya {hisob}")
if hisob >= 3:
break
print(f" Natija: {hisob} marta bajarildi")
print("\n\n=== 5. Morj operatori bilan ===")
MALUMOT = ["birinchi\n", "ikkinchi\n", "uchinchi\n", ""]
indeks = [0]
def soxta_readline():
if indeks[0] >= len(MALUMOT):
return ""
qator = MALUMOT[indeks[0]]
indeks[0] += 1
return qator
print(" ❌ Takrorlanish bilan:")
print(""" qator = f.readline()
while qator:
ishla(qator)
qator = f.readline() ← takrorlandi""")
print("\n ✅ Morj bilan:")
indeks[0] = 0
while (qator := soxta_readline()):
print(f" o'qildi: {qator.strip()!r}")
print("\n\n=== 6. Navbatni qayta ishlash ===")
from collections import deque
navbat = deque(["A", "B", "C", "D"])
print(f" Boshlang'ich navbat: {list(navbat)}")
while navbat:
element = navbat.popleft()
print(f" Ishlanmoqda: {element}")
# Ba'zi elementlar yangi vazifa yaratadi
if element == "B":
navbat.append("B-davomi")
print(f" → yangi vazifa qo'shildi: B-davomi")
print(f" Navbat bo'shadi: {list(navbat)}")Natijaning muhim qismi:
=== 1. Foydalanuvchi kiritmasi (simulyatsiya) ===
Yosh: abc
⚠️ Son kiriting
Yosh: -5
⚠️ 1-120 oralig'ida bo'lishi kerak
Yosh: 200
⚠️ 1-120 oralig'ida bo'lishi kerak
Yosh: 25
Natija: 25
=== 2. Qayta urinish (exponential backoff) ===
Urinish #1 — vaqt tugadi — 0.10s kutish...
Urinish #2 — vaqt tugadi — 0.20s kutish...
✅ Muvaffaqiyat (urinish #3)
=== 6. Navbatni qayta ishlash ===
Boshlang'ich navbat: ['A', 'B', 'C', 'D']
Ishlanmoqda: A
Ishlanmoqda: B
→ yangi vazifa qo'shildi: B-davomi
Ishlanmoqda: C
Ishlanmoqda: D
Ishlanmoqda: B-davomi
Navbat bo'shadi: []Nima ko'rsatdi: 2.3, 2.4-bo'limlar.
Misol 3 — while/else
"""Pythonning noyob imkoniyati."""
print("=== 1. Asosiy xatti-harakat ===")
print(" break SIZ:")
i = 0
while i < 3:
print(f" i = {i}")
i += 1
else:
print(" else: sikl normal tugadi ✅")
print("\n break BILAN:")
i = 0
while i < 3:
print(f" i = {i}")
if i == 1:
print(" break!")
break
i += 1
else:
print(" else: BU BAJARILMAYDI")
print("\n Shart darhol yolg'on:")
i = 10
while i < 3:
print(" bajarilmaydi")
else:
print(" else: baribir bajariladi ✅")
print("\n\n=== 2. Qidiruv naqshi ===")
ROYXAT = [3, 7, 12, 5, 9]
print(f" Ro'yxat: {ROYXAT}\n")
for qidiruv in [12, 100]:
print(f" Qidiruv: {qidiruv}")
# ❌ Bayroq bilan
topildi = False
i = 0
while i < len(ROYXAT):
if ROYXAT[i] == qidiruv:
topildi = True
break
i += 1
natija_bayroq = f"topildi (indeks {i})" if topildi else "topilmadi"
print(f" Bayroq bilan: {natija_bayroq}")
# ✅ else bilan
i = 0
while i < len(ROYXAT):
if ROYXAT[i] == qidiruv:
print(f" else bilan: topildi (indeks {i})")
break
i += 1
else:
print(f" else bilan: topilmadi")
print("\n\n=== 3. Amaliy: parol urinishlari ===")
PAROLLAR = iter(["notogri1", "notogri2", "togri", "kerak emas"])
HAQIQIY_PAROL = "togri"
MAX_URINISH = 3
def parol_tekshir():
urinish = 0
while urinish < MAX_URINISH:
parol = next(PAROLLAR)
urinish += 1
print(f" Urinish {urinish}: {parol!r}")
if parol == HAQIQIY_PAROL:
print(" ✅ Kirish muvaffaqiyatli")
break
else:
# Sikl break siz tugadi — barcha urinish ishlatildi
print(f" ❌ {MAX_URINISH} urinish tugadi — hisob bloklandi")
parol_tekshir()
print("\n\n=== 4. Konvergensiya tekshiruvi ===")
def yaqinlashtir(f, x0: float, aniqlik: float = 1e-10,
max_iter: int = 50) -> float | None:
"""Sobit nuqta usuli. Yaqinlashmasa None."""
x = x0
iter_soni = 0
while iter_soni < max_iter:
yangi = f(x)
if abs(yangi - x) < aniqlik:
print(f" ✅ {iter_soni + 1} iteratsiyada yaqinlashdi")
return yangi
x = yangi
iter_soni += 1
else:
print(f" ❌ {max_iter} iteratsiyada yaqinlashmadi")
return None
import math
print(" cos(x) = x tenglamasi:")
natija = yaqinlashtir(math.cos, 1.0)
print(f" x = {natija}")
print("\n Yaqinlashmaydigan funksiya (x * 2):")
natija = yaqinlashtir(lambda x: x * 2, 1.0)
print(f" x = {natija}")
print("\n\n=== 5. ⚠️ Nom chalkashligi ===")
print("""
`else` bu yerda "aks holda" EMAS.
U "nobreak" — "break bo'lmasa" degani.
Guido van Rossum: "bu nom xato edi".
Shuning uchun IZOH yozing:
while ...:
...
else:
# Sikl break siz tugadi — element topilmadi
...
""")=== 1. Asosiy xatti-harakat ===
break SIZ:
i = 0
i = 1
i = 2
else: sikl normal tugadi ✅
break BILAN:
i = 0
i = 1
break!
Shart darhol yolg'on:
else: baribir bajariladi ✅
=== 3. Amaliy: parol urinishlari ===
Urinish 1: 'notogri1'
Urinish 2: 'notogri2'
Urinish 3: 'togri'
✅ Kirish muvaffaqiyatli
=== 4. Konvergensiya tekshiruvi ===
cos(x) = x tenglamasi:
✅ 86 iteratsiyada yaqinlashdi
x = 0.7390851332151607
Yaqinlashmaydigan funksiya (x * 2):
❌ 50 iteratsiyada yaqinlashmadi
x = NoneNima ko'rsatdi: 2.5-bo'lim.
Misol 4 — Amaliy algoritmlar
"""while bilan klassik algoritmlar."""
import math
import time
print("=== 1. Ikkilik qidiruv ===")
def ikkilik_qidiruv(royxat: list[int], qidiruv: int) -> int:
"""Saralangan ro'yxatda O(log n) qidiruv."""
chap, ong = 0, len(royxat) - 1
qadamlar = 0
while chap <= ong:
qadamlar += 1
orta = (chap + ong) // 2
if royxat[orta] == qidiruv:
return orta, qadamlar
if royxat[orta] < qidiruv:
chap = orta + 1
else:
ong = orta - 1
return -1, qadamlar
ROYXAT = list(range(0, 1000, 3))
print(f" Ro'yxat: 0, 3, 6, ..., {ROYXAT[-1]} ({len(ROYXAT)} element)\n")
print(f" {'Qidiruv':>10} {'Indeks':>8} {'Qadamlar':>10} {'Chiziqli':>10}")
print(" " + "─" * 42)
for q in [0, 501, 999, 1000]:
indeks, qadamlar = ikkilik_qidiruv(ROYXAT, q)
chiziqli = ROYXAT.index(q) + 1 if q in ROYXAT else len(ROYXAT)
print(f" {q:>10} {indeks:>8} {qadamlar:>10} {chiziqli:>10}")
print(f"\n log2({len(ROYXAT)}) ≈ {math.log2(len(ROYXAT)):.1f} — "
f"maksimal qadamlar soni")
print("\n\n=== 2. Evklid algoritmi (EKUB) ===")
def ekub(a: int, b: int) -> int:
"""Eng katta umumiy bo'luvchi."""
while b:
a, b = b, a % b
return a
print(f" {'a':>8} {'b':>8} {'EKUB':>8} {'math.gcd':>10}")
print(" " + "─" * 38)
for a, b in [(48, 18), (100, 75), (17, 5), (1071, 462)]:
natija = ekub(a, b)
print(f" {a:>8} {b:>8} {natija:>8} {math.gcd(a, b):>10}")
print("\n\n=== 3. Kollatz gipotezasi ===")
def kollatz(n: int) -> tuple[int, int]:
"""Kollatz ketma-ketligi uzunligi va maksimal qiymati."""
qadamlar = 0
maksimal = n
while n != 1:
n = n // 2 if n % 2 == 0 else 3 * n + 1
maksimal = max(maksimal, n)
qadamlar += 1
return qadamlar, maksimal
print(f" {'n':>6} {'Qadamlar':>10} {'Maksimal':>12}")
print(" " + "─" * 32)
for n in [6, 27, 97, 871]:
qadamlar, maksimal = kollatz(n)
print(f" {n:>6} {qadamlar:>10} {maksimal:>12,}")
print("\n ⚠️ Bu sikl har doim tugashi ISBOTLANMAGAN (Kollatz gipotezasi)")
print(" Shuning uchun amalda max_iter cheklovi kerak")
print("\n\n=== 4. Nyuton usuli ===")
def nyuton_ildiz(n: float, aniqlik: float = 1e-12) -> tuple[float, int]:
"""Kvadrat ildiz — Nyuton usuli."""
if n < 0:
raise ValueError("Manfiy son")
if n == 0:
return 0.0, 0
x = n / 2 if n > 1 else 1.0
iteratsiya = 0
while True:
yangi = (x + n / x) / 2
iteratsiya += 1
if abs(yangi - x) < aniqlik or iteratsiya > 100:
return yangi, iteratsiya
x = yangi
print(f" {'n':>14} {'Nyuton':>20} {'math.sqrt':>20} {'Iter':>6}")
print(" " + "─" * 64)
for n in [2, 100, 1e6, 1e-6]:
natija, iterlar = nyuton_ildiz(n)
print(f" {n:>14,} {natija:>20.12f} {math.sqrt(n):>20.12f} {iterlar:>6}")
print("\n\n=== 5. Tezlik: while vs for ===")
N = 500_000
boshlandi = time.perf_counter()
i, jami = 0, 0
while i < N:
jami += i
i += 1
vaqt_while = time.perf_counter() - boshlandi
boshlandi = time.perf_counter()
jami2 = 0
for i in range(N):
jami2 += i
vaqt_for = time.perf_counter() - boshlandi
boshlandi = time.perf_counter()
jami3 = sum(range(N))
vaqt_sum = time.perf_counter() - boshlandi
assert jami == jami2 == jami3
eng_tez = min(vaqt_while, vaqt_for, vaqt_sum)
print(f" {'Usul':<12} {'Vaqt':>10} {'Nisbat':>9}")
print(" " + "─" * 34)
for nom, vaqt in [("while", vaqt_while), ("for", vaqt_for), ("sum()", vaqt_sum)]:
print(f" {nom:<12} {vaqt * 1000:>7.1f} ms {vaqt / eng_tez:>8.1f}x")
print("""
Nega farq bor:
while — shart va i += 1 Python bytecode'da
for — range iteratori C darajasida
sum() — butun sikl C darajasida
""")Natijaning muhim qismi:
=== 1. Ikkilik qidiruv ===
Ro'yxat: 0, 3, 6, ..., 999 (334 element)
Qidiruv Indeks Qadamlar Chiziqli
──────────────────────────────────────────
0 0 8 1
501 167 8 168
999 333 9 334
1000 -1 9 334
log2(334) ≈ 8.4 — maksimal qadamlar soni
=== 3. Kollatz gipotezasi ===
n Qadamlar Maksimal
────────────────────────────────
6 8 16
27 111 9,232
97 118 9,232
871 178 190,996
=== 5. Tezlik: while vs for ===
Usul Vaqt Nisbat
──────────────────────────────────
while 38.2 ms 11.2x
for 21.4 ms 6.3x
sum() 3.4 ms 1.0xNima ko'rsatdi: 2.8, 2.9-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
"Pythonda do...while bor" |
Yo'q. while True + break emulyatsiyasi |
"while/else — 'aks holda'" |
"nobreak" — break bo'lmasa bajariladi |
"while x != 1.0 xavfsiz" |
Kasr sonlar bilan cheksiz sikl (3.4-dars) |
"while va for bir xil tez" |
for tezroq — range C darajasida |
"continue while da xavfsiz" |
O'zgarishni o'tkazib yuborsa — cheksiz sikl |
"Indeks bilan yurish uchun while" |
for + enumerate idiomatik |
"while True — yomon uslub" |
Idiomatik, agar break bo'lsa |
| "Sikl doim tugaydi" | Kollatz kabi — isbotlanmagan. max_iter qo'ying |
6. Keng tarqalgan xatolar va yechimlari
1. O'zgarishni unutish
i = 0
while i < 5:
print(i) # ❌ cheksiz
# i += 1 unutildi2. continue dan keyin o'zgarish
i = 0
while i < 10:
if i % 2 == 0:
continue # ❌ i o'zgarmadi
i += 1
i = 0
while i < 10:
i += 1 # ✅ oldin
if i % 2 == 0:
continue3. Kasr sonlar bilan !=
while x != 1.0: # ❌
while x < 1.0: # ✅
while not math.isclose(x, 1.0): # ✅4. while True da break yo'q
while True:
ishla() # ❌ cheksiz5. for o'rniga while
i = 0
while i < len(royxat): # ❌ C uslubi
print(royxat[i])
i += 1
for x in royxat: # ✅
print(x)6. Siklda ro'yxatni o'zgartirish
while royxat:
for x in royxat: # ⚠️ o'zgartirilayotgan ro'yxat bo'ylab
royxat.remove(x) # ❌ kutilmagan natija
while royxat:
x = royxat.pop() # ✅7. Cheksiz sikldan himoya yo'q
while tashqi_shart(): # ❌ tashqi ma'lumotga bog'liq
...
hisob = 0
while tashqi_shart() and hisob < MAX: # ✅
...
hisob += 18. while/else ni noto'g'ri tushunish
while shart:
...
else:
# ⚠️ Bu "shart yolg'on bo'lganda" emas
# Bu "break bo'lmaganda"7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 5.6-dars:
forsikli — ko'p holatda afzal - 5.10-dars:
break,continue, siklelse— batafsil - 5.11-dars: ichma-ich sikllar va murakkablik
- 3.12-dars (o'tilgan): morj operatori
- 9-qism:
try/exceptbilan qayta urinish - 16-qism: fayl o'qish, bo'laklab qayta ishlash
- 31-qism: algoritmlar — ikkilik qidiruv, konvergensiya
- 14-qism: ko'p oqim, navbatlar
8. Eng yaxshi amaliyotlar
Uch elementni tekshiring: boshlang'ich holat, shart, o'zgarish. Bittasi yo'q bo'lsa — cheksiz sikl.
To'plam bo'ylab
forishlating.while i < len(x)— C odati, Pythonda noidiomatik.Kasr sonlar bilan
!=ishlatmang.<yokimath.isclose().continuedan oldin o'zgarishni qo'ying. Bu —whilening eng katta tuzog'i.Tashqi ma'lumotga bog'liq siklda
max_iter. Cheksiz sikldan himoya.Morj operatorini ishlating. Takrorlanishni yo'qotadi.
while/elsega izoh yozing. Ko'p dasturchi uni bilmaydi.while True+break— idiomatik. Bayroq o'zgaruvchisidan yaxshiroq.
9. Amaliy topshiriq
Vazifa 1: Natijani bashorat qiling
# a
i = 0
while i < 3:
print(i)
i += 1
# b
i = 5
while i < 3:
print(i)
else:
print("else")
# c
i = 0
while i < 3:
i += 1
if i == 2:
break
else:
print("else")
print(i)
# d
x = 0.0
n = 0
while x < 1.0:
x += 0.25
n += 1
print(n, x)Javoblar
a. 0, 1, 2
b. else — sikl umuman ishlamadi, lekin break yo'q
c. 2 — else bajarilmadi (break bor)
d. 4 1.0 — 0.25 aniq ifodalanadi (3.4-dars)
Vazifa 2: Cheksiz siklni toping
Har birida muammo nima?
1. i = 0
while i < 5:
print(i)
2. i = 10
while i > 0:
i += 1
3. x = 0.0
while x != 1.0:
x += 0.1
4. i = 0
while i < 10:
if i % 3 == 0:
continue
i += 1
5. while True:
malumot = oqi()
if malumot:
ishla(malumot)Javoblar
io'zgarmaydi- Noto'g'ri yo'nalish —
i -= 1bo'lishi kerak - Kasr son aynan
1.0bo'lmaydi —x < 1.0ishlating continuei += 1ni o'tkazib yuboradibreakyo'q —if not malumot: breakkerak
Vazifa 3: for ga o'tkazing
1. i = 0
while i < len(royxat):
print(royxat[i])
i += 1
2. i = 0
while i < 10:
print(i * i)
i += 1
3. i = len(royxat) - 1
while i >= 0:
print(royxat[i])
i -= 1Javoblar
1. for x in royxat: print(x)
2. for i in range(10): print(i * i)
3. for x in reversed(royxat): print(x)Vazifa 4: Raqamlarni topish o'yini
while True bilan o'yin yozing:
- Dastur 1-100 oralig'ida son o'ylaydi
- Foydalanuvchi taxmin qiladi
- "Kattaroq"/"Kichikroq"/"Topdingiz" deb javob beradi
- Urinishlar sonini sanaydi
chiqishdeb yozsa — tugatadi
Vazifa 5: Ikkilik qidiruv
4-misoldagi ikkilik_qidiruv ni kengaytiring:
- Rekursiv variantini yozing
- Eng chap/eng o'ng uchrashuvni topish (takrorlar bo'lsa)
- Kiritish uchun o'rin topish (
bisectkabi) bisectmoduli bilan solishtiring
Vazifa 6: Konvergensiya
Nyuton usulini kengaytiring:
- Ixtiyoriy
n-darajali ildiz - Har iteratsiyani chiqaruvchi rejim
- Boshlang'ich taxmin ta'sirini o'rganish
- Yaqinlashish tezligini o'lchash
Vazifa 7: O'ylash
Nega Pythonda do...while yo'q?
Javob
Uch sabab:
1. Kam kerak bo'ladi. Amaliyotda "kamida bir marta bajarish" holati nisbatan kam uchraydi.
2. while True + break — moslashuvchanroq.
do...while da shart faqat oxirida tekshiriladi. while True da esa istalgan joyda:
while True:
a = oldin()
if shart1:
break # o'rtada
b = keyin()
if shart2:
break # oxiridaBu — "loop-and-a-half" naqshi, u do...while dan kuchliroq.
3. Yangi kalit so'z kerak bo'lardi.
Python sintaksisni sodda saqlashga harakat qiladi (1.5-dars). do kalit so'zi qo'shish faqat bitta holat uchun — arzimaydi.
PEP 315 (2003) do...while ni taklif qilgan:
do:
...
while shartGuido rad etdi: "while True + break allaqachon ishlaydi va u aniqroq".
Solishtiring boshqa til bilan:
| Til | do...while |
|---|---|
| C, Java, JS | bor |
| Python | yo'q |
| Go | yo'q (for universal) |
| Rust | yo'q (loop + break) |
Zamonaviy tillar ham undan voz kechyapti — chunki loop + break moslashuvchanroq.
Nimani mustahkamlaydi: 2.2, 2.3, 2.5, 2.7, 2.8-bo'limlar.
Xulosa
Bu darsda while siklini o'rgandik.
Eng muhim uch fikr:
Uch element majburiy: boshlang'ich holat, shart va o'zgarish. Oxirgisini unutish — cheksiz siklning asosiy sababi.
continueishlatganda o'zgarishni undan oldin qo'ying.while True+break— idiomatik. Pythondado...whileyo'q, lekin bu naqsh undan kuchliroq: shartni siklning istalgan joyida tekshirish mumkin.while/else— "nobreak" degani.elsebloki siklbreaksiz tugaganda bajariladi. Bu qidiruv naqshlarida bayroq o'zgaruvchisini almashtiradi, lekin nomi chalkash — izoh yozing.
Keyingi darsda for siklini o'rganamiz — Pythonda eng ko'p ishlatiladigan sikl. U while dan farqli o'laroq iteratsiya protokoli ga asoslanadi.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!