V tej nalogi se bomo spet posvetili rodbinskim vprašanjem. Ta smo raziskovali, ko smo se učili o rekurziji. Ob oni priložnosti sem pripravil razred Oseba, vendar o njem nisem povedal nič posebnega. Zdaj smo pametnejši in ga lahko razumemo. Če izpustimo metode, ki so skrble le za lepši izpis, in dodamo metodo, ki jo bomo potrebovali tokrat, je bil videti takole:

class Oseba: def __init__(self, prednik, ime, spol, starost): self.prednik = prednik self.ime = ime self.spol = spol self.starost = starost self.otroci = [] def linija(self): dolzina = 0 oseba = self while oseba is not None: dolzina += 1 oseba = oseba.dedic() return dolzina

Vsaka oseba ima torej ime prednika, svoje ime, spol in starost ter seznam otrok (ki je lahko tudi prazen).

Celotno rodbino, s katero se ukvarjajo testi, kaže slika.

Ogrevalna naloga

Napiši metodi stevilo_otrok in stevilo_vnukov, ki za podano osebo vrneta število njenih otrok in število njenih vnukov. Če je oseba, recimo, Elizabeta, mora klic oseba.stevilo_otrok() vrniti 5, oseba.stevilo_vnukov() pa 3.

Obvezna naloga

V večini kultur je dedič (na primer kraljestva) prvorojenec. Med Judi pa so pogosto dedovali drugorojenci (Abrahama je nasledil drugi sin, Izak; Izaka je nasledil njegov drugi sin, Jakob; Jakoba je (OK, to ne deluje čisto, ampak skoraj ;) nasledil prvi sin njegove druge žene, Jožef); Jožefa je nasledil njegov drugi sin, Efraim). Po tej kratki in za potrebe naloge ne tako pomembni biblični študiji se delajmo, da je med Judi in še v kaki drugi kulturi pravilo, da je dedič drugi otrok. Glede spola podprimo emancipacijo in ga zanemarimo.

V razredu Oseba je že napisana metoda linija, ki je ne smete spreminjati!!!. Metoda linija izračuna najdaljšo linijo dedičev od določene osebe naprej. Če rečemo, da gre Adamova rodbina po prvorojencih, je njegova rodbina dolga 4, namreč Adam - Matjaž - Viljem - Tadeja. Če pa gre Adamova rodbina po drugorojencih, je dolga 2, namreč Adam - Cilka. Za drug primer vzemimo Elizabeto: po prvorojencih bi bila njena rodbina dolga 2 (Elizabeta - Ludvik), če štejejo drugorojenci, pa 4 (Elizabeta - Jurij - Jožef - Petra).

Metoda linija uporablja metodo dedic, ki vrne dediča. Vendar razred oseba te metode ne definira.

Definiraj razred Oseba1, ki definira osebo, pri kateri metoda dedic vrne prvorojenca in razred Oseba2, ki definira osebo, pri kateri metoda dedic vrne drugorojenca. Če oseba nima otrok (oz. nima dveh otrok), naj vrne None.

Opomba: testi so napisani tako, da enkrat preberejo celotno rodbino, kot da gre za objekte vrste Oseba1 in testirajo metodo linija; metoda linija bo delala pravilno, če ste pravilno definirali metodo dedic. Nato testi ponovijo vse skupaj tako, da celotno rodbino naložijo kot objekte Oseba2.

Dodatna naloga

Osebam dodaj metodo velikost_rodbine, ki vrne celotno velikost rodbine. Če je oseba, recimo, Jurij, mora oseba.velikost_rodbine() vrniti 6.

Opozorilo

Metode stevilo_otrok, stevilo_vnukov in velikost_rodbine dodate razredu Oseba. Metodi dedic dodate novim razredom, ki jih morate definirati.

In, še enkrat, metode linija ne smete spreminjati!

Rešitev

Tokratne rešitve bodo kratke in komentarji tudi, saj je bila takšna tudi naloga.

Ogrevalna naloga

Metodi, ki ju je bilo potrebno dodati za ogrevalno nalogo, sta

def stevilo_otrok(self): return len(self.otroci) def stevilo_vnukov(self): vnukov = 0 for otrok in self.otroci: vnukov += otrok.stevilo_otrok() return vnukov

Bistvo naloge je le, da znate napisati metodo in pravilno uporabljati self.

Obvezna naloga

Ob predpostavki, da so otroci našteti po vrsti, je rešitev takšna

class Oseba1(Oseba): def dedic(self): if self.otroci: return self.otroci[0] class Oseba2(Oseba): def dedic(self): if len(self.otroci) >= 2: return self.otroci[1]

Dodatna naloga

Rešitev dodatne naloge prepišemo iz zapiskov o rodbini, le da spremenimo funkcijo v metodo in mimogrede popravimo tudi rekurzivni klic iz velikost_rodbine(otrok) v otrok.velikost_rodbina.

def velikost_rodbine(self): velikost = 1 for otrok in self.otroci: velikost += otrok.velikost_rodbine() return velikost
Última modificación: jueves, 23 de abril de 2015, 22:10