Ga naar hoofdinhoud

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.

info

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​

  1. Draai de code. In welke volgorde komen de stations eruit?
  2. Zet boven de loop print(w.is_leeg()), en ook een onder de loop. Wat zie je?
  3. Verander in haal_eruit de pop(0) in pop(). Wat verandert er?
Python
Code-omgeving wordt voorbereid…
Antwoorden
  1. Zuid, Markt, Park: in de volgorde waarin ze erin gingen.
  2. False boven de loop, True eronder: na de loop is alles eruit.
  3. 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:

  1. Draai de code: bevat geeft nog steeds False.
  2. Loop in bevat met for knoop in self.lijst: langs de knopen, en print bij elke knoop knoop.toestand. Nu zie je twee keer Zuid en Markt.
  3. Haal de print weg. Geef True terug zodra knoop.toestand gelijk is aan toestand, en pas na de loop False.
Python
Code-omgeving wordt voorbereid…
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.