IlmHamroh
Python kursi/Boshqaruv oqimi12/12-dars35 daqiqa
Mundarija (26)

5.12-dars: match / case (3.10+)

5-QISM — BOSHQARUV OQIMI · 12-dars · 5-qism va BOSQICH 1 ning yakuni


1. Kirish va motivatsiya

1-darsda aytgandik: Pythonda switch yo'q. 2021-yilda Python 3.10 buni o'zgartirdi — lekin kutilganidek emas.

match/case — oddiy switch emas. U — strukturaviy naqsh moslashtirish (structural pattern matching), Rust, Scala va Haskell'dagi kabi.

Oddiy switch shunday ko'rinardi:

python
match buyruq:
    case "boshla":
        boshla()
    case "to'xtat":
        toxtat()
    case _:
        print("Noma'lum buyruq")

Lekin match ancha kuchliroq — u tuzilmani ochadi:

python
match javob:
    case {"holat": "ok", "malumot": malumot}:
        return malumot
    case {"holat": "xato", "kod": int(kod)} if kod >= 500:
        raise ServerXatosi(kod)
    case {"holat": "xato", "xabar": str(xabar)}:
        raise MijozXatosi(xabar)
    case _:
        raise ValueError("Noma'lum javob")

Bitta konstruksiyada: shakl tekshiruvi, tur tekshiruvi, qiymat ochish va qo'shimcha shart.

Bu darsda:

  • match/case sintaksisi va barcha naqsh turi
  • Nima uchun bu switch emas
  • Eng ko'p uchraydigan tuzoq — nom bog'lash
  • Qachon match, qachon if/elif yoki lug'at
  • Amaliy qo'llanishlar

2. Nazariya — chuqur tushuntirish

2.1. Asosiy sintaksis

python
match <ifoda>:
    case <naqsh1>:
        <blok1>
    case <naqsh2>:
        <blok2>
    case _:
        <sukut blok>
python
def javob(kod: int) -> str:
    match kod:
        case 200:
            return "OK"
        case 404:
            return "Topilmadi"
        case 500:
            return "Server xatosi"
        case _:
            return "Noma'lum"


print(javob(200))               # 'OK'
print(javob(999))               # "Noma'lum"

