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

Mensanator mensanator at aol.com
Fri Aug 7 23:01:06 CEST 2009


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.




More information about the Python-list mailing list