#!/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 # #fonction affine 3e import random from math import * from ..outils.Affichage import decimaux, decimaux_quiz from ..outils.Fractions import Fractions #fractions pyromaths def extreme(a,b,xmin,xmax,ymin,ymax): #donne les extremités de la droite passant par a et b (coordonnées) res=[] x1=float(a[0]) x2=float(b[0]) y1=float(a[1]) y2=float(b[1]) coef=float((y1-y2)/(x1-x2)) if coef != 0: xsort1=float(x1+(ymin-y1)/coef) #abscisse du point d'ordonnée ymin if xsort1 >=xmin and xsort1<=xmax and not(xsort1,ymin) in res: res.append((xsort1,ymin)) xsort2=float(x2+(ymax-y2)/coef) #abscisse du point d'ordonnée ymax if xsort2>=xmin and xsort2<=xmax and not(xsort2,ymax) in res: res.append((xsort2,ymax)) ysort1=float(y1+coef*(xmin-x1)) #ordonnée du point d'abscisse xmin if ysort1 >=ymin and ysort1<=ymax and not (xmin,ysort1)in res: res.append((xmin,ysort1)) ysort2=float(y2+coef*(xmax-x2)) #ordonnée du point d'abscisse xmax if ysort2 >=ymin and ysort2<=ymax and not(xmax,ysort2) in res: res.append((xmax,ysort2)) else: res=[(xmin,y1),(xmax,y1)] return res def vecdir(A,B): #retourne sous forme de liste le vecteur directeur normé de la droite (AB) norm= sqrt((B[0]-A[0])**2+(B[1]-A[1])**2) u=[(B[0]-A[0])/norm,(B[1]-A[1])/norm] if u[0]<0: u[0]=-u[0] u[1]=-u[1] return u def validedroite(A,B): #valide le choix du couple A B pour qu'ils ne soient pas "collés", # la droite (AB) ne sera ni horizontale ni verticale rep=True if abs(A[0]-B[0])<=1 and abs(A[1]-B[1])<=1: rep=False if A[0]==B[0] or A[1]==B[1]: rep=False if abs(A[0]-B[0])<1 or abs(A[1]-B[1])<1: rep=False return rep def validec(A,B): #valide le choix du couple A B pour qu'ils ne soient pas "collés" rep=True if abs(A[0]-B[0])<=1 and abs(A[1]-B[1])<=1: rep=False return rep def doublefleche(A,B): #trace une flèche "double" de justification en pointillés mid=(float((A[0]+B[0]))/2,float((A[1]+B[1]))/2) res1="\\psline[linestyle=dashed,linewidth=1.1pt]{->}"+str(A)+str(mid)+'\n ' res2="\\psline[linestyle=dashed,linewidth=1.1pt]{->}"+str(mid)+str(B) res=res1+res2 if A==B: res="" return res def couple () : A=(float(random.randrange(-8,9))/2,float(random.randrange(-8,9))/2) B=(float(random.randrange(-8,9))/2,float(random.randrange(-8,9))/2) while not validec(A,B): B=(float(random.randrange(-8,9))/2,float(random.randrange(-8,9))/2) return (A,B) def coupletrace () : A=(0,float(random.randrange(-4,5))) B=(float(random.randrange(-4,5)),float(random.randrange(-4,5))) while not validec(A,B): B=(float(random.randrange(-4,5)),float(random.randrange(-4,5))) return (A,B) def couples (): #génère 6 points. Chaque couple correspondra a une droite ( (AB)(CD)(EF)). A=(float(random.randrange(-8,9))/2,float(random.randrange(-8,9))/2) B=(float(random.randrange(-8,9))/2,float(random.randrange(-8,9))/2) while not validedroite(A,B): B=(float(random.randrange(-8,9))/2,float(random.randrange(-8,9))/2) C=(0,float(random.randrange(-4,5))) while not (validec(A,C) and validec(B,C)): C=(0,float(random.randrange(-4,5))) D=(float(random.randrange(-4,5)),float(random.randrange(-4,5))) while not (validec(A,D) and validec(B,D) and validedroite(C,D)) : D=(float(random.randrange(-4,5)),float(random.randrange(-4,5))) E=(0,float(random.randrange(-8,9))/2) while not (validec(A,E) and validec(B,E) and validec(C,E) and validec(D,E)): E=(0,float(random.randrange(-8,9))/2) F=(float(random.randrange(-4,5)),float(random.randrange(-4,5))) while not (validec(A,F) and validec(B,F) and validec(C,F) and validec(D,F)and validedroite(E,F)): F=(float(random.randrange(-4,5)),float(random.randrange(-4,5))) return (A,B,C,D,E,F) def tracedroite(A,B,xmin,xmax,ymin,ymax): #trace la droite (AB) l=extreme(A,B,xmin,xmax,ymin,ymax) return "\\psline "+str(l[0])+str(l[1]) def dansrep(A,xmin,xmax,ymin,ymax): #Si le points est dans le repère res= False if A[0]>xmin and A[0]ymin and A[1] ' if j == 0: res_quiz += ("$$(%s;$${1:SHORTANSWER:%s100%s%s}$$)$$

