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": 985, "Fenninger": 901, "Shiffrin": 750, "Vonn": 646, "Rebensburg": 533, "Zettel": 526} in tako naprej. Drugi argument je vrstni red po neki tekmi, 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 {"Maze": 1085, "Fenninger": 901, "Shiffrin": 750, "Vonn": 706, "Rebensburg": 533, "Zettel": 606, "Štuhec": 50}.

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:

def tocke(mesto): tocke = [None, 100, 80, 60, 50, 45, 40, 36, 32, 29, 26, 24, 22, 20, 18, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1] if mesto <= 30: return tocke[mesto] else: return 0

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.

def pristej(disciplina, vrstni_red): for i, ime in enumerate(vrstni_red): if ime not in disciplina: disciplina[ime] = 0 disciplina[ime] += tocke(i + 1)

Če ne poznamo enumerate, moramo šteti od 0 do toliko, kolikor elementov ima seznam.

def pristej(disciplina, vrstni_red): for i in range(len(vrstni_red)): ime = vrstni_red[i] if ime not in disciplina: disciplina[ime] = 0 disciplina[ime] += tocke(i + 1)

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.

def prvih_n(disciplina, n): tocke_mesto = [] for k, v in disciplina.items(): tocke_mesto.append((v, k)) tocke_mesto.sort(reverse=True) return tocke_mesto[:n]

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.

def razvrstitev(casi): casi = sorted(casi) vrstni_red = [] prejsnji_cas = -1 for i in range(len(casi)): cas, ime = casi.pop(0) if prejsnji_cas == cas: mesto = vrstni_red[-1][0] else: mesto = i + 1 vrstni_red.append((mesto, ime)) prejsnji_cas = cas return vrstni_red

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.

Zadnja sprememba: torek, 24. februar 2026, 17.53