Grapheur de fonctions mathématiques

Description

Permet de tracer un nombre illimité de fonctions mathématiques différentes ainsi que leurs dérivées sur un même graphique.
La fenêtre graphique est entièrement paramétrable (dimensions, échelle...), ainsi que les couleurs des courbes.
Permet le calcul intégral.

Source / Exemple :


# -*- coding: cp1252 -*-
# Grapheur mathématique
# Ecrit et immaginé par Amaury

from math import *
from Tkinter import *
import tkMessageBox
import tkFileDialog
import sys
import string
ux=0
global select,h,m,fen,root,lst1,a,can
save=[]
compteur=0
h=30
m=100
select="black"
cadre,selected,integer=False,False,False
croix=[]

def onInit():                                                                           #Création des axes de la fenêtre de traçage
    global xmin,xmax,ymin,ymax,pasx,pasy,save,lst1,a,compteur,uxx,ymin,uyy,selected,xo  #Trace la courbe entrée en effaçant les autres
    selected=False
    a=0
    h=30
    m=100
    lst1.delete(0,compteur)
    compteur=0
    can.create_rectangle(0,0,700,700,fill="white",outline="white")
    try:
        ent1.delete(0,len(str(xmin)))
        ent2.delete(0,len(str(xmax)))
        ent3.delete(0,len(str(pasx)))
        ent4.delete(0,len(str(ymin)))
        ent5.delete(0,len(str(ymax)))
        ent6.delete(0,len(str(pasy)))
    except:
        pass
    ent1.insert(0,str(-10))
    ent2.insert(0,str(10))
    ent3.insert(0,str(1))
    ent4.insert(0,str(-10))
    ent5.insert(0,str(10))
    ent6.insert(0,str(1))
    try:
            xmin=float(eval(ent1.get()))
    except SyntaxError:
            xmin=-10
    try:
            xmax=float(eval(ent2.get()))
    except SyntaxError:
            xmax=10
    try:
            pasx=float(eval(ent3.get()))
    except SyntaxError:
            pasx=1
    try:
            ymin=float(eval(ent4.get()))
    except SyntaxError:
            ymin=-10
    try:
            ymax=float(eval(ent5.get()))
    except SyntaxError:
            ymax=10
    try:
            pasy=float(eval(ent6.get()))
    except SyntaxError:
            pasy=1

    dx=float(xmax-xmin)
    dy=float(ymax-ymin)
    ux=700/dx
    uy=700/dy
    uxx=(dx/700)
    uyy=(dy/700)
    #Coordonnées du O(0,0):
    xo=ux*(-xmin)
    yo=uy*ymax
    # Axes:
    can.create_line(0,yo,700,yo,fill="red")
    can.create_line(xo,0,xo,700,fill="red")
    i=xo
    j=yo
    while i>-1:
        can.create_line(i,yo-2,i,yo+2,fill="red")
        i=i-(ux*pasx)
    while j>-1:
        can.create_line(xo-2,j,xo+2,j,fill="red")
        j=j-(uy*pasy)
    i=xo
    j=yo
    while i<701:
        can.create_line(i,yo-2,i,yo+2,fill="red")
        i=i+(ux*pasx)
    while j<701:
        can.create_line(xo-2,j,xo+2,j,fill="red")
        j=j+(uy*pasy)

    try:
        onCalc(str(ent10.get()),select,xo,yo,uy,uxx,xmin,1)
        save=str(ent10.get()),select
        lst1.insert(END,"f  (x)=  "+str(ent10.get())+"  "+str(select))
        compteur=compteur+1
    except SyntaxError:
        pass
            
def onAdd():                                                            #Ajoute la courbe entrée
    global select,h,xmin,xmax,ymin,ymax,pasx,pasy,lst1,compteur,uxx,yo,uy,ymin,uyy,selected,xo
    selected=False

    dx=float(xmax-xmin)
    dy=float(ymax-ymin)
    ux=700/dx
    uy=700/dy
    uxx=(dx/700)
    uyy=(dy/700)
    #Coordonnées du O(0,0):
    xo=ux*(-xmin)
    yo=uy*ymax
    # Axes:
    can.create_line(0,yo,700,yo,fill="red")
    can.create_line(xo,0,xo,700,fill="red")
    i=xo
    j=yo
    while i>-1:
        can.create_line(i,yo-2,i,yo+2,fill="red")
        i=i-(ux*pasx)
    while j>-1:
        can.create_line(xo-2,j,xo+2,j,fill="red")
        j=j-(uy*pasy)
    i=xo
    j=yo
    while i<701:
        can.create_line(i,yo-2,i,yo+2,fill="red")
        i=i+(ux*pasx)
    while j<701:
        can.create_line(xo-2,j,xo+2,j,fill="red")
        j=j+(uy*pasy)

    try:
        onCalc(str(ent10.get()),select,xo,yo,uy,uxx,xmin,1)
        save.append([str(ent10.get()),select])

        lst1.insert(END,"f  (x)=  " + str(ent10.get()) +"  "+str(select))
        compteur=compteur+1
        
        

    except SyntaxError:
        pass
    except NameError:
        onCalc(str(ent10.get()),"black",xo,yo,uy,uxx,xmin,1)
        lst1.insert(END,"dy/dx  (" + str(ent10.get()) + ")  "+str(select))
        
        

def Add(event):
    onAdd()

        
