def moins_dec(nombre_min, nombre_max):
    b = Arithmetique.valeur_alea(nombre_min*10, nombre_max*10)
    a = Arithmetique.valeur_alea(nombre_min*10, nombre_max*10)
    if a >=b:
        return (a/10.0, b/10.0)
    else:
        return (b/10.0, a/10.0)
def moins(nombre_min, nombre_max):
    b = Arithmetique.valeur_alea(nombre_min, nombre_max)
    a = Arithmetique.valeur_alea(nombre_min, nombre_max)
    if a >=b:
        return (a, b)
    else:
        return (b, a)
def valeurs(nbre_min, nbre_max, nbre_decimal_1, nbre_decimal_2):
    while 1:
        nba = Arithmetique.valeur_alea(nbre_min*10**nbre_decimal_1, nbre_max*10**nbre_decimal_1)
        if nba - (nba // 10) * 10:
            break
    while 1:
        nbb = Arithmetique.valeur_alea(nbre_min*10**nbre_decimal_2, nbre_max*10**nbre_decimal_2)
        if nbb - (nbb // 10) * 10:
            break
    nba = nba * 10 ** -nbre_decimal_1
    nbb = nbb * 10 ** -nbre_decimal_2
    deca = [str(nba)[i] for i in range(len(str(nba)))]
    decb = [str(nbb)[i] for i in range(len(str(nbb)))]
    if deca.count('.'):
        posa = deca.index('.')
    else:
        posa = len(deca)
    if decb.count('.'):
        posb = decb.index('.')
    else:
        posb = len(decb)

    lavtvirg = max(posa, posb)
    laprvirg = max(len(deca) - posa, len(decb) - posb)
    return (nba, nbb, deca, decb, lavtvirg, laprvirg)
def div(nombre_min, nombre_max):
    # on trouve a et b en valeur absolue
    a_absolu = 2
    while Arithmetique.premier(a_absolu):
        a_absolu = abs(Arithmetique.valeur_alea(nombre_min, nombre_max))
    decomposition_a_absolu = Arithmetique.factor(a_absolu)
    nbre_facteur_a_absolu = len(decomposition_a_absolu)
    decomposition_b_absolu = random.sample(decomposition_a_absolu,random.randrange(1,len(decomposition_a_absolu)))
    b_absolu = 1
    for facteur in  decomposition_b_absolu:
        b_absolu = b_absolu * facteur
    # on choisit le signe possible pour a et b
    a_possible = [-a_absolu , a_absolu]
    b_possible = [-b_absolu , b_absolu]

    if a_possible[1] < nombre_max:
        if nombre_min < a_possible[0]:
            a = a_possible[random.randrange(2)]
        else:
            a = a_possible[1]
    else:
        a = a_possible[0]

    if b_possible[1] < nombre_max:
        if nombre_min < b_possible[0]:
            b = b_possible[random.randrange(2)]
        else:
            b = b_possible[1]
    else:
        b = b_possible[0]

    return (a, b)
def valeurs_priorites_fractions(nb, nombre_min, nombre_max, 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, 1)
        while  abs(d) == 1:
            n = Arithmetique.valeur_alea(nombre_min, nombre_max)
            d = Arithmetique.valeur_alea(nombre_min, nombre_max)
        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 valeurs_quot(nbre_min, nbre_max, nbre_decimal):
    while 1:
        nba = Arithmetique.valeur_alea(nbre_min*10**nbre_decimal, nbre_max*10**nbre_decimal)
        if nba - (nba // 10) * 10:
            break
    puisa = - nbre_decimal
    nbb = Arithmetique.valeur_alea(nbre_min, nbre_max)

    return (nba, nbb, puisa)
def valeurs_prod():
    while 1:
        nba = Arithmetique.valeur_alea(101, 9999)
        if nba - (nba // 10) * 10:
            break
    puisa = Arithmetique.valeur_alea(-3, -1)
    while 1:
        nbb = Arithmetique.valeur_alea(101, 999)
        if nbb - (nbb // 10) * 10:
            break
    puisb = Arithmetique.valeur_alea(-3, -1)
    return (nba, nbb, puisa, puisb)
def valeurs_prod(nbre_min, nbre_max, nbre_decimal_1 , nbre_decimal_2):
    while 1:
        nba = Arithmetique.valeur_alea(nbre_min*10**nbre_decimal_1, nbre_max*10**nbre_decimal_1)
        if nba - (nba // 10) * 10:
            break
    puisa = - nbre_decimal_1
    while 1:
        nbb = Arithmetique.valeur_alea(nbre_min*10**nbre_decimal_2, nbre_max*10**nbre_decimal_2)
        if nbb - (nbb // 10) * 10:
            break
    puisb = - nbre_decimal_2
    return (nba, nbb, puisa, puisb)
def div_dec(nombre_min, nombre_max):
    a = 2
    while Arithmetique.premier(a):
        a = Arithmetique.valeur_alea(nombre_min*10, nombre_max*10)

    decomposition_a = Arithmetique.factor(a)
    nbre_facteur_a = len(decomposition_a)
    
    decomposition_b = random.sample(decomposition_a,random.randrange(1,len(decomposition_a)))
    b = 1
    for facteur in  decomposition_b:
        b = b * facteur
    return (a/10.0, b/10.0)
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 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 valeurs(nombre_min, nombre_max, carre_parfait, non_simplifiable):
    iteration = 0
    while True:
        # generation d'un nombre entre nombre_min et nombre_max
        nombre = random.randrange(nombre_min, nombre_max)
        # decomposition en facteur premier
        decomposition = Arithmetique.factor(nombre)
        compte = [(k, decomposition.count(k)) for k in set( decomposition)]
        # les facteurs qui apparaissent 2 fois forment le carré, les autres sont le coefficient   
        (coefficient, carre) = (1, 1)
        for i in range(len(compte)):
            coefficient = coefficient * compte[i][0] ** (compte[i][1] % 2)
            carre = carre * compte[i][0] ** (compte[i][1] / 2)
        #Choix
        if carre_parfait == 1 and non_simplifiable == 0 and coefficient == 1:
            break
        if carre_parfait == 0 and non_simplifiable == 1 and carre == 1:
            break
        if carre_parfait == 0 and non_simplifiable == 0 and coefficient != 1 and carre != 1:
            break
        # Controle du bouclage si l'utilisateur fait un choix de valeur min et max absurde
        if iteration > 10000:
            (coefficient, carre) = (0, 0)
            break
    return coefficient, carre
def valeurs_units():
    """
    renvoie les valeurs pour les conversions d'unités
    """

    a = Arithmetique.valeur_alea(101, 999)
    p = random.randrange(-2, 0)
    unit = random.randrange(3)
    if unit:
        #mètres ou grammes, on peut utiliser les k
        imax = 7
    else:
        #Litres, donc pas de kL
        imax = 6

    div0 = random.randrange(imax + p)

    while 1:
        div1 = random.randrange(imax)
        if div0 != div1:
            break

    if not unit: #Litres, donc pas de kL donc on décale d'un rang
        div0, div1 = div0 + 1, div1 + 1

    return (a, p, unit, div0, div1)
def produits_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)
        fr1 = Fractions(n1, d1)
        fr2 = Fractions(n2, d2)
        simplifiable = abs(fr1.d * fr2.n) !=   Fractions.simplifie(fr1 / fr2).d
        if not simplifiable:
            if level ==1:
                break
        else:
            if level ==2:
                break
    l = [fr1, '/', fr2]
    (cor, res, niveau) = OperateurPrioritaire(l, 4, solution=[])
    return (l, cor, res)
def valeurs10(nb):  # renvoie nb valeur de chaque type : *10, /10, *0.1
    l = []
    for i in range(nb):
        if random.randrange(0, 1):
            l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,
                     0), 10 ** (i + 1), '*'))
        else:
            l.append((10 ** (i + 1), Arithmetique.valeur_alea(111, 999) * 10 **
                     random.randrange(-3, 0), '*'))
    for i in range(nb):
        l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,
                 0), 10 ** (i + 1), '/'))
    for i in range(nb):
        if random.randrange(0, 1):
            l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,
                     0), 10 ** (-i - 1), '*'))
        else:
            l.append((10 ** (-i - 1), Arithmetique.valeur_alea(111, 999) * 10 **
                     random.randrange(-3, 0), '*'))
    return l
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 valeurs():
    nba = Arithmetique.valeur_alea(111, 99999)
    while 1:
        nbb = Arithmetique.valeur_alea(111, 99999)
        if nbb - (nbb // 10) * 10:
            break
    puisb = Arithmetique.valeur_alea(-2, 0)
    nbb = nbb * 10 ** puisb
    deca = [str(nba)[i] for i in range(len(str(nba)))]
    decb = [str(nbb)[i] for i in range(len(str(nbb)))]
    if random.randrange(2):
        (nba, deca, nbb, decb) = (nbb, decb, nba, deca)
    if deca.count('.'):
        posa = deca.index('.')
    else:
        posa = len(deca)
    if decb.count('.'):
        posb = decb.index('.')
    else:
        posb = len(decb)

    lavtvirg = max(posa, posb)
    laprvirg = max(len(deca) - posa, len(decb) - posb)
    return (nba, nbb, deca, decb, lavtvirg, laprvirg)
def valeurs_produit(nombre_min, nombre_max):
    iteration = 0
    while True:
        # generation de 2 nombres entre nombre_min et nombre_max
        nombre1 = random.randrange(nombre_min, nombre_max)
        nombre2 = random.randrange(nombre_min, nombre_max)
        # decomposition en facteur premier du produit des 2 nombres
        decomposition = Arithmetique.factor(nombre1*nombre2)
        compte = [(k, decomposition.count(k)) for k in set( decomposition)]
        # les facteurs qui apparaissent 2 fois forment le carré, les autres sont le coefficient   
        (coefficient, carre) = (1, 1)
        for i in range(len(compte)):
            coefficient = coefficient * compte[i][0] ** (compte[i][1] % 2)
            carre = carre * compte[i][0] ** (compte[i][1] / 2)
        #Choix
        if coefficient != 1 and carre != 1:
            break  
        # Controle du bouclage si l'utilisateur fait un choix de valeur min et max absurde
        if iteration > 10000:
            (nombre1, nombre2, coefficient, carre, decomposition) = (0, 0, 0, 0, 0)
            break 
    return nombre1, nombre2, coefficient, carre, decomposition
def valeurs10(operation):  # renvoie nb valeur de chaque type : *10, /10, *0.1, /0.1
    l = []
    for i in range(2):
        if operation == 0:
            if random.randrange(0, 1):
                l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,0), 10 ** (i + 1), '*'))
            else:
                l.append((10 ** (i + 1), Arithmetique.valeur_alea(111, 999) * 10 **random.randrange(-3, 0), '*'))
        if operation == 1:
            l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,0), 10 ** (i + 1), '/'))
        if operation == 2:
            if random.randrange(0, 1):
                l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,0), 10 ** (-i - 1), '*'))
            else:
                l.append((10 ** (-i - 1), Arithmetique.valeur_alea(111, 999) * 10 **random.randrange(-3, 0), '*'))
        if operation == 3:
            l.append((Arithmetique.valeur_alea(111, 999) * 10 ** random.randrange(-3,0), 10 ** (-i - 1), '/'))
    return l
