IlmHamroh
Python kursi/Satrlar chuqur3/12-dars22 daqiqa
Mundarija (24)

4.3-dars: Metodlar — qidirish va tekshirish

4-QISM — SATRLAR CHUQUR · 3-dars


1. Kirish va motivatsiya

Matnda nimadir topish — dasturchining kundalik ishi:

  • Fayl kengaytmasini tekshirish
  • Log qatoridan xato darajasini ajratish
  • Foydalanuvchi kiritmasini tasdiqlash
  • URL'dan domenni olish
  • Matnda kalit so'z izlash

Pythonda buning uchun ikki oila metod bor:

Qidirish — qayerda:

python
matn.find(x)        matn.rfind(x)       matn.index(x)
matn.rindex(x)      matn.count(x)       x in matn

Tekshirish — ha yoki yo'q:

python
matn.startswith(x)  matn.endswith(x)
matn.isdigit()      matn.isalpha()      matn.isalnum()
matn.isspace()      matn.isupper()      ...

Har birining o'z nozikligi bor:

python
print("abc".find("z"))          # -1
print("abc".index("z"))         # ❌ ValueError — nega farq?

print("²".isdigit())            # True!  — nega?
print("²".isdecimal())          # False
print("½".isnumeric())          # True

Bu darsda hammasini tartibga solamiz va qaysi birini qachon ishlatishni aniqlaymiz.


2. Nazariya — chuqur tushuntirish

2.1. in — eng oddiy tekshiruv

python
matn = "Python dasturlash"

print("Python" in matn)         # True
print("java" in matn)           # False
print("thon das" in matn)       # True — pastki satr
print("" in matn)               # True — bo'sh satr HAR DOIM bor
print("PYTHON" in matn)         # False — katta-kichik harf muhim

Katta-kichik harfsiz qidirish:

python
print("python" in matn.lower())         # True
print("PYTHON".lower() in matn.lower()) # True — ikkalasini ham

Ko'p qiymatni tekshirish:

python
kengaytmalar = (".jpg", ".png", ".gif")
fayl = "rasm.PNG"

print(fayl.lower().endswith(kengaytmalar))      # True — juftlik!

endswith va startswith juftlik qabul qiladi — bu juda qulay.

in — tezlik:

python
# Ichkarida Crochemore-Perrin algoritmi ishlatiladi
# Murakkablik: eng yomon holatda O(n+m), amalda juda tez

Ko'p matn ichida ko'p naqsh qidirish kerak bo'lsa — re (15-qism) yoki maxsus tuzilma kerak.

2.2. find va index — farq

python
matn = "Python dasturlash"

print(matn.find("dastur"))      # 7
print(matn.find("java"))        # -1     ← topilmasa

print(matn.index("dastur"))     # 7
# matn.index("java")            # ❌ ValueError: substring not found
Metod Topilmasa
find -1 qaytaradi
index ValueError ko'taradi

Qaysi birini qachon?

python
# Topilmaslik NORMAL holat → find
pozitsiya = matn.find("izlanayotgan")
if pozitsiya != -1:
    ...

# Topilmaslik XATO → index
pozitsiya = matn.index("majburiy_qism")     # yo'q bo'lsa — xato

# Faqat bor-yo'qligi kerak → in
if "dastur" in matn:
    ...

Klassik xato:

python
if matn.find("x"):              # ❌ -1 ham True, 0 ham False!
    ...

if matn.find("x") != -1:        # ✅
if "x" in matn:                 # ✅ eng yaxshi

find 0 qaytarsa (satr boshida topildi), if uni False deb qabul qiladi. Bu — jimgina xato.

2.3. rfind, rindex — oxiridan qidirish

python
yol = "/home/user/hujjatlar/hisobot.pdf"

print(yol.find("/"))            # 0   — birinchi
print(yol.rfind("/"))           # 21  — oxirgi

# Fayl nomini olish
print(yol[yol.rfind("/") + 1:])         # 'hisobot.pdf'

# Kengaytmani olish
print(yol[yol.rfind(".") + 1:])         # 'pdf'

Amaliy eslatma: fayl yo'llari uchun pathlib yaxshiroq (15-qism):

python
from pathlib import Path
print(Path(yol).name)      # 'hisobot.pdf'
print(Path(yol).suffix)    # '.pdf'
print(Path(yol).stem)      # 'hisobot'

rfind topilmasa ham -1:

python
print("abc".rfind("z"))         # -1

Amaliy misol — oxirgi so'z:

python
matn = "Bu bir necha so'zdan iborat gap"
print(matn[matn.rfind(" ") + 1:])       # 'gap'

# yoki soddaroq
print(matn.rsplit(maxsplit=1)[-1])      # 'gap'

2.4. Qidiruv oralig'i

Barcha qidiruv metodi boshi va oxiri argumentlarini qabul qiladi:

python
matn = "abcabcabc"

print(matn.find("abc"))         # 0
print(matn.find("abc", 1))      # 3   — 1-indeksdan boshlab
print(matn.find("abc", 4))      # 6
print(matn.find("abc", 1, 5))   # -1  — 1..5 oralig'ida to'liq yo'q
print(matn.count("abc"))        # 3
print(matn.count("abc", 3))     # 2

Bu — kesimdan tezroq:

python
# ❌ Yangi satr yaratadi
matn[5:].find("abc")

# ✅ Nusxa yo'q
matn.find("abc", 5)

Diqqat: natija asl satr indekslarida qaytadi:

python
matn = "abcabcabc"
print(matn.find("abc", 3))      # 3 — 0 emas!

Barcha uchrashuvni topish:

python
def barcha_pozitsiyalar(matn: str, qism: str) -> list[int]:
    """Barcha uchrashuv indekslarini qaytaradi."""
    natija = []
    boshi = 0
    while (p := matn.find(qism, boshi)) != -1:
        natija.append(p)
        boshi = p + 1           # 1 ta oldinga — ustma-ust uchrashuvlar uchun
    return natija


print(barcha_pozitsiyalar("abcabcabc", "abc"))      # [0, 3, 6]
print(barcha_pozitsiyalar("aaaa", "aa"))            # [0, 1, 2] — ustma-ust

boshi = p + len(qism) bo'lsa ustma-ust uchrashuvlar o'tkazib yuboriladi.

Morj operatori (:=) bu yerda juda qulay (3.12-dars).

2.5. count — sanash

python
matn = "abcabcabc"

print(matn.count("a"))          # 3
print(matn.count("abc"))        # 3
print(matn.count("z"))          # 0
print(matn.count(""))           # 10 — len + 1!

count ustma-ust uchrashuvlarni sanamaydi:

python
print("aaaa".count("aa"))       # 2 — 4 emas!

Sabab: count topilgan joydan keyin davom etadi:

text
aaaa
^^      1-uchrashuv (0-1)
  ^^    2-uchrashuv (2-3)

aa 1-2 va 2-3 pozitsiyalarida ham bor, lekin sanalmaydi.

Ustma-ust sanash:

python
def ustma_ust_sana(matn: str, qism: str) -> int:
    return sum(
        1 for i in range(len(matn) - len(qism) + 1)
        if matn[i:i + len(qism)] == qism
    )


print(ustma_ust_sana("aaaa", "aa"))     # 3

Amaliy foydalanish:

python
matn = """Birinchi qator
Ikkinchi qator
Uchinchi qator"""

print(matn.count("\n") + 1)             # 3 — qatorlar soni
print(len(matn.splitlines()))           # 3 — ishonchliroq

# So'zlar sonini taxminlash
print(matn.count(" ") + matn.count("\n") + 1)
print(len(matn.split()))                # aniqroq

2.6. startswith va endswith

python
fayl = "hisobot_2026.pdf"

print(fayl.startswith("hisobot"))       # True
print(fayl.endswith(".pdf"))            # True
print(fayl.endswith("PDF"))             # False — registr muhim

Juftlik bilan — ko'p variant:

python
rasmlar = (".jpg", ".jpeg", ".png", ".gif", ".webp")

for fayl in ["rasm.jpg", "hujjat.pdf", "logo.PNG"]:
    print(f"  {fayl:<14} → {fayl.lower().endswith(rasmlar)}")
text
  rasm.jpg       → True
  hujjat.pdf     → False
  logo.PNG       → True

Bu — or zanjiridan yaxshiroq:

python
# ❌ Uzun
if f.endswith(".jpg") or f.endswith(".png") or f.endswith(".gif"):

# ✅ Qisqa
if f.endswith((".jpg", ".png", ".gif")):

Ro'yxat emas, juftlik:

python
fayl.endswith([".jpg", ".png"])         # ❌ TypeError
fayl.endswith((".jpg", ".png"))         # ✅
fayl.endswith(tuple(kengaytmalar))      # ✅ ro'yxatdan

Oraliq bilan:

python
matn = "prefiks_asosiy_suffiks"
print(matn.startswith("asosiy", 8))     # True — 8-indeksdan
print(matn.endswith("asosiy", 0, 14))   # True — 0..14 oralig'ida

removeprefix / removesuffix bilan birga (Python 3.9+):

python
nom = "test_hisobot.py"

if nom.startswith("test_"):
    nom = nom.removeprefix("test_")
print(nom)                      # 'hisobot.py'

# Yoki to'g'ridan-to'g'ri (tekshiruv shart emas)
print("hisobot.py".removeprefix("test_"))   # 'hisobot.py' — o'zgarmadi

removeprefix prefiks bo'lmasa satrni o'zgartirmasdan qaytaradi.

2.7. is* oilasi — tekshirish metodlari

python
matn = "Salom123"

print(matn.isalpha())           # False — raqam bor
print(matn.isdigit())           # False — harf bor
print(matn.isalnum())           # True  — harf yoki raqam
print(matn.isspace())           # False
print(matn.isupper())           # False
print(matn.islower())           # False
print(matn.istitle())           # False
print(matn.isidentifier())      # True  — o'zgaruvchi nomi bo'la oladi
print(matn.isprintable())       # True
print(matn.isascii())           # True

Barchasi bo'sh satrda False:

python
print("".isalpha())             # False
print("".isdigit())             # False
print("".isspace())             # False
print("".isascii())             # True  ← ISTISNO!

Bu — juda ko'p xatoga sabab bo'ladi:

python
kirish = ""
if kirish.isdigit():            # False — to'g'ri ishlaydi
    son = int(kirish)

Bu holda to'g'ri. Lekin:

python
if not kirish.isalpha():
    print("Faqat harf kiriting")    # bo'sh satr ham shu yerga tushadi

Bo'sh satrni alohida tekshiring.

2.8. Raqam tekshiruvining uch turi

Bu — eng chalkashtiradigan qism.

python
namunalar = ["123", "١٢٣", "²", "½", "Ⅷ", "12.5", "-5", "1_000"]

print(f"{'Satr':<10} {'isdigit':>9} {'isdecimal':>11} {'isnumeric':>11}")
print("─" * 44)
for s in namunalar:
    print(f"{s!r:<10} {str(s.isdigit()):>9} "
          f"{str(s.isdecimal()):>11} {str(s.isnumeric()):>11}")