def onCalc(fonction,couleur,xo,yo,uy,uxx,xmin,e):                           #Créé la table de valeur de l'enssemble des points de la courbe
    global courbe,selected
    valeurs=[]
    a=0
    while a<701:
        x=float(xmin+(a*uxx))
        try:
            y=-eval (fonction)
            valeurs.append([x,y])
            a=a+1
        except ValueError:
            y=0
            valeurs.append([x,y])
            a=a+1
        except OverflowError:
            y=0
            valeurs.append([x,y])
            a=a+1
        except ZeroDivisionError:
            y=0
            valeurs.append([x,y])
            a=a+1    
        except NameError:
            tkMessageBox.showerror(title="Erreur de Syntaxe",message="""Fonction " """ + str(fonction) + """" inconnue""")
            break

    if e==2:
        courbe={}
        selected=True
    a=0
    while a<700:
        local0=valeurs[a]
        local1=valeurs[a+1]
        x1=a
        x2=a+1
        y1=int((local0[1]*uy)+yo)
        y2=int((local1[1]*uy)+yo)
        can.create_line(x1,y1,x2,y2,width=e,fill=couleur)
        if e==2:
            courbe[x1] = y1
        a=a+1
    can.create_line(0,yo,700,yo,fill="red")
    can.create_line(xo,0,xo,700,fill="red")

    
def onSelect(e):
    global select,liste,lbl

    select=listb.get(listb.curselection())
    if select == "black":
        lab.configure(text=select)
        listb.configure(bg="ivory")
        
    elif select=="autres":
        pop=Tk()
        liste=Listbox(pop)
        for  coul in  ["AliceBlue","AntiqueWhite","Aqua","Aquamarine","Azure","Beige","Bisque","BlanchedAlmond","Blue","BlueViolet","Brown","BurlyWood","CadetBlue","Chartreuse","Chocolate","Coral","CornflowerBlue","Cornsilk","Crimson","Cyan","DarkBlue","DarkCyan","DarkGoldenrod","DarkGray","DarkGreen","DarkKhaki","DarkMagenta","DarkOliveGreen","DarkOrange","DarkOrchid","DarkRed","DarkSalmon","DarkSeaGreen","DarkSlateBlue","DarkSlateGray","DarkTurquoise","DarkViolet","DeepPink","DeepSkyBlue","DimGray","DodgerBlue","FireBrick","FloralWhite","ForestGreen","Fuchsia","Gainsboro","Gold","Goldenrod","Gray","Green","GreenYellow","Honeydew","HotPink","IndianRed","Indigo","Khaki","Lavender","LavenderBlush","LawnGreen","LemonChiffon","LightBlue","LightCoral","LightCyan","LightGoldenrodYellow","LightGreen","LightSeaGreen","LightSkyBlue","LightSteelBlue","LightYellow","Lime","LimeGreen","Linen","Magenta","Maroon","MediumAquamarine","MediumBlue","MediumOrchid","MediumPurple","MediumSeaGreen","MediumSlateBlue","MediumSpringGreen","MediumTurquoise","MediumVioletRed","MidnightBlue","MintCream","MistyRose","Moccasin","NavajoWhite","Navy","OldLace","Olive","OliveDrab","Orange","OrangeRed","Orchid","PaleGoldenrod","PaleGreen","PaleTurquoise","PaleVioletRed","PapayaWhip","PeachPuff","Peru","Pink","Plum","PowderBlue","Purple","Red","RosyBrown","RoyalBlue","SaddleBrown","Salmon","SandyBrown","SeaGreen","Seashell","Sienna","Silver","SkyBlue","SlateBlue","SlateGray","SpringGreen","SteelBlue","Tan","Teal","Thistle","Tomato","Turquoise","Violet","Wheat","Yellow","YellowGreen"]:
            liste.insert(END,coul)

        scrollbar = Scrollbar(pop)
        liste.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=liste.yview)
        liste.bind('<Double-1>',onColor)
        liste.grid(row=0,column=0)
        scrollbar.grid(row=0,column=1)
        lbl=Button(pop,text="-",command=pop.destroy)
        lbl.grid(row=1,column=0)
        pop.mainloop()
        
    else:
        lab.configure(text=select)
        listb.configure(bg=select)

def onDerive():                                                         #Créé la table de valeur de la dérivée de la courbe
    global select,h,m,xmin,xmax,ymin,ymax,pasx,pasy,choix,compteur
    try:
            xmin=float(eval(ent1.get()))
    except SyntaxError:
            xmin=-10
    try:
            xmax=float(eval(ent2.get()))
    except SyntaxError:
            xmax=10
    try:
            pasx=float(eval(ent3.get()))
    except SyntaxError:
            pasx=1
    try:
            ymin=float(eval(ent4.get()))
    except SyntaxError:
            ymin=-10
    try:
            ymax=float(eval(ent5.get()))
    except SyntaxError:
            ymax=10
    try:
            pasy=float(eval(ent6.get()))
    except SyntaxError:
            pasy=1

    if len(choix)==2:
            tkMessageBox.showerror(title="Erreur de Syntaxe",message="""Fonction invalide""")
    elif len(choix)==3:
            tkMessageBox.showerror(title="Erreur de Syntaxe",message="""Fonction invalide""")
    elif len(choix)==4:
        onDeriv(choix[2],select,1)
        save.append(["derive",str(choix[2]),select])
        try:
            lst1.insert(END,"dy/dx  ("+str(choix[2])+")  " + str(select))
            compteur=compteur+1
        except:
            lst1.insert(END,"dy/dx  ("+str(ent10.get())+")  " + str(select))
            compteur=compteur+1
    
    
