Shadiester
Shadiester

Reputation: 33

Increase the number of steps Python turtle performs each second?

My class has been learning Python's Turtle module recently (which I gather uses tkinter), and I was wondering if there was a way to adjust the rate at which tkinter/turtle executes its code, because it doesn't seem (from my limited understanding) to be limited by the computational abilities of my computer. I say that because in task manager (I'm on Windows if that affects anything), the python shell only uses a small percentage of the CPU's limits (~2%) and likewise for the GPU, RAM, disc etc. Additionally, increasing it's operational priority neither affects how much of my CPU is used, nor does it increase the rate it executes its code.

Note that I'm not referring to the speed that the Turtle executes each action as determined by turtle.speed(), I've already got that at '0' such that it's effectively instantaneous, my problem instead lies with what seems to be the time taken between each step which appears to be limited to 80 actions per second (more on this later).

For example, the following code draws an approximation of a parabola, given some precision. The higher the precision, the better the approximation but the longer it takes to draw, as it's taking more, smaller steps.

precision=0.1
t.penup()
t.goto(-250,150)
t.pendown()

for n in range(800*precision):
    t.setheading(math.degrees(math.atan(0.02*n-8)))
    t.fd(1)

Effectively, for precisions close to or above 1, it takes far longer than I would like, and in general, drawing fine curves in Tkinter is too slow, so I want to know if there's a way to adjust this speed.

Part of my difficulty when trying to research a solution has been that I simply don't know what the relevant terminology is‚ so I've tried using vaguely related terms including some hardware-based analogues along with various other things that are kind of analogous eg: clock speed refresh rate frame rate tick speed (Minecraft ftw?) step-through rate execution rate actions per second steps per second

But all to no avail, attempting to describe the issue in Google fails too.

Additionally, I simply don't understand what the underlying bottleneck is (or even if there is a single bottleneck) that's causing it to be so slow, which makes the issue difficult to solve.

I've noticed that if a command for the turtle takes a significant amount of time to calculate (for example by forcing it to do ridiculous amounts of calculations to work out a simple value), then it does simply take longer to execute each step, suggesting that maybe it is just a hardware limitation. However, when using the python timeit decorator to time the execution, it seems to always execute precisely some number of actions per second for any function, regardless of the complexity of the individual action, up to a point, beyond which complexity begins to slow it down. So it's as though there's some limit on the rate it can occur. Though additionally, this specific limit seems to occasionally change suggesting that the computer's state does influence it to some degree.

Also, just in case, this is the timeit setup I used:

import timeit

mysetup="""
import math
import turtle as t

def DefaultDerivative(x):
    return 2*x-x

def GeneralEquation(precision=1,XShift=0,YShift=0,Derivative=DefaultDerivative):
    t.penup()
    t.goto(XShift,YShift)
    t.pendown()

    for n in range(0,int(800*precision)):
        t.setheading((math.degrees(math.atan(Derivative(((0.01*n)-(4*precision))/precision)))))
        t.fd(1/precision)

def equation1(x):
    return (2*(x**2))+(2*x)

def equation2(x):
    return x**2

def equation3(x):
    return math.cos(x)

def equation4(x):
        return 2*x

t.speed(0)
"""

mycode="""
GeneralEquation(5,-350,300,equation4)
"""

print("time: "+str(timeit.timeit(setup=mysetup,stmt=mycode,number=10)))

Anyway, this is my first question so I hope I explained myself well enough. Thank you.

Upvotes: 3

Views: 499

Answers (1)

cdlane
cdlane

Reputation: 41905

Is this quick enough for your purpose:

import timeit

mysetup = """
import turtle
from math import atan, cos

def DefaultDerivative(x):
    return 2 * x - x

def GeneralEquation(precision=1, XShift=0, YShift=0, Derivative=DefaultDerivative):
    turtle.radians()

    turtle.tracer(False)

    turtle.penup()
    turtle.goto(XShift, YShift)
    turtle.pendown()

    for n in range(0, int(800 * precision)):
        turtle.setheading(atan(Derivative((0.01 * n - 4 * precision) / precision)))
        turtle.forward(1 / precision)

    turtle.tracer(True)

def equation1(x):
    return 2 * x ** 2 + 2 * x

def equation2(x):
    return x ** 2

def equation3(x):
    return cos(x)

def equation4(x):
    return 2 * x
"""

mycode = """
GeneralEquation(5, -350, 300, equation4)
"""

print("time: " + str(timeit.timeit(setup=mysetup, stmt=mycode, number=10)))

Basically, I've turned off turtle's attempts at animation. I also threw in a command to make turtle think in radians so you don't need to call the degrees() function over and over. If you want to see some animation, you can tweak the argument to tracer(), eg. turtle.tracer(20).

Upvotes: 1

Related Questions