Reputation: 37
I have stored turtle-graphics functions in list and am using random functions to call it to create a random-path, however code does not work.
Can someone please have a look on this and provide suggestion.
from turtle import Turtle
from turtle import Screen
import random
pen = Turtle()
pen.pensize(8)
pen.speed(10)
window = Screen()
window.colormode(255)
moves=[pen.forward(30),pen.backward(30)]
turns=[pen.right(90),pen.left(90)]
is_true = True
while is_true:
pen.color(random.randint(0,255),random.randint(0,255),random.randint(0,255))
random.choice(turns)
random.choice(moves)
window.exitonclick()
Upvotes: 2
Views: 498
Reputation: 10238
The first problem is that you don't list function calls in the lists moves
and turns
but the results of the calls. The second problem is that you don't call functions after the random.choice
calls. What you are actually getting from this is the flickering effect of the visible pen tip that endlessly changes the color.
On way to fix it is already shown in buran's answer. Another way that keeps the turn and move arguments out of the loop is the following, here lambda :
transforms the function calls into anonymous functions to which references are stored in moves
and turns
:
Another option is to extract the actual moves and turns into functions
from turtle import Turtle
from turtle import Screen
import random
pen = Turtle()
pen.pensize(8)
pen.speed(10)
window = Screen()
window.colormode(255)
moves=[lambda : pen.forward(30), lambda : pen.backward(30)]
turns=[lambda : pen.right(90), lambda : pen.left(90)]
for _ in range(100):
pen.color(random.randint(0,255),random.randint(0,255),random.randint(0,255))
random.choice(turns)()
random.choice(moves)()
window.exitonclick()
I decided to only draw 10 lines, so the turtle will most likely remain on screen. For a better way to get rid of the while True
loop (including explanation) see cdlane's answer!
Upvotes: 0
Reputation: 41872
I would say the issue here is that you are using functions as data when you could simply use data as data. That is, giving forward()
a negative distance is the same as backward()
. Giving left()
a negative angle is the same as right()
. So we can simply do:
from turtle import Screen, Turtle
from random import random, choice
DISTANCES = [30, -30]
ANGLES = [90, -90]
def move():
turtle.color(random(), random(), random())
turtle.left(choice(ANGLES))
turtle.forward(choice(DISTANCES))
screen.ontimer(move, 10)
screen = Screen()
turtle = Turtle()
turtle.pensize(8)
turtle.speed('fastest')
move()
screen.exitonclick()
I also dealt the next issue, your implicit while True:
. The way you structured your code, the exitonclick()
is never reached and doesn't work. Now it works as we've kept both the drawing and exitonclick()
in the event loop.
Upvotes: 2
Reputation: 14233
You execute the methods only when you define the two list. Change the relevant part of the code like this
moves=[pen.forward, pen.backward]
turns=[pen.right, pen.left]
while True:
pen.color(random.randint(0,255), random.randint(0,255), random.randint(0,255))
random.choice(turns)(90)
random.choice(moves)(30)
Upvotes: 0