def onDeriv(fonction,couleur,e):
    global select,h,m,selected,courbe
    valeurs=[]
    a=0
    
    dx=float(xmax-xmin)
    dy=float(ymax-ymin)
    ux=700/dx
    uy=700/dy
    uxx=(dx/700)
    #Coordonnées du O(0,0):
    xo=ux*(-xmin)
    yo=uy*ymax
    i=xo
    j=yo
    while a<701:
        x=float(xmin+(a*uxx))
        try:
            y=-eval (fonction)
            valeurs.append([x,y])
            a=a+1
        except ValueError:
            y=0
            valeurs.append([x,y])
            a=a+1
        except OverflowError:
            y=0
            valeurs.append([x,y])
            a=a+1
        except ZeroDivisionError:
            y=0
            valeurs.append([x,y])
            a=a+1  
        except NameError:
            tkMessageBox.showerror(title="Erreur de Syntaxe",message="""Fonction " """ + str(fonction) + """" inconnue""")
            break
        a=a+1
    a=0
    if e==2:
        courbe={}
        selected=True
    while a<350:
        try:
            y4=y3
        except NameError:
            y4=0
        local0=valeurs[a]
        local1=valeurs[a+1]
        dy=local1[1]-local0[1]
        dx=local1[0]-local0[0]
        y3=dy/dx
        y1=int((y4*uy)+yo)
        y2=int((y3*uy)+yo)
        can.create_line(2*a,y1,2*(a+1),y2,width=e,fill=couleur)
        if e==2:
            courbe[2*a] = y1
            courbe[2*a+1] = y1
        a=a+1
    can.create_line(0,yo,700,yo,fill="red")
    can.create_line(xo,0,xo,700,fill="red")
    
        
def onHelp():
    tkMessageBox.showinfo(title="Aide",message="""Syntaxe des fonctions usuelles pour Python:

- log(x)<=> log(x,base)
- Racine(x) <=> sqrt(x)
- x^n <=> x**n
- E(x) <=> int(x)
- H(x) Trace un échelon d'Heaviside
- sin(x), cos(x) et tan(x) n'ont pas de syntaxe particulière,
  de même que asin(x), acos(x) et atan(x).
- SH(x), CH(x) et TH(x) définissentles fonctions trigo hyperboliques
- aSH(x), aCH(x) et aTH(x) sont les réciproques de SH, CH et TH

Perdu une courbe? Un double clic dans l'historique surligne la courbe!!!""")

def onRefresh():
    global save,xmin,xmax,pasx,ymin,ymax,pasy,uxx,yo,uy,ymin,uyy,selected,xo
    can.create_rectangle(0,0,700,700,fill="white",outline="white")
    selected=False

    try:
            xmin=float(eval(ent1.get()))
    except SyntaxError:
            xmin=-10
    try:
            xmax=float(eval(ent2.get()))
    except SyntaxError:
            xmax=10
    try:
            pasx=float(eval(ent3.get()))
    except SyntaxError:
            pasx=1
    try:
            ymin=float(eval(ent4.get()))
    except SyntaxError:
            ymin=-10
    try:
            ymax=float(eval(ent5.get()))
    except SyntaxError:
            ymax=10
    try:
            pasy=float(eval(ent6.get()))
    except SyntaxError:
            pasy=1

    dx=float(xmax-xmin)
    dy=float(ymax-ymin)
    ux=700/dx
    uy=700/dy
    uxx=(dx/700)
    uyy=(dy/700)
    #Coordonnées du O(0,0):
    xo=ux*(-xmin)
    yo=uy*ymax
    # Axes:
    can.create_line(0,yo,700,yo,fill="red")
    can.create_line(xo,0,xo,700,fill="red")
    i=xo
    j=yo
    while i>-1:
        can.create_line(i,yo-2,i,yo+2,fill="red")
        i=i-(ux*pasx)
    while j>-1:
        can.create_line(xo-2,j,xo+2,j,fill="red")
        j=j-(uy*pasy)
    i=xo
    j=yo
    while i<701:
        can.create_line(i,yo-2,i,yo+2,fill="red")
        i=i+(ux*pasx)
    while j<701:
        can.create_line(xo-2,j,xo+2,j,fill="red")
        j=j+(uy*pasy)
    a=0
    g=len(save)
    while a<g:
        local=save[a]
        if len(local)==3:
            onDeriv(local[1],local[2],1)
        elif len(local)==2:
            onCalc(local[0],local[1],xo,yo,uy,uxx,xmin,1)
        elif len(local)==4:
            onCourbe(local[2],local[3],1)
        a=a+1

def Refresh(event):
    onRefresh()
        
