source: pyromaths/trunk/fuentes/src/pyromaths/outils/Arithmetique.py @ 423

Last change on this file since 423 was 423, checked in by mabarracus, 4 years ago

add sources from pyromaths 15.10

File size: 9.6 KB
Line 
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3#
4# Pyromaths
5# Un programme en Python qui permet de créer des fiches d'exercices types de
6# mathématiques niveau collège ainsi que leur corrigé en LaTeX.
7# Copyright (C) 2006 -- Jérôme Ortais (jerome.ortais@pyromaths.org)
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22#
23
24import math, random
25
26def pgcd(*n):
27    """**pgcd**\ (*n*)
28
29    Calcule le pgcd de plusieurs entiers entiers.
30
31    Merci à http://python.jpvweb.com/mesrecettespython/doku.php?id=pgcd_ppcm
32
33    :param n: Les entiers dont on veut le pgcd
34    :type n: integer
35
36    >>> from pyromaths.outils import Arithmetique
37    >>> Arithmetique.pgcd(64,72,36)
38    4
39
40    :rtype: integer
41    """
42    from pyromaths.classes.SquareRoot import SquareRoot
43    def _pgcd(a, b):
44        #=======================================================================
45        # print "pgcd dans arithmetique ", a, b, isinstance(a, int), isinstance(b, int)
46        # print repr(a), repr(b)
47        #=======================================================================
48        if abs(a) == float('inf') or abs(b) == float('inf'): return 1
49        while b: a, b = b, a % b
50        return a
51    # Pour pouvoir utiliser pgcd(a) où a=(2,4,6) :
52    n = list(n)
53    if isinstance(n[0], (list, tuple)): n = n[0]
54    # Pour chercher à simplifier une fraction avec un objet SquareRoot
55    if isinstance(n[0], SquareRoot):
56        if len(n[0]) > 1:
57            n[0] = pgcd(*[n[0][i][0] for i in range(len(n[0]))])
58        else:
59            n[0] = n[0][0][0]
60    if isinstance(n[1], SquareRoot):
61        if len(n[1]) > 1:
62            n[1] = pgcd(*[n[1][i][0] for i in range(len(n[0]))])
63        else: n[1] = n[1][0][0]
64    p = _pgcd(n[0], n[1])
65    for x in n[2:]:
66        p = _pgcd(p, x)
67    return p
68
69def ppcm(*n):
70    """**ppcm**\ (*n*)
71
72    Calcule le ppcm de plusieurs entiers.
73
74    Merci à http://python.jpvweb.com/mesrecettespython/doku.php?id=pgcd_ppcm
75
76    :param n: Les entiers dont on veut le ppcm
77    :type n: integer
78
79    >>> from pyromaths.outils import Arithmetique
80    >>> Arithmetique.ppcm(64, 72, 36)
81    576
82
83    :rtype: integer
84    """
85    def _pgcd(a, b):
86        while b: a, b = b, a % b
87        return a
88    p = abs(n[0] * n[1]) // _pgcd(n[0], n[1])
89    for x in n[2:]:
90        p = abs(p * x) // _pgcd(p, x)
91    return p
92
93def premier(n):
94    """**premier**\ (*n*)
95
96    Teste si un nombre est premier.
97
98    :param n: Nombre à tester
99    :type n: integer
100
101    >>> from pyromaths.outils import Arithmetique
102    >>> Arithmetique.premier(2673)
103    False
104
105    :rtype: boolean
106    """
107    return not [x for x in xrange(2, int(math.sqrt(n)) + 1)
108                if n % x == 0]
109
110def eratosthene(n):
111    """**eratosthene**\ (*n*)
112
113    Établit la liste des nombres premiers inférieurs a n.
114
115    :param n: borne supérieure
116    :type n: integer
117
118    >>> from pyromaths.outils import Arithmetique
119    >>> Arithmetique.eratosthene(26)
120    [2, 3, 5, 7, 11, 13, 17, 19, 23]
121
122    :rtype: list
123    """
124    return [x for x in xrange(2, n) if premier(x)]
125
126
127def factor(n):
128    """**factor**\ (*n*)
129
130    Retourne la liste des facteurs premiers du nombre n.
131
132    :param n: Nombre à décomposer
133    :type n: integer
134
135    >>> from pyromaths.outils import Arithmetique
136    >>> Arithmetique.factor(2673)
137    [3, 3, 3, 3, 3, 11]
138    >>> Arithmetique.factor(23)
139    [23]
140
141    :rtype: list
142    """
143    premiers = []
144    candidats = xrange(2, n + 1)
145    candidat = 2
146    while not premiers and candidat in candidats:
147        if n % candidat == 0 and premier(candidat):
148            premiers.append(candidat)
149            premiers = premiers + factor(n / candidat)
150        candidat += 1
151    return premiers
152
153
154def factorise(n):
155    """**factorise**\ (*n*)
156
157    Retourne la liste des facteurs premiers du nombre n, ainsi que le détail de
158    la factorisation.
159
160    :param n: Nombre à décomposer
161    :type n: integer
162
163    >>> from pyromaths.outils import Arithmetique
164    >>> Arithmetique.factorise(2673)
165    ([3, 3, 3, 3, 3, 11], [['3', '891'], ['3', '3', '297'], ['3', '3', '3', '99'], ['3', '3', '3', '3', '33'], ['3', '3', '3', '3', '3', '11']])
166
167    :rtype: tuple
168    """
169    primes = []
170    etapes = []
171    primes_etapes = []
172    limite = int(math.sqrt(n)) + 1
173    candidate = 2
174    while (candidate < limite):
175        if n % candidate == 0:
176            primes.append(candidate)
177            primes_etapes.append(str(candidate))
178            n = n / candidate
179            if n == 1:
180                break
181            primes_etapes.append(str(n))
182            etapes.append(primes_etapes)
183            primes_etapes = primes_etapes[:-1]
184        else:
185            candidate += 1
186    if (n != 1) or (primes == []):
187        primes.append(n)
188    return (primes, etapes)
189
190
191def factoriseTex(n):
192    r"""**factoriseTex**\ (*n*)
193
194    Retourne la liste des facteurs premiers du nombre n, ainsi que le détail de
195    la factorisation au format TeX.
196
197    :param n: Nombre à décomposer
198    :type n: integer
199
200    >>> from pyromaths.outils import Arithmetique
201    >>> Arithmetique.factoriseTex(2673)
202    ([3, 3, 3, 3, 3, 11], ['\\begin{align*}', '2673', ' & = 3 \\times 891\\\\', ' & = 3 \\times 3 \\times 297\\\\', ' & = 3 \\times 3 \\times 3 \\times 99\\\\', ' & = 3 \\times 3 \\times 3 \\times 3 \\times 33\\\\', ' & = 3 \\times 3 \\times 3 \\times 3 \\times 3 \\times 11\\\\', '\\end{align*}'])
203
204    :rtype: tuple
205    """
206    """Version LaTeX pour factorise."""
207
208    corrige = ["\\begin{align*}", str(n)]
209    etapes = factorise(n)[1]
210    primes = factorise(n)[0]
211
212    if len(primes) > 1:
213        for i in range(len(etapes)):
214            text = ' & = '
215            for j in range(len(etapes[i])):
216                if j != len(etapes[i]) - 1:
217                    text += etapes[i][j] + ' \\times '
218                else:
219                    text += etapes[i][j]
220            corrige.append(text + '\\\\')
221        corrige.append("\\end{align*}")
222    else:
223        corrige = [str(n) + _(" est un nombre premier.\\par ")]
224
225    return (primes, corrige)
226
227
228def carrerise(n):
229    """**carrerise**\ (*n*)
230
231    Retourne le plus petit facteur par lequel multiplier pour obtenir un carré.
232
233    :param n: Nombre à rendre carré
234    :type n: integer
235
236    >>> from pyromaths.outils import Arithmetique
237    >>> Arithmetique.carrerise(75)
238    3
239
240    :rtype: integer
241    """
242    if round(math.sqrt(n), 0) == math.sqrt(n):
243        return 1
244    elif n <= 0:
245        return n
246    else:
247        primes = factorise(n)[0]
248        q = {}
249        for element in primes:
250            if (primes.count(element) % 2 == 1):
251                q[element] = 1
252        ncar = 1
253        for element in q.iterkeys():
254            ncar *= element
255    return ncar
256
257def combinaison(n, k):
258    """**combinaison**\ (*n*\ , *k*)
259
260    Retourne k parmi n
261
262    :param n: Nombre d'éléments
263    :type n: integer
264    :param k: éléments pris k à k
265    :type k: integer
266
267    >>> from pyromaths.outils import Arithmetique
268    >>> Arithmetique.combinaison(6,3)
269    20
270
271    :rtype: integer
272    """
273    if k > n // 2:
274        k = n - k
275    x = 1
276    y = 1
277    i = n - k + 1
278    while i <= n:
279        x = (x * i) // y
280        y += 1
281        i += 1
282    return x
283
284def signe(a):
285    """**signe**\ (*a*)
286
287    Retourne `1` si `a` est positif, `-1` sinon.
288
289    :param a: Nombre à tester
290    :type a: float
291
292    >>> from pyromaths.outils import Arithmetique
293    >>> Arithmetique.signe(234)
294    1
295    >>> Arithmetique.signe(-234)
296    -1
297
298    :rtype: integer
299    """
300    if a < 0:
301        return -1
302    else:
303        return 1
304
305def valeur_alea(a, b):
306    """**valeur_alea**\ (*a*\ , *b*)
307
308    Retourne une valeur comprise entre `a` et `b` non nulle.
309
310    :param a,b: bornes de l'ensemble de définition
311    :type a,b: integer
312
313    >>> from pyromaths.outils import Arithmetique
314    >>> Arithmetique.valeur_alea(-7,7)  # doctest: +SKIP
315    2
316
317    :rtype: integer
318    """
319    while True:
320        alea = random.randrange(a, b + 1)
321        if alea != 0:
322            return alea
323
324#---------------------------------------------------------------------
325# A supprimer dès que quatriemes/developpements.py aura été corrigé
326#---------------------------------------------------------------------
327
328def ecrit_tex(fichier, formule, cadre=None, thenocalcul='\\thenocalcul = ',
329              tabs=1):
330    """**ecrit_tex**\ (*n*)
331
332    **TODO :** À supprimer dès que quatriemes/developpements.py aura été corrigé
333
334    Écrit `formule` dans `fichier`.
335
336    :param fichier: Fichier dans lequel écrire
337    :type fichier: I/O
338    :param formule: formule à insérer
339    :type formule: string
340    :param cadre: faut-il entourer la formule ?
341    :type cadre: boolean
342    :param thenocalcul: Numérotation automatique par LaTeX de l'équation
343    :type thenocalcul: string
344    :param tabs: combien de tabulation insérer pour l'indentation du fichier ?
345    :type tabs: integer
346
347    :rtype: fichier
348    """
349
350    if formule != '':
351        if cadre == None or not cadre:
352            fichier.write((u'  \\[ %s%s \\] \n') % (thenocalcul, formule))
353        else:
354            fichier.write((u'  \\[ \\boxed{%s%s} \\] \n') % (thenocalcul, formule))
Note: See TracBrowser for help on using the repository browser.