diff --git a/funzioni.py b/funzioni.py index 11df84c..081207e 100644 --- a/funzioni.py +++ b/funzioni.py @@ -1,51 +1,189 @@ -import tkinter, tkinter.filedialog, re, canvas2svg, grafico +import tkinter, tkinter.filedialog from math import * +import re +#import canvas2svg +import grafico -class applicazione(tkinter.Frame): - +class Applicazione(tkinter.Frame): + """ + Classe dell'applicazione + Inizializzarla con un finestra creata con Tk(). + """ def __init__(self, finestra): tkinter.Frame.__init__(self, finestra) - finestra.geometry("{}x{}+{}+{}".format(645, 110, int((finestra.winfo_screenwidth() / 2) - 320), finestra.winfo_screenheight())) + + #Impostazioni della finestra + + finestra.title("Impostazioni") + finestra.resizable(0,0) + finestra.geometry("{}x{}+{}+{}".format( + 645, 110, + int((finestra.winfo_screenwidth() / 2) - 320), + finestra.winfo_screenheight() + )) + + #Variabili + self.tipo = tkinter.StringVar() self.testo = tkinter.StringVar() self.tipo.set("normale") - self.grafico = grafico.grafico(20,20) + self.grafico = grafico.Grafico(20,20) self.frame = self.grafico.frame self.widgets() self.scritta() def widgets(self): - self.label1 = tkinter.Label(finestra, textvariable=self.testo) - self.label2 = tkinter.Label(finestra, text="Intervallo:") - self.label3 = tkinter.Label(finestra, text="Colore:") + """ + Creare e disegna i widget della finestra. + """ + + #Etichette + + self.label1 = tkinter.Label( + finestra, + textvariable=self.testo + ) + self.label2 = tkinter.Label( + finestra, + text="Intervallo:" + ) + self.label3 = tkinter.Label( + finestra, + text="Colore:" + ) + + #Caselle di testo + self.casella1 = tkinter.Entry(finestra) self.casella2 = tkinter.Entry(finestra) self.casella3 = tkinter.Entry(finestra) - self.scelta1 = tkinter.Radiobutton(finestra, value="normale", text="Normale", variable=self.tipo, command=self.scritta) - self.scelta2 = tkinter.Radiobutton(finestra, value="punti", text="Definita a punti", variable=self.tipo, command=self.scritta) - self.scelta3 = tkinter.Radiobutton(finestra, value="tratti", text="Definita a tratti", variable=self.tipo, command=self.scritta) - self.pulsante1 = tkinter.Button(finestra, text="Disegna", command=self.disegna) - self.pulsante2 = tkinter.Button(finestra, text="Cancella", command=self.vuota) - self.pulsante3 = tkinter.Button(finestra, text="Pulisci Canvas", command=self.grafico.pulisci) - self.pulsante4 = tkinter.Button(finestra, text="Salva", command=self.salva) - self.pulsante5 = tkinter.Button(finestra, text="Esci", command=finestra.quit) + + #Opzioni + + self.scelta1 = tkinter.Radiobutton( + finestra, + value="normale", + text="Normale", + variable=self.tipo, + command=self.scritta + ) + self.scelta2 = tkinter.Radiobutton( + finestra, + value="punti", + text="Definita a punti", + variable=self.tipo, + command=self.scritta + ) + self.scelta3 = tkinter.Radiobutton(finestra, + value="tratti", + text="Definita a tratti", + variable=self.tipo, + command=self.scritta + ) + + #Pulsanti + + self.pulsante1 = tkinter.Button( + finestra, + text="Disegna", + command=self.disegna + ) + self.pulsante2 = tkinter.Button(finestra, + text="Cancella", + command=self.vuota + ) + self.pulsante3 = tkinter.Button( + finestra, + text="Pulisci Canvas", + command=self.grafico.pulisci + ) + self.pulsante4 = tkinter.Button(finestra, + text="Salva", + command=self.salva + ) + self.pulsante5 = tkinter.Button( + finestra, + text="Esci", + command=finestra.quit + ) - self.label1.grid(column=0, row=0, sticky="nw", pady=5, padx=5) - self.label2.grid(column=0, row=1, sticky="nw", pady=2.5, padx=5) - self.label3.grid(column=0, row=2, sticky="nw", pady=2.5, padx=5) - self.casella1.grid(column=1, row=0, sticky="nw", pady=5, padx=5) - self.casella2.grid(column=1, row=1, sticky="nw", pady=2.5, padx=5) - self.casella3.grid(column=1, row=2, padx=5, pady=2.5) - self.scelta1.grid(column= 2, row=1, sticky="nw", pady=2.5, padx=5) - self.scelta2.grid(column= 3, row=1, sticky="nw", pady=2.5, padx=5) - self.scelta3.grid(column= 4, row=1, sticky="nw", pady=2.5, padx=5) - self.pulsante1.grid(column= 2, row=0, sticky="nwes", pady=2.5, padx=5) - self.pulsante2.grid(column= 3, row=0, sticky="nwes", pady=2.5, padx=5) - self.pulsante3.grid(column=4, row=0, sticky="nwes", pady=2.5, padx=5) - self.pulsante4.grid(column=2, row=2, sticky="nwes", pady=2.5, padx=5, columnspan=2) - self.pulsante5.grid(column=4, row=2, sticky="nwes", pady=2.5, padx=5) + #Layout dei widgets + + self.label1.grid( + column=0, row=0, + sticky="nw", + pady=5, padx=5 + ) + self.label2.grid( + column=0, row=1, + sticky="nw", + pady=2.5, padx=5 + ) + self.label3.grid( + column=0, row=2, + sticky="nw", + pady=2.5, padx=5 + ) + self.casella1.grid( + column=1, row=0, + sticky="nw", + pady=5, padx=5 + ) + self.casella2.grid( + column=1, row=1, + sticky="nw", + pady=2.5, padx=5 + ) + self.casella3.grid( + column=1, row=2, + padx=5, pady=2.5 + ) + self.scelta1.grid( + column= 2, row=1, + sticky="nw", + pady=2.5, padx=5 + ) + self.scelta2.grid( + column= 3, row=1, + sticky="nw", + pady=2.5, padx=5 + ) + self.scelta3.grid( + column= 4, row=1, + sticky="nw", + pady=2.5, padx=5 + ) + self.pulsante1.grid( + column= 2, row=0, + sticky="nwes", + pady=2.5, padx=5 + ) + self.pulsante2.grid( + column= 3, row=0, + sticky="nwes", + pady=2.5, padx=5 + ) + self.pulsante3.grid( + column=4, row=0, + sticky="nwes", + pady=2.5, padx=5 + ) + self.pulsante4.grid( + column=2, row=2, + sticky="nwes", + pady=2.5, padx=5, + columnspan=2 + ) + self.pulsante5.grid( + column=4, row=2, + sticky="nwes", + pady=2.5, padx=5 + ) def scritta(self): + """ + Cambia la scritta in base al tipo di grafico. + """ if self.tipo.get() == "normale": self.testo.set("f(x): y =") elif self.tipo.get() == "tratti": @@ -54,9 +192,28 @@ class applicazione(tkinter.Frame): self.testo.set("(x1,y1),(x2,y2),...") def disegna(self): - funzione = re.sub("([\+-\-]?\d+)(x)", "\\1*x", self.casella1.get().replace("^", "**")) - funzione = re.sub("(\|)(.+)(\|)", "abs(\\2)", funzione) - funzione = re.sub("(.+)(\!)", "factorial(\\1)", funzione) + """ + Disegna il grafico della funzione o dei dati inseriti + """ + + #Converte la funzione in modo che possa essere interpretata da eval(). + funzione = re.sub( + "([\+-\-]?\d+)(x)", + "\\1*x", + self.casella1.get().replace("^", "**") + ) + funzione = re.sub( + "(\|)(.+)(\|)", + "abs(\\2)", + funzione + ) + funzione = re.sub( + "(.+)(\!)", + "factorial(\\1)", + funzione + ) + + #Legge l'intervallo inserito. try: intervallo = eval(self.casella2.get()) except SyntaxError: @@ -65,9 +222,13 @@ class applicazione(tkinter.Frame): else: inizio = float(intervallo[0]) fine = float(intervallo[1]) + + #Legge il colore inserito. colore = self.casella3.get() if colore == "": colore = "orange" + + #Disegna il grafico in base al tipo inserito. if self.tipo.get() == "normale": funzione = eval("lambda x:" + funzione) self.grafico.disegna(funzione, inizio, fine, colore) @@ -75,18 +236,34 @@ class applicazione(tkinter.Frame): funzioni = re.sub("(\[\()(.+?\))", "\\1lambda x:\\2", funzione) funzioni = re.sub("(\[)", "(", funzioni.replace("]",")")) for funzione in eval(funzioni): - self.grafico.disegna(funzione[0], funzione[1][0], funzione[1][1], colore) + self.grafico.disegna( + funzione[0], + funzione[1][0], + funzione[1][1], + colore + ) else: funzione = grafico.punti(eval(self.casella1.get())) - self.grafico.disegna(funzione, punti[0][0], punti[len(punti)-1][1], colore) + self.grafico.disegna( + funzione, + punti[0][0], + punti[len(punti)-1][1], + colore + ) def vuota(self): + """ + Rimuove tutti i dati inseriti. + """ self.casella1.delete(0, "end") self.casella2.delete(0, "end") self.casella3.delete(0, "end") self.finestra.withdraw() def salva(self): + """ + Salva il grafico in formato svg. + """ opzioni ={ "parent": self.frame, "defaultextension": ".svg", @@ -97,7 +274,5 @@ class applicazione(tkinter.Frame): canvas2svg.saveall(file, self.grafico.canvas) finestra = tkinter.Tk() -finestra.title("Impostazioni") -finestra.resizable(0,0) -app = applicazione(finestra) +app = Applicazione(finestra) app.mainloop() \ No newline at end of file diff --git a/grafico.py b/grafico.py index c860af7..a20e3d7 100644 --- a/grafico.py +++ b/grafico.py @@ -1,27 +1,42 @@ import turtle def punti(tupla): + """ + Data una tupla del tipo ((x_1, y_1), (x_2, y_2), (x_n, y_n),...) + restituisce una funzione f(x_n): y=y_n. + """ return lambda x: dict(tupla)[float(x)] -class varie(): - +class Varie(): + """ + Funzioni varie per turtle. + """ def vai(self, x, y): + """ + Sposta il cursore al punto (x, y) senza tracciare una linea. + """ self.pu() self.goto(x,y) self.pd() -class freccia(turtle.Pen, varie): - +class Freccia(turtle.Pen, Varie): + """ + Cursore di turtle personalizzato. + """ def __init__(self): - super(freccia, self).__init__() + super(Freccia, self).__init__() self.speed(0) self.shape("triangle") self.shapesize(0.5) -class grafico(turtle.Pen, varie): +class Grafico(turtle.Pen, Varie): def __init__(self, X=10, Y=10): - super(grafico, self).__init__() + """ + Inizializzazione del grafico + Fornire le dimensione degli assi se necessario. + """ + super(Grafico, self).__init__() turtle.title("Grafico") self.X = X self.Y = Y @@ -31,6 +46,9 @@ class grafico(turtle.Pen, varie): self.frecce() def assi(self): + """ + Disegna gli assi del piano cartesiano. + """ turtle.setworldcoordinates(-(self.X+2), -(self.Y+2), self.X+2, self.Y+2) self.hideturtle() self.speed(0) @@ -41,15 +59,21 @@ class grafico(turtle.Pen, varie): self.fd(self.Y*2) def frecce(self): - a = freccia() + """ + Disegna le frecce e i nomi degli assi. + """ + a = Freccia() a.vai(self.X, 0) a.write(" x", font=("helvetiva",16)) - b = freccia() + b = Freccia() b.lt(90) b.vai(0, self.Y) b.write(" y", font=("helvetiva",16)) def disegna(self, funzione, inizio, fine, colore="blue"): + """ + Disegna una funzione nel piano cartesiano. + """ medio = 2/self.X self.color(colore) try: @@ -64,5 +88,8 @@ class grafico(turtle.Pen, varie): self.vai(x, funzione(x+1*medio)) def pulisci(self): + """ + Pulisce il canvas e ridisegna gli assi. + """ self.reset() self.assi() \ No newline at end of file