def tableau_tex(titres, larg="c", eff=1, freq=1, val=[[],[]],total=1):
    """Génère le tableau des effectifs (liste val[1]) et fréquences (liste val[2])."""
    cols = len(titres)
    tableau_tex = u"\\begin{tabular}{|>{\\bfseries}c|*{"+str(cols-1)+"}{"+larg+"|}"
    
    if total:
        tableau_tex += ">{\\centering\\bfseries\\arraybackslash}p{2cm}|}\n"
    else:
        tableau_tex += "}\n"
        
    tableau_tex += u"\\hline\n"
    
    for titre in titres: # Ligne de titre, avec astuce pour éviter le cadre sur la dernière cellule "Total"
        tableau_tex += u"\\textbf{"+titre+"} & "
    
    if total:    
        tableau_tex += u"\\textbf{Total} \\\\\\hline\n"
    else:
        tableau_tex = tableau_tex[:-2]+u"\\\\\\hline\n"
    
    if eff:
        tableau_tex += "Effectifs"
        if len(val[0])>0:
            somme = 0
            for effectif in val[0]:
                if effectif < 0:
                    tableau_tex += " & "
                else:
                    tableau_tex += " & "+decimaux(effectif)
                    somme += effectif
        else:
            tableau_tex += " & " * (cols-1)
            somme = ""
        
        if total:    
            tableau_tex += " & "+str(somme)+"\\\\\\hline\n"
        else:
            tableau_tex += "\\\\\\hline\n"

    if freq:
        tableau_tex += u"Fréquences ( \\% )"
        if len(val[1])>0:
            for frequence in val[1]:
                somme = "100"
                if frequence < 0:
                    tableau_tex += " & "
                else:
                    tableau_tex += " & "+decimaux(frequence)
        else:
            tableau_tex += " & " * (cols-1)
            somme = ""
            
        if total:    
            tableau_tex += " & "+somme+"\\\\\\hline\n"
        else:
            tableau_tex += "\\\\\\hline\n"
    
    tableau_tex += "\\end{tabular}"    
    
    return tableau_tex
def exo_aire_diques(parametre):
    question = ""
    exo = []
    cor = []
    rayon1 = 2*(random.randrange(33) + 1)
    rayon2 = int(1.5*rayon1)
    i=random.randrange(2)
    if i==0:
        donnees=('rayons', rayon1, rayon2)
    else:
        donnees=(u'diamètres', 2*rayon1, 2*rayon2)
    difference_des_carres = rayon2**2-rayon1**2
    aire_arrondie = arrondir(str(3.14 * difference_des_carres))
    enonce = \
        u"""\\begin{minipage}{4cm}
\\begin{pspicture}(-2,-2)(2,2)
\\pscircle[fillstyle=solid](0,0){1.5}
\\pscircle[fillstyle=solid, fillcolor=white](0,0){1}
\\psdots[dotstyle=x](0,0)
\\rput(0.3;60){$O$}
\\end{pspicture}
\\end{minipage}\\hfill
\\begin{minipage}{13cm}
On considère deux cercles de centre $O$ et de %s respectifs $\\unit[%s]{cm}$ et $\\unit[%s]{cm}$.\\par
Calculer l'aire de la couronne circulaire (partie colorée) comprise entre les deux cercles en arrondissant le résultat au $\\unit{cm^2}$ le plus proche.""" % donnees
    exo.append(enonce)
    cor.append(enonce)
    cor.append("\\par\\dotfill{}\\\\\n")
    if i==0:
        cor.append(u"On calcule l'aire du disque de rayon $\\unit[%s]{cm}$:" % rayon2)
        cor.append(u"\\[\\pi \\times %s^2 = \\pi \\times %s \\times %s = \\unit[%s \\pi]{cm^2}\\]" % (rayon2,  rayon2, rayon2, decimaux(rayon2**2)))
        cor.append(u"On calcule l'aire du disque de rayon $\\unit[%s]{cm}$:" % rayon1)
        cor.append(u"\\[ \\pi \\times %s^2 = \\pi \\times %s \\times %s = \\unit[%s \\pi]{cm^2}\]" % (rayon1, rayon1, rayon1, decimaux(rayon1**2)))
    else:
        cor.append(u"Un disque de diamètre $\\unit[%s]{cm}$ a pour rayon $%s \div 2 = \\unit[%s]{cm}$. Calculons son aire:" % (2*rayon2, 2*rayon2, rayon2))
        cor.append(u"\\[\\pi \\times %s^2 = \\pi \\times %s \\times %s = \\unit[%s \\pi]{cm^2}\\]" % (rayon2,  rayon2, rayon2, decimaux(rayon2**2)))
        cor.append(u"Un disque de diamètre $\\unit[%s]{cm}$ a pour rayon $%s \div 2 = \\unit[%s]{cm}$. Calculons son aire:" % (2*rayon1, 2*rayon1, rayon1))
        cor.append(u"\\[\\pi \\times %s^2 = \\pi \\times %s \\times %s = \\unit[%s \\pi]{cm^2}\\]" % (rayon1,  rayon1, rayon1, decimaux(rayon1**2)))
    cor.append(u"L'aire $\\mathcal{A}$ de la couronne est obtenue en retranchant l'aire du disque de rayon  $\\unit[%s]{cm}$  à l'aire du disque de rayon  $\\unit[%s]{cm}$:"% (rayon1, rayon2))
    cor.append(u"\\[\\mathcal{A} = %s \\pi  - %s \\pi= (%s - %s)\\pi =\\unit[%s \\pi]{cm^2}\\]" % (decimaux(rayon2**2), decimaux(rayon1**2), decimaux(rayon2**2), decimaux(rayon1**2), decimaux(difference_des_carres)))
    cor.append(u"L'aire exacte de la couronne est $\\unit[%s \\pi]{cm^2}$." % (decimaux(difference_des_carres)))
    cor.append(u"En prenant 3,14 comme valeur approchée du nombre $\\pi$, on obtient :")
    cor.append(u"\\[\\mathcal{A}  \\approx %s \\times 3,14\\]" % decimaux(difference_des_carres))
    cor.append(u"\\[\\boxed{\\mathcal{A} \\approx  \\unit[%s]{cm^2}}\\]" % decimaux(aire_arrondie))
    exo.append("\\end{minipage}\n")
    cor.append("\\end{minipage}\n")
    return (exo, cor, question)