\n" % (decimaux_quiz(str(A[i])), "%", "%", decimaux_quiz(str(A[abs(i-1)]),0))) else: res_quiz += ("$$($${1:SHORTANSWER:%s100%s%s}$$\\, ;%s)$$

\n" % ("%", "%", decimaux_quiz(str(A[abs(i-1)])), decimaux_quiz(str(A[i]),0))) if i==0: res.append(doublefleche((A[0],0),A)) res.append(doublefleche(A,(0,A[1]))) else: res.append(doublefleche((0,A[1]),A)) res.append(doublefleche(A,(A[0],0))) i=abs(i-1) j=i if i==1: j=i+random.randrange(0,2) res.append(_(u'Donner ')+l[j]+'$'+decimaux(str(B[i]))+'$'+_(u' par la fonction ')+'\\textit{'+fonc+'}.') res.append('$'+decimaux(str(B[abs(i-1)]))+'$'+lcor[j]+'$'+decimaux(str(B[i]))+'$'+_(u' par la \\hbox{fonction ')+'\\textit{'+fonc+'}}.') res_quiz += _(u'Écrit')+l[j]+'$$'+decimaux_quiz(str(B[i]))+'$$'+_(u' dans la fonction ')+'$$'+fonc+'$$:
' if j == 0: res_quiz += ("$$(%s;$${1:SHORTANSWER:%s100%s%s}$$)$$

\n" % (decimaux_quiz(str(B[i])), "%", "%", decimaux_quiz(str(B[abs(i-1)]),0))) else: res_quiz += ("$$($${1:SHORTANSWER:%s100%s%s}$$\\, ;%s)$$