def onZoom(facteur):
    global save,xmin,xmax,pasx,ymin,ymax,pasy,ent1,ent2,ent3,ent4,ent5,ent6,uxx,uyy
    try:
            xmin=float(eval(ent1.get()))
    except SyntaxError:
            xmin=-10
    try:
            xmax=float(eval(ent2.get()))
    except SyntaxError:
            xmax=10
    try:
            pasx=float(eval(ent3.get()))
    except SyntaxError:
            pasx=1
    try:
            ymin=float(eval(ent4.get()))
    except SyntaxError:
            ymin=-10
    try:
            ymax=float(eval(ent5.get()))
    except SyntaxError:
            ymax=10
    try:
            pasy=float(eval(ent6.get()))
    except SyntaxError:
            pasy=1
    ent1.delete(0,len(str(xmin)))
    ent2.delete(0,len(str(xmax)))
    ent3.delete(0,len(str(pasx)))
    ent4.delete(0,len(str(ymin)))
    ent5.delete(0,len(str(ymax)))
    ent6.delete(0,len(str(pasy)))
    if facteur=="init":
        ent1.delete(0,len(str(xmin)))
        ent2.delete(0,len(str(xmax)))
        ent3.delete(0,len(str(pasx)))
        ent4.delete(0,len(str(ymin)))
        ent5.delete(0,len(str(ymax)))
        ent6.delete(0,len(str(pasy)))
        ent1.insert(0,str(-10))
        ent2.insert(0,str(10))
        ent3.insert(0,str(1))
        ent4.insert(0,str(-10))
        ent5.insert(0,str(10))
        ent6.insert(0,str(1))
        onRefresh()
    else:
        xmin,xmax,ymin,ymax,pasx,pasy=xmin/facteur,xmax/facteur,ymin/facteur,ymax/facteur,pasx/facteur,pasy/facteur

        ent1.insert(0,str(xmin))
        ent2.insert(0,str(xmax))
        ent3.insert(0,str(pasx))
        ent4.insert(0,str(ymin))
        ent5.insert(0,str(ymax))
        ent6.insert(0,str(pasy))
        can.create_rectangle(0,0,700,700,fill="white",outline="white")
        dx=float(xmax-xmin)
        dy=float(ymax-ymin)
        ux=700/dx
        uy=700/dy
        uxx=(dx/700)
        #Coordonnées du O(0,0):
        xo=ux*(-xmin)
        yo=uy*ymax
        # Axes:
        can.create_line(0,yo,700,yo,fill="red")
        can.create_line(xo,0,xo,700,fill="red")
        i=xo
        j=yo
        while i>-1:
            can.create_line(i,yo-2,i,yo+2,fill="red")
            i=i-(ux*pasx)
        while j>-1:
            can.create_line(xo-2,j,xo+2,j,fill="red")
            j=j-(uy*pasy)
        i=xo
        j=yo
        while i<701:
            can.create_line(i,yo-2,i,yo+2,fill="red")
            i=i+(ux*pasx)
        while j<701:
            can.create_line(xo-2,j,xo+2,j,fill="red")
            j=j+(uy*pasy)
        a=0
        g=len(save)
        while a<g:
            local=save[a]
            if len(local)==3:
                onDeriv(local[1],local[2],1)
            elif len(local)==2:
                onCalc(local[0],local[1],xo,yo,uy,uxx,xmin,1)
            a=a+1

def onFact():
    try:
        facteur=float(ent11.get())
    except ValueError:
        facteur=1.
    onZoom(facteur)

def Fact(event):
    try:
        facteur=float(ent11.get())
    except ValueError:
        facteur=1.
    onZoom(facteur)

def onCourbe(fichier,couleur,e):
    global can,flag,select,ent1,ent2,en3,ent4,ent5,ent6,col,lst1,a
    flag=0
    try:
            xmin=float(eval(ent1.get()))
    except SyntaxError:
            xmin=-10
    try:
            xmax=float(eval(ent2.get()))
    except SyntaxError:
            xmax=10
    try:
            pasx=float(eval(ent3.get()))
    except SyntaxError:
            pasx=1
    try:
            ymin=float(eval(ent4.get()))
    except SyntaxError:
            ymin=-10
    try:
            ymax=float(eval(ent5.get()))
    except SyntaxError:
            ymax=10
    try:
            pasy=float(eval(ent6.get()))
    except SyntaxError:
            pasy=1

    dx=float(xmax-xmin)
    dy=float(ymax-ymin)
    ux=700/dx
    uy=700/dy
    uxx=(dx/700)
    #Coordonnées du O(0,0):
    xo=ux*(-xmin)
    yo=uy*ymax
    i=xo
    j=yo

    file = open(fichier,"r")
    temp=str(file.read())
    temp=temp.replace(",",".")
    file.close()
    file=open(fichier,"w")
    file.write(temp)
    file.close()
    file=open(fichier,"r")
    a=0
    liste=[]
    try:
        while a<700:
            liste.append((file.readline().split(";")))
            try:
                liste[a][0]=float(liste[a][0])
            except:
                liste[a][0]=0
            try:
                liste[a][1]=float(liste[a][1])
            except IndexError:
                liste[a].append(0)
                
            a=a+1
        a=0
        while a<699:
            x1=int((liste[a][0]*uxx)+xo)
            y1=int(yo-(liste[a][1]*uy))
            x2=int((liste[a+1][0]*uxx)+xo)
            y2=int(yo-(liste[a+1][1]*uy))
            can.create_line(int(x1),int(y1),int(x2),int(y2),width=e,fill=col)
            a=a+1
    except :
        flag=1
        
def onCol(e):
    global col,fen,listd,labd,liste,lbl

    col=listd.get(listd.curselection())
    if col == "black":
        labd.configure(text=select)
        listd.configure(bg="ivory")

    else:
        labd.configure(text=col)
        listd.configure(bg=col)

        
