Asosiy mazmunga o'tish

19-dars: Testlash va toza kod

5-blokHaqiqiy programma17–20 darslar

Bu darsdan keyin siz

  • assert bilan funksiyaga test yozasiz
  • chegara holatlarini oldindan sanab chiqasiz
  • kodni o’qishga oson qiladigan uch qoidani qo’llaysiz

assert shartni tekshiradi: shart to’g’ri bo’lsa hech narsa bo’lmaydi, xato bo’lsa AssertionError chiqadi. Bir qator kod, ammo u kodni har o’zgartirishdan keyin tekshirib turadi.

assertassert

Shartni tekshiruvchi ko’rsatma. assert kvadrat(3) == 9 — shart buzilsa programma darhol to’xtaydi va qaysi tekshiruv yiqilganini aytadi.

test_kvadrat.py
def kvadrat(son):  return son * sonassert kvadrat(3) == 9assert kvadrat(0) == 0assert kvadrat(-4) == 16print("Barcha testlar o'tdi")

Uchta test yozib “kodim tekshirilgan” deb o’ylash oson. Lekin uchta test bir xil holatni tekshirsa, ular bitta testga teng.

Muhim savol boshqa: bu test qanday xatoni ushlay oladi? Javob “hech qanday” bo’lsa, test faqat xotirjamlik beradi — va bu xatodan yomonroq.

Nom nima saqlayotganini aytishi kerak. x emas, narx. f emas, ortacha_hisobla. Uzun nom yozishdan qo’rqmang: kod bir marta yoziladi, o’n marta o’qiladi.

nomlash.py
# Yomondef f(a, b):  return a * b / 100# Yaxshidef chegirma_summasi(narx, foiz):  return narx * foiz / 100

PEP 8 — Python jamoasining kod yozish kelishuvi. Uni yodlash shart emas, uch qoidasi esa darhol foyda beradi: chekinish 4 bo’shliq, funksiya va o’zgaruvchi nomlari kichik harfda (ortacha_baho, narx_hisobla), amal belgilari atrofida bo’shliq (a + b, a+b emas).

PEP 8PEP 8

Python kodini yozish bo’yicha rasmiy uslub qo’llanmasi. Maqsadi — barcha Python kodi bir xil ko’rinishi va shu sababli oson o’qilishi.

VS Code buni o’zi eslatadi. Sozlash 0-darsda qilingan: editor.insertSpaces va tabSize: 4.

Izoh kod nima qilayotganini takrorlamaydi — buni kodning o’zi aytadi. Izoh nega shunday qilinganini yozadi.

izoh.py
# Yomon izoh: kodni takrorlaydisoni = soni + 1        # soni ga 1 qo'shamiz# Yaxshi izoh: sababni aytadisoni = soni + 1        # sarlavha qatori ham sanalgani uchun tuzatamiz

Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.

Bashorat qiling
def eng_katta(sonlar):  eng = 0  for son in sonlar:      if son > eng:          eng = son  return engprint(eng_katta([-5, -2, -9]))
Javobni ko'rish
0

eng = 0 dan boshlangani uchun barcha sonlar manfiy bo'lganda hech biri 0 dan katta bo'lmaydi. Natija — ro'yxatda umuman yo'q son. To'g'ri boshlanish: eng = sonlar[0].

Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.

Bashorat qiling
def qosh(element, royxat=[]):  royxat.append(element)  return royxatprint(qosh(1))print(qosh(2))
Javobni ko'rish
[1]
[1, 2]

Standart qiymat funksiya e'lon qilinganda BIR MARTA yaratiladi. Shuning uchun ikkinchi chaqiruv o'sha ro'yxatni oldi — 9-darsdagi aliasingning eng ayyor ko'rinishi.

Beshta testni bittalab ishga tushiring. Har testdan keyin bitta savolni bering: bu test nimani ushlay oldi? Oxirgi test alohida — u xato emas, hal qilinmagan qarorni ochib beradi.

Test yozuvchi

Testlarni bittalab ishga tushiring: qaysi biri buzuq versiyani ushlaydi?

Bu simulyatorda bitta funksiya ikki versiyada berilgan: to'g'ri va buzuq (buzuq versiya eng = 0 dan boshlaydi). Beshta test bor va siz ularni bittalab ishga tushirasiz.

JavaScript'siz eng muhim savol: assert eng_katta([-5, -2, -9]) == -2 testi nega buzuq versiyani ushlaydi? Chunki barcha sonlar manfiy bo'lganda eng = 0dan boshlangan sanoq 0 ni qaytaradi — ro'yxatda mavjud bo'lmagan sonni.

