#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Pyromaths
# Un programme en Python qui permet de créer des fiches d'exercices types de
# mathématiques niveau collège ainsi que leur corrigé en LaTeX.
# Copyright (C) 2006 -- Jérôme Ortais (jerome.ortais@pyromaths.org)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
from ..outils import Arithmetique
from ..outils.Priorites import OperateurPrioritaire
from ..outils.TeXMiseEnForme import Affichage, Affichage_quiz
import random
from ..classes.Fractions import Fractions #Classe Fractions de pyromaths
def sommes_fractions_4e(op, level):
'''Choisit des valeurs aléatoires pour effectuer une somme ou une différence
de fractions en fonction du niveau de difficulté souhaité (de 1 à 4) et renvoie
l'énoncé et le corrigé au format TeX
@param op: '+' ou '-'
@param level: niveau de difficulté :
1- Fractions positives et dénominateur de l'une multiple de l'autre
2- Fractions positives et dénominateurs non multiples
3- Fractions avec des nombres relatifs
4- Fractions avec des nombres relatifs et résultats simplifiable
'''
while True:
(n1, d1, n2, d2) = (2, 2, 2, 2)
# import pdb; pdb.set_trace()
while True:
if level == 1:
n1 = random.randrange(1, 16)
d1 = random.randrange(1, 9)
n2 = random.randrange(1, 16)
d2 = d1*random.randrange(2, 11)
if random.randrange(2):
d1, d2 = d2, d1
elif level == 2:
n1 = Arithmetique.valeur_alea(1, 16)
d1 = Arithmetique.valeur_alea(1, 40)
n2 = Arithmetique.valeur_alea(1, 16)
d2 = Arithmetique.valeur_alea(1, 40)
else:
while True:
neg=[(-1,1)[random.randrange(2)] for x in range(4)]
if neg[0]<0 or neg[1]<0 or neg[2]<0 or neg[3]<0:
break
n1 = random.randrange(1, 16)*neg[0]
d1 = random.randrange(1, 40)*neg[1]
n2 = random.randrange(1, 16)*neg[2]
d2 = random.randrange(1, 40)*neg[3]
fr1 = Fractions(n1, d1)
fr2 = Fractions(n2, d2)
if Arithmetique.pgcd(fr1.n, fr1.d) == 1 and \
Arithmetique.pgcd(fr2.n, fr2.d) == 1 and \
(level == 1 or (Arithmetique.pgcd(fr1.d, fr2.d) != abs(fr1.d) \
and Arithmetique.pgcd(fr1.d, fr2.d) != abs(fr2.d))):
if op == "+":
simplifiable = abs(fr1.d * fr2.d) != \
abs(Fractions.simplifie(fr1 + fr2).d)
else:
simplifiable = abs(fr1.d * fr2.d) != \
abs(Fractions.simplifie(fr1 - fr2).d)
if level == 1 or (simplifiable and level == 4) or \
(not simplifiable and level < 4):
break
l = [fr1, op, fr2]
(cor, res, niveau) = OperateurPrioritaire(l, 4, solution=[])
if niveau >= 4:
break
fr1 = Fractions(n1, d1)
fr2 = Fractions(n2, d2)
return ([fr1, op, fr2], cor, res)
def produits_fractions_4e(op, level):
'''Choisit des valeurs aléatoires pour effectuer un produit ou un quotient de
fractions en fonction du niveau de difficulté souhaité (de 1 à 4) et renvoie
l'énoncé et le corrigé au format TeX
@param op: '*' ou '/'
@param level: niveau de difficulté :
1- Fractions positives non décomposables
2- Fractions avec des nombres relatifs non décomposables
3- Fractions positives à décomposer
4- Fractions avec des nombres relatifs à décomposer
'''
while True:
(n1, d1, n2, d2) = (2, 2, 2, 2)
while True:
n1=d1=n2=d2=a=b=2
if level == 3 or level == 4:
while Arithmetique.pgcd(a,b)>1:
a=random.randrange(2,11)
b=random.randrange(2,11)
else:
a, b = 1, 1
if op == "*":
if level == 1 or level == 3:
while Arithmetique.pgcd(n1*a,d1*b)>1:
n1=random.randrange(1,11)
d1=random.randrange(2,11)
while Arithmetique.pgcd(n2*b,d2*a)>1:
n2=random.randrange(1,11)
d2=random.randrange(2,11)
elif level == 2 or level == 4:
while True:
neg=[(-1,-1,1)[random.randrange(3)] for x in range(4)]
if neg[0]<0 or neg[1]<0 or neg[2]<0 or neg[3]<0:
break
while Arithmetique.pgcd(n1*a,d1*b)>1:
n1=random.randrange(1,11)*neg[0]
d1=random.randrange(2,11)*neg[1]
while Arithmetique.pgcd(n2*b,d2*a)>1:
n2=random.randrange(1,11)*neg[2]
d2=random.randrange(2,11)*neg[3]
fr1 = Fractions(n1*a, d1*b)
fr2 = Fractions(n2*b, d2*a)
simplifiable = abs(fr1.d * fr2.d) != Fractions.simplifie(fr1 *
fr2).d
else:
if level == 1 or level == 3:
while Arithmetique.pgcd(n1*a,d1*b)>1:
n1=random.randrange(1,11)
d1=random.randrange(2,11)
while Arithmetique.pgcd(n2*a,d2*b)>1:
n2=random.randrange(1,11)
d2=random.randrange(2,11)
else:
while Arithmetique.pgcd(n1*a,d1*b)>1:
n1=random.randrange(-11,11)
d1=random.randrange(2,11)*(-1,1)[random.randrange(2)]
while Arithmetique.pgcd(n2*a,d2*b)>1:
n2=random.randrange(1,11)*(-1,1)[random.randrange(2)]
d2=random.randrange(2,11)*(-1,1)[random.randrange(2)]
fr1 = Fractions(n1*a, d1*b)
fr2 = Fractions(n2*a, d2*b)
simplifiable = abs(fr1.d * fr2.n) != \
Fractions.simplifie(fr1 / fr2).d
if (simplifiable and level>2) or (not simplifiable and level<=2):
break
l = [fr1, op, fr2]
(cor, res, niveau) = OperateurPrioritaire(l, 4, solution=[])
if niveau >= 4:
break
return (l, cor, res)
def valeurs_priorites_fractions(nb, entier=1): # renvoie les 2 listes contenant les opérateurs et les opérandes.
listoperateurs = [
"+",
"*",
"-",
"/",
'(',
'(',
'(',
'(',
')',
')',
')',
')',
]
loperateurs = []
loperandes = []
i = 0 #nombre d'opérateurs créés
p = 0 #nombre de parenthèses ouvertes
cpt = 0 #compteur pour éviter que le programme ne boucle.
while i < nb - 1:
cpt = cpt + 1
if cpt > 10: #On recommence
(cpt, i, p, loperateurs) = (0, 0, 0, [])
if p:
if loperateurs[-1] == '(': # On n'écrit pas 2 parenthèses à suivre
operateur = listoperateurs[random.randrange(4)]
else:
operateur = listoperateurs[random.randrange(12)]
elif loperateurs == []:
# On ne commence pas par une parenthèse
operateur = listoperateurs[random.randrange(4)]
else:
operateur = listoperateurs[random.randrange(8)]
if nb > 3:
test = ('-*/').find(operateur) >= 0 and loperateurs.count(operateur) < \
1 or operateur == "+" and loperateurs.count(operateur) < \
2
else:
test = ('-*/+').find(operateur) >= 0 and loperateurs.count(operateur) < \
1
if test:
#On n'accepte pas plus de 1 produit, différence, quotient et de 2 sommes ou parenthèses par calcul.
if i == 0 or loperateurs[-1] != '(' or ('*/').find(operateur) < \
0: #pas de * ou / dans une parenthèse.
i = i + 1
loperateurs.append(operateur)
elif operateur == '(' and (')+').find(loperateurs[-1]) < 0:
#Il ne peut y avoir de ( après une ) ou après un +
p = p + 1
loperateurs.append(operateur)
elif operateur == ')':
p = p - 1
loperateurs.append(operateur)
while p > 0:
loperateurs.append(')')
p = p - 1
loperandes = []
for i in range(nb):
(n, d) = (2, 2)
while Arithmetique.pgcd(n, d) != 1 or abs(d) == 1:
n = Arithmetique.valeur_alea(-16, 16)
d = -Arithmetique.valeur_alea(-40, 40)
loperandes.append(Fractions(n, d))
exercice = [loperandes[0]]
i = 1
j = 0
while i < len(loperandes) or j < len(loperateurs):
if j < len(loperateurs):
exercice.append(loperateurs[j])
j = j + 1
while j < len(loperateurs) and (loperateurs[j] == '(' or
loperateurs[j - 1] == ')'):
exercice.append(loperateurs[j])
j = j + 1
if i < len(loperandes):
exercice.append(loperandes[i])
i = i + 1
return exercice
def exo_sommes_fractions():
exo = ["\\exercice",
_(u"Effectuer les calculs suivants et donner le résultat sous la forme d'une fraction simplifiée :"),
"\\begin{multicols}{4}", " \\noindent%"]
cor = ["\\exercice*",
_(u"Effectuer les calculs suivants et donner le résultat sous la forme d'une fraction simplifiée :"),
"\\begin{multicols}{4}", " \\noindent%"]
quiz = [u"cloze"]
quiz_nom = _(u"Fractions: Somme et soustrait")
quiz_exo_cor = _(u"Effectue les suivants calculs et écrit le résultat sous forme de sa fraction irréductible:
\n")
quiz_exo_cor += _(u"(Utilise la barre \"/\" pour écrire la fraction)
\n")
quiz_exo_cor += u'
\n'
op = ["+", "-","+", "-","+", "-","+", "-"]
for i in range(8):
if i%2:
(l, sol, res) = sommes_fractions_4e(op.pop(0), i//2+1)
else:
(l, sol, res) = sommes_fractions_4e(op.pop(random.randrange(2)),
i//2+1)
exo.append("\\[\\thenocalcul = %s\\]" % Affichage(l))
cor.append("\\[\\thenocalcul = %s\\]" % Affichage(l))
quiz_exo_cor += (u"$$%s) \\; %s =$$" % (i+1, Affichage_quiz(l)))
quiz_exo_cor += (u"{1:SHORTANSWER:%s100%s%s} \n" % ("%", "%", Fractions.TeX_quiz(res,1))) if i+1 == 4: quiz_exo_cor += u" | \n" for l in sol: if l == sol[-1]: cor.append("\\[\\boxed{\\thenocalcul = %s}\\]" % l) else: cor.append("\\[\\thenocalcul = %s\\]" % l) exo.append("\\stepcounter{nocalcul}%") cor.append("\\stepcounter{nocalcul}%") exo.append("\\end{multicols}\n") cor.append("\\end{multicols}\n") quiz_exo_cor += u" |
\n'
op = ["*", "/","*", "/","*", "/","*", "/"]
for i in range(8):
if i%2:
(l, sol, res) = produits_fractions_4e(op.pop(0), i//2+1)
else:
(l, sol, res) = produits_fractions_4e(op.pop(random.randrange(2)), i//2+1)
exo.append("\\[\\thenocalcul = %s\\]" % Affichage(l))
cor.append("\\[\\thenocalcul = %s\\]" % Affichage(l))
quiz_exo_cor += (u"$$%s) \\; %s =$$" % (i+1, Affichage_quiz(l)))
quiz_exo_cor += (u"{1:SHORTANSWER:%s100%s%s} \n" % ("%", "%", Fractions.TeX_quiz(res,1))) if i+1 == 4: quiz_exo_cor += u" | \n" for l in sol: if l == sol[-1]: cor.append("\\[\\boxed{\\thenocalcul = %s}\\]" % l) else: cor.append("\\[\\thenocalcul = %s\\]" % l) exo.append("\\stepcounter{nocalcul}%") cor.append("\\stepcounter{nocalcul}%") exo.append("\\end{multicols}\n") cor.append("\\end{multicols}\n") quiz_exo_cor += u" |
\n'
for i in range(6):
while True:
l = valeurs_priorites_fractions(3)
(sol, res, niveau) = OperateurPrioritaire(l, 4, solution=[])
if niveau >= 4:
break
exo.append("\\[\\thenocalcul = %s\\]" % Affichage(l))
cor.append("\\[\\thenocalcul = %s\\]" % Affichage(l))
quiz_exo_cor += (u"$$%s) \\; %s =$$" % (i+1, Affichage_quiz(l)))
quiz_exo_cor += (u"{1:SHORTANSWER:%s100%s%s} \n" % ("%", "%", Fractions.TeX_quiz(res,1))) if i+1 == 3: quiz_exo_cor += u" | \n" for l in sol: if l == sol[-1]: cor.append("\\[\\boxed{\\thenocalcul = %s}\\]" % l) else: cor.append("\\[\\thenocalcul = %s\\]" % l) exo.append("\\stepcounter{nocalcul}%") cor.append("\\stepcounter{nocalcul}%") exo.append("\\end{multicols}\n") cor.append("\\end{multicols}\n") quiz_exo_cor += u" |