Tule so rešene izpitne naloge. Pri vsaki nalogi sem pokazal nekaj možnih rešitev in premislekov (razen pri tistih, ki so za to preenostavne). Pravilne pa so seveda tudi druge rešitve, ki dajo pravi rezultat. Nekatere od napisanih rešitev očitno presegajo pricakovani nivo znanja. Vsaka naloga pa je, kot boste videli, preprosto rešljiva tudi z osnovnim znanjem.
Izpit je bil v resnici lažji, kot se morda zdi. :)
Dan v letu
Ta naloga je bila ogrevalna.
def danVLetu(dan, mesec):
dni = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
return sum(dni[:mesec-1]) + dan
Po starosti
Da bo rešitev preglednejša, si pripravimo funkcijo, ki ji damo EMŠO, na primer "2012983505012" in vrne rojstni datum v formatu 19821220, se pravi najprej leto rojstva s štirimi števkami, nato mesec, nato dan (YYYYMMDD).
def datumIzEmso(emso):
dat = emso[4:7] + emso[2:4] + emso[:2]
if dat[0] == "0":
return "2"+dat
else:
return "1"+dat
Stavek if
na koncu služi temu, da pri tistih, katerih trimestna letnica se začne z 0, dodamo na začetek dvojko (rojeni so po 2000), tistim, ki imajo 8 ali 9, pa enico (18xx, 19xx). Mimogrede, šlo bi tudi takole
def datumIzEmso(emso):
return ("2" if emso[4]=="0" else "1") + emso[4:7] + emso[2:4] + emso[:2]
in, grše, takole
def datumIzEmso(emso):
return "12"[emso[4]] + emso[4:7] + emso[2:4] + emso[:2]
Odtod je naša pot lahka. Seznam predelamo tako, da bo imel namesto parov (ime, EMŠO) pare (datum, ime). Tak seznam lahko uredimo s sort
, saj bo le-ta urejal najprej po prvem elementu para, datumu (če bosta dve osebi rojeni na isti dan, pa ju uredi po imenu). Nato iz urejenega seznama poberemo imena.
def poStarosti(s):
novSez = []
for ime, emso in s:
novSez.append((datumIzEmso(emso), ime))
novSez.sort()
rez = []
for datum, ime in novSez:
rez.append(ime)
return rez
Če se spomnimo izpeljevanja seznamov, pa moremo nalogo rešiti tudi hitreje.
def poStarosti(s):
novSez = [(datumIzEmso(emso), ime) for ime, emso in s]
novSez.sort()
return [ime for datum, ime in novSez]
Lahko pa rečemo celo kar
def poStarosti(s):
return [ime for datum, ime in sorted((datumIzEmso(emso), ime) for ime, emso in s)]
Še nekaj truda pa si prihranimo, če vemo, da ima sort
dodaten argument key
.
def poStarosti(s):
return [ime for ime, emso in sorted(s, key=datumIzEmso)]
ali pa kar
def poStarosti(s):
return [e[0] for e in sorted(s, key=lambda x: datumIzEmso(x[1])]
Če bi
datumIzEmso
napisali tako, da bi sprejemala kar cel par (oseba, EMŠO), pa bi lahko napisali preprosto
def poStarosti(s):
return [e[0] for e in sorted(s, key=datumIzEmso]
Število znakov
Spet najprej poglejmo nerodno rešitev: z zanko gremo čez črke besede in v seznam zlagamo vse črke, ki še niso v seznamu. To storimo za vsako besedo in vrnemo tisto z najdaljšim seznamom.
def najraznolika(bes):
najCrk = 0
for b in bes:
crke = []
for c in b.lower():
if not c in crke:
crke.append(c)
if len(crke) > najCrk:
najCrk = len(crke)
najBeseda = b
return najBeseda
Veliko elegantnejša je rešitev z množicami (spomnite se na nalogo z vislicami!).
def najraznolika(bes):
najCrk = 0
for b in bes:
crk = len(set(b.lower()))
if crk > najCrk:
najCrk = crk
najBeseda = b
return najBeseda
Rokohitreci pa vedo, da ima funkcija max
dodaten argument key
in nalogo rešijo v enem zamahu.
def najraznolika(bes):
return max(l, key=lambda x:len(set(x.lower())))
Numerologija
Vrednost črke c
dobimo tako, da od ord(c)
odštejemo 64. Vrednosti seštejemo, nato pa ponavljamo tole: gremo preko števk vsote, jih seštevamo... in to počnemo, dokler vsota ni manjša od 9.
def numerologija(ime):
vs = 0
for c in ime.upper():
vs += ord(c) - 64
while vs > 9:
nova = 0
for c in str(vs):
nova += int(c)
vs = nova
return vs
Kot druge tudi ta naloga postane smešno preprosta z malo funkcijskega programiranja.
def numerologija(ime):
s = sum(ord(c)-64 for c in ime.upper())
while s >= 10:
s = sum(map(int, str(s)))
return s
Delnice
Čeprav za probleme tega tipa (in, najbrž, tudi za ta problem) obstajajo učinkovitejše rešitve, ki jih boste spoznavali v drugem letniku, je preprost rešitev z dvema zankama prav enostavna. V zunanji zanki poskušamo mesece nakupa delnice, za vsak mesec nakupa pa poskusimo vse možne mesece prodaje. Dobiček izračunamo tako, da seštejemo spremembe vrednosti delnice od meseca nakupa do meseca prodaje.
def posrednik(delnica):
najDobicek = -1
for od in range(12):
for do in range(od, 12):
dobicek = sum(delnica[od:do])
if dobicek > najDobicek:
najDobicek = dobicek
najOd, najDo = od, do
return najOd, najDo
Vse skupaj
Spet zberimo rešitve celotnega izpita, kakor bi jih lahko rešil študent brez posebno naprednega programiranja.
# Naloga 1
def danVLetu(dan, mesec):
dni = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
return sum(dni[:mesec-1] + dan)
# Naloga 2
def poStarosti(s):
novSez = []
for ime, emso in s:
dat = emso[4:7] + emso[2:4] + emso[:2]
if dat[0] == "0":
dat = "2"+dat
else:
dat = "1"+dat
novSez.append((dat, ime))
novSez.sort()
rez = []
for datum, ime in novSez:
rez.append(ime)
return rez
# Naloga 3
def najraznolika(bes):
najCrk = 0
for b in bes:
crk = len(set(b.lower()))
if crk > najCrk:
najCrk = crk
najBeseda = b
return najBeseda
# Naloga 4
def numerologija(ime):
vs = 0
for c in ime.upper():
vs += ord(c) - 64
while vs > 9:
nova = 0
for c in str(vs):
nova += int(c)
vs = nova
return vs
# Naloga 5
def posrednik(delnica):
najDobicek = -1
for od in range(12):
for do in range(od, 12):
dobicek = sum(delnica[od:do])
if dobicek > najDobicek:
najDobicek = dobicek
najOd, najDo = od, do
return najOd, najDo
Krajše rešitve pa so takšne (seveda gre še krajše, ampak tisto je pa že grdo).
# Naloga 1
def danVLetu(dan, mesec):
dni = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
return sum(dni[:mesec-1] + dan)
# Naloga 2
def datumIzEmso(emso):
return "12"[emso[4]] + emso[4:7] + emso[2:4] + emso[:2]
def poStarosti(s):
return [ime for ime, emso in sorted(s, key=datumIzEmso)]
# Naloga 3
def najraznolika(bes):
return max(l, key=lambda x:len(set(x.lower())))
# Naloga 4
def numerologija(ime):
s = sum(ord(c)-64 for c in ime.upper())
while s >= 10:
s = sum(map(int, str(s)))
return s
# Naloga 5
def posrednik(delnica):
najDobicek = -1
for od in range(12):
for do in range(od, 12):
dobicek = sum(delnica[od:do])
if dobicek > najDobicek:
najDobicek = dobicek
najOd, najDo = od, do
return najOd, najDo