Testi

testi-inventar.py

Naloga

Ogrevalna naloga

Neka trgovina shranjuje svoj inventar v datoteki v naslednji obliki:

makovka 10 kruh 15 pašteta 10 sir 8 klobasa 7 mortadela 4 pasja radost 2

Ime artikla in količina sta ločena s tabulatorjem (\t).

Napiši funkcijo preberi_inventar(ime_dat), ki prebere takšnole datoteko (ime datoteke je argument funkcije) in vrne slovar, katerega ključi so artikli in vrednosti količine, recimo takšen:

{'sir': 8, 'kruh': 15, 'makovka': 10, 'pasja radost': 2, 'pašteta': 10, 'mortadela': 4, 'klobasa': 7}

Pazi: vrednosti so števila (npr. 10) in ne nizi ("10").

Obvezna naloga

Napisati bo potrebno nekaj funkcij za delo s te inventarjem.

Funkcija zaloga(inventar, artikel) naj pove, koliko izdelka artikel imamo na zalogi. Če bi imeli gornji slovar z inventarjem shranjen v slovarju inv, mora klic zaloga(inv, "makovka") vrniti 10.

Funkcija prodaj(inventar, artikel, kolicina), ki zmanjša količino artikla artikel v inventarju inventar za kolicina. Klic prodaj(inv, "makovka", 3) (prodali smo tri makovke) mora spremeniti slovar inv tako, da zmanjša vrednost pri ključu "makovke" za 3. Novi slovar je torej takšen:

{'sir': 8, 'kruh': 15, 'makovka': 7, 'pasja radost': 2, 'pašteta': 10, 'mortadela': 4, 'klobasa': 7}

Nasvet: če veš preveč in si že slišal za argumente po vrednosti in po referenci, te misli do nadaljnjega opusti, saj za Python niso relevantne.

Trgovina sprejema tudi naročila, ki so zapisana v datotekah v natančno enaki obliki kot inventar - v vsaki vrstici je po en artikel in njegova količina, med njima pa tabulator. Predpostaviti smeš, da se vsak artikel pojavi le enkrat. Napiši funkcijo preberi_narocilo(ime_dat), ki prebere takšno naročilo in ga vrne v obliki slovarja.

Namig: znajdi se in ne programiraj tistega, kar si že sprogramiral.

Končno, napiši funkcijo primanjkljaj(inventar, narocilo), ki prejme dva slovarja: prvi predstavlja trenutni inventar, drugi pa, kaj neka stranka naroča. Funkcija mora vrniti nov slovar, v katerem bo zapisano, koliko česa moramo še kupiti, da bomo lahko stranki dobavili vse, kar si želi. Če bi, recimo, stranka želela tri paštete, devet klobas in eno pivo, mora funkcija vrniti slovar {"klobasa": 2, "pivo": 1}. Dve klobasi zato, ker jih imamo sedem, stranka pa jih želi devet. Paštet ne bo potrebno naročati, saj jih imamo dovolj. Pivo pa potrebujemo, saj nimamo nobenega.

Dodatna naloga

Dodatna naloga je tokrat med preprostejšimi. Napiši funkcijo zberi_narocila(imena_dat), ki kot argument dobi seznam imen datotek z naročili. Funkcija mora prebrati vse datoteke in sešteti naročila, ko so v njih. Vsota naročil mora biti spet slovar, katerega ključi so artikli, vrednosti pa skupna količina teh artiklov, ki so jo naročile stranke.

Poleg tega napiši funkcijo izracunaj_dobavo(inventar, narocila), ki izračuna, koliko posameznega artikla je potrebno še naročiti. Pri tem je inventar trenutni inventar, narocila pa vsota naročil, kot jih vrne funkcija zberi_narocila.

Namig: če si olajšate delo in ne programirate iste stvari dvakrat, ne bomo zamerili. Nasprotno.

Rešitev

Ogrevanje

