II OSA sisukord |
2.3 REAALSETE ANDMETE KASUTAMINE
Andmed failist
Seni oleme tegutsenud kahemõõtmeliste järjenditega, mille elemendid kirjutasime programmiteksti sisse, näiteks:
tabel = [[1, 2, 4], [-1, 5, 0]]
või käsureale, kui funktsiooni rakendasime, näiteks:
>>> on_bingo_tabel([[1, 30, 34, 55, 75], [10, 16, 40, 50, 67], [5, 20, 38, 48, 61], [4, 26, 43, 49, 70], [15, 17, 33, 51, 66]])
Vähegi suuremate mahtude juures on see ebamugav ja praktikas ka tihti võimatu, sest tahame sama programmi abil töödelda palju erinevaid andmeid. Failist lugemist käsitlesime eelmisel kursusel, aga nüüd vaatame, kuidas failist andmed mugavalt kahemõõtmelisse järjendisse saada.
Olgu näiteks õpilaste saadud (täisarvulised) punktid iga õpilase korral failis eraldi ridadel tühikutega eraldatult. Näiteks:
1 4 5 3 6 8 2 4 8 10 5 0
Kahemõõtmelisse järjendisse saab need andmed aga näiteks nii:
punktide_tabel = [] for rida in fail: # iga rea jaoks failist op_punktid = [] # kogume ühe õpilase punkte osad = rida.split() for osa in osad: # osade kaupa op_punktid.append(int(osa)) punktide_tabel.append(op_punktid)
Eelmises näites olid ühel real olevad andmed eraldatud tühikutega. Ajalooliselt on eraldajaks olnud ka näiteks koma. Sellest tuleb ka lühend CSV - ingl Comma-separated values. Tegelikult ei pruugi koma alati hästi eraldajaks sobida, kuna võib andmetes tähendada midagi muud, näiteks komadega arve. Levinumad eraldajad on tabulatsioonimärk "\t"
ja semikoolon. Ka meie edasistes näidetes on eraldajaks just semikoolon.
Reaalsete andmete kasutamine
Väga palju andmeid elust enesest on tegelikult täiesti vabalt kättesaadavad ja kasutatavad. Eesti kohta leiab huvitavaid andmeid näiteks statistikaameti veebilehelt. Haridusteemalisi andmeid saab Haridussilmast.
Näiteks leidub statistikaameti kodulehel andmeid Eesti rahvastiku soolisest koossesisust erinevates vanuserühmades.
Selle tabeli põhjal saaks lahendada erinevaid ülesandeid. Näiteks saab leida:
- mis vanuses elanikke on kõige rohkem,
- mis vanuserühmas on meeste ja naiste arvuline erinevus kõige suurem,
- teatud vanuserühma elanike arvu.
Haridussilmast võiksime leida näiteks nelja ülikooli vilistlaste keskmised palgad erialade kaupa. Haridussilmast saab andmeid alla laadida küll ainult (Exceli) xls-formaadis, kuid tabeltöötlusprogrammis saab selle faili ka csv-formaati salvestada.
Järgmise näite puhul püüame teada saada, mis aastatel on Tartu elanike arv kasvanud. Statistikaameti veebilehelt saab Tartu elanike arvud kätte järgmiste valikutega: Statistika andmebaas -> Rahvastik -> Rahvastikunäitajad ja koosseis -> Rahvaarv ja rahvastiku koosseis -> RV0282 Rahvastik soo, vanuserühma ja haldusüksuse või asustusüksuse liigi järgi, 1. jaanuar (otselink).
Andmete salvestamisel on võimalik valida, mis kujul me neid faili tahame. Hetkel on sobiv Ilma pealkirjata Semikooloneraldusega pealkirjata tekst (.csv). Nii saame faili RV0282sm.csv, mille esimene rida on
"..Tartu linn";"Mehed ja naised";"2000";106200
Näeme, et meid eriti huvitavad andmed on rea lõpus mõnevõrra erineval kujul - aastaarvul on jutumärgid ümber ja elanike arvul mitte. Kui nüüd eeltoodud moel fail sisse lugeda ja rida osadeks jaotada, siis saame, et osad[2]
on sõne ""2000""
ja osad[3]
on sõne "106200"
. Meie tahame neid mõlemaid täisarvudena, mida annab funktsioon int
. Küll aga tuleb ""2000""
puhul arvu ümbert sõnesisesed jutumärgid eemaldada, mida saame teha funktsiooni strip
abil: osad[2].strip('"')
.
Järgmises programmis paneme saadud andmed järjendisse nii, et ühes reas (andmed[0]
) on kõik aastaarvud ja teises (andmed[1]
) kõik elanike arvud. Failis olid andmed eri ridadel.
fail = open("RV0282sm.csv", encoding="UTF-8") andmed = [[], []] for rida in fail: # loeme ridahaaval osad = rida.split(";") # semikoolonitega eraldatud sõne järjendiks andmed[0].append(int(osad[2].strip('"'))) andmed[1].append(int(osad[3])) fail.close()
Kui nüüd tahame leida aastad, mil elanike arv kasvas, siis võrdleme iga aasta korral, kas järgmise aasta elanike arv on suurem. Kuna andmed on 1. jaanuari seisuga, siis täpselt ühe aasta kaupa muudatusi saamegi nii jälgida.
for i in range(len(andmed[0]) - 1): if andmed[1][i + 1] > andmed[1][i]: print(andmed[0][i])
Siin on oluline, et tsükkel lõpeb eelviimase elemendiga, sest viimasel elemendil poleks järgmist (andmed[1][i + 1]
), millega võrrelda.
Kuna CSV-failidega tegutsemist võib ikka ette tulla, siis on selleks tarbeks olemas spetsiaalne Pythoni moodul, mille nimi ongi csv, millega võite huvi korral ise tutvuda. Tegemist on Pythoni standardmooduliga, mille kasutamine tuleb programmi alguses näidata import csv
abil. Selle abil saaks sama programmi kirjutada näiteks nii:
import csv andmed = [[], []] csvfail = open('RV0282sm.csv', encoding='UTF-8') loetudCSV = csv.reader(csvfail, delimiter=';') for rida in loetudCSV: andmed[0].append(int(rida[2])) andmed[1].append(int(rida[3])) csvfail.close() for i in range(len(andmed[0]) - 1): if andmed[1][i + 1] > andmed[1][i]: print(andmed[0][i])
II OSA sisukord |