Browse Source

La perfection existe-t-elle ?

master
BARRAUX Arthur 2 years ago
parent
commit
6dd9959ef2
  1. 142
      main.py

142
main.py

@ -1,5 +1,6 @@
from data_structure import *
import customtkinter as ctk
import math
class Expression:
"""manipule les expression sous forme d'arbre"""
@ -51,31 +52,33 @@ class App(ctk.CTk):
super().__init__()
self.grid_columnconfigure(0, weight=0)
# Calcul Frame
self.calcul_frame = ctk.CTkFrame(self,corner_radius=0, fg_color="transparent")
self.screen = ctk.CTkTextbox(self.calcul_frame)
self.screen.pack(padx=20, pady=20, fill="both", expand=True)
self.numbers = []
for i, val in enumerate(["(", ")", "/", "^", 7,8,9,"*", 4, 5, 6, "-", 1, 2, 3, "+", "clear", 0, '.', "exe"]): # add numbers button
self.numbers.append(ctk.CTkButton(self, text=val))
if val == "clear":
self.numbers[i]._command = self.textbox_clear
elif val == "exe":
self.numbers[i]._command = self.calculate
self.numbers[i]._command = self.clear_screen
else:
self.numbers[i]._command = lambda x=val: self.add_value(x)
self.numbers[i].grid(row=1+i//4, column=i%4+1, sticky="NSEW", padx=5, pady=5)
self.numbers[i].grid(row=5+i//4, column=i%4+1, sticky="NSEW", padx=5, pady=5)
# Calcul Frame
self.calcul_frame = ctk.CTkFrame(self,corner_radius=0, fg_color="transparent")
self.calcul_screen = ctk.CTkLabel(self.calcul_frame, text="hello")
self.calcul_screen.pack(fill="both", expand=True)
self.calcul_entry = ctk.CTkEntry(self.calcul_frame)
self.calcul_entry.pack(fill="both", expand=True)
# Fonction Frame
self.fonction_frame = ctk.CTkFrame(self, corner_radius=0, fg_color="transparent")
self.fonction_frame = ctk.CTkFrame(self, fg_color="transparent")
self.fonction_screen = ctk.CTkCanvas(self.fonction_frame)
self.fonction_screen.pack(padx=20, pady=20, fill="both", expand=True)
self.fonction_screen.pack(fill="both", expand=True)
self.fonction_entry = ctk.CTkEntry(self.fonction_frame)
self.fonction_entry.pack(fill="both", expand=True)
# navigation menu
@ -100,6 +103,7 @@ class App(ctk.CTk):
self.appearance_mode_menu = ctk.CTkOptionMenu(self.navigation_frame, values=["Light", "Dark", "System"],
command=self.change_appearance_mode_event)
self.appearance_mode_menu.grid(row=4, column=0, padx=20, pady=20, sticky="s")
self.mode = 'Calcul'
# select default frame
self.select_frame_by_name("Calcul")
@ -111,11 +115,20 @@ class App(ctk.CTk):
# show selected frame
if name == "Calcul":
self.calcul_frame.grid(columnspan=4, column=1, row=0, sticky="nsew")
self.mode = "Calcul"
self.calcul_frame.grid(padx=20, pady=20,columnspan=4, column=1, rowspan=5, row=0, sticky="nsew")
self.numbers[-1]._command = self.calculate
else:
self.calcul_frame.grid_forget()
if name == "Fonction":
self.fonction_frame.grid(columnspan=4, column=1, row=0, sticky="nsew")
self.mode = "Fonction"
self.fonction_frame.grid(columnspan=4, column=1, row=0, padx=20, pady=20, sticky="nsew")
self.fonction_frame.update()
self.fonction_screen_width = self.fonction_screen.winfo_width()
self.numbers[-1]._command = self.draw_graph
self.fonction_screen_height = self.fonction_screen.winfo_height()
print(self.fonction_screen_height)
else:
self.fonction_frame.grid_forget()
@ -123,20 +136,94 @@ class App(ctk.CTk):
ctk.set_appearance_mode(new_appearance_mode)
def add_value(self, value) -> None:
self.screen.insert('end', value)
if self.mode == 'Fonction':
self.fonction_entry.insert("end", value)
else:
self.calcul_entry.insert("end", value)
def clear_screen(self) -> None:
if self.mode == "Calcul":
self.calcul_screen.configure(text="")
else:
self.fonction_screen.delete('all')
def textbox_clear(self):
self.screen.delete("0.0", "end")
def draw_framing(self, min_x, max_x, min_y, max_y):
ratio = self.fonction_screen_height / self.fonction_screen_width # longueur par largeur du canvas
def draw_framing(self):
pass
# position du max dans l'interval
abscisse = max_y / (abs(min_y)+abs(max_y))
ordonnee = max_x / (abs(min_x)+abs(max_x))
for i in range(20):# dessin des lignes verticales
if i == int(20*ordonnee):
self.fonction_screen.create_line(0 + i * self.fonction_screen_width/20, 0, 0 + i * self.fonction_screen_width/20, self.fonction_screen_height, fill='red', width=4)
text = self.fonction_screen.create_text(0 + i * self.fonction_screen_width/20, 10, text=max_y)
rect = self.fonction_screen.create_rectangle(self.fonction_screen.bbox(text),fill="white")
self.fonction_screen.tag_lower(rect, text)
text = self.fonction_screen.create_text(0 + i * self.fonction_screen_width/20, self.fonction_screen_height - 10, text=min_y)
rect = self.fonction_screen.create_rectangle(self.fonction_screen.bbox(text),fill="white")
self.fonction_screen.tag_lower(rect, text)
else:
self.fonction_screen.create_line(0 + i * self.fonction_screen_width/20, 0, 0 + i * self.fonction_screen_width/20, self.fonction_screen_height, fill='red')
coo_abscisse = self.fonction_screen_height * ordonnee % 20 -6 # décalage modulo 20 par rapport à l'origine
nb_abscisse_lines = math.ceil(20*ratio)+1 # nombres de lignes horizontales à tracer
for i in range(nb_abscisse_lines): # dessin des lignes verticales
if i == int(nb_abscisse_lines * abscisse): # tracer de l'axe des abscisses
self.fonction_screen.create_line(0, 0 + i * self.fonction_screen_width/20 - coo_abscisse, self.fonction_screen_width, 0 + i * self.fonction_screen_width/20 - coo_abscisse, fill='red', width=4)
text = self.fonction_screen.create_text(15, 0 + i * self.fonction_screen_width/20 - coo_abscisse, text=min_x)
rect = self.fonction_screen.create_rectangle(self.fonction_screen.bbox(text),fill="white")
self.fonction_screen.tag_lower(rect, text)
text = self.fonction_screen.create_text(self.fonction_screen_width - 15, 0 + i * self.fonction_screen_width/20 - coo_abscisse, text=max_x)
rect = self.fonction_screen.create_rectangle(self.fonction_screen.bbox(text),fill="white")
self.fonction_screen.tag_lower(rect, text)
else:
self.fonction_screen.create_line(0, 0 + i * self.fonction_screen_width/20 - coo_abscisse, self.fonction_screen_width, 0 + i * self.fonction_screen_width/20 - coo_abscisse, fill='red')
def calculate(self) -> None:
exp = list(self.screen.get("0.0", "end").strip())
exp = list(self.calcul_entry.get())
exp = inf2npi(exp)
result = npi2tree(exp).evalue()
self.textbox_clear()
self.screen.insert("end", result)
self.calcul_screen.configure(text=result)
def draw_graph(self):
self.fonction_screen.delete('all')
self.fonction_points = npi2tree(inf2npi(parse_string_to_list(self.fonction_entry.get()))).valeurs_de_fonction()
max_y = max(self.fonction_points,key=lambda item:item[1])[1]
min_y = min(self.fonction_points,key=lambda item:item[1])[1]
self.draw_framing(-100, 100, min_y, max_y)
for x, y in self.fonction_points:
image_x = self.fonction_screen_width / 2 + x * (self.fonction_screen_width/len(self.fonction_points))
image_y = self.fonction_screen_height - (y - min_y) * self.fonction_screen_height / (abs(max_y)+abs(min_y)) - 3
self.fonction_screen.create_rectangle(image_x, image_y, image_x, image_y)
def parse_string_to_list(text: str) -> list:
text = list(text)
result = []
elem = ""
for char in text:
if char.isdigit():
elem += char
elif char == 'x':
result.append(char)
else:
if len(elem) != 0:
result.append(elem)
elem = ""
result.append(char)
if len(elem) != 0:
result.append(elem)
elem = ""
return result
def npi2tree(expr: list) -> Expression:
@ -189,10 +276,7 @@ def inf2npi(expr: list) -> list:
return output
# [3, '-', 6, '*', 4, '+', 3]
exp = inf2npi(list('x^2'))
print(npi2tree(exp).evalue(2))
print(npi2tree(exp).valeurs_de_fonction())
print(parse_string_to_list('x'))
print(inf2npi(parse_string_to_list('x')))
gui = App()
gui.mainloop()
Loading…
Cancel
Save