Čebelja statistika
Testi
Testi: testi-cebelja-statistika.zip
Naloga
V nalogi se bomo ukvarjali kar s čebelarjenjem, saj ste se v prejšnji nalogi dodobra spoznali s čebeljim zapisom količine nektarja v cvetovih.
Bistvo te domače naloge je, da vse rešitve napišete v eni sami vrstici.
Vse funkcije morajo biti takšne:
def ime_funkcije(argumenti):
return tule_pise_kar_pac_mora_pisati
Ogrevalni nalogi
V ogrevalnih nalogah ne pozabite, da ima Python funkciji
sum(s)
in max(s)
, ki vrneta vsoto elementov
seznama s
in njegov največji element.
Vsota po vrstah
Napiši funkcijo po_vrstah(vrt)
, ki vrne seznam vsot količin
nektarja po vseh vrstah. Torej,
po_vrstah([[3, 5, 1], [1, 1, 1], [2, 0, 4]])
mora vrniti
[9, 3, 6]
.
Najboljši v vrsti
Napiši funkcijo najboljsi(vrt)
, ki vrne seznam z
maksimalnimi količin nektarja po vseh vrstah. Torej,
najboljsi([[3, 5, 1], [1, 1, 1], [2, 0, 4]])
mora vrniti
[5, 1, 4]
.
O teh nalogi ni izgubljati besed: prva zahteva seznam vsot, druga seznam maksimumov vrstice - za vsako vrstico v vrtu. Ali, v Pythonu
Obvezne naloge
Apis diagonalicus
Napiši funkcijo diagonala(vrt)
, ki pove, koliko naberejo
čebele vrste Apis diagonalicus, ki gredo čez vrt vedno po
diagonali, (0, 0), (1, 1), (2, 2), ...), dokler ne pridejo do roba. Klic
po_diagonali([[3, 5, 1], [1, 1, 1], [2, 0, 4]])
mora vrniti 8
(to je, 3 + 1 + 4).
Sešteti moramo torej vrt[i][i]
za vsak i
od 0
do - koliko? Do len(vrt)
ali len(vrt[0])
? Do
tistega, kar je manjše; čebela bo šla po diagonali in se ustavi, ki ji
zmanjka bodisi vrstic bodisi stolpcev.
Palindromni vrt
Napiši fukcijo je_palindromen
, ki pove, ali je vrt
palindromen. Vrt je palindromen, če so vse njegove vrste palindromi.
Spomnite se, kako v Pythonu hitro ugotovimo, ali je nek niz (ali seznam,
saj je isto) palindrom.
Ali je neka vrsta
palindromna, preverimo z
vrsta == vrsta[::-1]
. Funkcija mora preveriti, ali to velja
za vsako vrsto v vrtu (for vrsta in vrt
), torej
Palindromne vrste
Napiši fukcijo palindromne
, ki vrne vse palindromne vrste
v vrtu. (Povedano bližje Pythonu: vrniti mora seznam vseh tistih vrstic,
ki so palindrome.) Tako mora
palindromne([[1, 2, 2, 1], [1, 2, 3, 4], [0, 7, 7, 0], [0, 0, 0, 1]])
vrniti [[1, 2, 2, 1], [0, 7, 7, 0]]
.
Besedilo naloge je že izdalo vse.
Dodatne naloge
Dodatne naloge so zahtevale dvojne zanke.
Branje datotek
Čebele shranjujejo stanje vrtov v datoteke.
Nekaj primerov najdete na
Učilnici. Napišite funkcijo preberi_vrt(ime_dat)
, ki prebere
datoteko s podanim imenom ime_dat
in vrne vsebino v takšni
obliki kot, so navadno zapisani vrtovi (s seznamom seznamov).
Če imamo nek niz števil, ločenih z vejico, naredimo iz njega seznam
števil tako: [int(x) for x in vrsta.split(",")]
. Druga
možnost - o kateri se sicer nismo učili - je, da uporabimo funkcijo
map
, takole: map(int, vrsta.split(","))
. Čeprav je
map
krajši, so izpeljani seznami pogosto hitrejši, predvsem pa
jih imamo za lepše.
Zdaj, ko vemo, kako predelati eno vrstico, to storimo z vsemi vrsticami iz datoteke:
Nekateri so tu pisali
for vrsta in open(ime_dat).read().splitlines()
, vendar to ni
potrebno; če spustimo zanko for
čez datoteko, počne natančno
isto, kot če se sami zafrkavamo s splitlines
(pa še manj
pomnilnika pokuri).
Apis vraževernikus
Recimo, da imamo že napisano funkcijo
ki pove, ali je podano število n
praštevilo (funkcija,
čisto preprosto, pove, ali so ostanki po deljenju n z i različni od 0 za vse
i-je od 2 do n-1).
Napiši funkcijo prastevilski(vrt)
, ki kot argument dobi vrt
in kot rezultat vrne vrt, v katerem so čebele obrale vse cvetove razen
tistih, v katerih je količina nektarja praštevilo. (Gre namreč za vrsto
Apis vraževernikus, ki se takšnih cvetov boji.) Z drugimi besedami,
vsa sestavljena števila nadomestite z 0.
Klic prastevilski([[3, 5, 1], [7, 8, 12], [9, 3, 4]])
mora
vrniti [[3, 5, 1], [7, 0, 0], [0, 3, 0]]
.
Če bi naloga zahtevala, da to naredimo samo z navadnim seznamom
vrsta
, bi pisali
[x if prastevilo(x) else 0 for x in vrsta]
, to je, hočemo
seznam, ki za vsak x
vsebuje x
, če je
x
praštevilo, in 0
, če ni.
Zdaj pa, tako kot prej, to naredimo prek vseh vrst.
Apis vraževernikus (2)
Napiši funkcijo vrazevernikus(vrt)
, ki pove, koliko nektarja
nabere vraževerna čebela, če v podanem vrtu obere vse, kar si upa.
Tole je isto kot prej, le da ne ustvarjamo seznamov, temveč računamo vsote.
Povsod kaj praznega
Napiši funkcijo povsod_0(vrt)
, ki pove, ali je v vsaki
vrstici vrta vsaj ena ničla.
V malo grši slovenščini, a bližje Pythonu: za vse vrste morajo veljati, da je vse en njihov element enak 0.
Vedno več
Napiši funkcijo vedno_vec(vrt)
, ki pove, ali je res, da je v
vrtu v vsaki naslednji vrsti vsaj toliko nektarja kot v prejšnji (torej,
vsota nektarja v prvi vrstici mora biti večja ali enaka vsoti v ničti, vsota
v drugi večja ali enaka vsoti v prvi in tako naprej). Namig:
zip(vrt, vrt[1:])
.
Namignjeni zip
nam sestavi natančno pare, ki jih moramo
primerjati - ničtega in prvega, prvega in drugega, drugega in tretjega...
Prvi element iz para mora biti manjši ali enak drugemu za vse pare:
Vedno več ali manj
Napiši funkcijo vedno_vec_ali_manj(vrt)
, ki pove, ali je
res, da je količina nektarja po vrsti nepadajoča (kot v prejšnji funkciji)
ali pa nenaraščajoča (tako, da je v vsaki naslednji vrstici kvečjemu
toliko nektarja kot v prejšnji.
Trik te naloge je v tem, da se je ne da rešiti tako, kot bi morda naivno naredili na prvi pogled.
Težava je v tem, da je pogoj vedno resničen, saj bo prva vsota manjša ali pa večja od druge (ali pa celo enaka, obakrat ;).
Najbrž je najboljše, kar lahko storimo, to, da združimo prejšnjo funkcijo in obrnjeno.
Kot pravilno rešitev bi priznali tudi tole duhovitost:
Če bi bil prehod prek seznama "drag" (ker je seznam velik ali pa, recimo, ne gre za seznam temveč za datoteko, ki jo sproti beremo, ali za podatke, ki jih sproti dobivamo iz baze), bi se morali potruditi sprogramirati funkcijo tako, da gre prek seznama le enkrat. Razmislite, kako.