De weg met lijnen
Je hebt nu alle onderdelen: het netwerk met buren, een Knoop die onthoudt
waar hij vandaan kwam, en een Wachtrij. In deze stap zet je ze samen in een
functie reis(van, naar). Die geeft de weg als een lijst paren: bij elke
halte de lijn waarmee je er komt.
Voorspel
weg = []
weg.insert(0, ("rood", "Strand"))
weg.insert(0, ("rood", "Haven"))
weg.insert(0, ("blauw", "Markt"))
for lijn, station in weg:
print("Neem", lijn, "naar", station)
Wat print dit programma?
Antwoord
Neem blauw naar Markt
Neem rood naar Haven
Neem rood naar Strand
Elk paar komt vooraan, dus het laatst toegevoegde paar staat voorop. Zo bouw je de weg op als je van het eind terugloopt.
Zo werkt het
Het zoeken is hetzelfde als in het doolhof, maar in de wachtrij staan nu
knopen. Bij elke nieuwe buur maak je een knoop met de buur als toestand, de
huidige knoop als ouder en de lijn als actie. De lijst gezien onthoudt welke
stations al een knoop hebben, zoals afstand dat in het doolhof deed.
Haal je de knoop van naar uit de wachtrij, dan loop je via ouder terug.
Bij elke knoop zet je het paar (knoop.actie, knoop.toestand) vooraan in de
weg. De start komt er niet in: daar nam je geen lijn.
In deze functie staan twee while-loops. Stopt er een nooit, dan loopt het tabblad vast, want de speeltuin heeft geen stopknop: herlaad de pagina, en je code is weg. Kopieer je code daarom eerst naar een kladblok voordat je een nieuwe while-loop draait.
Onderzoek
- Draai de code. In welke volgorde komen de stations uit de wachtrij?
- Waarom komen Centraal, Haven en Park allemaal vóór Strand?
- Zet
van = "Strand". Welk station komt als laatste?
Antwoorden
- Zuid, Markt, Centraal, Haven, Park, Strand, Museum, Noord, Stadion.
- Die liggen twee haltes van Zuid, Strand drie. Een wachtrij geeft eerst alles op twee haltes, dan alles op drie.
- Noord: dat is vier haltes van Strand, verder dan elk ander station.
Opdracht: een reis plannen
Schrijf de functie reis(van, naar), die de weg geeft als lijst paren
(lijn, station), en None als er geen weg is:
[('blauw', 'Markt'), ('rood', 'Haven'), ('rood', 'Strand')]
[('blauw', 'Park'), ('groen', 'Stadion'), ('geel', 'Museum')]
None
Begin klein, en breid de code stap voor stap uit:
- Draai de code:
reisgeeft nog"?". - Kijk in de while-loop, direct na
haal_eruit, ofknoop.toestand == naar. Zo ja, geef danknoop.toestandterug. Nu print hijStrand. - Loop daar in plaats daarvan terug langs
knoop.ouder, zoals bij een knoop, en zet elk paar vooraan in een lijstweg. Geefwegterug. - Vraag ook
reis("Noord", "Museum")enreis("Zuid", "Eiland"), en zet onderaanreturn Nonein plaats vanreturn "?".
Tip
Mist het laatste station in de weg, of staat Zuid erin? Kijk in welke
volgorde je in de loop het paar toevoegt en knoop = knoop.ouder doet.
Antwoord
Dit vervangt alles in de editor:
def reis(van, naar):
wachtrij = Wachtrij()
wachtrij.voeg_toe(Knoop(van, None, None))
gezien = [van]
while not wachtrij.is_leeg():
knoop = wachtrij.haal_eruit()
if knoop.toestand == naar:
weg = []
while knoop.ouder is not None:
weg.insert(0, (knoop.actie, knoop.toestand))
knoop = knoop.ouder
return weg
for lijn, buur in buren(knoop.toestand):
if buur not in gezien:
gezien.append(buur)
wachtrij.voeg_toe(Knoop(buur, knoop, lijn))
return None
print(reis("Zuid", "Strand"))
print(reis("Noord", "Museum"))
print(reis("Zuid", "Eiland"))
[('blauw', 'Markt'), ('rood', 'Haven'), ('rood', 'Strand')]
[('blauw', 'Park'), ('groen', 'Stadion'), ('geel', 'Museum')]
None
Eiland staat niet in het netwerk. De wachtrij raakt leeg zonder dat de knoop
van Eiland langskwam, en dan komt de functie bij return None.
Door naar overstappen.