Bonjour à tous,

Voilà, j'ai un graphique avec des valeurs précises ( ca = 0.01,cb = 0.01 et va = 10.0). J'ai voulu réalisé une interface tkinter permettant à l'utilisateur de pouvoir choisir les valeurs qu'il souhaite et une fois celles-ci entrées, le graphique se créé. Le problème, c'est que à chaque fois il me met que c'est un problème de math ou que une de mes valeurs n'est pas défini..
Voici le programme :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
 
#!/usr/bin/env python
#-*- coding: utf-8 -*-
 
import numpy as np #Importation d'une extention de la librairie matplotlib : numpy.
#NumPy est une extension du language de programmation Python, destinée à manipuler des matrices ou tableaux multidimensionnels ainsi que des fonctions mathématiques opérant sur ces tableaux.
import math
from matplotlib.pyplot import * #Importation d'une librairie supplémentaire : matplotlib.
#Matplotlib est une librairie permettant de tracer des graphiques pour le langage de programmation Python. Il utilise une extension de mathématiques numérique : NumPy.
from Tkinter import * #Tkinter est la bibliothèque graphique libre d'origine pour le language Python, permettant la création d'interfaces graphiques.
 
 
def volume(pK,ca,va,cb,ph): #On définit la fonction "volume" dépendant du pka de l'acide (pK), de la concentration initiale de ce dernier (ca), son volume initial(va), la concentration initiale en titrant (cb) et le pH.
                            #Cette fonction fait le calcul des concentrations et des volumes à une valeur de pH donnée.
                            #Le but de cette première partie de code est de traduire en language python les équations d'échanges protoniques et de conservation de masse de notre problème.
    n = len(pK)             #pK est une liste contenant 3 éléments ( qui sont les pka de notre polyacide). la fonction "len" appliquée à pK nous renvoie le nombre d'éléments n compris dans cette liste.
                            #Ainsi, n correspond au nombre maximal de protons que le polyacide peut libérer.
    Ke = 1.0e-14            #On pose que Ke correspond au produit ionique de l'eau.
    h = 10**(-ph)           #On pose que h correspond à la concentration en ion H+ présent dans le milieu.
    c = np.ones(n+1)        #On définit c comme étant une matrice constituée de n + 1 colonnes, 1 ligne et uniquement remplies de 1.
    Da = 1                  #On pose que Da correspond au coefficient de distribution de la base conjuguée (phosphate) provenant du titré. Sa forme actuelle ne correspond pas encore à celle dans nos calculs.
    kk = 1                  
    for p in range(1,n+1):  #Nous devons définir Da comme étant égale à la somme de 4 termes (d'où cette largeur de "range"). Pour tout élément p dans une liste allant de 1 à n+1.
        kk *= 10**(-pK[p-1])#kk est ici redéfini comme étant un produit de constantes de dissociation, et cela en  multipliant kk = 1 par des Ka.
        x = h**p/kk         
        c[p] = x            #????
        Da += x             #On incrémente à la variable Da = 1, la variable x = c[p]
    Na = n                  #Tout comme Da, Na est introduit afin d'alléger l'écriture de nos calculs. Sa forme actuelle ne correspond pas encore à celle de nos calculs.
    kk = 1
    for p in range(1,n):    #Nous devons définir Na comme étant égale à la somme de 3 termes (d'où cette largeur de "range").
        kk *= 10**(-pK[p-1])#idem que précédemment.   
        Na += (n-p)*h**p/kk #On incrémente à la variable Na = n la variable (n-p)*h**p/kk.  
    y = Ke/h-h                  #Comme Ke/h correspond à la concentration en ion hydroxyde, y correspond à [H3O+] - [OH-].
    vb = va*(y+Na*ca/Da)/(cb-y) #Au final, par ce raisonnement, nous réussissons à exprimer vb uniquement au départ de constantes et de h.
    for p in range(n+1):
        c[p] *= ca*va/(va+vb)/Da
    return [vb,c]
 
