import re
from pylab import *
class Thermochimie:
    def __init__(self,dataFile):
        f = open(dataFile,"r") 
        self.data = {}
        for line in f.readlines():
            li = line.strip()
            t = re.split('[\s]+',li)
            if len(t)==3:
                self.data[t[0]]={'H':float(t[1]),'S':float(t[2])}
        f.close()
    def somme(self,som):
        sum = som.replace("+}","@")
        sum = sum.replace("^+","^@")
        cliste = re.split("\+",sum)
        H = 0
        S = 0
        for c in cliste:
            a = re.split("\*",c)
            if len(a)==2:
                coef = float(a[0])
                nom = a[1]
            else:
                coef = 1
                nom = a[0]
            nom = nom.replace("@","+}")
            nom = nom.replace("^@","^+")
            if self.data.has_key(nom):
                H = H + coef*self.data[nom]['H']
                S = S + coef*self.data[nom]['S']
            else:
                print "Erreur : le compose %s n'est pas dans la table de donnees"%nom
                raise SystemExit
        return [H,S]
    def reaction(self,equation):
        [reactifs,produits]=re.split("=",equation)
        [Hp,Sp]=self.somme(produits)
        [Hr,Sr]=self.somme(reactifs)
        return [Hp-Hr,Sp-Sr]
class EnthalpieLibre:
    def __init__(self,thermo,reactionsFile):
        self.thermo = thermo
        self.reaction = {}
        f = open(reactionsFile,"r")
        for line in f.readlines():
            li = line.strip()
            t = re.split('[\s]+',li)
            if len(t)==5:
                n = int(t[3])
                equation = t[0]
                texte = t[2]
                marker = t[4]
                a = re.split('=|,',t[1]) 
                Tmin = float(a[1]) 
                Tmax = float(a[2])
                if not self.reaction.has_key(n):
                    self.reaction[n] = []
                self.reaction[n].append([equation,Tmin,Tmax,texte,marker])
        f.close()
    def plot(self,n,color):
        for e in self.reaction[n]:
            equation = e[0]
            Tmin = e[1]
            Tmax = e[2]
            texte = e[3]
            mark = e[4]
            [DH,DS] = self.thermo.reaction(equation)
            G1 = DH-DS*1e-3*Tmin
            G2 = DH-DS*1e-3*Tmax
            plot([Tmin,Tmax],[G1,G2],color=color)
            if mark=="T":
                scatter([Tmax],[G2],color=color,marker='o')
            if texte=='O' or texte=='o':
                eq = equation.replace("*","")
                text(Tmax,G2,r'$\rm %s$'%eq,color=color,size=12)
    def gstandard(self,n,T):
        G = 0
        for e in self.reaction[n]:
            equation = e[0]
            Tmin = e[1]
            Tmax = e[2]
            if (T>=Tmin) and (T<=Tmax):
                [DH,DS] = self.thermo.reaction(equation)
                G = DH-DS*1e-3*T
        return G
