English translation and some fixes

This commit is contained in:
Rnhmjoj 2014-01-14 20:11:42 +01:00
parent 2be4ad8d46
commit 01a9663a88
4 changed files with 54 additions and 448 deletions

View File

@ -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

View File

@ -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()
* 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()`
Grafico() è sottoclasse di turtle.Pen quindi è possibile usare tutti i metodi ereditati.
`Graph()` is subclass of turtle.Pen so you can use all the methods inherited.
funzioni.py:
plotter.py:
Normale:
Normal:
* 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
* 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
Definita a punti:
Defined by points:
* 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
* 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
Definita a tratti:
Piecewise:
* 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
* 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
È possibile usare tutte le funzioni e le costanti del modulo math.
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

View File

@ -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()

View File

@ -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()