def onColor(e):
    global pop,liste,lbl,select,listb,lab
    col=liste.get(liste.curselection())
    try:
        if col == "black":
            liste.configure(bg="ivory")
            lbl.configure(text=col)
            lab.configure(text=col)

        else:
            liste.configure(bg=col)
            lbl.configure(text=col)
            lab.configure(text=col)
        select=col
        listb.configure(bg=col)
    except :
        pass

def quitter(e):
    global fen
    fen.destroy()
    

def onImport():
    global fen,ent100,root,col,listd,labd,ent1,ent2,en3,ent4,ent5,ent6,ent101,ent102,ent103,ent104
    fen=Tk()
    fen.bind('<Escape>',quitter)
    lbl1=Label(fen,text="Importer un classeur au format .csv:")
    lbl2=Label(fen,text="Emplacement:")
    lbl3=Label(fen,text="Couleur :")
    lbl4=Label(fen,text="Xmin=")
    lbl5=Label(fen,text="Xmax=")
    lbl6=Label(fen,text="Ymin=")
    lbl7=Label(fen,text="Ymax=")
    ent100=Entry(fen)
    ent101=Entry(fen)
    ent102=Entry(fen)
    ent103=Entry(fen)
    ent104=Entry(fen)
    bou1=Button(fen,text="Parcourir",command=onSearch)
    bou2=Button(fen,text="Ok",command=Importer)
    bou3=Button(fen,text="Annuler",command=fen.destroy)

    listd=Listbox(fen)
    scrollbar = Scrollbar(fen)

    labd=Label(fen,text="_")
    listd.grid(row=2,column=1,rowspan=2)
    scrollbar.grid(row=2,column=2,rowspan=2)
    labd.grid(row=2,column=3,rowspan=2)
    # Insertion des éléments dans la liste:
    for  coul in  ["gray", "blue", "orange", "yellow", "green", "cyan", "red", "pink", "gold","green","purple","brown","black","beige","autres"]:
            listd.insert(END,coul)
                    
    # Un double click dans la liste appellera la fonction onSelect:		
    listd.bind('<Double-1>',onCol)
    listd.config(yscrollcommand=scrollbar.set)
    scrollbar.config(command=listd.yview)

    lbl1.grid(row=0,column=0,columnspan=3)
    lbl2.grid(row=1,column=0)
    lbl3.grid(row=2,column=0)
    lbl4.grid(row=4,column=0)
    lbl5.grid(row=4,column=2)
    lbl6.grid(row=5,column=0)
    lbl7.grid(row=5,column=2)
    ent101.grid(row=4,column=1)
    ent102.grid(row=4,column=3)
    ent103.grid(row=5,column=1)
    ent104.grid(row=5,column=3)
    ent100.grid(row=1,column=1,columnspan=2)
    bou1.grid(row=1,column=3)
    bou2.grid(row=6,column=2)
    bou3.grid(row=6,column=3)
    fen.title("Importation de données")
    fen.mainloop()

def onSearch():
    global fen,file,ent100
    file = tkFileDialog.askopenfilename(parent=fen,title='Choisissez le fichier .csv à importer:',filetypes = [("Tpus les fichiers", "*"),("Fichiers Excel","*.csv;*.prn")])
    ent100.insert(0,str(file))
    
def Importer():
    global fen,ent100,file,select,flag,ent101,ent102,ent103,ent104,save,root,compteur
    fichier=ent100.get()
    onCourbe(file,select,1)
    save.append([0,0,str(fichier),str(select)])
    lst1.insert(END,str(file)+" "+str(select))
    compteur=compteur+1

    try:
            xmin=float(eval(ent101.get()))
    except SyntaxError:
            xmin=-10
    try:
            xmax=float(eval(ent102.get()))
    except SyntaxError:
            xmax=10

    try:
            ymin=float(eval(ent103.get()))
    except SyntaxError:
            ymin=-10
    try:
            ymax=float(eval(ent104.get()))
    except SyntaxError:
            ymax=10
            
    ent1.insert(0,str(xmin))
    ent2.insert(0,str(xmax))
    ent4.insert(0,str(ymin))
    ent5.insert(0,str(ymax))
    onRefresh()
    
    fen.destroy()
    if flag==0:
        file = open(fichier,"r")
        temp=str(file.read())
        temp=temp.replace(".",",")
        file.close()
        file=open(fichier,"w")
        file.write(temp)
        file.close()
        tkMessageBox.showinfo(title="Importation",message="""Le classeur " """ + str(fichier) + """" a bien été importé.""")
        root.update()
    elif flag==1:
        tkMessageBox.showerror(title="Importation",message="""Une erreur est survenue lors de l'importation de " """ + str(fichier) + """" .""")
    

def onSurligne(e):
    global lst1,xmin,xmax,pasx,ymin,ymax,pasy,surline,choix

    dx=float(xmax-xmin)
    dy=float(ymax-ymin)
    ux=700/dx
    uy=700/dy
    uxx=(dx/700)
    #Coordonnées du O(0,0):
    xo=ux*(-xmin)
    yo=uy*ymax
    
    choix=lst1.get(lst1.curselection())
    choix=choix.split("  ")
    onRefresh()
    if len(choix)==2:
        onCourbe(choix[0],choix[1],2)
    elif len(choix)==3:
        onDeriv(choix[1],choix[2],2)
    elif len(choix)==4:
        onCalc(choix[2],choix[3],xo,yo,uy,uxx,xmin,2)

