source: pyromaths/trunk/fuentes/src/pyromaths/ex/sixiemes/operations.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: 18.1 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
25import random
26from pyromaths.outils import Arithmetique, Affichage
27
28#===============================================================================
29# Poser des opérations
30#===============================================================================
31
32
33def valeurs():
34    nba = Arithmetique.valeur_alea(111, 99999)
35    while 1:
36        nbb = Arithmetique.valeur_alea(111, 99999)
37        if nbb - (nbb // 10) * 10:
38            break
39    puisb = Arithmetique.valeur_alea(-2, 0)
40    nbb = nbb * 10 ** puisb
41    deca = [str(nba)[i] for i in range(len(str(nba)))]
42    decb = [str(nbb)[i] for i in range(len(str(nbb)))]
43    if random.randrange(2):
44        (nba, deca, nbb, decb) = (nbb, decb, nba, deca)
45    if deca.count('.'):
46        posa = deca.index('.')
47    else:
48        posa = len(deca)
49    if decb.count('.'):
50        posb = decb.index('.')
51    else:
52        posb = len(decb)
53
54    lavtvirg = max(posa, posb)
55    laprvirg = max(len(deca) - posa, len(decb) - posb)
56    return (nba, nbb, deca, decb, lavtvirg, laprvirg)
57
58
59def valeurs_prod():
60    while 1:
61        nba = Arithmetique.valeur_alea(101, 9999)
62        if nba - (nba // 10) * 10:
63            break
64    puisa = Arithmetique.valeur_alea(-3, -1)
65    while 1:
66        nbb = Arithmetique.valeur_alea(101, 999)
67        if nbb - (nbb // 10) * 10:
68            break
69    puisb = Arithmetique.valeur_alea(-3, -1)
70    return (nba, nbb, puisa, puisb)
71
72
73def lignes(ligne, deca, lavtvirg, laprvirg):
74    if deca.count('.'):
75        posa = deca.index('.')
76    else:
77        posa = len(deca)
78    if posa < lavtvirg:
79        for i in range(lavtvirg - posa):
80            ligne.append('')
81    for i in range(len(deca)):
82        if deca[i] == '.':
83            ligne.append(',')
84        else:
85            ligne.append(str(deca[i]))
86    for i in range(laprvirg - (len(deca) - posa)):
87        if ligne.count(','):
88            ligne.append('0')
89        else:
90            ligne.append(',')
91    return ligne
92
93
94def mon_int(t):  # retourne un entier texte sous la forme d'un nombre, zéro sinon
95    if t == '':
96        t = 0
97    elif ('1234567890').count(t):
98        t = int(t)
99    else:
100        t = 0
101    return t
102
103
104def retenues_somme(ligne1, ligne2):
105    lg = len(ligne1)
106    ligne0 = ['' for i in range(lg)]
107    for i in range(lg - 1):
108
109        # on déplace la retenue pour qu'elle ne soit pas au-dessus de la virgule
110
111        if ligne1[(lg - i) - 1] == ',' and ligne0[(lg - i) - 1] == '1':
112            ligne0[(lg - i) - 2] = '1'
113        elif mon_int(ligne1[(lg - i) - 1]) + mon_int(ligne2[(lg - i) - 1]) + \
114            mon_int(ligne0[(lg - i) - 1]) > 9:
115            ligne0[(lg - i) - 2] = '1'
116    return ligne0
117
118
119def retenues_diff(ligne1, ligne2):
120    lg = len(ligne1)
121    ret = 0
122    for i in range(lg - 1):
123        if not (ligne1[(lg - i) - 1] == ',' and ret):
124            if mon_int(ligne1[(lg - i) - 1]) < mon_int(ligne2[(lg - i) - 
125                    1]) + ret:
126                ligne1[(lg - i) - 1] = '$_1$%s' % ligne1[(lg - i) - 1]
127                tmpret = 1
128            else:
129                tmpret = 0
130            if ret:
131                ligne2[(lg - i) - 1] = '%s$_1$' % ligne2[(lg - i) - 1]
132            ret = tmpret
133    return (ligne1, ligne2)
134
135
136def tex_somme(exo, cor):
137    (ligne1, ligne2) = ([''], ['+'])
138    (nba, nbb, deca, decb, lavtvirg, laprvirg) = valeurs()
139    total = nba + nbb
140    dectotal = [str(total)[i] for i in range(len(str(total)))]
141    if dectotal.index('.') <= lavtvirg:
142        ligne3 = ['']
143    else:
144        ligne3 = []
145    ligne1 = lignes(ligne1, deca, lavtvirg, laprvirg)
146    ligne2 = lignes(ligne2, decb, lavtvirg, laprvirg)
147    ligne3 = lignes(ligne3, dectotal, lavtvirg, laprvirg)
148    ligne0 = retenues_somme(ligne1, ligne2)
149    if ligne0[0] == '1':
150        ligne0[0] = '\\tiny 1'
151    exo.append('\\item La somme des termes %s et %s.\\par' % (Affichage.decimaux(nba),
152             Affichage.decimaux(nbb)))
153    cor.append('\\item La somme des termes %s et %s.\\par' % (Affichage.decimaux(nba),
154             Affichage.decimaux(nbb)))
155    cor.append('\\begin{tabular}[t]{*{%s}{c}}' % (lavtvirg + 
156             laprvirg + 1))
157    cor.append('%s \\\\' % ' & \\tiny '.join(ligne0))
158    cor.append('%s \\\\' % ' & '.join(ligne1))
159    cor.append('%s \\\\\n\\hline' % ' & '.join(ligne2))
160    cor.append('%s \\\\' % ' & '.join(ligne3))
161    cor.append('\\end{tabular}\\par')
162    formule = '%s+%s = %s' % (Affichage.decimaux(nba, 1),
163                     Affichage.decimaux(nbb, 1), Affichage.decimaux(nba + 
164                     nbb, 1))
165    cor.append((u'\\[ \\boxed{%s} \\] ').expandtabs(2 * 3) % (formule))
166
167def tex_difference(exo, cor):
168    (ligne1, ligne2) = ([''], ['-'])
169    (nba, nbb, deca, decb, lavtvirg, laprvirg) = valeurs()
170    if nba < nbb:
171        (nba, nbb, deca, decb) = (nbb, nba, decb, deca)
172    total = nba - nbb
173    dectotal = [str(total)[i] for i in range(len(str(total)))]
174    if dectotal.index('.') <= lavtvirg:
175        ligne3 = ['']
176    else:
177        ligne3 = []
178    ligne1 = lignes(ligne1, deca, lavtvirg, laprvirg)
179    ligne2 = lignes(ligne2, decb, lavtvirg, laprvirg)
180    ligne3 = lignes(ligne3, dectotal, lavtvirg, laprvirg)
181    (ligne1, ligne2) = retenues_diff(ligne1, ligne2)
182    exo.append(u"\\item La différence des termes %s et %s.\\par" % 
183             (Affichage.decimaux(nba), Affichage.decimaux(nbb)))
184    cor.append(u"\\item La différence des termes %s et %s.\\par" % 
185             (Affichage.decimaux(nba), Affichage.decimaux(nbb)))
186    cor.append('\\begin{tabular}[t]{*{%s}{c}}' % (lavtvirg + 
187             laprvirg + 1))
188    cor.append('%s \\\\' % ' & '.join(ligne1))
189    cor.append('%s \\\\\n\\hline' % ' & '.join(ligne2))
190    cor.append('%s \\\\' % ' & '.join(ligne3))
191    cor.append('\\end{tabular}\\par')
192    formule = '%s-%s = %s' % (Affichage.decimaux(nba, 1),
193                     Affichage.decimaux(nbb, 1), Affichage.decimaux(nba - 
194                     nbb, 1))
195    cor.append((u'\\[ \\boxed{%s} \\] ').expandtabs(2 * 3) % (formule))
196
197def pose_mult(nba, nbb):
198    (ligne, total) = ([], 0)
199    for i in range(int(math.log10(nbb)) + 1):
200        sstotal = ((nbb - (nbb // 10) * 10) * nba) * 10 ** i
201        total = total + sstotal
202        ligne.append(sstotal)
203        nbb = nbb // 10
204    return (ligne, total)
205
206
207def ligneprod(ligne, dec, lg):
208    ligne.extend(['' for dummy in range((lg - len(dec)) - len(ligne))])
209    ligne.extend(dec)
210    return ligne
211
212
213def tex_produit(exo, cor):
214    (nba, nbb, puisa, puisb) = valeurs_prod()
215    deca = [','.join(str(nba * 10 ** puisa).rsplit('.'))[i] \
216                    for i in range(len(str(nba * 10 ** puisa)))]
217    decb = [','.join(str(nbb * 10 ** puisb).rsplit('.'))[i] \
218                    for i in range(len(str(nbb * 10 ** puisb)))]
219
220    (dec3, dummy) = pose_mult(nba, nbb)
221    (dec3bis, dummy) = pose_mult(nbb, nba)
222    total = ((nba * 10 ** puisa) * nbb) * 10 ** puisb
223    dec4 = [str(total)[i] for i in range(len(str(total)))]
224    if dec4.count('.'):
225        i = dec4.index('.')
226        if (len(dec4) - i) - 1 < -(puisa + puisb):
227            for j in range(-(puisa + puisb) - len(dec4) + i + 1):
228                dec4.append('0')  # ajoute les 0 inutiles au produit
229        dec4.pop(i)  # supprime le point décimal
230        dec4[i - 1] = '%s\\Huge ,' % dec4[i - 1]  # et ajoute une Huge virgule au chiffre des unités
231    lg = max(len(dec4), max(len(deca), len(decb)))  # nombre de colonnes dans le tableau
232    exo.append('\\item Le produit des facteurs %s et %s.\\par' % (Affichage.decimaux(nba * 
233             10 ** puisa), Affichage.decimaux(nbb * 10 ** puisb)))
234    cor.append('\\item Le produit des facteurs %s et %s.\\par' % (Affichage.decimaux(nba * 
235             10 ** puisa), Affichage.decimaux(nbb * 10 ** puisb)))
236    cor.append('\\begin{enumerate}')
237    cor.append(u'\\item Première méthode :\\par')
238    lg = max(len(dec4), max(len(deca), len(decb)+1))
239    cor.append('\\begin{tabular}[t]{*{%s}{c}}' % lg)
240    cor.append('%s \\\\' % ' & '.join(ligneprod([], deca, lg)))
241    cor.append('%s \\\\\n\\hline' % ' & '.join(ligneprod(['$\\times$'], decb, lg)))
242    for i in range(len(dec3)):
243        dec = [str(dec3[i])[j] for j in range(len(str(dec3[i])))]
244        cor.append('%s \\\\' % ' & '.join(ligneprod([], dec, lg)))
245    cor.append('\\hline \\\\')
246    cor.append('%s \\\\' % ' & '.join(ligneprod([], dec4, lg)))
247    cor.append('\\end{tabular}')
248    cor.append(u'\\item Seconde méthode :\\par')
249    lg = max(len(dec4), max(len(deca)+1, len(decb)))
250    cor.append('\\begin{tabular}[t]{*{%s}{c}}' % lg)
251    cor.append('%s \\\\' % ' & '.join(ligneprod([], decb, lg)))
252    cor.append('%s \\\\\n\\hline' % ' & '.join(ligneprod(['$\\times$'], deca, lg)))
253    for i in range(len(dec3bis)):
254        dec = [str(dec3bis[i])[j] for j in range(len(str(dec3bis[i])))]
255        cor.append('%s \\\\' % ' & '.join(ligneprod([], dec, lg)))
256    cor.append('\\hline \\\\')
257    cor.append('%s \\\\' % ' & '.join(ligneprod([], dec4, lg)))
258    cor.append('\\end{tabular}')
259    cor.append('\\end{enumerate}')
260
261    #===========================================================================
262    # # outils.Arithmetique.ecrit_tex(f1, '%s\\times%s = %s' % (Affichage.decimaux(nba *
263    #                  # 10 ** puisa, 1), Affichage.decimaux(nbb * 10 **
264    #                  # puisb, 1), Affichage.decimaux((nba * nbb) * 10 ** (puisa +
265    #                  # puisb), 1)), cadre=1, thenocalcul='', tabs=3)
266    #===========================================================================
267
268    #### Remplacement de la fonction Arithmetique.ecrit_tex :
269
270    formule = '%s\\times%s = %s' % (Affichage.decimaux(nba * 
271                     10 ** puisa, 1), Affichage.decimaux(nbb * 10 ** 
272                     puisb, 1), Affichage.decimaux((nba * nbb) * 10 ** (puisa + 
273                     puisb), 1))
274    cor.append((u'\\[ \\boxed{%s} \\] ').expandtabs(2 * 3) % (formule))
275
276
277def Operations():
278    nb_exos = 3
279    tex_exos = (tex_somme, tex_difference, tex_produit)
280
281    ordre_exos = [i for i in range(nb_exos)]
282
283    exo = ["\\exercice", u'Poser et effectuer les opérations suivantes.', '\\begin{multicols}{2}\\noindent', '\\begin{enumerate}']
284    cor = ["\\exercice*", u'Poser et effectuer les opérations suivantes.', '\\begin{multicols}{2}\\noindent', '\\begin{enumerate}']
285
286    for i in range(nb_exos):
287        a = random.randrange(nb_exos - i)
288        j = ordre_exos.pop(a)
289        tex_exos[j](exo, cor)
290    exo.append('\\end{enumerate}')
291    exo.append('\\end{multicols}')
292    cor.append('\\end{enumerate}')
293    cor.append('\\end{multicols}')
294    return (exo, cor)
295
296Operations.description = u'Poser des opérations (sauf divisions)'
297
298
299#===============================================================================
300# Calcul mental
301#===============================================================================
302
303
304def tex_calcul_mental(exo, cor):
305    modules = (plus, moins, plus, div)
306    calculs = [i for i in range(20)]
307    for i in range(20):
308        j = random.randrange(0, len(calculs))
309        (a, b) = modules[calculs[j] // 5](10)
310        if calculs[j] // 5 == 0:
311            choix_trou(a, b, a + b, '+', exo, cor)
312        if calculs[j] // 5 == 1:
313            choix_trou(a, b, a - b, '-', exo, cor)
314        if calculs[j] // 5 == 2:
315            choix_trou(a, b, a * b, '\\times', exo, cor)
316        if calculs[j] // 5 == 3:
317            choix_trou(a, b, a // b, '\\div', exo, cor)
318        calculs.pop(j)
319
320
321def choix_trou(nb1, nb2, tot, operateur, exo, cor):
322    nbaleatoire = random.randrange(4)
323    if nbaleatoire > 1:
324        exo.append('\\item $%s %s %s = \\ldots\\ldots$' % (nb1,
325                 operateur, nb2))
326        cor.append('\\item $%s %s %s = \\mathbf{%s}$' % (nb1,
327                 operateur, nb2, tot))
328    elif nbaleatoire > 0:
329        exo.append('\\item $%s %s \\ldots\\ldots = %s$' % (nb1,
330                 operateur, tot))
331        cor.append('\\item $%s %s \\mathbf{%s} = %s$' % (nb1,
332                 operateur, nb2, tot))
333    else:
334        exo.append('\\item $\\ldots\\ldots %s %s = %s$' % (operateur,
335                 nb2, tot))
336        cor.append('\\item $\\mathbf{%s} %s %s = %s$' % (nb1,
337                 operateur, nb2, tot))
338
339
340def plus(valeurmax):
341    (a, b) = (Arithmetique.valeur_alea(1, valeurmax), Arithmetique.valeur_alea(1,
342              valeurmax))
343    return (a, b)
344
345
346def moins(valeurmax):
347    (a, b) = (Arithmetique.valeur_alea(1, valeurmax), Arithmetique.valeur_alea(1,
348              valeurmax))
349    return (a + b, a)
350
351
352def div(valeurmax):
353    (a, b) = (Arithmetique.valeur_alea(1, valeurmax), Arithmetique.valeur_alea(1,
354              valeurmax))
355    return (a * b, a)
356
357
358
359
360def CalculMental():
361    exo = ["\\exercice", 'Effectuer sans calculatrice :', '\\begin{multicols}{4}\\noindent', '\\begin{enumerate}']
362    cor = ["\\exercice*", 'Effectuer sans calculatrice :', '\\begin{multicols}{4}\\noindent', '\\begin{enumerate}']
363
364    tex_calcul_mental(exo, cor)
365
366    exo.append('\\end{enumerate}')
367    exo.append('\\end{multicols}')
368    cor.append('\\end{enumerate}')
369    cor.append('\\end{multicols}')
370    return (exo, cor)
371
372CalculMental.description = u'Calcul mental'
373
374
375#===============================================================================
376# PRODUITS ET QUOTIENTS PAR 10, 100, 1000
377#===============================================================================
378
379
380def tex_dix(exo, cor):
381    nb = 4  # nb de calculs de chaque type
382    l = valeurs10(nb)
383    for dummy in range(len(l)):
384        j = random.randrange(0, len(l))
385        tex_formule_dix(l.pop(j), exo, cor)
386
387
388def tex_formule_dix(l, exo, cor):
389    if l[2] == '*':
390        alea = random.randrange(0, 5)
391        if alea > 1:
392            exo.append('\\item $%s \\quad\\times\\quad %s \\quad = \\quad \\dotfill$' % 
393                     (Affichage.decimaux(l[0], 1), Affichage.decimaux(l[1],
394                     1)))
395            cor.append('\\item $%s \\times %s = \\mathbf{%s}$' % 
396                     (Affichage.decimaux(l[0], 1), Affichage.decimaux(l[1],
397                     1), Affichage.decimaux(l[0] * l[1], 1)))
398        elif alea > 0:
399            exo.append('\\item $%s \\quad\\times\\quad \\dotfill \\quad = \\quad %s$' % 
400                     (Affichage.decimaux(l[0], 1), Affichage.decimaux(l[0] * 
401                     l[1], 1)))
402            cor.append('\\item $%s \\times \\mathbf{%s} = %s$' % 
403                     (Affichage.decimaux(l[0], 1), Affichage.decimaux(l[1],
404                     1), Affichage.decimaux(l[0] * l[1], 1)))
405        else:
406            exo.append('\\item $\\dotfill \\quad\\times\\quad %s \\quad = \\quad %s$' % 
407                     (Affichage.decimaux(l[1], 1), Affichage.decimaux(l[0] * 
408                     l[1], 1)))
409            cor.append('\\item $\\mathbf{%s} \\times %s = %s$' % 
410                     (Affichage.decimaux(l[0], 1), Affichage.decimaux(l[1],
411                     1), Affichage.decimaux(l[0] * l[1], 1)))
412    else:
413        alea = random.randrange(0, 5)
414        if alea > 1:
415            exo.append('\\item $%s \\quad\\div\\quad %s \\quad = \\quad \\dotfill$' % 
416                     (Affichage.decimaux(l[0], 1), Affichage.decimaux(l[1],
417                     1)))
418            cor.append('\\item $%s \\div %s = \\mathbf{%s}$' % (Affichage.decimaux(l[0],
419                     1), Affichage.decimaux(l[1], 1), Affichage.decimaux(l[0] / 
420                     l[1], 1)))
421        elif alea > 0:
422            exo.append('\\item $%s \\quad\\div\\quad \\dotfill \\quad = \\quad %s$' % 
423                     (Affichage.decimaux(l[0], 1), Affichage.decimaux(l[0] / 
424                     l[1], 1)))
425            cor.append('\\item $%s \\div \\mathbf{%s} = %s$' % (Affichage.decimaux(l[0],
426                     1), Affichage.decimaux(l[1], 1), Affichage.decimaux(l[0] / 
427                     l[1], 1)))
428        else:
429            exo.append('\\item $\\dotfill \\quad\\div\\quad %s \\quad = \\quad %s$' % 
430                     (Affichage.decimaux(l[1], 1), Affichage.decimaux(l[0] / 
431                     l[1], 1)))
432            cor.append('\\item $\\mathbf{%s} \\div %s = %s$' % (Affichage.decimaux(l[0],
433                     1), Affichage.decimaux(l[1], 1), Affichage.decimaux(l[0] / 
434                     l[1], 1)))
435
436
437def valeurs10(nb):  # renvoie nb valeur de chaque type : *10, /10, *0.1
438    l = []
439    for i in range(nb):
440        if random.randrange(0, 1):
441            l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,
442                     0), 10 ** (i + 1), '*'))
443        else:
444            l.append((10 ** (i + 1), Arithmetique.valeur_alea(111, 999) * 10 ** 
445                     random.randrange(-3, 0), '*'))
446    for i in range(nb):
447        l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,
448                 0), 10 ** (i + 1), '/'))
449    for i in range(nb):
450        if random.randrange(0, 1):
451            l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,
452                     0), 10 ** (-i - 1), '*'))
453        else:
454            l.append((10 ** (-i - 1), Arithmetique.valeur_alea(111, 999) * 10 ** 
455                     random.randrange(-3, 0), '*'))
456    return l
457
458
459
460def ProduitPuissanceDix():
461    exo = ["\\exercice", u'Compléter sans calculatrice :', '\\begin{multicols}{2}\\noindent', '\\begin{enumerate}']
462    cor = ["\\exercice*", u'Compléter sans calculatrice :', '\\begin{multicols}{2}\\noindent', '\\begin{enumerate}']
463
464    tex_dix(exo, cor)
465
466    exo.append('\\end{enumerate}')
467    exo.append('\\end{multicols}')
468    cor.append('\\end{enumerate}')
469    cor.append('\\end{multicols}')
470    return (exo, cor)
471
472ProduitPuissanceDix.description = u'Produits, quotients par 10, 100, 1000'
Note: See TracBrowser for help on using the repository browser.