Een klasse
Bij Nim die leert stonden de tabel score en de functies die hem gebruiken
los van elkaar. In het project Nim van CS50 AI zitten ze samen in een
klasse: één ding met een tabel en de functies die erbij horen. Dit
project oefent dat op een ander spel: een muis in een gang, die leert waar de
kaas ligt. Je begint met de klasse zelf. Nieuw zijn class, __init__ en
self.
Je gebruikt in dit project class, __init__ en self uit
Je eerste klasse, een
attribuut met een beginwaarde uit
Attributen veranderen,
methoden uit Je eerste methode
en Methoden met return,
random.random() uit
de surfer springt soms,
en een tuple als sleutel uit
een score per zet.
Voorspel
class Muis:
def __init__(self, vakje):
self.vakje = vakje
piep = Muis(2)
snuf = Muis(0)
piep.vakje = piep.vakje + 1
print(piep.vakje, snuf.vakje)
Wat print dit programma?
Antwoord
3 0. piep en snuf hebben elk een eigen vakje. Zet je piep een vakje
verder, dan blijft snuf staan.
Zo werkt het
Klassen zijn nieuw in de route. De python-cursus legt ze uit in Je eerste klasse; dit zijn de regels die je hier nodig hebt:
class Muis:maakt een klasse. De naam begint met een hoofdletter.__init__zegt wat er gebeurt als je een nieuwe muis maakt, metMuis(2). De twee lage streepjes voor en nainithoren erbij.selfis de muis die op dat moment gemaakt wordt.self.vakje = vakjebewaart het vakje in die muis.piepis een object: één muis, gemaakt volgens de klasse. Metpiep.vakjelees je zijn vakje, en metpiep.vakje = 3zet je het.
Een attribuut kan ook een dictionary zijn. Bij CS50 heeft de speler een tabel
self.q, met een waarde voor elke stand en elke zet, net als score bij Nim.
De muis krijgt er ook een. Elke muis heeft dan zijn eigen tabel.
Onderzoek
- Draai de code. Waarom is de tabel van
snufleeg? - Zet onderaan
snuf.vakjeop 3, en print beide muizen opnieuw. Verandertpiepmee? - Haal in
__init__deself.weg vóórq = {}. Wat gebeurt er nu?
Wat zie je?
2 {(2, 'rechts'): 0.5}
2 {}
Antwoorden
- Elke muis krijgt in
__init__een eigen, lege tabel. Je zette alleen iets in de tabel vanpiep. - Nee.
piepblijft in vakje 2: elk object heeft zijn eigen attributen. - Python stopt met een foutmelding, zie
Er gaat iets mis. Zonder
self.isqeen gewone variabele in__init__, die verdwijnt als__init__klaar is. De muis heeft dan geen tabel.
Opdracht: twee muizen
Geef de muis een naam en een teller voor zijn stappen. Laat piep twee
stappen naar rechts zetten, en maak een tweede muis snuf in vakje 1:
Piep zit in vakje 4 na 2 stappen
Snuf zit in vakje 1 na 0 stappen
Begin klein, en breid de code stap voor stap uit:
- Draai de code: je ziet in welk vakje
piepzit. - Geef
__init__een tweede parameternaam, bewaar hem in de muis, en print de naam in plaats van het woord piep. - Geef elke muis een attribuut
stappendat op 0 begint. Zetpieptwee keer een vakje naar rechts, en tel elke keer een stap bij zijnstappenop. - Maak een tweede muis
snufin vakje 1, en print hem ook.
Tip
De volgorde telt: Muis("Piep", 2) vult de parameters na self van links
naar rechts in. Staat in __init__ eerst naam en dan vakje, dan wordt
"Piep" de naam.
Antwoord
class Muis:
def __init__(self, naam, vakje):
self.naam = naam
self.vakje = vakje
self.stappen = 0
piep = Muis("Piep", 2)
piep.vakje = piep.vakje + 1
piep.stappen = piep.stappen + 1
piep.vakje = piep.vakje + 1
piep.stappen = piep.stappen + 1
snuf = Muis("Snuf", 1)
print(piep.naam, "zit in vakje", piep.vakje, "na", piep.stappen, "stappen")
print(snuf.naam, "zit in vakje", snuf.vakje, "na", snuf.stappen, "stappen")
Piep zit in vakje 4 na 2 stappen
Snuf zit in vakje 1 na 0 stappen
stappen is geen parameter: elke nieuwe muis begint op 0. Twee keer
dezelfde twee regels voor een stap is wel veel. In de volgende stap maak je
daar een methode van.
Er gaat iets mis
AttributeError: 'Muis' object has no attribute 'q'
Oorzaak: in __init__ staat q = {} zonder self.. Dan is q een
variabele die alleen in __init__ bestaat, en krijgt de muis zelf geen tabel.
Oplossing: zet self. voor elk attribuut dat de muis moet onthouden.
# FOUT
class Muis:
def __init__(self, vakje):
self.vakje = vakje
q = {}
piep = Muis(2)
piep.q[(2, "rechts")] = 0.5
# GOED
class Muis:
def __init__(self, vakje):
self.vakje = vakje
self.q = {}
piep = Muis(2)
piep.q[(2, "rechts")] = 0.5
Meer uitleg: Je eerste klasse.
Door naar methoden.