Vaje
V eni od nalog smo se ukvarjali z resničnimi podatki z vremenskih postaj v Sloveniji. Podatki so s strani https://www.ncei.noaa.gov/data/daily-summaries/access/. Ta vsebuje datoteke za vse(?) postaje na svetu; arhiv z vsemi datotekami je na https://www.ncei.noaa.gov/data/daily-summaries/archive/ (in je velik 7 GB). Da ne bi pobrali vsega, so v priloženi datoteki .zip samo datoteke, ki se nanašajo na Slovenijo.
Kot boste videli, podatki niso v tako prijazni obliki, kot so bili tisti, s katerimi ste delali vi. Za to vajo boste delali s podatki v obliki, kakršno bi dobili na spletu. Kot boste videli, to ne bo zgolj vaja iz programiranja, temveč tudi iz brskanja po dokumentaciji in splošne iznajdljivosti. Narobe lahko gre marsikaj, sitnosti lahko povzroča karkoli. Vaje iz resničnega sveta, torej.
Odzipaj datoteko s podatki. Lahko v direktorij, v katerem bo program, lahko drugam (če jih znaš kljub temu brati).
Vsaka postaja ima svojo kodo. Kredarica, recimo, je SIE00105938. Napiši funkcijo
kodirnik_postaj
, ki ne prejme nobenih argumentov, vrne pa takšen slovar:{'Bilje': 'SIE00115106', 'Celje Medlog': 'SIE00115176', 'Crnomelj Doblice': 'SIE00114856', 'Kocevje': 'SIE00114956', 'Kredarica': 'SIE00105938', 'Lesce': 'SIE00114966', 'Letalisce Edvarda Rusjana Mari': 'SIE00115156', 'Letalisce Jozeta Pucnika Ljubl': 'SIE00115146', 'Lisca': 'SIE00115186', 'Murska Sobota Rakican': 'SIE00115196', 'Nova Vas Na Blokah': 'SIE00115066', 'Novo Mesto': 'SIE00115126', 'Portoroz Letalisce': 'SIE00115166', 'Postojna': 'SIE00115076', 'Ratece Planica': 'SIE00115206', 'Smartno Pri Slovenj Gradcu': 'SIE00115136', 'Topol Pri Medvodah': 'SIE00115006', 'Veliki Dolenci': 'SIE00115096', 'Vojsko': 'SIE00115016'}
Bodi pozoren na velike in male črke. Slovar mora seveda razbrati iz datotek in/ali njihovih imen. (Teste bi prestala tudi, če bi ta slovar preprosto prekopirali v funkcijo. :)
Rešitev
def kodirnik_postaj():
kodirnik = {}
for fn in os.listdir():
if not fn.endswith(".csv"):
continue
for vrstica in csv.DictReader(open(fn)):
kodirnik[vrstica["NAME"][:-4].title()] = vrstica["STATION"]
break
return kodirnik
Imena krajev niso lepa. Nekatera se končajo sredi besede, druga so brez šumnikov, tretja vsebujejo preveč podroben opis krajev (namesto Celje Medlog smo zadovoljni tudi s Celje). Napiši funkcijo
popravi(kodirnik)
, ki prejme slovar, kakršnega vrača prva funkcija in ga spremeni - zamenja imena krajev (ključe) z lepšimi.Zahtevane pretvorbe so zapisane v tem slovarju.
popravki = {'Murska Sobota Rakican': 'Murska Sobota', 'Crnomelj Doblice': 'Črnomelj', 'Letalisce Edvarda Rusjana Mari': 'Maribor', 'Letalisce Jozeta Pucnika Ljubl': 'Brnik', 'Ljubljana Bezigrad': 'Ljubljana', 'Kocevje': 'Kočevje', 'Smartno Pri Slovenj Gradcu': 'Smartno pri Slovenj Gradcu', 'Kredarica': 'Kredarica', 'Veliki Dolenci': 'Veliki Dolenci', 'Novo Mesto': 'Novo mesto', 'Nova Vas Na Blokah': 'Bloke', 'Celje Medlog': 'Celje', 'Portoroz Letalisce': 'Portorož', 'Topol Pri Medvodah': 'Topol pri Medvodah', 'Ratece Planica': 'Rateče' }
Torej:
'Crnomelj Doblice'
se mora spremeniti v'Črnomelj'
.Ta slovar skopiraj v funkcijo in ga uporabi.
Pomoč: ključa v slovarju se ne da spremeniti. Pač pa odstraniš stari ključ (uporabiš lahko
del d[k]
ali, mogoče še boljšed.pop(k)
, kjer jed
slovar,k
pa ključ, ki ga želiš odstraniti) in dodaš nov, popravljen ključ, z vrednostjo, kakršna je bila pripisana staremu ključu.
Rešitev
def popravi(kodirnik):
for ime, menjava in popravki.items():
kodirnik[menjava] = kodirnik.pop(ime)
Napiši funkcijo
preberi_meritve(ime_postaje, kodirnik)
, ki prejme ime postaje in kodirnik (slovar, kakršnega pridela prejšnja funkcija). Vrniti mora slovar, katerega ključi so datumi, vrednosti pa najvišje temperature na ta dan.Ključi morajo biti terke v obliki (leto, mesec, dan). Po klicu
temperature = preberi_meritve("Kredarica", kodirnik)
, jetemperature[(2023, 8, 13)]
temperatura 13. avgusta 2023.Temperatura je v stolpcu TMAX, podana je v desetinkah Celzijev. Deliti jo morate torej z 10. Na omenjeni datum je za temperaturo na Kredarici zapisano 144; to pomeni, da je bila temperatura 14.4 Celzijev. Shraniti morate seveda to, popravljeno temperaturo.
Na nekatere dneve temperatura ni bila izmerjena. Vrednosti za ta dan ne shranjuj v slovar. Tako, recimo, slovar za Kredarico ne bo imel ključa
(2023, 10, 4)
, ker ta dan termometer, izgleda, ni obratoval. :)
Rešitev
def preberi_meritve(kraj, kodirnik):
meritve = {}
for vrstica in csv.DictReader(open(kodirnik[kraj] + ".csv")):
datum = datetime.strptime(vrstica["DATE"], "%Y-%m-%d")
temp = vrstica["TMAX"].strip()
if temp:
temp = int(temp) / 10
meritve[(datum.year, datum.month, datum.day)] = temp
return meritve