Pythoni põhimõisted
Sissejuhatus
Esimese peatüki eesmärk on tutvustada Pythoni põhilisi töövahendeid ning anda üldine ülevaade programmeerimise olemusest ja võimalustest.
Käesolevas kursuses soovitame kasutada algajatele mõeldud Pythoni programmeerimiskeskkonda Thonny. Pythoni programme võiks vabalt kirjutada näiteks Notepadi või mõne muu üldotstarbelise tekstiredaktoriga, kuid Thonny on selle töö jaoks palju sobivam.
Thonny saad installeerida siit: https://thonny.org/
Alustuseks kirjutame ühe väga lihtsa programmi, mis ei tee muud, kui kirjutab ekraanile Tervist!.
Thonny esmakordsel avamisel peaks olema kohe tühi redaktor uue programmi kirjutamiseks. Esimeseks katsetuseks kirjuta või kopeeri sinna järgnev üherealine programmitekst:
print("Tervist!")
Salvesta fail (Ctrl+S) lisades failinime lõpus laiendi py, nt tervist.py. (NB! Soovitatav on juba praegu teha oma programmeerimisharjutuste jaoks eraldi kaust.) Taolist Pythoni programmi sisaldavat tekstifaili nimetame edaspidi skriptiks. Programmi käivitamiseks vajuta klaviatuuril F5. Akna allservas olevasse käsurea paneeli peaks tekkima uus rida tekstiga Tervist!.
Nagu võid järeldada, tähendab print Pythoni jaoks teksti ekraanile kuvamist, mitte printerisse saatmist. Selleks, et Python suudaks teha vahet käskudel ja tavalisel tekstil, kirjutatakse tekst jutumärkide vahele.
Pythoni käsurida
Programmeerida saab ka käsureal, ilma et programmi peaks skriptina salvestamata. Selline programmeerimise viis sobib väiksemate ülesannete lahendamiseks ning Pythoni võimaluste katsetamiseks. Kuna käske antakse ühekaupa ja tulemus näidatakse kohe järgmisel real, nimetatakse seda ka interaktiivseks programmeerimiseks.
Thonnys on käsurida alati nähtav. Käsuviip >>> näitab kohta, kuhu saab kirjutada Pythoni käsu – vajutades ENTER, see käsk täidetakse. Järgnev näide on kopeeritud käsurealt, kuhu sisestati kaks käsku print("Tervist!") ja print(23*454):
>>> print("Tervist!") Tervist! >>> print(23*454) 10442
Märkus: Edaspidi tuleb meil näiteid nii käsurea kui ka skriptide (st faili salvestatud programmide) kohta. Kui näide algab käsuviibaga (>>>), siis esitab see käsurea dialoogi. Vastasel juhul on tegemist skriptiga. NB! Käsureal kasutatakse käsuviiba märki vaid selleks, et oleks kergem eristada, millistel ridadel on käsud ja millistel on vastused. Seda ei ole vaja kunagi ise kirjutada. Skriptis ei kasutata seda märki kunagi.
Vigadest
Veel enne katsetamist on hea teada, et veateated on programmeerimises tavapärane nähtus. Kuna arvutiga ei saa suhelda nagu inimesega, siis kui teha kasvõi kõige väiksem viga näiteks vormistuses, siis ei oska Python enam midagi teha. See on tema viis ütlemiseks, et ma ei saa täpselt aru, mis sa minust tahad.
Kaks peamist veatüüpi, millega alguses kokku võib puutuda:
Süntaksivea (ingl syntax error) korral ei saa Python programmi tekstist aru ja seetõttu ei hakka ta programmi üldse käivitama. Veateade ütleb Python selle rea kohta, kust ta enam edasi lugeda ei osanud, tegelik vea põhjus on tihti hoopis eelneval real. Üks tüüpilisemaid süntaksivigu on puuduv lõpetav sulg – kuigi iga programmeerija saab aru, mida on mõeldud lausega x = 3 + (4 * 5, on see Pythoni jaoks täiesti mõttetu tekst, sest see ei vasta Pythoni reeglitele. Teisiti öeldes, Python (nagu ka iga teine programmeerimiskeel) on suur tähenärija ning sellega tuleb arvestada – programmi kirjutamisel tuleb olla täpne!
Täitmisaegse vea (ingl runtime error) puhul programm küll käivitati, aga mingi konkreetse käsu täitmine ebaõnnestus. Vigaseks käsuks võis olla näiteks nulliga jagamine, valesti kirjutatud funktsiooninime kasutamine, olematu faili lugemine vms. Kui sa pole siiani ühtki täitmisaegset veateadet näinud, siis sisesta käsureal käsk prin("Tere!"). Täitmisaegseid vigu nimetatakse tihti ka erinditeks (ingl exception).
Märkus: Täitmisaegses veateates on tavaliselt mitme rea jagu infot, mis on abiks kogenud programmeerijale, aga võib algajal silme eest kirjuks võtta. Sellest ei tasu lasta ennast heidutada – enamasti piisab vaid veateate viimase rea lugemisest. Lisaks probleemi kirjeldusele on veateates alati ka reanumber, mis viitab vea tekitanud reale programmi tekstis. (Käsureal töötades on aktiivse käsu reanumber alati 1.) Paraku tuleb algajatel vahel ka veateate viimase rea üle pead murda – hea näide on see, kui sulle öeldakse käsu cos(pi) peale NameError: name "cos" not defined. Sisuline põhjus pole siin mitte see, et käsk cos vale oleks, vaid see, et sa unustasid eelnevalt cos funktsiooni importida. (Ei, Python ei soovi programmeerijaid segaste teadetega kiusata – kui õpid tundma Pythoni tööpõhimõtteid, siis paistab ka sulle antud veateate sõnastus täiesti loomulik.)
Veateateid näed sa oma programmeerimise karjääri jooksul väga palju, seega ei maksa neid karta. Lähtu sellest, et iga veateade on mõeldud programmeerija abistamiseks – loe teate tekst (või vähemalt viimane rida) alati hoolikalt läbi ja mõtle, milles võis probleem olla. Nii märkad varsti, et Pythoni veateadete salakiri on muutunud arusaadavaks ja kasulikuks informatsiooniks.
Laused ja avaldised
Pythoni programmid koosnevad lausetest, mis on olemuselt väga sarnased loomuliku keele käskiva kõneviisi lausetega – iga lausega (nt y = 123 või print("Tervist!")) annab programmeerija Pythonile mingi korralduse. Lihtsamate lausete puhul tähendab üks Pythoni koodi rida ühte lauset ja programmi käivitamisel täidab Python laused sellises järjekorras, nagu need on programmitekstis esitatud (edaspidi tutvume ka lausetega, mis võivad võtta enda alla palju ridu ja võimaldavad keerulisemaid käskude järjestamise skeeme).
Nii nagu loomulikus keeles moodustatakse laused omakorda sõnadest ja fraasidest, pannakse ka Pythoni laused kokku väiksematest keele elementidest, millest kõige olulisemad on avaldised.
Avaldised on näiteks: Lihtne arvutustehe, nt 2 + 3 või sin(0.5); „Arvutustehe“ teksti ja muutujaga, nt "Tere " + nimi + "!"; Lihtsalt muutuja, nt x või nipitiri; Lihtsalt arv, nt 123 või 3.987; Lihtsalt tekst, nt "Tervist!"; Mingi käsk, mis annab mingi tulemuse, nt input("Sisesta mingi täisarv: "); Ükskõik kui keeruline kombinatsioon eelnevatest, nt sin(int(y) * x / 1.76).
Avaldised esinevad enamasti mingi lause komponendina – nt avaldist 2 + 3 võib kasutada lauses x = 2 + 3 või lauses print(2 + 3).
Kui me eespool demonstreerisime Pythoni paindlikkust loetledes erinevaid võimalikke print käsu kasutamise vorme, siis uue terminoloogia abil saame seda väljendada palju lühemalt: print-käsu järel olevatesse sulgudesse võime kirjutada suvalise avaldise. Samamoodi saab öelda muutuja defineerimise kohta: võrdusmärgist paremale võib kirjutada suvalise avaldise.
Iga avaldist, ükskõik kui keerulist, saab kasutada veel keerulisema avaldise moodustamiseks, nt avaldistest 1 ja x * 3 saab moodustada avaldise x * 3 - 1. Sama põhimõtet teiselt poolt vaadates võime öelda, et iga keeruline avaldis koosneb lihtsamatest avaldistest ehk alamavaldistest.
Väärtused
Tähelepanelikul lugejal võib tekkida õigustatud küsimus: miks ilmub lause print(2 + 3) käivitamisel ekraanile 5, mitte 2 + 3? Asi on selles, et avaldist sisaldava lause käivitamisel arvutab Python kõigepealt tulemuse välja ja kasutab siis seda esialgse avaldise asemel. Arvutuse tulemust nimetatakse väärtuseks (ingl value) ning arvutusprotsessi avaldise väärtustamiseks (ingl evaluation).
Väärtused (nt arv 5, arv 3.141592653589793, tekst Tere!) on need reaalsed andmed, mida programm oma töö käigus kasutab, loob, arvutab, teisendab vms. Võib öelda, et avaldised tähistavad mingisuguseid asju (arve, tekstijuppe) programmi tekstis, aga väärtused on need asjad programmi jooksutamise ajal. Väärtustamine genereerib avaldisele vastava väärtuse.
Avaldised käsureal: Üldjuhul ei ole eraldiseisev avaldis (nt 2 + 3) Pythoni jaoks mõistlik lause (nii nagu eesti keeles ei saa üksikut fraasi, nt „suur mets“, pidada lauseks). Seetõttu, nagu eespool mainitud, on avaldised harilikult mingi lause komponendid (nt vastus = 2 + 3). Pythoni käsurida aga võimaldab avaldisi väärtustada ka ilma neid mingi lause konteksti panemata – see on mugav viis erinevate tehete katsetamiseks. Kuna antud peatüki esimeses pooles keskendumegi just avaldiste ja väärtuste teemale, siis eelistame praegu skripti koostamise asemel käsurea kasutamist:
>>> 2 + 3 5
Andmetüübid, tehted ja muutujad
Eelnevatest näidetest tuli välja, et Python oskab kasutada erinevat liiki andmeid ehk väärtusi nagu teksti, täisarve ja murdarve. Andmete liiki nimetatakse programmeerimisel andmetüübiks või lihtsalt tüübiks.
Iga andmetüübi juures on esimene küsimus, kuidas panna kirja selle andmetüübi konkreetseid väärtusi. Siin tuleb lihtsalt teada vastavaid reegleid, nt kümnendmurru esitamisel tuleb koma asemel kasutada punkti ning tekst tuleb panna ülakomade vahele või jutumärkidesse. Sedasi programmi teksti sisse kirjutatud konkreetseid väärtusi nimetatakse peenemas keeles literaalideks, aga neid võib nimetada ka konstantideks.
Teine küsimus on, mida antud tüüpi andmetega teha saab. Siin tuleb jällegi teada Pythoni võimalusi – näiteks arve saab omavahel liita, teksti saab teisendada suurtähtedesse ning kõiki andmetüüpe saab käsuga print ekraanile kuvada. Selliseid toiminguid nimetatakse teheteks ehk operatsioonideks.
Tähtis mõiste on veel muutuja. Kerge on seda sassi ajada varasemate matemaatikateadmistega, aga muutuja programmeerimiskeeles on täiesti teine asi. Muutujaid kasutatakse väärtuste salvestamiseks.
Näide:
a = 15 b = 13 muutuja = a + b
Näites on muutujad: a, b ja muutuja. Muutuja võib salvestada ka teiste muutujate väärtuseid
Pythoni jaoks on ükskõik, millise nime sa mingi muutuja jaoks valid, aga programmi loetavuse huvides peaks nimi kirjeldama muutuja tähendust antud ülesande kontekstis (nt brutopalk või isikukood). Kui on tarvis kasutada mitmest sõnast koosnevat muutujanime, siis tuleks kasutada tühikute asemel allkriipse, nt laste_arv. Muutujanimes võib kasutada ka numbreid, aga esimene sümbol peab olema täht (või allkriips).
Arvud
Pythonis (nagu ka enamikus teistes programmeerimiskeeltes) käsitletakse täisarve ja reaalarve veidi erinevalt.
Täisarvud
Pythoni täisarvu andmetüübi nimi on int (lühend ingliskeelsest sõnast integer). Erinevalt paljudest teistest keeltest ei ole Python 3-s piiratud, kui suuri (või kui väikseid) täisarve saab esitada.
Ujukomaarvud
Reaalarvudele vastavad Pythonis (ja paljudes teistes keeltes) nn ujukomaarvud (ingl floating point number, lühemalt float). Näiteks võib ujukoma esineda nii: 3.0, 1.653. NB! Koma asemel kasutatakse punkti!
Ujukomaarvude ligikaudsus Proovi läbi järgnev lihtne näide:
>>> 0.1 * 3.0 0.30000000000000004
Ootuspärane vastus oleks 0.3, kuid Python tagastas midagi muud. Asi on selles, et arvutis esitatakse ujukomaarvud kahendkujul, kasutades piiratud arvu bitte ja seetõttu polegi võimalik teatud kümnendmurde (nende hulgas 0.1) täpselt esitada (analoogiliselt pole kümnendmurruna võimalik täpselt esitada näiteks 10 / 3). Taolistel juhtudel ümardatakse sisestatud arv lihtsalt lähima võimaliku kahendmurruni ja see ongi põhjus, miks antud näites oli tulemus ebatäpne. Kui ujukomaarvu on tarvis esitada kümnendmurruna (nt ekraanile kuvamisel), siis toimub jälle ümardamine – see on põhjus, miks käsureale 0.1 sisestades antakse vastuseks tagasi 0.1, kuigi Python sisimas ei suuda seda arvu täpselt esitada. Kui korrutasime 0.1 3-ga, siis muutus viga juba piisavalt suureks, et saadud tulemusele lähim võimalik kümnendmurd oli 0.30000000000000004, mitte 0.3 Tegelikult tekitab ujukomaarvude ligikaudsus probleeme vaid siis, kui me eeldame reaalarvude absoluutselt täpset esitamist (nt kümnendmurruna esitatud rahasummad, kus murdosa tähistatab sente). Praktikas kasutatakse ujukomaarve peamiselt kõikvõimalike mõõtmistulemuste esitamiseks ja selle jaoks on Pythoni float-tüübi ulatus ning täpsus enam kui piisav.
Avaldis | Väärtus | Selgitus |
---|---|---|
6 / 3 | 2.0 | Tavalise jagamise tulemus on alati ujukomaarv |
5 // 3 | 1 | Täisarvuline jagamine |
5 % 3 | 2 | Jagamise jäägi leidmine |
5 ** 3 | 125 | Astendamine |
round(2.6375, 2) | 2.64 | Ümardamine nõutud täpsusega |
round(2.6375) | 3 | Ümardamine lähima täisarvuni |
abs(-2) | 2 | Absoluutväärtuse võtmine |
int(2.6375) | 2 | Täisarvuks teisendades ei ümardata |
Märkus Kui avaldis on keeruline, siis võiks kaaluda sulgude kasutamist ka seal, kus Python neid ei nõua, et teha lugemist lihtsamaks. Lisaks on loetavuse huvides siin ja edaspidistes näidetes pandud tehtemärkide ümber tühikud, aga need võib ka ära jätta.
Sisend ja väljund
Sisendit küsime välismaailmast ja väljundi väljastame välismaailma. Sisendi saamiseks on käsk input, mis küsib kasutajalt sisendi.
nimi = input("Palun sisesta oma nimi ja vajuta ENTER: ") print("Tere " + nimi + "!")
Salvesta ja käivita programm. Ilmub taas käsurea aken palvega sisestada oma nimi. Enne oma nime kirjutamist (kooloni järele) proovi ennustada, milline tekst ilmub ekraanile, kui sa oled nime sisestanud. Katseta! Kui arvasid õigesti, siis vaata programmi tekst uue pilguga üle ja mõtle, milline otstarve võiks olla igal programmielemendil.
Selgitus: Käsk input võimaldab kasutajal midagi sisestada ning edastab saadud teksti Pythonile; Konstruktsioon nimi = ... salvestab selle teksti mällu, edaspidi saab sellele tekstile viidata kirjutades lihtsalt nimi; konstruktsioon "Tere " + nimi + "!" kombineerib etteantud tekstijupid ja kasutaja nime uueks tekstiks.
Väljundi andmiseks on juba korra proovitud print. Esimesena võiks ära märkida, et kui siiani keskendusime põhiliselt avaldistele, mida kasutatakse mingi lause koosseisus, siis käsuga print moodustatatakse juba päris lauseid. Seetõttu on järgnev lihtne programmijupp täisväärtuslik Pythoni lause ja seega ka täisväärtuslik Pythoni programm:
print(32 * 57)
Käsule print võib anda ka mitu argumenti, sel juhul trükitakse samale reale mitu asja järjest, tühikutega eraldatuna. Järgnev näide demonstreerib kolme samaväärset viisi, kuidas trükkida ekraanile mitu infokildu korraga:
- variant kombineerib komponendid kõigepealt üheks sõneks ja kasutab seda print-i argumendina.
- variant annab kõik komponendid eraldi argumentidena.
- variant kasutab f-stringi ehk sõnede interpolatsiooni, kus kõige ette kirjutatakse f-täht ja seejärel jutumärkidesse ekraanile väljastatav tekst. Muutujate väärtused saab teksti sisse paigutada kirjutades loogeliste sulgude vahele muutujanimed.
>>> eesnimi = "Peeter" >>> perenimi = "Paan" >>> vanus = 21 >>> print(eesnimi + " " + perenimi + " vanus: " + str(vanus)) Peeter Paan vanus: 21 >>> print(eesnimi, perenimi, "vanus:", vanus) Peeter Paan vanus: 21 >>> print(f"{eesnimi} {perenimi} vanus: {vanus}") Peeter Paan vanus: 21
Kommenteerimine
Lisaks Pythoni jaoks mõeldud käskudele saab programmi kirjutada kommentaare, mis on mõeldud vaid programmi lugemise hõlbustamiseks. Järgnevas näites kasutatakse kommentaare koodi osade pealkirjadena:
# Küsin kasutaja nime nimi = input("Kuidas on sinu nimi? ") # Tervitan kasutajat print("No tere " + nimi) print("Kuidas läheb?") # Praktikas keegi nii lihtsa programmi puhul tegelikult # kommentaare ei kasutaks
Kommentaar esitatakse sümboliga # – Python ignoreerib kogu teksti, mis kirjutatakse sellest sümbolist kuni rea lõpuni.
Programmifail
Selleks, et kõike eelnevalt arvuti kõvakettale salvestada ning sealt lugeda ja käivitada, on võimalik kirjutada ka programmifaili. Programmifaili võib luua tavalise tekstiredaktoriga (nt Notepad) või ka näiteks Thonnyga.
- Thonnys uue faili loomiseks tuleb Thonny avada, klõpsata "File" -> "New".
- Seejäreld tuleks fail salvestada arvutisse "File" -> "Save as...".
- Selliselt salvestatud faili on võimalik käivitada, valides menüüst "Run" -> "Run current script", klõpsates rohelist noolega nuppu või vajutades klaviatuuril klahvi F5.
Kilpkonnagraafika ehk turtle
Siia lõppu ka midagi lõbusat õhtutundideks.
Pythoni standardteegis on tore moodul nimega turtle, mis võimaldab algajatel Pythoniga lihtsaid joonistusi ja skeeme koostada. Järgnevalt mõned käsud, mida võiks proovida:
forward(100) – liigu 100 sammu edasi
backward(100) – liigu 100 sammu tagasi
right(90) – pööra 90 kraadi paremale
left(90) – pööra 90 kraadi vasakule
up() – ära enam joonista (pliiats tõstetakse üles)
down() – hakka joonistama (pliiats lastakse alla)
speed(1000) – muuda joonistamise kiirust vahemikus 1-10. 0 on maksimumkiirus.
# – kommenteeri rida välja. Trellidega algavat rida ei käivitata ja võib kasutada kommenteerimiseks.
Veel käske: https://docs.python.org/3/library/turtle.html
Ennusta ja proovi, mida teeb allolev näidisprogramm:
forward(100) right(90) forward(100)
Kilpkonnagraafika joone värvimine
Proovime nüüd teha programmi natukene lõbusamaks- lisame värve. Pliiatsi värvi on võimalik muuta nii: color("värvinimi"). Näiteks käsku color("red") saaks kasutada punase joone tegemiseks nii:
color("red") forward(100)
Värve saab veel selliselt: color("#285078"), kus värvikoodi saab näiteks guugeldades "color codes".
Kujundi seest värvimine
Lisaks on võimalik kujundeid ka seest värvida. Selleks, et ruut seest punaseks värvida, tuleks panna ruudu joonistamisel selle ette käsud color("red") ja begin_fill() ja pärast joonistamist käsk end_fill().
Proovi nüüd teha näiteks jõulukaart, kus on ehitud kuusepuu.