turtle.setworldscoordinates() and floating point precision
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 35/100
Hướng nghiên cứu
Bắt đầu bằng cách chạy trình tái hiện xoắn ốc turtle được cung cấp và kiểm tra Lib/turtle.py quanh dòng 1105. Theo dõi cách setworldcoordinates cập nhật xscale và yscale, sau đó so sánh lỗi số thực dấu phẩy động của Tk với ZeroDivisionError của RawTurtle. Được xem là hoàn thành khi hành vi tại giới hạn độ chính xác được xử lý mà không xuất hiện màn hình trống hoặc sự cố, với độ bao phủ cho các điều kiện biên đã được báo cáo.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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()
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 36k
- Merge trung bình
- 1 ngày 9 giờ
- Pull request đã merge (30 ngày)
- 558
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của python/cpython
-
docs pending
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
stdlib type-feature
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
stdlib type-feature
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
build type-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
-
stdlib topic-email type-feature
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Tất cả issue của python/cpython
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
-
🐛 Bug 🔔 Pending processing
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
jumpserver/jumpserver#17584 ·