Turtle Graphics are incompatible with gmpy

Discussion in 'Python' started by Mensanator, Aug 5, 2009.

  1. Mensanator

    Mensanator Guest

    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).

    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')
    Mensanator, Aug 5, 2009
    #1
    1. Advertising

  2. Mensanator

    casevh Guest

    On Aug 4, 10:49 pm, Mensanator <> wrote:
    > 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.
    > 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
    >

    Warning: Completely untested fix ahead!

    What happens if you change turtle.py to use

    nhops=1+int((math.sqrt(diffsq)/(3*math.pow(1.1, self._speed)
    *self._speed))

    casevh
    casevh, Aug 5, 2009
    #2
    1. Advertising

  3. On Wed, 5 Aug 2009 03:49 pm Mensanator wrote:

    > 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).


    What makes it an error? Do you consider the following an error?

    >>> class Test:

    .... pass
    ....
    >>> t = Test()
    >>> t.tracer = 5
    >>>


    Perhaps you mean, it's an API change you didn't know about, and you wish to
    protest that Turtle Graphics made an incompatible API change without
    telling you?


    > Naturally, having tracing on caused my program to crash.


    It seg faulted or raised an exception?


    [...]
    > Unfortunately, that calculation of nhops is illegal if diffsq is
    > an .mpf (gmpy floating point). Otherwise, you get


    How does diffsq get to be a mpf? Are gmpy floats supposed to be supported?



    --
    Steven
    Steven D'Aprano, Aug 5, 2009
    #3
  4. Mensanator

    Gregor Lingl Guest

    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')
    Gregor Lingl, Aug 5, 2009
    #4
  5. Mensanator

    Gregor Lingl Guest

    Steven D'Aprano schrieb:
    > On Wed, 5 Aug 2009 03:49 pm Mensanator wrote:
    >
    >> 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).

    >
    > What makes it an error? Do you consider the following an error?
    >
    >>>> class Test:

    > ... pass
    > ...
    >>>> t = Test()
    >>>> t.tracer = 5
    >>>>

    >
    > Perhaps you mean, it's an API change you didn't know about, and you wish to
    > protest that Turtle Graphics made an incompatible API change without
    > telling you?
    >


    It didn't form 2.5 to 2.6 (at least not intentionally). But with the
    indroduction of the TurtleScreen class and the Screen class/object
    (singleton) a few of the turtle methods were also implemented as screen
    methods and as turtle methods declared deprecated (see docs of Python
    2.6). These deprecated turtle methods do not occur as turtle methods any
    more in Python 3.x.

    Among them is the tracer method, which in fact does not control single
    turtle objects but all the turtles on a given screen.

    So there is an icompatibility beween 2.6 and 3.x

    But as far as I have understood, this doesn't concern the problem
    reported by mensator.

    Regards,
    Gregor


    >
    >> Naturally, having tracing on caused my program to crash.

    >
    > It seg faulted or raised an exception?
    >
    >
    > [...]
    >> Unfortunately, that calculation of nhops is illegal if diffsq is
    >> an .mpf (gmpy floating point). Otherwise, you get

    >
    > How does diffsq get to be a mpf? Are gmpy floats supposed to be supported?
    >
    >
    >
    Gregor Lingl, Aug 5, 2009
    #5
  6. Mensanator

    casevh Guest

    On Aug 5, 12:19 am, Steven D'Aprano <st...@REMOVE-THIS-
    cybersource.com.au> wrote:
    > On Wed, 5 Aug 2009 03:49 pm Mensanator wrote:
    >
    > > 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).

    >
    > What makes it an error? Do you consider the following an error?
    >
    > >>> class Test:

    >
    > ...     pass
    > ...
    >
    > >>> t = Test()
    > >>> t.tracer = 5

    >
    > Perhaps you mean, it's an API change you didn't know about, and you wish to
    > protest that Turtle Graphics made an incompatible API change without
    > telling you?
    >
    > > Naturally, having tracing on caused my program to crash.

    >
    > It seg faulted or raised an exception?
    >
    > [...]
    >
    > > Unfortunately, that calculation of nhops is illegal if diffsq is
    > > an .mpf (gmpy floating point). Otherwise, you get

    >
    > How does diffsq get to be a mpf? Are gmpy floats supposed to be supported?
    >
    > --
    > Steven


    The root cause of the error is that GMP, the underlying library for
    gmpy, provides only the basic floating point operations. gmpy
    implements a very limited exponentiation function. Python's math
    library will convert an mpf to a float automatically so I think the
    revised calculation for nhops should work with either any numerical
    type that supports __float__.

    casevh
    casevh, Aug 5, 2009
    #6
  7. Mensanator

    Mensanator Guest

    > It didn't form 2.5 to 2.6 (at least not intentionally). But with the
    > indroduction of the TurtleScreen class and the Screen class/object
    > (singleton) a few of the turtle methods were also implemented as screen
    > methods and as turtle methods declared deprecated (see docs of Python
    > 2.6). These deprecated turtle methods do not occur as turtle methods any
    > more in Python 3.x.


    More info.

    Yes, there is no tracer attribute...when the object is created.

    But watch this (Python 3.1):

    >>> import turtle
    >>> tooter = turtle.Turtle()
    >>> tooter.tracer

    Traceback (most recent call last):
    File "<pyshell#2>", line 1, in <module>
    tooter.tracer
    AttributeError: 'Turtle' object has no attribute 'tracer'
    >>> tooter.hideturtle()
    >>> tooter.speed('fast')
    >>> turtle.update()
    >>> turtle.tracer

    <function tracer at 0x013E0ED0>

    Now, after setting hide, speed, update, a tracer exists.
    Is that supposed to happen? That explains why there was no error
    when I set the turtle attribute instead of the screen attribute.
    And, of course, setting the turtle attribute accomplishes nothing,
    as actual tracing is controlled by the screen attribute as you say.

    >
    > Among them is the tracer method, which in fact does not control single
    > turtle objects but all the turtles on a given screen.
    >
    > So there is an icompatibility beween 2.6 and 3.x
    >
    > But as far as I have understood, this doesn't concern the problem
    > reported by mensator.


    Only that the problem is hidden when tracing is off, as the nhops
    variable is never evaluated when trace is off.

    >
    > Regards,
    > Gregor
    Mensanator, Aug 5, 2009
    #7
  8. Mensanator

    Gregor Lingl Guest

    Mensanator schrieb:
    >> It didn't form 2.5 to 2.6 (at least not intentionally). But with the
    >> indroduction of the TurtleScreen class and the Screen class/object
    >> (singleton) a few of the turtle methods were also implemented as screen
    >> methods and as turtle methods declared deprecated (see docs of Python
    >> 2.6). These deprecated turtle methods do not occur as turtle methods any
    >> more in Python 3.x.

    >
    > More info.
    >
    > Yes, there is no tracer attribute...when the object is created.
    >
    > But watch this (Python 3.1):
    >
    >>>> import turtle
    >>>> tooter = turtle.Turtle()
    >>>> tooter.tracer

    > Traceback (most recent call last):
    > File "<pyshell#2>", line 1, in <module>
    > tooter.tracer
    > AttributeError: 'Turtle' object has no attribute 'tracer'
    >>>> tooter.hideturtle()
    >>>> tooter.speed('fast')
    >>>> turtle.update()
    >>>> turtle.tracer

    > <function tracer at 0x013E0ED0>
    >
    > Now, after setting hide, speed, update, a tracer exists.


    No,

    >>> import turtle
    >>> turtle.tracer

    <function tracer at 0x013CFE40>
    >>> help(turtle.tracer)

    Help on function tracer in module turtle:

    tracer(n=None, delay=None)
    Turns turtle animation on/off and set delay for update drawings.

    Optional arguments:
    n -- nonnegative integer
    delay -- nonnegative integer

    If n is given, only each n-th regular screen update is really
    performed.
    (Can be used to accelerate the drawing of complex graphics.)
    Second arguments sets delay value.)

    Example:
    >>> tracer(8, 25)
    >>> dist = 2
    >>> for i in range(200):

    fd(dist)
    rt(90)
    dist += 2

    >>>


    The reason for this is, that the turtle module (the new one as well as
    the old one) has a vers special design: The methods of class Turtle are
    also available as functions (which are in fact methods calls of an
    anonymous turtle). The same holds for the methods of TurtleScreen.

    The intention behind this design is that you can use the module in an
    OOP way as well as with procedural programming (especially for beginners).

    When using objects I normally use

    from turtle import Turtle, Screen
    screen = Screen()
    # that creates singleton object, the screen the turtle acts on
    and I create as many turtles as I need from the Turtle class

    So turtle.tracer() doesn't make sense anymore


    > Is that supposed to happen? That explains why there was no error
    > when I set the turtle attribute instead of the screen attribute.


    You do not 'set the turtle attribute', you call the tracer function of
    the turtle module

    > And, of course, setting the turtle attribute accomplishes nothing,
    > as actual tracing is controlled by the screen attribute as you say.
    >
    >> Among them is the tracer method, which in fact does not control single
    >> turtle objects but all the turtles on a given screen.
    >>
    >> So there is an icompatibility beween 2.6 and 3.x
    >>
    >> But as far as I have understood, this doesn't concern the problem
    >> reported by mensator.

    >
    > Only that the problem is hidden when tracing is off, as the nhops
    > variable is never evaluated when trace is off.


    Nevertheless I'd like to see a working Python 2.5 version of your script.

    Regards,
    Gregor
    Gregor Lingl, Aug 5, 2009
    #8
  9. Mensanator

    Mensanator Guest

    On Aug 5, 2:19 am, Steven D'Aprano <st...@REMOVE-THIS-
    cybersource.com.au> wrote:
    > On Wed, 5 Aug 2009 03:49 pm Mensanator wrote:
    >
    > > 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).

    >
    > What makes it an error? Do you consider the following an error?
    >
    > >>> class Test:

    >
    > ...     pass
    > ...
    >
    > >>> t = Test()
    > >>> t.tracer = 5


    Come on, even _I_ know this:

    >>> class Test:

    pass
    >>> t = Test()
    >>> t.tracer

    Traceback (most recent call last):
    File "<pyshell#17>", line 1, in <module>
    t.tracer
    AttributeError: 'Test' object has no attribute 'tracer'
    >>> t.tracer = False
    >>> t.tracer

    False


    >
    > Perhaps you mean, it's an API change you didn't know about, and you wish to
    > protest that Turtle Graphics made an incompatible API change without
    > telling you?


    What does this mean?

    >>> import turtle
    >>> tooter = turtle.Turtle()
    >>> tooter.tracer

    Traceback (most recent call last):
    File "<pyshell#2>", line 1, in <module>
    tooter.tracer
    AttributeError: 'Turtle' object has no attribute 'tracer'
    >>> tooter.hideturtle()
    >>> tooter.speed('fast')
    >>> turtle.update()
    >>> turtle.tracer

    <function tracer at 0x013E0ED0>

    How did the tracer attribute appear out of thin air?
    And more importantly, why, if has been deprecated and
    dropped from 3.x?

    >
    > > Naturally, having tracing on caused my program to crash.

    >
    > It seg faulted or raised an exception?


    Why did you snip it? Should I not refer to this as a crash?

    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

    >
    > [...]
    >
    > > Unfortunately, that calculation of nhops is illegal if diffsq is
    > > an .mpf (gmpy floating point). Otherwise, you get

    >
    > How does diffsq get to be a mpf?


    No idea. I neglected to mention I'm using the new gmpy 1.10.
    Don't know if that has any bearing.

    > Are gmpy floats supposed to be supported?


    Apparently not, as gmpy has only limited exponential capability.
    Looks like I need to change turtle.py to use math.sqrt(diffsq)
    or float(diffsq)**0.5. Or not pass turtle.py any .mpz since it
    can't handle them.

    >
    > --
    > Steven
    Mensanator, Aug 5, 2009
    #9
  10. On 5 Aug., 21:31, Mensanator <> wrote:
    >
    > >>> import turtle
    > >>> tooter = turtle.Turtle()
    > >>> tooter.tracer

    >
    > Traceback (most recent call last):
    >   File "<pyshell#2>", line 1, in <module>
    >     tooter.tracer
    > AttributeError: 'Turtle' object has no attribute 'tracer'>>> tooter.hideturtle()
    > >>> tooter.speed('fast')
    > >>> turtle.update()
    > >>> turtle.tracer

    >
    > <function tracer at 0x013E0ED0>
    >
    > How did the tracer attribute appear out of thin air?


    You seem to confuse the "tooter" Turtle object and the "turtle" module
    when talking about "the tracer attribute".
    Wolfram Hinderer, Aug 5, 2009
    #10
  11. Mensanator

    Ethan Furman Guest

    Mensanator wrote:

    <snippers galore>

    >
    > What does this mean?
    >
    >
    >>>>import turtle
    >>>>tooter = turtle.Turtle()
    >>>>*tooter*.tracer

    >
    > Traceback (most recent call last):
    > File "<pyshell#2>", line 1, in <module>
    > tooter.tracer
    > AttributeError: 'Turtle' object has no attribute 'tracer'
    >
    >>>>tooter.hideturtle()
    >>>>tooter.speed('fast')
    >>>>turtle.update()
    >>>>*turtle*.tracer

    >
    > <function tracer at 0x013E0ED0>
    >
    > How did the tracer attribute appear out of thin air?


    Perhaps I am missing something (wouldn't surprise me!) but it seems that
    the first time you are looking for a tracer on 'tooter', and the second
    time you are looking for a tracer on 'turtle'. After *turtle.tracer*
    succeeds, does *tooter.tracer*?

    ~Ethan~
    Ethan Furman, Aug 5, 2009
    #11
  12. Mensanator

    Mensanator Guest

    On Aug 5, 3:08 pm, Ethan Furman <> wrote:
    > Mensanator wrote:
    >
    > <snippers galore>
    >
    >
    >
    >
    >
    >
    >
    > > What does this mean?

    >
    > >>>>import turtle
    > >>>>tooter = turtle.Turtle()
    > >>>>*tooter*.tracer

    >
    > > Traceback (most recent call last):
    > >   File "<pyshell#2>", line 1, in <module>
    > >     tooter.tracer
    > > AttributeError: 'Turtle' object has no attribute 'tracer'

    >
    > >>>>tooter.hideturtle()
    > >>>>tooter.speed('fast')
    > >>>>turtle.update()
    > >>>>*turtle*.tracer

    >
    > > <function tracer at 0x013E0ED0>

    >
    > > How did the tracer attribute appear out of thin air?

    >
    > Perhaps I am missing something (wouldn't surprise me!) but it seems that
    > the first time you are looking for a tracer on 'tooter', and the second
    > time you are looking for a tracer on 'turtle'.  


    Duh. I could have looked at that from now til the sun don't shine and
    not seen it. And I even retyped it, no cut/paste.

    > After *turtle.tracer*
    > succeeds, does *tooter.tracer*?


    No, that was my mistake. Too late now as the record is gone, but I
    could have sworn I had the math exception first. That's what made
    me go realize the tracing wasn't off which led me to add .screen.

    Sounds like I should have gotten the attribute error first.

    Maybe I did and am mis-remembering it. Usually, I don't start keeping
    notes at first because I'm not expecting failure.

    >
    > ~Ethan~
    Mensanator, Aug 5, 2009
    #12
  13. Mensanator

    Mensanator Guest

    On Aug 5, 12:56 pm, Gregor Lingl <> wrote:
    > Mensanator schrieb:
    >
    >
    >
    >
    >
    > >> It didn't form 2.5 to 2.6 (at least not intentionally). But with the
    > >> indroduction of the TurtleScreen class and the Screen class/object
    > >> (singleton) a few of the turtle methods were also implemented as screen
    > >> methods and as turtle methods declared deprecated (see docs of Python
    > >> 2.6). These deprecated turtle methods do not occur as turtle methods any
    > >> more in Python 3.x.

    >
    > > More info.

    >
    > > Yes, there is no tracer attribute...when the object is created.

    >
    > > But watch this (Python 3.1):

    >
    > >>>> import turtle
    > >>>> tooter = turtle.Turtle()
    > >>>> tooter.tracer

    > > Traceback (most recent call last):
    > >   File "<pyshell#2>", line 1, in <module>
    > >     tooter.tracer
    > > AttributeError: 'Turtle' object has no attribute 'tracer'
    > >>>> tooter.hideturtle()
    > >>>> tooter.speed('fast')
    > >>>> turtle.update()
    > >>>> turtle.tracer

    > > <function tracer at 0x013E0ED0>

    >
    > > Now, after setting hide, speed, update, a tracer exists.

    >
    > No,


    Yeah, I mistyped my example, sorry about that. I thought sure
    it was the math error that lead me to the tracer issue, but that
    might have been a mistake.

    >
    > Nevertheless I'd like to see a working Python 2.5 version of your script.


    I've commented out the parts that v2.5 doesn't have.
    So the pen is still down and I have no .dot function,
    but the gotos appear to still work as evidenced by
    the large black square it now draws.

    With tracing on in 2.5, I see the turtle move around
    the square. With tracing off, I still the the square
    outined, but without a turtle and much faster.

    With 3.1, the screen is completely blank for 3-4 seconds and appears
    all at once when it's done.

    import gmpy

    ## (even) hi----|
    ## |
    ## lo (odd)
    ## or
    ##
    ## (even) lo
    ## |
    ## |
    ## ----hi (odd)
    ##
    ##
    ##
    ##

    import turtle

    tooter = turtle.Turtle()

    #tooter.hideturtle()
    tooter.speed('fast')
    #turtle.update()
    tooter.tracer(False)
    #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

    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)]

    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
    the_coord = [-n, -n-1]
    else:
    n = (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'


    >
    > Regards,
    > Gregor
    Mensanator, Aug 5, 2009
    #13
  14. Mensanator

    Mensanator Guest

    I fixed this to produce the actual image I'm looking
    for instead of that stupid black square. All I did was
    use up() & dowm() in place of penup(), pendown() and
    replace dot(2) with forward(1).

    I'll be posting a followup report later.


    import gmpy

    ## (even) hi----|
    ## |
    ## lo (odd)
    ## or
    ##
    ## (even) lo
    ## |
    ## |
    ## ----hi (odd)
    ##
    ##
    ##
    ##

    import turtle

    tooter = turtle.Turtle()

    #tooter.hideturtle()
    tooter.speed('fast')
    #turtle.update()
    tooter.tracer(False)
    #tooter.penup()
    tooter.up()
    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)
    tooter.down()
    tooter.forward(1)
    tooter.up()
    if s[1] == '0':
    tooter.goto([1,0])
    #tooter.dot(1)
    tooter.down()
    tooter.forward(1)
    tooter.up()

    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

    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)]

    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
    the_coord = [-n, -n-1]
    else:
    n = (gmpy.sqrt(i)-1)/2 - 1
    the_coord = [1+n, 1+n]
    if j == '0':
    tooter.goto(the_coord)
    #tooter.dot(2)
    tooter.down()
    tooter.forward(1)
    tooter.up()
    print 'done'

    #turtle.update()
    turtle.done()
    print 'done'
    Mensanator, Aug 5, 2009
    #14
  15. Mensanator

    Mensanator Guest

    On Aug 5, 5:31 pm, Mensanator <> wrote:
    > I fixed this to produce the actual image I'm looking
    > for instead of that stupid black square. All I did was
    > use up() & dowm() in place of penup(), pendown() and
    > replace dot(2) with forward(1).
    >
    > I'll be posting a followup report later.
    >


    http://www.mensanator.com/mensanator/PythonTurtle/turtle.htm
    Mensanator, Aug 6, 2009
    #15
  16. Mensanator

    Gregor Lingl Guest

    Mensanator schrieb:
    > On Aug 5, 5:31 pm, Mensanator <> wrote:
    >> I fixed this to produce the actual image I'm looking
    >> for instead of that stupid black square. All I did was
    >> use up() & dowm() in place of penup(), pendown() and
    >> replace dot(2) with forward(1).
    >>
    >> I'll be posting a followup report later.
    >>

    >
    > http://www.mensanator.com/mensanator/PythonTurtle/turtle.htm


    Hi Mansanator,

    Thanks for that thorough investigations.
    I hope I'll soon find time to study it in detail.

    I've just one idea, but I don't know if you might
    be intersted in it or if it's rewarding at all:

    What would be the results when using the old turtle
    module with Python 3.1 (it will certainly not run
    out of the box, but perhaps 2to3 might do it?)

    That would clarify the question if there is some
    impact of new division or some changes in Tkinter.

    Best regards,
    Gregor
    Gregor Lingl, Aug 6, 2009
    #16
  17. Mensanator

    Mensanator Guest

    On Aug 5, 7:49 pm, Gregor Lingl <> wrote:
    > Mensanator schrieb:
    >
    > > On Aug 5, 5:31 pm, Mensanator <> wrote:
    > >> I fixed this to produce the actual image I'm looking
    > >> for instead of that stupid black square. All I did was
    > >> use up() & dowm() in place of penup(), pendown() and
    > >> replace dot(2) with forward(1).

    >
    > >> I'll be posting a followup report later.

    >
    > >http://www.mensanator.com/mensanator/PythonTurtle/turtle.htm

    >
    > Hi Mansanator,
    >
    > Thanks for that thorough investigations.
    > I hope I'll soon find time to study it in detail.
    >
    > I've just one idea, but I don't know if you might
    > be intersted in it or if it's rewarding at all:


    Sure, not tonight, of course, but I can give it try.

    >
    > What would be the results when using the old turtle
    > module with Python 3.1 (it will certainly not run
    > out of the box, but perhaps 2to3 might do it?)


    I would just need to copy turtle.py to 3.1 Lib (renamed,
    of course)?

    >
    > That would clarify the question if there is some
    > impact of new division or some changes in Tkinter.


    I had a quick glance through the code. Not too many divisions
    and most of them seemd to already be forcing float division
    by constructs such as mutiplying by 1.0 (which I assume isn't
    strictly neccessary as long as / and // are used correctly.

    It seemed a lot of floats were used in the 2.5 code as I saw
    such stuff as int(difference), so I really don't know why
    ..mpz would be a problem since they are integers also and a
    Python int ought to be the same thing when coerced to a float
    (at least in the range used by Turtle graphics.

    >
    > Best regards,
    > Gregor
    Mensanator, Aug 6, 2009
    #17
  18. Mensanator

    Mensanator Guest

    Good news & bad news (was: Turtle Graphics are incompatible withgmpy)

    Bad news:

    I ran the 2.5 turtle.py through the 2to3 refactorer but the
    result would not run in 3.1, some kind of type mismatch between
    ints and NoneType. So I set it aside.

    Good news:

    I tracked down the actual cause of the image discrepencies in my
    report.

    http://www.mensanator.com/mensanator/PythonTurtle/turtle.htm

    These are completely bogus as it turns out. I had thought I was
    essentially executing the same code (aside from changing 3.1
    turtle functions that don't exist in 2.5 to their equivalent).

    But in my mucking about tracking down the gmpy problem, a bug
    crept in when I converted back from Python ints

    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))]

    to gmpy ints.

    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)]

    A ")" is mislocated in -((gmpy.sqrt(elbow)-1)//2) +1], the one
    after "//2" should have been placed after the "+1". There were
    still three matching sets, but the +1 was now happening after
    the negation instead or prior to it. And, of course, this lead
    to discrepencies in the calls to the turtle goto function.
    And, luckily, the code chain for 2.5 originated from the version
    prior to the introduction of this error, otherwise, if the same
    error was in both, the images would have been identicle albeit
    wrong.

    So it looks like there is NO practical difference between the
    2.5 algorithm and the 3.1 algorithm. I'm no longer going to try
    to get the 2.5 turtle.py to work in 3.1.

    And with the nhops calculation changed to

    nhops = 1+int((float(diffsq)**0.5)/(3*(1.1**self._speed)
    *self._speed))

    it no longer crashes in trace mode.

    This was probably originally provoked by gmpy 1.10 and probably
    isn't a problem in 2.6 with gmpy 1.04. I had upgraded my 2.6 gmpy
    to 1.10 where it also crashed. I may have run the test code in
    2.6 when I had 1.04 installed but it's unlikely I would have done
    so with tracing on since it's 100 times slower. But I expect it
    would not have failed due to this:

    <quote>
    Changes in gmpy 1.10

    Number conversion rules have changed.
    -------------------------------------
    The arguments in operations involving mixed types are converted
    using the following rules:

    Integer --> Rational --> Floating-point
    'int' 'Fraction' 'float'
    'long' 'mpq' 'Decimal'
    'mpz' 'mpf'

    Old behavior:
    mpz(1) + float(1.2) --> float(2.2)
    mpz(1) + Decimal('1.2') --> mpz(2)

    New behavior:
    mpz(1) + float(1.2) --> mpf(2.2)
    mpz(1) + Decimal('1.2') --> mpf(2.2)
    </quote>

    Apparently, as I painfully found out, that rule change can cause
    applications to fail due to an mpf result from a mixed type function
    instead of a float when they subsequently use fractional
    exponentiation.
    Mensanator, Aug 7, 2009
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Brent W. Hughes

    Python and Turtle Graphics

    Brent W. Hughes, Jul 19, 2004, in forum: Python
    Replies:
    4
    Views:
    1,508
    Lee Harr
    Jul 20, 2004
  2. Dick Moores

    Saving output of Turtle Graphics?

    Dick Moores, Apr 7, 2007, in forum: Python
    Replies:
    7
    Views:
    421
    Dick Moores
    Apr 7, 2007
  3. tomy
    Replies:
    5
    Views:
    313
  4. Replies:
    3
    Views:
    3,093
    Alf P. Steinbach
    Feb 28, 2010
  5. Adam Funk
    Replies:
    7
    Views:
    201
    Adam Funk
    Feb 6, 2013
Loading...

Share This Page