Salome HOME
travail sur monPlusieurs
[tools/eficas.git] / Noyau / N_utils.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 """
22    Ce module contient des fonctions utilitaires
23 """
24
25 # Modules Python
26 import sys
27
28 # Modules EFICAS
29 from N_Exception import AsException
30 from N_types     import is_int, is_float, is_complex, is_str, is_sequence, is_assd
31
32 SEP='_'
33
34 try:
35    # Si la version de Python possède la fonction _getframe
36    # on l'utilise.
37    cur_frame=sys._getframe
38 except:
39    # Sinon on l'émule
40    def cur_frame(offset=0):
41      """ Retourne la frame d execution effective eventuellement en remontant
42          de offset niveaux dans la pile d execution
43          Si il y a moins de offset niveaux retourne None
44      """
45      try:1/0
46      except:
47        frame=sys.exc_info()[2].tb_frame.f_back
48      while offset > 0:
49        if frame == None:return None
50        frame=frame.f_back
51        offset=offset-1
52      return frame
53
54
55 def callee_where(niveau=4):
56    """
57       recupere la position de l appel
58    """
59    frame=cur_frame(niveau)
60    if frame == None: return 0,"inconnu",0,{}
61    try:
62      return frame.f_lineno,frame.f_code.co_filename,frame.f_code.co_firstlineno,frame.f_locals
63    except:
64      return 0,"inconnu",0,{}
65
66
67 def AsType(a):
68    """
69       Retourne le type d'un concept (a) à partir
70       des caractéristiques de l'objet Python
71    """
72    if is_sequence(a):
73        return AsType(a[0])
74    if is_assd(a):
75        return type(a)
76    if is_float(a):
77        return "R"
78    if is_int(a):
79        return "I"
80    if is_str(a):
81        return "TXM"
82    if a == None:
83        return None
84    raise AsException("type inconnu: %r %s" % (a, type(a)))
85
86
87 def prbanner(s):
88    print "*"*(len(s)+10)
89    print "*"*5 + s + "*"*5
90    print "*"*(len(s)+10)
91
92
93 def repr_float(valeur):
94   """
95       Cette fonction représente le réel valeur comme une chaine de caractères
96       sous forme mantisse exposant si nécessaire cad si le nombre contient plus de
97       5 caractères
98       NB : valeur est un réel au format Python ou une chaine de caractères représentant un réel
99   """
100   if type(valeur) == str : valeur = eval(valeur)
101   if valeur == 0. : return '0.0'
102   if abs(valeur) > 1. :
103     if abs(valeur) < 10000. : return repr(valeur)
104   else :
105     if abs(valeur) > 0.01 : return repr(valeur)
106   t=repr(valeur)
107   if t.find('e') != -1 or t.find('E') != -1 :
108     # le réel est déjà sous forme mantisse exposant !
109     # --> on remplace e par E
110     t=t.replace('e','E')
111     # --> on doit encore vérifier que la mantisse contient bien un '.'
112     if t.find('.')!= -1:
113       return t
114     else:
115       # -->il faut rajouter le point avant le E
116       t=t.replace('E','.E')
117       return t
118   s=''
119   neg = 0
120   if t[0]=='-':
121     s=s+t[0]
122     t=t[1:]
123   cpt = 0
124   if t[0].atof() == 0.:
125     # réel plus petit que 1
126     neg = 1
127     t=t[2:]
128     cpt=1
129     while t[0].atof() == 0. :
130       cpt = cpt+1
131       t=t[1:]
132     s=s+t[0]+'.'
133     for c in t[1:]:
134       s=s+c
135   else:
136     # réel plus grand que 1
137     s=s+t[0]+'.'
138     if t[1:].atof() == 0.:
139       l=t[1:].split('.')
140       cpt = len(l[0])
141     else:
142       r=0
143       pt=0
144       for c in t[1:]:
145         r=r+1
146         if c != '.' :
147           if pt != 1 : cpt = cpt + 1
148           s=s+c
149         else:
150           pt = 1
151           if r+1 == len(t) or t[r+1:].atof() == 0.:break
152   s=s+'E'+neg*'-'+repr(cpt)
153   return s
154
155
156 def import_object(uri):
157     """Load and return a python object (class, function...).
158     Its `uri` looks like "mainpkg.subpkg.module.object", this means
159     that "mainpkg.subpkg.module" is imported and "object" is
160     the object to return.
161     """
162     path = uri.split('.')
163     modname = '.'.join(path[:-1])
164     if len(modname) == 0:
165         raise ImportError(u"invalid uri: %s" % uri)
166     mod = object = '?'
167     objname = path[-1]
168     try:
169         __import__(modname)
170         mod = sys.modules[modname]
171     except ImportError, err:
172         raise ImportError(u"can not import module : %s (%s)" % (modname, str(err)))
173     try:
174         object = getattr(mod, objname)
175     except AttributeError, err:
176         raise AttributeError(u"object (%s) not found in module '%s'. "
177             "Module content is: %s" % (objname, modname, tuple(dir(mod))))
178     return object
179
180
181 class Singleton(object):
182     """Singleton implementation in python."""
183     # add _singleton_id attribute to the class to be independant of import path used
184     __inst = {}
185     def __new__(cls, *args, **kargs):
186         cls_id = getattr(cls, '_singleton_id', cls)
187         if Singleton.__inst.get(cls_id) is None:
188             Singleton.__inst[cls_id] = object.__new__(cls)
189         return Singleton.__inst[cls_id]
190
191
192 class Enum(object):
193     """
194     This class emulates a C-like enum for python. It is initialized with a list
195     of strings to be used as the enum symbolic keys. The enum values are automatically
196     generated as sequencing integer starting at 0.
197     """
198     def __init__(self, *keys):
199         """Constructor"""
200         self._dict_keys = {}
201         for inum, key in enumerate(keys):
202             setattr(self, key, 2**inum)
203             self._dict_keys[2**inum] = key
204
205     def exists(self, value):
206         """Tell if value is in the enumeration"""
207         return self.get_id(value) is not None
208
209     def get_id(self, value):
210         """Return the key associated to the given value"""
211         return self._dict_keys.get(value, None)