IlmHamroh
Python kursi/Boshqaruv oqimi5/12-dars27 daqiqa
Mundarija (23)

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":

python
hisob = 0
while hisob < 5:
    print(hisob)
    hisob += 1

Sodda ko'rinadi. Lekin while — eng xavfli boshqaruv tuzilmasi, chunki u hech qachon tugamasligi mumkin:

python
hisob = 0
while hisob < 5:
    print(hisob)            # ❌ hisob o'zgarmaydi — cheksiz sikl

Va bir necha nozik jihat bor:

python
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:

  • while sintaksisi va bajarilish tartibi
  • Cheksiz sikl — sabablari va oldini olish
  • while True + break naqshi
  • while/else — kam ma'lum, lekin foydali
  • Morj operatori bilan
  • Qachon while, qachon for

2. Nazariya — chuqur tushuntirish

2.1. Asosiy sintaksis

python
while <shart>:
    <blok>

Bajarilish tartibi:

text
1. <shart> hisoblanadi
2. Yolg'on bo'lsa → sikl tugaydi
3. Rost bo'lsa → <blok> bajariladi
4. 1-qadamga qaytiladi
python
hisob = 0
while hisob < 3:
    print(f"  hisob = {hisob}")
    hisob += 1
print(f"  Sikldan keyin: {hisob}")
text
  hisob = 0
  hisob = 1
  hisob = 2
  Sikldan keyin: 3

Shart har iteratsiyadan OLDIN tekshiriladi:

python
hisob = 10
while hisob < 3:
    print("Bu bajarilmaydi")    # sikl umuman ishlamaydi

Ba'zi tillarda do...while bor — u kamida bir marta bajariladi. Pythonda yo'q:

python
# do...while emulyatsiyasi
while True:
    ishla()
    if not shart:
        break

Uch element:

  1. Boshlang'ich holat — sikldan oldin
  2. Shart — qachon davom etish
  3. O'zgarish — blok ichida
python
hisob = 0                   # 1. boshlang'ich
while hisob < 5:            # 2. shart
    print(hisob)
    hisob += 1              # 3. o'zgarish ← BUNI UNUTMANG

2.2. Cheksiz sikl

Eng ko'p uchraydigan xato — o'zgarishni unutish:

python
hisob = 0
while hisob < 5:
    print(hisob)            # ❌ hisob hech qachon o'zgarmaydi

Bu — cheksiz sikl. Dastur to'xtamaydi.

To'xtatish: Ctrl + C (2.4-dars).

Boshqa sabablar:

python
# 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 += 1

Kasr sonlar tuzog'i — batafsil:

python
x = 0.0
for _ in range(11):
    print(f"  {x!r}")
    x += 0.1
text
  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:

python
# 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:

python
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:

python
while True:
    kirish = input("Buyruq: ").strip()

    if kirish == "chiqish":
        break

    ishla(kirish)

Bu — idiomatik Python. Muqobil variantlar chirkinroq:

python
# ❌ 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:

python
# 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:

python
while True:
    ishla()                 # ❌ break yo'q — cheksiz

Ruff bunday holatni topmaydi. Diqqat bilan yozing.

2.4. Morj operatori bilan

3.12-darsda tanishgandik. while bilan u ayniqsa foydali:

python
# ❌ Takrorlanish
qator = fayl.readline()
while qator:
    ishla(qator)
    qator = fayl.readline()

# ✅ Morj bilan
while (qator := fayl.readline()):
    ishla(qator)

Boshqa misollar:

python
# 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:

python
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.

python
while <shart>:
    <blok>
else:
    <else_blok>             # sikl NORMAL tugaganda bajariladi

else qachon bajariladi:

  • Sikl shart yolg'on bo'lgani uchun tugaganda
  • break bilan chiqilganda
python
i = 0
while i < 3:
    print(f"  i = {i}")
    i += 1
else:
    print("  else: sikl normal tugadi")
text
  i = 0
  i = 1
  i = 2
  else: sikl normal tugadi
python
i = 0
while i < 3:
    print(f"  i = {i}")
    if i == 1:
        break
    i += 1
else:
    print("  else: bajarilmaydi")
text
  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:

python
# ❌ 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:

python
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 True

Bu 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:

python
while ...:
    ...
else:
    # Sikl break siz tugadi — ya'ni topilmadi
    ...

2.6. break va continue

10-darsda batafsil ko'ramiz. Qisqacha:

python
# 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:

python
i = 0
while i < 10:
    if i % 2 == 0:
        continue            # ❌ i o'zgarmadi — cheksiz sikl!
    print(i)
    i += 1

To'g'ri:

python
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:

python
for x in royxat:            # ✅
for i in range(10):         # ✅
for kalit in lugat:         # ✅

while — shart bo'yicha:

python
while not tugadi():         # ✅ nechta iteratsiya noma'lum
while ulanish.faol():       # ✅
while navbat:               # ✅

for ni while bilan almashtirish — anti-naqsh:

python
# ❌ 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:

python
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:

python
while stek:
    element = stek.pop()
    ishla(element)

while navbat:
    element = navbat.popleft()
    ishla(element)

3. Konvergensiya:

python
# 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.414213562373095

4. Ikkilik qidiruv:

python
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 -1

31-qismda algoritmlarni batafsil o'rganamiz.

