DSPython  00.03.03 — 25 juin 2012
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Pages
numbernone.py
Aller à la documentation de ce fichier.
1 #!/usr/bin/env python
2 # -*- coding: latin-1 -*-
3 ##\package DSPython.numbernone Nombre non nécessairement défini
4 # !!! Work in progress !!!
5 # ??? à transformer en class NumberNone
6 
7 ##\file
8 # Nombre non nécessairement défini
9 # !!! Work in progress !!!
10 
11 # (c) Olivier Pirson --- DragonSoft
12 # http://www.opimedia.be/DS/
13 # Débuté le 4 février 2006
14 ####################################
15 from __future__ import division
16 from __future__ import print_function
17 
18 ## Date du dernier changement pour ce module
19 VERSION = 'numbernone --- 2010 March 16'
20 
21 import numbers
22 
23 
24 
25 # ###########
26 # Fonctions #
27 #############
28 ## x + y
29 def add(x, y):
30  """Renvoie x + y
31  ou None si x ou y == None
32 
33  Pre: x: Number ou None
34  y: Number ou None
35 
36  Result: Number ou None
37 
38  O(x, y) = ..."""
39  assert isinstance(x, numbers.Number) or (x == None), x
40  assert isinstance(y, numbers.Number) or (y == None), y
41 
42  return (x + y if (x != None) and (y != None)
43  else None)
44 
45 
46 ## x / y
47 def div(x, y):
48  """Renvoie x / y
49  ou None si x ou y == None ou y == 0
50 
51  Pre: x: Number ou None
52  y: Number ou None
53 
54  Result: Number ou None
55 
56  O(x, y) = ..."""
57  assert isinstance(x, numbers.Number) or (x == None), x
58  assert isinstance(y, numbers.Number) or (y == None), y
59 
60  return (x / y if (x != None) and (y != None) and (y != 0)
61  else None)
62 
63 
64 ## divmod(x, y)
65 def divmod(x, y):
66  """Renvoie divmod(x, y)
67  ou None si x ou y == None ou y == 0
68 
69  Pre: x: Real ou None
70  y: Real ou None
71 
72  Result: (Real ou None, Real ou None)
73 
74  O(x, y) = ..."""
75  assert isinstance(x, numbers.Real) or (x == None), x
76  assert isinstance(y, numbers.Real) or (y == None), y
77 
78  return (x.__divmod__(y) if (x != None) and (y != None) and (y != 0)
79  else (None, None))
80 
81 
82 ## k<sup>e</sup> puissance factorielle descendante de x
84  """Renvoie la kème puissance factorielle descendante de x
85  == x * (x - 1) * (x - 2) * ... * (x - k + 1)
86  ou None si non défini
87 
88  Pre: x: Number ou None
89  k: Integral ou None
90 
91  Result: Number ou None
92 
93  O(x, k) = ..."""
94  assert isinstance(x, numbers.Number) or (x == None), x
95  assert isinstance(k, numbers.Integral) or (k == None), k
96 
97  if (x != None) and (k != None):
98  if k >= 0:
99  r = 1
100  for i in range(k):
101  r *= x
102  x -= 1
103  if r == 0:
104  return 0
105  return r
106  else:
107  return inv(rising_factorial_pow(x + 1, -k))
108  else:
109  return None
110 
111 
112 ## 1/x
113 def inv(x):
114  """Renvoie 1/x
115  ou None si x == None ou 0
116 
117  Pre: x: Number ou None
118 
119  Result: Number ou None
120 
121  O(x) = ..."""
122  assert isinstance(x, numbers.Number) or (x == None), x
123 
124  return (1/x if (x != None) and (x != 0)
125  else None)
126 
127 
128 ## x mod y
129 def mod(x, y):
130  """Renvoie x mod y
131  ou None si x ou y == None ou y == 0
132 
133  Pre: x: Number ou None
134  y: Number ou None
135 
136  Result: Number ou None
137 
138  O(x, y) = ..."""
139  assert isinstance(x, numbers.Number) or (x == None), x
140  assert isinstance(y, numbers.Number) or (y == None), y
141 
142  return (mod(x, y) if (x != None) and (y != None) and (y != 0)
143  else None)
144 
145 
146 ## x * y
147 def mul(x, y):
148  """Renvoie x * y
149  ou None si x ou y == None
150 
151  Pre: x: Number ou None
152  y: Number ou None
153 
154  Result: Number ou None
155 
156  O(x, y) = ..."""
157  assert isinstance(x, numbers.Number) or (x == None), x
158  assert isinstance(y, numbers.Number) or (y == None), y
159 
160  return (x*y if (x != None) and (y != None)
161  else None)
162 
163 
164 ## -x
165 def neg(x):
166  """Renvoie -x
167  ou None si x == None
168 
169  Pre: x: Number ou None
170 
171  Result: Number ou None
172 
173  O(x) = ..."""
174  assert isinstance(x, numbers.Number) or (x == None), x
175 
176  return (-x if x != None
177  else None)
178 
179 
180 ## k<sup>e</sup> puissance factorielle montante de x
182  """Renvoie la kème puissance factorielle montante de x
183  == x * (x + 1) * (x + 2) * ... * (x + k - 1)
184  ou None si non défini
185 
186  Pre: x: Number ou None
187  k: Integral ou None
188 
189  Result: Number ou None
190 
191  O(x, k) = ..."""
192  assert isinstance(x, numbers.Number) or (x == None), x
193  assert isinstance(k, numbers.Integral) or (k == None), k
194 
195  if (x != None) and (k != None):
196  if k >= 0:
197  r = 1
198  for i in range(k):
199  r *= x
200  x += 1
201  if r == 0:
202  return 0
203  return r
204  else:
205  return inv(falling_factorial_pow(x + 1, -k))
206  else:
207  return None
208 
209 
210 ## x - y
211 def sub(x, y):
212  """Renvoie x - y
213  ou None si x ou y == None
214 
215  Pre: x: Number ou None
216  y: Number ou None
217 
218  Result: Number ou None
219 
220  O(x, y) = ..."""
221  assert isinstance(x, numbers.Number) or (x == None), x
222  assert isinstance(y, numbers.Number) or (y == None), y
223 
224  return (x - y if (x != None) and (y != None)
225  else None)
226 
227 
228 
229 # ######\cond MAINTEST
230 # Main #
231 ########
232 if __name__ == '__main__':
233  def main_test():
234  """Test du module"""
235  import sys
236 
237  import math
238 
239  import DSPython.debug as debug
240  import DSPython.bit32 as bit32
241 
242  debug.test_begin(VERSION, __debug__)
243 
244  print('add()...', end=''); sys.stdout.flush()
245  print('???', end='')
246  print('ok'); sys.stdout.flush()
247 
248 
249  print('div()...', end=''); sys.stdout.flush()
250  print('???', end='')
251  print('ok'); sys.stdout.flush()
252 
253 
254  print('divmod()...', end=''); sys.stdout.flush()
255  assert divmod(4, 0) == (None, None), divmod(4, 0)
256  assert divmod(7, 3) == (2, 1), divmod(7, 3)
257  print('???', end='')
258  print('ok'); sys.stdout.flush()
259 
260 
261  print('falling_factorial_pow()...', end=''); sys.stdout.flush()
262  assert falling_factorial_pow(0, 0) == 1, falling_factorial_pow(0, 0)
263  for n in range(1000):
264  assert falling_factorial_pow(n, 0) == 1, (n, falling_factorial_pow(n, 0))
265  assert falling_factorial_pow(n, 1) == n, (n, falling_factorial_pow(n, 1))
266  assert falling_factorial_pow(n, 2) == n*(n - 1), (n, falling_factorial_pow(n, 2))
267  assert falling_factorial_pow(n, 3) == n*(n - 1)*(n - 2), \
268  (n, falling_factorial_pow(n, 3))
269  assert falling_factorial_pow(n, n + 1) == 0, (n, falling_factorial_pow(n, n+1))
270  for k in range(20):
271  assert falling_factorial_pow(k, k) == math.factorial(k), \
272  (k, math.factorial(k), falling_factorial_pow(k, k))
273  for k in range(20):
274  assert falling_factorial_pow(k + 1, k) == math.factorial(k + 1), \
275  (k, math.factorial(k + 1), falling_factorial_pow(2, k))
276  for k in range(1, 100):
277  assert falling_factorial_pow(0, k) == 0, (k, falling_factorial_pow(0, k))
278  for k in range(1, 20):
279  for n in range(k, min(100, int(pow(bit32.MERSENNE32, 1/k)) + 3)):
280  assert falling_factorial_pow(n, k) \
281  == math.factorial(n)//math.factorial(n - k), \
282  (n, k, math.factorial(n + k - 1)//math.factorial(n - 1),
283  falling_factorial_pow(n, k))
284  print('???', end='')
285  print('ok'); sys.stdout.flush()
286 
287 
288  print('inv()...', end=''); sys.stdout.flush()
289  print('???', end='')
290  print('ok'); sys.stdout.flush()
291 
292 
293  print('mod()...', end=''); sys.stdout.flush()
294  print('???', end='')
295  print('ok'); sys.stdout.flush()
296 
297 
298  print('mul()...', end=''); sys.stdout.flush()
299  print('???', end='')
300  print('ok'); sys.stdout.flush()
301 
302 
303  print('neg()...', end=''); sys.stdout.flush()
304  print('???', end='')
305  print('ok'); sys.stdout.flush()
306 
307 
308  print('rising_factorial_pow()...', end=''); sys.stdout.flush()
309  assert rising_factorial_pow(0, 0) == 1, rising_factorial_pow(0, 0)
310  for n in range(2000):
311  assert rising_factorial_pow(n, 0) == 1, (n, rising_factorial_pow(n, 0))
312  assert rising_factorial_pow(n, 1) == n, (n, rising_factorial_pow(n, 1))
313  assert rising_factorial_pow(n, 2) == n*(n + 1), (n, rising_factorial_pow(n, 2))
314  assert rising_factorial_pow(n, 3) == n*(n + 1)*(n + 2), (n, rising_factorial_pow(n, 3))
315  for k in range(20):
316  assert rising_factorial_pow(1, k) == math.factorial(k), \
317  (k, math.factorial(k), rising_factorial_pow(1, k))
318  for k in range(20):
319  assert rising_factorial_pow(2, k) == math.factorial(k + 1), \
320  (k, math.factorial(k+1), rising_factorial_pow(2, k))
321  for k in range(1, 20):
322  assert rising_factorial_pow(0, k) == 0, (k, rising_factorial_pow(0, k))
323  for n in range(1, min(100, int(pow(bit32.MERSENNE32, 1/k) - k + 4))):
324  assert rising_factorial_pow(n, k) \
325  == math.factorial(n + k - 1)//math.factorial(n - 1), \
326  (n, math.factorial(n + k - 1)//math.factorial(n - 1),
327  rising_factorial_pow(n, k))
328  print('???', end='')
329  print('ok'); sys.stdout.flush()
330 
331 
332  print('sub()...', end=''); sys.stdout.flush()
333  print('???', end='')
334  print('ok'); sys.stdout.flush()
335  debug.test_end()
336 
337  main_test()
338 ##\endcond MAINTEST