Initial commit

This commit is contained in:
Klemek
2018-08-26 02:05:48 +01:00
parent ff637d164e
commit af853ab0f2
13 changed files with 2311 additions and 1 deletions
+23
View File
@@ -1,2 +1,25 @@
# Python Stuff
Where I store small Python projects
* [EZ Net](#ez-net)
* [Graph (french)](#graph-french-)
* [PI Dichotomy](#pi-dichotomy)
## EZ Net
You know what a pain it is to divide a network into subnetworks ? Not anymore with EZ Net ! (lol), just have fun
![preview](ez-net/preview.jpg)
## Graph (french)
A tool to make beautiful mathematical curves
![preview](graph/preview.jpg)
## PI Dichotomy
What happens when you execute dichotomy on PI starting with 4 ? Result : an infinite binary data, i used it to generate bitmaps and sound.
Obviously I didn't had infinite PI digits but "only" the 1st million.
Just run the script `pi-dich.py`, it will tell you what you can do such as :
![black and white bitmap](pi-dichotomy/pi_bw_1000.bmp)
+1042
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

+954
View File
@@ -0,0 +1,954 @@
import tkinter
from math import *
from functools import partial
ver="1.1.0"
#Déclaration des variables
#Tailles du menu (minimal pour la hauteur)
WMENU = 200
HMENU = 450
#Couleur des champs de saisie en erreur
WRONG="tomato"
#Les différentes polices d'écritures utilisées dans le programme
t3font = ('Times Roman', 18,'bold')
t2font = ('Times Roman', 14,'bold')
t1font = ('Times Roman', 12,'underline')
pbfont = ('Times Roman',11,'bold')
pfont = ('Times Roman',10)
bfont = ('Times Roman',10)
mfont = ('Times Roman',10,'bold')
b2font = ('Times Roman',12,'bold')
curves=[] #Liste de stockage des courbes
LENCURVES=10 #Nombre de variables d'une courbe
ACTIVE=0 #Clé d'accès à une variable
TYPE=1
EQ=2
XEQ=3
YEQ=4
PARMIN=5
PARMAX=6
PARSTEP=7
CCOLOR=8
SIZE=9
#TYPES
PARAM=0
POLAR=1
YFX=2
XFY=3
ntypes=["Arc parametré","Courbe polaire","y=f(x)","x=f(y)"]
types={ntypes[PARAM]:PARAM,ntypes[POLAR]:POLAR,ntypes[YFX]:YFX,ntypes[XFY]:XFY}
#Idem pour le stockage des variables pour le graphique
graph=[]
LENGRAPH=14
XMIN=0
XMAX=1
YMIN=2
YMAX=3
AXIS1=4
AXIS2=5
AXIS3=6
AXIST1=7
AXIST2=8
AXISA=9
GRID1=10
GRID2=11
GRID3=12
GCOLOR=13
#Idem pour le stockage des variables des options
opts=[]
LENOPTS=4
TX=0
TY=1
ZOOM=2
RND=3
scr=0 #Courbe sélectionnée dans le menu
page=1 #Page du menu
zoombe=False
def start():
'''Lancement du programme'''
global win #Définition de la fenetre en variable globale
win=tkinter.Tk() #Création de la fenetre / démarrage de tkinter
#Création des variables tkinter (courbes, graph, options)
tkvars([],[-5,5,-5,5,1,1,0,1,1,1,1,1,1,"white"],[500,500,0,3])
#tkvars([],[-4.5,4.5,-6,3,0,0,0,0,0,0,0,0,0,"white"],[500,500,0,3])
#Ajout d'une nouvelle courbe suivant certains paramètres
#newCurve(1,ntypes[POLAR],"cos(t)/(1-sin(t))","","",0,2*pi,0.1,"red",1)
#newCurve(1,ntypes[PARAM],"","t**5-(10/3)*t**3","(-t**4+(11/5)*t**2)*3/2",-1.825,1.825,0.01,"red",2)
#newCurve(1,ntypes[POLAR],"sin(2*t)","","",0,"2*pi",0.1,"red",1)
#Création des éléments de la fenetre
paintwin()
def paintwin():
global win,cv #le canvas doit être global pour l'accès d'autres fonctions
#Création de la fenetre
width=opts[TX].get()+WMENU #Largeur en fonction du canvas + menu
#Hauteur en fonction du canvas mais minimum du menu
if(opts[TY].get()<HMENU):
height=HMENU
else:
height=opts[TY].get()
win.title("Graph (version "+ver+")") #Titre de la fenetre
win.resizable(width=False,height=False) #Fenetre non redimensionnable
#Application des tailles de la fenetre
win.geometry(""+str(width)+"x"+str(height))
#Création du canvas
#Création des evenements
win.bind("<Return>",enter) #La touche entrée appelle la fonction enter
win.bind("<MouseWheel>",zoom)
#Cration du menu avec rafraichissement du canvas
menu(1,True,False)
#Fin de la création de la fenetre
win.mainloop()
def menu(pagea,repaint,same,*args):
global menuf
#Si on demande de rafraichir le canvas, on appelle paint
if(repaint):
paint()
#On essaye de détruire l'ancien menu, menuf
try:
menuf.destroy()
except NameError: #Si menuf n'existe pas, on ne fais rien
pass
except tkinter.TclError:
pass
#On crée un nouveau conteneur d'élements, menuf
menuf=tkinter.Frame(win)
#Si on demande juste de rafraichir le menu, on prend page comme réference
if(same):
if(page==1):
page1(menuf) #Ajouts des élements de la page 1 sur menuf
if(page==2):
page2(menuf)
if(page==3):
page3(menuf)
else: #Sinon on prend le paramètre pagea pour changer de page
if(pagea==1):
page1(menuf)
if(pagea==2):
page2(menuf)
if(pagea==3):
page3(menuf)
#On positionne le menu à droite du canvas
#side LEFT signifie le sens d'ajout des élements
#fill Y signifie que l'élement doit remplir toute la hauteur disponible
menuf.grid(column=1,row=0,sticky=tkinter.N)
def menuBar(frame,n):
#Barre de navigation du menu
men=tkinter.Frame(frame) #Nouveau conteneur ajouté à celui en paramètre
#Les différents boutons
#partial permet de rajouter des paramètres à une fonction de commande
b1=tkinter.Button(men,text="Courbes",font=mfont,command=partial(menu,1,False,False),width=7)
b2=tkinter.Button(men,text="Graph",font=mfont,command=partial(menu,2,False,False),width=7)
b3=tkinter.Button(men,text="Options",font=mfont,command=partial(menu,3,False,False),width=7)
#Modification du bouton de la page actuelle
if(n==1):
b1.config(state=tkinter.DISABLED,bg="yellow")
if(n==2):
b2.config(state=tkinter.DISABLED,bg="yellow")
if(n==3):
b3.config(state=tkinter.DISABLED,bg="yellow")
#Position des boutons sur une grille
b1.grid(column=0,row=0)
b2.grid(column=1,row=0)
b3.grid(column=2,row=0)
men.pack(fill=tkinter.X)
def page1(frame):
global page
page=1
f=tkinter.Frame(frame) #Nouveau conteneur ajouté à celui en paramètre
menuBar(f,1) #On ajoute les boutons sur f
f1=tkinter.Frame(f) #Conteneur des boutons de navigation des ourbes
#celui de droite appelle la fonction move(-1)
#et affiche le nombre de courbes avant
b1=tkinter.Button(f1,text=("<= ("+str(scr)+")"),font=bfont,command=partial(move,-1),width=11)
if(scr==0): #Si il n'y as pas de courbes avant, il est désctivé
b1.config(state=tkinter.DISABLED)
b1.grid(column=0,row=0) #on l'ajoute sur une grille
del b1 #On libère la mémoire
#le bouton de gauche affiche le nombre de courbes apres
b2=tkinter.Button(f1,text=("("+str(len(curves)-scr-1)+") =>"),font=bfont,command=partial(move,1),width=11)
#S'il ni y en a pas, on change son nom et sa commande
if(scr==len(curves)-1 or len(curves)==0):
b2.config(text="Nouvelle courbe",command=badd)
b2.grid(column=1,row=0)
del b2
f1.pack(fill=tkinter.X) #on pack l'ensemble des boutons
#Si scr se trouve dans la liste des courbes
#Il se peut que non si il n'y a pas de courbes
if(len(curves)>scr):
#A chaque element de saisie se trouve une variable de la liste du début
#la modification s'effectue en instantanée mais pas le rafraichissement
#du graph ici géré par entrée
#Cela permet aussi de choisir quand on a finis l'edition
#pour eviter les erreurs constamment
f1=tkinter.LabelFrame(f,text=("Courbe "+str(scr+1)),padx=5,pady=5)
f2=tkinter.Frame(f1)
tkinter.Label(f2,text="Type :",font=pfont).grid(column=0,row=0)
tkinter.OptionMenu(f2,curves[scr][TYPE],*ntypes,command=ctype).grid(column=1,row=0)
f2.pack(fill=tkinter.X)
if(types[curves[scr][TYPE].get()]==PARAM):
f2=tkinter.LabelFrame(f1,text="Equations paramétriques",padx=5,pady=5)
tkinter.Label(f2,text="x(t)=",font=pfont).grid(column=0,row=0)
e=tkinter.Entry(f2,textvariable=curves[scr][XEQ],width=19)
try:
ft(curves[scr][XEQ].get(),0.01)
except(ZeroDivisionError):
pass
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=0)
tkinter.Label(f2,text="y(t)=",font=pfont).grid(column=0,row=1)
e=tkinter.Entry(f2,textvariable=curves[scr][YEQ],width=19)
try:
ft(curves[scr][YEQ].get(),0.01)
except(ZeroDivisionError):
pass
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=1)
f2.pack(fill=tkinter.X)
else:
f2=tkinter.LabelFrame(f1,text="Equation",padx=5,pady=5)
if(types[curves[scr][TYPE].get()]==POLAR):
tkinter.Label(f2,text="ρ(t)=",font=pfont).grid(column=0,row=0)
e=tkinter.Entry(f2,textvariable=curves[scr][EQ],width=19)
try:
ft(curves[scr][EQ].get(),0.01)
except(ZeroDivisionError):
pass
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=0)
if(types[curves[scr][TYPE].get()]==YFX):
tkinter.Label(f2,text="y=f(x)=",font=pfont).grid(column=0,row=0)
e=tkinter.Entry(f2,textvariable=curves[scr][EQ],width=19)
try:
x=0.01
eval(curves[scr][EQ].get())
except(ZeroDivisionError):
pass
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=0)
if(types[curves[scr][TYPE].get()]==XFY):
tkinter.Label(f2,text="x=f(y)=",font=pfont).grid(column=0,row=0)
e=tkinter.Entry(f2,textvariable=curves[scr][EQ],width=19)
try:
y=0.01
eval(curves[scr][EQ].get())
except(ZeroDivisionError):
pass
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=0)
f2.pack(fill=tkinter.X)
if(types[curves[scr][TYPE].get()]==PARAM or types[curves[scr][TYPE].get()]==POLAR):
f2=tkinter.LabelFrame(f1,text="Paramètre t",padx=5,pady=5)
if(types[curves[scr][TYPE].get()]==POLAR):
f2.config(text="Paramètre t (θ)")
tkinter.Label(f2,text="Min:",font=pfont).grid(column=0,row=0)
e=tkinter.Entry(f2,textvariable=curves[scr][PARMIN],width=6)
try:
int(eval(curves[scr][PARMIN].get()))
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=0)
tkinter.Label(f2,text="Max:",font=pfont).grid(column=2,row=0)
e=tkinter.Entry(f2,textvariable=curves[scr][PARMAX],width=6)
try:
int(eval(curves[scr][PARMAX].get()))
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=3,row=0)
tkinter.Label(f2,text="Pas:",font=pfont).grid(column=0,row=1)
e=tkinter.Entry(f2,textvariable=curves[scr][PARSTEP],width=6)
try:
int(1/eval(curves[scr][PARSTEP].get()))
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=1)
f2.pack(fill=tkinter.X)
f2=tkinter.LabelFrame(f1,text="Autre",padx=5,pady=5)
tkinter.Label(f2,text="Couleur: ",font=pfont).grid(column=0,row=0)
tkinter.Entry(f2,textvariable=curves[scr][CCOLOR],width=10).grid(column=1,row=0)
tkinter.Label(f2,text="Epaisseur:",font=pfont).grid(column=0,row=1)
e=tkinter.Entry(f2,textvariable=curves[scr][SIZE],width=10)
try:
int(curves[scr][SIZE].get())
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=1)
f2.pack(fill=tkinter.X)
f2=tkinter.Frame(f1,padx=5,pady=5)
tkinter.Button(f2,text="Supprimer",width=12,command=partial(delCurve,scr),font=bfont).grid(column=0,row=0)
tkinter.Checkbutton(f2,text="Visible",variable=curves[scr][ACTIVE],command=paint).grid(column=1,row=0)
f2.pack(fill=tkinter.X)
f2.pack()
f1.pack(fill=tkinter.Y)
f.pack(fill=tkinter.BOTH,anchor=tkinter.N)
def page2(frame):
global page
page=2
#mêmes principes que précedemment
f=tkinter.Frame(frame)
menuBar(f,2)
f1=tkinter.LabelFrame(f,text="Fenêtre",padx=5,pady=5)
f2=tkinter.Frame(f1)
f3=tkinter.LabelFrame(f2,text="X",padx=5,pady=5)
tkinter.Label(f3,text="min:",font=pfont).grid(column=0,row=0)
e=tkinter.Entry(f3,textvariable=graph[XMIN],width=7)
try:
int(eval(graph[XMIN].get()))
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=0)
tkinter.Label(f3,text="max:",font=pfont).grid(column=2,row=0)
e=tkinter.Entry(f3,textvariable=graph[XMAX],width=7)
try:
int(eval(graph[XMAX].get()))
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=3,row=0)
f3.grid(column=0,row=0)
f3=tkinter.LabelFrame(f2,text="Y",padx=5,pady=5)
tkinter.Label(f3,text="min:",font=pfont).grid(column=0,row=0)
e=tkinter.Entry(f3,textvariable=graph[YMIN],width=7)
try:
int(eval(graph[YMIN].get()))
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=1,row=0)
tkinter.Label(f3,text="max:",font=pfont).grid(column=2,row=0)
e=tkinter.Entry(f3,textvariable=graph[YMAX],width=7)
try:
int(eval(graph[YMAX].get()))
except(NameError):
e.config(bg=WRONG)
except:
e.config(bg=WRONG)
e.grid(column=3,row=0)
f3.grid(column=0,row=1)
f2.pack(fill=tkinter.X)
f2=tkinter.Frame(f1)
tkinter.Button(f2,text="Orthonormer X",command=orthx).grid(column=0,row=0)
tkinter.Button(f2,text="Orthonormer Y",command=orthy).grid(column=1,row=0)
f2.pack(fill=tkinter.X)
st=tkinter.NORMAL
if(not(azoomenable)):
st=tkinter.DISABLED
tkinter.Button(f1,text="Zoom auto",command=azoom,state=st).pack(fill=tkinter.X)
f1.pack(fill=tkinter.BOTH)
f1=tkinter.LabelFrame(f,text="Graduation",padx=5,pady=5)
f2=tkinter.LabelFrame(f1,text="Axes",padx=5,pady=5)
tkinter.Checkbutton(f2,text="1 ",variable=graph[AXIS1],command=paint,width=7).pack()
tkinter.Checkbutton(f2,text="0.5",variable=graph[AXIS2],command=paint,width=7).pack()
tkinter.Checkbutton(f2,text="0.1",variable=graph[AXIS3],command=paint,width=7).pack()
f2.grid(column=0,row=0)
f2=tkinter.LabelFrame(f1,text="Grille",padx=5,pady=5)
tkinter.Checkbutton(f2,text="1 ",variable=graph[GRID1],command=paint,width=7).pack()
tkinter.Checkbutton(f2,text="0.5",variable=graph[GRID2],command=paint,width=7).pack()
tkinter.Checkbutton(f2,text="0.1",variable=graph[GRID3],command=paint,width=7).pack()
f2.grid(column=1,row=0)
f1.pack(fill=tkinter.BOTH)
f1=tkinter.LabelFrame(f,text="Autre",padx=5,pady=5)
f2=tkinter.Frame(f1)
tkinter.Label(f2,text="Fond:",font=pfont).grid(column=0,row=0)
tkinter.Entry(f2,textvariable=graph[GCOLOR],width=18).grid(column=1,row=0)
f2.pack()
tkinter.Checkbutton(f1,text="Titre des axes",variable=graph[AXIST1],command=paint).pack(anchor=tkinter.NW)
tkinter.Checkbutton(f1,text="Axes flechés",variable=graph[AXISA],command=paint).pack(anchor=tkinter.NW)
tkinter.Checkbutton(f1,text="Unités",variable=graph[AXIST2],command=paint).pack(anchor=tkinter.NW)
f1.pack(fill=tkinter.X)
f.pack(fill=tkinter.BOTH,anchor=tkinter.N)
def page3(frame):
global page
page=3
#idem
f=tkinter.Frame(frame)
menuBar(f,3)
f1=tkinter.LabelFrame(f,text="Taille du graph",padx=5,pady=5)
tkinter.Label(f1,text="X:",font=pfont).grid(column=0,row=0)
e=tkinter.Entry(f1,textvariable=opts[TX],width=6)
try:
int(opts[TX].get())
except:
e.config(bg=WRONG)
e.grid(column=1,row=0)
tkinter.Label(f1,text="Y:",font=pfont).grid(column=2,row=0)
e=tkinter.Entry(f1,textvariable=opts[TY],width=6)
try:
int(opts[TX].get())
except:
e.config(bg=WRONG)
e.grid(column=3,row=0)
tkinter.Button(f1,text="changer",font=bfont,command=restart).grid(column=4,row=0)
f1.pack(fill=tkinter.X)
f1=tkinter.LabelFrame(f,text="Autre",padx=5,pady=5)
tkinter.Checkbutton(f1,text="Zoomer localement",variable=opts[ZOOM]).pack(anchor=tkinter.NW)
f2=tkinter.Frame(f1)
tkinter.Label(f2,text="Précision déplacements:",font=pfont).grid(column=0,row=0)
tkinter.Entry(f2,textvariable=opts[RND],width=5).grid(column=1,row=0)
f2.pack()
f1.pack(fill=tkinter.X)
f1=tkinter.LabelFrame(f,text="Informations",padx=5,pady=5)
tkinter.Label(f1,text="Commandes",font=pbfont).pack()
tkinter.Label(f1,text="Entrée - Valider les champs\nClic gauche - Déplacer l'origine\nClic droit - Dézoomer\nClic droit (glisser) - Zoomer\nMolette - Zoomer/Dézoomer",font=pfont).pack()
tkinter.Label(f1,text="Divers",font=pbfont).pack()
tkinter.Label(f1,text="\"pi\" est valide dans l'écriture\ndes fonctions et valeurs.",font=pfont).pack()
tkinter.Label(f1,text="A propos",font=pbfont).pack()
tkinter.Label(f1,text="Graph version "+ver+"\nDéveloppé par : Clément Gouin\nclement.gouin@reseau.eseo.fr",font=pfont).pack()
f1.pack(fill=tkinter.X)
f.pack(fill=tkinter.BOTH,anchor=tkinter.N)
def paint():
global cv,autozoom,azoomenable
try:
cv.destroy()
except NameError:
pass
except tkinter.TclError:
pass
cv=tkinter.Canvas(win,width=opts[TX].get(),height=opts[TY].get())
cv.grid(column=0,row=0,sticky=tkinter.N)
cv.bind("<Button-1>",bu1)
cv.bind("<Button-3>",bu3)
cv.bind("<B3-Motion>",bu3m)
cv.bind("<ButtonRelease-3>",bu3r)
#Une des fonctions principales du programme
#elle permet le rafraichissement du canvas
#on crée tout d'abord le fond par un rectangle,
#on efface rien, on colle juste le fond par dessus le précédent
cv.create_rectangle(2,2,opts[TX].get(),opts[TY].get()-3,fill=graph[GCOLOR].get())
#suivant les paramètres, on affiche les grilles et axes ou non
if(graph[GRID3].get()):
gridf(0.1,"grey90")
if(graph[GRID2].get()):
gridf(0.5,"grey80")
if(graph[GRID1].get()):
gridf(1,"grey70")
#Ici on met en paramètre qui est l'axe maitre,
#car c'est lui qui affiche les noms des axes, les unités et les fleches
if(graph[AXIS1].get()):
axisf(1,"grey40",4,True) #L'axe 1 est toujours maitre s'il est actif
if(graph[AXIS2].get()):
axisf(0.5,"grey40",2,(not(graph[AXIS1].get()))) #Sinon c'est le 0.5 etc.
if(graph[AXIS3].get()):
axisf(0.1,"grey40",1,(not(graph[AXIS1].get()) and not(graph[AXIS2].get())))
#enfin on affiche les courbes successivement et si elles sont affichées
autozoom=[0,0,0,0]
azoomenable=False
if(len(curves)>0):
for k in range(len(curves)):
if(curves[k][ACTIVE].get()):
curvef(k,curves[k][CCOLOR].get(),curves[k][SIZE].get())
if(zoombe):
cv.create_rectangle(zoomb[0][0],zoomb[0][1],zoomb[1][0],zoomb[1][1],outline="red")
def gridf(pas,col):
#On récupère les différentes variables
try:
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
except:
pass
else:
factx=tx/(abs(xmax-xmin))
facty=ty/(abs(ymax-ymin))
n = int((2+abs(ymax-ymin))/pas)
d=abs(ymin)-abs(int(ymin))
for k in range(n+1):
cv.create_line(0,ty-(k*pas+d-1)*facty,tx,ty-(k*pas+d-1)*facty,fill=col)
n = int((2+abs(xmax-xmin))/pas)
d=abs(xmin)-abs(int(xmin))
for k in range(n+1):
cv.create_line((k*pas+d-1)*factx,0,(k*pas+d-1)*factx,ty,fill=col)
def axisf(pas,col,t1,high):
try:
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
except:
pass
else:
factx=tx/(abs(xmax-xmin))
facty=ty/(abs(ymax-ymin))
if(min(xmin,xmax)<0 and max(xmin,xmax)>0):
n = int((2+abs(ymax-ymin))/pas)
d=abs(min(ymin,ymax))-abs(int(min(ymin,ymax)))
if(high and graph[AXISA].get()):
if(ymax>ymin):
cv.create_line(-sgn(xmin,xmax)*xmin*factx,0,-sgn(xmin,xmax)*xmin*factx,ty,fill=col,arrow=tkinter.FIRST)
else:
cv.create_line(-sgn(xmin,xmax)*xmin*factx,0,-sgn(xmin,xmax)*xmin*factx,ty,fill=col,arrow=tkinter.LAST)
else:
cv.create_line(-sgn(xmin,xmax)*xmin*factx,0,-sgn(xmin,xmax)*xmin*factx,tx,fill=col)
for k in range(n+1):
cv.create_line(-sgn(xmin,xmax)*xmin*factx-t1,ty-(k*pas+d-1)*facty,-sgn(xmin,xmax)*xmin*factx+t1+1,ty-(k*pas+d-1)*facty,fill=col)
if(high and graph[AXIST2].get() and min(ymin,ymax)<pas and max(ymin,ymax)>pas):
cv.create_text(-10-sgn(xmin,xmax)*xmin*factx,ty-(pas-ymin)*facty,text=str(pas),font=pfont,fill=col)
if(high and graph[AXIST1].get()):
if(ymax>ymin):
cv.create_text(-10-xmin*factx,15,text="y",font=pfont,fill=col)
else:
cv.create_text(-10-xmin*factx,ty-35,text="y",font=pfont,fill=col)
if(min(ymin,ymax)<0 and max(ymin,ymax)>0):
n = int((2+abs(xmax-xmin))/pas)
d=abs(min(xmin,xmax))-abs(int(min(xmin,xmax)))
if(high and graph[AXISA].get()):
if(xmax>xmin):
cv.create_line(0,ty+sgn(ymin,ymax)*ymin*facty,tx,ty+sgn(ymin,ymax)*ymin*facty,fill=col,arrow=tkinter.LAST)
else:
cv.create_line(0,ty+sgn(ymin,ymax)*ymin*facty,tx,ty+sgn(ymin,ymax)*ymin*facty,fill=col,arrow=tkinter.FIRST)
else:
cv.create_line(0,ty+sgn(ymin,ymax)*ymin*facty,tx,ty+sgn(ymin,ymax)*ymin*facty,fill=col)
for k in range(n+1):
cv.create_line((k*pas+d-1)*factx,ty+sgn(ymin,ymax)*ymin*facty-t1,(k*pas+d-1)*factx,ty+sgn(ymin,ymax)*ymin*facty+t1+1,fill=col)
if(high and graph[AXIST2].get() and min(xmin,xmax)<pas and max(xmin,xmax)>pas):
cv.create_text((pas-xmin)*factx,ty+sgn(ymin,ymax)*ymin*facty+15,text=str(pas),font=pfont,fill=col)
if(high and graph[AXIST1].get()):
if(xmax>xmin):
cv.create_text(tx-10,ty+ymin*facty+15,text="x",font=pfont,fill=col)
else:
cv.create_text(10,ty+ymin*facty+15,text="x",font=pfont,fill=col)
def curvef(k,col,ta):
global curves,azoomenable,autozoom
try:
tx,ty,xmax,xmin,ymax,ymin,parmin,parmax,parstep=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get()),eval(curves[k][PARMIN].get()),eval(curves[k][PARMAX].get()),eval(curves[k][PARSTEP].get())
1/parstep
except:
pass
else:
factx=tx/(xmax-xmin)
facty=ty/(ymax-ymin)
if(types[curves[k][TYPE].get()]==PARAM):
azoomenable=True
if(types[curves[k][TYPE].get()]==POLAR):
azoomenable=True
curves[k][XEQ].set("("+curves[k][EQ].get()+")*cos(t)")
curves[k][YEQ].set("("+curves[k][EQ].get()+")*sin(t)")
if(types[curves[k][TYPE].get()]==YFX):
curves[k][XEQ].set("t")
curves[k][YEQ].set(curves[k][EQ].get().replace('x','t'))
curves[k][PARMIN].set(xmin)
curves[k][PARMAX].set(xmax)
curves[k][PARSTEP].set(abs(xmax-xmin)/(tx))
if(types[curves[k][TYPE].get()]==XFY):
curves[k][YEQ].set("t")
curves[k][XEQ].set(curves[k][EQ].get().replace("y","t"))
curves[k][PARMIN].set(ymin)
curves[k][PARMAX].set(ymax)
curves[k][PARSTEP].set(abs(ymax-ymin)/(ty))
n = int((parmax-parmin)/parstep)+2
li=[];
for k1 in range(n):
t=parmin+k1*parstep
try:
li+=[[ft(curves[k][XEQ].get(),t),ft(curves[k][YEQ].get(),t),True]]
if(azoomenable):
if(li[k1][0]>autozoom[XMAX]):
autozoom[XMAX]=li[k1][0]
if(li[k1][0]<autozoom[XMIN]):
autozoom[XMIN]=li[k1][0]
if(li[k1][1]>autozoom[YMAX]):
autozoom[YMAX]=li[k1][1]
if(li[k1][1]<autozoom[YMIN]):
autozoom[YMIN]=li[k1][1]
except(ZeroDivisionError):
li+=[[0,0,False]]
for k1 in range(n):
li[k1][0]=int((li[k1][0]-xmin)*factx)
li[k1][1]=ty-int((li[k1][1]-ymin)*facty)
for k1 in range(n-1):
if(li[k1][2] and li[k1+1][2] and
((0<li[k1][0]<tx and 0<li[k1][1]<ty) or
(0<li[k1+1][0]<tx and 0<li[k1+1][1]<ty))):
cv.create_line(li[k1][0],li[k1][1],li[k1+1][0],li[k1+1][1],fill=col,width=ta)
def restart():
global win,curves,graph,opts,scr
#Lorsque l'on veut modifier la fenetre, on doit la détruire
#et cela détruit toutes les variables tkinter, on les sauvegarde
#donc dans des listes et on les recrée
if(len(curves)>0):
savcurves = []
for k in range(len(curves)):
temp=[]
for l in range(len(curves[k])):
temp+=[curves[k][l].get()]
savcurves+=[temp[:]]
savgraph=[]
for k in range(len(graph)):
savgraph+=[graph[k].get()]
savopts=[]
for k in range(len(opts)):
savopts+=[opts[k].get()]
win.destroy()
win=tkinter.Tk()
tkvars(savcurves,savgraph,savopts)
paintwin()
def tkvars(cu,ax,op):
global curves,graph,opts
#Définitions des variables et de leur type
curves=[]
if(len(cu)>0):
for k in range(len(cu)):
newCurve(cu[k][ACTIVE],cu[k][TYPE],cu[k][EQ],cu[k][XEQ],cu[k][YEQ],cu[k][PARMIN],cu[k][PARMAX],cu[k][PARSTEP],cu[k][CCOLOR],cu[k][SIZE])
graph=LENGRAPH*[None]
graph[XMAX]=tkinter.StringVar()
graph[XMIN]=tkinter.StringVar()
graph[YMIN]=tkinter.StringVar()
graph[YMAX]=tkinter.StringVar()
graph[AXIS1]=tkinter.IntVar()
graph[AXIS2]=tkinter.IntVar()
graph[AXIS3]=tkinter.IntVar()
graph[AXIST1]=tkinter.IntVar()
graph[AXIST2]=tkinter.IntVar()
graph[AXISA]=tkinter.IntVar()
graph[GRID1]=tkinter.IntVar()
graph[GRID2]=tkinter.IntVar()
graph[GRID3]=tkinter.IntVar()
graph[GCOLOR]=tkinter.StringVar()
for k in range(len(graph)):
graph[k].set(ax[k])
opts=LENOPTS*[None]
opts[TX]=tkinter.IntVar()
opts[TY]=tkinter.IntVar()
opts[ZOOM]=tkinter.IntVar()
opts[RND]=tkinter.IntVar()
for k in range(len(opts)):
opts[k].set(op[k])
def newCurve(active,typef,eq,xeq,yeq,tmin,tmax,tstep,color,size):
global curves,scr
#Ajout d'une courbe
curves+=[LENCURVES*[None]]
n=len(curves)-1
curves[n][ACTIVE]=tkinter.IntVar()
curves[n][TYPE]=tkinter.StringVar()
curves[n][EQ]=tkinter.StringVar()
curves[n][XEQ]=tkinter.StringVar()
curves[n][YEQ]=tkinter.StringVar()
curves[n][PARMIN]=tkinter.StringVar()
curves[n][PARMAX]=tkinter.StringVar()
curves[n][PARSTEP]=tkinter.StringVar()
curves[n][CCOLOR]=tkinter.StringVar()
curves[n][SIZE]=tkinter.IntVar()
curves[n][ACTIVE].set(active)
curves[n][TYPE].set(typef)
curves[n][EQ].set(eq)
curves[n][XEQ].set(xeq)
curves[n][YEQ].set(yeq)
curves[n][PARMIN].set(tmin)
curves[n][PARMAX].set(tmax)
curves[n][PARSTEP].set(tstep)
curves[n][CCOLOR].set(color)
curves[n][SIZE].set(size)
def delCurve(n):
global curves,scr
#Destruction d'une courbe
del curves[n]
scr-=1
menu(1,True,False)
def enter(event):
#Evenement correspondand à l'appui de la touche entrée
menu(1,True,True)
def bu1(event):
global graph
#Evenement du clic de la souris
#le graph ce centre sur ce clic
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
factx=tx/(xmax-xmin)
facty=ty/(ymax-ymin)
dx=(event.x-tx/2)/factx
dy=(event.y-ty/2)/facty
graph[XMAX].set(rnd(xmax+dx,opts[RND].get()))
graph[XMIN].set(rnd(xmin+dx,opts[RND].get()))
graph[YMAX].set(rnd(ymax-dy,opts[RND].get()))
graph[YMIN].set(rnd(ymin-dy,opts[RND].get()))
menu(2,True,True)
def bu3(event):
global zoomb,zoombe,win
zoombe=True
zoomb=[[event.x,event.y],[event.x,event.y]]
win.after(20,paint)
def bu3m(event):
global zoomb,win
zoomb[1]=[event.x,event.y]
win.after(20,paint)
def bu3r(event):
global zoomb,zoombe,graph
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
zoombe=False
if(abs(zoomb[0][0]-zoomb[1][0])<5 and abs(zoomb[0][1]-zoomb[1][1])<5):
factx=opts[TX].get()/(abs(xmax-xmin))
facty=opts[TY].get()/(abs(ymax-ymin))
factx/=2
facty/=2
dx=(opts[TX].get()-(xmax-xmin)*factx)/factx
dy=(opts[TY].get()-(ymax-ymin)*factx)/factx
graph[XMAX].set(rnd(xmax+dx/2,opts[RND].get()))
graph[XMIN].set(rnd(xmin-dx/2,opts[RND].get()))
graph[YMAX].set(rnd(ymax+dy/2,opts[RND].get()))
graph[YMIN].set(rnd(ymin-dy/2,opts[RND].get()))
else:
factx=opts[TX].get()/(abs(xmax-xmin))
facty=opts[TY].get()/(abs(ymax-ymin))
graph[XMIN].set(rnd(xmin+zoomb[0][0]/factx,opts[RND].get()))
graph[XMAX].set(rnd(xmin+zoomb[1][0]/factx,opts[RND].get()))
graph[YMIN].set(rnd(ymax-zoomb[0][1]/facty,opts[RND].get()))
graph[YMAX].set(rnd(ymax-zoomb[1][1]/facty,opts[RND].get()))
menu(1,True,True)
def zoom(event):
global graph
#Evenement de la molette de la souris
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
zoom = event.delta/120
factx=opts[TX].get()/(abs(xmax-xmin))
facty=opts[TY].get()/(abs(ymax-ymin))
factx+=zoom*2
facty+=zoom*2
dx=(opts[TX].get()-(xmax-xmin)*factx)/factx
dy=(opts[TY].get()-(ymax-ymin)*factx)/factx
graph[XMAX].set(rnd(xmax+dx/2,opts[RND].get()))
graph[XMIN].set(rnd(xmin-dx/2,opts[RND].get()))
graph[YMAX].set(rnd(ymax+dy/2,opts[RND].get()))
graph[YMIN].set(rnd(ymin-dy/2,opts[RND].get()))
if(zoom>0 and opts[ZOOM].get()):
dx=(event.x-opts[TX].get()/2)/factx
dy=(event.y-opts[TY].get()/2)/facty
graph[XMAX].set(rnd(graph[XMAX]+dx,opts[RND].get()))
graph[XMIN].set(rnd(graph[XMIN]+dx,opts[RND].get()))
graph[YMAX].set(rnd(graph[YMAX]-dy,opts[RND].get()))
graph[YMIN].set(rnd(graph[YMIN]-dy,opts[RND].get()))
menu(2,True,True)
def azoom():
global graph
graph[XMAX].set(autozoom[XMAX]*1.1)
graph[XMIN].set(autozoom[XMIN]*1.1)
graph[YMAX].set(autozoom[YMAX]*1.1)
graph[YMIN].set(autozoom[YMIN]*1.1)
menu(2,True,True)
def badd():
global scr
#ajout d'une courbe vide avec le bouton "Nouvelle Courbe"
newCurve(0,ntypes[PARAM],"","","",0,0,0.1,"black",1)
if(len(curves)>1):
scr+=1
menu(1,True,False)
def ctype(*args):
#TODO
if(types[curves[scr][TYPE].get()]==POLAR and curves[scr][EQ].get()!=""):
curves[scr][EQ].set(curves[scr][EQ].get().replace("y","t"))
curves[scr][EQ].set(curves[scr][EQ].get().replace("x","t"))
if(types[curves[scr][TYPE].get()]==XFY and curves[scr][EQ].get()!=""):
curves[scr][EQ].set(curves[scr][EQ].get().replace("t","y"))
curves[scr][EQ].set(curves[scr][EQ].get().replace("x","y"))
if(types[curves[scr][TYPE].get()]==YFX and curves[scr][EQ].get()!=""):
curves[scr][EQ].set(curves[scr][EQ].get().replace("t","x"))
curves[scr][EQ].set(curves[scr][EQ].get().replace("y","x"))
menu(1,False,False)
def move(n):
global scr
#Changement de courbe dans le menu
if(n>0 and scr<len(curves)-1):
scr+=1
elif(n<0 and scr>0):
scr-=1
menu(1,False,False)
def orthx():
global graph
#Orthonormalisation de l'axe x en fonction de l'axe y
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
if(xmax<xmin):
i=xmin
graph[XMIN].set(xmax)
graph[YMAX].set(i)
c=xmin+(abs(xmax-xmin))/2
dx=(abs(ymax-ymin))*tx/ty
graph[XMAX].set(c+dx/2)
graph[XMIN].set(c-dx/2)
menu(2,True,True)
def orthy():
global graph
#Idem en inversant
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
if(ymax<ymin):
i=ymin
graph[YMIN].set(ymax)
graph[YMAX].set(i)
c=ymin+(abs(ymax-ymin))/2
dy=(abs(xmax-xmin))*ty/tx
graph[YMAX].set(c+dy/2)
graph[YMIN].set(c-dy/2)
menu(2,True,True)
#fonctions utiles
def ft(text,t):
#Transformation du texte de f(t) en vraie fonction
return eval(text)
def rnd(n,p):
#arrondi de n au p-ième chiffre
return int(n*10**p+0.5)/(10**p)
def sgn(minv,maxv):
#signe en fonction de l'inversion des axes
if(maxv<minv):
return -1
return 1
#Démarrage du programme
start()
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