def tableau_diagramme_tex(typed=2,val=[[],[]],larg="c"):
    """Génère le tableau de calculs des angles ou des longueurs pour le corrigé de la construction des diagrammes."""
    tab = ""
    cols = len(val[0])
    tab = u"\\begin{tabular}{|>{\\bfseries}c|*{"+str(cols-1)+"}{"+larg+"|}>{\\centering\\bfseries\\arraybackslash}p{2cm}|}\n"
    tab += u"\\hline\n"    
    
    for titre in val[0]: # Ligne de titre, avec astuce pour éviter le cadre sur la dernière cellule "Total"
        tab += u"\\textbf{"+titre+"} & "
    tab += u"\\textbf{Total} \\\\\\hline\n"
    
    tab += u"Fréquences ( \\% )"

    for frequence in val[1]:
        tab += " & "+decimaux(frequence)
       
    tab += " & 100 \\\\\\hline\n"
      
    if typed == 1: # Diagramme en bâtons
        texte = u"Comme 10\\% sont représentés par 1cm, il faut diviser chaque fréquence par 10 pour obtenir la longueur ( arrondie au dixième ) du bâton à dessiner :\\par\n"
        tab = texte + tab
        tab += u"Hauteur ( cm )"
        for frequence in val[1]:
            tab += " & "+decimaux(round(frequence/10.0,1))
        tab += " & 10 \\\\\\hline\n"
        
    elif typed == 2: # Diagramme circulaire
        texte = u"Comme il y a $360^{\circ}$ dans un cercle pour représenter 100\\%, il faut multiplier chaque fréquence par 3,6 pour connaître son angle ( arrondi au degré ) de représentation dans le diagramme :\\par\n"
        tab = texte + tab
        tab += u"Angle ( Degrés )"        
        for frequence in val[1]:
            tab += " & "+decimaux(round(frequence*3.6,0))
        tab += " & 360 \\\\\\hline\n"
        
    elif typed == 3: # Diagramme semi-circulaire
        texte = u"Comme il y a $180^{\circ}$ dans un cercle pour représenter 100\\%, il faut multiplier chaque fréquence par 1,8 pour connaître son angle ( arrondi au degré ) de représentation dans le diagramme :\\par\n"
        tab = texte + tab
        tab += u"Angle ( Degrés )"        
        for frequence in val[1]:
            tab += " & "+decimaux(round(frequence*1.8,0))
        tab += " & 180 \\\\\\hline\n"        
    
    tab += "\\end{tabular}\n"
    
    return tab
