def sommes_fractions_4e(nombre_min, nombre_max, level):
    while True:
        n1 = Arithmetique.valeur_alea(nombre_min, nombre_max)
        d1 = Arithmetique.valeur_alea(nombre_min, nombre_max)
        n2 = Arithmetique.valeur_alea(nombre_min, nombre_max)
        d2 = Arithmetique.valeur_alea(nombre_min, nombre_max)
        # Creation des 2 fractions
        fr1 = Fractions(n1, d1)
        fr2 = Fractions(n2, d2)
        # Sortie de boucle 
        if Arithmetique.pgcd(fr1.n, fr1.d) == 1 and Arithmetique.pgcd(fr2.n, fr2.d) == 1:
            if abs(fr1.d)== abs(fr2.d):
                # Sortie de boucle niveau 1
                if level == 1:
                    break
            else:
                if Arithmetique.pgcd(fr1.d, fr2.d) == abs(fr1.d) or Arithmetique.pgcd(fr1.d, fr2.d) == abs(fr2.d): 
                    # Sortie de boucle niveau 2
                    if level == 2:
                        break
                else: 
                    simplifiable = abs(fr1.d * fr2.d) != abs(Fractions.simplifie(fr1 + fr2).d)
                    if not simplifiable:
                        # Sortie de boucle niveau 3
                        if level == 3:
                            break
                    else:
                        # Sortie de boucle niveau 4
                        if level == 4:
                            break
    l = [fr1, '+', fr2]
    (cor, res, niveau) = OperateurPrioritaire(l, 4, solution=[])
    return ([fr1, '+', fr2], cor, res)
def sommes_fractions(parametre):
    question = ""
    exo = [u"Effectuer les calculs suivants et donner le résultat sous la forme d'une fraction simplifiée :",
           "\\begin{multicols}{4}", "  \\noindent"]
    cor = [u"Effectuer les calculs suivants et donner le résultat sous la forme d'une fraction simplifiée :",
           "\\begin{multicols}{4}", "  \\noindent"]
    for i in range(8):
        if random.randrange(2):
            s = "+"
        else:
            s = "-"
        n = d = c = n2 = 2
        while Arithmetique.pgcd(n, d) > 1:
            n = random.randrange(1, 11)
            d = random.randrange(2, 11)
        while Arithmetique.pgcd(n2, d * c) > 1:
            c = random.randrange(2, 11)
            n2 = random.randrange(2, 11)
        fr1 = Fractions(n, d)
        fr2 = Fractions(n2, d * c)
        if s == "-" and (fr1 - fr2).n * (fr1 - fr2).d < 0 or s == "+" and \
            random.randrange(2):
            (fr1, fr2) = (fr2, fr1)
        exo.append("\\[ \\thenocalcul = %s%s%s \\]" % (Fractions.TeX(fr1),
                   s, Fractions.TeX(fr2)))
        cor.append("\\[ \\thenocalcul = %s%s%s \\]" % (Fractions.TeX(fr1),
                   s, Fractions.TeX(fr2)))
        if fr1.d < fr2.d:
            cor.append("\\[ \\thenocalcul = %s%s%s \\]" % (Fractions.TeX(fr1,
                       coef=c), s, Fractions.TeX(fr2)))
        else:
            cor.append("\\[ \\thenocalcul = %s%s%s \\]" % (Fractions.TeX(fr1),
                       s, Fractions.TeX(fr2, coef=c)))
        if s == "+":
            fr = fr1 + fr2
        else:
            fr = fr1 - fr2
        frs = Fractions.simplifie(fr)
        if frs.d != fr.d:
            cor.append("\\[ \\thenocalcul = %s \\]" % Fractions.TeX(frs,
                       coef=fr.d // frs.d))
            cor.append("\\[ \\boxed{\\thenocalcul = %s} \\]" %
                       Fractions.TeX(frs))
        else:
            cor.append("\\[ \\boxed{\\thenocalcul = %s} \\]" %
                       Fractions.TeX(fr))
        exo.append("\\stepcounter{nocalcul}%")
        cor.append("\\stepcounter{nocalcul}%")
    exo.append("\\end{multicols}\n")
    cor.append("\\end{multicols}\n")
    return (exo, cor, question)
def produits_fractions(parametre):
    question = ""
    exo = [u"Effectuer les calculs suivants et donner le résultat sous la forme d'une fraction simplifiée :",
           "\\begin{multicols}{4}", "  \\noindent"]
    cor = [u"Effectuer les calculs suivants et donner le résultat sous la forme d'une fraction simplifiée :",
           "\\begin{multicols}{4}", "  \\noindent"]
    for i in range(8):
        n1=d1=n2=d2=a=b=2
        while Arithmetique.pgcd(a,b)>1:
            a=random.randrange(1,11)
            b=random.randrange(2,11)
        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)

        fr1 = Fractions(n1*a, d1*b)
        fr2 = Fractions(n2*b, d2*a)
        exo.append("\\[ \\thenocalcul = %s \\times %s \\]" % (Fractions.TeX(fr1),
                   Fractions.TeX(fr2)))
        cor.append("\\[ \\thenocalcul = %s \\times %s \\]" % (Fractions.TeX(fr1),
                   Fractions.TeX(fr2)))
        fr1s = Fractions.simplifie(fr1)
        fr2s = Fractions.simplifie(fr2)
        if abs(fr1s.d) < abs(fr1.d) or abs(fr2s.d) < abs(fr2.d):
            cor.append("\\[ \\thenocalcul = %s \\times %s \\]" % (Fractions.TeXSimplifie(fr1),
                       Fractions.TeXSimplifie(fr2)))
        fr = fr1s * fr2s
        frs = Fractions.simplifie(fr)
        if abs(frs.d) < abs(fr.d):
            cor.append("\\[ \\thenocalcul = %s \\]" % Fractions.TeXProduit(fr1s,
                       fr2s))
        cor.append("\\[ \\boxed{\\thenocalcul = %s} \\]" % Fractions.TeX(frs))
        exo.append("\\stepcounter{nocalcul}%")
        cor.append("\\stepcounter{nocalcul}%")
    exo.append("\\end{multicols}\n")
    cor.append("\\end{multicols}\n")
    return (exo, cor, question)
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 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 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