Python Vadovėlis/Derinimas
Kas yra derinimas?
- „Pradėjus programuoti supratau, kad nėra taip lengva kurti teisingai veikiančias programas. Atsimenu akimirką, kai supratau, kad didedė dalis mano gyvenimo, bus skirta klaidų ieškojimui mano paties kurtose programose. Taip atsidaro derinimas.“ — Maurice Wilkes atranda derinimą, 1949
Jei jau bandei parašyti kelias programas, turbūt pastebėjai, kad kartais programa daro ką nors, ko neturėtų daryti. Tai yra tikrai dažna situacija. Derinimas tai yra procesas, kuomet bandoma suprasti, ką kompiuteris daro ir kaip jį priversti daryti tai, ką norėtum, kad jis darytų. Tai gali būti sudėtinga. Vieną kartą aš praleidau beveik savaitę ieškodamas ir taisydamas klaidą, kurią sukėlė kitas žmogus, kode parašęs x
vietoje y
.
Ši dalis bus abstraktesnė, nei prieš tai buvusios dalys.
Ką turėtų daryti programa?
Pirmas dalykas, ką reikia padaryti (kad ir kaip akivaizdžiai tai skamba), tai suprasti, ką turėtų daryti teisingai veikianti programa. Sugalvok kelis tikrinimo scenarijus ir pažiūrėk, kas nutiks. Tarkime, kad aš noriu sukurti programą, kuri suskaičiuoja stačiakampio perimetrą (visų kraštinių sumą). Turiu tokius tikrinimo scenarijus:
aukštis | plotis | perimetras |
---|---|---|
3 | 4 | 14 |
2 | 3 | 10 |
4 | 4 | 16 |
2 | 2 | 8 |
5 | 1 | 12 |
Dabar galiu vykdyti savo programą su visais tikrinimo scenarijais ir pamatyti, ar programa daro tai, ko tikiuosi. Jei ne, turiu suprasti, ką iš tiesų daro kompiuteris.
Dažniausiai, dalis tikrinimo scenarijų veikia, dalis - ne. Jei toks yra ir tavo atvejis, turėtum bandyti suprasti, ką veikiantys scenarijai turi bendro. Pavyzdžiui, apačioje yra perimetro programos išvestis (kodas bus pateiktas kiek vėliau):
Aukštis: 3 Plotis: 4 Perimetras = 15
Aukštis: 2 Plotis: 3 Perimetras = 11
Aukštis: 4 Plotis: 4 Perimetras = 16
Aukštis: 2 Plotis: 2 Perimetras = 8
Aukštis: 5 Plotis: 1 Perimetras = 8
Gali pastebėti, kad programa neveikė su pirmomis dvejomis įvestimis, veikė su sekančiomis dvejomis ir vėl neveikė su paskutine. Pabandyk sugalvoti, kas yra bendro tarp veikiančių scenarijų. Kai supranti, kokia yra programos problema, atrasti jos priežastį yra daug lengviau. Jei reikia, savo programoms gali sugalvoti ir daugiau tikrinimo scenarijų.
Ką daro programa?
Kitas dalykas, ką reikia padaryti, tai peržiūrėti pirminį programos tekstą. Tai vienas iš svarbiausių dalykų programavime. Pagrindinis būdas, kaip tai daroma - tai kodo peržiūros.
Kodo peržiūra prasideda pirma eilute ir tęsiasi iki programos galo. while
ciklai ir if
sakiniai reiškia, kad kai kurios eilutės gali būti nekviečiamos niekada, o kai kurios - vykdomos keletą kartų. Kiekvienoje eilutėje turi suprasti, ką daro Python'as.
Pradėkime su paprasta parametro programa. Šios programos nerašyk. Tau reikės ją tik skaityti, ne vykdyti. Programos pirminis tekstas:
aukstis = int(input("Aukštis: "))
plotis = int(input("Plotis: "))
print("perimetras =", plotis + aukstis + plotis + plotis)
- Klausimas: Kuri eilutė vykdoma pirma?
- Atsakymas: Pirmoji kodo eilutė visada yra vykdoma pirma. Šiuo atveju tai:
aukstis = int(input("Aukštis: "))
- Ką daro ši eilutė?
- Spausdina
Aukštis:
, laukia, kol naudotojas įves teksto eilutę ir ją konvertuoja į sveikąjį kintamąjįaukstis
. - Kuri eilutė vykdoma po to?
- Bendrai, tai yra kita eilutė, kuri yra
plotis = int(input("Plotis: "))
- Ką daro ši eilutė?
- Spausdina
Plotis:
, laukia, kol naudotojas įves teksto eilutę ir ją konvertuoja į sveikąjį kintamąjįplotis
. - Kuri eilutė vykdoma po to?
- Kai kita eilutė nėra daugiau ar mažiau įtraukta, nei esama eilutė, ji ir yra vykdoma. Šiuo atveju tai:
print("perimetras =", plotis + aukstis + plotis + plotis)
(Taip pat gali būti kviečiama funkcija esamoje eilutėje, bet tai bus paaiškinta tolimesniame skyriuje) - Ką daro ši eilutė?
- Visų pirma, ji spausdina
perimetras =
, o tada - sumą, sudarytą iš kintamųjųplotis
iraukstis
, kuri užrašoma taip:plotis + aukstis + plotis + plotis
. - Ar kodas
plotis + aukstis + plotis + plotis
skaičiuoja perimetrą teisingai? - Pažiūrėk: stačiakampio perimetras yra apatinė kraštinė (plotis), plius kairė (aukstis), plius viršutinė (plotis), plius dešinė kraštinė (a?). Paskutinis kintamasis turėtų būti dešinės kraštinės ilgis, arba kitaip - aukštis.
- Ar supranti, kodėl, kai kuriais atvejais, skaičiuojant perimetrą buvo gaunamas teisingas atsakymas?
- Teisingas atsakymas buvo gaunamas kai aukštis ir plotis buvo lygūs.
Kita programa, kurios kodo peržiūrą darysime, tai programa, kuri turėtų ekrane išvesti 5 taškus. Tačiau, programos išvestis yra:
. . . .
Programa:
skaicius = 5
while skaicius > 1:
print(".", end = " ")
skaicius = skaicius - 1
print()
Šios programos peržiūra bus kiek sudėtingesnė, nes joje yra įtrauktų kodo dalių. Pradėk.
- Kuri eilutė vykdoma pirma?
- Pirmoji kodo eilutė:
skaicius = 5
- Ką ji daro?
- Priskiria skaičių 5 kintamajam
skaicius
. - Kuri eilutė vykdoma po to?
- Kita eilutė yra:
while skaicius > 1:
- Ką ji daro?
- Na,
while
sakiniai žiūri į juose esančius reiškinius. Jei jie yra tesingi, vykdomas kitas įtrauktas blokas. Jei klaidingi – įtrauktas blokas yra praleidžiamas. - Tai ką ji daro šiuo atveju?
- Jei
skaicius > 1
yra teisinga, bus vykdomos kitos dvi eilutės. - Taigi, ar
skaicius > 1
? - Paskutinė vertė, kuri buvo priskirta
skaicius
buvo5
ir5 > 1
, taigi – taip. - O kuri eilutė vykdoma po to?
- Kadangi
while
buvo teisinga, tai kita eilutė yra:print(".", end = " ")
- Ką daro ši eilutė?
- Spausdina vieną tašką. Kadangi funkcija turi papildomą argumentą
end = " "
, toliau spausdinamas tekstas nebus pradedamas naujoje eilutėje. - Kuri eilutė vykdoma po to?
skaicius = skaicius - 1
, nes tai yra kita eilutė ir nėra jokių įtraukos pasikeitimų.- Ką ji daro?
- Eilutė skaičiuoja
skaicius - 1
: iš esamosskaicius
vertės (5) atimamas 1, ir tai tampa nauja kintamojoskaicius
reikšmė. Sutrumpintai,skaicius
vertė yra pakeičiama iš 5 į 4. - Kuri eilutė vykdoma po to?
- Įtraukos lygis keičiasi, todėl turi žiūrėti į tai, kokią valdymo struktūrą turime. Peržiūrėk
while
ciklą, taigi turi grįžti įwhile
sąlygą, kuri yrawhile skaicius > 1:
- Ką ji daro?
- Eilutė žiūri į
skaicius
reikšmę, kuri yra 4, ir lygina ją su 1. Kadangi4 > 1
, ciklas tęsiasi. - Kuri eilutė vykdoma po to?
- Kadangi ciklo sąlyga buvo teisinga, kita eilutė yra:
print(".", end = " ")
- Ką ji daro?
- Ekrane išspausdina dar vieną tašką, po jo padėdama tarpą.
- Kuri eilutė vykdoma po to?
- Nėra įtraukos pokyčio, todėl:
skaicius = skaicius - 1
- Ir ką ji daro?
- Ima dabartinę
skaicius
reikšmę (4), atima 1, kas yra lygu 3 ir priskiria 3 kaip naująskaicius
reikšmę. - Kuri eilutė vykdoma po to?
- Kadangi turime įtraukos pokytį dėl ciklo, kita eilutė yra:
while skaicius > 1:
- Ką ji daro?
- Palygina dabartinę
skaicius
reikšmę (3) su 1.3 > 1
, todėl ciklas tęsiasi. - Kuri eilutė vykdoma po to?
- Kadangi ciklo sąlyga yra teisinga, kita eilutė:
print(".", end = " ")
- O ji daro?
- Trečias taškas yra spausdinamas eilutėje.
- Kuri eilutė vykdoma po to?
- Tai:
skaicius = skaicius - 1
- Ką ji daro?
- Ima dabartinę
skaicius
reikšmę (3), atima 1, kas yra lygu 2 ir priskiria 2 kaip naująskaicius
reikšmę. - Kuri eilutė vykdoma po to?
- Vėl grįžtame į ciklo pradžią:
while skaicius > 1:
- Ką ji daro?
- Palygina dabartinę
skaicius
reikšmę (2) su 1.2 > 1
, todėl ciklas tęsiasi. - Kuri eilutė vykdoma po to?
- Kadangi ciklas tęsiasi:
print(".", end = " ")
- Ką ji daro?
- Atranda atsakymą gyvenimui, Visatai, ir viskam. Juokauju (turėjau patikrinti, kad dar neužmigai). Eilutė spausdina ketvirtą tašką ekrane.
- Kuri eilutė vykdoma po to?
- Tai:
skaicius = skaicius - 1
- Ką ji daro?
- Ima dabartinę
skaicius
reikšmę (2), atima 1, kas yra lygu 1 ir priskiria 1 kaip naująskaicius
reikšmę. - Kuri eilutė vykdoma po to?
- Atgal į ciklo pradžią:
while skaicius > 1:
- Ką daro ši eilutė?
- Ji palygina
skaicius
reikšmę (1) to 1. Kadangi1 > 1
yra klaidinga (vienas nėra daugiau nei vienas), ciklas baigiasi. - Kuri eilutė vykdoma po to?
- Kadangi ciklo sąlyga buvo klaidinga, vykdoma kita eilutė esanti už ciklo. Tai yra:
print()
- Ką daro ši eilutė?
- Priverčia teksto žymeklį ekrane peršokti į kitą eilutę.
- Kodėl programa nespausdina 5 taškų?
- Ciklas baigiasi vienu tašku per anksti.
- Kaip tai sutvarkyti?
- Priversti ciklą baigtis vienu tašku vėliau.
- Ir kaip tai padaryti?
- Yra keli būdai. Vienas iš jų yra pakeisti ciklo sąlygą į:
while skaicius > 0:
. Kitas būdas pakeisti sąlygą į:skaicius >= 1
. Yra ir daugiau būdų.
Kaip turėčiau taisyti savo programą?
Tau reikia suprasti, ką programa daro. Tau reikia suprasti, ką programa turėtų daryti. Suprasti, koks skirtumas tarp šių dviejų dalykų. Derinimas - tai įgūdis, kurį norint išmokti, reikia daug praktikos. Jei po valandos nepavyksta išspręsti problemos, pailsėk, pakalbėk su kuo nors apie tai. Po kurio laiko sugrįžk prie problemos ir greičiausiai turėsi naujų minčių, kaip ją įveikti. Sėkmės.