def exo_pi():
    """Exercice sur les décimales de Pi."""
    global exo, cor
    
    pi = "14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009" # 2000 décimales de Pi après la virgule
    
    nb_dec = random.randint(50,100)
    idx_dec = random.randint(0,2000-nb_dec)
    dec_str = list(pi[idx_dec:(idx_dec+nb_dec)])
    dec = [int(d) for d in dec_str]
    dec_tex = "\\begin{center}\n\\begin{tabular}{|*{20}{p{0.2cm}}|}\n\\hline\n"
    
    for d in range(len(dec_str)):
        dec_tex += dec_str[d] + " & "
        if ((d+1) % 20 == 0):
            dec_tex = dec_tex[:-3]+"\\\\\n"
    dec_tex += " & "*(19-len(dec_str)%20)+"\\\\\n"
    dec_tex += "\\hline\n\\end{tabular}\n\\end{center}"
     
    effectifs = [dec.count(i) for i in range(10)]    
    frequences = [round(i*100.0/nb_dec,2) for i in effectifs] # FIX somme pas toujours égale à 100%
    
    tableau = tableau_tex([u"Chiffres", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],">{\\centering}p{0.5cm}") 
    tableau_cor = tableau_tex([u"Chiffres", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],">{\\centering}p{0.8cm}",1,1,[effectifs,frequences])
    
    exo.append(u"Voici une liste de chiffres choisis au hasard dans les décimales de $\\pi$ :\\par")    
    cor.append(u"Voici une liste de chiffres choisis au hasard dans les décimales de $\\pi$ :\\par")
    exo.append(dec_tex) 
    cor.append(dec_tex)
    exo.append("\\begin{enumerate}")
    cor.append("\\begin{enumerate}")
    exo.append(u"\\item Compléter le tableau ci-dessous, sachant que les fréquences doivent être arrondies au centième.\\par")
    cor.append(u"\\item Compléter le tableau ci-dessous, sachant que les fréquences doivent être arrondies au centième.\\par")   
    exo.append("\\end{enumerate}")    
    exo.append(tableau)
    exo.append(u"\\par")
    cor.append(u"Chaque effectif se complète en comptant le nombre d'apparition de chaque chiffre dans la liste de l'énoncé.")
    cor.append(u"Comme les chiffres sont rangés par 20, on voit assez rapidement que le nombre total de chiffres est de "+str(nb_dec)+".\\par")
    cor.append(u"Pour le calcul des fréquences, on multiplie l'effectif par 100, et on divise par le nombre total de chiffres, puis il ne faut pas oublier d'arrondir au centième.\\par\n")
    cor.append(u"Par exemple pour la fréquence du chiffre 1 : $\\dfrac{"+decimaux(effectifs[0])+"\\times 100}{"+str(nb_dec)+"} \\approx "+decimaux(frequences[0])+"$.\\par")
    cor.append("\\end{enumerate}")
    cor.append(tableau_cor)
    exo.append("\\begin{enumerate}")
    cor.append("\\begin{enumerate}")
    exo.append(u"\\item[$\\blacktriangleright$\\textbf{2.}] Représenter la répartition des chiffres dans un diagramme en bâtons avec 1~cm pour 10\\%.\\par")
    cor.append(u"\\item[$\\blacktriangleright$\\textbf{2.}] Représenter la répartition des chiffres dans un diagramme en bâtons avec 1~cm pour 10\\%.\\par") 
    exo.append("\\end{enumerate}")
    cor.append("\\end{enumerate}")
    
    diagramme = diagramme_tex(1,[[u"Valeurs", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],frequences])
    diagramme_tableau = tableau_diagramme_tex(1,[[u"Valeurs", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],frequences],">{\\centering}p{0.8cm}")
    
    cor.append(diagramme_tableau)  
    cor.append("\\bigskip")
    cor.append(diagramme)  
    
    return False