text
Satr         isdigit   isdecimal   isnumeric
────────────────────────────────────────────
'123'           True        True        True
'١٢٣'           True        True        True
'²'             True       False        True
'½'            False       False        True
'Ⅷ'            False       False        True
'12.5'         False       False       False
'-5'           False       False       False
'1_000'        False       False       False

Farqi:

Metod Nima qamrab oladi
isdecimal() Faqat o'nlik raqamlar (0-9 va boshqa tillardagi analoglari)
isdigit() Yuqoridagilar + yuqori/pastki indekslar (², ³)
isnumeric() Yuqoridagilar + kasrlar (½) va rim raqamlari (Ⅷ)

Qaysi birini ishlatish?

python
# int() ga aylantirish uchun → isdecimal (eng qat'iy)
if kirish.isdecimal():
    son = int(kirish)           # kafolatlangan ishlaydi

# ❌ isdigit yetarli emas
if "²".isdigit():               # True
    int("²")                    # ❌ ValueError!

Amaliy qoida:

int() ga aylantirishdan oldin isdecimal() ishlating. Yoki eng yaxshisi — try/except (EAFP, 3.8-dars).

Manfiy va kasr sonlar:

python
def son_mi(matn: str) -> bool:
    """Satr songa aylantirilishi mumkinmi."""
    try:
        float(matn)
        return True
    except ValueError:
        return False


for s in ["123", "-5", "12.5", "1e3", "abc", "", "1_000"]:
    print(f"  {s!r:<10} → {son_mi(s)}")
text
  '123'      → True
  '-5'       → True
  '12.5'     → True
  '1e3'      → True
  'abc'      → False
  ''         → False
  '1_000'    → True

float() _ ajratgichni ham qabul qiladi (3.3-dars).

2.9. Registr tekshiruvi

python
print("SALOM".isupper())        # True
print("Salom".isupper())        # False
print("salom".islower())        # True
print("Salom Dunyo".istitle())  # True
print("Salom dunyo".istitle())  # False

# Raqam va belgilar e'tiborsiz
print("SALOM123!".isupper())    # True
print("123".isupper())          # False — harf yo'q
print("123!".islower())         # False

Qoida: kamida bitta harf bo'lishi va barcha harf mos registrda bo'lishi kerak.

casefold — agressiv kichik harf:

python
print("STRASSE".lower())        # 'strasse'
print("STRASSE".casefold())     # 'strasse'

print("ß".lower())              # 'ß'    — o'zgarmadi
print("ß".casefold())           # 'ss'   — nemis ß → ss

casefold() — registrsiz solishtirish uchun to'g'ri usul:

python
# ✅ Xalqaro matn uchun
if a.casefold() == b.casefold():
    ...

# ⚠️ Faqat lotin uchun yetarli
if a.lower() == b.lower():
    ...

2.10. Boshqa foydali tekshiruvlar

isidentifier — Python nomi bo'la oladimi (3.2-dars):

python
print("ism".isidentifier())         # True
print("_ism".isidentifier())        # True
print("2ism".isidentifier())        # False
print("ism-2".isidentifier())       # False
print("class".isidentifier())       # True — lekin kalit so'z!

import keyword
def yaroqli_nom(s: str) -> bool:
    return s.isidentifier() and not keyword.iskeyword(s)

print(yaroqli_nom("class"))         # False
print(yaroqli_nom("sinf"))          # True

isprintable — chiqarish mumkinmi:

python
print("salom".isprintable())        # True
print("salom\n".isprintable())      # False — \n chiqarilmaydi
print("salom\t".isprintable())      # False
print("".isprintable())             # True  ← ISTISNO

isascii (Python 3.7+):

python
print("salom".isascii())            # True
print("салом".isascii())            # False
print("".isascii())                 # True

Foydali: fayl nomlari, URL, identifikatorlar tekshirishda.

Barcha is* metodlari jadvali:

Metod True bo'lsa
isalpha() Faqat harflar
isdecimal() Faqat o'nlik raqamlar
isdigit() Raqamlar + indekslar
isnumeric() Har qanday sonli belgi
isalnum() Harf yoki raqam
isspace() Faqat bo'shliq belgilari
isupper() Barcha harf katta
islower() Barcha harf kichik
istitle() Har So'z Bosh Harfda
isidentifier() Yaroqli Python nomi
isprintable() Chiqarish mumkin
isascii() Faqat ASCII belgilar

3. Tez ma'lumotnoma

Qidirish

python
x in matn                   bor-yo'qligi (eng oddiy)
matn.find(x)                indeks yoki -1
matn.rfind(x)               oxiridan
matn.index(x)               indeks yoki ValueError
matn.rindex(x)              oxiridan
matn.count(x)               nechta (ustma-ust EMAS)

# Barchasi oraliq qabul qiladi
matn.find(x, boshi, oxiri)

Tekshirish

python
matn.startswith(x)          x — satr yoki JUFTLIK
matn.endswith((".jpg", ".png"))
matn.removeprefix(x)        3.9+
matn.removesuffix(x)        3.9+

is* oilasi

text
isdecimal()   0-9 → int() uchun ISHONCHLI
isdigit()     + ² ³ → int() uchun YETARLI EMAS
isnumeric()   + ½ Ⅷ

isalpha() isalnum() isspace()
isupper() islower() istitle()
isidentifier() isprintable() isascii()

⚠️ Bo'sh satrda hammasi False (isascii dan tashqari)

Tuzoqlar

