Ta domača naloga je ... čudna. Je čisto lahka, razen ene funkcije, s katero se boste morda precej zafrkavali, ker vam ne bo jasno, zakaj ne deluje. Ampak to bo eden od poučnejših delov naloge.

Po drugi strani pa je naloga bolj zgled, kako se nečesa ne dela. Prišla nam bo prav kot izhodišče za naslednje predavanje (ko se bomo učili, kako se to dela) in še za eno od kasnejših (ko se bomo učili, zakaj vas je ena od funkcij v tej nalogi zafrkavala).

Obvezna naloga

Šalabajzerbanka shranjuje podatke o svojih strankah v seznam parov (par je predstavljen kot seznam): prvi element je ime stranke, drugi pove, koliko denarja ima ta stranka. Banka predpostavlja, da nikoli ne bo imela dveh strank z enakim imenom (če bo sploh imela kakšno).

Za lažjo predstavo: v nekem obdobju, ko jim je šlo posebej dobro, so imeli tri stranke. Shranili so jih v seznamu [["Ana", 42], ["Berta", 13], ["Cilka", 66]].

Napisati boste morali več funkcij. Vse funkcije kot prvi argument dobijo seznam banka, kakršen je gornji (seveda pa ni nujno enak gornjemu).

Napišite naslednje funkcije.

  • dodaj_stranko(banka, ime, denarja): na konec seznama strank doda novo stranko s podanim imenom.

    banka = [["Ana", 42], ["Berta", 13], ["Cilka", 66]]
    dodaj_stranko(banka, "Dani", 15)
    print(banka)
    

    mora izpisati

    [["Ana", 42], ["Berta", 13], ["Cilka", 66], ["Dani", 15]]
    

    (Ja, funkcija je trivialna.)

    Funkcija ne sme vrniti ničesar. (Ah, je slovenščina zoprna. Funkcija mora vrniti nič. Ne, tudi dobro; ne sme vrniti 0. Funkcija naj ne vrne ničesar. Hočem reči, naj vrne ničesar. :))

  • koliko_ima(banka, ime): vrne količino denarja, ki jo je stranka ime vložila v banko. Klic koliko_ima(banka, "Berta") bi v gornjem primeru vrnil 13. Če stranke s tem imenom ni, funkcija vrne None.

  • bilanca(banka) vrne vsoto vložkov vseh strank. Za gornje štiri stranke je to 136.

  • najbogatejsi(banka) vrne ime najbogatejše osebe. Predpostaviti smeš, da ni para strank, ki imata enako denarja, pa tudi nobena ni v minusu. Pač pa moraš vrniti None, če banka nima nobene stranke.

  • placilo(banka, kdo, komu, koliko) spremeni seznam banka tako, da stranki kdo odvzame koliko in stranki komu doda koliko. Če je trenutno stanje [["Ana", 42], ["Berta", 13], ["Cilka", 66]] in pokličemo placilo(banka, "Ana", "Cilka", 10), je novo stanje [["Ana", 32], ["Berta", 13], ["Cilka", 76]].

    Tudi ta funkcija naj ne vrne nobenega rezultata.

Dodatna naloga

V bistvu enaka, vendar: napišite funkcije dodaj_stranko_t, koliko_ima_t, bilanca_t, najbogatejsi_t, placilo_t, ki počnejo točno isto kot zgornje, le da so stranke namesto v seznamu seznamov shranjene v seznamu terk, na primer [("Ana", 42), ("Berta", 13), ("Cilka", 66)].

Rešitev

Pri dodaj_stranko ni kaj motoviliti: v banka z append dodamo nov seznam.

def dodaj_stranko(banka, ime, denar):
    banka.append([ime, denar])

Nekateri ste najprej sestavili seznam in ga dodali potem. Tudi to je OK.

Pri koliko_ima se bil vesel, če ste razpakirali terko:

def koliko_ima(banka, ime):
    for stranka, denarja in banka:
        if stranka == ime:
            return denarja

Manj pregledno je

def koliko_ima(banka, ime):
    for podatek in banka:
        if podatek[0] == ime:
            return podatek[1]

saj moramo potem ob branju funkcije razmišljati, kaj sta podatek[0] in podatek[1]. Seveda pa je možno zakomplicirati še veliko bolj. Odkompliciramo pa s slovarjem - o katere se bomo, o, kakšno naključje, učili ravno na predavanjih po tej domači nalogi.

Tudi pri bilanca je najlepše uporabljati razpakirano terko:

def bilanca(banka):
    v = 0
    for _, denarja in banka:
        v += denarja
    return v

Spet bi bilo veliko elegantneje s slovarji. Tule pa imamo seznam parov zato takrat, ko razpakiramo, dobimo dve stvari, pri čemer nas prva, ime, sploh ne briga. Spremnljivkam, ki nas sploh ne brigajo damo ime _.

Iskanje najbogatejšega je klasika, o kateri ni izgubljati besed. Če vemo, da ima vsak vsaj 0, lahko naredimo tako:

def najbogatejsi(banka):
    naj_ime = None
    naj_denarja = -1
    for ime, denarja in banka:
        if denarja > naj_denarja:
            naj_ime, naj_denarja = ime, denarja
    return naj_ime

Zdaj pa najzanimivejša: placilo. Tu tole ne deluje

def placilo(banka, kdo, komu, koliko):
    for ime, denarja in banka:
        if ime == kdo:
            denarja -= koliko
        if ime == komu:
            denarja += koliko

Kot ste, upam, opazili pri reševanju, bo denarja -= koliko spremenil le vrednost spremenljivke denarja, ne pa tudi vrednosti v seznamu, odkoder je ta spremenljivka dobila ime. O tem se bomo več pogovarjali prihodnji teden.

Čeprav mi je težko ... bomo tole morali rešiti tako:

def placilo(banka, kdo, komu, koliko):
    for stranke in banka:
        if stranke[0] == kdo:
            stranke[1] -= koliko
        if stranke[0] == komu:
            stranke[1] += koliko

S slovarji pa bi bilo vse drugače.

Rešitev dodatne naloge

Funkcija dodaj_stranko_t je praktično enaka funkcijo dodaj_stranko, le da namesto seznama dodamo terko.

def dodaj_stranko_t(banka, ime, denar):
    banka.append((ime, denar))

Naslednje tri funkcije niso le praktično, temveč popolnoma enake kot prej. Lahko jih skopiramo in jim popravimo ime, ali pa napišemo kar

koliko_ima_t = koliko_ima
bilanca_t = bilanca
najbogatejsi_t = najbogatejsi

Tudi o tem več prihodnji teden.

Zadnja, placilo_t pa je bolj zoprna. Medtem kot smo v placilo spreminjali elemente mini-seznama (para z imenom stranke in njenim denarjem), tu tega ne moremo, saj elementov terk ni možno spreminjati. Potrebno bo zamenjati celo terko. Da bomo vedeli, kje, si moramo zapomniti indeks dotičnega elementa v seznamu. Naredimo lahko tako:

def placilo_t(banka, kdo, komu, koliko):
    for i, (ime, denarja) in enumerate(banka):
        if ime == kdo:
            banka[i] = (ime, denarja - koliko)
        if ime == komu:
            banka[i] = (ime, denarja + koliko)

Bodite pozorni na to, kako smo razpakirali terki v zanki for: gnezdene terke lahko razpakiramo gnezdeno.

Last modified: Monday, 18 February 2019, 7:47 PM