\n" % ("%", "%", decimaux_quiz(str(B[abs(i-1)])), decimaux_quiz(str(B[i]),0))) if i==0: res.append(doublefleche((B[0],0),B)) res.append(doublefleche(B,(0,B[1]))) else: res.append(doublefleche((0,B[1]),B)) res.append(doublefleche(B,(B[0],0))) return (res, res_quiz) def tracefonc(f,i,A,B,xmin,xmax,ymin,ymax): #A est sur l'axe des ordonnées, f est le nom de la fonction #Génère la 2e queston et sa réponse u=coefdir(A,B) if A[1]>=0: b='+'+decimaux(str(A[1])) else: b=decimaux(str(A[1])) if u[1]==1: coef=decimaux(str(u[0])) if u[0]==-1: coef='-' if u[0]==1: coef='' x1=decimaux(str(B[0])) y1=decimaux(str(B[1])) u[0]=u[0]*B[0] else: B=(u[1],u[0]+float(A[1])) if not dansrep(B,xmin,xmax,ymin,ymax): B=(-u[1],-u[0]+float(A[1])) x1=decimaux(str(B[0])) y1=decimaux(str(B[1])) if u[0]>0: coef='\\dfrac{'+decimaux(str(u[0]))+'}{'+decimaux(str(u[1]))+'}' else: coef='-\\dfrac{'+decimaux(str(abs(u[0])))+'}{'+decimaux(str(u[1]))+'}' x0='0' y0=b if coef=='' or (coef=='-' and B[0]>0) : st=_(u'On sait que $')+f+'(0)='+decimaux(str(A[1]))+_(u'$ et $')+f+'('+x1+')='+coef+x1+b+'='+y1+'$.' elif coef=='-' and B[0]<0: st=_(u'On sait que $')+f+'(0)='+decimaux(str(A[1]))+_(u'$ et $')+f+'('+x1+')='+coef+'('+x1+')'+b+'='+y1+'$.' elif B[0]<0: st=_(u'On sait que $')+f+'(0)='+decimaux(str(A[1]))+_(u'$ et $')+f+'('+x1+')='+coef+_(' \\times (')+x1+')'+b+'='+decimaux(str(u[0]))+b+'='+y1+'$.' else: st=_(u'On sait que $')+f+'(0)='+decimaux(str(A[1]))+_(u'$ et $')+f+'('+x1+')='+coef+_(' \\times ')+x1+b+'='+decimaux(str(u[0]))+b+'='+y1+'$.' l=[_(u'Tracer la droite représentative ($d_')+str(i)+_(u'$) de la fonction $')+f+':x\\longmapsto '+coef+'x'+b+'$.', st, '\\psdot [dotsize=4.5pt,dotstyle=x]'+str(A), '\\psdot [dotsize=4.5pt,dotstyle=x]'+str(B), ] return l def exprfonc(f,i,A,B): #Génère la 3e question. #A est sur l'axe des ordonnées, f est le nom de la fonction u=coefdir(A,B) if A[1]>=0: b='+'+decimaux(str(A[1])) else: b=decimaux(str(A[1])) b_quiz = decimaux_quiz(str(A[1])) if u[1]==1: coef=decimaux(str(u[0])) coef_quiz=decimaux_quiz(str(u[0])) if u[0]==-1: coef='-' #utilisé dans l'expression de la fonction if u[0]==1: coef='' coefres=decimaux(str(u[0])) #résultat utilisé pour a else: if u[0]>0: coef='\\dfrac{'+decimaux(str(u[0]))+'}{'+decimaux(str(u[1]))+'}' coef_quiz=decimaux_quiz(str(u[0]))+'/'+decimaux_quiz(str(u[1])) else: coef='-\\dfrac{'+decimaux(str(abs(u[0])))+'}{'+decimaux(str(u[1]))+'}' coef_quiz='-'+decimaux_quiz(str(abs(u[0])))+'/'+decimaux_quiz(str(u[1])) coefres=coef if A[1]-B[1]>0: deltay='+'+decimaux(str(A[1]-B[1])) else : deltay=decimaux(str(A[1]-B[1])) if A[0]-B[0]>0: deltax='+'+decimaux(str(A[0]-B[0])) else: deltax=decimaux(str(A[0]-B[0])) if float(B[0])<0 : mid11=float(B[0])-0.75 mid12=float((B[1]+A[1]))/2 #milieu de la flèche verticale else: mid11=float(B[0])+0.75 mid12=float((B[1]+A[1]))/2 if float(B[0])*float(u[1]/u[0])>0 : mid21=float((A[0]+B[0]))/2 mid22=A[1]-0.6 #milieu de la flèche horizontale else : mid21=float((A[0]+B[0]))/2 mid22=A[1]+0.5 if mid12 < 0 and mid12 >-0.8: mid12=-1 if mid12 >= 0 and mid12 < 0.5: mid12=0.5 if mid11 < 0 and mid11 >-0.8: mid11=-1 if mid11 >=0 and mid11 < 0.5: mid11=0.5 if mid21 < 0 and mid21 >-0.8: mid21=-1 if mid21 >=0 and mid21 < 0.5: mid21=0.5 if mid22 < 0 and mid22 >-0.8: mid22=-1 if mid22 >= 0 and mid22 < 0.5: mid22=0.5 mid1=(mid11,mid12) mid2=(mid21,mid22) l=[_(u'Déterminer l\'expression de la fonction $')+f+_(u'$ représentée ci-contre par la droite ($d_')+str(i)+'$).', _(u'On lit l\'ordonnée à l\'origine et le coefficient de la fonction affine sur le graphique.\\\ '), '$'+f+'(x)=ax+b$ ' +_(u'avec $b=')+ decimaux(str(A[1]))+_(u'$ et $a=')+'\\dfrac{'+deltay+'}{'+deltax+'}='+coefres+'$.\\\ ', _(u'L\'expression de la fonction $')+f+_(u'$ est $')+f+'(x)='+coef+'x'+b+'$.', doublefleche(B,(B[0],A[1])), doublefleche((B[0],A[1]),A), '\\rput'+str(mid1)+'{('+deltay+')}', '\\rput'+str(mid2)+'{('+deltax+')}'] l_quiz = _(u'Détermine l\'expression de la fonction $$')+f+_(u'$$ représentée par $$(d_')+str(i)+')$$:
\n' l_quiz += ("$$%s(x)=$$ {1:SHORTANSWER:%s100%s%s}$$x+$${1:SHORTANSWER:%s100%s%s}
\n" % (f, "%", "%", coef_quiz, "%", "%", b_quiz)) l_quiz += _(u"(En le 1º utilise la barre \"/\" pour la fraction irréductible et en le 2º écrit le décimale)") return (l, l_quiz) def f_quiz(x, m_quiz, n_quiz): return m_quiz * x + n_quiz def corte_quiz(m_quiz, n_quiz, n=500): #Devuelve de una recta en el marco de dibujo el: [punto de partida, punto de llegada] if m_quiz != 0: if abs(m_quiz) > 10000: return [[-n_quiz/m_quiz,0],[-n_quiz/m_quiz,n]] else: x_y = [] if n_quiz < n and n_quiz >= 0: x_y.append([0,n_quiz]) if -n_quiz/m_quiz < n and -n_quiz/m_quiz >= 0: x_y.append([-n_quiz/m_quiz,0]) if f_quiz(n, m_quiz, n_quiz) < n and f_quiz(n, m_quiz, n_quiz) >= 0: x_y.append([n,f_quiz(n, m_quiz, n_quiz)]) if (n-n_quiz)/m_quiz < n and (n-n_quiz)/m_quiz >= 0: x_y.append([(n-n_quiz)/m_quiz,n]) return x_y else: return [[0,n_quiz],[n,n_quiz]] def coord_quiz(fonc1, pts_f1, fonc3, pts_f3, l_m1, l_m3): # Inicio quiz_quadrant = "$$\\fs3\\picture(361){" # Líneas horizontales quiz_quadrant += "(0,0){\\line(360,0)}(0,30){\\line(360,0)}(0,60){\\line(360,0)}(0,90){\\line(360,0)}(0,120){\\line(360,0)}(0,150){\\line(360,0)}(0,180){\\line(360,0)}(0,210){\\line(360,0)}(0,240){\\line(360,0)}(0,270){\\line(360,0)}(0,300){\\line(360,0)}(0,330){\\line(360,0)}(0,360){\\line(360,0)}" # Líneas Verticales quiz_quadrant += "(0,0){\\line(0,360)}(30,0){\\line(0,360)}(60,0){\\line(0,360)}(90,0){\\line(0,360)}(120,0){\\line(0,360)}(150,0){\line(0,360)}(180,0){\\line(0,360)}(210,0){\\line(0,360)}(240,0){\\line(0,360)}(270,0){\\line(0,360)}(300,0){\\line(0,360)}(330,0){\\line(0,360)}(360,0){\\line(0,360)}" # Ejes quiz_quadrant += "(0,179){\\line(360,0)}(0,181){\\line(360,0)}(179,0){\\line(0,360)}(181,0){\\line(0,360)}" # Numeración eje OX quiz_quadrant += "(20,165){-5}(50,165){-4}(80,165){-3}(110,165){-2}(140,165){-1}(185,165){0}(215,165){1}(245,165){2}(275,165){3}(305,165){4}(335,165){5}" # Numeración eje OY quiz_quadrant += "(160,15){-5}(160,45){-4}(160,75){-3}(160,105){-2}(160,135){-1}(170,195){1}(170,225){2}(170,255){3}(170,285){4}(170,315){5}" for j in range(2): pts_quiz = [] if j == 0: pts_f = pts_f1 noms_f = "(d_1)" else: pts_f = pts_f3 noms_f = "(d_3)" for i in range(2): pts_quiz.append([30*pts_f[i][0]+180, 30*pts_f[i][1]+180]) den_m = (pts_quiz[1][0]-pts_quiz[0][0]) if den_m == 0: m_quiz = 10001 else: m_quiz = (pts_quiz[1][1] - pts_quiz[0][1])/den_m n_quiz = pts_quiz[0][1] - m_quiz*pts_quiz[0][0] x_y_quiz = corte_quiz(m_quiz,n_quiz,361) quiz_quadrant += ("(%s,%s){\\line(%s,%s)}" % (x_y_quiz[0][0], x_y_quiz[0][1], (x_y_quiz[1][0]-x_y_quiz[0][0]), (x_y_quiz[1][1]-x_y_quiz[0][1]))) quiz_quadrant += ("(%s,%s){%s}" % (x_y_quiz[0][0], x_y_quiz[0][1], noms_f)) quiz_quadrant += "}$$\n" quiz_cor = _(u"$$(d_1)$$ est la ligne droite qui représente la fonction $$")+fonc1+"$$

