Naloge - razredi (Želva)
Unittestov ta teden ne bo.
Obrnljiva želva
Za ogrevanje dodaj želvi metodo turnAround
, ki jo obrne v nasprotno
smer.
Rešitev
Metodo turnAround
dodaj razredu Turtle
def turnAround(self):
self.turn(180)
t = Turtle()
t.turnAround()
Želva+
Razredu Turtle
dodaj metodi setWidth
in setColor
, s katerima
določiš debelino in barvo črte, ki jo za seboj pušča želva. Uporabili ju
bomo takole:
>>> t.forward(20)
>>> t.setWidth(10)
>>> t.forward(20)
>>> t.setColor(risar.rdeca)
>>> t.forward(20)
Rešitev
Prikazane so le metode, ki jih je treba spremeniti oz. dodati
def __init__(self):
self.x, self.y = risar.maxX/2, risar.maxY/2
self.angle = 0
self.penActive = True
self.width = 1 ## DODANO ##
self.color = risar.bela ## DODANO ##
self.pause = 0
self.body = risar.krog(0, 0, 5, risar.zelena, 3)
self.head = risar.krog(0, 0, 2, risar.zelena, 3)
self.update()
def forward(self, l):
angle = radians(90 - self.angle)
nx, ny = self.x+l*cos(angle), self.y-l*sin(angle)
nx, ny = max(0, nx), max(0, ny)
nx, ny = min(nx, risar.maxX), min(ny, risar.maxY)
if self.penActive:
risar.crta(self.x, self.y, nx, ny, self.color, self.width) ## SPREMENJENO ##
self.x, self.y = nx, ny
self.update()
def setWidth(self, width): ## NOVA METODA ##
self.width = width
def setColor(self, color): ## NOVA METODA ##
self.color = color
# Testiranje
t = Turtle()
t.setWidth(10)
t.forward(20)
t.setColor(risar.rdeca)
t.forward(20)
Indikator peresa
K izrisu želve dodaj še indikator, ali je pero spuščeno ali ne. Pri programiranju pazi, da bodo pravilno delovale tudi kombinacije, kot na primer
>>> t.penUp()
>>> t.hide()
>>> t.show()
Po tem mora biti pero nevidno, ker je dvignjeno.
>>> t.hide()
>>> t.penDown()
Pero mora biti nevidno, ker je želva nevidna.
Želva s spuščenim peresom
Želva z dvignjenim peresom
Pomoč: Ali je želvja glava vidna, preverite z self.head.isVisible()
.
Rešitev
Razredu Turtle dodajte oz. popravite naslednje metode:
def __init__(self):
self.x, self.y = risar.maxX/2, risar.maxY/2
self.angle = 0
self.penActive = True
self.width = 1
self.color = risar.bela
self.pause = 0
self.body = risar.krog_s(0, 0, 5, risar.zelena, 3)
self.head = risar.krog_s(0, 0, 2, risar.zelena, 3)
self.pen = risar.krog_s(0, 0, 2, risar.rumena, 3) ## DODANO ##
self.update()
def show(self):
self.body.show()
self.head.show()
if self.penActive: ## DODANO ##
self.pen.show() ## DODANO ##
def hide(self):
self.body.hide()
self.head.hide()
self.pen.hide() ## DODANO ##
def penUp(self):
self.penActive = False
self.pen.hide() ## DODANO ##
def penDown(self):
self.penActive = True
if self.head.isVisible(): ## DODANO ##
self.pen.show() ## DODANO ##
# Testiranje
import turtle
t = turtle.Turtle()
t.hide()
t.penDown()
t.wait()
Štempelj
Dodaj metodi stamp()
, ki naredi odtis želve, torej izriše želvo, ki
ostane izrisana tudi, ko gre želva naprej, in clearStamps()
, ki
pobriše vse odtisnjene želve s trenutne slike. Program
t.forward(10)
t.stamp()
t.left()
t.forward(100)
t.turn(45)
t.forward(20)
t.stamp()
t.right()
t.forward(40)
t.left()
t.forward(40)
t.right()
t.forward(40)
t.stamp()
t.right()
t.forward(40)
t.hide()
nariše
Če nato rečemo clearStamps()
, želvice izginejo:
Zahteva: metodi morata pravilno delovati tudi, če imamo več želv, ki se odtiskujejo in brišejo svoje odtise!
Namig: stamps
naj vse, kar riše, shranjuje v seznam, clearStamps
pa
pobriše narisano.
Rešitev
Najprej je bilo potrebno v funkcijo __init__
dodati seznam, v katerega
bomo shranjevali odtise želv. Dodamo, recimo
self.stamps = []
Funkciji za odtis želve in brisanje odtisov sta takšni
def stamp(self):
angle = radians(90 - self.angle)
body = risar.krog(self.x, self.y, 5, risar.zelena, 3)
head = risar.krog(self.x+5*cos(angle), self.y-5*sin(angle), 2, risar.zelena, 3)
self.stamps.append(body)
self.stamps.append(head)
def clearStamps(self):
for stamp in self.stamps:
stamp.hide()
self.stamps = []
ali takšni
def stamp(self):
t = Turtle()
t.fly(self.x, self.y, self.angle)
self.stamps.append(t)
def clearStamps(self):
for t in self.stamps:
t.hide()
self.stamps = []
Snemalnik makrov
želvi dodaj metode startRecording()
, ki sproži snemalnik makrov,
stopRecording()
, ki ustavi snemanje in vrne posneti makro, ter
play(makro)
, ki izvede posnetek.
t = Turtle()
t.startRecording()
for i in range(4):
t.forward(100)
t.right()
kvadrat = t.stopRecording()
for i in range(10):
t.turn(36)
t.play(kvadrat)
risar.stoj()
Namig: Če stvari pravilno pripravite, bo metoda play takšna
def play(self, trace):
for func, pars in trace:
func(*pars)
Kaj počne *
v vrstici func(*pars)
?
Rešitev
Razred Turtle je treba popraviti tako:
def __init__(self):
self.x, self.y = risar.maxX/2, risar.maxY/2
self.angle = 0
self.penActive = True
self.width = 1
self.color = risar.bela
self.trace = [] ## DODANO ##
self.pause = 0
self.body = risar.krog_s(0, 0, 5, risar.zelena, 3)
self.head = risar.krog_s(0, 0, 2, risar.zelena, 3)
self.pen = risar.krog_s(0, 0, 2, risar.rumena, 3)
self.update()
def startRecording(self): ## NOVA METODA ##
self.trace = []
def stopRecording(self): ## NOVA METODA ##
return self.trace[:]
def play(self, trace): ## NOVA METODA ##
for func, pars in trace:
func(*pars)
def forward(self, l):
angle = radians(90 - self.angle)
nx, ny = self.x+l*cos(angle), self.y-l*sin(angle)
nx, ny = max(0, nx), max(0, ny)
nx, ny = min(nx, risar.maxX), min(ny, risar.maxY)
if self.penActive:
risar.crta(self.x, self.y, nx, ny, self.color, self.width)
self.x, self.y = nx, ny
self.update()
self.trace.append((self.forward, (l,))) ## DODANO ##
def turn(self, angle):
self.angle += angle
self.update()
self.trace.append((self.turn, (angle,))) ## DODANO ##
# Testiranje
t = Turtle()
t.startRecording()
for i in range(4):
t.forward(100)
t.right()
kvadrat = t.stopRecording()
for i in range(10):
t.turn(36)
t.play(kvadrat)
risar.stoj()
Ali z dekoratorji:
def __init__(self):
self.x, self.y = risar.maxX/2, risar.maxY/2
self.angle = 0
self.penActive = True
self.width = 1
self.color = risar.bela
self.trace = [] ## DODANO ##
self.pause = 0
self.body = risar.krog_s(0, 0, 5, risar.zelena, 3)
self.head = risar.krog_s(0, 0, 2, risar.zelena, 3)
self.pen = risar.krog_s(0, 0, 2, risar.rumena, 3)
self.update()
def startRecording(self): ## NOVA METODA ##
self.trace = []
def stopRecording(self): ## NOVA METODA ##
return self.trace[:]
def play(self, trace): ## NOVA METODA ##
for func, pars in trace:
func(*pars)
def recorded(f):
def g(*args):
args[0].trace.append((f, args))
f(*args)
return g
@recorded
def forward(self, l):
angle = radians(90 - self.angle)
nx, ny = self.x+l*cos(angle), self.y-l*sin(angle)
nx, ny = max(0, nx), max(0, ny)
nx, ny = min(nx, risar.maxX), min(ny, risar.maxY)
if self.penActive:
risar.crta(self.x, self.y, nx, ny)
self.x, self.y = nx, ny
self.update()
@recorded
def turn(self, angle):
self.angle += angle
self.update()