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
Zadnja sprememba: sreda, 10. avgust 2011, 10.20