def pointeur(event):
    x=event.x
    y=event.y
    global chaine,uxx,xmin,ymin,xmax,ymax,pasx,pasy,uyy,coins,cadre,croix,selected,courbe,integer,bornes,borne1,borne2,lst1,choix
    
    erreur=False
    try:
        can.delete(croix[0],croix[1])
    except:
        pass
    
    if cadre==False and selected==False and integer==False:
        chaine.configure(text = "Clic détecté en X =" + str(xmin+(x)*uxx) +", Y =" + str(ymin+(700-y)*uyy))
        croix=[can.create_line(x-5,y,x+5,y,fill="red"),can.create_line(x,y-5,x,y+5,fill="red")]

    elif cadre==False and selected==True and integer==False:
        chaine.configure(text = "Point de la courbe en X =" + str(xmin+(x)*uxx) +", Y =" + str(ymin+(700-courbe[x])*uyy))
        croix=[can.create_line(x-5,courbe[x],x+5,courbe[x],fill="red"),can.create_line(x,courbe[x]-5,x,courbe[x]+5,fill="red")]

    elif cadre==False and selected==True and integer==True and len(bornes)==0:
        chaine.configure(text = "Calcul d'intégrale: Borne inférieure=" + str(xmin+(x)*uxx) +", Borne Supérieure")
        croix=[can.create_line(x-5,courbe[x],x+5,courbe[x],fill="red"),can.create_line(x,courbe[x]-5,x,courbe[x]+5,fill="red")]
        borne1=can.create_line(x,0,x,700,fill="Gray")
        bornes.append(x)

    elif cadre==False and selected==True and integer==True and len(bornes)==1:
        chaine.configure(text = "Calcul d'intégrale: Borne inférieure=" + str(xmin+(bornes[0])*uxx) +", Borne Supérieure=" + str(xmin+(x)*uxx))
        croix=[can.create_line(x-5,courbe[x],x+5,courbe[x],fill="red"),can.create_line(x,courbe[x]-5,x,courbe[x]+5,fill="red")]
        borne2=can.create_line(x,0,x,700,fill="Gray")
        bornes.append(x)
        
        if tkMessageBox.askokcancel('Confirmer','La borne inférieure est ' + str(xmin+(bornes[0])*uxx) + '\nLa borne supérieure est ' + str(xmin+(bornes[1])*uxx)):
    
            if len(choix)==2:
                couleur=choix[1]
            elif len(choix)==3:
                couleur=choix[2]
            elif len(choix)==4:
                couleur=choix[3]
            chaine.configure(text = "Calcul d'intégrale: Aire="+ str(integrale(courbe,bornes[0],bornes[1],couleur)) +" Borne inférieure=" + str(xmin+(bornes[0])*uxx) +", Borne Supérieure=" + str(xmin+(x)*uxx))

        else:
            chaine.configure(text = "Cliquez sur le graphique pour afficher les coordonnées d'un point.")
            onRefresh()
                             
        can.delete(borne1,borne2)
                             

    elif len(coins)==0 and selected==False and integer==False:
        coins.append([xmin+x*uxx , ymin+(700-y)*uyy])
        croix=[can.create_line(x-5,y,x+5,y,fill="red"),can.create_line(x,y-5,x,y+5,fill="red")]

    elif len(coins)==1 and selected==False and integer==False:
        coins.append([xmin+x*uxx , ymin+(700-y)*uyy])

        ent1.delete(0,len(str(xmin)))
        ent2.delete(0,len(str(xmax)))
        ent4.delete(0,len(str(ymin)))
        ent5.delete(0,len(str(ymax)))
        
        x1,y1,x2,y2=coins[0][0],coins[0][1],coins[1][0],coins[1][1]
        
        if x1<x2:
            ent1.insert(0,str(x1))
            ent2.insert(0,str(x2))

        elif x2<x1:
            ent1.insert(0,str(x2))
            ent2.insert(0,str(x1))

        else:
            erreur=True
            tkMessageBox.showerror(title="Erreur",message="""Cadre d'épaisseur nulle. \n Les coordonnées d'origine seront restaurées""")
            ent1.delete(0,len(str(xmin)))
            ent2.delete(0,len(str(xmax)))
            ent3.delete(0,len(str(pasx)))
            ent4.delete(0,len(str(ymin)))
            ent5.delete(0,len(str(ymax)))
            ent6.delete(0,len(str(pasy)))
            ent1.insert(0,str(-10))
            ent2.insert(0,str(10))
            ent3.insert(0,str(1))
            ent4.insert(0,str(-10))
            ent5.insert(0,str(10))
            ent6.insert(0,str(1))
            
        if y1<y2:    
            ent4.insert(0,str(y1))
            ent5.insert(0,str(y2))

        elif y2<y1:    
            ent4.insert(0,str(y2))
            ent5.insert(0,str(y1))

        elif erreur!=True:
            tkMessageBox.showerror(title="Erreur",message="""Cadre d'épaisseur nulle. \n Les coordonnées d'origine seront restaurées""")
            ent1.delete(0,len(str(xmin)))
            ent2.delete(0,len(str(xmax)))
            ent3.delete(0,len(str(pasx)))
            ent4.delete(0,len(str(ymin)))
            ent5.delete(0,len(str(ymax)))
            ent6.delete(0,len(str(pasy)))
            ent1.insert(0,str(-10))
            ent2.insert(0,str(10))
            ent3.insert(0,str(1))
            ent4.insert(0,str(-10))
            ent5.insert(0,str(10))
            ent6.insert(0,str(1))

        coins=[]
        erreur=False
        cadre=False
        chaine.configure(text = "Clic détecté en X =" + str(xmin+(x)*uxx) +", Y =" + str(ymin+(700-y)*uyy))
        onRefresh()

    else:
        chaine.configure(text = "Choisir une Courbe")
        
