Een wachtrij als klasse
Tot nu toe was de wachtrij een lijst, met append en pop(0). CS50 geeft je
de wachtrij als klasse, met methoden om iets toe te voegen, het voorste eruit
te halen en te kijken of hij leeg is. Hier bouw je zo'n klasse zelf,
zodat je straks herkent wat CS50 je geeft.
Een methode, met self als eerste parameter, leer je in
Je eerste methode, en een
methode met return in
Methoden met return.
Voorspel
class Wachtrij:
def __init__(self):
self.lijst = []
def voeg_toe(self, iets):
self.lijst.append(iets)
w = Wachtrij()
w.voeg_toe("Zuid")
w.voeg_toe("Markt")
print(w.lijst)
Wat print dit programma?
Antwoord
['Zuid', 'Markt']
De wachtrij heeft een lijst in zich, self.lijst. voeg_toe zet iets
achteraan in die lijst.
Zo werkt het
Een Wachtrij bewaart zijn lijst zelf, en de rest van je code gebruikt alleen
de methoden: voeg_toe, haal_eruit en is_leeg. Hoe de wachtrij dat doet,
staat op één plek. Verander je in haal_eruit de pop(0) in pop(), dan is
het een stapel, zonder dat de rest van je code verandert. CS50 heeft daarom
twee klassen: een voor een stapel en een voor een wachtrij.
while not w.is_leeg(): gaat door zolang de wachtrij niet leeg is. Dat is
hetzelfde als while len(wachtrij) > 0: met een gewone lijst.
Onderzoek
- Draai de code. In welke volgorde komen de stations eruit?
- Zet boven de loop
print(w.is_leeg()), en ook een onder de loop. Wat zie je? - Verander in
haal_eruitdepop(0)inpop(). Wat verandert er?
Antwoorden
- Zuid, Markt, Park: in de volgorde waarin ze erin gingen.
Falseboven de loop,Trueeronder: na de loop is alles eruit.- Nu komt Park eerst, dan Markt, dan Zuid. De wachtrij is een stapel geworden, terwijl de loop onderaan hetzelfde bleef.
Opdracht: zit hij erin?
Geef de wachtrij een methode bevat(toestand), die True geeft als er een
knoop met die toestand in de wachtrij staat, en anders False. CS50 geeft
zijn wachtrij net zo'n methode.
True
False
Begin klein, en breid de code stap voor stap uit:
- Draai de code:
bevatgeeft nog steedsFalse. - Loop in
bevatmetfor knoop in self.lijst:langs de knopen, en print bij elke knoopknoop.toestand. Nu zie je twee keer Zuid en Markt. - Haal de print weg. Geef
Trueterug zodraknoop.toestandgelijk is aantoestand, en pas na de loopFalse.
Tip
Geeft hij False voor Markt? Kijk dan of de return False niet in de loop
staat: dan stopt de methode al bij de eerste knoop.
Antwoord
Dit vervangt de methode bevat in de editor:
def bevat(self, toestand):
for knoop in self.lijst:
if knoop.toestand == toestand:
return True
return False
Draai je de editor nu, dan zie je True en False. Een return in een loop
stopt de hele methode. Pas als geen enkele knoop
past, kom je bij return False.
Er gaat iets mis
TypeError: Wachtrij.voeg_toe() takes 1 positional argument but 2 were given
Oorzaak: je vergat self bovenaan de methode. Bij w.voeg_toe("Zuid")
geeft Python de wachtrij zelf als eerste mee, en "Zuid" als tweede. De
methode had maar plaats voor één.
Oplossing: zet self als eerste parameter van elke methode.
# FOUT
class Wachtrij:
def __init__(self):
self.lijst = []
def voeg_toe(iets):
self.lijst.append(iets)
Wachtrij().voeg_toe("Zuid")
# GOED
class Wachtrij:
def __init__(self):
self.lijst = []
def voeg_toe(self, iets):
self.lijst.append(iets)
Wachtrij().voeg_toe("Zuid")
Door naar de weg met lijnen.