101 lines
2.2 KiB
Python
101 lines
2.2 KiB
Python
import tkinter as tk
|
|
import turtle
|
|
import math
|
|
|
|
# ---------- Tk setup ----------
|
|
root = tk.Tk()
|
|
root.title("Turtle Function Inspector")
|
|
|
|
# ---------- Canvas ----------
|
|
canvas = tk.Canvas(root, width=600, height=600)
|
|
canvas.grid(row=0, column=0, rowspan=6)
|
|
|
|
screen = turtle.TurtleScreen(canvas)
|
|
screen.setworldcoordinates(-300, -300, 300, 300)
|
|
|
|
t = turtle.RawTurtle(screen)
|
|
t.speed(0)
|
|
t.hideturtle()
|
|
|
|
# ---------- Globals ----------
|
|
scale = 40 # zoom level
|
|
|
|
# ---------- Drawing ----------
|
|
def draw_axes():
|
|
t.clear()
|
|
t.color("black")
|
|
t.penup()
|
|
t.goto(-300, 0)
|
|
t.pendown()
|
|
t.goto(300, 0)
|
|
|
|
t.penup()
|
|
t.goto(0, -300)
|
|
t.pendown()
|
|
t.goto(0, 300)
|
|
|
|
def plot_function():
|
|
draw_axes()
|
|
expr = func_entry.get()
|
|
|
|
t.color("blue")
|
|
t.penup()
|
|
|
|
first = True
|
|
for px in range(-300, 300):
|
|
try:
|
|
x = px / scale
|
|
y = eval(expr, {"x": x, "math": math})
|
|
py = y * scale
|
|
|
|
if abs(py) > 300:
|
|
raise ValueError
|
|
|
|
if first:
|
|
t.goto(px, py)
|
|
t.pendown()
|
|
first = False
|
|
else:
|
|
t.goto(px, py)
|
|
except:
|
|
t.penup()
|
|
first = True
|
|
|
|
# ---------- Zoom ----------
|
|
def zoom_in():
|
|
global scale
|
|
scale *= 1.25
|
|
plot_function()
|
|
|
|
def zoom_out():
|
|
global scale
|
|
scale /= 1.25
|
|
plot_function()
|
|
|
|
# ---------- Mouse inspection ----------
|
|
info = tk.Label(root, text="x=0 y=0")
|
|
info.grid(row=5, column=1)
|
|
|
|
def inspect(event):
|
|
x = (event.x - 300) / scale
|
|
try:
|
|
y = eval(func_entry.get(), {"x": x, "math": math})
|
|
info.config(text=f"x={x:.3f} y={y:.3f}")
|
|
except:
|
|
info.config(text="undefined")
|
|
|
|
canvas.bind("<Motion>", inspect)
|
|
|
|
# ---------- Controls ----------
|
|
tk.Label(root, text="f(x) =").grid(row=0, column=1)
|
|
func_entry = tk.Entry(root, width=20)
|
|
func_entry.insert(0, "math.sin(x)")
|
|
func_entry.grid(row=1, column=1)
|
|
|
|
tk.Button(root, text="Plot", command=plot_function).grid(row=2, column=1)
|
|
tk.Button(root, text="Zoom +", command=zoom_in).grid(row=3, column=1)
|
|
tk.Button(root, text="Zoom -", command=zoom_out).grid(row=4, column=1)
|
|
|
|
plot_function()
|
|
root.mainloop()
|