def exo_fruits(parametre):
    fruit = ["Cerises", "Tomates", "Pommes", "Poires", "Raisin", "Oranges"][randrange(6)]
    while 1:
        a, b, c = randint(10, 50)/10.0, randint(10, 50)/10.0, randint(10, 50)/10.0
        if a != b and a != c and b != c:
            break
    tarif = randint(20, 50)/10.0
    fruits_c = (fruit, a, b, c)
    fruits_e = (fruit, decimaux(a), decimaux(b), "")
    prix_c = ("prix", decimaux(fruits_c[1]*tarif), decimaux(fruits_c[2]*tarif), decimaux(fruits_c[3]*tarif))
    prix_e = ("prix", decimaux(fruits_c[1]*tarif), "", decimaux(fruits_c[3]*tarif))
    
    fruits_c = (fruit, decimaux(a), decimaux(b), decimaux(c))
    tableau_exo = ["\\begin{tabular}{|l|c|c|c|}",
               "\hline",
               u"%s (en kg) & %s & %s &  %s  \\\\"%fruits_e,
               "\hline",
               u"%s (en \\euro)  & %s &  %s  & %s \\\\"%prix_e,
               "\hline",
               "\\end{tabular}"]
    tableau_cor = ["\\begin{tabular}{|l|c|c|c|}",
               "\hline",
               u"%s (en kg) & %s & %s &  \\bf %s  \\\\"%fruits_c,
               "\hline",
               u"%s (en \\euro)  & %s &  \\bf %s  & %s \\\\"%prix_c,
               "\hline",
               "\\end{tabular}"]
    question = ""
    exo = [u"Le prix à payer est proportionnel à la masse de fruits achetés.\\par",
           u"Détermine la valeur des cases vides"]
    cor = [u"Le prix à payer est proportionnel à la masse de fruits achetés.\\par",
           u"Détermine la valeur des cases vides"]
    exo += ["\n"] + tableau_exo
    cor += ["\n"] + tableau_cor
    cor.append("$$\\frac{%s \\times %s}{%s} = %s \\quad;\\qquad"%(prix_e[1], fruits_e[2], fruits_e[1],prix_c[2]))
    cor.append("\\frac{%s \\times %s}{%s} = %s $$"%(fruits_c[1], prix_c[3], prix_e[1],fruits_c[3]))
    
    return (exo, cor, question)
def proportionnalite_3eme(parametre):
    #choix exercice
    i = randrange(2)
    #choix valeurs
    [min_prct, max_prct, min_nbre, max_nbre] = [[40, 80, 40, 65],
                                                [40, 80, 65, 90]][i]
    #choisit les valeurs du groupe A
    #prctA : pourcentage d'individu dans le groupe A entre 40% et 80%
    #totA : nombre total du groupe A entre 40 et 70
    prctA, totA = choix_valeurs(min_prct = 40, max_prct = 80, min_nbre = 40, max_nbre = 65)

    #On choisit B avec des valeurs différentes
    while 1:
        prctB, totB = choix_valeurs(min_prct = 40, max_prct = 80, min_nbre = 40, max_nbre = 65)
        if prctA != prctB and totB != totA:
            break
        
    Total = totA + totB

    #calcul
    nbA = (prctA * totA / 100)
    nbB = (prctB * totB / 100)
    nbTotal = ((nbA + nbB))
    prct_final = (100.0*nbTotal/Total)
    prct_final_arrondi = round(100.0*nbTotal/Total, 1)
    if prct_final == prct_final_arrondi:
        approx = "="
    else:
        approx = "\\approx"
    
    #La situation
    texte = [u"Lors d'un voyage scolaire, les élèves sont répartis dans deux bus :",
             u"Au collège Dubois, il y a $%s$ élèves en quatrièmes et $%s$ élèves en troisièmes."%(totA,totB)][i]

    #Les deux groupes
    ligne1 = [u"\\item Bus A : %s élèves dont %s %s de garçons."%(totA, prctA,"\\%"),
              u"\\item $%s$ %s des élèves de quatrièmes possèdent un ordinateur ;"%(prctA,"\\%")][i]
    ligne2 = [u"\\item Bus A : %s élèves dont %s %s de garçons."%(totB, prctB,"\\%"),
              u"\\item $%s$ %s des élèves de troisièmes possèdent un ordinateur ;"%(prctB,"\\%")][i]

    #La question
    question = [u"Quel est, sur l'ensemble des deux bus, le pourcentage de garçons ?\\par",
                u"Quel est le pourcentage des élèves qui possèdent un ordinateur ?\\par"][i]

    #La correction
    correction =[#Dans le bus
        [u"Dans le bus A, il y a $\\cfrac{%s \\times %s}{100} = %s$ garçons.\\par"%(prctA, totA, decimaux(nbA)),
           u"Dans le bus B, il y a $\\cfrac{%s \\times %s}{100} = %s$ garçons.\\par"%(prctB, totB, decimaux(nbB)),
           u"On en déduit qu'il y a $%s + %s = %s$ garçons sur un total de $%s + %s = %s $ élèves.\\par"
                   %(decimaux(nbA), decimaux(nbB), nbTotal, totA, totB, Total),
            u" Le pourcentage de garçons sur l'ensemble des deux bus est donc de $\\cfrac{%s}{%s}\\times 100 %s %s%s$"
                  %(nbTotal, Total, approx, decimaux(prct_final_arrondi), "\,\\%")],
        #À l'ordinateurs
                 [u"En quatrièmes, $\\cfrac{%s \\times %s}{100} = %s$ élèves possèdent un ordinateur.\\par"%(prctA, totA, decimaux(nbA)),
                  u"En troisièmes, $\\cfrac{%s \\times %s}{100} = %s$ élèves possèdent un ordinateur.\\par"%(prctB, totB, decimaux(nbB)),
                  u"On en déduit qu'il y a $%s + %s = %s$ élèves qui possèdent un ordinateur sur un total de $%s + %s = %s $ élèves.\\par"
                   %(decimaux(nbA), decimaux(nbB), nbTotal, totA, totB, Total),
                   u" Le pourcentage d'élèves possédant un ordinateur est donc de $\\cfrac{%s}{%s}\\times 100 %s %s%s$"
                  %(nbTotal, Total, approx, decimaux(prct_final_arrondi), "\,\\%")],
                   ][i]
    question = ""
    exo = [texte,
           "\\begin{itemize}",
           ligne1,
           ligne2,
           "\\end{itemize}",
           question,
           ]
        
    cor = [texte,
           "\\begin{itemize}",
           ligne1,
           ligne2,
           "\\end{itemize}",
           question,
           "\\dotfill\\par"
           ] + correction
    
    
    return (exo, cor, question)
