turtle.setworldscoordinates() and floating point precision

Abierto
#101,113 10 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
35/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
python
Área
desktop

Línea de trabajo

Empieza ejecutando el reproductor de espiral de turtle proporcionado e inspecciona Lib/turtle.py alrededor de la línea 1105. Sigue cómo setworldcoordinates actualiza xscale y yscale, y compara el error de coma flotante de Tk con el ZeroDivisionError de RawTurtle. Se considera terminado cuando el comportamiento en el límite de precisión se gestiona sin una pantalla en blanco ni un bloqueo, con cobertura para las condiciones límite indicadas.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

topic-tkinter

I made a turtle draw a spiral while rescaling the screen according to the last position of the turtle.

Simple code to reproduce (increasing the speed variable will make it crash sooner):

"""Crash a Turtle with negative infinity canvas scale"""
import turtle

speed = 3

angle = 0
radius = 1
boundaries = {'llx': -1.0, 'lly': -1.0, 'urx': 1.0, 'ury': 1.0}
pen = turtle.Turtle()
pen.speed(10)
pen.getscreen().tracer(1e3)
while True:
    print(f"radius {radius}, angle {angle}")
    print(f"screen xscale {pen.getscreen().xscale}")
    print(f"screen yscale {pen.getscreen().yscale}")
    pen.circle(radius, angle)
    radius *= speed
    angle += 1
    pos = pen.pos()
    boundaries['llx'] = min(boundaries['llx'], pos[0])
    boundaries['lly'] = min(boundaries['lly'], pos[1])
    boundaries['urx'] = max(boundaries['urx'], pos[0])
    boundaries['ury'] = max(boundaries['ury'], pos[1])
    pen.getscreen().setworldcoordinates(**boundaries)

This will raise _tkinter.TclError: expected floating-point number but got "floating" when x or y scale gets near 1e-306.

But in the code I'm using with a RawTurtle and a TurtleScreen I get ZeroDivisionError because somewhere after 6.7e-307 (in my machine) both TurtleScreen's x and y scales becomes 0.0, RawTurtle's position becomes (-inf, -inf) and then this line of code is reached: https://github.com/python/cpython/blob/3ef9f6b508a8524f385cdc9fdd4b4afca0eac59b/Lib/turtle.py#L1105

I had to set this in my code to prevent screen becoming blank (because of scale becoming 0.0), so I could stop drawing before it crashes:

precision: int = 1e-306
while True:
    logger.debug(f"""
boundaries = {boundaries}
screen.xscale = {screen.xscale}
screen.yscale = {screen.yscale}
""")
    try:
        1 / screen.xscale
        1 / screen.yscale
    except ZeroDivisionError:
        logger.warning(f"reached infinity")
        break
    if precision != min(precision, screen.xscale, screen.yscale):
        logger.warning(f"reached floating point precision limit")
        break
    screen.setworldcoordinates(**boundaries)
## Make screen still without going blank
root.mainloop()
Lenguaje dominante
Python
Estrellas
77.2k
Forks
36k
Merge medio
1 d 9 h
PR fusionados (30 d)
558

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de python/cpython

Todos los issues de python/cpython

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.