Izpeljana malica z rešitvami
Punce so spet naročale malico. Naročila spet shranjujemo v seznamu terk, kot na primer
narocila = [("Ana", "sendvič"), ("Berta", "sendvič"), ("Cilka", "burek"),
("Dani", "jogurt"), ("Ema", "sendvič"), ("Fanči", "burek")]
Funkcije, ki jih morate napisati, so enake kot v domači nalogi Malice in če želite, lahko pri reševanju gledate tudi objavljeno rešitev one domače naloge.
Naloge so nekoliko spremenjene (ponekod so seznami zamenjani z množicami), predvsem pa je nekoliko premešan njihov vrstni red. Pa oddaj bomo preskočili, saj ta ne gre v eno vrsto (brez resnega nasilja).
Obvezna naloga
Napiši funkcijo
narocniki(narocila, hrana), ki vrne množico imen vseh, ki so naročili podano hrano. Če sonarocilaseznam z začetka besedila, klicnarocniki(narocila, "sendvič")vrne{"Ana", "Berta", "Ema"}.Rešitev:
def narocniki(narocila, hrana): return {oseba for oseba, narocilo in narocila if narocilo == hrana}Napiši funkcijo
stevilo_narocil(narocila, hrana), ki prejme seznam, kakršen je zgornji, in ime neke hrane, vrne pa število ljudi, ki so naročili to hrano. Če jenarocilagornji seznam, klicstevilo_narocil(narocila, "sendvič")vrne 3.Rešitev:
def stevilo_narocil(narocila, hrana): return sum(narocilo == hrana for _, narocilo in narocila)Napiši funkcijo
slovar_narocil(narocila), ki prejme seznam, kakršen je gornji, vrne pa slovar, katerega ključi so imena oseb, pripadajoče vrednosti pa hrana, ki so jo naročile. Za gornja naročila funkcija vrne{"Ana": "sendvič", "Berta": "sendvič", "Cilka": "burek", "Dani": "jogurt", "Ema": "sendvič", "Fanči": "burek"}.Rešitev:
def slovar_narocil(narocila): return dict(narocila)Napiši funkcijo
kosovnica(narocila), ki prejme seznam naročil in vrne slovar, katerega ključi so različne malice, vrednosti pa število oseb, ki so naročile to malico. Za gornja naročila funkcija vrne{"sendvič": 3, "burek": 2, "jogurt": 1}.Rešitev:
def kosovnica(narocila): return Counter(hrana for _, hrana in narocila)Napiši funkcijo
najpopularnejse(narocila), ki vrne ime največkrat naročene jedi. Predpostavljajmo, da je le ena. Za gornja naročila funkcija vrne"sendvič". Pri tej funkciji si pomagajte s trikom zamax, ki ste ga nekateri že odkrili, potem pa sem ga tudi razložil na predavanjih. Če se želiš izogniti temu, da bi nekaj računal dvakrat, ima ta funkcija lahko tudi dve vrstici. Najprej nekaj izračunaš in potem to uporabiš. (Nekateri ste jo že rešili tako.)Rešitev:
def najpopularnejse(narocila): return max(kosovnica(narocila), key=kosovnica(narocila).get)Napiši funkcijo
vsa_narocila(narocila), ki vrne slovar, katerega ključi so imena jedi, vrednosti pa množice imen oseb, ki so naročili to jed. Za gornja naročila funkcija vrne{"sendvič": {"Ana", "Berta", "Ema"}, "burek": {"Cilka", "Fanči"}, "jogurt": {"Dani"}. Namig: ne vznemirjaj se, če bo funkcija nekoliko neučinkovita in bo nekatere stvari računala večkrat.Rešitev:
def vsa_narocila(narocila): return {hrana: narocniki(narocila, hrana) for _, hrana in narocila}Napiši funkcijo
primanjkljaj(kosovnica, zaloga), ki prejme slovar, kakršnega vrača funkcijakosovnicain podoben slovar, katerega ključi so imena jedi, vrednosti pa število kosov te jedi, ki jih imamo na zalogi. Funkcija vrne slovar, ki pove, koliko kosov jedi nam manjka. Klicprimanjkljaj({"sendvič": 3, "burek": 2, "jogurt": 1}, {"sendvič": 2, "jogurt": 2, "korenček": 4})vrne,{"sendvič": 1, "burek": 2}. Z drugimi besedami: jed se pojavi v tem slovarju, če je je premalo.Rešitev:
def primanjkljaj(kosovnica, zaloga): return {hrana: kosov - zaloga.get(hrana, 0) for hrana, kosov in kosovnica.items() if kosov > zaloga.get(hrana, 0)}Napiši funkcijo
goljufi(narocila), ki vrne množico imen vseh, ki so naročili več kot eno malico. V gornjem primeru takšnih ni. Če pokličemogoljufi([("Ana", "burek"), ("Berta", "sendvič"), ("Berta", "sendvič"), ("Cilka", "sendvič"), ("Berta", "korenček"), ("Ana", "burek")]), pa vrne seznam{"Ana", "Berta"}. Ana je v množici, ker je naročila dvakrat - pa čeprav isto jed. Pomoč: morda najprej reši v dveh vrsticah. Najprej izračunaj, kolikokrat je kdo naročil;Counterje tvoj prijatelj. Nato sestavi množico tistih, ki so naročili več kot enkrat. Ko bo to napisano v dveh vrsticah, ju bo trivialno zliti v eno.Rešitev:
def goljufi(narocila): return {oseba for oseba, kolikokrat in Counter(os for os, _ in narocila).items() if kolikokrat > 1}
Dodatna naloga
Napiši funkcijo
kosovnica_brez_goljufov(narocila), ki dela podobno kot funkcijakosovnica, le da pri vsaki osebi upošteva le njeno prvo naročilo. Namig: kaj se zgodi, če iz naročil sestaviš slovar? Ni čisto tak, kot bi ga želel? Prav, v tem primeru pa sestavi slovar iz tako preobrnjenih naročil, da bo tak, kot bi ga želel.Rešitev:
Kosovnico brez goljufov dobimo tako, da seznam naročil obrnemo (z
reversed) in iz njega naredimo slovar. Tako bodo naročila, ki so bila prej, prišla kasneje in povozila tista, ki so bila kasneje. Potem poberemo stvari (.items()iz tega slovarja in iz njega naredimo kosovnico.def kosovnica_brez_goljufov(narocila): return kosovnica(dict(reversed(narocila)).items())Če bi hoteli to storiti v eni vrstici - še lažje. Iz onega slovarja poberemo le vrednosti in jih preštejemo.
def kosovnica_brez_goljufov(narocila): return Counter(dict(reversed(narocila)).values())