To'g'ri versiya

def eng_katta(sonlar):
    eng = sonlar[0]
    for son in sonlar:
        if son > eng:
            eng = son
    return eng

Buzuq versiya

def eng_katta(sonlar):
    eng = 0                  # <- shu yerda
    for son in sonlar:
        if son > eng:
            eng = son
    return eng

Ishga tushirildi: 0/5 · buzuq versiyani ushlagan test: 0

Testlarni bittalab bosib chiqing. Har testdan keyin bitta savol bering: bu test nimani ushlay oladi?

Bu kod ataylab buzuq — xatoni toping

Buzuq kod
def ortacha(sonlar):  return sum(sonlar) / len(sonlar)assert ortacha([2, 4]) == 3print("Test o'tdi")

Python shunday javob beradi:

Test o'tdi
(keyinroq, haqiqiy ma'lumotda:)
Traceback (most recent call last):
File "hisob.py", line 8, in <module>
  print(ortacha([]))
ZeroDivisionError: division by zero
Sababi va tuzatish

Test bor, lekin u faqat oddiy holatni tekshirdi. Bo'sh ro'yxat holati tekshirilmagan — va aynan u haqiqiy ma'lumotda uchradi.

Bitta test o’tgani kod ishlayotganini bildirmaydi. Chegara holatlari qo’shiladi va funksiyaning o’zi ham himoyalanadi:

tuzatilgan.py
def ortacha(sonlar):  if not sonlar:      return 0  return sum(sonlar) / len(sonlar)assert ortacha([2, 4]) == 3assert ortacha([]) == 0assert ortacha([-2, -4]) == -3assert ortacha([5]) == 5print("Barcha testlar o'tdi")

Diqqat qiling: return 0 — bu qaror, tuzatish emas. Bo’sh ro’yxatning o’rtachasi 0 mi yoki xato mi — buni siz hal qilasiz va testda yozib qo’yasiz. Test kodni tekshirishdan tashqari qaroringizni ham hujjatlashtiradi.

1assert nima qiladi?

Javobni ko'rish

Shartni tekshiradi. Shart to’g’ri bo’lsa hech narsa bo’lmaydi, buzilsa AssertionError chiqadi va programma to’xtaydi.

2Uch test yozdim, hammasi o'tdi. Kod ishonchlimi?

Javobni ko'rish

Ma’lum emas. Savol boshqa: bu testlar qanday xatoni ushlay oladi? Uchtasi bir xil holatni tekshirsa, ular bitta testga teng.

3Qaysi to'rt chegara holatini har doim tekshirasiz?

Javobni ko'rish

Nol, manfiy son, bo’sh ro’yxat va bitta elementli ro’yxat.

4def f(a, b) nomlashda nima yomon?

Javobni ko'rish

Nomlar hech narsa aytmaydi. Ikki haftadan keyin bu funksiya nima qilishini tushunish uchun butun kodni o’qish kerak bo’ladi.

5Yaxshi izoh nimani yozadi?

Javobni ko'rish

Nega shunday qilinganini. Kod nima qilayotganini kodning o’zi aytadi — izohda uni takrorlash keraksiz.

Topshiriq — darajangizni tanlang

Asos · 5–7-sinf — Vizual va aniq ko'rsatmali

13-darsda yozgan funksiyalaringizdan biriga uchta assert yozing: oddiy holat, nol va manfiy son. Keyin funksiyani ataylab buzib, qaysi test yiqilganini ko’ring.

Mustahkam · 8–9-sinf — Matnli masala, o'zingiz tuzasiz

eng_katta(sonlar) funksiyasini yozing va unga beshta test qo’shing — to’rt chegara holati majburiy. Keyin funksiyani eng = 0 bilan buzib, qaysi test ushlaganini yozing. Nomlarni ham tekshirib chiqing: har nom nima saqlayotganini aytyaptimi?

Chuqur · 10–11-sinf — Algoritmik, chegara holatlari bilan

Oldingi darslardagi programmalaringizdan birini oling va uni qayta yozing: funksiyalarga bo’ling, nomlarni tuzating, testlar qo’shing. Keyin ikki versiyani solishtirib, uch punktda yozing: nima o’qishga osonlashdi, nima yo’qoldi, qaysi test eng foydali bo’ldi. Oxirida bo’sh kiritish uchun qaror qabul qiling va uni testda yozib qo’ying.

Darsni belgilash uchun JavaScript kerak. Bu progressni saqlash uchun ishlatiladi — darslikning o'zi JavaScript'siz ham to'liq o'qiladi.