Ga naar hoofdinhoud

15h Een klasse vol objecten

In 15g stond de lijst honden los in je programma. Een asiel kan zelf ook een klasse zijn, met de lijst honden als attribuut:

class Hond:
def __init__(self, naam, leeftijd):
self.naam = naam
self.leeftijd = leeftijd


class Asiel:
def __init__(self, naam):
self.naam = naam
self.honden = []

def neem_op(self, hond):
self.honden.append(hond)

def aantal(self):
return len(self.honden)


asiel = Asiel("De Blije Staart")
asiel.neem_op(Hond("Rex", 3))
asiel.neem_op(Hond("Bello", 7))

print(f"{asiel.naam} heeft {asiel.aantal()} honden.")

Uitvoer:

De Blije Staart heeft 2 honden.

Niets hiervan is nieuw: self.honden = [] kent je uit 15c, neem_op is een methode met een parameter uit 15e, en aantal geeft iets terug zoals in 15f. Nieuw is alleen dat de lijst nu objecten bevat, en dat het asiel die zelf bijhoudt.

Een methode die door de lijst loopt​

Een methode van het asiel kan door zijn eigen lijst lopen, zoals je in 15g door een losse lijst liep:

class Hond:
def __init__(self, naam, leeftijd):
self.naam = naam
self.leeftijd = leeftijd


class Asiel:
def __init__(self, naam):
self.naam = naam
self.honden = []

def neem_op(self, hond):
self.honden.append(hond)

def jonger_dan(self, jaar):
namen = []
for hond in self.honden:
if hond.leeftijd < jaar:
namen.append(hond.naam)
return namen


asiel = Asiel("De Blije Staart")
asiel.neem_op(Hond("Rex", 3))
asiel.neem_op(Hond("Bello", 7))
asiel.neem_op(Hond("Max", 1))

print(asiel.jonger_dan(5))

Uitvoer:

['Rex', 'Max']

Wie asiel gebruikt, hoeft niet te weten hoe de honden bewaard worden. Hij roept neem_op en jonger_dan aan, en het asiel regelt de rest.


Er gaat iets mis​

class Asiel:
def __init__(self):
self.honden = []

def neem_op(self, hond):
honden.append(hond)


asiel = Asiel()
asiel.neem_op("Rex")

Uitvoer:

NameError: name 'honden' is not defined. Did you mean: 'self.honden'?

De lijst hoort bij het asiel, dus in een methode heet hij self.honden. Zonder self. zoekt Python een losse variabele honden, en die is er niet. Python raadt het zelf al.


Opdracht 15h.1: Een afspeellijst​

Maak een klasse Afspeellijst met een naam en een lege lijst nummers. Geef hem een methode voeg_toe(nummer) en een methode totale_duur() die teruggeeft hoeveel seconden alle nummers samen duren.

Verwachte uitvoer:

Onderweg duurt 612 seconden
class Nummer:
    def __init__(self, titel, seconden):
        self.titel = titel
        self.seconden = seconden


class Afspeellijst:
    def __init__(self, naam):
        self.naam = naam
        self.nummers = []

    def voeg_toe(self, nummer):
        print(f"Nog te doen: {nummer.titel} toevoegen")

    def totale_duur(self):
        return 0


lijst = Afspeellijst("Onderweg")
lijst.voeg_toe(Nummer("Zonnig", 201))
lijst.voeg_toe(Nummer("Snelweg", 187))
lijst.voeg_toe(Nummer("Thuis", 224))
print(f"{lijst.naam} duurt {lijst.totale_duur()} seconden")
Klik hier voor een tip.

voeg_toe doet self.nummers.append(nummer). In totale_duur tel je in een loop nummer.seconden op bij een totaal dat op 0 begint.

Klik hier voor de oplossing.
class Nummer:
def __init__(self, titel, seconden):
self.titel = titel
self.seconden = seconden


class Afspeellijst:
def __init__(self, naam):
self.naam = naam
self.nummers = []

def voeg_toe(self, nummer):
self.nummers.append(nummer)

def totale_duur(self):
totaal = 0
for nummer in self.nummers:
totaal += nummer.seconden
return totaal


lijst = Afspeellijst("Onderweg")
lijst.voeg_toe(Nummer("Zonnig", 201))
lijst.voeg_toe(Nummer("Snelweg", 187))
lijst.voeg_toe(Nummer("Thuis", 224))
print(f"{lijst.naam} duurt {lijst.totale_duur()} seconden")

Uitvoer:

Onderweg duurt 612 seconden

Opdracht 15h.2: Minuten en seconden​

Geef Afspeellijst nog een methode langste() die het Nummer-object teruggeeft dat het langst duurt. Print daarna de titel en de duur in minuten en seconden.

Daarvoor gebruik je twee rekentekens die je in les 12 al zag. // deelt en gooit de rest weg: 224 // 60 is 3. % geeft juist die rest: 224 % 60 is 44. De seconden schrijf je altijd met twee cijfers: met :02 in een f-string wordt f"{4:02}" de tekst 04.

Verwachte uitvoer:

Langste nummer: Thuis (3:44)
class Nummer:
    def __init__(self, titel, seconden):
        self.titel = titel
        self.seconden = seconden


class Afspeellijst:
    def __init__(self, naam):
        self.naam = naam
        self.nummers = []

    def voeg_toe(self, nummer):
        self.nummers.append(nummer)

    def langste(self):
        return self.nummers[0]


lijst = Afspeellijst("Onderweg")
lijst.voeg_toe(Nummer("Zonnig", 201))
lijst.voeg_toe(Nummer("Snelweg", 187))
lijst.voeg_toe(Nummer("Thuis", 224))

nummer = lijst.langste()
print(f"Langste nummer: {nummer.titel} ({nummer.seconden} s)")
Klik hier voor een tip.

Zoek het langste nummer zoals je in 15g.1 het dikste boek zocht. Reken daarna buiten de klasse de minuten en seconden uit.

Klik hier voor de oplossing.
class Nummer:
def __init__(self, titel, seconden):
self.titel = titel
self.seconden = seconden


class Afspeellijst:
def __init__(self, naam):
self.naam = naam
self.nummers = []

def voeg_toe(self, nummer):
self.nummers.append(nummer)

def langste(self):
langste = self.nummers[0]
for nummer in self.nummers:
if nummer.seconden > langste.seconden:
langste = nummer
return langste


lijst = Afspeellijst("Onderweg")
lijst.voeg_toe(Nummer("Zonnig", 201))
lijst.voeg_toe(Nummer("Snelweg", 187))
lijst.voeg_toe(Nummer("Thuis", 224))

nummer = lijst.langste()
minuten = nummer.seconden // 60
seconden = nummer.seconden % 60
print(f"Langste nummer: {nummer.titel} ({minuten}:{seconden:02})")

Uitvoer:

Langste nummer: Thuis (3:44)