def moins(pyromax):
    (a, b) = (Arithmetique.valeur_alea(-pyromax, pyromax), Arithmetique.valeur_alea(-pyromax,
              pyromax))
    return (a + b, a)
def plus(pyromax):
    (a, b) = (Arithmetique.valeur_alea(-pyromax, pyromax), Arithmetique.valeur_alea(-pyromax,
              pyromax))
    return (a, b)
def plus(valeurmax):
    (a, b) = (Arithmetique.valeur_alea(1, valeurmax), Arithmetique.valeur_alea(1,
              valeurmax))
    return (a, b)
def moins_dec(pyromax):
    (a, b) = (Arithmetique.valeur_alea(-10*pyromax, 10*pyromax)/10.0, Arithmetique.valeur_alea(-10*pyromax, 10*pyromax)/10.0)
    return (a + b, a)
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 moins(valeurmax):
    (a, b) = (Arithmetique.valeur_alea(1, valeurmax), Arithmetique.valeur_alea(1,
              valeurmax))
    return (a + b, a)
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 div(valeurmax):
    (a, b) = (Arithmetique.valeur_alea(1, valeurmax), Arithmetique.valeur_alea(1,
              valeurmax))
    return (a * b, a)
def div(pyromax):
    (a, b) = (Arithmetique.valeur_alea(-pyromax, pyromax), Arithmetique.valeur_alea(-pyromax,
              pyromax))
    return (a * b, a)
def plus(nombre_min, nombre_max):
    (a, b) = (Arithmetique.valeur_alea(nombre_min, nombre_max), Arithmetique.valeur_alea(nombre_min, nombre_max))
    return (a, b)
def plus_dec(nombre_min, nombre_max):
    (a, b) = (Arithmetique.valeur_alea(nombre_min*10, nombre_max*10), Arithmetique.valeur_alea(nombre_min*10, nombre_max*10))
    return (a/10.0, b/10.0)