Z branjem je tako. Pripravimo prazen slovar, v katerega bomo shranili inventar (inventar = {}). Nato gremo čez vse vrstice datoteke (for vrstica in open(ime_dat). Vsako vrstico razbijemo na del pred in za tabulatorjem (\t) na artikel in količino (artikel, kolicina = vrstica.split("\t")). Shranimo ju v slovar, pri čemer ne pozabimo pretvoriti količine iz niza v število (inventar[artikel] = int(kolicina)). Ko je datoteke konec, vrnemo sestavljeni inventar (return inventar).

def preberi_inventar(ime_dat): inventar = {} for vrstica in open(ime_dat): artikel, kolicina = vrstica.split("\t") inventar[artikel] = int(kolicina) return inventar

Funkcija, ki vrne zalogo, mora le prebrati vrednost iz inventarja.

def zaloga(inventar, artikel): return inventar[artikel]

Funkcija, ki zmanjša zalogo, mora zmanjšati količino podanega artikla v inventarju.

def prodaj(inventar, artikel, kolicina): inventar[artikel] -= kolicina

Obvezna naloga

Naloga z branjem naročil ... je samo trik. Če ima datoteka z naročili enako obliko kot datoteka z inventarjem, je najboljše, da jo preberemo kar z isto funkcijo. Lahko bi naredili takole

def preberi_narocilo(ime_dat): return preberi_inventar(ime_dat)

Vendar gre še veliko preprosteje. Recimo, da imamo nek seznam s . Tedaj lahko rečemo t = s in t bo isto kot s. Ker so v Pythonu tudi funkcije objekti, lahko z njimi narecimo isto. Če imamo neko funkcijo preberi_inventar in rečemo preberi_narocilo = preberi_inventar, bo preberi_narocilo isto kot preberi_inventar. Rešitev naloge je torej kar

preberi_narocilo = preberi_inventar

Ob drugi nalogi, primanjkljaj, samo pomislimo, kako bi to delal pravi skladiščnik. Vzel bi prazen list, na katerega si bo zapisoval, kaj manjka (manjka = {}). Za vsako stvar iz seznama naročil (for artikel in narocilo) bo pogledal, če ga ima na zalogi (if artikel in inventar). V tem primeru pogleda, ali ga ima slučajno premalo (if narocilo[artikel] > inventar[artikel]). Če je tako, zabeleži primankljaj (manjka[artikel] = narocilo[artikel] - inventar[artikel]). Če ga je na zalogi dovolj, ne stori nič. Sicer, torej, če artikla sploh ni na zalogi, je primanjkljaj takšen, kolikor tega artikla je naročenega (manjka[artikel] = narocilo[artikel]).

def primanjkljaj(inventar, narocilo): manjka = {} for artikel in narocilo: if artikel in inventar: if narocilo[artikel] > inventar[artikel]: manjka[artikel] = narocilo[artikel] - inventar[artikel] else: manjka[artikel] = narocilo[artikel] return manjka

Pazite, kam smo postavili else: pod tisti if, na katerega se nanaša.

Ta rešitev je čisto OK. Če poznamo malo več Pythona, pa naredimo tako:

def primanjkljaj(inventar, narocilo): manjka = {} for artikel, kolicina in narocilo.items(): imamo = inventar.get(artikel, 0) if imamo < kolicina: manjka[artikel] = kolicina - imamo return manjka

Dodatna naloga

Najprej si pripravimo funkcijo, ki k enemu slovarju prišteje drugi slovar: v prvega doda vse, kar je v drugem, pri stvareh, ki so v obeh, pa izračuna vsoto.

def pristej_slovar(a, b): for artikel, kolicina in b.items(): a[artikel] = a.get(artikel, 0) + kolicina

Zbiranje naročil je tedaj le branje in seštevanje slovarjev.

def zberi_narocila(imena_dat): skupno = {} for ime_dat in imena_dat: narocilo = preberi_narocilo(ime_dat) pristej_slovar(skupno, narocilo) return skupno

Računanje dobave pa je isto kot računanje primanjkljaja.

izracunaj_dobavo = primanjkljaj
Zadnja sprememba: torek, 23. marec 2021, 19.45