+289
View File
@@ -0,0 +1,289 @@
import os.path
import math
def tryparse_int(value):
try:
return int(value)
except ValueError:
return None
def do_dich(name):
pi = load(name)
b = "0110"
x = 14
d = 25
n = 3
while n < len(pi):
if x > d:
x -= d
b += "1"
else:
b += "0"
x = 10 * x + int(str(pi[n]))
d *= 5
n += 1
return b
def load(name):
d = ""
with open(name) as f:
for line in f:
d = line.strip()
break
return d
def save(name, bi):
with open(name, mode='w') as f:
f.write(bi)
def verify_dich(b):
x = 4.0
n = float(0)
i = 0
while i < len(b) and x > 0:
if b[i] == '1':
n += x
x /= 2.0
i += 1
print(n)
return n == 3.141592653589793
def save_byte(name, data):
with open(name, mode='wb') as f:
f.write(bytearray(data))
def n2b(num, nbyte=4):
b = []
for i in range(nbyte):
b += [num % 256]
num //= 256
return b
def print_bytes(data):
for i in range(len(data) // 16 + 1):
for j in range(16):
if i * 16 + j >= len(data):
print(" . ", end='')
else:
print("{:02x} ".format(data[i * 16 + j]), end='')
print()
def save_bmp(name, data, width):
# fix data size
height = len(data) // (width * 3)
if len(data) > height * width * 3:
data = data[0:height * width * 3]
# fix line width not %4
line_width = (width * 3) % 4
if line_width != 0:
tail = (3 - line_width) * [0] + [255]
data2 = []
for i in range(height):
data2 += data[i * width * 3:(i + 1) * width * 3] + tail
data = data2
header = [0] * 54
header[0:2] = [66, 77] # BM
header[2:6] = n2b(len(data) + 54) # file size
# 4 bytes application reserved
header[10:14] = n2b(54) # offset of data
header[14:18] = n2b(40) # size of header
header[18:22] = n2b(width) # width
header[22:26] = n2b(height) # height
header[26:28] = n2b(1, 2) # color panes
header[28:30] = n2b(24, 2) # color depth
# 4 bytes compression method
# 4 bytes optional image size
header[38:42] = n2b(3780) # horizontal resolution
header[42:46] = n2b(3780) # vertical resolution
# 4 bytes number of colors
# 4 bytes number of important colors
print_bytes(header)
with open(name, mode='wb') as f:
f.write(bytearray(header + data))
def save_wav(name, data, channels, freq, sampling):
header_size = 44
header = [0] * header_size
bytesPerBloc = int(channels * sampling / 8)
dataSize = len(data)
mod = dataSize % bytesPerBloc
if mod > 0:
dataSize -= mod
# file info
header[0:4] = [0x52, 0x49, 0x46, 0x46] # "RIFF"
header[4:8] = n2b(header_size + dataSize - 8) # file size - 8bytes
header[8:12] = [0x57, 0x41, 0x56, 0x45] # "WAVE"
# audio format
header[12:16] = [0x66, 0x6D, 0x74, 0x20]
header[16:20] = n2b(16)
header[20:22] = n2b(1) # PCM format
header[22:24] = n2b(channels) # nb of channels
header[24:28] = n2b(freq) # frequency 11025, 22050, 44100, 48000, 96000
header[28:32] = n2b(freq * bytesPerBloc) # BytePerSec
header[32:34] = n2b(bytesPerBloc) # BytePerBloc
header[34:36] = n2b(sampling) # BitsPerSample 8, 16, 24
# data
header[36:40] = [0x64, 0x61, 0x74, 0x61] # "data"
header[40:44] = n2b(dataSize)
print_bytes(header)
with open(name, mode='wb') as f:
f.write(bytearray(header + data[:dataSize]))
def get_data(b):
return [int(b[n * 8:(n + 1) * 8], 2) for n in range(int(len(b) / 8))]
def get_bw_bmp_data(b, width):
data = []
for n in range(width * width):
c = 0
if b[n] == '1':
c = 255
data += [c, c, c] # grey
return data
def get_grey_bmp_data(b, width):
data = []
for n in range(width * width):
c = b[n * 8:(n + 1) * 8]
data += [int(c, 2), int(c, 2), int(c, 2)] # grey
return data
DIGIT_FILE = "pi1000000.txt"
BIN_FILE = "pi1000000bin.txt"
bpi = ""
if os.path.isfile(BIN_FILE):
print("loading dichotomy...")
bpi = load(BIN_FILE)
elif os.path.isfile(DIGIT_FILE):
print("computing dichotomy (this might take a while)...")
bpi = do_dich(DIGIT_FILE)
print("saving dichotomy...")
save(BIN_FILE, bpi)
else:
print(DIGIT_FILE, "was not found")
exit(1)
print(len(bpi), "bits of dichotomy in memory")
print()
print("verifying dichotomy...")
if not (verify_dich(bpi)):
print("could not verify dichotomy you may delete the file ", BIN_FILE)
exit(1)
print()
print("modes :")
print("1:binary file")
print("2:black & white bitmap file")
print("3:grey scale bitmap file")
print("4:wave file")
mode = tryparse_int(input("select a mode : "))
print()
if mode == 1:
defname = "pi_bin"
name = input("enter file name : [{}] ".format(defname)).strip()
if len(name) == 0:
name = defname
print("getting data...")
data = get_data(bpi)
print("saving to file '" + name + "' ...")
save_byte(name, data)
print("saved to file '" + name + "'")
elif mode == 2:
maxw = int(math.sqrt(len(bpi)))
width = tryparse_int(input("enter image width (max:{0}): [{0}] ".format(maxw)))
if width is None or width > maxw or width < 1:
width = maxw
defname = "pi_bw_{}.bmp".format(width)
name = input("enter file name : [{}] ".format(defname)).strip()
if len(name) == 0:
name = defname
if not (name.endswith(".bmp")):
name += ".bmp"
print("getting data...")
data = get_bw_bmp_data(bpi, width)
print("saving to file '" + name + "' ...")
save_bmp(name, data, width)
print("saved to file '" + name + "'")
elif mode == 3:
maxw = int(math.sqrt(len(bpi)) / 8)
width = tryparse_int(input("enter image width (max:{0}): [{0}] ".format(maxw)))
if width is None or width > maxw or width < 1:
width = maxw
defname = "pi_grey_{}.bmp".format(width)
name = input("enter file name : [{}] ".format(defname)).strip()
if len(name) == 0:
name = defname
if not (name.endswith(".bmp")):
name += ".bmp"
print("getting data...")
data = get_grey_bmp_data(bpi, width)
print("saving to file '" + name + "' ...")
save_bmp(name, data, width)
print("saved to file '" + name + "'")
elif mode == 4:
channels = tryparse_int(input("number of channels (max:6) : [1] "))
if channels is None or channels <= 0:
channels = 1
if channels > 6:
channels = 6
freq = tryparse_int(input("frequency (1->11k, 2->22k, 3->44.1k, 4->48k 5->96k) : [3] "))
if freq is None:
freq = 3
if freq <= 0:
freq = 1
if freq > 5:
freq = 5
freq = int(11025 * math.pow(2, freq - 1))
bps = tryparse_int(input("bits per sample (1->8, 2->16, 3->24) : [1] "))
if bps is None or bps <= 0:
bps = 1
if bps > 3:
bps = 6
bps *= 8
defname = "pi_{}_{}_{}.wav".format(channels, bps, int(freq / 1000))
name = input("enter file name : [{}] ".format(defname)).strip()
if len(name) == 0:
name = defname
if not (name.endswith(".wav")):
name += ".wav"
print("getting data...")
data = get_data(bpi)
print("saving to file '" + name + "' ...")
save_wav(name, data, channels, freq, bps)
print("saved to file '" + name + "'")
print()
print("goodbye")
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB