This file is indexed.

/usr/share/pyshared/pyacidobasic/acidebase.py is in python-acidobasic 2.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#-*- coding: utf-8 -*-


licence="""
    file acidebase.py: part of the package pyacidobasic version %s:

    Copyright (C) 2010 Georges Khaznadar <georgesk@ofset.org>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

from PyQt4.QtCore import *
from HTMLParser import *
from xml.dom.minidom import *
import PyQt4.Qwt5.anynumpy as np

class abHTMLparser(HTMLParser):
    """
    un analyseur de code HTML capable de construire une liste d'acides
    et de bases
    """
    def __init__(self,liste):
        HTMLParser.__init__(self)
        self.liste=liste
        self.ligne=False
        self.d=False
        self.input=""
        
    def handle_starttag(self, tag, attrs):
        if tag=="tr" :
            self.ligne=True
            self.ab=acideBase()
            self.gotAb=None
        elif tag=="td":
            self.d=True
            self.input=""
            if self.ligne:
                if self.gotAb == None: self.gotAb=0
                else: self.gotAb+=1
        elif self.ligne and self.d and (tag=="sup" or tag=="sub"):
            self.input+="<"+tag+">"
                
    def handle_data(self, data):
        if self.ligne and self.d:
            self.input+=data
            
    def handle_endtag(self, tag):
        if tag=="tr" :
            if self.gotAb:
                self.liste.append(self.ab)
            self.ligne=False
        elif tag=="td":
            #retire les retours à la ligne intempestifs
            self.input = self.input.strip()
            if self.gotAb==0:
                formes=self.input.split(',')
                self.ab.formes=[]
                for f in formes:
                    f=unicode(f,"utf-8")
                    self.ab.formes.append(QString(f))
            elif self.gotAb==1:
                self.ab.formeIndex=   int(self.input)
            elif self.gotAb==2:
                self.ab.nom= QString(unicode(self.input,"utf-8"))
            elif self.gotAb==3:
                pKs=self.input.split(",")
                self.ab.pK=[]
                for pK in pKs:
                    self.ab.pK.append(float(pK))
            elif self.gotAb==4:
                self.ab.c= float(self.input)
            elif self.gotAb==5:
                self.ab.charge= int(self.input)
            else:
                raise Exception(rangeError, u"trop de données dans le fichier d'entrée")
            self.d=False
        elif self.ligne and self.d and (tag=="sup" or tag=="sub"):
            self.input+="</"+tag+">"


class acideBase:
    def __init__(self, formes=["AH","A<sup>-</sup>"], formeIndex=0, nom="acide générique", pK=[3.5], c=1.0, charge=0, v=0.0, other=None):
        """
        objet représentant un couple acido-basique
        @param formes la liste des formes acido-basiques conjuguées
        @param formeIndex la forme de base
        @param nom désignation de la forme de base
        @param pK liste des constantes d'acidité
        @param c concentration initiale en mol/L
        @param charge charge électrique de la forme acide en unité élémentaire
        @param v volume en mL
        @param other une instance d'acideBase à recopier
        """
        if other !=None:
            self.formes=other.formes
            self.formeIndex=other.formeIndex
            self.nom=other.nom
            self.pK=other.pK
            self.c=other.c
            self.charge=other.charge
            self.v=other.v
        else:
            self.formes=formes
            self.formeIndex=formeIndex
            self.nom=nom
            self.pK=pK
            self.c=c
            self.charge=charge
            self.v=v

    def copie(self):
        return acideBase(self.formes, self.formeIndex, self.nom, self.pK,  self.c, self.charge, self.v)

    def __str__(self):
        return "%s;%s;%s;%s;%s;%s;%s" %(self.formes,
                                         self.formeIndex,
                                         self.nom.toUtf8(),
                                         self.pK,
                                         self.c,
                                         self.charge,
                                         self.v)

    def concentrationParPH(self, espece, pHData, vTotal, vBurette=None):
        """
        @param espece un index dans self.formes
        @param pHData un array (numpy) de données de pH
        @param vTotal un vecteur de volume total de la solution en unité mL
        @param vBurette un vecteur de volumes versés en unité mL, ou None si on s'intéresse au bécher
        @return un array de données pour la concentration de l'espèce en fonction du pH
        """
        result=np.ones(len(pHData))
        for i in range(len(pHData)):
            if vBurette!=None:
                verse=vBurette[i]
            else:
                verse=None
            result[i]=self.ni(pHData[i],
                              vBurette=verse)[espece]*1e3/vTotal[i]
        return result
    
    def chargeNette(self,pH):
        """
        @param pH : le pH
        @return la charge électrique en Faraday en fonction du pH
        """
        ni=self.ni(pH)
        ch=self.charge # on considère la charge de l'espèce acide
        result=0.0
        # on calcule d'abord la concentration de charges
        for n in ni:
            result+=n*ch # on cumule la charge de l'espèce acide
            ch-=1        # et on passe à la base conjuguée
        return result

    def ni(self,pH, vBurette=None):
        """
        renvoie la liste des quantités des formes acido-basiques
        @param pH : le pH
        @param vBurette volume versé, ou None si ce n'est pas de la burette que vient le produit
        @return la liste des quantités de formes acido-basiques
        """
        n=np.ones(1+len(self.pK)) # liste des quantités des espèces
        total=1.0                 # concentration totale
        for i in range(len(self.pK)):
            c=n[i]*10**(pH-self.pK[i])
            n[1+i]=c
            total+=c
        # On normaliste pour que la quantité totale soit self.c*self.v*1e-3
        if vBurette!=None:
            n *= self.c*vBurette*1e-3/total
        else:
            n *= self.c*self.v*1e-3/total
        return n
    
def fromString(s):
    s=s.split(";")
    ab=acideBase()
    formes=s[0].split(',')
    ab.formes=[]
    for f in formes:
        f=unicode(f,"utf-8")
        ab.formes.append(QString(f))
    ab.formeIndex=   int(s[1])
    ab.nom=          QString(unicode(s[2],"utf-8"))
    pKs=s[3].split(",")
    ab.pK=[]
    for pK in pKs:
        ab.pK.append(float(pK))
    ab.c= float(s[4])
    ab.charge= int(s[5])
    return ab

def listFromString(s):
    liste=[]
    for ligne in s.split("\n"):
        try:
            acideOuBase=fromString(ligne)
            liste.append(acideOuBase)
        except:
            pass
    return liste

def listFromHTML(s):
    """
    remplit une liste d'acides/bases à partir de code HTML
    """
    liste=[]
    p=abHTMLparser(liste)
    p.feed(s)
    return liste

class abDOZparser:
    """
    classe pour un analyseur de fichier .equ de dozzaqueux
    """
    def __init__(self, liste):
        """
        Le constructeur
        @ param liste référence d'une liste que l'analyseur va allonger
        """
        self.liste=liste
        self.doc=None     # racine du document
        self.el=[]        # liste d'éléments de la base de donnée

    def feed(self, s):
        """
        digère le contenu d'un fichier .qu de dozzaqueux
        """
        if s[:5]!='<Doz>':
            s=xmlizeDoz(s)
        self.doc=parseString(s)
        self.el=self.doc.getElementsByTagName("Element")
        print "GRRR"
        self.lesAcides()
        
    def lesAcides(self):
        """
        extrait les composés de la base qui ont un comportement acido-basique
        """
        for e in self.el:
            lk=e.getElementsByTagName("Log_K")
            if lk:
                lk=lk[0].firstChild.nodeValue.strip().split("\n")
                i=e.getElementsByTagName("Identifiant")[0]
                nom=i.firstChild.nodeValue.strip().encode("utf-8")
                attributs=e.getElementsByTagName("Composition")[0].firstChild.nodeValue.strip().split("\n")
                print "GRRR", nom, lk, attributs
    

def xmlizeDoz(s):
    """
    change un fichier dozzaqueux de type .equ pour en faire un fichier
    xml valide. Testé avec la version 119 du fichier base.equ
    """
    s="<Doz>\n"+s+"</Doz>\n" # établit une racine unique
    s=s.replace("Representant de l'element", "Representant")
    s=s.replace("Atomes constitutifs","Atomes_constitutifsq")
    s=s.replace("Log K","Log_K")
    return s

def listFromDozzaqueux(s):
    """
    remplit une liste d'acides/bases à partir de code Dozzaqueux
    """
    liste=[]
    p=abDOZparser(liste)
    p.feed(s)
    return liste

def listFromFile(fname):
    p=fname.find("html")
    if p>0:
        return listFromHTML(open(fname,"r").read(2000000))
    p=fname.find("equ")
    if p>0:
        return listFromDozzaqueux(open(fname,"r").read(2000000))
    return listFromString(open(fname,"r").read(2000000))
                

if __name__=="__main__":
    import sys
    print listFromFile(sys.argv[1])