def exo_echelles(parametre):
    """À partir d'un plan tracé, déterminer l'échelle et des longueurs déterminées."""

    #Échelle
    echelle = [ 100, 250, 400, 500, 750, 1000][randrange(6)]

    #figure : un plan d'appartement déssiner en psTricks
    a, d = randint(40,60), randint(36,45)
    b, c = randint(8, d - 27), randint(9, a - 25 )
    xF = a - c
    xE = xF - 6
    yK = b + 9
    yF = b - 6
    yH = b
    #Calculs des grandeurs réelles en mm !
    reels = [echelle * a, echelle * b, echelle * c, echelle * d]
    
    plan = [a, b, c, d]
    #choix permet de choisir si on donne a, b, c ou d en énoncé
    choix = randrange(4)
    reponses = ["a", "b", "c", "d"]
    enonce = reponses.pop(choix)
    
    #sur la deuxième ligne du tableau, on écrit en cm, en gras, les nombres calculés
    tab_reels = [ "\\bf"*(i!=choix) + decimaux(reels[i]/10.0) for i in range(4)]
    
    #Pour placer les quatre lettres sur le plan
    cotation_couleur = [["a", ""],
                        ["b", ""],
                        ["c", ""],
                        ["d", ""]]
        #la longueur donnée est tracée en bleu
    cotation_couleur[choix][1] = "enonce"
    
    #figure PSTricks en fonction des paramètres a, d, xE, XF, yF
    figure = ["{",
              "\\psset{PointName = none,  PointSymbol = none, unit = 1mm, linewidth = .5pt}",
              "\\definecolor{enonce}{rgb}{0.11,0.56,0.98}",
              "\\begin{pspicture}(-10mm, -10mm)(50mm ,50mm)",
              #le rectangle ABCD
              "\\pstGeonode[CurveType = polygon, linewidth = 1pt](0, 0)A(%s,0)B (%s, %s)C (0, %s)D"%(a, a, d, d),
              #les points permettant de placer les cloisons
              "\\pstGeonode(%s, 0){E1}(%s, %s){E2}(%s, 0){F1}(%s, %s){F2}"%(xE, xE, yF, xF, xF, yF),
              "\\pstGeonode(%s, %s){G1}(%s, %s){G2}(%s, %s){G3}"%(a, b, xF, b, xF, 25),
              "\\pstGeonode(%s, %s){H1}(%s, %s){H2}(%s, %s){H3}(%s, %s){H4}"%(xE, b, xE, 25, xE, yK, 15, yK),
              "\\pstGeonode(0, %s){K2}(7, %s){K1}"%(yK, yK),
              "\\pstGeonode(%s, %s){J1}(%s, %s){J2}(%s, %s){J3}(%s, %s){J4}"%(xE, d - 7, xE, d, xF, d - 7, xF, d),
              #trace les cloisons, limitées par des tirets
              "\\ncline{-|}{E1}{E2}\\ncline{-|}{F1}{F2}",
              "\\ncline{|-}{J1}{J2}\\ncline{|-}{J3}{J4}",
              "\\ncline{|-}{K1}{K2}",
              "\\ncline{G1}{G2}\\ncline{|-|}{G3}{G2}",
              "\\ncline{|-|}{H1}{H2}\\ncline{-|}{H3}{H4}",
              #place les cotations sr la figure, l'énoncé en bleu
              ncotation_h("D", "C", cotation_couleur[0][0], cotation_couleur[0][1]),
              ncotation("B", "G1", cotation_couleur[1][0], cotation_couleur[1][1]),
              ncotation("F1", "B", cotation_couleur[2][0], cotation_couleur[2][1]),
              ncotation_h("A", "D", cotation_couleur[3][0], cotation_couleur[3][1]),
              "\\end{pspicture}",
              "}"]

    question = ""
    exo = [u"Sur ce plan, la longueur $%s$ mesure en réalité \\unit[%s]{m} :\n"%(enonce, decimaux(reels[choix]/1000.0))] \
          + figure +\
           ["\\begin{enumerate}",
           u"\\item Déterminer l'échelle de ce plan.",
           u"\\item Déterminer les longueurs réelles $%s$, $%s$ et $%s$."%(reponses[0], reponses[1], reponses[2]),
            "\\end{enumerate}"]
    cor = [u"Sur ce plan, la longueur $%s$ mesure en réalité \\unit[%s]{m} : \n"%(enonce, decimaux(reels[choix]/1000.0))] \
           + figure +\
          ["\\begin{enumerate}",
           u"\\item Déterminer l'échelle de ce plan.\\par",
           u"Sur le plan, je mesure que $%s=\\unit[%s]{cm}$.\\par"%(enonce, decimaux(plan[choix]/10.0) ),
           u"Or on sait que en réalité $%s = \\unit[%s]{m} = \\unit[%s]{cm}$"%(enonce, decimaux(reels[choix]/1000.0),decimaux(reels[choix]/10.0)),
           u" et  $%s \\div %s = %s$.\\par"%(decimaux(reels[choix]), decimaux(plan[choix]), decimaux(echelle)),
           u"L'échelle de ce plan est donc $1/%s^e$."%echelle,
           u"\\item Déterminer les longueurs réelles $%s$, $%s$ et $%s$.\n"%(reponses[0], reponses[1], reponses[2]),
           u"Grâce à la question précédente, je peux compléter le tableau :\n",
           "\\begin{tabular}{|l|c|c|c|c|c}",
           ("\\multicolumn{1}{c}{}"+"&\\multicolumn{1}{c}{$%s$}"*4+"\\\\")%("a", "b", "c", "d"),
           "\\cline{1-5}",
           "Sur le plan (en cm)  & %s & %s & %s & %s &\\rnode{plan1}{}\\\\"%tuple(map(lambda n:decimaux(n/10.0),plan)),
           "\\cline{1-5}",
           u"En réalité (en cm)  & %s & %s & %s & %s &\\rnode{plan2}{}\\\\"%tuple(tab_reels),
           "\\cline{1-5}",
           "\\end{tabular}\n",
           "\\ncbar{->}{plan1}{plan2}\\Aput{$\\times %s$}"%echelle,
           u"Pour conclure, on convertit ses longueurs en m :\\par",
           "$$a = \\unit[%s]{m} \\quad ; \\quad b = \\unit[%s]{m} \\quad ; \\quad c  = \\unit[%s]{m} \\quad ; \\quad d =\\unit[%s]{m}$$"\
                   %tuple(map(lambda n:decimaux(n/1000.0),reels)),
           "\\end{enumerate}"]
            
    return (exo, cor, question)
