Salome HOME
premiere version
[tools/eficas.git] / Noyau / N_FONCTION.py
1 # -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2013   EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 # Attention : cet import permet d'avoir, en Python, le comportement
22 # de la division réelle pour les entiers, et non la division entière
23 # 1/2=0.5 (et non 0). Comportement par défaut dans Python 3.0.
24 from __future__ import division
25 from math import sin, cos, tan, asin, acos, atan2, atan, sinh, cosh, tanh
26 from math import pi, exp, log, log10, sqrt
27
28 from N_ASSD import ASSD
29 from N_info import message, SUPERV
30
31 class FONCTION(ASSD):
32     pass
33
34 class formule(ASSD):
35     def __init__(self, *args, **kwargs):
36         ASSD.__init__(self, *args, **kwargs)
37         self.nompar = None
38         self.expression = None
39         ctxt = {}
40         ctxt.update(getattr(self.parent, 'const_context', {}))
41         ctxt.update(getattr(self.parent, 'macro_const_context', {}))
42         self.parent_context = self.filter_context(ctxt)
43         #message.debug(SUPERV, "add parent_context %s %s", self.nom, self.parent_context)
44
45     def __call__(self, *val):
46         """Evaluation de la formule"""
47         # en POURSUITE, self.parent_context is None, on essaie de reprendre const_context
48         context = getattr(self, 'parent_context') or getattr(self.parent, 'const_context', {})
49         for param, value in zip(self.nompar, val):
50             context[param] = value
51         try:
52             # globals() pour math.*
53             res = eval(self.code, context, globals())
54         except Exception, exc:
55             message.error(SUPERV, "ERREUR LORS DE L'ÉVALUATION DE LA FORMULE '%s' " \
56                           ":\n>> %s",self.nom, str(exc))
57             raise
58         return res
59
60     def setFormule(self, nom_para, texte):
61         """Cette methode sert a initialiser les attributs
62         nompar, expression et code qui sont utilisés
63         dans l'évaluation de la formule."""
64         self.nompar = nom_para
65         self.expression = texte
66         try :
67             self.code = compile(texte, texte, 'eval')
68         except SyntaxError, exc:
69             message.error(SUPERV, "ERREUR LORS DE LA CREATION DE LA FORMULE '%s' " \
70                           ":\n>> %s", self.nom, str(exc))
71             raise
72
73     def __setstate__(self,state):
74         """Cette methode sert a restaurer l'attribut code lors d'un unpickle."""
75         self.__dict__.update(state)                   # update attributes
76         self.setFormule(self.nompar, self.expression) # restore code attribute
77
78     def __getstate__(self):
79         """Pour les formules, il faut enlever l'attribut code qui n'est
80         pas picklable."""
81         d = ASSD.__getstate__(self)
82         del d['code']
83         return d
84
85     def supprime(self, force=False):
86         """
87         Cassage des boucles de références pour destruction du JDC.
88         'force' est utilisée pour faire des suppressions complémentaires.
89         
90         Pour être évaluées, les formules ont besoin du contexte des "constantes"
91         (objets autres que les concepts) qui sont soit dans (jdc).const_context,
92         soit dans (macro).macro_const_context.
93         On le stocke dans 'parent_context'.
94         Deux précautions valent mieux qu'une : on retire tous les concepts.
95         
96         Lors de la suppression du concept, 'supprime' est appelée par
97         'build_detruire' avec force=True afin de supprimer le "const_context"
98         conservé.
99         """
100         if force:
101             for ctxt in ('parent_context', 'g_context'):
102                 if hasattr(self, ctxt):
103                     setattr(self, ctxt, None)
104         ASSD.supprime(self, force)
105
106     def Parametres(self):
107         """Equivalent de fonction.Parametres pour pouvoir utiliser des formules
108         à la place de fonctions dans certaines macro-commandes.
109         """
110         from SD.sd_fonction import sd_formule
111         from Utilitai.Utmess import UTMESS
112         if self.accessible():
113             TypeProl={ 'E':'EXCLU', 'L':'LINEAIRE', 'C':'CONSTANT', 'I':'INTERPRE' }
114             sd = sd_formule(self.get_name())
115             prol = sd.PROL.get()
116             nova = sd.NOVA.get()
117             if prol is None or nova is None:
118                 UTMESS('F', 'SDVERI_2', valk=[objev])
119             dico={
120                 'INTERPOL'    : ['LIN','LIN'],
121                 'NOM_PARA'    : [s.strip() for s in nova],
122                 'NOM_RESU'    : prol[3][0:16].strip(),
123                 'PROL_DROITE' : TypeProl['E'],
124                 'PROL_GAUCHE' : TypeProl['E'],
125             }
126         else:
127             raise Accas.AsException("Erreur dans fonction.Parametres en PAR_LOT='OUI'")
128         return dico
129
130
131 class formule_c(formule):
132     pass
133
134