python
if matn.find(x):            ❌ 0 — False, -1 — True
if matn.find(x) != -1:      ✅
if x in matn:               ✅

"aaaa".count("aa")          → 2, 3 emas (ustma-ust yo'q)
"²".isdigit()               → True, lekin int("²") ❌
matn.endswith([".a"])       ❌ ro'yxat → juftlik

4. Batafsil misollar

Misol 1 — find va index farqi

python
"""Qidiruv metodlarining farqi."""

matn = "Python dasturlash tili"

print(f"Satr: {matn!r}\n")

print("=== find vs index (topilganda) ===")
print(f"  find('dastur')  → {matn.find('dastur')}")
print(f"  index('dastur') → {matn.index('dastur')}")

print("\n=== find vs index (topilmaganda) ===")
print(f"  find('java')    → {matn.find('java')}")
try:
    matn.index("java")
except ValueError as x:
    print(f"  index('java')   → ValueError: {x}")

print("\n=== ⚠️ if bilan tuzoq ===")
qism = "Python"
print(f"  matn.find({qism!r}) = {matn.find(qism)}")
print(f"  if matn.find({qism!r}):        → {bool(matn.find(qism))}  ❌ NOTO'G'RI")
print(f"  if matn.find({qism!r}) != -1:  → {matn.find(qism) != -1}  ✅")
print(f"  if {qism!r} in matn:           → {qism in matn}  ✅")

print("\n=== Oxiridan qidirish ===")
yol = "/home/user/hujjatlar/hisobot.pdf"
print(f"  Yo'l: {yol}")
print(f"  find('/')  → {yol.find('/')}   (birinchi)")
print(f"  rfind('/') → {yol.rfind('/')}  (oxirgi)")
print(f"  Fayl nomi:  {yol[yol.rfind('/') + 1:]!r}")
print(f"  Kengaytma:  {yol[yol.rfind('.') + 1:]!r}")

print("\n  pathlib bilan (tavsiya etiladi):")
from pathlib import Path
p = Path(yol)
print(f"    .name   → {p.name!r}")
print(f"    .stem   → {p.stem!r}")
print(f"    .suffix → {p.suffix!r}")
print(f"    .parent → {str(p.parent)!r}")

print("\n=== Oraliq bilan qidirish ===")
takror = "abcabcabc"
print(f"  Satr: {takror!r}")
for boshi in [0, 1, 4, 7]:
    print(f"    find('abc', {boshi}) → {takror.find('abc', boshi)}")

print("\n=== Barcha uchrashuvlar ===")


def barcha_pozitsiyalar(matn: str, qism: str) -> list[int]:
    natija = []
    boshi = 0
    while (p := matn.find(qism, boshi)) != -1:
        natija.append(p)
        boshi = p + 1
    return natija


print(f"  'abcabcabc' da 'abc' → {barcha_pozitsiyalar('abcabcabc', 'abc')}")
print(f"  'aaaa' da 'aa'       → {barcha_pozitsiyalar('aaaa', 'aa')}")
print(f"  count('aa')          → {'aaaa'.count('aa')}  ← ustma-ust sanamaydi")
text
Satr: 'Python dasturlash tili'

=== find vs index (topilganda) ===
  find('dastur')  → 7
  index('dastur') → 7

=== find vs index (topilmaganda) ===
  find('java')    → -1
  index('java')   → ValueError: substring not found

=== ⚠️ if bilan tuzoq ===
  matn.find('Python') = 0
  if matn.find('Python'):        → False  ❌ NOTO'G'RI
  if matn.find('Python') != -1:  → True  ✅
  if 'Python' in matn:           → True  ✅

=== Oxiridan qidirish ===
  Yo'l: /home/user/hujjatlar/hisobot.pdf
  find('/')  → 0   (birinchi)
  rfind('/') → 21  (oxirgi)
  Fayl nomi:  'hisobot.pdf'
  Kengaytma:  'pdf'

  pathlib bilan (tavsiya etiladi):
    .name   → 'hisobot.pdf'
    .stem   → 'hisobot'
    .suffix → '.pdf'
    .parent → '/home/user/hujjatlar'

=== Barcha uchrashuvlar ===
  'abcabcabc' da 'abc' → [0, 3, 6]
  'aaaa' da 'aa'       → [0, 1, 2]
  count('aa')          → 2  ← ustma-ust sanamaydi

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

Misol 2 — Raqam tekshiruvining uch turi

python
"""isdecimal, isdigit, isnumeric — farq va oqibatlar."""

namunalar = [
    ("123",     "oddiy raqamlar"),
    ("٠١٢٣",    "arab-hind raqamlari"),
    ("0123",  "to'liq kenglikdagi raqamlar"),
    ("²",       "yuqori indeks"),
    ("³",       "yuqori indeks"),
    ("½",       "kasr belgisi"),
    ("¾",       "kasr belgisi"),
    ("Ⅷ",       "rim raqami"),
    ("一二三",   "xitoy raqamlari"),
    ("12.5",    "kasr son"),
    ("-5",      "manfiy"),
    ("1_000",   "ajratgich bilan"),
    ("",        "bo'sh"),
    ("abc",     "harflar"),
]

print(f"{'Satr':<10} {'decimal':>8} {'digit':>7} {'numeric':>8}  "
      f"{'int()':>10}  Izoh")
print("─" * 68)

for s, izoh in namunalar:
    try:
        natija = repr(int(s))
    except ValueError:
        natija = "❌"

    print(f"{s!r:<10} "
          f"{str(s.isdecimal()):>8} "
          f"{str(s.isdigit()):>7} "
          f"{str(s.isnumeric()):>8}  "
          f"{natija:>10}  {izoh}")

print("\n=== ⚠️ TUZOQ: isdigit int() ni kafolatlamaydi ===")
xavfli = "²"
print(f"  {xavfli!r}.isdigit() → {xavfli.isdigit()}")
try:
    int(xavfli)
except ValueError as x:
    print(f"  int({xavfli!r})       → ValueError: {x}")

print("\n=== ✅ isdecimal kafolatlaydi ===")
for s in ["123", "٠١٢٣", "0123"]:
    print(f"  {s!r}.isdecimal() = {s.isdecimal()},  int() = {int(s)}")

print("\n=== ✅ Eng ishonchli: try/except ===")


def songa(matn: str, sukut=None):
    """Har qanday sonli satrni songa aylantiradi."""
    matn = matn.strip()
    try:
        return int(matn)
    except ValueError:
        pass
    try:
        return float(matn.replace(",", "."))
    except ValueError:
        return sukut


sinovlar = ["123", "12.5", "-5", "1_000", "1,5", "²", "½", "abc", ""]
for s in sinovlar:
    print(f"  songa({s!r:<8}) → {songa(s)!r}")

print("\n=== Unicode qiymatini olish ===")
import unicodedata
for s in ["²", "½", "Ⅷ", "٣"]:
    qiymat = unicodedata.numeric(s, None)
    ism = unicodedata.name(s)
    print(f"  {s}  qiymati={qiymat}  {ism}")

Natijaning muhim qismi:

text
Satr        decimal   digit  numeric       int()  Izoh
────────────────────────────────────────────────────────────────────
'123'          True    True     True         123  oddiy raqamlar
'٠١٢٣'         True    True     True         123  arab-hind raqamlari
'0123'        True    True     True         123  to'liq kenglikdagi
'²'           False    True     True           ❌  yuqori indeks
'½'           False   False     True           ❌  kasr belgisi
'Ⅷ'           False   False     True           ❌  rim raqami
'一二三'        False   False     True           ❌  xitoy raqamlari
'12.5'        False   False    False           ❌  kasr son
'-5'          False   False    False          -5  manfiy
'1_000'       False   False    False        1000  ajratgich bilan

=== Unicode qiymatini olish ===
  ²  qiymati=2.0  SUPERSCRIPT TWO
  ½  qiymati=0.5  VULGAR FRACTION ONE HALF
  Ⅷ  qiymati=8.0  ROMAN NUMERAL EIGHT
  ٣  qiymati=3.0  ARABIC-INDIC DIGIT THREE

Diqqat: '-5' va '1_000' uchun int() ishlaydi, lekin hech qanday is* True bermaydi. Bu — try/except nima uchun eng ishonchli ekanini ko'rsatadi.

Nima ko'rsatdi: 2.8-bo'lim.

Misol 3 — Fayl nomlarini filtrlash

python
"""startswith/endswith bilan amaliy filtrlash."""

FAYLLAR = [
    "hisobot_2026.pdf", "rasm.JPG", "test_asoslar.py", "malumot.csv",
    "logo.png", "test_satrlar.py", "hujjat.docx", "arxiv.tar.gz",
    ".gitignore", "README.md", "video.mp4", "_ichki.py",
    "skript.PY", "malumot.CSV", "rasm.jpeg",
]

RASM_KENGAYTMALARI = (".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg")
HUJJAT_KENGAYTMALARI = (".pdf", ".docx", ".doc", ".txt", ".md")
MALUMOT_KENGAYTMALARI = (".csv", ".json", ".xml", ".xlsx")


def turi(fayl: str) -> str:
    """Fayl turini aniqlaydi."""
    kichik = fayl.lower()

    if kichik.endswith(RASM_KENGAYTMALARI):
        return "🖼️  Rasm"
    if kichik.endswith(HUJJAT_KENGAYTMALARI):
        return "📄 Hujjat"
    if kichik.endswith(MALUMOT_KENGAYTMALARI):
        return "📊 Ma'lumot"
    if kichik.endswith((".py", ".js", ".ts", ".go")):
        return "💻 Kod"
    if kichik.endswith((".mp4", ".avi", ".mkv")):
        return "🎬 Video"
    if kichik.endswith((".zip", ".tar", ".gz", ".rar")):
        return "📦 Arxiv"
    if fayl.startswith("."):
        return "⚙️  Yashirin"
    return "❓ Noma'lum"


print("┌─ FAYLLAR")
print("│")
for fayl in FAYLLAR:
    print(f"│  {fayl:<22} {turi(fayl)}")
print("└─")

print("\n=== Filtrlash ===")
testlar = [f for f in FAYLLAR if f.lower().startswith("test_")]
print(f"  Test fayllari:   {testlar}")

python = [f for f in FAYLLAR if f.lower().endswith(".py")]
print(f"  Python fayllari: {python}")

yashirin = [f for f in FAYLLAR if f.startswith(".")]
print(f"  Yashirin:        {yashirin}")

ichki = [f for f in FAYLLAR if f.startswith("_")]
print(f"  Ichki:           {ichki}")

print("\n=== Prefiks/suffiks olib tashlash ===")
for f in testlar:
    toza = f.removeprefix("test_").removesuffix(".py")
    print(f"  {f:<22} → {toza}")

print("\n=== ⚠️ strip bilan noto'g'ri ===")
for f in ["python.py", "test_py.py", "yolboshchi.py"]:
    print(f"  {f:<18} strip('.py')        → {f.strip('.py')!r}")
    print(f"  {'':18} removesuffix('.py') → {f.removesuffix('.py')!r}")

print("\n=== Statistika ===")
from collections import Counter
hisob = Counter(turi(f) for f in FAYLLAR)
for t, soni in hisob.most_common():
    print(f"  {t:<14} {soni}")
text
┌─ FAYLLAR
│
│  hisobot_2026.pdf       📄 Hujjat
│  rasm.JPG               🖼️  Rasm
│  test_asoslar.py        💻 Kod
│  malumot.csv            📊 Ma'lumot
│  logo.png               🖼️  Rasm
│  test_satrlar.py        💻 Kod
│  hujjat.docx            📄 Hujjat
│  arxiv.tar.gz           📦 Arxiv
│  .gitignore             ⚙️  Yashirin
│  README.md              📄 Hujjat
│  video.mp4              🎬 Video
│  _ichki.py              💻 Kod
│  skript.PY              💻 Kod
│  malumot.CSV            📊 Ma'lumot
│  rasm.jpeg              🖼️  Rasm
└─

=== Filtrlash ===
  Test fayllari:   ['test_asoslar.py', 'test_satrlar.py']
  Python fayllari: ['test_asoslar.py', 'test_satrlar.py', '_ichki.py', 'skript.PY']
  Yashirin:        ['.gitignore']
  Ichki:           ['_ichki.py']

=== Prefiks/suffiks olib tashlash ===
  test_asoslar.py        → asoslar
  test_satrlar.py        → satrlar

=== ⚠️ strip bilan noto'g'ri ===
  python.py          strip('.py')        → 'ython'
                     removesuffix('.py') → 'python'
  test_py.py         strip('.py')        → 'test_'
                     removesuffix('.py') → 'test_py'

Diqqat: "test_py.py".strip(".py") → 'test_' — oxiridagi py ham o'chdi. Bu — strip ning belgilar to'plami bilan ishlashining oqibati.

Nima ko'rsatdi: 2.6-bo'lim.

Misol 4 — Log tahlilchisi

python
"""Log faylini qidirish metodlari bilan tahlil qilish."""

from collections import Counter

LOG = """\
2026-09-07 10:00:12 INFO  [api] Server ishga tushdi, port=8000
2026-09-07 10:00:45 INFO  [db] Ulanish o'rnatildi
2026-09-07 10:01:03 WARN  [api] Sekin so'rov: /users (1250ms)
2026-09-07 10:01:15 ERROR [db] Ulanish uzildi: timeout
2026-09-07 10:01:16 INFO  [db] Qayta ulanmoqda...
2026-09-07 10:01:18 INFO  [db] Ulanish tiklandi
2026-09-07 10:02:30 ERROR [api] 500 xatosi: /orders — NullPointerException
2026-09-07 10:03:01 WARN  [cache] Kesh to'ldi, eskilarini o'chirish
2026-09-07 10:05:22 ERROR [api] 404: /nomalum-yol
2026-09-07 10:06:00 INFO  [api] Salomatlik tekshiruvi: OK
"""

DARAJALAR = ("INFO", "WARN", "ERROR")


def darajani_ol(qator: str) -> str:
    """Qatordan log darajasini ajratadi."""
    for daraja in DARAJALAR:
        if daraja in qator:
            return daraja
    return "NOMA'LUM"


def modulni_ol(qator: str) -> str:
    """[modul] qismini ajratadi."""
    boshi = qator.find("[")
    oxiri = qator.find("]", boshi)
    if boshi == -1 or oxiri == -1:
        return "?"
    return qator[boshi + 1:oxiri]


def vaqtni_ol(qator: str) -> str:
    """Vaqt qismini ajratadi (HH:MM:SS)."""
    return qator[11:19]


def xabarni_ol(qator: str) -> str:
    """Xabar qismini ajratadi."""
    oxiri = qator.find("]")
    return qator[oxiri + 1:].strip() if oxiri != -1 else qator


qatorlar = [q for q in LOG.splitlines() if q.strip()]

print("┌─ LOG TAHLILI")
print("│")
print(f"│  Jami qatorlar: {len(qatorlar)}")
print("│")

# Daraja bo'yicha
darajalar = Counter(darajani_ol(q) for q in qatorlar)
print("│  Daraja bo'yicha:")
belgilar = {"INFO": "ℹ️ ", "WARN": "⚠️ ", "ERROR": "❌"}
for d, soni in darajalar.most_common():
    ulush = soni / len(qatorlar)
    chiziq = "█" * int(ulush * 30)
    print(f"│    {belgilar.get(d, '  ')} {d:<8} {soni:>2}  {chiziq} {ulush:.0%}")

print("│")

# Modul bo'yicha
modullar = Counter(modulni_ol(q) for q in qatorlar)
print("│  Modul bo'yicha:")
for m, soni in modullar.most_common():
    print(f"│    [{m}]{'':<{10 - len(m)}} {soni}")

print("│")

# Faqat xatolar
xatolar = [q for q in qatorlar if q.count("ERROR")]
print(f"│  Xatolar ({len(xatolar)}):")
for x in xatolar:
    print(f"│    {vaqtni_ol(x)}  [{modulni_ol(x)}]  {xabarni_ol(x)}")

print("│")

# Kalit so'z qidirish
KALIT_SOZLAR = ["timeout", "500", "404", "sekin"]
print("│  Kalit so'zlar:")
for soz in KALIT_SOZLAR:
    topilgan = [q for q in qatorlar if soz.lower() in q.lower()]
    if topilgan:
        print(f"│    {soz!r:<12} {len(topilgan)} ta:")
        for t in topilgan:
            print(f"│      {vaqtni_ol(t)} {xabarni_ol(t)[:50]}")

print("└─")
text
┌─ LOG TAHLILI
│
│  Jami qatorlar: 10
│
│  Daraja bo'yicha:
│    ℹ️  INFO      5  ███████████████ 50%
│    ❌ ERROR     3  █████████ 30%
│    ⚠️  WARN      2  ██████ 20%
│
│  Modul bo'yicha:
│    [api]      5
│    [db]       4
│    [cache]    1
│
│  Xatolar (3):
│    10:01:15  [db]  Ulanish uzildi: timeout
│    10:02:30  [api]  500 xatosi: /orders — NullPointerException
│    10:05:22  [api]  404: /nomalum-yol
│
│  Kalit so'zlar:
│    'timeout'    1 ta:
│      10:01:15 Ulanish uzildi: timeout
│    '500'        1 ta:
│      10:02:30 500 xatosi: /orders — NullPointerException
│    '404'        1 ta:
│      10:05:22 404: /nomalum-yol
│    'sekin'      1 ta:
│      10:01:03 Sekin so'rov: /users (1250ms)
└─

Kodda ko'rish kerak:

  • find("[") va find("]", boshi) — oraliq bilan qidirish (2.4-bo'lim)
  • qator[11:19] — sobit pozitsiyadan kesim (4.2-dars)
  • soz.lower() in q.lower() — registrsiz qidirish
  • q.count("ERROR") — in ning muqobili (bu yerda in yaxshiroq)

Amaliy eslatma: haqiqiy log tahlilida re moduli (15-qism) ancha kuchliroq. Bu misol satr metodlarining imkoniyatini ko'rsatadi.

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


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

Noto'g'ri fikr To'g'risi
"if matn.find(x): ishlaydi" 0 — False, -1 — True. != -1 yoki in
"find va index bir xil" find -1, index ValueError
"count barcha uchrashuvni sanaydi" Ustma-ust uchrashuvlarni sanamaydi
"isdigit() int() ni kafolatlaydi" Yo'q! "²".isdigit() True, int("²")
"endswith ro'yxat qabul qiladi" Faqat juftlik. tuple(royxat)
"strip(".py") suffiksni olib tashlaydi" Belgilar to'plamini. removesuffix()
"Bo'sh satrda is* True" Hammasi False (isascii dan tashqari)
"lower() xalqaro matn uchun yetarli" casefold() to'g'riroq (nemis ß va h.k.)

6. Keng tarqalgan xatolar va yechimlari

1. find natijasini if da ishlatish

python
if matn.find("x"):              # ❌
if matn.find("x") != -1:        # ✅
if "x" in matn:                 # ✅ eng yaxshi

2. index ni himoyasiz ishlatish

python
p = matn.index("x")             # ❌ ValueError bo'lishi mumkin

if "x" in matn:                 # ✅
    p = matn.index("x")

p = matn.find("x")              # ✅
if p != -1:
    ...

3. isdigit ga ishonish

python
if kirish.isdigit():
    son = int(kirish)           # ❌ "²" da qulaydi

if kirish.isdecimal():          # ✅
    son = int(kirish)

try:                            # ✅ eng ishonchli
    son = int(kirish)
except ValueError:
    ...

4. Bo'sh satr tekshiruvi

python
if not kirish.isalpha():
    print("Faqat harf")         # ❌ bo'sh satr ham shu yerga

if not kirish:
    print("Bo'sh")
elif not kirish.isalpha():
    print("Faqat harf")         # ✅

5. endswith ga ro'yxat berish

python
kengaytmalar = [".jpg", ".png"]
fayl.endswith(kengaytmalar)             # ❌ TypeError
fayl.endswith(tuple(kengaytmalar))      # ✅

6. Registrni hisobga olmaslik

python
if fayl.endswith(".jpg"):               # ❌ ".JPG" ishlamaydi
if fayl.lower().endswith(".jpg"):       # ✅

7. count bilan ustma-ust

python
"aaaa".count("aa")                      # 2, kutilgan 3

Ustma-ust kerak bo'lsa qo'lda sanang (2.5-bo'lim).

8. Kesim bilan qidirish (sekin)

python
matn[10:].find("x")                     # ❌ yangi satr yaratadi
matn.find("x", 10)                      # ✅ nusxasiz

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 4.4-dars: replace — topilgan joyni almashtirish
  • 4.5-dars: split, partition — find ning yuqori darajali muqobili
  • 5-qism: shartlarda in va startswith
  • 9-qism: ValueError ni ushlash (index)
  • 15-qism: fayl nomlari, pathlib
  • 15-qism: muntazam ifodalar — murakkab qidiruv uchun
  • 31-qism: satr qidirish algoritmlari (KMP, Boyer-Moore)
  • Kundalik ishda: ma'lumotni tozalash va tasdiqlash

8. Eng yaxshi amaliyotlar

  1. Bor-yo'qligi uchun in ishlating. find(x) != -1 dan qisqaroq va o'qish oson.

  2. find natijasini != -1 bilan tekshiring. if matn.find(x): — jimgina xato.

  3. int() uchun isdecimal() yoki try/except. isdigit() yetarli emas.

  4. endswith/startswith ga juftlik bering. Uzun or zanjiridan yaxshiroq.

  5. Registrni normallashtiring. fayl.lower().endswith(...).

  6. strip() o'rniga removeprefix/removesuffix. Belgilar to'plami tuzog'idan qutuling.

  7. Oraliq argumentlarini ishlating. find(x, 10) matn[10:].find(x) dan tez.

  8. Fayl yo'llari uchun pathlib. rfind("/") — eskirgan usul.


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
matn = "abcabcabc"

1.  matn.find("abc")
2.  matn.find("abc", 1)
3.  matn.rfind("abc")
4.  matn.find("z")
5.  matn.count("abc")
6.  matn.count("")
7.  "aaaa".count("aa")
8.  "".isdigit()
9.  "".isascii()
10. "²".isdigit()
11. "²".isdecimal()
12. "Salom123".isalnum()
Javoblar
  1. 0
  2. 3
  3. 6
  4. -1
  5. 3
  6. 10 — len + 1
  7. 2 — ustma-ust sanamaydi
  8. False
  9. True — istisno
  10. True
  11. False
  12. True

Vazifa 2: Xatolarni tuzatish

python
1.  if matn.find("xato"):
        print("Topildi")

2.  p = matn.index("kerakli")

3.  if kirish.isdigit():
        son = int(kirish)

4.  if fayl.endswith([".jpg", ".png"]):

5.  toza = fayl.strip(".txt")
Javoblar
python
1.  if "xato" in matn:

2.  p = matn.find("kerakli")
    if p != -1: ...

3.  if kirish.isdecimal():
        son = int(kirish)
    # yoki try/except

4.  if fayl.endswith((".jpg", ".png")):

5.  toza = fayl.removesuffix(".txt")

Vazifa 3: Barcha uchrashuvlar

barcha_pozitsiyalar(matn, qism, ustma_ust=True) funksiyasini yozing:

  • ustma_ust=True → ustma-ust uchrashuvlarni ham topsin
  • ustma_ust=False → count kabi ishlasin

Sinang: "aaaa" da "aa".

Vazifa 4: URL tahlilchisi

Funksiya yozing — URL dan qismlarni ajratsin (faqat satr metodlari bilan, urllib siz):

python
tahlil("https://wisar.uz:8080/kurslar/python?id=42#bolim")
text
  Protokol: https
  Host:     wisar.uz
  Port:     8080
  Yo'l:     /kurslar/python
  So'rov:   id=42
  Bo'lim:   bolim
Yechim
python
def tahlil(url: str) -> dict:
    natija = {}

    # Protokol
    p = url.find("://")
    if p != -1:
        natija["protokol"] = url[:p]
        url = url[p + 3:]

    # Bo'lim (fragment)
    p = url.find("#")
    if p != -1:
        natija["bolim"] = url[p + 1:]
        url = url[:p]

    # So'rov
    p = url.find("?")
    if p != -1:
        natija["sorov"] = url[p + 1:]
        url = url[:p]

    # Yo'l
    p = url.find("/")
    if p != -1:
        natija["yol"] = url[p:]
        url = url[:p]
    else:
        natija["yol"] = "/"

    # Port
    p = url.rfind(":")
    if p != -1:
        natija["port"] = url[p + 1:]
        url = url[:p]

    natija["host"] = url
    return natija

Haqiqiy ishda urllib.parse.urlparse() ishlating (20-qism).

Vazifa 5: Parol tekshiruvchi

is* metodlaridan foydalanib parol kuchini tekshiring:

  • Kamida 8 belgi
  • Kamida bitta katta va bitta kichik harf
  • Kamida bitta raqam (isdecimal)
  • Kamida bitta maxsus belgi
  • Bo'sh joy yo'q
  • Faqat ASCII

Vazifa 6: Log tahlilchisini kengaytirish

4-misoldagi dasturga qo'shing:

  1. Vaqt oralig'i bo'yicha filtrlash
  2. Har bir modul uchun xatolar foizi
  3. Ketma-ket ERROR larni topish (ehtimol bir muammo)

Vazifa 7: O'ylash

Nega "aaaa".count("aa") 2 qaytaradi, 3 emas?

Javob

count ustma-ust bo'lmagan uchrashuvlarni sanaydi. Algoritm:

text
aaaa
^^      1-uchrashuv topildi (0-1), keyingi qidiruv 2-indeksdan
  ^^    2-uchrashuv topildi (2-3)
        qidiruv tugadi

1-2 pozitsiyadagi uchrashuv o'tkazib yuborildi, chunki qidiruv 2 dan boshlandi.

Nega shunday? Chunki count odatda "nechta alohida bo'lak bor" degan savolga javob beradi. Masalan:

python
"aaaa".replace("aa", "X")       # 'XX' — 2 ta almashtirish
"aaaa".count("aa")              # 2 — mos keladi

count va replace izchil ishlaydi. Agar count 3 qaytarsa, replace bilan mos kelmasdi.

Ustma-ust sanash kerak bo'lsa — qo'lda yozing yoki re.finditer ni lookahead bilan ishlating (15-qism).

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


Xulosa

Bu darsda qidirish va tekshirish metodlarini o'rgandik.

Eng muhim uch fikr:

  1. find -1, index ValueError, in bool qaytaradi. Bor-yo'qligi uchun in, pozitsiya uchun find, majburiy topilishi kerak bo'lsa index. if matn.find(x): — jimgina xato.

  2. isdigit() int() ni kafolatlamaydi. "²".isdigit() True, lekin int("²") xato beradi. isdecimal() yoki try/except ishlating.

  3. startswith/endswith juftlik qabul qiladi. fayl.lower().endswith((".jpg", ".png")) — uzun or zanjiridan ancha yaxshiroq.

Keyingi darsda o'zgartirish va tozalash metodlarini o'rganamiz: replace, strip, upper/lower, translate va matn normalizatsiyasi.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
4.3-dars: Metodlar — qidirish va tekshirish — IlmHamroh