def plot_pH(pK,ca,va,cb,vb_max): # On définit une fonction "graphique" qui va nous permettre de créer le graphique de titrage. Les paramètres de cette fonction sont les pK, ca, va, cb et vb_max.
    npts = 1000                  # On définit le nombre de points que va contenir notre graphique afin de le tracer avec une assez bonne précision.
    pH = np.zeros(npts)          # On définit pH comme étant une matrice constituée de 1000 colonnes (npts), 1 ligne et uniquement remplies de 0. 
    vb = np.zeros(npts)          # On définit vb comme étant une matrice constituée de 1000 colonnes (npts), 1 ligne et uniquement remplies de 0. 
    ph_max = 14+math.log10((vb_max*cb-ca*va)/(vb_max+va)) # On définit le pH maximum (ph_max) de notre titrage par la formule d'une base forte (ici, le titrant) qui sera en excès en solution une fois l'acide complètement neutralisé.
                                                          # Le volume maximum (vb_max) de la base (titré) est choisi arbitrairement plus tard.
    dph = ph_max/(npts-1)        # 
    for i in range(npts):
        ph = dph*i
        [vb[i],c] = volume(pK,ca,va,cb,ph)
        pH[i] = ph
    plot(vb,pH)
    axis([0,vb_max,0,14])
    xlabel("Volume de NaOH (mL)")
    ylabel("pH")
    ax = gca()
    ax.barh(3.1, vb_max, height=1.3, color='orange', label=u"hélianthine")
    ax.barh(8.2, vb_max, height=1.8, color='red', label=u"phénolphtaléine")
    legend(loc=2)
    ax.annotate(u'1ère équivalence', xy=(10., 4.65),  xycoords='data',
                xytext=(15.,5.), textcoords='data',
                bbox=dict(boxstyle="round", fc="#0FE3E3"),
                arrowprops=dict(arrowstyle="->",
                                connectionstyle="arc3"),)
    ax.annotate(u'2ème équivalence', xy=(20., 9.2),  xycoords='data',
                xytext=(5.,9.), textcoords='data',
                bbox=dict(boxstyle="round", fc="#0FE3E3"),
                arrowprops=dict(arrowstyle="->",
                                connectionstyle="arc3"),)
    ax.annotate('[$H_3PO_4$] = [$H_2PO_4^-$]', xy=(5., 2.7),  xycoords='data',
                xytext=(5.,1.), textcoords='data',
                bbox=dict(boxstyle="roundtooth", fc="#2EF075"),
                arrowprops=dict(arrowstyle="->",
                                connectionstyle="arc3"),)
    ax.annotate('[$H_2PO_4^-$] = [$HPO_4^{2-}$]', xy=(15., 7.2),  xycoords='data',
                xytext=(20.,6.7), textcoords='data',
                bbox=dict(boxstyle="roundtooth", fc="#2EF075"),
                arrowprops=dict(arrowstyle="->",
                                connectionstyle="arc3"),)
    ax.annotate('[$HPO_4^{2-}$] = [$PO_4^{3-}$]', xy=(25., 11.1),  xycoords='data',
                xytext=(22.,12.7), textcoords='data',
                bbox=dict(boxstyle="roundtooth",fc='#2EF075'),
                arrowprops=dict(arrowstyle="->",
                                connectionstyle="arc3"),)
 
pK = [12.1,7.2,2.15]
 
ca=np.arange(0.,1.,10) #intervalle de valeur des volumes (m3)
cb=np.arange(0.,1.,10)#intervalle de valeur des pressions voulues (Pa)
vb_max = 40.0
va=np.arange(0.,40.,40)
(vb_max*cb>ca*va)
 
figure(figsize=(8,5))
vb_max = 40.0
plot_pH(pK,ca,va,cb,vb_max)
grid()
title("Titrage de l'acide phosphorique ($H_3PO_4$) par la soude (NaOH)")
 
def plot_dis(pK,ca,va,cb,vb_max):
    npts = 1000
    n = len(pK)
    vb = np.zeros(npts)
    dis = np.zeros((n+1,npts))
    ph_max = 14+math.log10((vb_max*cb-ca*va)/(vb_max+va))
    dph = ph_max/(npts-1)
    for i in range(npts):
        ph = dph*i
        [vb[i],c] = volume(pK,ca,va,cb,ph)
        for p in range(n+1):
            dis[p][i] = c[p]*(vb[i]+va)/(ca*va)*100
    for p in range(0,n+1):
        s1 = "H_{"+str(p)+"}"
        if p==0:
            s1 = ""
        elif p==1:
            s1 = "H"
        s2 = "A^{"+str(n-p)+"-}"
        if n-p==0:
            s2 = "A"
        elif n-p==1:
            s2 = "A^-"
        plot(vb,dis[p],label="$"+s1+s2+"$")
 
    axis([0,vb_max,0,100])
    xlabel("Volume de NaOH (mL)")
    ylabel(u"Pourcentage de chaque espèce phosphorée (%)")
 
figure(figsize=(8,5))
plot_dis(pK,ca,va,cb,vb_max)
legend(loc=7)
grid()
title(u"Diagramme de distribution des espèces")
 
fen = Tk() #création de l'interface graphique où l'on va mettre les données
fen.title('Valeur de ca, cb et va') # donne un titre à la fenêtre
fen.geometry('470x160') #permet de régler les dimensions de la fenêtre de données
CA = Label(fen, text= "Valeur de ca:") #La commande Label permet de mettre du texte et ainsi nommer les cellules qui serviront à insérer les données
CB = Label(fen, text= "Valeur de cb:")     
VA = Label(fen, text= "Valeur de va:") 
CA.grid(row=1, sticky=W) # la commande grid permet de donner la position voulue dans l'interface                                
CB.grid(row=2, sticky=W)                                                                  
VA.grid(row=3, sticky=W)
ca= Entry(fen) #crée une cellule d'écriture
cb= Entry(fen)
va= Entry(fen)
ca.grid(row=2, column=1)
cb.grid(row=3, column=1)
va.grid(row=4, column=1)
 
b=Button(fen,text="Graphe",command=plot_pH)
b.grid(row=7, column=0)
show()
mainloop() # permet le démarrage du programme
J'ai essayé plusieurs alternatives mais je n'ai toujours pas trouvé..
Quelqu'un saurait-il m'aider ?

Merci d'avance