diff --git a/License.txt b/License.txt deleted file mode 100644 index 5276bee..0000000 --- a/License.txt +++ /dev/null @@ -1,10 +0,0 @@ - * Funzioni - * - * Applicazione per stampare funzioni in python 3. - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - * @author Michele Guerini Rocco aka Rnhmjoj - * @since 2013 \ No newline at end of file diff --git a/README.md b/README.md index e684fe9..de542ec 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,60 @@ -Funzioni -======== +# Plotter -Applicazione per stampare funzioni in python 3. ------------------------------------------------ +## Application to plot functions in python 3. -### Informazioni -Un' applicazione per stampare nel piano cartesiano una funzione(per punti, definita a tratti o normale) tramite turtle graphics. -L'applicazione è strutturata in due moduli: "grafico.py" contiene le classi e le funzioni per il disegno vero e proprio mentre "funzioni.py" è l'interfaccia grafica(tkinter) al modulo che facilita e ne velocizza l'uso. -Grafico.py è indipendente e può essere usato anche senza l'interfaccia grafica. -È possibile salvare il piano cartesiano in formato svg tramite [canvas2svg](Link: http://wm.ite.pl/proj/canvas2svg/index.html). +### Info +An application to plot a function (points, piecewise or normal) using turtle graphics. +The application is structured in two modules: "graph.py" contains classes and functions for drawing while "plotter.py" is the GUI (tkinter) module that facilitates and speeds up the use. +graph.py is independent and can be used even without the graphical interface. +You can save the plot in svg format via [canvas2svg] (Link: http://wm.ite.pl/proj/canvas2svg/index.html). -### Istruzioni -grafico.py: +### Instructions +graph.py: - * importare il modulo grafico.py. - Es. import grafico - * Per creare un piano cartesiano istanziare un oggetto "grafico" fornendo le lunghezze degli assi. - Es. piano = grafico.grafico(20,20) - * Per disegnare una funzione usare il metodo disegna fornendo una funzione, l'intervallo nel dominio e il colore. - Es. piano.disegna(lamda x: x**2-2*x+1, -10, 10, ""#92182b") - * Per cancellare usare il metodo pulisci. - Es. piano.pulisci() - - Grafico() è sottoclasse di turtle.Pen quindi è possibile usare tutti i metodi ereditati. - -funzioni.py: +* Import the module graph.py. + `import graph` +* Create a Cartesian plane instantiate an object "graph" by providing the lengths of the axes. + `plane = graph.graph(20,20)` +* Draw a function using the method draws providing a function, the interval in the domain, and color. + `plane.plot (lambda x: x**2-2*x+1, -10, 10, "#92182b")` +* Clean the graph. + `plane.clean()` - Normale: - - * Inserire la funzione nella prima casella di testo. Tra la variabile e i coefficienti il * non è necessario. - Per elevare a potenza usare ^, per il valore assoluto usare |f(x)|. - Es. |cos(x)*1/2x| - * Inserire l'intervallo della funzione da stampare nella seconda casella. - Es. -10,10 - * Inserire il colore nella terza casella. - Una stringa con il nome del colore, una tupla che contiene i numeri RGB del colore o #colore in RGB esadecimale): - Es #a1a1a1 +`Graph()` is subclass of turtle.Pen so you can use all the methods inherited. - Definita a punti: - - * Inserire i punti della funzione in una tupla del tipo (x1,y2),(x2,y2). - Es. (0,0),(1,2),(2,4),(3,-3) - * Inserire l'intervallo della funzione da stampare nella seconda casella. - Es. -10,10 - * Inserire il colore nella terza casella. - Una stringa con il nome del colore, una tupla che contiene i numeri RGB del colore o #colore in RGB esadecimale): - Es #a1a1a1 - - Definita a tratti: - - * Inserire i tratti in una tupla del tipo [f1(x),(intervallo)],[f2(x),(intervallo)]. - Es. [(-x),(-100,0)],[(x),(0,100)] - * Inserire l'intervallo della funzione da stampare nella seconda casella. - Es. -10,10 - * Inserire il colore nella terza casella. - Una stringa con il nome del colore, una tupla che contiene i numeri RGB del colore o #colore in RGB esadecimale): - Es #a1a1a1 - - È possibile usare tutte le funzioni e le costanti del modulo math. \ No newline at end of file +plotter.py: + +Normal: + +* Enter the function in the first text box. Between the variable and the coefficients a * is not necessary. +  Use `^` for exponentiation and `|` for the absolute value |f(x)|. + eg |cos(x)*1/2x| +* Enter the range of the function to print in the second box. + eg -10, 10 +* Enter the color in the third box. A string with the name of the color, a tuple that contains RGB numbers, #RGB color in hex. + eg #a1a1a1 + +Defined by points: + +* Insert the points of the function into a tuple of the form (x1, y2), (x2, y2). + eg (0,0), (1,2), (2,4), (3,-3) +* Enter the range of the function to print the second box. + eg -10,10 +* Enter the color in the third box. A string with the name of the color, a tuple that contains RGB numbers, #RGB color in hex. + eg #a1a1a1 + +Piecewise: + +* Enter the traits in a tuple type [f1(x), (range)], [f2(x), (range)]. + eg [ (-x), (-100,0)], [(x), (0,100)] +* Enter the range of the function to print the second box. + eg -10.10 +* Enter the color in the third box. A string with the name of the color, a tuple that contains RGB numbers or #RGB color in hex. + eg #a1a1a1 + +You can use all the functions and constants defined in `math` module. + +### License +Dual licensed under the MIT and GPL licenses: +http://www.opensource.org/licenses/mit-license.php +http://www.gnu.org/licenses/gpl.html diff --git a/funzioni.py b/funzioni.py deleted file mode 100644 index e8242f5..0000000 --- a/funzioni.py +++ /dev/null @@ -1,282 +0,0 @@ -import tkinter, tkinter.filedialog -from math import * -import re -#import canvas2svg -import grafico - - -class Applicazione(tkinter.Frame): - """ - Classe dell'applicazione - Inizializzarla con un finestra creata con Tk(). - """ - def __init__(self, finestra): - tkinter.Frame.__init__(self, finestra) - - #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.frame = self.grafico.frame - self.widgets() - self.scritta() - - def widgets(self): - """ - 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) - - #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 - ) - - #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": - self.testo.set("[f1(x),(intervallo)],[f2(x),(intervallo)],...") - else: - self.testo.set("(x1,y1),(x2,y2),...") - - def disegna(self): - """ - 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: - inizio = -self.grafico.X - fine = self.grafico.X - 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) - elif self.tipo.get() == "tratti": - 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 - ) - else: - funzione = grafico.punti(eval(self.casella1.get())) - 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", - "initialfile": "grafico.svg", - "title": "Salva il grafico" - } - file = tkinter.filedialog.asksaveasfilename(**opzioni) - canvas2svg.saveall(file, self.grafico.canvas) - -finestra = tkinter.Tk() -app = Applicazione(finestra) -app.mainloop() diff --git a/grafico.py b/grafico.py deleted file mode 100644 index df5a3b0..0000000 --- a/grafico.py +++ /dev/null @@ -1,102 +0,0 @@ -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(): - """ - 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): - """ - Cursore di turtle personalizzato. - """ - def __init__(self): - super(Freccia, self).__init__() - self.speed(0) - self.shape("triangle") - self.shapesize(0.5) - - -class Grafico(turtle.Pen, Varie): - - def __init__(self, X=10, Y=10): - """ - Inizializzazione del grafico - Fornire le dimensione degli assi se necessario. - """ - super(Grafico, self).__init__() - turtle.title("Grafico") - self.X = X - self.Y = Y - self.canvas = turtle.getcanvas() - self.frame = turtle._Screen._root - self.assi() - 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) - self.vai(-self.X, 0) - self.fd(self.X * 2) - self.vai(0, -self.Y) - self.lt(90) - self.fd(self.Y * 2) - - def frecce(self): - """ - Disegna le frecce e i nomi degli assi. - """ - a = Freccia() - a.vai(self.X, 0) - a.write(" x", font=("helvetiva", 16)) - 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: - self.vai(inizio, funzione(inizio)) - except ZeroDivisionError: - self.vai(inizio, funzione(inizio + 1 * medio)) - for x in range(int(inizio / medio), int(fine / medio) + 1): - x *= medio - try: - self.goto(x, funzione(x)) - except ZeroDivisionError: - self.vai(x, funzione(x + 1 * medio)) - - def pulisci(self): - """ - Pulisce il canvas e ridisegna gli assi. - """ - self.reset() - self.assi()