Silmaring. Standardteek ja moodulid
Õpiku esimeses peatükis sai uuritud math
moodulit ning selle funktsioone ja konstante. Pythonis on palju rohkem selliseid mooduleid erinevate probleemide lahendamiseks.
Näiteks:
- Kuidas saada kätte homne kuupäev? Kuu lõpus võib muutuda küsimus väga keeruliseks, kui seda ise üritada arvutada. Mitu päeva on praeguses kuus? Veebruari lõpus: kas on liigaasta?
- Kuidas panna elemendid juhuslikku järjekorda?
- Kuidas uurida kausta sisu Pythoniga?
- Kuidas muuta faili nimesid?
Pythonisse sisse ehitatud moodulid teevad lahendused sellistele küsimustele lihtsaks. Selles peatükis vaatame mõne huvitavama mooduli kasutamise näited. Uurime, kuidas moodulid üldse töötavad ja kuidas teha enda lihtne moodul.
Ettevalmistus
Selle peatüki läbimiseks piisab Pythoni installatsioonist ning õpiku esimese peatüki lugemisest. Väikesel määral käsitletakse andmestruktuure, mida pole veel tutvustatud.
Et kõigest aru saada, on soovitatav tutvuda funktsioonidega (peatükk 4) ja järjenditega (peatükk 7).
Moodulite importimine
Tuletame kõigepealt meelde, kuidas mooduleid importida. Seda saab teha import
lause abil:
>>> import math >>> math.cos(math.pi) -1.0
Moodulitele saab anda ka nimesid as
lausega. Seda tehakse pigem harva ja pikemate või väga sagedasti kasutatavate nimedega. Tavaks on lühendada pandas
moodul pd
-ks ja numpy
moodul np
-ks.
>>> import math as m >>> m.cos(m.pi) -1.0
Moodulitest saab importida ainult vajalikud muutujad kasutades from
lauset. Tervet moodulit sellega ei impordita. Mitu muutujat saab eraldada komaga.
>>> from math import pi, cos >>> pi 3.141592653589793 >>> cos(pi) -1.0 >>> math.pi NameError: name 'math' is not defined
Tärni abil saab importida kõik mooduli muutujad.
>>> from math import * >>> pi 3.141592653589793 >>> e 2.718281828459045 >>> tau 6.283185307179586 >>> cos(pi) -1.0
Standardteek
Pythoniga tuleb kaasa palju mooduleid, mida nimetatakse kollektiivselt standardteegiks. Nende täisnimekiri on saadaval Pythoni dokumentatsioonis, aga vaatame lähemalt mõnda huvitavamat.
Moodul math
Selle mooduli abil saab ligi matemaatilistele funktsioonidele, mida Pythonis vaikimisi ei ole. Täisdokumentatsioon: https://docs.python.org/3/library/math.html
Importimine:
>>> import math
Kasulikud konstandid ja funktsioonid:
>>> math.pi # pii 3.141592653589793 >>> math.inf # lõpmatus (kõik arvud on võrdlemisel sellest väiksemad) inf >>> math.floor(1.7) # alla ümardamine 1 >>> math.ceil(1.3) # üles ümardamine 2
>>> math.sqrt(2) # ruutjuur 1.4142135623730951 >>> math.factorial(6) # faktoriaal 720 >>> math.log(128, 2) # logaritmid 7.0 >>> math.cos(math.pi) # trigonomeetria -1.0
>>> math.isclose(1.45, 1.46, rel_tol=0.01) # tõeväärtus, kas kaks arvu on lähestikku rel_tol piires True
Mõned kasulikud matemaatilised funktsioonid on Pythonisse juba sisse ehitatud:
>>> round(1.7) # ümardamine 2 >>> round(1.337, 2) # kahe komakohani ümardamine 1.34 >>> abs(-5) # absoluutväärtus 5 >>> 2**0.5 # ruutjuur ilma math moodulita 1.4142135623730951
Moodul random
Selle mooduliga saab genereerida pseudojuhuslikke arve, et tuua programmidesse juhuslikkust. Täisdokumentatsioon: https://docs.python.org/3/library/random.html
Importimine:
>>> import random
Kasulikud funktsioonid:
>>> random.randint(1, 10) # juhuslik täisarv kahe arvu vahel 7 >>> random.randint(1, 10) 10
>>> random.random() # juhuslik ujukomaarv 0 ja 1 vahel 0.8426622092891721 >>> random.uniform(1.5, 3) # juhuslik ujukomaarv kahe arvu vahel 1.9124507393369863
>>> pakk = ["ärtu", "ruutu", "poti", "risti"] >>> random.choice(pakk) # juhuslik valik järjendist "ruutu" >>> random.shuffle(pakk) # järjendi segamine >>> pakk ['ruutu', 'risti', 'poti', 'ärtu']
Moodul datetime
Selle mooduli abil saab käsitleda kuupäevi ja aegu. Siin näites luuakse objekte, millest räägitakse täpsemalt peatükis "Objektorienteeritud programmeerimine". Praeguseks olgu need lihtsalt keerulised muutujad, millega saab erinevaid asju teha. Täisdokumentatsioon: https://docs.python.org/3/library/datetime.html
Importimine:
>>> import datetime
Datetime objekti loomine (aasta, kuu, päev, tund, minut, sekund):
>>> kuupäev = datetime.datetime(2020, 2, 29, 12, 34, 56) >>> kuupäev datetime.datetime(2020, 2, 29, 12, 34, 56) >>> kuupäev.year 2020 >>> kuupäev.second 56
Praeguse ajahetke saamine:
>>> praegu = datetime.datetime.now() >>> praegu datetime.datetime(2020, 2, 29, 18, 20, 33, 30651)
Datetime objekti vormindamine sõneks:
>>> praegu.strftime("%Y-%m-%d %H:%M:%S") '2020-02-29 18:20:33'
Vormindamise märgendite nimekiri: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes
Datetime objekti parsimine sõnest.
>>> datetime.datetime.strptime("2020-02-29 18:20:33", "%Y-%m-%d %H:%M:%S") datetime.datetime(2020, 2, 29, 18, 20, 33)
Aegadele saab kestusi juurde liita ja maha lahutada, mille kaudu tekib uus datetime objekt. Liidame enne loodud kuupäevale juurde 13 tundi ja 37 minutit:
>>> kestus = datetime.timedelta(hours=13, minutes=37) >>> kuupäev + kestus datetime.datetime(2020, 3, 1, 2, 11, 56) >>> kuupäev - kestus # lahutada saab ka datetime.datetime(2020, 2, 28, 22, 57, 56)
Seega homse kuupäeva saab kätte nii:
>>> homme = praegu + datetime.timedelta(days=1) >>> homme datetime.datetime(2020, 3, 1, 18, 20, 33, 30651)
Moodul os
Selle mooduliga saab ligi operatsioonisüsteemi funktsionaalsusele, näiteks failide asukohtadele.
Täisdokumentatsioon: https://docs.python.org/3/library/os.html
Importimine:
>>> import os
Praeguse tee (current working directory) saamine:
>>> os.getcwd() '/home/kasutaja/Python/Moodulid/'
Failinimede järjendi saamine praeguses kaustas ja määratud kaustas:
>>> os.listdir() ['programm.py', 'pilt.jpg', 'Uus kaust', 'Lõputöö.pdf'] >>> os.listdir('/home/kasutaja/Python/Moodulid/Uus kaust') ['saladused.txt']
Failinime muutmine:
>>> os.rename("pilt.jpg", "foto.jpg") >>> os.listdir() ['programm.py', 'foto.jpg', 'Uus kaust', 'Lõputöö.pdf']
Kausta loomine:
>>> os.mkdir("Teine kaust") >>> os.listdir() ['programm.py', 'foto.jpg', 'Uus kaust', 'Lõputöö.pdf', 'Teine kaust']
Proovi kirjutada programm, mis loeb sisse kausta kõik failid ja väljastab nende sisu. Siin tuleb kasuks for-tsükkel. Katseta seda kaustaga, mis sisaldab tekstifaile.
Moodul sys
Selle mooduliga saab ligi süsteemipõhisele funktsionaalsusele. Täisdokumentatsioon: https://docs.python.org/3/library/sys.html
Importimine:
>>> import sys
Käsurea argumentidele saab ligi `sys.argv` muutujast:
>>> sys.argv ['programm.py', 'esimene', 'teine']
Selline väärtus tuleb, kui käivitada Thonnys `programm.py` järgmise käsuga:
>>> % Run programm.py esimene teine
Või käsurealt:
kasutaja@arvuti ~/Python/Moodulid$ python3 programm.py esimene teine C:\Users\kasutaja\Python\Moodulid> python3 programm.py esimene teine
Täisarvu maksimaalne väärtus praeguses arvutis:
>>> sys.maxsize 9223372036854775807
Pythoni interpretaatori versiooni saamine:
>>> sys.version '3.7.6 (default, Jan 19 2020, 22:34:52) \n[GCC 9.2.1 20200117]'
Programmi töö lõpetamine:
>>> sys.exit("Põhjus")
Moodul 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:
from turtle import * 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.
Pykkar
Pykkar on virtuaalne robot, kes tegutseb oma virtuaalses maailmas. Ta suudab liikuda, ruute värvida, asju kanda ja tal on andurid mitmesuguste objektide tuvastamiseks. Pykkar on realiseeritud moodulis pykkar (see ei ole Pythoni põhimoodul, seega pead selle tõenäoliselt installima: Thonnys vali Tööriistad → Halda lisapakke... või Tools → Manage Packages ... ning otsi sealt pykkar).
Proovige esimest programminäidet:
from pykkar import * create_world(""" ######## # > # # # # # # # # # ######## """) step() step() step() right()
See programm peaks kuvama väljaku koos liikuva robotiga:
Pykkar mõistab järgmisi käsklusi:
- step() – tee samm edasi.
- right() – pööra 90° paremale.
- take() – korja üles järgmisel ruudul olev koonus. Pykkar suudab transportida ühte koonust korraga.
- put() – pane koonus järgmisele ruudule. Ühel ruudul võib asuda kuni 9 koonust.
- push() – lükka Pykkari ees olevat kasti või koonust.
- paint() – värvi jooksev ruut tumedaks.
- is_wall() – ütleb, kas ees on sein (tagastab True või False).
- is_cone() – ütleb, kas ees on koonus.
- is_box() – ütleb, kas ees on kast.
- is_painted() – ütleb, kas jooksev ruut on värvitud.
- get_direction() – küsib jooksvat suunda (tagastab 'N', 'E', 'S' või 'W').
Pykkari maailm luukase funktsiooniga create_world, millele antakse argumendina ette mitmerealine sõne. Sõne kirjeldab maailma kaarti, iga sümbol tähistab ühte ruutu.
Ruutude tüübid on järgmised:
Sümbol | Tähendus | Näide |
(tühik) | Hele ruut | |
. | Tume ruut | |
# | Sein | |
^ > v < | Pykkar heledal ruudul, nool näitab suunda | |
N E S W | Pykkar tumedal ruudul, täht näitab suunda | |
1 2 ... 9 | Koonuste arv heledal ruudul | |
C | Üks koonus tumedal ruudul | |
b | Kast heledal ruudul | |
B | Kast tumedal ruudul |
Moodul this
Selle mooduli importimine väljastab Pythoni põhimõtted (The Zen of Python). Proovi seda importida.
Moodul antigravity
Seda proovi ise importida. :)
Kuidas moodulid töötavad?
Importisime palju erinevaid mooduleid ja kasutasime nende konstante ja funktsioone, aga kuidas need üldse töötavad? Kuidas luua ise üks moodul?
Mooduli importimine tegelikult otsib üles sellenimelise Pythoni faili ja käivitab selle. Kõiki mooduli failis defineeritud muutujaid saab importivas programmis kasutada.
Isetehtud moodul
Proovime ise mooduli teha. Kirjutame programmi minumoodul
.py
, kus defineerime ühe konstandi ja lihtsa funktsiooni. Lisame ka ühe print-lause, et tõestada, kuidas kogu programm käivitub.
konstant = "Tere" def ruut(n): return n**2 print("Moodul imporditud!")
Nüüd avame samas kaustas interpretaatori või loome uue Pythoni faili ja proovime tehtud moodulit importida ning muutujaid kasutada.
>>> import minumoodul Moodul imporditud! >>> minumoodul.konstant 'Tere' >>> minumoodul.ruut(17) 289
Kõik muutujad töötavad ning sõnum väljastatakse. Üldiselt välditakse moodulite importimisega millegi väljastamist. Teised moodulid ju seda ei teinud.
Mooduli kõikide muutujate loetlemiseks on olemas sisseehitatud funktsioon dir()
. Kui sulud tühjaks jätta, näidatakse kõiki muutujaid, mis on kogu programmis, s.h imporditud moodulid. Kui sulgude sisse panna muutuja, siis loetletakse selle muutujaga seotud muutujaid.
>>> dir() ['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'math', 'minumoodul'] >>> dir(minumoodul) ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'konstant', 'ruut'] >>> dir(math) # kui on imporditud ['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
Kui kunagi satub ette võõras muutuja, on mõistlik jooksutada selle peal dir()
funktsioon, et näha kõiki selle võimalusi. Katseta ka help()
funktsiooni.
Saame ka uurida erinevate objektide funktsioone ja muutujaid. Vaatame eelnevalt mainitud datetime objekti võimalusi.
>>> from datetime import datetime >>> praegu = datetime.now() >>> dir(praegu) ['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'astimezone', 'combine', 'ctime', 'date', 'day', 'dst', 'fold', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'microsecond', 'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second', 'strftime', 'strptime', 'time', 'timestamp', 'timetuple', 'timetz', 'today', 'toordinal', 'tzinfo', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple', 'weekday', 'year'] >>> praegu.year 2020
Leia vastused küsimustele:
- Mida teeb
help()
funktsioon? - Millised funktsioonid ja konstandid on
re
moodulil? - Millised funktsioonid ja muutujad on
timedelta
objektil?
Moodulite asukohad
Kirjutasime enda mooduli interpretaatoriga samasse kausta ja saime seda importida, aga muud moodulid ei asu selles kaustas ja neid saab ikka importida. Kus need asuvad?
Pythonil on erinevate moodulite asukohtadest nimekiri nimega path
. Sellele saab ligi mooduli sys
muutujast.
>>> import sys >>> sys.path ['', '/usr/lib/python37.zip', '/usr/lib/python3.7', '/usr/lib/python3.7/lib-dynload', '/home/kasutaja/.local/lib/python3.7/site-packages', '/usr/local/lib/python3.7/dist-packages', '/usr/lib/python3/dist-packages', '/usr/lib/python3.7/dist-packages']
Mooduli importimisel otsitakse need kaustad järjest läbi, alustades esimesest. Esimene kaust on tühisõne ehk esimesena vaadatakse üle kaust, kus programm käivitati.
Imporditud moodulite failide asukohta saab ka näha:
>>> import turtle >>> turtle <module 'turtle from '/usr/lib/python3.7/turtle.py'> >>> turtle.__file__ '/usr/lib/python3.7/turtle.py'
Mõned moodulid on Pythoni lähtekoodi sisseehitatud ja nende lähtekoodile nii lihtsalt ligi ei pääse.
>>> import math >>> math <module 'math' (built-in)> >>> math.__file__ AttributeError: module 'math' has no attribute '__file__'
Proovi uurida moodulite this
ja antigravity
lähtekoode. Kas need vastavad ootustele?
Kas programm käivitati või imporditi?
Igal programmil (ja seega moodulil) on muutuja __name__
(kaks alakriipsu ees ja taga), mille väärtuseks on mooduli nimi sõnena. See muutuja on ka käivitataval programmil, aga selle väärtus on siis hoopis "__main__"
.
>>> __name__ '__main__'
Kui __name__
väärtuseks on mooduli nimi, siis järelikult programm imporditi. Kui selle väärtus on "__main__"
, siis see käivitati.
Tihti lisatakse programmi ette if-lause kontrolliga, kas programmi käivitati. Nii saavad teised arendajad programmi importida ja selle funktsioone kasutada ilma, et programmi põhiosa käivitub.
if __name__ == "__main__": print("Programm käivitati, ei imporditud!")
Proovi seda järele minumoodul.py
programmis.
Enesekontrolliküsimused
Ülesanded
Ülesanne 1
Muuda minumoodul.py
programmi nii, et see väljastab sõnumi ainult siis, kui see käivitatakse. Importimisel ei tohi midagi väljastada.
>>> %Run minumoodul.py Programm käivitati, ei imporditud! >>> import minumoodul >>>
Ülesanne 2
Kirjuta programm, mis võtab käsurealt sisendiks päevade arvu ning väljastab kuupäeva ja aja pärast sisestatud päevade arvu.
Näide:
>>> %Run ajaarvutaja.py 1337 Praegune aeg on 2020-02-29 18:20:33. 1337 päeva pärast on aeg 2023-10-28 18:20:33.
Ülesanne 3
Google Mapsi koordinaatsüsteemi laiuskraadide piirid on -85 kuni +85 ning pikkuskraadide piirid on -180 kuni +180. Et minna Google Mapsi rakenduses mingitele koordinaatidele, saab minna veebilehitsejaga aadressile https://maps.google.com/?q=laiuskraad,pikkuskraad
. Näiteks Delta hoone puhul https://maps.google.com/?q=58.385894,26.725829.
Kirjuta programm, mis genereerib juhusliku koordinaadipaari ja avab veebilehitsejaga selle asukoha Google Mapsis. Veebilehitseja peaks avama lehekülge samamoodi, nagu seda teeb antigravity
moodul. Programmi koodi kirjuta kommentaar huvitava asukohaga, kuhu see sind viis.
4. Kirjuta programm, mis kasutab asjalikult kolme erineva mooduli funktsionaalsust. Võib kasutada mooduleid, mida materjalides ei ole käsitletud.