Muhim jihatlar:

  1. Birinchi mos keladigan case bajariladi
  2. break kerak emas — C dagi kabi "fallthrough" yo'q
  3. _ — joker (wildcard), har narsaga mos keladi
  4. Hech biri mos kelmasa — hech narsa bajarilmaydi (xato yo'q)

match va case — "yumshoq kalit so'zlar":

python
match = 5                       # ✅ o'zgaruvchi sifatida ishlatish mumkin
case = "test"                   # ✅
print(match, case)              # 5 test

Python ularni kontekstga qarab ajratadi. Bu — moslikni saqlash uchun.

2.2. Naqsh turlari — to'liq ro'yxat

1. Literal naqsh:

python
match x:
    case 42: ...                # son
    case "matn": ...            # satr
    case True: ...              # bool
    case None: ...              # None
    case 3.14: ...              # kasr

None, True, False — is bilan solishtiriladi, qolganlari == bilan.

2. Nom bog'lash (capture) — ENG KATTA TUZOQ:

python
match x:
    case y:                     # ❌ HAR NARSAGA mos keladi!
        print(y)                # va x ni y ga bog'laydi

Bu — switch emas! case y "agar x == y bo'lsa" emas, balki "x ni y ga bog'la" degani.

python
QIYMAT = 42

match 100:
    case QIYMAT:                # ❌ QIYMAT ga 100 bog'lanadi!
        print("Mos keldi")      # HAR DOIM bajariladi
print(QIYMAT)                   # 100 ← o'zgaruvchi qayta yozildi!

Yechim — nuqta bilan yozish:

python
class Doimiylar:
    QIYMAT = 42

match 100:
    case Doimiylar.QIYMAT:      # ✅ qiymat bilan solishtirish
        print("Mos keldi")      # bajarilmaydi

Yoki Enum bilan (8-qism):

python
from enum import Enum

class Holat(Enum):
    FAOL = 1
    NOFAOL = 2

match h:
    case Holat.FAOL: ...        # ✅ nuqta bor — qiymat solishtiruvi

Qoida:

Naqshda oddiy nom — bog'lash. Nuqtali nom — qiymat solishtiruvi.

3. Joker (_):

python
match x:
    case 1: ...
    case _: ...                 # qolgan hamma holat

_ — maxsus: u bog'lamaydi, faqat mos keladi.

4. VA naqsh (|) — bir necha variant:

python
match kod:
    case 200 | 201 | 204:
        return "Muvaffaqiyat"
    case 400 | 401 | 403 | 404:
        return "Mijoz xatosi"
    case 500 | 502 | 503:
        return "Server xatosi"

5. Ketma-ketlik naqshi:

python
match nuqta:
    case [0, 0]:
        print("Markaz")
    case [x, 0]:
        print(f"X o'qida: {x}")
    case [0, y]:
        print(f"Y o'qida: {y}")
    case [x, y]:
        print(f"Nuqta: ({x}, {y})")

Ketma-ketlik naqshi list va tuple ga mos keladi, lekin str ga YO'Q:

python
match [1, 2]:
    case [a, b]: print("mos")   # ✅
match (1, 2):
    case [a, b]: print("mos")   # ✅ tuple ham
match "ab":
    case [a, b]: print("mos")   # ❌ satr mos kelmaydi

Bu — ataylab: satr ham ketma-ketlik, lekin uni belgilarga ajratish deyarli hech qachon kerak emas.

6. Yulduzcha (*) — qolgan elementlar:

python
match royxat:
    case []:
        print("Bo'sh")
    case [x]:
        print(f"Bitta: {x}")
    case [x, y]:
        print(f"Ikkita: {x}, {y}")
    case [birinchi, *qolgani]:
        print(f"Birinchi: {birinchi}, qolgani: {qolgani}")

7. Lug'at naqshi:

python
match malumot:
    case {"turi": "doira", "radius": r}:
        return 3.14159 * r ** 2
    case {"turi": "to'rtburchak", "en": e, "bo'y": b}:
        return e * b

Lug'at naqshi — QISMAN moslik:

python
match {"a": 1, "b": 2, "c": 3}:
    case {"a": 1}:              # ✅ mos keladi — qolgan kalitlar e'tiborsiz
        print("mos")

Bu — ketma-ketlikdan farqi: [1] faqat bir elementli ro'yxatga mos keladi.

Barcha kalitni tekshirish uchun ** ishlating:

python
match malumot:
    case {"a": 1, **qolgani} if not qolgani:     # ✅ faqat "a" bo'lsa
        ...

8. Sinf naqshi:

python
from dataclasses import dataclass

@dataclass
class Nuqta:
    x: int
    y: int


match nuqta:
    case Nuqta(x=0, y=0):
        print("Markaz")
    case Nuqta(x=0, y=y):
        print(f"Y o'qida: {y}")
    case Nuqta(x=x, y=y):
        print(f"({x}, {y})")

Pozitsion argumentlar — __match_args__ bilan:

python
@dataclass
class Nuqta:
    x: int
    y: int
    # dataclass avtomatik __match_args__ = ("x", "y") yaratadi


match nuqta:
    case Nuqta(0, 0):           # ✅ pozitsion
        print("Markaz")

Tur tekshiruvi:

python
match qiymat:
    case int():
        print("Butun son")
    case str():
        print("Satr")
    case list():
        print("Ro'yxat")

Tur + bog'lash:

python
match qiymat:
    case int(x) if x > 0:
        print(f"Musbat butun: {x}")
    case str(s) if len(s) > 10:
        print(f"Uzun satr: {s[:10]}...")

9. Qo'riqchi shart (if):

python
match nuqta:
    case [x, y] if x == y:
        print("Diagonal")
    case [x, y] if x > 0 and y > 0:
        print("Birinchi chorak")
    case [x, y]:
        print("Boshqa")

Qo'riqchi shart naqsh mos kelgandan keyin tekshiriladi.

10. as naqshi — bog'lash bilan:

python
match malumot:
    case {"turi": "doira", "radius": r} as shakl:
        print(f"Shakl: {shakl}, radius: {r}")

    case [Nuqta(0, 0) as boshi, *qolgani]:
        print(f"Boshi: {boshi}")

2.3. Nom bog'lash tuzog'i — batafsil

Bu — match bilan bog'liq eng katta muammo.

python
# ❌ Kutilgan: "x 42 ga tengmi"
QIYMAT = 42
x = 100

match x:
    case QIYMAT:
        print("Teng!")          # HAR DOIM bajariladi
print(QIYMAT)                   # 100 — o'zgaruvchi qayta yozildi!

Nega? Naqshda oddiy nom — bu bog'lash naqshi. U har narsaga mos keladi va nomga qiymat bog'laydi.

Uch yechim:

python
# 1. Nuqtali nom (nuqta bo'lishi kerak)
class Doimiylar:
    QIYMAT = 42

match x:
    case Doimiylar.QIYMAT: ...  # ✅

# 2. Enum (8-qism) — eng yaxshi
from enum import Enum

class Kod(Enum):
    OK = 200
    XATO = 500

match kod:
    case Kod.OK: ...            # ✅

# 3. Modul orqali
import konfig
match x:
    case konfig.QIYMAT: ...     # ✅

# 4. Qo'riqchi shart
match x:
    case y if y == QIYMAT: ...  # ✅ ishlaydi, lekin chirkin

Yana bir tuzoq — bir necha bog'lash:

python
match nuqta:
    case [x, x]:                # ❌ SyntaxError
        print("Bir xil")

Bir naqshda bir xil nom ikki marta ishlatib bo'lmaydi.

To'g'ri:

python
match nuqta:
    case [a, b] if a == b:      # ✅
        print("Bir xil")

| bilan bog'lash:

python
match x:
    case [1, y] | [2, y]:       # ✅ har ikkala tarmoqda y bor
        print(y)

    case [1, y] | [2]:          # ❌ SyntaxError — y faqat bir tarmoqda
        ...

| bilan birlashtirilgan naqshlar bir xil nomlarni bog'lashi kerak.

2.4. Ketma-ketlik naqshlari — batafsil

python
def tahlil(malumot):
    match malumot:
        case []:
            return "bo'sh"
        case [x]:
            return f"bitta: {x}"
        case [x, y]:
            return f"ikkita: {x}, {y}"
        case [x, y, *qolgani]:
            return f"ko'p: {x}, {y} + yana {len(qolgani)} ta"
        case _:
            return "ketma-ketlik emas"


for m in [[], [1], [1, 2], [1, 2, 3, 4], "abc", 42]:
    print(f"  {m!r:<14} → {tahlil(m)}")
text
  []             → bo'sh
  [1]            → bitta: 1
  [1, 2]         → ikkita: 1, 2
  [1, 2, 3, 4]   → ko'p: 1, 2 + yana 2 ta
  'abc'          → ketma-ketlik emas
  42             → ketma-ketlik emas

Satr ketma-ketlik naqshiga mos kelmaydi — bu ataylab.

Ichma-ich naqshlar:

python
match malumot:
    case [[a, b], [c, d]]:
        print(f"2×2 matritsa: {a} {b} / {c} {d}")

    case [{"ism": ism}, *qolgani]:
        print(f"Birinchi: {ism}, yana {len(qolgani)} ta")

Yulduzcha o'rtada ham:

python
match royxat:
    case [birinchi, *orta, oxirgi]:
        print(f"{birinchi} ... {oxirgi} ({len(orta)} ta o'rtada)")

Bir naqshda bitta *:

python
case [*a, *b]:                  # ❌ SyntaxError

Sobit uzunlik:

python
case [_, _, _]:                 # aynan 3 element
case [_, _, *_]:                # kamida 2 element

2.5. Lug'at va sinf naqshlari

Lug'at — qisman moslik:

python
JAVOBLAR = [
    {"holat": "ok", "malumot": [1, 2, 3]},
    {"holat": "xato", "kod": 404, "xabar": "Topilmadi"},
    {"holat": "xato", "kod": 500},
    {"noma'lum": "format"},
]

for javob in JAVOBLAR:
    match javob:
        case {"holat": "ok", "malumot": malumot}:
            print(f"  ✅ {len(malumot)} ta element")

        case {"holat": "xato", "kod": kod, "xabar": xabar}:
            print(f"  ❌ {kod}: {xabar}")

        case {"holat": "xato", "kod": kod}:
            print(f"  ❌ {kod}: (xabar yo'q)")

        case _:
            print(f"  ⚠️ Noma'lum format")

Tartib muhim — aniqroq naqsh oldinda bo'lishi kerak.

Sinf naqshi:

python
from dataclasses import dataclass


@dataclass
class Doira:
    radius: float


@dataclass
class Tortburchak:
    en: float
    boy: float


@dataclass
class Uchburchak:
    a: float
    b: float
    c: float


def yuza(shakl) -> float:
    match shakl:
        case Doira(radius=r):
            return 3.14159 * r ** 2
        case Tortburchak(en=e, boy=b):
            return e * b
        case Uchburchak(a=a, b=b, c=c):
            p = (a + b + c) / 2
            return (p * (p-a) * (p-b) * (p-c)) ** 0.5
        case _:
            raise ValueError(f"Noma'lum shakl: {shakl}")

Pozitsion argumentlar:

python
match shakl:
    case Doira(r):              # ✅ __match_args__ tufayli
        return 3.14159 * r ** 2
    case Tortburchak(e, b):
        return e * b

@dataclass avtomatik __match_args__ yaratadi. Oddiy sinf uchun qo'lda:

python
class Nuqta:
    __match_args__ = ("x", "y")

    def __init__(self, x, y):
        self.x, self.y = x, y

Tur va qiymat birga:

python
match qiymat:
    case int() | float() as son if son > 0:
        print(f"Musbat son: {son}")
    case str() as matn if matn.isdecimal():
        print(f"Sonli satr: {matn}")

2.6. Qachon match, qachon boshqa narsa

match yaxshi:

python
# 1. Tuzilmani ochish
match javob:
    case {"holat": "ok", "malumot": m}: ...

# 2. Turli shakldagi ma'lumot
match hodisa:
    case {"turi": "bosish", "x": x, "y": y}: ...
    case {"turi": "tugma", "kod": kod}: ...

# 3. AST/token qayta ishlash
match tugun:
    case BinaryOp(chap, "+", ong): ...

# 4. Rekursiv tuzilmalar
match daraxt:
    case Barg(qiymat): ...
    case Tugun(chap, ong): ...

match ortiqcha:

python
# 1. Oddiy qiymat solishtiruvi → lug'at
match rang:
    case "qizil": return "#FF0000"
    case "yashil": return "#00FF00"

RANGLAR = {"qizil": "#FF0000", "yashil": "#00FF00"}      # ✅ tezroq
return RANGLAR.get(rang, "#000000")

# 2. Diapazon tekshiruvi → if/elif
match ball:
    case b if b >= 90: return "A"
    case b if b >= 80: return "B"

if ball >= 90: return "A"                                # ✅ aniqroq
if ball >= 80: return "B"

# 3. Ikki holat → if/else
match bayroq:
    case True: ...
    case False: ...

if bayroq: ...                                           # ✅
else: ...

Qaror jadvali:

Vaziyat Yechim
Aniq qiymatlar (2-3 ta) if/elif
Aniq qiymatlar (ko'p) Lug'at
Diapazonlar if/elif
Tuzilmani ochish match
Turli shakldagi ma'lumot match
Tur bo'yicha tarmoqlanish match yoki isinstance
Rekursiv tuzilmalar match

2.7. Tezlik

python
import time

N = 1_000_000

# match
def match_bilan(x):
    match x:
        case 0: return "nol"
        case 1: return "bir"
        case 2: return "ikki"
        case _: return "boshqa"


# if/elif
def if_bilan(x):
    if x == 0: return "nol"
    if x == 1: return "bir"
    if x == 2: return "ikki"
    return "boshqa"


# Lug'at
LUGAT = {0: "nol", 1: "bir", 2: "ikki"}

def lugat_bilan(x):
    return LUGAT.get(x, "boshqa")

Natija (taxminan):

text
lugat_bilan:  0.42 s      ← eng tez (xesh jadval, O(1))
if_bilan:     0.58 s
match_bilan:  0.61 s

match — switch emas, jadval sakrash (jump table) yaratmaydi. U ketma-ket tekshiradi, if/elif kabi.

Lekin murakkab naqshlarda match yutadi:

python
# match bilan — bitta o'tish
match javob:
    case {"holat": "ok", "malumot": [birinchi, *qolgani]}: ...

# if bilan — bir necha tekshiruv
if (isinstance(javob, dict)
        and javob.get("holat") == "ok"
        and isinstance(javob.get("malumot"), list)
        and len(javob["malumot"]) >= 1):
    birinchi = javob["malumot"][0]
    qolgani = javob["malumot"][1:]

Xulosa: match — tezlik uchun emas, o'qish osonligi uchun.

2.8. Versiya mosligi

match/case — Python 3.10+.

python
import sys

if sys.version_info >= (3, 10):
    # match ishlatish mumkin
    ...

Eski versiyada SyntaxError — hatto kod bajarilmasa ham, chunki bu sintaksis darajasida.

Shuning uchun shartli import ishlamaydi:

python
if sys.version_info >= (3, 10):
    match x:                    # ❌ 3.9 da SyntaxError (parse paytida)
        case 1: ...

Yechim — alohida modul:

python
# match_yordamchi.py (faqat 3.10+ da import qilinadi)
def ishla(x):
    match x:
        case ...: ...

# main.py
if sys.version_info >= (3, 10):
    from match_yordamchi import ishla
else:
    from oddiy_yordamchi import ishla

pyproject.toml da (2.7-dars):

toml
[project]
requires-python = ">=3.10"

[tool.ruff]
target-version = "py310"

Amaliy maslahat: kutubxona yozayotgan bo'lsangiz va eski versiyalarni qo'llab-quvvatlash kerak bo'lsa — match ishlatmang. Ilova uchun — bemalol.

2.9. Amaliy naqshlar

1. HTTP javobini qayta ishlash:

python
def javobni_ishla(javob: dict):
    match javob:
        case {"status": 200, "data": data}:
            return data
        case {"status": 201, "id": id}:
            return f"Yaratildi: {id}"
        case {"status": 400 | 422, "errors": errors}:
            raise ValidationError(errors)
        case {"status": 401 | 403}:
            raise AuthError()
        case {"status": int(kod)} if kod >= 500:
            raise ServerError(kod)
        case _:
            raise ValueError(f"Noma'lum javob: {javob}")

2. Buyruq satri argumentlari:

python
import sys

match sys.argv[1:]:
    case []:
        yordam()
    case ["--help" | "-h"]:
        yordam()
    case ["--version" | "-v"]:
        print(VERSIYA)
    case ["run", fayl]:
        ishga_tushir(fayl)
    case ["run", fayl, *bayroqlar]:
        ishga_tushir(fayl, bayroqlar)
    case [buyruq, *_]:
        print(f"Noma'lum buyruq: {buyruq}")

3. Hodisalarni qayta ishlash:

python
match hodisa:
    case {"turi": "bosish", "tugma": "chap", "x": x, "y": y}:
        chap_bosish(x, y)
    case {"turi": "bosish", "tugma": "ong", "x": x, "y": y}:
        ong_bosish(x, y)
    case {"turi": "klaviatura", "kod": kod, "shift": True}:
        katta_harf(kod)
    case {"turi": "klaviatura", "kod": kod}:
        oddiy_harf(kod)

4. Rekursiv tuzilmalar:

python
@dataclass
class Barg:
    qiymat: int


@dataclass
class Tugun:
    chap: "Barg | Tugun"
    ong: "Barg | Tugun"


def yigindi(daraxt) -> int:
    match daraxt:
        case Barg(qiymat=q):
            return q
        case Tugun(chap=c, ong=o):
            return yigindi(c) + yigindi(o)
        case _:
            raise TypeError(f"Noma'lum tugun: {daraxt}")

5. Ma'lumot tekshiruvi:

python
def tekshir(malumot) -> str:
    match malumot:
        case {"ism": str(ism), "yosh": int(yosh)} if 0 < yosh < 150:
            return f"✅ {ism}, {yosh}"
        case {"ism": str()}:
            return "❌ Yosh noto'g'ri"
        case {"yosh": int()}:
            return "❌ Ism yo'q"
        case dict():
            return "❌ Majburiy maydonlar yetishmaydi"
        case _:
            return "❌ Lug'at kutilgan edi"

3. Tez ma'lumotnoma

Sintaksis

python
match <ifoda>:
    case <naqsh>:           birinchi mos keladigan bajariladi
    case <naqsh> if <shart>:  qo'riqchi shart
    case _:                 joker (sukut)

Naqsh turlari

python
case 42:                    literal
case "matn" | "boshqa":     yoki (|)
case x:                     ⚠️ BOG'LASH — har narsaga mos
case Modul.DOIMIY:          qiymat solishtiruvi (nuqta kerak!)
case _:                     joker
case [a, b]:                ketma-ketlik (list, tuple — str EMAS)
case [a, *qolgani]:         yulduzcha
case {"kalit": q}:          lug'at (QISMAN moslik)
case Sinf(x=1, y=y):        sinf (nomli)
case Sinf(a, b):            sinf (pozitsion, __match_args__)
case int() | float():       tur tekshiruvi
case [x, y] as juftlik:     as bilan bog'lash

ENG KATTA TUZOQ

python
QIYMAT = 42
match 100:
    case QIYMAT:            ❌ QIYMAT ga 100 BOG'LANADI
        ...                 har doim bajariladi

case Doimiylar.QIYMAT:      ✅ nuqta bilan
case Enum.QIYMAT:           ✅ eng yaxshi
case y if y == QIYMAT:      ✅ qo'riqchi shart

Farqlar

text
Ketma-ketlik: [1]      → AYNAN bir elementli
Lug'at:       {"a": 1} → QISMAN (qolgan kalitlar e'tiborsiz)
Satr:         ketma-ketlik naqshiga MOS KELMAYDI

Qachon match

text
✅ Tuzilmani ochish, turli shakldagi ma'lumot, rekursiv tuzilma
❌ Oddiy qiymat solishtiruvi → lug'at
❌ Diapazonlar → if/elif
❌ Ikki holat → if/else

Versiya

text
Python 3.10+ — eski versiyada SyntaxError (parse paytida)

4. Batafsil misollar

Misol 1 — Barcha naqsh turi

python
"""match/case — to'liq ma'lumotnoma."""

import sys
from dataclasses import dataclass
from enum import Enum

if sys.version_info < (3, 10):
    print("⚠️ match/case Python 3.10+ talab qiladi")
    sys.exit(1)


print("=== 1. Literal naqshlar ===")


def literal(x):
    match x:
        case 42:
            return "son 42"
        case "salom":
            return "salom satri"
        case True:
            return "True"
        case None:
            return "None"
        case 3.14:
            return "pi"
        case _:
            return f"boshqa: {x!r}"


for x in [42, "salom", True, None, 3.14, "boshqa", 0]:
    print(f"  {x!r:<10} → {literal(x)}")

print("\n  ⚠️ True/False/None — `is` bilan, qolganlari `==` bilan")


print("\n\n=== 2. | (yoki) naqshi ===")


def http_turi(kod: int) -> str:
    match kod:
        case 200 | 201 | 204:
            return "✅ Muvaffaqiyat"
        case 301 | 302 | 307 | 308:
            return "↪️  Yo'naltirish"
        case 400 | 401 | 403 | 404 | 422:
            return "❌ Mijoz xatosi"
        case 500 | 502 | 503 | 504:
            return "🔴 Server xatosi"
        case _:
            return "❓ Noma'lum"


for kod in [200, 301, 404, 500, 999]:
    print(f"  {kod} → {http_turi(kod)}")


print("\n\n=== 3. Ketma-ketlik naqshlari ===")


def tahlil_ketma_ketlik(x):
    match x:
        case []:
            return "bo'sh"
        case [a]:
            return f"bitta: {a}"
        case [a, b]:
            return f"ikkita: {a}, {b}"
        case [a, b, c]:
            return f"uchta: {a}, {b}, {c}"
        case [birinchi, *orta, oxirgi]:
            return f"{birinchi} ... {oxirgi} ({len(orta)} o'rtada)"
        case _:
            return "ketma-ketlik emas"


for x in [[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4, 5],
          (1, 2), "abc", 42, {"a": 1}]:
    print(f"  {x!r:<16} → {tahlil_ketma_ketlik(x)}")

print("\n  ⚠️ Satr ketma-ketlik naqshiga MOS KELMAYDI (ataylab)")
print("  ✅ tuple ham mos keladi")


print("\n\n=== 4. Lug'at naqshlari ===")


def tahlil_lugat(x):
    match x:
        case {"turi": "doira", "radius": r}:
            return f"Doira: r={r}, yuza={3.14159 * r**2:.2f}"
        case {"turi": "to'rtburchak", "en": e, "bo'y": b}:
            return f"To'rtburchak: {e}×{b}, yuza={e * b}"
        case {"turi": turi}:
            return f"Noma'lum shakl: {turi}"
        case {}:
            return "Bo'sh yoki 'turi' yo'q"
        case _:
            return "Lug'at emas"


NAMUNALAR = [
    {"turi": "doira", "radius": 5},
    {"turi": "doira", "radius": 5, "rang": "qizil"},      # ortiqcha kalit
    {"turi": "to'rtburchak", "en": 3, "bo'y": 4},
    {"turi": "uchburchak"},
    {},
    [1, 2],
]

for x in NAMUNALAR:
    print(f"  {str(x)[:38]:<40} → {tahlil_lugat(x)}")

print("\n  ⭐ Lug'at naqshi — QISMAN moslik (ortiqcha kalitlar e'tiborsiz)")


print("\n\n=== 5. Sinf naqshlari ===")


@dataclass
class Nuqta:
    x: float
    y: float


@dataclass
class Doira:
    markaz: Nuqta
    radius: float


def tahlil_sinf(shakl):
    match shakl:
        case Nuqta(x=0, y=0):
            return "Koordinata boshi"
        case Nuqta(x=0, y=y):
            return f"Y o'qida: y={y}"
        case Nuqta(x=x, y=0):
            return f"X o'qida: x={x}"
        case Nuqta(x=x, y=y) if x == y:
            return f"Diagonalda: ({x}, {y})"
        case Nuqta(x, y):                       # pozitsion
            return f"Nuqta: ({x}, {y})"
        case Doira(markaz=Nuqta(0, 0), radius=r):
            return f"Markazda joylashgan doira: r={r}"
        case Doira(markaz=m, radius=r):
            return f"Doira: markaz={m}, r={r}"
        case _:
            return "Noma'lum shakl"


for shakl in [
    Nuqta(0, 0), Nuqta(0, 5), Nuqta(3, 0), Nuqta(2, 2), Nuqta(1, 7),
    Doira(Nuqta(0, 0), 10), Doira(Nuqta(1, 1), 5), "boshqa",
]:
    print(f"  {str(shakl):<32} → {tahlil_sinf(shakl)}")


print("\n\n=== 6. Tur naqshlari ===")


def tur_tahlil(x):
    match x:
        case int(n) if n < 0:
            return f"Manfiy butun: {n}"
        case int(n):
            return f"Musbat butun: {n}"
        case float(f):
            return f"Kasr: {f}"
        case str(s) if s.isdecimal():
            return f"Sonli satr: {s}"
        case str(s):
            return f"Satr ({len(s)} belgi)"
        case list() | tuple() as ketma:
            return f"Ketma-ketlik ({len(ketma)} element)"
        case dict() as d:
            return f"Lug'at ({len(d)} kalit)"
        case None:
            return "None"
        case _:
            return f"Boshqa: {type(x).__name__}"


for x in [-5, 42, 3.14, "123", "salom", [1, 2], (1, 2), {"a": 1}, None, set()]:
    print(f"  {x!r:<12} → {tur_tahlil(x)}")


print("\n\n=== 7. as naqshi ===")


def as_naqsh(x):
    match x:
        case {"turi": "user", "id": int(uid)} as malumot:
            return f"Foydalanuvchi #{uid}, to'liq: {malumot}"
        case [Nuqta(0, 0) as boshi, *qolgani]:
            return f"Boshi {boshi}, yana {len(qolgani)} nuqta"
        case _:
            return "Mos kelmadi"


print(f"  {as_naqsh({'turi': 'user', 'id': 42})}")
print(f"  {as_naqsh([Nuqta(0, 0), Nuqta(1, 1), Nuqta(2, 2)])}")

Natijaning muhim qismi:

text
=== 3. Ketma-ketlik naqshlari ===
  []               → bo'sh
  [1]              → bitta: 1
  [1, 2]           → ikkita: 1, 2
  [1, 2, 3]        → uchta: 1, 2, 3
  [1, 2, 3, 4, 5]  → 1 ... 5 (3 o'rtada)
  (1, 2)           → ikkita: 1, 2
  'abc'            → ketma-ketlik emas
  42               → ketma-ketlik emas
  {'a': 1}         → ketma-ketlik emas

=== 4. Lug'at naqshlari ===
  {'turi': 'doira', 'radius': 5}           → Doira: r=5, yuza=78.54
  {'turi': 'doira', 'radius': 5, 'rang'...  → Doira: r=5, yuza=78.54
  ⭐ Lug'at naqshi — QISMAN moslik

Nima ko'rsatdi: 2.2, 2.4, 2.5-bo'limlar.

Misol 2 — Nom bog'lash tuzog'i

python
"""match ning eng katta tuzog'i."""

from enum import Enum

print("=== 1. ❌ Muammo ===")

QIYMAT = 42
x = 100

print(f"  QIYMAT = {QIYMAT}, x = {x}\n")

# ⚠️ Agar "case QIYMAT:" dan keyin yana naqsh bo'lsa, Python buni
#    KOMPILYATSIYADA ushlaydi — butun fayl ishga tushmaydi:
KOD = """
match x:
    case QIYMAT:
        pass
    case _:
        pass
"""
try:
    compile(KOD, "<misol>", "exec")
except SyntaxError as e:
    print(f"  Keyin case _ bo'lsa → ❌ SyntaxError: {e.msg}\n")

# ⚠️ Lekin u OXIRGI naqsh bo'lsa — hech qanday ogohlantirish yo'q:
match x:
    case QIYMAT:
        print(f"  case QIYMAT: BAJARILDI (kutilmagan!)")

print(f"\n  QIYMAT endi = {QIYMAT}  ← ❌ QAYTA YOZILDI!")

print("""
  Sabab: naqshda ODDIY NOM — bu BOG'LASH naqshi.
  U har narsaga mos keladi va nomga qiymat bog'laydi.

  `case QIYMAT:` = "x ni QIYMAT nomiga bog'la"
  emas           = "x QIYMAT ga tengmi"
""")


print("=== 2. ✅ Yechim 1: nuqtali nom ===")


class Doimiylar:
    QIYMAT = 42
    BOSHQA = 100


QIYMAT = 42                     # qayta tiklash

for x in [42, 100, 7]:
    match x:
        case Doimiylar.QIYMAT:
            natija = "QIYMAT (42) bilan mos"
        case Doimiylar.BOSHQA:
            natija = "BOSHQA (100) bilan mos"
        case _:
            natija = "mos kelmadi"
    print(f"  x={x:>4} → {natija}")


print("\n\n=== 3. ✅ Yechim 2: Enum (eng yaxshi) ===")


class Holat(Enum):
    FAOL = "faol"
    NOFAOL = "nofaol"
    BLOKLANGAN = "bloklangan"


def holat_matni(h):
    match h:
        case Holat.FAOL:
            return "✅ Faol"
        case Holat.NOFAOL:
            return "⏸️  Nofaol"
        case Holat.BLOKLANGAN:
            return "🔴 Bloklangan"
        case _:
            return "❓ Noma'lum"


for h in [Holat.FAOL, Holat.NOFAOL, Holat.BLOKLANGAN, "boshqa"]:
    print(f"  {str(h):<24} → {holat_matni(h)}")

print("\n  ⭐ Enum — nuqta bor, shuning uchun qiymat solishtiruvi")


print("\n\n=== 4. ✅ Yechim 3: qo'riqchi shart ===")

QIYMAT = 42

for x in [42, 100]:
    match x:
        case y if y == QIYMAT:
            natija = f"QIYMAT bilan mos"
        case _:
            natija = "mos kelmadi"
    print(f"  x={x:>4} → {natija}")

print("\n  ⚠️ Ishlaydi, lekin chirkin — Enum yaxshiroq")


print("\n\n=== 5. ⚠️ Bir naqshda takroriy nom ===")

print("""
  ❌ SyntaxError:
       match nuqta:
           case [x, x]:            # bir xil nom ikki marta
               print("Bir xil")

  ✅ Qo'riqchi shart bilan:
       match nuqta:
           case [a, b] if a == b:
               print("Bir xil")
""")


def bir_xilmi(nuqta):
    match nuqta:
        case [a, b] if a == b:
            return "Bir xil"
        case [a, b]:
            return f"Farqli: {a} != {b}"
        case _:
            return "Juftlik emas"


for n in [[1, 1], [1, 2], [5]]:
    print(f"  {n!r:<10} → {bir_xilmi(n)}")


print("\n\n=== 6. ⚠️ | bilan bog'lash ===")

print("""
  ✅ Har ikkala tarmoqda bir xil nomlar:
       case [1, y] | [2, y]:
           print(y)

  ❌ SyntaxError — nomlar mos kelmaydi:
       case [1, y] | [2]:
           ...
""")


def yoki_bilan(x):
    match x:
        case [1, y] | [2, y]:
            return f"Birinchi 1 yoki 2, ikkinchi: {y}"
        case [a, b]:
            return f"Boshqa juftlik: {a}, {b}"
        case _:
            return "Juftlik emas"


for x in [[1, 5], [2, 7], [3, 9]]:
    print(f"  {x!r:<10} → {yoki_bilan(x)}")


print("\n\n=== 7. `_` — maxsus joker ===")

print("""
  `_` — bog'lamaydi, faqat mos keladi:

     case _:              ✅ joker
     case [_, _]:         ✅ ikki elementli, qiymatlar kerak emas
     case {"a": _}:       ✅ "a" kaliti bor
     case [x, _, y]:      ✅ o'rtadagi kerak emas
""")


def joker(x):
    match x:
        case [_, _, _]:
            return "aynan uch element"
        case [_, _]:
            return "aynan ikki element"
        case [_]:
            return "bitta element"
        case _:
            return "boshqa"


for x in [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]:
    print(f"  {x!r:<14} → {joker(x)}")

Natijaning muhim qismi:

text
=== 1. ❌ Muammo ===
  QIYMAT = 42, x = 100

  case QIYMAT: BAJARILDI (kutilmagan!)

  QIYMAT endi = 100  ← ❌ QAYTA YOZILDI!

=== 3. ✅ Yechim 2: Enum (eng yaxshi) ===
  Holat.FAOL               → ✅ Faol
  Holat.NOFAOL             → ⏸️  Nofaol
  Holat.BLOKLANGAN         → 🔴 Bloklangan
  boshqa                   → ❓ Noma'lum

  ⭐ Enum — nuqta bor, shuning uchun qiymat solishtiruvi

Nima ko'rsatdi: 2.3-bo'lim.

Misol 3 — Amaliy qo'llanishlar

python
"""match/case real vazifalarda."""

from dataclasses import dataclass
from enum import Enum

print("=== 1. HTTP javobini qayta ishlash ===")


class XatoTuri(Exception):
    pass


def javobni_ishla(javob: dict):
    match javob:
        case {"status": 200, "data": data}:
            return f"✅ Ma'lumot: {data}"

        case {"status": 201, "id": id}:
            return f"✅ Yaratildi: #{id}"

        case {"status": 204}:
            return "✅ Bajarildi (mazmun yo'q)"

        case {"status": 400 | 422, "errors": errors}:
            return f"❌ Tekshiruv xatosi: {errors}"

        case {"status": 401}:
            return "❌ Autentifikatsiya kerak"

        case {"status": 403}:
            return "❌ Ruxsat yo'q"

        case {"status": 404, "resource": res}:
            return f"❌ Topilmadi: {res}"

        case {"status": int(kod), "message": msg} if kod >= 500:
            return f"🔴 Server xatosi {kod}: {msg}"

        case {"status": int(kod)} if kod >= 500:
            return f"🔴 Server xatosi {kod}"

        case {"status": int(kod)}:
            return f"❓ Noma'lum status: {kod}"

        case _:
            return "❌ Noto'g'ri javob formati"


JAVOBLAR = [
    {"status": 200, "data": [1, 2, 3]},
    {"status": 201, "id": 42},
    {"status": 204},
    {"status": 400, "errors": {"ism": "majburiy"}},
    {"status": 401},
    {"status": 404, "resource": "/users/999"},
    {"status": 500, "message": "Ichki xato"},
    {"status": 503},
    {"status": 999},
    {"noma'lum": "format"},
]

for javob in JAVOBLAR:
    print(f"  {str(javob)[:42]:<44} → {javobni_ishla(javob)}")


print("\n\n=== 2. Buyruq satri argumentlari ===")


def buyruqni_ishla(argv: list[str]) -> str:
    match argv:
        case []:
            return "Yordam ko'rsatiladi"

        case ["--help" | "-h"]:
            return "Yordam"

        case ["--version" | "-v"]:
            return "Versiya 1.0.0"

        case ["run", fayl]:
            return f"Ishga tushirish: {fayl}"

        case ["run", fayl, *bayroqlar]:
            return f"Ishga tushirish: {fayl}, bayroqlar: {bayroqlar}"

        case ["test", *_] if "--verbose" in argv:
            return "Test (batafsil rejim)"

        case ["test", *fayllar]:
            return f"Test: {fayllar or 'barcha'}"

        case [buyruq, *_]:
            return f"❌ Noma'lum buyruq: {buyruq}"


ARGUMENTLAR = [
    [],
    ["--help"],
    ["-v"],
    ["run", "main.py"],
    ["run", "main.py", "--debug", "--port=8000"],
    ["test"],
    ["test", "test_a.py", "test_b.py"],
    ["test", "--verbose"],
    ["nomalum"],
]

for argv in ARGUMENTLAR:
    print(f"  {str(argv)[:40]:<42} → {buyruqni_ishla(argv)}")


print("\n\n=== 3. Hodisalarni qayta ishlash ===")


def hodisani_ishla(hodisa: dict) -> str:
    match hodisa:
        case {"turi": "bosish", "tugma": "chap", "x": x, "y": y}:
            return f"👆 Chap bosish: ({x}, {y})"

        case {"turi": "bosish", "tugma": "ong", "x": x, "y": y}:
            return f"👉 O'ng bosish: ({x}, {y})"

        case {"turi": "bosish", "tugma": tugma}:
            return f"❓ Noma'lum tugma: {tugma}"

        case {"turi": "klaviatura", "kod": kod, "shift": True}:
            return f"⌨️  Shift + {kod}"

        case {"turi": "klaviatura", "kod": kod, "ctrl": True}:
            return f"⌨️  Ctrl + {kod}"

        case {"turi": "klaviatura", "kod": kod}:
            return f"⌨️  {kod}"

        case {"turi": "aylantirish", "yonalish": "yuqori", "miqdor": m}:
            return f"⬆️  Yuqoriga: {m}"

        case {"turi": "aylantirish", "yonalish": "past", "miqdor": m}:
            return f"⬇️  Pastga: {m}"

        case {"turi": turi}:
            return f"❓ Noma'lum hodisa: {turi}"

        case _:
            return "❌ Noto'g'ri format"


HODISALAR = [
    {"turi": "bosish", "tugma": "chap", "x": 100, "y": 200},
    {"turi": "bosish", "tugma": "ong", "x": 50, "y": 75},
    {"turi": "klaviatura", "kod": "A", "shift": True},
    {"turi": "klaviatura", "kod": "C", "ctrl": True},
    {"turi": "klaviatura", "kod": "x"},
    {"turi": "aylantirish", "yonalish": "yuqori", "miqdor": 3},
    {"turi": "nomalum"},
]

for h in HODISALAR:
    print(f"  {str(h)[:48]:<50} → {hodisani_ishla(h)}")


print("\n\n=== 4. Rekursiv tuzilma — ifoda daraxti ===")


@dataclass
class Son:
    qiymat: float


@dataclass
class Amal:
    chap: "Son | Amal"
    operator: str
    ong: "Son | Amal"


def hisobla(ifoda) -> float:
    match ifoda:
        case Son(qiymat=q):
            return q
        case Amal(chap=c, operator="+", ong=o):
            return hisobla(c) + hisobla(o)
        case Amal(chap=c, operator="-", ong=o):
            return hisobla(c) - hisobla(o)
        case Amal(chap=c, operator="*", ong=o):
            return hisobla(c) * hisobla(o)
        case Amal(chap=c, operator="/", ong=o):
            bolvchi = hisobla(o)
            if bolvchi == 0:
                raise ZeroDivisionError("Nolga bo'lish")
            return hisobla(c) / bolvchi
        case _:
            raise ValueError(f"Noma'lum ifoda: {ifoda}")


def korsat(ifoda) -> str:
    match ifoda:
        case Son(qiymat=q):
            return str(q)
        case Amal(chap=c, operator=op, ong=o):
            return f"({korsat(c)} {op} {korsat(o)})"
        case _:
            return "?"


# (2 + 3) * (10 - 4)
IFODA = Amal(
    Amal(Son(2), "+", Son(3)),
    "*",
    Amal(Son(10), "-", Son(4)),
)

print(f"  Ifoda:  {korsat(IFODA)}")
print(f"  Natija: {hisobla(IFODA)}")

# Ichma-ich
IFODA2 = Amal(
    Amal(Son(100), "/", Son(4)),
    "+",
    Amal(Amal(Son(2), "*", Son(3)), "-", Son(1)),
)
print(f"\n  Ifoda:  {korsat(IFODA2)}")
print(f"  Natija: {hisobla(IFODA2)}")


print("\n\n=== 5. Ma'lumot tekshiruvi ===")


def tekshir(malumot) -> str:
    match malumot:
        case {"ism": str(ism), "yosh": int(yosh), "email": str(email)} \
                if 0 < yosh < 150 and "@" in email:
            return f"✅ {ism}, {yosh} yosh, {email}"

        case {"ism": str(), "yosh": int(yosh)} if not 0 < yosh < 150:
            return f"❌ Yosh noto'g'ri: {yosh}"

        case {"ism": str(), "yosh": int(), "email": str(email)}:
            return f"❌ Email noto'g'ri: {email}"

        case {"ism": str(), "yosh": _}:
            return "❌ Yosh butun son bo'lishi kerak"

        case {"ism": _}:
            return "❌ Ism satr bo'lishi kerak"

        case dict():
            return "❌ 'ism' maydoni yetishmaydi"

        case _:
            return "❌ Lug'at kutilgan edi"


MALUMOTLAR = [
    {"ism": "Ali", "yosh": 25, "email": "ali@example.com"},
    {"ism": "Vali", "yosh": 200, "email": "vali@example.com"},
    {"ism": "Guli", "yosh": 30, "email": "notogri"},
    {"ism": "Sardor", "yosh": "25"},
    {"ism": 42, "yosh": 30},
    {"yosh": 25},
    [1, 2, 3],
]

for m in MALUMOTLAR:
    print(f"  {str(m)[:44]:<46} → {tekshir(m)}")

Natijaning muhim qismi:

text
=== 2. Buyruq satri argumentlari ===
  []                                         → Yordam ko'rsatiladi
  ['--help']                                 → Yordam
  ['-v']                                     → Versiya 1.0.0
  ['run', 'main.py']                         → Ishga tushirish: main.py
  ['run', 'main.py', '--debug', '--port=80   → Ishga tushirish: main.py, bayroqlar: ['--debug', '--port=8000']
  ['test']                                   → Test: barcha
  ['test', 'test_a.py', 'test_b.py']         → Test: ['test_a.py', 'test_b.py']
  ['test', '--verbose']                      → Test (batafsil rejim)

=== 4. Rekursiv tuzilma — ifoda daraxti ===
  Ifoda:  ((2 + 3) * (10 - 4))
  Natija: 30

  Ifoda:  ((100 / 4) + ((2 * 3) - 1))
  Natija: 30.0

Nima ko'rsatdi: 2.9-bo'lim.

Misol 4 — Qachon match, qachon boshqa narsa

python
"""match/case ni to'g'ri tanlash."""

import time
from enum import Enum

print("=== 1. ❌ match ORTIQCHA — oddiy qiymat ===")


def rang_match(rang: str) -> str:
    match rang:
        case "qizil":
            return "#FF0000"
        case "yashil":
            return "#00FF00"
        case "ko'k":
            return "#0000FF"
        case _:
            return "#000000"


RANGLAR = {"qizil": "#FF0000", "yashil": "#00FF00", "ko'k": "#0000FF"}


def rang_lugat(rang: str) -> str:
    return RANGLAR.get(rang, "#000000")


for r in ["qizil", "yashil", "binafsha"]:
    m, l = rang_match(r), rang_lugat(r)
    assert m == l
    print(f"  {r:<12} match={m}  lugat={l}")

print("\n  ✅ Lug'at — tezroq, ma'lumot koddan ajratilgan")


print("\n\n=== 2. ❌ match ORTIQCHA — diapazonlar ===")


def baho_match(ball: int) -> str:
    match ball:
        case b if b >= 90:
            return "A"
        case b if b >= 80:
            return "B"
        case b if b >= 70:
            return "C"
        case _:
            return "D"


def baho_if(ball: int) -> str:
    if ball >= 90:
        return "A"
    if ball >= 80:
        return "B"
    if ball >= 70:
        return "C"
    return "D"


for b in [95, 85, 75, 65]:
    m, i = baho_match(b), baho_if(b)
    assert m == i
    print(f"  {b:>4} match={m}  if={i}")

print("\n  ✅ if/elif — aniqroq, `case b if` chirkin")


print("\n\n=== 3. ✅ match KERAK — tuzilmani ochish ===")

print("""
  match bilan — bitta konstruksiya:

      match javob:
          case {"holat": "ok", "malumot": [birinchi, *qolgani]}:
              ...

  if bilan — bir necha tekshiruv:

      if (isinstance(javob, dict)
              and javob.get("holat") == "ok"
              and isinstance(javob.get("malumot"), list)
              and len(javob["malumot"]) >= 1):
          birinchi = javob["malumot"][0]
          qolgani = javob["malumot"][1:]
""")


def ishla_match(javob):
    match javob:
        case {"holat": "ok", "malumot": [birinchi, *qolgani]}:
            return f"✅ Birinchi: {birinchi}, yana {len(qolgani)} ta"
        case {"holat": "ok", "malumot": []}:
            return "✅ Bo'sh"
        case {"holat": "xato", "xabar": xabar}:
            return f"❌ {xabar}"
        case _:
            return "❓ Noma'lum"


def ishla_if(javob):
    if not isinstance(javob, dict):
        return "❓ Noma'lum"
    holat = javob.get("holat")
    if holat == "ok":
        malumot = javob.get("malumot")
        if isinstance(malumot, list):
            if not malumot:
                return "✅ Bo'sh"
            return f"✅ Birinchi: {malumot[0]}, yana {len(malumot) - 1} ta"
    elif holat == "xato":
        xabar = javob.get("xabar")
        if xabar is not None:
            return f"❌ {xabar}"
    return "❓ Noma'lum"


JAVOBLAR = [
    {"holat": "ok", "malumot": [1, 2, 3]},
    {"holat": "ok", "malumot": []},
    {"holat": "xato", "xabar": "Ulanish yo'q"},
    {"noma'lum": True},
]

for j in JAVOBLAR:
    m, i = ishla_match(j), ishla_if(j)
    assert m == i, f"{m} != {i}"
    print(f"  {str(j)[:36]:<38} → {m}")

print("\n  ✅ match — ancha o'qiladigan")


print("\n\n=== 4. Tezlik ===")

N = 500_000


def match_bilan(x):
    match x:
        case 0: return "nol"
        case 1: return "bir"
        case 2: return "ikki"
        case _: return "boshqa"


def if_bilan(x):
    if x == 0: return "nol"
    if x == 1: return "bir"
    if x == 2: return "ikki"
    return "boshqa"


LUGAT = {0: "nol", 1: "bir", 2: "ikki"}


def lugat_bilan(x):
    return LUGAT.get(x, "boshqa")


natijalar = []
for nom, f in [("match", match_bilan), ("if/elif", if_bilan),
               ("lug'at", lugat_bilan)]:
    boshlandi = time.perf_counter()
    for i in range(N):
        f(i % 4)
    natijalar.append((nom, time.perf_counter() - boshlandi))

eng_tez = min(v for _, v in natijalar)
print(f"  {N:,} chaqiruv:\n")
print(f"  {'Usul':<12} {'Vaqt':>9} {'Nisbat':>8}")
print("  " + "─" * 32)
for nom, vaqt in sorted(natijalar, key=lambda x: x[1]):
    print(f"  {nom:<12} {vaqt * 1000:>6.1f} ms {vaqt / eng_tez:>7.2f}x")

print("""
  ⚠️ match — `switch` EMAS, jadval sakrash yaratmaydi.
     U ketma-ket tekshiradi, `if`/`elif` kabi.

  ⭐ match — tezlik uchun emas, O'QISH OSONLIGI uchun.
""")


print("=== 5. Qaror jadvali ===")

print(f"""
  {'Vaziyat':<36} {'Yechim'}
  {'─' * 62}
  {'Aniq qiymatlar (2-3 ta)':<36} if/elif
  {'Aniq qiymatlar (koʻp)':<36} ⭐ Lug'at
  {'Diapazonlar':<36} if/elif
  {'Ikki holat':<36} if/else
  {'Tuzilmani ochish':<36} ⭐ match
  {'Turli shakldagi maʻlumot':<36} ⭐ match
  {'Tur boʻyicha tarmoqlanish':<36} match yoki isinstance
  {'Rekursiv tuzilmalar':<36} ⭐ match
  {'AST/token qayta ishlash':<36} ⭐ match
""")


print("=== 6. Versiya mosligi ===")

import sys

print(f"  Joriy Python: {sys.version_info.major}.{sys.version_info.minor}")
print(f"  match/case:   3.10+ da mavjud")
print("""
  ⚠️ Eski versiyada SyntaxError — PARSE paytida!
     Shuning uchun shartli import ishlamaydi:

       if sys.version_info >= (3, 10):
           match x:          # ❌ 3.9 da SyntaxError
               case 1: ...

  ✅ Yechim — alohida modul:

       # match_yordamchi.py (faqat 3.10+ da import)
       # main.py:
       if sys.version_info >= (3, 10):
           from match_yordamchi import ishla
       else:
           from oddiy_yordamchi import ishla

  ✅ pyproject.toml:
       requires-python = ">=3.10"
       [tool.ruff] target-version = "py310"
""")

Natijaning muhim qismi:

text
=== 4. Tezlik ===
  500,000 chaqiruv:

  Usul              Vaqt   Nisbat
  ────────────────────────────────
  lug'at            42.1 ms    1.00x
  if/elif           58.3 ms    1.38x
  match             61.7 ms    1.47x

  ⚠️ match — `switch` EMAS, jadval sakrash yaratmaydi.
  ⭐ match — tezlik uchun emas, O'QISH OSONLIGI uchun.

Nima ko'rsatdi: 2.6, 2.7, 2.8-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"match — bu switch" Naqsh moslashtirish — ancha kuchliroq
"case QIYMAT: qiymat bilan solishtiradi" Bog'laydi! Nuqtali nom yoki Enum kerak
"match tezroq" if/elif bilan bir xil. Lug'at tezroq
"break kerak" Yo'q — fallthrough yo'q
"Satr ketma-ketlik naqshiga mos keladi" Ataylab yo'q
"Lug'at naqshi to'liq moslikni talab qiladi" Qisman — ortiqcha kalitlar e'tiborsiz
"Hech biri mos kelmasa xato" Hech narsa bajarilmaydi
"match har doim yaxshi" Oddiy qiymatlar uchun lug'at yaxshiroq

6. Keng tarqalgan xatolar va yechimlari

1. Nom bog'lash tuzog'i

python
QIYMAT = 42
match x:
    case QIYMAT:                # ❌ bog'laydi
        ...

case Doimiylar.QIYMAT:          # ✅
case Holat.FAOL:                # ✅ Enum
case y if y == QIYMAT:          # ✅

2. Takroriy nom

python
case [x, x]:                    # ❌ SyntaxError
case [a, b] if a == b:          # ✅

3. | bilan nomlar mos kelmasligi

python
case [1, y] | [2]:              # ❌ SyntaxError
case [1, y] | [2, y]:           # ✅

4. Satr ketma-ketlik deb kutish

python
match "ab":
    case [a, b]: ...            # ❌ mos kelmaydi
    case str(s): ...            # ✅

5. Lug'at to'liq moslik deb o'ylash

python
match {"a": 1, "b": 2}:
    case {"a": 1}: ...          # ✅ mos keladi (qisman)

case {"a": 1, **qolgani} if not qolgani: ...    # ✅ faqat "a"

6. Tartib noto'g'ri

python
match javob:
    case {"holat": h}: ...              # ❌ har doim mos keladi
    case {"holat": "ok", "data": d}: ...  # hech qachon yetib kelmaydi

case {"holat": "ok", "data": d}: ...    # ✅ aniqroq oldinda
case {"holat": h}: ...

7. Eski Python versiyasi

python
# Python 3.9 da SyntaxError — parse paytida
requires-python = ">=3.10"      # ✅ pyproject.toml

8. Oddiy holatda match

python
match x:                        # ⚠️ ortiqcha
    case True: ...
    case False: ...

if x: ...                       # ✅
else: ...

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 5.1-dars (o'tilgan): if/elif, lug'at bilan tarmoqlanish
  • 6-qism: ro'yxat, lug'at — naqsh manbalari
  • 8-qism: Enum, dataclass, __match_args__
  • 9-qism: istisnolarni turlar bo'yicha ajratish
  • 13-qism: tur ishoralari bilan birga
  • 10-qism: __match_args__ protokoli
  • 16-qism: JSON/API javoblarini qayta ishlash
  • 12-qism: parser, AST, token qayta ishlash

8. Eng yaxshi amaliyotlar

  1. Doimiylar uchun Enum ishlating. Oddiy nom naqshda bog'laydi, qiymat bilan solishtirmaydi.

  2. Aniqroq naqshni oldinga qo'ying. Umumiy naqsh keyingilarini soya qiladi.

  3. Oddiy qiymatlar uchun lug'at. match — tuzilmani ochish uchun.

  4. case _: ni qo'shing. Aks holda mos kelmaganda jimgina o'tib ketadi.

  5. Qo'riqchi shartni ishlating. case [x, y] if x == y — takroriy nom o'rniga.

  6. Satr uchun str() naqshi. Ketma-ketlik naqshiga mos kelmaydi.

  7. requires-python = ">=3.10" yozing. Eski versiyada SyntaxError.

  8. Rekursiv tuzilmalarda ishlating. AST, daraxtlar, ichma-ich JSON — match ning eng kuchli joyi.


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
QIYMAT = 5

# a
match 10:
    case QIYMAT: print("a")
    case _: print("b")
print(QIYMAT)

# b
match [1, 2, 3]:
    case [a, b]: print("ikki")
    case [a, b, c]: print("uch")
    case [a, *q]: print("ko'p")

# c
match {"a": 1, "b": 2}:
    case {"a": 1}: print("mos")
    case _: print("mos emas")

# d
match "ab":
    case [x, y]: print("ketma-ketlik")
    case str(): print("satr")
Javoblar

a. a va 10 — QIYMAT ga 10 bog'landi! b. uch — aniq uch elementli c. mos — lug'at qisman moslik d. satr — satr ketma-ketlik naqshiga mos kelmaydi

Vazifa 2: Xatolarni tuzatish

python
1.  MAX = 100
    match x:
        case MAX: print("maksimal")

2.  match nuqta:
        case [x, x]: print("bir xil")

3.  match javob:
        case {"holat": h}: ...
        case {"holat": "ok", "data": d}: ...

4.  match x:
        case [1, y] | [2]: print(y)
Javoblar
python
1.  class C: MAX = 100
    match x:
        case C.MAX: print("maksimal")

2.  match nuqta:
        case [a, b] if a == b: print("bir xil")

3.  match javob:
        case {"holat": "ok", "data": d}: ...    # aniqroq oldinda
        case {"holat": h}: ...

4.  match x:
        case [1, y] | [2, y]: print(y)

Vazifa 3: Shakl kalkulyatori

match bilan yozing:

python
@dataclass
class Doira: radius: float

@dataclass
class Tortburchak: en: float; boy: float

@dataclass
class Uchburchak: a: float; b: float; c: float

Funksiyalar: yuza(shakl), perimetr(shakl), tavsif(shakl).

Qo'shing: Kvadrat (Tortburchak bo'lib en == boy).

Vazifa 4: JSON tahlilchisi

Turli shakldagi JSON javoblarni qayta ishlaydigan funksiya yozing:

python
{"type": "user", "id": 1, "name": "Ali"}
{"type": "list", "items": [...], "total": 100}
{"type": "error", "code": 404, "message": "..."}
{"type": "paginated", "items": [...], "page": 1, "next": "..."}

Vazifa 5: Kalkulyator

match bilan oddiy kalkulyator yozing:

python
hisobla(["2", "+", "3"])            # 5
hisobla(["10", "/", "0"])           # ZeroDivisionError
hisobla(["sqrt", "16"])             # 4.0
hisobla(["max", "1", "5", "3"])     # 5

Vazifa 6: Buyruq satri

3-misoldagi buyruqni_ishla ni kengaytiring:

  1. --output FAYL bayrog'i
  2. -o FAYL qisqa shakli
  3. Bir necha bayroq
  4. -- dan keyin — pozitsion argumentlar

Vazifa 7: O'ylash

Nega case QIYMAT: qiymat bilan solishtirmaydi?

Javob

Chunki match — naqsh moslashtirish, switch emas.

Naqsh moslashtirishning asosiy g'oyasi — tuzilmani ochish:

python
case Nuqta(x, y):               # x va y ni BOG'LAYDI
case [birinchi, *qolgani]:      # bog'laydi
case {"ism": ism}:              # bog'laydi

Bu tillarda (Haskell, Rust, Scala) oddiy nom har doim bog'lash. Bu — izchil qoida.

Agar case QIYMAT: qiymat solishtiruvi bo'lganida:

python
case Nuqta(x, y):               # x, y — qiymat solishtiruvi?
                                # yoki bog'lash?

Qoida noaniq bo'lardi: qaysi nom bog'laydi, qaysi biri solishtiradi?

Yechim — sintaktik farq:

text
Oddiy nom      →  BOG'LASH        (x, y, natija)
Nuqtali nom    →  SOLISHTIRISH    (Modul.QIYMAT, Enum.A)
Literal        →  SOLISHTIRISH    (42, "matn", None)

Bu — aniq va izchil.

PEP 634 mualliflari buni muhokama qilishgan va nuqtali nom talabini ataylab qo'yishgan. Muqobil variantlar (masalan, case ==QIYMAT:) rad etilgan — chunki ular yangi sintaksis talab qilardi.

Amaliy xulosa: doimiylarni Enum da saqlang. U:

  • Nuqtali nom beradi (Holat.FAOL)
  • Tur xavfsizligini beradi
  • IDE avtomatik to'ldirishi ishlaydi
  • Xato yozuvda AttributeError beradi

Nimani mustahkamlaydi: 2.2, 2.3, 2.5, 2.6-bo'limlar.


Xulosa

Bu darsda match/case ni o'rgandik.

Eng muhim uch fikr:

  1. match — switch emas, naqsh moslashtirish. U tuzilmani ochadi, turni tekshiradi va qiymatlarni bog'laydi — bularning hammasi bitta konstruksiyada.

  2. case QIYMAT: — bu bog'lash, solishtirish emas. Bu — eng katta tuzoq. Doimiylar uchun Enum yoki nuqtali nom ishlating.

  3. match — tezlik uchun emas, o'qish osonligi uchun. Oddiy qiymat solishtiruvi uchun lug'at tezroq. match — turli shakldagi ma'lumot, rekursiv tuzilmalar va tuzilmani ochish uchun.


5-QISM YAKUNLANDI

O'n ikki darsni tugatdingiz:

Dars Nima o'rgandingiz
5.1 if/elif/else, shartlar tartibi, switch o'rniga lug'at
5.2 Qo'riqchi shart, murakkablik, refaktoring
5.3 and/or/not, De Morgan, any/all
5.4 Uchlik operator, prioritet, muqobillar
5.5 while, cheksiz sikl, while True + break
5.6 for, iteratsiya protokoli, ochish
5.7 range — ro'yxat emas, O(1) in
5.8 enumerate — range(len()) o'rniga
5.9 zip, transpozitsiya, strict=True
5.10 break, continue, sikl else
5.11 Ichma-ich sikllar, O(n²) → O(n)
5.12 match/case — naqsh moslashtirish

BOSQICH 1 — POYDEVOR YAKUNLANDI

55 dars, 5 qism, ~24 000 qator.

Qism Darslar Nima o'rgandingiz
1. Kompyuter va dasturlash 8 Kompyuter qanday ishlaydi, Python nima va nega
2. Muhit va vositalar 9 O'rnatish, terminal, VS Code, xato o'qish
3. Asoslar 14 O'zgaruvchi, turlar, operatorlar, PEP 8
4. Satrlar chuqur 12 Metodlar, Unicode, kodlash, formatlash
5. Boshqaruv oqimi 12 Shartlar, sikllar, match/case

Endi siz:

  • Python o'rnatilgan, professional sozlangan ish maydoni bor
  • Xato xabarlarini o'qiy olasiz
  • Barcha asosiy tur va operatorni bilasiz
  • Matn bilan professional ishlay olasiz
  • Mantiq va sikllar bilan istalgan algoritmni ifodalay olasiz
  • Kodni PEP 8 ga mos va o'qiladigan yoza olasiz

Bu — poydevor. Undan keyingi hamma narsa shu ustiga quriladi.


Keyingi qadam: BOSQICH 2 — TIL USTASI (77 dars)

Qism Darslar Mavzu
6. Ma'lumot tuzilmalari 18 list, tuple, set, dict, generatorlar
7. Funksiyalar 14 *args, LEGB, lambda, rekursiya
8. OOP 20 Sinflar, meros, dunder metodlar, dataclass
9. Xatolar va istisnolar 8 try/except, raise, o'z istisnolaringiz
10. Ilg'or til imkoniyatlari 17 Iteratorlar, generatorlar, dekoratorlar, context manager, deskriptorlar

6-qismdan boshlab siz ma'lumotni tashkil qilishni o'rganasiz — bu dasturchilikning yuragi.

Tabriklaymiz — eng qiyin qism ortda!

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
5.12-dars: match / case (3.10+) — IlmHamroh