addy yt
addy yt

Reputation: 37

Create random-path by randomly choosing from lists of stored turtle-graphics functions

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

Answers (3)

Wolf
Wolf

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

cdlane
cdlane

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

buran
buran

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

Related Questions