Ёфтани хатоҳо - Муқаддимаи барномасозӣ · Python
Асосӣ Курсҳо Муқаддимаи барномасозӣ · Python Сохтани барномаҳо
Ёфтани хатоҳо Усули ёфтани хато: се намуди мушкилиро фарқ кардан, traceback-ро ба воситаи функсия хондан, вуруди хурдро бо даст пайгирӣ кардан, санҷишҳои мувақатӣ ва навиштани санҷишҳо бо assert.
Назария Дарси 2 аз 4 Хониш: 17 дақиқа Саволҳо: 6
Се навъи мушкилот
Барнома айнан он чизро иҷро мекунад, ки шумо навиштаед, на он чизеро, ки дар назар доштед. Вақте ин ду аз ҳам фарқ мекунанд, хато (bug) ҳаст. Ёфтани он ёфтан ва ислоҳи хато (debugging) ном дорад. Устод аз шумо камтар хато намекунад. Устод барои ёфтани хато усул дорад. Функсияҳо кӯмак мекунанд: хаторо дар функсияи даҳсатра аз барномаи садсатра хеле осонтар меёбед.
Шумо чӣ мебинед Чист SyntaxError ё IndentationError, ҳеҷ чиз кор намекунадКод қоидаҳои Python-ро вайрон мекунад. Сатри дар паём номбаршуда ё сатри болоии онро бинед. Traceback ё Runtime Error аз довар Хато ҳангоми иҷро: номе, ки вуҷуд надорад, индекс берун аз рӯйхат, тақсим ба сифр. Сатри охирро бихонед, баъд сатреро, ки ба он ишора мекунад. То охир кор мекунад, вале ҷавоб нодуруст аст Хатои мантиқӣ : код чизеро мегӯяд, ки аз он чи шумо дар назар доштед, фарқ мекунад. Боқимони дарс дар бораи ҳамин аст.
Хондани traceback
Вақте барнома бо хато қатъ мешавад, Python traceback чоп мекунад. Онро аз поён бихонед. Сатри охирин мегӯяд, ки чӣ вайрон шуд. Сатрҳои болотар мегӯянд, ки дар куҷо, ҳамчун занҷири даъватҳо. Даъвате, ки вайрон шуд, дар поён аст.
Сатри охирин: тақсим ба сифр. Сатри болотар: дар дохили average, дар сатри 2. Боз болотар: average аз сатри 6-уми барномаи асосӣ (<module> номи он дар Python аст) бо рӯйхати холӣ даъват шуд. Пас функсия дуруст аст. Ба он рӯйхате доданд, ки миёнаашро ҳисоб карда намешавад.
навбатӣ Машқ: барномаҳо аз функсияҳо Масъалаҳо оид ба барномаҳо аз функсияҳои хурди ёрирасон, ки ҳар кадом алоҳида санҷида мешавад: ёрирасонҳое, ки ёрирасонҳои дигарро даъват мекунанд, вурудҳое, ки ёрирасонро мешикананд (сифр, манфӣ) ва ёрирасоне, ки маънои фармонро муайян мекунад.
NameError: name 'biger' is not definedХатои имлоӣ дар ном, номе, ки берун аз функсияаш истифода шудааст, ё даъват дар болои def. TypeError: ... missing 1 required positional argumentДар даъват аз шумораи параметрҳои функсия камтар аргумент гузаштааст. TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'Функсия None баргардонд: return-и он нест. IndexError: list index out of rangeИндекс дар len(a) ё берунтар аз он, аксар вақт давр як қадам дарозтар аст. ValueError: invalid literal for int() ...int(input()) дар сатре, ки ду адад дорад.
Лаборатория ҳамин паёмро бо забони шумо ва бо рақами сатр нишон медиҳад. Дар компютери худатон Python traceback-и пурраро бо забони англисӣ чоп мекунад, мисли болоӣ. Акнун ҳарду шаклро хондан медонед.
Бо даст пайравӣ кунед Ҷавоби нодуруст ҳеҷ паёме намедиҳад. Ҷойи хаторо худатон бояд ёбед ва усуле ҳаст, ки қариб ҳамеша кор мекунад.
Инак is_prime бо хато, ки барои 9 иҷро шудааст. Ҷавоби дурустро медонед: 9 = 3 · 3, пас сода нест. Барномаро қадам ба қадам гузаронед ва лаҳзаеро ёбед, ки он аз нақшаи шумо дур мешавад.
is_prime(9) бо хато: барнома дар куҷо аз нақшаи шумо дур мешавад?
2 if n < 2:
3 return False
4 d = 2
5 while d * d < n:
6 if n % d == 0:
7 return False
8 d += 1
9 return True
10
11 print(is_prime(9))
def танҳо муайян мекунад
сатр 1 Як савол: оё 9 сода аст? Пеш аз қадам гузоштан ҷавобро ҳисоб кунед. 9 = 3 · 3, пас ҷавоб бояд False бошад.
Давр дар d = 3 қатъ мешавад, чунки 9 < 9 нодуруст аст, пас 3 ҳеҷ гоҳ санҷида намешавад. Бо d * d <= n давр 3-ро месанҷад ва тақсимкунандаро меёбад. Хато танҳо дар квадрати адади сода зоҳир шуд. Барои 7, 15 ё 97 нусхаи бохато дуруст ҷавоб медиҳад. Барои ҳамин вурудҳои хурде, ки худатон интихоб мекунед, муҳиманд: 1, 2, 4, 9-ро санҷед, на танҳо мисолро.
Чоп кунед, ки барнома чӣ мекунад Вақте барнома барои бо даст пайравӣ кардан аз ҳад дароз аст, ба он гӯед, ки худаш нақл кунад. Чанд сатри муваққатии print илова кунед, ки номҳоро дар ҷойҳои шубҳанок нишон медиҳанд. Вуруди хурдро иҷро кунед ва ҳар сатри чопшударо бо нақшаи худ муқоиса кунед. Ҳар қиматро нишона гузоред, то баромадро хонда тавонед.
Як ададро хонед ва баъд ҳамон қадар адади бутун, ки метавонанд манфӣ бошанд. Барои ҳар кадом ҷамъи рақамҳояшро чоп кунед: барои −305 он 3 + 0 + 5 = 8 аст.
Сатрҳои санҷишӣ ба sys.stderr , ҷараёни хатоҳо, бо file=sys.stderr мераванд. Дар ин ҷо err = sys.stderr ба он номи кӯтоҳ медиҳад. Лаборатория ҳарду ҷараёнро дар як тиреза нишон медиҳад.
Бо вуруди 2, 305, -305 чунин менамояд:
Барои 305 давр се бор иҷро мешавад, мувофиқи нақша. Барои −305 сатри start ҳаст, вале сатри loop намеояд . Давр ҳеҷ гоҳ иҷро нашуд, зеро −305 аз 0 калон нест. Хато дар шарт аст: адади манфӣ аввал n = abs(n) мехоҳад. Сатре, ки дар баромади санҷишӣ нест, ҳамон қадар кӯмак мекунад, ки адади нодуруст.
print-и фаромӯшшудаи санҷишӣ дар хориҷкунии стандартӣ ба ҷавоби шумо ҳамроҳ мешавад ва ҷавоби дуруст ба Wrong Answer табдил меёбад. sys.stderr ҷараёни алоҳида аст, бинобар ин ҷавоби чопшуда тоза мемонад. Бо ин ҳама ҳар чопи санҷиширо бо тавзеҳи # DEBUG нишон кунед ва пеш аз пешниҳод ҳамаро нест кунед.
Акнун хатоеро бо ҳамин усул ҷустуҷӯ кунед. Дар як сатр чопи санҷишӣ гузоред, иҷро кунед ва чопшударо бо қиматҳои дуруст муқоиса кунед.
Хаторо бо чопи санҷишӣ гиред санҷида бин! Аз нав
Бигӯед, ки функсия бояд чӣ кор кунад Пеш аз санҷидани функсия дар як ҷумла нависед, ки вай бояд чӣ кор кунад . Ин ҷумла ваъдаи функсия аст. Масалан: is_leap(year) True-ро бармегардонад, агар year соли кабиса бошад, ва False-ро, агар набошад. Ваъда мегӯяд, ки функсия чиро мегирад, чиро медиҳад ва барои кадом вурудҳо.
Санҷиш даъвате аст, ки ҷавобашро аз рӯи ваъда медонед. Дастури assert онро барои шумо месанҷад. assert condition вақте шарт дуруст аст, коре намекунад, ва вақте нодуруст аст, барномаро бо AssertionError қатъ мекунад. Баъд аз вергул паём илова кардан мумкин аст, масалан, соле ки месанҷед. Инак функсия бо хато ва се санҷиш:
Ду санҷиши аввал гузаштанд, сеюм барномаро қатъ кард ва паём ҳолатро ном мебарад: 1900. Ислоҳ қоидаи соли кабисаест, ки асрҳоро медонад: year % 4 == 0 and (year % 100 != 0 or year % 400 == 0). Бо ин сатр барнома all tests passed чоп мекунад.
Се навъи санҷишро интихоб кунед:
Муқаррарӣ: вуруди оддӣ, масалан, 2024.
Канорӣ: хурдтарин ё аҷибтарин вуруде, ки ваъда иҷозат медиҳад, масалан, 0, 1, рӯйхати холӣ ё соле, ки асрро анҷом медиҳад.
Нодуруст: вуруде, ки ваъда иҷозат намедиҳад, масалан, адади манфӣ. Функсия вазифадор нест, ки онро коркард кунад, вале бояд донед, ки чӣ мешавад.
Аксари хатоҳо дар канорҳо зиндагӣ мекунанд. Агар танҳо ҳолатҳои муқаррариро санҷед, канорҳоро довар месанҷад.
Ба мурғобӣ шарҳ диҳед Вақте дармондаед, барномаатонро бо овози баланд, сатр ба сатр, ба каси дигар шарҳ диҳед: ба дӯст ё ба бозичае, ки болои миз аст. Аксар вақт дар миёнаи ҷумла меистед: «ва дар ин ҷо d то... аҳа». Шарҳи кори ҳар сатр шуморо маҷбур мекунад онро санҷед, ба ҷои он ки он чизеро бихонед, ки гумон мекунед дар он ҷост.
Худатон озмоед Варақаи 1 барои бозии озод аст. Дар варақаҳои 2, 3 ва 4 барнома хато дорад ва машқ мегӯяд, ки он бояд чӣ кор кунад. Хатоҳо аз як сатр то барнома калон мешаванд. Дар варақаи 5 шумо санҷишҳо менависед.
Хатоҳоро шикор кунед санҷида бин! Аз нав
Кор дар синф
Вазифаи хонагӣ
Машқҳои лабораторияро, ки тамом накардаед, анҷом диҳед.
Агар муаллимтон супориш дода бошад, вазифаи хонагии онлайни «Python · Вазифаи хонагӣ · Модули 16.2»-ро дар саҳифаи Супоришҳо иҷро кунед.
Барномаи худатонро гиред, ки як вақт ҷавоби нодуруст дод. Ваъдаи функсияи асосии онро дар як ҷумла ва се санҷиши assert барояш нависед.
Хулоса
Се навъи мушкилот: барнома оғоз намешавад (SyntaxError), бо хато қатъ мешавад (traceback), ё кор мекунад ва ҷавоби нодуруст чоп мекунад. Traceback-ро аз поён бихонед.
Барои ҷавоби нодуруст: вуруди хурдтарин гиред, ҷавоби дурустро бо даст ҳисоб кунед, аз барнома пайравӣ кунед ва дар аввалин қадами фарқкунанда истед.
Чопи санҷишӣ print-и муваққатӣ дар sys.stderr аст. Сатри намерасидаи баромад низ нишона аст.
Бигӯед, ки функсия бояд чӣ кор кунад (ваъдаи он), баъд бо assert санҷед: ҳолати муқаррарӣ, ҳолати канорӣ ва ҳолати нодуруст.
Дармондаед? Барномаатонро сатр ба сатр ба мурғобӣ шарҳ диҳед.
Дар ин дарс
се навъи мушкилотро аз ҳам фарқ мекунед ва медонед, ки барои ҳар кадом аз куҷо ҷустуҷӯ кардан лозим аст;
traceback-ро мехонед, ки аз функсия мегузарад;
ҷавоби нодурустро бо пайравии дастии вуруди хурд ва бо чопҳои санҷишӣ меёбед;
мегӯед, ки функсия бояд чӣ кор кунад, ва барои он assert-санҷиш менависед.
Такрор (2 дақиқа) Ҳар яке аз инҳо кадом навъи мушкилот аст: барнома оғоз намешавад, барнома бо хато қатъ мешавад, ё барнома кор мекунад ва ҷавоби нодуруст чоп мекунад?
print("Hi"
print(10 / 0)
Барномае, ки бояд ҷамъи 2 ва 3-ро чоп кунад, 6 чоп мекунад.
Ҷавоб
Барнома оғоз намешавад: SyntaxError, як қавс ҳеҷ гоҳ баста нашудааст. 2. Бо хато қатъ мешавад: ZeroDivisionError. 3. Кор мекунад ва ҷавоби нодуруст чоп мекунад: хато дар мантиқ.
Вазъият барои андешаронӣ Барномаи шумо барои мисоли дуюм ҷавоби нодуруст чоп мекунад ва шумо онро се бор хондед: дуруст менамояд. Баъд чӣ кор мекунед? Пеш аз хондани идома ду фикр нависед.
Се навъи мушкилот ва ҷойи ҷустуҷӯ. 4.5
Traceback (most recent call last):
File "main.py", line 6, in <module>
print(average([]))
^^^^^^^^^^^
File "main.py", line 2, in average
return sum(a) / len(a)
~~~~~~~^~~~~~~~
ZeroDivisionError: division by zero
Вақте ҷавоб нодуруст аст
Вуруди хурдтаринро гиред. Хурдтарин вурудеро ёбед, ки ҳанӯз ҷавоби нодуруст медиҳад. Аз се адад пайравӣ кардан аз се ҳазор адад осонтар аст.
Ҷавоби дурустро бо даст ҳисоб кунед , пеш аз он ки бубинед барнома чӣ мекунад.
Аз барнома пайравӣ кунед бо ҳамин вуруд, сатр ба сатр, ва номҳояшро нависед. Дар аввалин қадаме истед, ки онҳо аз нақшаи шумо фарқ мекунанд. Хато дар ҳамон сатр ё дар пеш аз он аст.
Як чизро ислоҳ кунед ва ҳамаи мисолҳоро аз нав иҷро кунед.
Рӯйхати хатоҳои маъмул
return намерасад Функсия ҷавобро ҳисоб мекунад ва ҳеҷ гоҳ намебарорад: None бармегардад.
return дар дохили давр Як сархат дуртар, ва return дар давраи аввали давр иҷро мешавад.
Ҷавоби партофташуда order(x, y) дар сатри алоҳида: ҷавоб ба ҳеҷ ҷо намеравад. Нависед x, y = order(x, y).
range як қадам кӯтоҳ range(1, n) дар n − 1 қатъ мешавад. Шумораи гузаришҳоро бо даст дар вуруди хурд ҳисоб кунед.
Матн, на адад input() сатр медиҳад ва "10" < "9" True аст. Онро дар int() гиред.
Номе, ки функсия аз нав мебандад v = v + [x] рӯйхати нав месозад ва рӯйхати даъваткунанда ҳеҷ гоҳ калон намешавад. v.append(x) онро тағйир медиҳад.
Ададҳои манфӣ while n > 0 онҳоро мегузаронад. Ва -7 // 2 баробари −4 аст, дар ҳоле ки -7 % 2 баробари 1 аст.
Номи дарунсохт пинҳон шуд sum = 0 ё list = [] номи шуморо болои номи худи Python мемонад, ва sum(a)-и навбатӣ вайрон мешавад.
Оё медонед? «Rubber duck debugging» (ислоҳи хато бо мурғобии резинӣ) номи воқеии ин ҳиллаест. Он аз китоби The Pragmatic Programmer (1999) омадааст, ки дар бораи барномасозе нақл мекунад, ки мурғобии резинӣ дошт ва кодашро ба он шарҳ медод. Бисёр барномасозон ҳоло ҳам болои мизашон мурғобӣ доранд.
Калимаҳои калидӣ ҷудо кардан ба қисмҳо ёрирасон ёфтан ва ислоҳи хато traceback тест assert
Ман дар ин дарс чӣ омӯхтам? Кадом қадами усулро аксартар мегузаронед: вуруди хурдтарин, ҷавоби дуруст бо даст ё пайравӣ аз барнома? Дафъаи оянда чӣ тавр дигар мекунед?
Метавонед ё не? (✓ ё ✗):
Ман метавонам масъаларо ба вазифаҳо ҷудо кунам ва аввал барномаи асосиро нависам.
Ман traceback-ро аз поён хонда метавонам.
Ман метавонам аввалин қадамеро ёбам, ки барнома аз нақшаи ман дур мешавад.
Ман метавонам санҷиши assert барои ҳолати муқаррарӣ ва барои ҳолати канорӣ нависам.
def average ( a ) :
return sum ( a ) / len ( a )
print ( average ( [ 4 , 5 ] ) )
print ( average ( [ ] ) )
Барнома дар мисол то охир иҷро мешавад ва 41-ро чоп мекунад. Ҷавоби дуруст 42 аст. Ин чӣ гуна хато аст?
Як ҷавобро интихоб кунед A Хатои мантиқӣ B IndentationError C Хатои синтаксисӣ D Хато ҳангоми иҷро
Барномаи шумо дар мисоли дуюм ҷавоби нодуруст медиҳад. Кадом қадамҳо барои ёфтани хато кӯмак мекунанд? Ҳамаро интихоб кунед.
Ҳамаи мувофиқро интихоб кунед A Аз барнома бо ҳамин вуруд пайравӣ кунед ва дар аввалин қадами аз нақшаи шумо фарқкунанда истед. B Ҷавоби дурустро барои он бо даст ҳисоб кунед. C Тамоми барномаро аз сар нависед. D Хурдтарин вурудеро ёбед, ки ҳанӯз ҷавоби нодуруст медиҳад. E Бе ягон тағйирот боз пешниҳод кунед, шояд довар хато карда бошад.
Ваъдаи digit_sum(n) мегӯяд: «ҷамъи рақамҳои адади бутуни n-ро бармегардонад, барои n аз 0 боло». Кадом санҷиш ҳолати канорӣ аст?
Як ҷавобро интихоб кунед A assert digit_sum(45) == 9
B assert digit_sum(2024) == 8
C assert digit_sum(0) == 0
D assert digit_sum(123) == 6
Вақте ин барнома иҷро мешавад, чӣ рӯй медиҳад?
Як ҷавобро интихоб кунед A x is small ва баъд done чоп мекунад.
B Бо AssertionError: x is small қатъ мешавад ва дигар ҳеҷ чиз чоп намекунад.
C done чоп мекунад.
D Бо SyntaxError қатъ мешавад.
start 305
loop 30 5
loop 3 5
loop 0 8
305 -> 8
start -305
-305 -> 0
Traceback (most recent call last):
File "main.py", line 7, in <module>
assert is_leap(1900) == False, "1900"
^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1900
import sys
# ҷараёни хатоҳо
err = sys . stderr
def digit_sum ( n ) :
print ( "start" , n , file = err )
s = 0
while n > 0 :
s += n % 10
n //= 10
print ( "loop" , n , s , file = err )
return s
q = int ( input ( ) )
for _ in range ( q ) :
x = int ( input ( ) )
print ( x , "->" , digit_sum ( x ) )
def is_leap ( year ) :
return year % 4 == 0
assert is_leap ( 2024 ) == True
assert is_leap ( 2023 ) == False
assert is_leap ( 1900 ) == False , "1900"
print ( "all tests passed" )
Traceback (most recent call last):
File "main.py", line 9, in <module>
print(ratio(a, b))
^^^^^^^^^^^
File "main.py", line 4, in ratio
return a // b
~~^^~~
ZeroDivisionError: integer division or modulo by zero
s = 0
for i in range ( 1 , 10 , 3 ) :
s += i
x = 5
assert x > 10 , "x is small"
print ( "done" )