Salome HOME
mise en cohesion 78
[tools/eficas.git] / Noyau / N_FONCTION.py
1 # coding=utf-8
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 # Attention : cet import permet d'avoir, en Python, le comportement
21 # de la division réelle pour les entiers, et non la division entière
22 # 1/2=0.5 (et non 0). Comportement par défaut dans Python 3.0.
23 from __future__ import division
24 from math import sin, cos, tan, asin, acos, atan2, atan, sinh, cosh, tanh
25 from math import pi, exp, log, log10, sqrt
26
27 from N_ASSD import ASSD
28 from N_info import message, SUPERV
29
30
31 class FONCTION(ASSD):
32     pass
33
34
35 class formule(ASSD):
36
37     def __init__(self, *args, **kwargs):
38         ASSD.__init__(self, *args, **kwargs)
39         self.nompar = None
40         self.expression = None
41         ctxt = {}
42         ctxt.update(getattr(self.parent, 'const_context', {}))
43         ctxt.update(getattr(self.parent, 'macro_const_context', {}))
44         self.parent_context = self.filter_context(ctxt)
45         # message.debug(SUPERV, "add parent_context %s %s", self.nom,
46         # self.parent_context)
47
48     def __call__(self, *val):
49         """Evaluation de la formule"""
50         # en POURSUITE, self.parent_context is None, on essaie de reprendre
51         # const_context
52         context = getattr(self, 'parent_context') or getattr(
53             self.parent, 'const_context', {})
54         for param, value in zip(self.nompar, val):
55             context[param] = value
56         try:
57             # globals() pour math.*
58             res = eval(self.code, context, globals())
59         except Exception, exc:
60             message.error(SUPERV, "ERREUR LORS DE L'ÉVALUATION DE LA FORMULE '%s' "
61                           ":\n>> %s", self.nom, str(exc))
62             raise
63         return res
64
65     def setFormule(self, nom_para, texte):
66         """Cette methode sert a initialiser les attributs
67         nompar, expression et code qui sont utilisés
68         dans l'évaluation de la formule."""
69         self.nompar = nom_para
70         self.expression = texte
71         try:
72             self.code = compile(texte, texte, 'eval')
73         except SyntaxError, exc:
74             message.error(SUPERV, "ERREUR LORS DE LA CREATION DE LA FORMULE '%s' "
75                           ":\n>> %s", self.nom, str(exc))
76             raise
77
78     def __setstate__(self, state):
79         """Cette methode sert a restaurer l'attribut code lors d'un unpickle."""
80         self.__dict__.update(state)                   # update attributes
81         self.setFormule(self.nompar, self.expression)  # restore code attribute
82
83     def __getstate__(self):
84         """Pour les formules, il faut enlever l'attribut code qui n'est
85         pas picklable."""
86         d = ASSD.__getstate__(self)
87         del d['code']
88         return d
89
90     def supprime(self, force=False):
91         """
92         Cassage des boucles de références pour destruction du JDC.
93         'force' est utilisée pour faire des suppressions complémentaires.
94
95         Pour être évaluées, les formules ont besoin du contexte des "constantes"
96         (objets autres que les concepts) qui sont soit dans (jdc).const_context,
97         soit dans (macro).macro_const_context.
98         On le stocke dans 'parent_context'.
99         Deux précautions valent mieux qu'une : on retire tous les concepts.
100
101         Lors de la suppression du concept, 'supprime' est appelée par
102         'build_detruire' avec force=True afin de supprimer le "const_context"
103         conservé.
104         """
105         if force:
106             for ctxt in ('parent_context', 'g_context'):
107                 if hasattr(self, ctxt):
108                     setattr(self, ctxt, None)
109         ASSD.supprime(self, force)
110
111     def Parametres(self):
112         """Equivalent de fonction.Parametres pour pouvoir utiliser des formules
113         à la place de fonctions dans certaines macro-commandes.
114         """
115         from SD.sd_fonction import sd_formule
116         from Utilitai.Utmess import UTMESS
117         if self.accessible():
118             TypeProl = {
119                 'E': 'EXCLU', 'L': 'LINEAIRE', 'C': 'CONSTANT', 'I': 'INTERPRE'}
120             sd = sd_formule(self.get_name())
121             prol = sd.PROL.get()
122             nova = sd.NOVA.get()
123             if prol is None or nova is None:
124                 UTMESS('F', 'SDVERI_2', valk=[objev])
125             dico = {
126                 'INTERPOL': ['LIN', 'LIN'],
127                 'NOM_PARA': [s.strip() for s in nova],
128                 'NOM_RESU': prol[3][0:16].strip(),
129                 'PROL_DROITE': TypeProl['E'],
130                 'PROL_GAUCHE': TypeProl['E'],
131             }
132         else:
133             raise Accas.AsException(
134                 "Erreur dans fonction.Parametres en PAR_LOT='OUI'")
135         return dico
136
137
138 class formule_c(formule):
139     pass