def onCadre():
    global chaine,cadre,coins,croix
    chaine.configure(text = "Zoom par Cadre: définissez les deux coins du cadre")
    cadre=True
    try:
        can.delete(croix[0],croix[1])
    except:
        croix=[can.create_line(0,350,700,350,fill="red"),can.create_line(350,0,350,700,fill="red")]
    coins=[]

def integrale(courbe,inff,supp,couleur):
    global uxx,uyy,ymin,xo
    aire=0
    largeur=abs(supp-inff)
    if inff<supp:
        positif,erreur=True,False
        inf,sup=inff,supp
        
    elif inff>supp:
        inf,sup=supp,inff
        positif,erreur=False,False

    else:
        erreur,positif=True,True

    if erreur==False:        
        a=inf
        while a<sup+1:
            try:
                can.create_line(a,xo,a,courbe[a],fill=couleur)
                aire=aire+(ymin+(700-courbe[a])*uyy)*uxx
            except:
                pass
            a=a+1
            
    if positif==True:
        return aire

    elif positif==False:
        return -aire

    elif erreur==True:
        return 0

def onInteger():
    global chaine,integer,bornes,coins,pop,inff,supp
    if tkMessageBox.askyesno('Information','Voulez-vous entrer les bornes au clavier ?'):
        pop=Tk()
        lbl1=Label(pop,text="Borne inférieure =")
        lbl2=Label(pop,text="Borne supérieure =")
        inff=Entry(pop)
        supp=Entry(pop)
        inff.bind("<Return>",Take)
        supp.bind("<Return>",Take)
        bou=Button(pop,text="Ok",command=onTake)
        lbl1.grid(row=0,column=0)
        lbl2.grid(row=1,column=0)
        inff.grid(row=0,column=1)
        supp.grid(row=1,column=1)
        bou.grid(row=2,column=0,columnspan=2)

    else:
        chaine.configure(text = "Calcul d'intégrale: Borne inférieure")
        integer=True
    bornes=[]
    coins=[]

def Take(e):
    onTake()
    
def onTake():
    global pop,lst1,chaine,inff,supp,choix,xmin,uxx
    try:
        bornes=[int((eval(inff.get())*uy)+yo),int((eval(supp.get())*uy)+yo)]

    except:
        tkMessageBox.showerror(title="Erreur",message="""Champs incomplets""")
        
    try:
        if len(choix)==2:
            couleur=choix[1]
        elif len(choix)==3:
            couleur=choix[2]
        elif len(choix)==4:
            couleur=choix[3]
    except:
        tkMessageBox.showerror(title="Erreur",message="""Veuillez choisir une courbe""")

    chaine.configure(text = "Calcul d'intégrale: Aire=" + str(integrale(courbe,bornes[0],bornes[1],couleur)) + ", Borne inférieure=" + str(xmin+(bornes[0])*uxx) +", Borne Supérieure=" + str(xmin+(bornes[1])*uxx))
    pop.destroy()

def onClose():
    try:
        root.destroy()
    except:
        pass
    try:
        divide.destroy()
    except:
        pass

############################### Fonctions Mathématiques ###############################

def H(x):
    return (atan(x)+atan(1/x)+(pi/2))/pi

def SH(x):
    return (exp(x)-exp(-x))/2

def CH(x):
    return (exp(x)+exp(-x))/2

def TH(x):
    return SH(x)/CH(x)

def aSH(x):
    return log((x+sqrt(1+x**2)),exp(1))

def aCH(x):
    return log((x+sqrt(-1+x**2)),exp(1))

def aTH(x):
    return (-1+x**2)/(1+x**2)

def h(x):
    return (atan(x)+atan(1/x)+(pi/2))/pi

def sh(x):
    return (exp(x)-exp(-x))/2

def ch(x):
    return (exp(x)+exp(-x))/2

def th(x):
    return SH(x)/CH(x)

def ash(x):
    return log((x+sqrt(1+x**2)),exp(1))

def ach(x):
    return log((x+sqrt(-1+x**2)),exp(1))

def ath(x):
    return (-1+x**2)/(1+x**2)

def ln(x):
    return log(x,exp(1))

#######################################################################################

################################# Interface Graphique #################################
root=Tk()

if root.winfo_screenwidth()>1024:           #Ajuste la présentation du programme à la résolution de l'écran
    divide=root
    can=Canvas(divide,width=700,height=700)
else:
    self=Tk()
    divide=self
    can=Canvas(divide,width=700,height=700)
    
can.bind("<Button-1>", pointeur)
can.create_rectangle(0,0,700,700,fill="white",outline="black")
can.grid (row=0,column=0,rowspan=30)

