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

zelva_dol

Želva z dvignjenim peresom

zelva_gor

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

stamp1

Če nato rečemo clearStamps(), želvice izginejo:

stamp2

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()
Последнее изменение: понедельник, 6 ноября 2023, 09:40