Izvozniki
Testi
Testi: testi-izvoz.py
Podatki: izvoz.txt
Naloga
Poberite si datoteko s podatki o izvozu iz posameznih držav in jo shranite v direktorij, v katerem boste pisali svoj program. Odprite jo v poljubnem urejevalniku besedil in si oglejte, kako je videti. (Pazite, da je pri tem ne bi ponesreči shranili, da ne bo kaj narobe.)
Ogrevalna naloga
Napiši program, ki bere datoteko izvoz.txt
in jo izpiše (kar s print
)
v takšni obliki:
Afghanistan ['opium', 'fruits', 'nuts', 'handwoven carpets', 'wool', 'cotton', 'hides', 'pelts', 'gems'] Albania ['textiles', 'footwear', 'asphalt', 'metals', 'metallic ores', 'oil', 'vegetables', 'fruits', 'tobacco'] Algeria ['petroleum', 'natural gas', 'petroleum products'] American Samoa ['tuna'] Andorra ['tobacco products', 'furniture'](in tako naprej). Torej, v eni vrstici ime države, v naslednji vrstici sledi seznam (da, sestavite seznam in ga izpišite s
print
!) izvoženih dobrin, nato prazna vrstica in potem
naslednja država.
Opomba: za to nalogo nismo pripravili testov. Če je ne boste napisali pravilno, vam pač ne bo pomagala pri ostalih nalogah. Rešitev morate kljub temu oddati.
Obvezna naloga
Dani sta funkciji kdo_izvaza
in kaj_izvaza
.
Funkciji sta, kakršni sta, in ju ne smeš spreminjati! Prva za vsak produkt vrne množico držav, ki slove kot izvoznice tega produkta. Druga funkcija za vsako državo vrne množico produktov, ki jih ta izvaža.
Napiši funkcijo preberi_podatke
, ki prebere podatke iz datoteke in jih
shrani v takšne spremenljivke, da bosta funkciji delovali.
Ideja je torej v tem, da bi na začetku programa poklicali to funkcijo, da bi pripravila
podatke, kasneje pa bi v programu klicali kdo_izvaza
in kaj_izvaza
.
Dodatna naloga
Podobnost med državami - glede na njihov izvoz - lahko merimo z Jaccardovim indeksom. Vzemimo dve državi, \(F_1\) in \(F_2\), ter recimo, da prva izvaža produkte \(P_1\) in druga \(P_2\). Podobnost med državama je enaka velikosti preseka množic produktov deljeni z velikostjo unije (torej: število skupnih produktov deljenem s številom vseh produktov), \[J(D_1, D_2) = \frac{|D_1\cap D_2|}{|D_1\cup D_2|}\]
Napiši funkcijo, ki za vsako državo poišče pet najbolj podobnih držav glede na izvožene produkte. Vrne naj seznam z imeni teh držav, urejen po abecedi (ne po podobnosti!). Če si več držav deli peto mesto, naj vrne tudi vse te države. Pri Franciji, recimo, so najbolj podobne države
1. European Union 0.375 2. India 0.3076923076923077 3. Austria 0.26666666666666666 4. Bulgaria 0.25 5-7. Slovakia 0.23076923076923078 5-7. Macedonia 0.23076923076923078 5-7. Lithuania 0.23076923076923078Ker si peto mesto delijo tri države, funkcija vrne vseh sedem držav, konkretno
['Austria', 'Bulgaria', 'European Union', 'India', 'Lithuania', 'Macedonia', 'Slovakia']
.
Več primerov najdete v testnih primerih.
Rešitev
Ogrevalna naloga
Ogrevalna naloga naj bi vam tokrat predvsem pomagala počasi sestavljati rešitev obvezne. Ko rešujemo težak problem (za poprečnega programerja je tole sicer trivialno, za začetnika pa gotovo že sodi v kategorijo težkega) se splača program sestavljati po korakih in sproti izpisovati, kar imamo. Če ste pravilno rešili ogrevalno nalogo, je s tem že praktično rešena polovica obvezne naloge.
Datoteko se splača brati po vrsticah. Nekateri so pisali
Od vsake vrstice odluščimo šaro na začetku in (predvsem) koncu ter jo razdelimo po \t v dva dela; v prvem je država, v drugem stvari, ki jih država izvaža. Nekateri so pisali
drzava
, b[0]
ali b
. Rekel bi, da država. Upam,
da vi tudi.
V naslednji vrstici razbijemo še niz s produkti v seznam produktov; z dodatnim stripom se rešimo nepotrebnega presledka na začetku.
Obvezna naloga
Spremenljivki drzave
in produkti
bosta globalni, kar je najlepše povedati na začetku
funkcije. Nato sestavimo dva prazna slovarja. Eden bo običajni slovar, za drugega se bo pokazalo, da je bolj praktičen
defaultdict
. Funkcija se nato nadaljuje po zgledu prve, le da držav in stvari ne izpisujemo, temveč v
slovar drzave
zabeležimo, da država izvaža te in te stvari: drzave[drzava] = set(stvari)
.
Seznam stvari mimogrede pretvorimo v množico stvari. Za to nalogo to ni potrebno, prav pa pride pri naslednji.
Zadnji dve vrstici poskrbita za obratni slovar. Ta je dal mnogim reševalcem precej vetra. Če uporabimo
defaultdict
, nam ni hudega: za vsak produkt zabeležimo, da je med njegovimi izvozniki tudi drzava
,
tako da jo dodamo v slovar izvoznikov: produkti[stvar].add(drzava)
. Če ne bi imeli defaultdicta
,
bi se morali prej potruditi, da bi dodali stvar v slovar. Točneje: za vsako stvar, ki jo vidimo prvič, dodamo v slovar
pod ključ stvar
prazno množico. Zadnji dve vrstici se s tem spremenita v
Pogosta napaka je bila takšna:
Če delamo tako, pri vsakem produktu vedno znova ustvarimo prazno množico in vanj dodamo državo. Na ta način bo vsak produkt navidez izvažala samo ena država.
Najpodobnejših pet
Najprej sestavimo seznam parov (podobnost, drzava)
. Tu nam pride prav, da imamo množice produkto, saj
lahko mirno računamo njihove preseke in unije. Seznam uredimo. Ker je seznam urejen naraščajoče, bo peta najpodobnejša
država bo na koncu, torej podobne[-5]
. Njena podobnost je podobne[-5][0]
. V seznam
najpod
zložimo tiste države, katerih podobnost je večja ali enaka podobnosti pete države. Vrnemo po
abecedi urejen seznam teh držav.