def exo_de():
    """Exercice sur le lancer d'un dé."""
    global exo, cor
    
    nb_simul = random.randint(50,80)
    simul = []
    simul_tex = ""
    for f in range(nb_simul): # Simulation de nb_simul lancés d'un dé
        temp = random.randint(1,6)
        simul.append(temp)
        simul_tex += str(temp) + " "
        if ((f+1) % 25 == 0):
            simul_tex += "\\par\n"
        
    effectifs = [simul.count(i+1) for i in range(6)]    
    frequences = [round(i*100.0/nb_simul,2) for i in effectifs] # FIX somme pas toujours égale à 100%
    
    tableau = tableau_tex([u"Valeurs", "1", "2", "3", "4", "5", "6"],">{\\centering}p{1cm}") 
    tableau_cor = tableau_tex([u"Valeurs", "1", "2", "3", "4", "5", "6"],">{\\centering}p{1cm}",1,1,[effectifs,frequences])
    
    exo.append(u"Voici une liste des résultats obtenus en lançant plusieurs fois un dé à six faces :\\par")    
    cor.append(u"Voici une liste des résultats obtenus en lançant plusieurs fois un dé à six faces :\\par")
    exo.append(simul_tex)
    cor.append(simul_tex)
    exo.append(u"\\bigskip")
    cor.append(u"\\bigskip")
    exo.append("\\begin{enumerate}")
    cor.append("\\begin{enumerate}")
    exo.append(u"\\item Compléter le tableau ci-dessous, sachant que les fréquences doivent être arrondies au centième.\\par")
    cor.append(u"\\item Compléter le tableau ci-dessous, sachant que les fréquences doivent être arrondies au centième.\\par")   
    exo.append(tableau)
    exo.append(u"\\bigskip")
    cor.append(u"Chaque effectif se complète en comptant le nombre d'apparition de chaque chiffre dans la liste de l'énoncé.")
    cor.append(u"Comme les chiffres sont rangés par 25, on voit assez rapidement que le nombre total de chiffres est de "+str(nb_simul)+".\\par")
    cor.append(u"Pour le calcul des fréquences, on multiplie l'effectif par 100, et on divise par le nombre total de chiffres, puis il ne faut pas oublier d'arrondir au centième.\\par\n")
    cor.append(u"Par exemple pour la fréquence du chiffre 1 : $\\dfrac{"+str(effectifs[0])+"\\times 100}{"+str(nb_simul)+"} \\approx "+decimaux(frequences[0])+"$.\\par")
    cor.append(tableau_cor)
    cor.append(u"\\bigskip")
    exo.append(u"\\item Représenter la répartition des chiffres dans un diagramme en bâtons avec 1cm pour 10\\%.\\par")
    cor.append(u"\\item Représenter la répartition des chiffres dans un diagramme en bâtons avec 1cm pour 10\\%.\\par") 
    
    diagramme = diagramme_tex(1,[[u"Valeurs", "1", "2", "3", "4", "5", "6"],frequences])
    diagramme_tableau = tableau_diagramme_tex(1,[[u"Valeurs", "1", "2", "3", "4", "5", "6"],frequences],">{\\centering}p{1cm}")
    
    cor.append(diagramme_tableau)  
    cor.append("\\bigskip")
    cor.append(diagramme)
    
    exo.append("\n\\end{enumerate}")
    cor.append("\n\\end{enumerate}")
    
    return False