\n" quiz_cor += l_m1 quiz_cor += l_m3 quiz_table = ("
%s%s
" % (quiz_quadrant, quiz_cor)) return quiz_table def affine(): #Génère l'exercice xmin,xmax,ymin,ymax=-5,5,-5,5 f=['f','g','h','k','l','u'] rgfonc1=random.randrange(0,6) fonc1=f[rgfonc1] (A,B,C,D,E,F)=couples() l_m=anteimage(fonc1,A,B) l=l_m[0] #lecture d'image d'antécédent fonc2=f[(rgfonc1+1)%6] l2=tracefonc(fonc2,2,C,D,xmin,xmax,ymin,ymax) #représenter une fonction fonc3=f[(rgfonc1+2)%6] l3_m = exprfonc(fonc3,3,E,F) l3 = l3_m[0] noms=nom3droites(A,B,C,D,E,F,xmin,xmax,ymin,ymax) exo=["\\exercice", "\\parbox{0.5\\linewidth}{", _(u"($d_1$) est la droite représentative de la fonction $")+fonc1+"$.", "\\begin{enumerate}", "\\item "+l[0], "\\item "+l[4], "\\item "+l2[0], "\\item "+l3[0], "\\end{enumerate}}\\hfill", "\\parbox{0.45\\linewidth}{", "\\psset{unit=0.8cm}", "\\begin{pspicture}"+str((xmin,ymin))+str((xmax,ymax)), "\\psgrid[subgriddiv=2, gridlabels=8pt](0,0)"+str((xmin,ymin))+str((xmax,ymax)), "\\psline[linewidth=1.2pt]{->}"+str((xmin,0))+str((xmax,0)), "\\psline[linewidth=1.2pt]{->}"+str((0,ymin))+str((0,ymax)), tracedroite(A,B,xmin,xmax,ymin,ymax), noms[0], tracedroite(E,F,xmin,xmax,ymin,ymax), noms[2], "\\end{pspicture}}"] cor=["\\exercice*", "\\setlength{\\columnsep}{2mm}", "\\begin{multicols}{2}\\noindent \\small", _(u"($d_1$) est la droite représentative de la fonction $")+fonc1+"$.", "\\begin{enumerate}", "\\item "+l[1], "\\item "+l[5], "\\item\n\\begin{flushleft}\n"+l2[1]+"\n\\end{flushleft}", "\\item\n\\begin{flushleft}\n"+l3[1], l3[2], l3[3]+"\n\\end{flushleft}", "\\end{enumerate}", "\\end{multicols}", "\\vspace{0.45cm}", "\\begin{minipage}{0.5\\linewidth}", "\\psset{unit=0.7cm}", "\\begin{center}", "\\begin{pspicture}"+str((xmin,ymin))+str((xmax,ymax)), "\\psgrid[subgriddiv=2, gridlabels=8pt](0,0)"+str((xmin,ymin))+str((xmax,ymax)), "\\psline[linewidth=1.2pt]{->}"+str((xmin,0))+str((xmax,0)), "\\psline[linewidth=1.2pt]{->}"+str((0,ymin))+str((0,ymax)), tracedroite(A,B,xmin,xmax,ymin,ymax), noms[0], tracedroite(C,D,xmin,xmax,ymin,ymax), noms[1], l[2], l[3], l[6], l[7], l2[2], l2[3], "\\end{pspicture}", "\\end{center}", "\\end{minipage}", "\\begin{minipage}{0.5\\linewidth}", "\\psset{unit=0.7cm}", "\\begin{center}", "\\begin{pspicture}"+str((xmin,ymin))+str((xmax,ymax)), "\\psgrid[subgriddiv=2, gridlabels=8pt](0,0)"+str((xmin,ymin))+str((xmax,ymax)), "\\psline[linewidth=1.2pt]{->}"+str((xmin,0))+str((xmax,0)), "\\psline[linewidth=1.2pt]{->}"+str((0,ymin))+str((0,ymax)), tracedroite(E,F,xmin,xmax,ymin,ymax), noms[2], l3[4], l3[5], l3[6], l3[7], "\\end{pspicture}", "\\end{center}", "\\end{minipage}", "\\vspace{0.45cm}"] quiz = ["cloze"] quiz_nom = _(u"Fonctions affines") quiz_exo_cor = coord_quiz(fonc1, [A,B], fonc3, [E,F], l_m[1], l3_m[1]) quiz.append([quiz_nom, quiz_exo_cor, ""]) return exo,cor,quiz def tex_affine(): return affine()