Vaje
Ker za ta predavanja še ni zapiskov, bo tokrat v navodilih za vaje spisek uporabnih funkcij in povezava na dokumentacijo.
Alumni UL
Odzipaj alumni-ul.json.zip. Preberi vsebino datoteke ter izpiši imena, letnice rojstva in poklice tam zbranih oseb v obliki
Jakob Savinšek (1922): pesnik
Jakob Savinšek (1922): pisatelj
Taras Kermauner (1930): prevajalec
Milan Kučan (1941): politični komisar
Milan Kučan (1941): pravnik
Marijan Brecelj (1910): politik
Vladimir Šuklje (1907): odvetnik
Božo Škerlj (1904): univerzitetni učitelj
Vladimir Šuklje (1907): politik
Rešitev
import json
from collections import defaultdict
with open("alumni-ul.json") as f:
alumni = json.load(f)
for a in alumni:
rojstvo = a["datum_rojstva"].split("-")[0]
print(f"{a['itemLabel']} ({rojstvo}): {a['poklicLabel']}")
Kot smo odkrili na predavanju, se imena ponavljajo. Pripravi boljši izpis: vsaka oseba naj bo izpisana le enkrat, sledijo naj vsi njegovi poklici, ločeni z vejico.
Jakob Savinšek (1922): slikar, ilustrator, kipar, pesnik, risar, pisatelj
Taras Kermauner (1930): literarni kritik, esejist, jezikoslovec, prevajalec, filozof, literarni zgodovinar, pisatelj
Milan Kučan (1941): politični komisar, politik, pravnik, pravoznanec
Marijan Brecelj (1910): politični komisar, politik, partizan
Vladimir Šuklje (1907): pravnik, odvetnik, politik
Božo Škerlj (1904): antropolog, univerzitetni učitelj, pisatelj
Uporabne funkcije:
- json.load(f)
prebere podatke iz datoteke f
v formatu json. Rezultat je pač vsebina datoteke - v tem primeru seznam slovarjev. Naprej se ne bo težko znajti.
- Nasvet za drugi del: glede na to, da različne ljudi z enakimi imeni ločimo po letnici rojstva, bo najboljše narediti slovar, katerega ključi bodo terke (ime, leto_rojstva)
, vrednosti pa množice ali seznami poklicev.
Rešitev
import json
from collections import defaultdict
with open("alumni-ul.json") as f:
alumni = json.load(f)
ljudje_poklici = defaultdict(list)
for a in alumni:
rojstvo = a["datum_rojstva"].split("-")[0]
ljudje_poklici[(a['itemLabel'], rojstvo)].append(a["poklicLabel"])
for (ime, r), poklici in ljudje_poklici.items():
print(f"{ime} ({r}): {', '.join(poklici)}")
Novice z RSS (XML)
V brskalniku odpri stran https://img.rtvslo.si/feeds/00.xml, desnoklikni in izberi View Page Source (oz. ustrezno izbiro v svojem brskalniku in nastavljenem jeziku). Tako boš videl strukturo XMLja.
Napiši program, ki vsakič, ko ga poženemo, prebere to spletno stran in izpiše naslove novic ter njihove datume in ure objave. Takole:
20 Dec 2023 18:48:14: Finančni ministri EU-ja dosegli dogovor glede reforme javnih financ
20 Dec 2023 18:20:20: HSE: V kibernetskem napadu ukradeni in objavljeni podatki se nanašajo na Premogovnik Velenje
20 Dec 2023 18:08:49: Zdravnik iz Ruande obsojen na 24 let zapora zaradi vloge v genocidu
20 Dec 2023 16:51:37: Selitev Večera v nove prostore se je začela, zaposleni zaskrbljeni
20 Dec 2023 16:42:47: Skakalke in skakalci imajo najvišje cilje
20 Dec 2023 16:37:34: Bruhanje islandskega ognjenika slabi, a oblastem težave povzročajo radovedni opazovalci
20 Dec 2023 16:27:09: Iz predora na trasi 2. tira zaradi požara evakuirali delavce
20 Dec 2023 16:14:54: Glasbena šola Litija - Šmartno praznuje 70 let glasbenega izobraževanja
Uporabne funkcije:
urlopen(url)
(from urllib.request import urlopen
) "odpre" spletno stran, na podoben način, kotopen
"odpre" datoteko.minidom(f)
(from xml.dom import minidom
) prebere xml iz podane datoteke ali spletne strani (f
je torej tisto, kar vrneopen
aliurlopen
). Rezultat je drevo (pravilnejši izraz je dokument), ki predstavlja xml. (https://docs.python.org/3/library/xml.dom.html#document-objects)- Tako dokument kot vsi elementi imajo metodo
getElementsByTagName(ime)
, ki vrne vse elemente znotraj podanega elementa s podanim imenom. (https://docs.python.org/3/library/xml.dom.html#xml.dom.Element.getElementsByTagName). Če za dokument RSS pokličemodoc.getElementByTagName("item")
dobimo seznam vseh "itemov" (pri čemer jedoc
dokument, torej to, kar smo dobili zminidom
). Če imamo nekitem
, lahko zitem.getElementsByTagName("title")
dobimo vseh elementov title znotraj njega. - Če se znotraj nekega elementa
el
nahaja besedilo, ga dobimo zel.firstChild.nodeValue
. (https://docs.python.org/3/library/xml.dom.html#xml.dom.Node.firstChild)
Rešitev
from urllib.request import urlopen
from xml.dom import minidom
novice = minidom.parse(urlopen("https://img.rtvslo.si/feeds/00.xml"))
for novica in novice.getElementsByTagName("item"):
title = novica.getElementsByTagName("title")[0].firstChild.nodeValue
date = novica.getElementsByTagName("pubDate")[0].firstChild.nodeValue.split()[1:5]
print(f"{' '.join(date)}: {title}")
Tečaj dolarja (XML)
(Tole smo delali na predavanju.) Odzipaj priloženo datoteko dtecbs-l.zip.
- Preberi tečaj dolarja za vsak dan. Shrani ga v seznam seznamov: posamični elementi seznama se nanašajo na dneve. Vsak "podseznam" naj vsebuje zaporedno številko dneva (od 1. 1. 2007) in vrednost dolarja na ta dan.
- To tabelo spravi v
np.array
. Stolpca prepiši v spremenljivkidan
invrednost
. - Nato nariši graf s tečajem dolarja.
Uporabne funkcije:
- Večina funkcij iz prejšnje naloge.
- Morda ti pride prav: če imaš nek element
el
, jeel.parentNode
element, ki je nad njim v hierarhiji. el.getAttribute(ime)
vrne vsebino atributa. Če jetecaj
nek elementtecaj
iz tega htmlja, potem jetecaj.getAttribute("oznaka")
oznaka valute. (https://docs.python.org/3/library/xml.dom.html#xml.dom.Element.getAttribute)datetime.fromisoformat(datum)
vrne datum v spremenljivki tipadatetime
. (https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformatdatetime(2007, 1, 1)
vrne 1. januar 2007 v spremenljivki tipadatetime
. ([https://docs.python.org/3/library/datetime.html#datetime.datetime])(https://docs.python.org/3/library/datetime.html#datetime.datetime))- Spremenljivke tipa
datetime
lahko odštevamo. Rezultat je objekt tipatimedelta
. Ta ima atributdays
, ki pove, koliko dni je velika "razlika". (https://docs.python.org/3/library/datetime.html#datetime.timedelta]
Rešitev
from datetime import datetime
from xml.dom import minidom
from matplotlib import pyplot as plt
lista = minidom.parse(open("dtecbs-l.xml"))
x, y = [], []
for el in lista.getElementsByTagName("tecaj"):
if el.getAttribute("oznaka") == "USD":
datum = el.parentNode.getAttribute("datum")
dan = (datetime.fromisoformat(datum) - datetime(2007, 1, 1)).days
x.append(dan)
y.append(float(el.firstChild.nodeValue))
plt.plot(x, y)
plt.show()