chaine=Label(divide,text="Cliquez sur le graphique pour afficher les coordonnées d'un point.")
chaine.grid(row=30,column=0)

lbl1=Label(root,text="Configuration de la fenètre de traçage:")
lbl2=Label(root,text="Xmin =")
lbl3=Label(root,text="Xmax =")
lbl4=Label(root,text="Ymin =")
lbl5=Label(root,text="Ymax =")
lbl6=Label(root,text="Pas =")
lbl7=Label(root,text="Pas =")

listb=Listbox(root)
scrollbar = Scrollbar(root)

lab=Label(root,text="_")
listb.grid(row=10,column=2,rowspan=5)
scrollbar.grid(row=10,column=3,rowspan=5)
lab.grid(row=10,column=1)
# Insertion des éléments dans la liste:
for  coul in  ["gray", "blue", "orange", "yellow", "green", "cyan", "red", "pink", "gold","green","purple","brown","black","autres"]:
        listb.insert(END,coul)
		
# Un double click dans la liste appellera la fonction onSelect:		
listb.bind('<Double-1>',onSelect)
listb.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=listb.yview)

ent1=Entry(root)
ent2=Entry(root)
ent3=Entry(root)
ent4=Entry(root)
ent5=Entry(root)
ent6=Entry(root)
bou1=Button(root,text="Nouvelle trace",command=onInit)
bou2=Button(root,text="Quitter",command=onClose)
bou3=Button(root,text="Ajouter trace",command=onAdd)
bou4=Button(root,text="Tracer dérivée",command=onDerive)
bou5=Button(root,text="Aide",command=onHelp)
bou6=Button(root,text="Rafraichir",command=onRefresh)
bou7=Button(root,text="Importer des Données",command=onImport)
bou8=Button(root,text="Calcul d'intégrale",command=onInteger)

bou1.grid(row=28,column=1)
bou2.grid(row=29,column=2)
bou3.grid(row=27,column=1)
bou4.grid(row=27,column=2)
bou5.grid(row=29,column=1)
bou6.grid(row=28,column=2)
bou7.grid(row=26,column=2)
bou8.grid(row=26,column=1)
lbl1.grid(row=0,column=1,columnspan=2)
lbl2.grid(row=1,column=1)
lbl3.grid(row=2,column=1)
lbl4.grid(row=4,column=1)
lbl5.grid(row=5,column=1)
lbl6.grid(row=3,column=1)
lbl7.grid(row=6,column=1)

ent1.grid(row=1,column=2)
ent2.grid(row=2,column=2)
ent3.grid(row=3,column=2)
ent4.grid(row=4,column=2)
ent5.grid(row=5,column=2)
ent6.grid(row=6,column=2)

ent1.bind ("<Return>",Refresh)
ent2.bind ("<Return>",Refresh)
ent3.bind ("<Return>",Refresh)
ent4.bind ("<Return>",Refresh)
ent5.bind ("<Return>",Refresh)
ent6.bind ("<Return>",Refresh)

lbl10=Label(root,text="Configuration du Grapheur:")
lbl11=Label(root,text="f(x)=")

ent10=Entry(root)
ent10.bind("<Return>",Add)

lbl10.grid(row=8,column=1,columnspan=2)
lbl11.grid(row=9,column=1)
ent10.grid(row=9,column=2)
ent11=Entry(root)
bou10=Button(root,text="Zoom x2",command=lambda arg=2.:onZoom(arg))
bou11=Button(root,text="Zoom x4",command=lambda arg=4.:onZoom(arg))
bou12=Button(root,text="Zoom /2",command=lambda arg=0.5:onZoom(arg))
bou13=Button(root,text="Zoom /4",command=lambda arg=0.25:onZoom(arg))
bou14=Button(root,text="Zoom par facteur",command=onFact)
bou15=Button(root,text="Zoom Initial",command=lambda arg="init":onZoom(arg))
bou16=Button(root,text="Zoom par Cadre",command=onCadre)
bou10.grid(row=20,column=1)
bou11.grid(row=20,column=2)
bou12.grid(row=21,column=1)
bou13.grid(row=21,column=2)
bou14.grid(row=22,column=1)
bou15.grid(row=23,column=1)
bou16.grid(row=23,column=2)

ent11.grid(row=22,column=2)
ent11.bind("<Return>",Fact)

lst1=Listbox(root)
bar = Scrollbar(root)
bar2 = Scrollbar(root,orient = HORIZONTAL)

bar.grid(row=1,column=5,rowspan=5)
bar2.grid(row=6,column=4)
		
lst1.bind('<Double-1>',onSurligne)
lst1.config(yscrollcommand=bar.set)
lst1.config(xscrollcommand=bar2.set)
bar.config(command=lst1.yview)
bar2.config(command=lst1.xview)

title=Label(root,text="Historique :")
title.grid(row=0,column=4)
lst1.grid(row=1,column=4,rowspan=5)

onInit()

root.resizable(False,False)
divide.resizable(False,False)
root.title("Paramètres Grapheur")
divide.title("Tracés Grapheur")
divide.protocol("WM_DELETE_WINDOW", onClose)
root.protocol("WM_DELETE_WINDOW", onClose) 

root.mainloop()
divide.mainloop()

#######################################################################################

Conclusion :


Très pratique si un PC portable doit remplacer une calculatrice graphique.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.