Turtle Graphics are incompatible with gmpy

Gregor Lingl gregor.lingl at aon.at
Wed Aug 5 03:21:44 EDT 2009


Mensanator schrieb:
> I hadn't noticed this before, but the overhaul of Turtle Graphics
> dating
> back to 2.6 has been broken as far as gmpy is concerned.
> 
> I hadn't noticed because I usually have tracing turned off (tracing
> off
> takes 3-4 seconds, tracing on takes 6-7 minutes).
> 
> In 3.1, tracing is now a screen attribute, not a turtle atribute.
> I have no idea why
> 
>   tooter = turtle.Turtle()
>   tooter.tracer(False)
> 
> doesn't give me an error (I thought silent errors were a bad thing).
> 

Hi,

on my machine I get:

Python 3.1 (r31:73574, Jun 26 2009, 20:21:35) [MSC v.1500 32 bit 
(Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
 >>> import turtle
 >>> tooter = turtle.Turtle()
 >>> tooter.tracer(False)
Traceback (most recent call last):
   File "<pyshell#2>", line 1, in <module>
     tooter.tracer(False)
AttributeError: 'Turtle' object has no attribute 'tracer'
 >>>

I'd like to help with your problem but I'd much better be
able to analyze it, if I had a version of your script,
which works as you intended with Python 2.5 and the old
turtle module. Could you please post it?

(The one you posted below uses some commands of the
turtle 2.6 module which are not present in 2.5, so it
doesn't run with Python 2.5)

Regards,
Gregor


> Had to change to
> 
>   tooter = turtle.Turtle()
>   tooter.screen.tracer(False) # tracer now a screen attribute
> 
> to turn tracing off in 3.1.
> 
> Naturally, having tracing on caused my program to crash. The 2.6
> version
> seemed to work, but only because turning off tracing as a turtle
> attribute
> works in 2.6.
> 
> So I turned it back on and it crashed too.
> 
> 2.5 worked okay.
> 
> The reason is that code in turtle.py was chabged from
> 
> v2.5
>         if self._drawing:
>             if self._tracing:
>                 dx = float(x1 - x0)
>                 dy = float(y1 - y0)
>                 distance = hypot(dx, dy)
>                 nhops = int(distance)
> 
> to
> 
> v3.1
>        if self._speed and screen._tracing == 1:
>             diff = (end-start)
>             diffsq = (diff[0]*screen.xscale)**2 + (diff[1]
> *screen.yscale)**2
>             nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)
> *self._speed))
> 
> Unfortunately, that calculation of nhops is illegal if diffsq is
> an .mpf (gmpy
> floating point). Otherwise, you get
> 
> Traceback (most recent call last):
>   File "K:\user_python26\turtle\turtle_xy_Py3.py", line 95, in
> <module>
>     tooter.goto(the_coord)
>   File "C:\Python31\lib\turtle.py", line 1771, in goto
>     self._goto(Vec2D(*x))
>   File "C:\Python31\lib\turtle.py", line 3165, in _goto
>     nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
> ValueError: mpq.pow fractional exponent, inexact-root
> 
> So when using gmpy, you have to convert the .mpz to int before calling
> turtle
> functions. (if tracing is on).
> 
> demo code (fixed code commented out)
> 
> import gmpy
> 
> ##   (even) hi----|
> ##                |
> ##                lo (odd)
> ## or
> ##
> ##   (even) lo
> ##           |
> ##           |
> ##           ----hi (odd)
> ##
> ##
> ##
> ##
> 
> import turtle
> 
> tooter = turtle.Turtle()
> 
> tooter.hideturtle()
> tooter.speed('fast')
> turtle.update()
> # make tracer false and it works
> #tooter.screen.tracer(False) # tracer now a screen attribute
> tooter.penup()
> tooter.color('black')
> 
> s = ['1','0']
> while len(s[0])<10000:
>     s = [''.join(s), s[0]]
> 
> 
> origin = [0,0]
> if s[0] == '0':
>   tooter.goto(origin)
>   tooter.dot(1)
> if s[1] == '0':
>   tooter.goto([1,0])
>   tooter.dot(1)
> 
> print(len(s[0]))
> 
> for i,j in enumerate(s[0]):
>   the_coord=[]
>   cur_root = gmpy.sqrt(i)
>   lo__root = gmpy.sqrt(i)**2
>   hi__root = ((gmpy.sqrt(i)+1)**2)
> ##  cur_root = int(gmpy.sqrt(i))
> ##  lo__root = int(gmpy.sqrt(i)**2)
> ##  hi__root = int(((gmpy.sqrt(i)+1)**2))
> 
>   if hi__root%2==0:
>     side = 'northeast'
>   else:
>     side = 'southwest'
> 
>   elbow = (hi__root - lo__root)//2 + lo__root + 1
> 
>   if i>= elbow:
> 
>     side_len = i - elbow
>     elbow_plus = True
>   else:
>     side_len = elbow - i
>     elbow_plus = False
> 
>   if side == 'northeast':
>     elbow_offset = [(gmpy.sqrt(elbow)-1)//2 +1,-((gmpy.sqrt(elbow)-1)//
> 2) +1]
>   else:
>     elbow_offset = [-((gmpy.sqrt(elbow)-1)//2 +1),((gmpy.sqrt
> (elbow)-1)//2 +1)]
> ##  if side == 'northeast':
> ##    elbow_offset = [int((gmpy.sqrt(elbow)-1)//2 +1),-int(((gmpy.sqrt
> (elbow)-1)//2) +1)]
> ##  else:
> ##    elbow_offset = [-int(((gmpy.sqrt(elbow)-1)//2 +1)),int
> (((gmpy.sqrt(elbow)-1)//2 +1))]
> 
>   elbow_coord = [origin[0]+elbow_offset[0],origin[1]+elbow_offset[1]]
> 
>   if i != hi__root and i != lo__root:
>     if i == elbow:
>       the_coord = elbow_coord
>     else:
>       if elbow_plus:
>         if side == 'northeast':
>           the_coord = [elbow_coord[0]-side_len,elbow_coord[1]]
>         else:
>           the_coord = [elbow_coord[0]+side_len,elbow_coord[1]]
>       else:
>         if side == 'northeast':
>           the_coord = [elbow_coord[0],elbow_coord[1]+side_len]
>         else:
>           the_coord = [elbow_coord[0],elbow_coord[1]-side_len]
>   else:
>     if i % 2 == 0:  # even square
>       n = gmpy.sqrt(i)//2 - 1
> ##      n = int(gmpy.sqrt(i)//2) - 1
>       the_coord = [-n, -n-1]
>     else:
>       n = (gmpy.sqrt(i)-1)//2 - 1
> ##      n = int((gmpy.sqrt(i)-1)//2) - 1
>       the_coord = [1+n, 1+n]
>   if j == '0':
>     tooter.goto(the_coord)
>     tooter.dot(2)
> print('done')
> 
> turtle.update()
> turtle.done()
> print('done')



More information about the Python-list mailing list