19-dars: Testlash va toza kod
5-blokHaqiqiy programma17–20 darslar
Bu darsdan keyin siz
assertbilan funksiyaga test yozasiz- chegara holatlarini oldindan sanab chiqasiz
- kodni o’qishga oson qiladigan uch qoidani qo’llaysiz
Nazariya
“Nazariya” bo'limiga havolaassert — eng arzon test
“assert — eng arzon test” bo'limiga havolaassert 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.
def kvadrat(son): return son * sonassert kvadrat(3) == 9assert kvadrat(0) == 0assert kvadrat(-4) == 16print("Barcha testlar o'tdi")Testning soni emas, qaysi holat muhim
“Testning soni emas, qaysi holat muhim” bo'limiga havolaUchta 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.
Nomlash — birinchi qoida
“Nomlash — birinchi qoida” bo'limiga havolaNom 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.
# Yomondef f(a, b): return a * b / 100# Yaxshidef chegirma_summasi(narx, foiz): return narx * foiz / 100PEP 8 — umumiy kelishuv
“PEP 8 — umumiy kelishuv” bo'limiga havolaPEP 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 nima uchun yoziladi
“Izoh nima uchun yoziladi” bo'limiga havolaIzoh kod nima qilayotganini takrorlamaydi — buni kodning o’zi aytadi. Izoh nega shunday qilinganini yozadi.
# Yomon izoh: kodni takrorlaydisoni = soni + 1 # soni ga 1 qo'shamiz# Yaxshi izoh: sababni aytadisoni = soni + 1 # sarlavha qatori ham sanalgani uchun tuzatamizBashorat qiling
“Bashorat qiling” bo'limiga havolaAvval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
def eng_katta(sonlar): eng = 0 for son in sonlar: if son > eng: eng = son return engprint(eng_katta([-5, -2, -9]))Haqiqiy natija:
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].
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.
def qosh(element, royxat=[]): royxat.append(element) return royxatprint(qosh(1))print(qosh(2))Haqiqiy natija:
[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.
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.
Sinab ko’r
“Sinab ko’r” bo'limiga havolaBeshta 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 engBuzuq versiya
def eng_katta(sonlar):
eng = 0 # <- shu yerda
for son in sonlar:
if son > eng:
eng = son
return engIshga tushirildi: 0/5 · buzuq versiyani ushlagan test: 0
to'g'ri5 qaytdi — kutilgani 5
buzuq5 qaytdi — kutilgani 5
Test o'tdi, lekin ikki versiyada ham o'tdi — demak u xatoni ushlay olmadi. Bunday test yo'q emas, lekin xotirjamlik beradi va bu xavfli.
to'g'ri10 qaytdi
buzuq10 qaytdi
Bitta elementli ro'yxat — chegara holatga o'xshaydi, lekin bu yerda ham ikki versiya bir xil ishladi.
to'g'ri-2 qaytdi
buzuqAssertionError: 0 qaytdi, -2 kutilgan
MANA USHLADI. Buzuq versiya eng = 0 dan boshlaydi, shuning uchun barcha sonlar manfiy bo'lganda 0 qaytadi — ro'yxatda umuman yo'q son. Bu chegara holati testi va uni o'ylab topish kerak edi.
to'g'ri0 qaytdi
buzuq0 qaytdi
Yana ikki versiyada ham o'tdi. Nollar buzuq versiyaning xatosini yashiradi.
to'g'riIndexError: list index out of range
buzuq0 qaytdi
Qiziq holat: bu yerda TO'G'RI versiya yiqildi. Bo'sh ro'yxat uchun javob nima bo'lishi kerak — 0 mi, xato mi, None mi? Kodda bu qaror qabul qilinmagan. Test faqat xato topmaydi, hal qilinmagan qarorni ham ochib beradi.
Testlarni bittalab bosib chiqing. Har testdan keyin bitta savol bering: bu test nimani ushlay oladi?
Xatoni toping
“Xatoni toping” bo'limiga havolaBu kod ataylab buzuq — xatoni toping
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:
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.
O’zingizni sinang
“O’zingizni sinang” bo'limiga havola1assert 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
“Topshiriq” bo'limiga havolaTopshiriq — 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.