def exo_notes():
    """Exercice sur les notes."""
    global exo, cor
 
    len_classe = [4,5][random.randint(0,1)] # Classes de longueur 4 ou 5
    classes = []
    val = 0
    while val+len_classe <= 20:
        classes += [[val,val+len_classe]]
        val = val+len_classe
    
    titres = [u"Classes de notes"]+[u"$" +str(f[0])+u" \leq n < "+str(f[1])+u"$" for f in classes[:-1]]+[u"$" +str(classes[-1][0])+u" \leq n \leq 20$"]
    
    exo.append(u"Voici un tableau regroupant les notes d'une classe lors d'un contrôle :\\par")
    cor.append(u"Voici un tableau regroupant les notes d'une classe lors d'un contrôle :\\par")
    
    nb_eleves = random.randint(25,35)
    notes_tpl = [str(i) for i in range(21)]
    notes = [random.randint(1,20) for i in range(nb_eleves)]
    notes_effectifs = [notes.count(i) for i in range(21)]
    tableau_notes = tableau_tex([u"Notes"]+notes_tpl,">{\\centering\\arraybackslash}p{0.25cm}",1,0,[notes_effectifs,[]],0)
    
    exo.append(tableau_notes)
    cor.append(tableau_notes)
    exo.append(u"\\bigskip")
    cor.append(u"\\bigskip")
    exo.append(u"\\begin{enumerate}")
    cor.append(u"\\begin{enumerate}")
    exo.append(u"\\item Compléter le tableau ci-dessous afin de regrouper les notes par classes et effectuer le calcul des fréquences arrondies au centième :\\par")
    cor.append(u"\\item Compléter le tableau ci-dessous afin de regrouper les notes par classes et effectuer le calcul des fréquences arrondies au centième :\\par")
    exo.append(u"\\end{enumerate}")
    exo.append(tableau_tex(titres,">{\\centering\\arraybackslash}p{2.1cm}"))
    
    classes_effectifs=[0 for f in classes]
    
    for n in notes:
        if n == 20:
            classes_effectifs[-1] += 1
        else:
            for c in classes:
                if c[0] <= n < c[1]:
                    classes_effectifs[classes.index(c)] += 1            

    frequences = [round(i*100.0/nb_eleves,2) for i in classes_effectifs]   
    
    cor.append(u"Chaque effectif se complète en comptant le nombre d'apparition de chaque note dans le tableau de l'énoncé.")
    cor.append(u"Le nombre de notes du contrôle, qui est aussi le nombre d'élèves, est donc de "+str(nb_eleves)+".\\par")
    cor.append(u"Pour le calcul des fréquences, on multiplie l'effectif par 100, et on divise par le nombre total de notes, puis il ne faut pas oublier d'arrondir au centième.\\par\n")
    cor.append(u"Par exemple pour la fréquence des notes dans la première classe : $\\dfrac{"+decimaux(classes_effectifs[0])+"\\times 100}{"+str(nb_eleves)+"} \\approx "+decimaux(frequences[0])+"$.\\par")    
    cor.append(u"\\end{enumerate}")
    cor.append(tableau_tex(titres,">{\\centering\\arraybackslash}p{2.1cm}",1,1,[classes_effectifs,frequences]))
    
    note1_rand = random.randint(0,len(classes)-2)
    note1 = classes[note1_rand][1]
    note2 = 20 - note1
    note2_rand = len(classes)-1-note1_rand
    
    cor.append(u"\\bigskip")    
    exo.append(u"\\begin{enumerate}")
    cor.append(u"\\begin{enumerate}")
    exo.append(u"\\item[$\\blacktriangleright$\\textbf{2.}] Combien d'élèves ont une note strictement inférieure à "+str(note1)+u" ? Supérieure ou égale à "+str(note2)+" ?\\par")
    cor.append(u"\\item[$\\blacktriangleright$\\textbf{2.}] Combien d'élèves ont une note strictement inférieure à "+str(note1)+u" ? Supérieure ou égale à "+str(note2)+" ?\\par")    
    
    card_note1 = 0
    card_note2 = 0

    if note1_rand == 0:
        card_note1 = classes_effectifs[0]
        card_note2 = classes_effectifs[-1]
        texte_note1 = str(card_note1)
        texte_note2 = str(card_note2)
    else:
        tmp = 0
        texte_note1 = ""
        
        while tmp <= note1_rand:
            card_note1 += classes_effectifs[tmp]
            texte_note1 += str(classes_effectifs[tmp]) + " + " 
            tmp += 1
        
        tmp = note2_rand
        texte_note2 = ""
        
        while tmp < len(classes):
            card_note2 += classes_effectifs[tmp]
            texte_note2 += str(classes_effectifs[tmp]) + " + " 
            tmp += 1

        texte_note1 =  texte_note1[:-3]+" = "+str(card_note1)
        texte_note2 =  texte_note2[:-3]+" = "+str(card_note2)
    
    cor.append(u"D'après le tableau rempli précédemment, le nombre d'élèves ayant une note strictement inférieure à "+str(note1)
               +u" sont tous les élèves comptés dans les classes situées à gauche de "+str(note1)
               +u". En effectuant le total des élèves de ces classes, on obtient : "+texte_note1+u" élèves.\\par")
    
    cor.append(u"La réponse à la seconde question se fait de même en comptant tous les effectifs des élèves se situant à droite de "+str(note2)+u".\\par")
    cor.append(u"Le résultat est donc : "+texte_note2+u" élèves.\\par")
    
    exo.append(u"\\end{enumerate}")
    cor.append(u"\\end{enumerate}")
    
    return False