Algajate programmeerijate vead ehk algus on oluline
Ilmselt üks kõige rohkem uuritud teema programmeerimise hariduses on see, kuidas algaja programmeerija oma esimest programmeerimiskeelt õpivad ja millised raskusi see neile valmistab. Ainuüksi Google Scholari otsing fraasiga “novice programmers” annab üle 51 000 vaste. Samuti on seda uuritud juba 80ndate lõpust. Põhjused, mis on tekitanud säärase huvi selle teema vastu on mitmeid, kuid üks ilmselt kõige olulisem on see, et väga palju õpilasi kukuvad läbi oma esimese programmeerimise kursuse ja nende toetamiseks on vaja leida läbikukkumise põhjused. On leitud, et umbes 33% - 50% katkestab oma esimese programmeerimiskursuse (Bennedsen & Caspersen, 2007; Watson & Li, 2014), kuid viimaste aastate jooksul on läbikukkujate osakaal veidi vähenenud (Bennedsen & Caspersen, 2019). See ajendas teadlasi uurima milliseid vigu õpilased programmides teevad ja mis täpsemalt neile raskusi valmistab.
On analüüsitud algaja programmeerija programmides esinevaid vigu (Ettles et al, 2018, McCall & Kölling, 2014). Peamised vead, mida tehakse, võib jagada kahte rühma:
- Loogikavead - vead, mille puhul programm annab mitte sobivaid tulemusi, kuid programm käivitub ja kompileerub ilma veateateta.
- Käivitus- ja kompileerimiseaegsed vead - vead, mille kohta kuvatakse veateade ja programm lõpetab töötamise.
Kõige keerulisemad vead, mida pole lihtne programmist leida, on loogikavead. On leitud, et peamised loogikavead võib jagada kolme kategooriasse (Ettles et al, 2018):
- Algoritmilised - algoritm, mida õpilane püüab programmis probleemi lahendamisel kasutada, on põhimõtteliselt vale või vigane. Need vead on tihti seotud sellega, et õpilase matemaatika teadmised ei ole piisavad. Näiteks võib selline viga tekkida siis, kui on vaja omavahel võrrelda kolme arvu ja nendest leida kõige suurem, kuid viis kuidas õpilane seda teeb, on vigane.
- Valesti tõlgendamised - õpilane teeb vea, sest ei ole ülesande küsimusest õigesti aru saanud. Näiteks tagastab funktsioon vale väärtuse, mis ei ole ülesandes nõutud.
- Väärarusaamad - loogikaviga, mis tekib sellest, et õpilase programmeerimise teadmistes on viga. Näiteks arvab õpilane, et indekseerimine algab 1-st.
Sama uuringu tulemustest leiti ka seda, et kõige rohkem tehti vigu, mis olid seotud väärarusaamadega, ning õpilastel oli kergem parandada algoritmidega ja valesti tõlgendamisega seotud vead. Selle uuringu tulemused näitavad seda, et oluline on juba programmeerimise õppimise alguses leida õpilaste väärarusaamad ja püüda neid muuta. Samuti toetada neid ülesande tõlgendamisel ja selles, kuidas luua programm, mis selle ülesande lahendab.
Sagedasemad vead
Ilmselt kõige sagedasemad vead, mida õpilased teevad programmeerimiskeele õppimisel, on süntaksiga seotud vead. Käivitus- ja kompileerimisaegseid vigu on uuritud erinevate programmeerimiskeelte puhul. Selles materjalis keskendume peamiselt Pythoni programmeerimiskeelega seotud vigadele.
Järgmisena esitatakse kõige sagedasemad vead, mida algajad võivad teha, kuid see nimekiri ei pruugi olla lõplik (Kohn, 2017):
- Sobimatud muutuja nimed, näiteks
uus järjend
. - Vasakult paremale omistamine. Näiteks arvatakse, et
m = 1
on samaväärne, mis1 = m
. - Sobimatute avaldiste koostamine muutujate omistamisel. Näiteks
m = n += 1
. Põhjuseks on see, etm += 1
on lubatud kirjaviis ja selle eeskujul koostatakse sarnaseid omistuslauseid. - Avaldiste kasutamine funktsiooni parameetritena. Näiteks
def fun(m+2, n*2):
. - Literaali kasutamine muutuja asemel. Näiteks
a = 1 print("a")
- Puuduvad või üleliigsed tühikud. Näiteks
deffun(a):
. - Vigane else-haru. Näiteks koos tingimusega
else a > 5:
või if-haru seesif a > 5: else: print(1)
- Puuduvad või üleliigsed jutumärgid/ülakomad. Näiteks
def "fun"(a):
võiMaria
(sõnena). - Täisarvulise ja jäägiga jagamisega seotud vead.
%
-märgi kasutamine tundub jäägi leidmiseks ebaintuitiivne ja seega aetakse seda segamini täisarvulise jagamisega//
või jagamisega/
. Näiteksm // 2 == 0
. and
tehte ebasobiv kasutus. Näiteksreturn m and n
.- Vale või üleliigne võtmesõna. Näiteks
for m >= 1:
võidef fun(6)
(funktsiooni väljakutse). - Vigane programmistuktuur. Näiteks defineeritakse funktsioon tsükli sees.
while m > 5: def liida(n): return n + 1
- Lõpetamata sulud. Näiteks
print("Tere1"
. - Valesti kirjutatud muutuja/funktsiooni nimed või võtmesõnad. Näiteks
m = 0 M +=1 pint(m)
- Võtmesõnade kasutamine muutuja nimedena. Näiteks
else = 5
. - Võrdsuse kontrollimiseks kasutatakse ühekordset
=
-märki, mitte==
. Näiteksif m = 0:
. - Ära vahetatud tehte operaatorid. Näiteks
m =+ 1
. - Lõpetamata sõne. Näitkes
m = "a
. - Puuduv koolon, koma või tehtemärk. Näiteks
if m == 1 # koolon puudu print("Tulemus:" 2m) # koma ja tehtemärk puudu
- Ebakorrektsed taanded. Näiteks
if m > 5: print("Suurem kui 5")
- Lisatakse laused peale return- ja break-lauseid vastavalt funktsiooni või tsükli sisse, teadmata, et neid ei täideta. Näiteks
def fun(m): return m + 2 n = m**2
- Funktsiooni väljakutse on ilma sulgudeta või on funktsiooni nimi puudu. Näiteks
fun
. - Mittevajalike lausete kasutamine. Näiteks
min(m) # pole vajalik miinimum = min(m)
- Ebasobivate võrdluste kasutamine. Näiteks
m > 3 == True:
. - Muutujate, parameetrite ja funktsioonide nimede taaskasutamine erinevas kontekstis. Näiteks kasutatakse funktsiooni nime parameeteri nimena. Näiteks
def liida(input): return input + 2
Veateadete analüüs
Programmeerimise õppimise alguses süntaksivead olla väga frustreerivad ja õpimotivatsioon võib langeda, sest õpilane ei oska veateateid lugeda ning vigu tekib liiga tihti. Seetõttu on vajalik juba alguses õpetada ka veateadete lugemist ja selgitada, et vigade tegemine on loomulik. Samuti, kui teame, millised on sagedasemad vead, mida algajad teevad, siis oskame neile ka tähelepanu pöörata ja õpetada nendega toime tulemist.
Järgmisena vaatame lähemalt Pythoni veateadet ja selle osasid. Näitena kasutame süntaksiviga, mis on põhjustatud sellest, et on unustatud jutumärgid või ülakomad lisada.
Traceback (most recent call last): File "/Users/Kasutaja/PÕGA/guido.py", line 1 → viide probleemsele reale punktid = input(Sisesta punktisumma:) → probleemne rida ^ → vea asukoht SyntaxError: invalid syntax → vea sõnum ↑ veatüüp
Viis kõige sagedasemat veatüüpi, mida algajad programmeerijad võivad teha, on järgmised (Kelley, 2018; Kohn, 2019; Pritchard, 2015; Smith and Rixner, 2019):
- SyntaxError (süntaksiviga) - eksimused Pythoni süntaksi reeglite vastu
- NameError (nimeviga) - vastava nimega muutuja/funktsioon ei ole defineeritud
- TypeError (tüübiviga) - püütakse rakendada tehted või funktsioone, mida andmetüüp ei toeta
- IndentationError (taandeviga) - vale treppimisega seotud vead
- IndexError (indeksviga) - püütakse kasutada järjestatud jada indekseid, mis ei kuulu selle indeksite hulka
(Errors and Exceptions, 2001)
Uurime iga veatüübi teadet ja millist infot see pakub, et programmi parandada.
1. Süntaksiviga
Traceback (most recent call last): File "/Users/Kasutaja/PÕGA/guido.py", line 2 if a > 1; ^ SyntaxError: invalid syntax
a = 10 if a > 1; print("Suurem kui 1")
Veateatest on näha, et viga asub 2. real ja vea asukoht on if
-päise lõpus. Näeme, et kasutatud on semikoolonit kooloni asemel.
2. Nimeviga
Traceback (most recent call last): File "Users/Kasutaja/PÕGA/guido.py", line 4, in <module> print(aste) NameError: name 'aste' is not defined
astme_alune = int(input("Palun sisestage astme alus: ")) astendaja = int(input("Palun sisestage astendaja: ")) vastus = astme_alune ** astendaja print(aste)
Veateate järgi on viga 4. real, kus püütakse väljastada muutuja väärtust, kuid vastavat muutujat ei ole. Parandamiseks peab programmis vastava muutuja defineerima. Vastav muutuja võib olla ka valesti print
-lauses kirjutatud.
3. Tüübiviga
Traceback (most recent call last): File "/Users/Kasutaja/PÕGA/guido.py", line 4, in <module> lause = aasta + lause_keskosa + liblikas TypeError: unsupported operand type(s) for +: 'int' and 'str'
aasta = 2020 liblikas = "teelehe-mosaiikliblikas" lause_keskosa = ". aasta liblikas on " lause = aasta + lause_keskosa + liblikas print(lause)
Viga on 4. real, kus on püütud sõnesid kokku liita. Vea sõnum vihjab sellele, et püütud on liita täisarvu ja sõnet, mis ei ole lubatud operatsioon. Vea parandamiseks tuleb vaadata, millist tüüpi on liidetavad muutujad. aasta
muutuja väärtus on täisarv, lause_keskosa
ja liblikas
on sõned. Seega peab aasta väärtuse teisendama sõneks → lause = str(aasta) + lause_keskosa + liblikas
.
4. Taandeviga
Traceback (most recent call last): File "/Users/Kasutaja/PÕGA/guido.py", line 6 print("Kiri on spämm") ^^^^^ IndentationError: expected an indented block after 'if' statement on line 5
suurus = float(input("Kirja suurus MB: ")) pealkiri = input("Pealkiri: ") fail = input("Kas on fail kaasa? (jah/ei) ") if pealkiri == "" or suurus > 1 and fail == "jah": print("Kiri on spämm") else: print("Kiri ei ole spämm")
Viga on 6. real. Sõnumis on kirjas, et print
-lause ees peaks olema taane, kuid see puudub.
5. Indeksviga
Traceback (most recent call last): File "/Users/Kasutaja/PÕGA/guido.py", line 3, in <module> print(nimed[3]) IndexError: list index out of range
nimed = ["Sander", "Külli", "Mario"] print(nimed[3])
Veateade viitab, et viga on 3. real, kus püütakse väljastada elementi indeksi abil, kuid sellise indeksiga elementi ei ole järjendis. Tüüpiliselt on selliste vigade põhjuseks see, et ei teata, et indekseerimine algab 0-st.
Allikad
Bennedsen, J. & Caspersen, M. E. (2007). Failure rates in introductory programming. ACM SIGCSE Bulletin, 39(2), 32–36.
Bennedsen, J., & Caspersen, M. E. (2019). Failure rates in introductory programming: 12 years later. ACM Inroads, 10(2), 30–36. https://doi.org/10.1145/3324888
Errors and Exceptions. (2001). Python 3.9.0 Documentation. https://docs.python.org/3/tutorial/errors.html
Ettles, A., Luxton-Reilly, A., & Denny, P. (2018, January). Common logic errors made by novice programmers. In Proceedings of the 20th Australasian Computing Education Conference (pp. 83-89).
Kelley, A. K. (2018). A system for classifying and clarifying python syntax errors for educational purposes (Doctoral dissertation, Massachusetts Institute of Technology).
Kohn, T. (2017). Teaching Python Programming to Novices: Addressing Misconceptions and Creating a Development Environment. https://doi.org/10.3929/ethz-a-010871088
Kohn, T. (2019). The Error Behind The Message: Finding the Cause of Error Messages in Python. Proceedings of the 50th ACM Technical Symposium on Computer Science Education, 524–530. https://doi.org/10.1145/3287324.3287381
McCall, D., & Kolling, M. (2014). Meaningful categorisation of novice programmer errors. 2014 IEEE Frontiers in Education Conference (FIE) Proceedings, 1–8. https://doi.org/10.1109/fie.2014.7044420
Pritchard, D. (2015, October). Frequency distribution of error messages. In Proceedings of the 6th Workshop on Evaluation and Usability of Programming Languages and Tools (pp. 1-8).
Smith, R., & Rixner, S. (2019). The Error Landscape: Characterizing the Mistakes of Novice Programmers. Proceedings of the 50th ACM Technical Symposium on Computer Science Education, 538–544. https://doi.org/10.1145/3287324.3287394
Watson, C. & Li, F. W. (2014). Failure rates in introductory programming revisited. In Proceedings of the 2014 Conference on Innovation & Technology in Computer Science Education (pp. 39–44). New York, NY: ACM.