Napišite funkcijo knjigovodstvo(ime_datoteke)
, ki prejme
ime datoteke s prihodki (vrstice s pozitivnimi števili) in odhodki
(negativna števila) v obliki, kot jo kaže okvirček na desni. Funkcija
mora vrniti trojko: seznam s pari imen dohodkov in pripadajočih zneskov,
seznam s pari imen odhodkov in pripadajočih cen (kot pozitivna števila)
ter skupno vsoto. Za datoteko
slika: 50
slika: 100
tempera: -3
stol: -20
kip: 20
zrak: 0
torba: 12
vrne
([('slika', 50), ('slika', 100), ('kip', 20), ('torba', 12)],
[('tempera', 3), ('stol', 20)],
159)
pri čemer je 159 preprosto vsota vseh številk.
Najprej pripravimo, kar bomo vrnili - seznama prihodki
in odhodki
ter bilanca
.
Nato gremo po datoteki: vsako vrstico razdelimo glede na
:
in pretvorimo znesek v število. Če je šteivlo negativno,
dodamo par s stvarjo in zneskom v odhodki
(pri čemer mora
biti število -znesek
), sicer v prihodki
. Pa
bilanco
povečamo za znesek
.
def knjigovodstvo(ime_datoteke):
= []
prihodki = []
odhodki = 0
bilanca for vrstica in open(ime_datoteke):
= vrstica.split(":")
stvar, znesek = int(znesek)
znesek if znesek < 0:
-znesek))
odhodki.append((stvar, elif znesek > 0:
prihodki.append((stvar, znesek))+= znesek
bilanca return prihodki, odhodki, bilanca
Nekateri radi pišejo
if znesek > 0:
bilanca += znesek
else:
bilanca -= abs(znesek)
To seveda ni potrebno. Python zna prištevati negativne vrednosti. :)
Prav tako je lepo, da bilanco spreminjamo izven if
in ne
znotraj, ločeno za odhodke in za prihodke.
Eden od študentov je poskusil nalogo rešiti z numpy
-jem.
Ni mu popolnoma uspelo. Vendar se da in je kar lepo.
def knjigovodstvo(ime_datoteke):
= np.genfromtxt(ime_datoteke, delimiter=":", dtype=str)
podatki = podatki[:, 0]
stvari = podatki[:, 1].astype(int)
cene = cene > 0
dohodki = cene < 0
odhodki return (list(zip(stvari[dohodki], cene[dohodki])),
list(zip(stvari[odhodki], -cene[odhodki])),
sum(cene)) np.
Zoprna stvar je tisto na koncu: z zip
poberemo skupaj
stvari in cene, da nam sestavi pare, potem pa pokličemo še
list
, da jih zložimo v seznam.
Napiši funkcijo draginja(odhodki)
, ki vrne seznam parov
imen stvari in cen. Ista stvar se lahko pojavi večkrat, a morda z
različnimi cenami. Funkcija mora vrniti ime stvari, katere povprečna
cena je bila največja. Če je takšnih stvari več, lahko vrne poljubno
izmed njih.
Klic
draginja([('stol', 20), ('torba', 12), ('tempera', 3), ('miza', 50), ('stol', 30), ('stol', 60), ('miza', 40), ('torba', 5)])
vrne 'miza'
, saj je povprečna cena miz enaka
(50 + 40) / 2 = 45
, medtem ko je povprečna cena, recimo,
stolov (20 + 30 + 60) / 3 = 36,66
, torbe in tempere pa so
še cenejše.
Tole je naloga iz slovarjev. Da bomo lahko računali povprečne cene, bomo potrebovali dva: v enem beležimo vsote cen vsake stvari, v drugem število takšnih stvari.
Ko se odločimo glede tega, je funkcija preprosta.
def draginja(odhodki):
= defaultdict(float)
skupna_cena = defaultdict(int)
skupno_kosov for stvar, cena in odhodki:
+= cena
skupna_cena[stvar] += 1
skupno_kosov[stvar]
= None, -1
naj_stvar, naj_povp for stvar in skupna_cena:
= skupna_cena[stvar] / skupno_kosov[stvar]
povp if povp > naj_povp:
= stvar, povp
naj_stvar, naj_povp return naj_stvar
Zoprni drugi del se da skrajšati, če znamo bolj spretno uporabljati
max
in poznamo lambde
.
def draginja(odhodki):
= defaultdict(float)
skupna_cena = defaultdict(int)
skupno_kosov for stvar, cena in odhodki:
+= cena
skupna_cena[stvar] += 1
skupno_kosov[stvar] return max(skupna_cena, key=lambda stvar: skupna_cena[stvar] / skupno_kosov[stvar])
Napišite funkcijo dragocenosti(stvari, cene, meja)
, ki
prejme numpy-jevo tabelo z imeni stvari in dvodimenzionalno tabelo,
katere vrstice ustrezajo stvarem (v enakem vrstnem redu kot so te
naštete v prvi tabeli), stolpci pa dnevom. Vrednosti v tabeli povedo,
koliko je stvar stala na posamezni dan.
Funkcija mora vrniti tabelo z imeni vseh stvari, katerih cene so bile vsaj en dan višje od podane meje meja. Vrstni red mora biti enak vrstnemu redu v tabeli stvari.
Pri tej nalogi pričakujemo rešitev v čistem numpy-ju, brez zank v Pythonu.
Takole.
def dragocenosti(stvari, cene_po_dnevih, meja):
return stvari[np.any(cene_po_dnevih > meja, axis=1)]
Ali pa takole.
def dragocenosti(stvari, cene_po_dnevih, meja):
return stvari[np.max(cene_po_dnevih, axis=1) > meja]
Imamo drevo dobaviteljev. Če se odločimo nek izdelek kupiti prek Elizabete, ga lahko dobimo od nje, lahko pa od kogarkoli, ki je v "drevesu" pod njo, recimo od Barbare, France, Alenke. Kadar gre izdelek prek več rok, vmesni členi seveda poberejo provizije: če nekaj kupimo od Elizabete, dejansko pa pride izdelek od Franca, bo Jurij pribil 10 % na Frančevo ceno, Elizabeta pa 10 % na Jurijevo.
"Drevo" je v slovarju pogodbeniki. Cene so v slovarju cene: njegovi
ključi so imena pogodbenikov, vrednosti pa slovarji, katerega ključi so
imena izdelkov, vrednosti pa cene. Elizabetina cena za metlo je v
cene["Elizabeta"]["metla"]
. Če Elizabeta nima na zalogi
metel, v njenem slovarju tega ključa ni. Če nekdo v resnici nima nobenih
izdelkov, temveč samo posreduje, ga ni niti v slovarju cene.
Predpostaviti smeš, da za vsak izdelek obstaja vsaj en ponudnik.
Napiši funkcijo najcenejsa_ponudba(dobavitelj, izdelek)
,
ki vrne najnižjo ceno, po kateri lahko od pogodbenika dobimo podani
izdelek. Ta cena je torej lahko cena, po kateri izdelek dejansko pride
od te osebe, lahko pa je cena, po kateri izdelek ponuja kdo od
podpogodbenikov, seveda z dodanimi provizijami.
Za začetek pogledamo, za koliko se reč dobi pri
dobavitelj
; če je ne ponuja, je njegova cena
inf
. Nato gremo po vseh, ki so pod njim; cene, ki jih
ponudijo, pomnožimo z 1.1 in če so nižje od najnižje doslej, si
zapomnimo to.
def najcenejsa_ponudba(dobavitelj, stvar):
= cene.get(dobavitelji, {}).get(stvar, float("inf"))
najcena for pogodbenik in dobavitelji[dobavitelj]:
= najcenejsa_ponudba(pogodbenik, stvar) * 1.1
cena if cena < najcena:
= cena
najcena return najcena
Napišite funkcijo evidenca(postavke, ime_datoteke)
, ki
prejme postavke v obliki trojk z imenom stvarmi, ceno za kos in številom
kosov, na primer
[("slika", 50, 2), ("tempera", 3, 1), ("stol", 20, 1), ("kip", 20, 12), ("zrak", 0, 141), ("torba", 12, 1)]
.
Funkcija mora v datoteko ime_datoteke zapisati tabelo v obliki, ki jo
kaže slika na desni. Točno obliko - število presledkov - razberite iz
testov.
Stvar Cena x Kosov Skupaj
------------------------------------
slika 50 x 2 100
tempera 3 x 1 3
stol 20 x 1 20
kip 20 x 12 240
zrak 0 x 141 0
torba 12 x 1 12
Tule gre zgolj za osnovno oblikovanje nizo: prešteti moramo, na
koliko znakov poravnamo kakšno stvar, pa z >
in
<
potiskati stvari na desno in na levo.
def evidenca(postavke, ime_datoteke):
= open(ime_datoteke, "w")
f f"{'Stvar':10} {'Cena':>6} x {'Kosov':<5} {'Skupaj':>10}\n")
f.write("-" * 36 + "\n")
f.write(for stvar, cena, kosov in postavke:
f"{stvar:10} {cena:>6} x {kosov:<5} {cena * kosov:10}\n") f.write(