5. Holat mashinasi:

python
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:

python
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:

python
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 += 1 bajariladi (Python bytecode)

Eng tez — ichki funksiyalar:

python
print(sum(range(N)))        # C darajasida

Optimizatsiya maslahatlari:

python
# ❌ 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

python
while <shart>:
    <blok>
else:                       # ixtiyoriy — break BO'LMASA bajariladi
    <else_blok>

Uch element

python
hisob = 0                   # 1. boshlang'ich holat
while hisob < 5:            # 2. shart
    ...
    hisob += 1              # 3. o'zgarish ← UNUTMANG

Cheksiz sikl sabablari

text
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'q

Naqshlar

python
while True:                 do-while emulyatsiyasi
    ishla()
    if shart: break

while (x := f()):           morj operatori
while stek:                 to'plamni bo'shatish
while chap <= ong:          ikkilik qidiruv

while vs for

text
for   — to'plam bo'ylab, ma'lum son marta
while — shart bo'yicha, iteratsiya soni noma'lum

Himoya

python
MAX = 10_000
hisob = 0
while shart() and hisob < MAX:
    ...
    hisob += 1

4. Batafsil misollar

Misol 1 — Cheksiz sikl sabablari

python
"""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:

text
=== 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+00

Nima ko'rsatdi: 2.2, 2.6-bo'limlar.

Misol 2 — while True naqshlari

python
"""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:

text
=== 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

python
"""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
        ...
""")
text
=== 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 = None

Nima ko'rsatdi: 2.5-bo'lim.

Misol 4 — Amaliy algoritmlar

python
"""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:

text
=== 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.0x

Nima 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

python
i = 0
while i < 5:
    print(i)                # ❌ cheksiz
    # i += 1 unutildi

2. continue dan keyin o'zgarish

python
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:
        continue

3. Kasr sonlar bilan !=

python
while x != 1.0:             # ❌
while x < 1.0:              # ✅
while not math.isclose(x, 1.0):     # ✅

4. while True da break yo'q

python
while True:
    ishla()                 # ❌ cheksiz

5. for o'rniga while

python
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

python
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

python
while tashqi_shart():       # ❌ tashqi ma'lumotga bog'liq
    ...

hisob = 0
while tashqi_shart() and hisob < MAX:   # ✅
    ...
    hisob += 1

8. while/else ni noto'g'ri tushunish

python
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: for sikli — ko'p holatda afzal
  • 5.10-dars: break, continue, sikl else — batafsil
  • 5.11-dars: ichma-ich sikllar va murakkablik
  • 3.12-dars (o'tilgan): morj operatori
  • 9-qism: try/except bilan 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

  1. Uch elementni tekshiring: boshlang'ich holat, shart, o'zgarish. Bittasi yo'q bo'lsa — cheksiz sikl.

  2. To'plam bo'ylab for ishlating. while i < len(x) — C odati, Pythonda noidiomatik.

  3. Kasr sonlar bilan != ishlatmang. < yoki math.isclose().

  4. continue dan oldin o'zgarishni qo'ying. Bu — while ning eng katta tuzog'i.

  5. Tashqi ma'lumotga bog'liq siklda max_iter. Cheksiz sikldan himoya.

  6. Morj operatorini ishlating. Takrorlanishni yo'qotadi.

  7. while/else ga izoh yozing. Ko'p dasturchi uni bilmaydi.

  8. while True + break — idiomatik. Bayroq o'zgaruvchisidan yaxshiroq.


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
# 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?

python
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
  1. i o'zgarmaydi
  2. Noto'g'ri yo'nalish — i -= 1 bo'lishi kerak
  3. Kasr son aynan 1.0 bo'lmaydi — x < 1.0 ishlating
  4. continue i += 1 ni o'tkazib yuboradi
  5. break yo'q — if not malumot: break kerak

Vazifa 3: for ga o'tkazing

python
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 -= 1
Javoblar
python
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
  • chiqish deb yozsa — tugatadi

Vazifa 5: Ikkilik qidiruv

4-misoldagi ikkilik_qidiruv ni kengaytiring:

  1. Rekursiv variantini yozing
  2. Eng chap/eng o'ng uchrashuvni topish (takrorlar bo'lsa)
  3. Kiritish uchun o'rin topish (bisect kabi)
  4. bisect moduli bilan solishtiring

Vazifa 6: Konvergensiya

Nyuton usulini kengaytiring:

  1. Ixtiyoriy n-darajali ildiz
  2. Har iteratsiyani chiqaruvchi rejim
  3. Boshlang'ich taxmin ta'sirini o'rganish
  4. 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:

python
while True:
    a = oldin()
    if shart1:
        break               # o'rtada
    b = keyin()
    if shart2:
        break               # oxirida

Bu — "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:

python
do:
    ...
while shart

Guido 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:

  1. Uch element majburiy: boshlang'ich holat, shart va o'zgarish. Oxirgisini unutish — cheksiz siklning asosiy sababi. continue ishlatganda o'zgarishni undan oldin qo'ying.

  2. while True + break — idiomatik. Pythonda do...while yo'q, lekin bu naqsh undan kuchliroq: shartni siklning istalgan joyida tekshirish mumkin.

  3. while/else — "nobreak" degani. else bloki sikl break siz 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.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
5.5-dars: while sikli — IlmHamroh