Smučanje
Naloga
Ogrevalna naloga
Napišite funkcijo tocke(n), ki pove, koliko točk dobi smučar v
svetovnem pokalu v alpskem smučanju, če zasede n-to mesto.
(Glej:
http://en.wikipedia.org/wiki/FIS_Alpine_Ski_World_Cup#World_Cup_scoring_system
Obvezna naloga
Tokrat boste napisali dve funkciji.
Funkcija pristej(disciplina, vrstni_red) dobi kot prvi argument
trenutno razvrstite v svetovnem pokalu v neki disciplini. Podana je kot slovar,
recimo:
["Maze", "Zettel, "Vonn", "Štuhec"] ;). Funkcija mora k točkam v
podanem slovarju prišteti točke, pridobljene v tej tekmi. Če jo torej pokličemo
z gornjima argumentoma, mora spremeniti slovar v
Druga funkcija je prvih_n(disciplina, n). Kot argument ji podamo
slovar, kakršen je gornji in število mest, ki jih želimo izpisati. Vrniti mora
seznam terk s številom točk in imenom. V seznamu morajo biti terke, ki ustrezajo
prvim n smučarjem, urejene morajo biti po točkah. Če pokličemo
prvih_n z gornjim seznamom in kot drugi argument damo 3, mora
vrniti seznam
[(1085, "Maze"), (901, "Fenninger"), (750, "Shiffrin)].
Nasvet: funkcija naj predela slovar, kot je gornji, v seznam
[(1085, "Maze"), (901, "Fenninger"), (750, "Shiffrin"),
(706, "Vonn"), (533, "Rebensburg"), (606, "Zettel"),
(50, "Štuhec)]. Nato naj ga
uredi. Če hočete urejati padajoče, pokličete metodo sort in kot
argument napišete reverse=True --- se pravi
sort(reverse=True).
Dodatna naloga
Napišite funkcijo razvrstitev(casi), ki dobi kot argument
seznam parov (čas, ime). Vrniti mora seznam parov (mesto, ime). Če jo pokličemo
z [(54, "Shiffrin"), (53, "Maze"), (55, "Vonn")], naj vrne
[(1, "Maze"), (2, "Shiffrin"), (3, "Vonn")]. Paziti mora tudi na
deljena mesta. Če jo pokličemo z
[(54, "Shiffrin"), (53, "Maze"), (55, "Vonn"), (54, "Zettel")],
mora vrniti
[(1, "Maze"), (2, "Shiffrin"), (2, "Zettel"), (r, "Vonn")]. V
(V primeru, da ima več smučarjev isti čas, naj bodo urejeni po abecedi. S tem
se ne ukvarjajte preveč, to se vam bo najbrž itak zgodilo samo od sebe.)
Rešitev
Ogrevalna naloga
Naloga ni podala posebnih zahtev, kako naj bi bilo to narejeno. Povsem preprosta rešitev je takšna:
Ker smo izjemno leni, smo dali na začetek seznama None in se
tako izognili temu, da bi morali pisati return tocke[mesto - 1].
(Drži, drži, manj dela bi imeli, če bi pisali tisto -1. Vendar
si predstavljajte, da bi seznam točk uporabljali na več mestih v programu. V
temu primeru pa bi bilo lepo, če se zmenimo, da so na indeksu n
točke za n-to mesto, ne?
Obvezna naloga
Za to nalogo je bilo potrebno znati spreminjati slovar. Mnogi ste namesto
tega sestavljali nov slovar - in to je narobe. Ne, spreminjati je bilo potrebno
obstoječega. Poleg tega si nste mogli pomagati z defaultdictom,
saj naloga ne obljublja, da boste dobili defaultdict.
Gremo torej čez podani seznam imen, pri čemer moramo poznati tako ime kot
indeks - zato uporabimo enumerate (upam, da ste ga v prvem
semestru spoznali?). Ko imamo torej ime in mesto, najprej preverimo, ali to
ime že obstaja in ga, če ga ni, dodamo v slovar, tako da mu damo 0 točk. Nato
v slovar k tej osebi prištejemo toliko točk, kolikor je vredno mesto, ki ga je
oseba zasedla.
Če ne poznamo enumerate, moramo šteti od 0 do toliko, kolikor
elementov ima seznam.
Vse enako, le malo bolj zapleteno.
Z drugo funkcijo pa je tako: če sledimo nasvetu, bomo najprej preobrnili
slovar v seznam terk, v katerih
so najprej točke. Nato pokličemo sort ... in naloga je skoraj
končana, le še prvih n elementov vrnemo.
Dodatna naloga
Tule gre za klasično vajo iz programerske spretnosti. To funkcijo je mogoče poljubno zaplesti, lahko pa je elegantna. Ena od možnih rešitev je takšna.
Najprej uredimo čase; funkcija sorted(casi) bo vrnila nov
seznam - za razliko od casi.sort(), ki bi spreminjala podani
seznam. še Sestavimo prazen seznam, v katerega bomo zložili, kar
je potrebno, in ga na koncu vrnili. Nato si zapomnimo, da je zadnja tekmovalka,
ki smo jo dodali, za progo potrebovala -1 sekundo. (Ni, saj nismo dodali še
nobene. Ampak to nam bo prišlo prav.)
Zanko napišemo s štetjem - for i in range(len(casi)). Tako bo
i + 1 vedno vseboval trenutno mesto - razen, kadar je prišlo do
delitve mest.
Nato iz seznama casi jemljemo elemente z začetka
(cas, ime = casi.pop(0)). Če je čas enak prejšnjemu, je tudi mesto
enako mestu zadnje dodane tekmovalke, mesto = vrstni_red[-1][0].
Kadar pa ima tekmovalka večji čas od prejšnje, je na mestu i + 1.
V seznam dodamo par (mesto, ime) in si zapomnimo čas te
tekmovalke (prejsnji_cas = cas), da ga bomo lahko primerjali
s časom naslednje.