source: pyromaths/trunk/fuentes/src/pyromaths/ex/troisiemes/affine.py @ 423

Last change on this file since 423 was 423, checked in by mabarracus, 5 years ago

add sources from pyromaths 15.10

File size: 16.5 KB
Line 
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3#
4# Pyromaths
5# Un programme en Python qui permet de créer des fiches d'exercices types de
6# mathématiques niveau collège ainsi que leur corrigé en LaTeX.
7# Copyright (C) 2006 -- Jérôme Ortais (jerome.ortais@pyromaths.org)
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22#
23
24# fonction affine 3e
25# from math import *
26from math import sqrt
27from pyromaths.classes.Fractions import Fraction  # fractions pyromaths
28from pyromaths.classes.PolynomesCollege import Polynome
29from pyromaths.outils.Affichage import decimaux
30import random
31import pyromaths.outils.Priorites3
32from pyromaths.outils import Priorites3
33
34
35def extreme(a, b, xmin, xmax, ymin, ymax):
36# donne les extremités de la droite passant par a et b (coordonnées)
37    res = []
38    x1 = float(a[0])
39    x2 = float(b[0])
40    y1 = float(a[1])
41    y2 = float(b[1])
42    coef = float((y1 - y2) / (x1 - x2))
43    if coef != 0:
44        xsort1 = float(x1 + (ymin - y1) / coef)  # abscisse du point d'ordonnée ymin
45        if xsort1 >= xmin and xsort1 <= xmax and not(xsort1, ymin) in res:
46            res.append((xsort1, ymin))
47        xsort2 = float(x2 + (ymax - y2) / coef)  # abscisse du point d'ordonnée ymax
48        if xsort2 >= xmin and xsort2 <= xmax and not(xsort2, ymax) in res:
49            res.append((xsort2, ymax))
50        ysort1 = float(y1 + coef * (xmin - x1))  # ordonnée du point d'abscisse xmin
51        if ysort1 >= ymin and ysort1 <= ymax and not (xmin, ysort1)in res:
52            res.append((xmin, ysort1))
53        ysort2 = float(y2 + coef * (xmax - x2))  # ordonnée du point d'abscisse xmax
54        if ysort2 >= ymin and ysort2 <= ymax and not(xmax, ysort2) in res:
55            res.append((xmax, ysort2))
56    else:
57        res = [(xmin, y1), (xmax, y1)]
58    return res
59
60def vecdir(A, B):
61    # retourne sous forme de liste le vecteur directeur normé de la droite (AB)
62    norm = sqrt((B[0] - A[0]) ** 2 + (B[1] - A[1]) ** 2)
63    u = [(B[0] - A[0]) / norm, (B[1] - A[1]) / norm]
64    if u[0] < 0:
65        u[0] = -u[0]
66        u[1] = -u[1]
67    return u
68
69def validedroite(A, B):
70    # valide le choix du couple A B pour qu'ils ne soient pas "collés",
71    # la droite (AB) ne sera ni horizontale ni verticale
72
73    rep = True
74    if abs(A[0] - B[0]) <= 1 and abs(A[1] - B[1]) <= 1:
75        rep = False
76    if A[0] == B[0] or A[1] == B[1]:
77        rep = False
78    if abs(A[0] - B[0]) < 1 or abs(A[1] - B[1]) < 1:
79        rep = False
80    return rep
81
82
83def validec(A, B):
84    # valide le choix du couple A B pour qu'ils ne soient pas "collés"
85    rep = True
86    if abs(A[0] - B[0]) <= 1 and abs(A[1] - B[1]) <= 1:
87        rep = False
88    return rep
89
90def doublefleche(A, B):
91    # trace une flèche "double" de justification en pointillés
92    mid = (float((A[0] + B[0])) / 2, float((A[1] + B[1])) / 2)
93    res1 = "\\psline[linestyle=dashed,linewidth=1.1pt]{->}" + str(A) + str(mid) + '\n '
94    res2 = "\\psline[linestyle=dashed,linewidth=1.1pt]{->}" + str(mid) + str(B)
95    res = res1 + res2
96    if A == B:
97        res = ""
98
99    return res
100
101def couple () :
102    A = (float(random.randrange(-8, 9)) / 2, float(random.randrange(-8, 9)) / 2)
103    B = (float(random.randrange(-8, 9)) / 2, float(random.randrange(-8, 9)) / 2)
104    while not validec(A, B):
105        B = (float(random.randrange(-8, 9)) / 2, float(random.randrange(-8, 9)) / 2)
106    return (A, B)
107
108def coupletrace () :
109    A = (0, float(random.randrange(-4, 5)))
110    B = (float(random.randrange(-4, 5)), float(random.randrange(-4, 5)))
111    while not validec(A, B):
112        B = (float(random.randrange(-4, 5)), float(random.randrange(-4, 5)))
113    return (A, B)
114
115def couples ():
116    # génère 6 points. Chaque couple correspondra a une droite ( (AB)(CD)(EF)).
117    A = (float(random.randrange(-8, 9)) / 2, float(random.randrange(-8, 9)) / 2)
118    B = (float(random.randrange(-8, 9)) / 2, float(random.randrange(-8, 9)) / 2)
119    while not validedroite(A, B):
120        B = (float(random.randrange(-8, 9)) / 2, float(random.randrange(-8, 9)) / 2)
121    C = (0, float(random.randrange(-4, 5)))
122    while not (validec(A, C) and validec(B, C)):
123        C = (0, float(random.randrange(-4, 5)))
124    D = (float(random.randrange(-4, 5)), float(random.randrange(-4, 5)))
125    while not (validec(A, D) and validec(B, D) and validedroite(C, D)) :
126        D = (float(random.randrange(-4, 5)), float(random.randrange(-4, 5)))
127    E = (0, float(random.randrange(-8, 9)) / 2)
128    while not (validec(A, E) and validec(B, E) and validec(C, E) and validec(D, E)):
129        E = (0, float(random.randrange(-8, 9)) / 2)
130    F = (float(random.randrange(-4, 5)), float(random.randrange(-4, 5)))
131    while not (validec(A, F) and validec(B, F) and validec(C, F) and validec(D, F)and validedroite(E, F)):
132        F = (float(random.randrange(-4, 5)), float(random.randrange(-4, 5)))
133    return (A, B, C, D, E, F)
134
135def tracedroite(A, B, xmin, xmax, ymin, ymax):
136    # trace la droite (AB)
137    l = extreme(A, B, xmin, xmax, ymin, ymax)
138    return "\\psline " + str(l[0]) + str(l[1])
139
140def dansrep(A, xmin, xmax, ymin, ymax):
141# Si le points est dans le repère
142    res = False
143    if A[0] > xmin and A[0] < xmax and A[1] > ymin and A[1] < ymax:
144        res = True
145    return res
146
147def nomdroite(i, coordo):
148    # place le nom de la droite (d_i) sur le graphique aux coordonnées coordo
149    x0 = coordo[0]
150    y0 = coordo[1]
151    if x0 != 0:
152        x = x0 / abs(x0) * (abs(x0) + 0.5)
153    else:
154        x = 0
155    if y0 != 0:
156        y = y0 / abs(y0) * (abs(y0) + 0.5)
157    else:
158        y = 0
159    return "\\rput" + str((x, y)) + "{($d_" + str(i) + "$)}"
160
161def nom3droites(A, B, C, D, E, F, xmin, xmax, ymin, ymax):
162    # place le nom des droites (AB), (CD), (EF) dans le graphique
163    # les 3 instructions latex sont contenues dans une liste
164    # évite la juxtaposition des écritures
165    res = []
166    l1 = extreme(A, B, xmin, xmax, ymin, ymax)
167    res.append(nomdroite(1, l1[0]))
168    l2 = extreme(C, D, xmin, xmax, ymin, ymax)
169    if validec(l1[0], l2[0]):
170        memo = l2[0]  # se rappeler qu'on a utilisé l2[0]
171        res.append(nomdroite(2, l2[0]))
172    else:
173        memo = l2[1]
174        res.append(nomdroite(2, l2[1]))
175    l3 = extreme(E, F, xmin, xmax, ymin, ymax)
176    if validec(l1[0], l3[0]) and validec(memo, l3[0]):
177        res.append(nomdroite(3, l3[0]))
178    else :
179        res.append(nomdroite(3, l3[1]))
180    return res
181
182def isint(x):
183    # est entier?
184    res = False
185    if int(x) == x:
186        res = True
187    return res
188
189def isdemi(x):
190    # est-ce une moitié d'entier
191    res = False
192    x = float(x) * 2
193    if isint(x):
194        res = True
195
196    return res
197
198def coefdir(A, B):
199    # donne le coefficient directeur x/y sous forme de liste [x,y]
200    # Si y=1 on ecrira x sinon on écrira la fraction x/y
201    return Fraction.simplifie(Fraction(B[1] - A[1], B[0] - A[0]))
202
203def anteimage(fonc, A, B):
204    # Génère la 1ère question et sa réponse
205
206    l = [' l\'image de ', ' un nombre qui a pour image ', u' un antécédent de ']
207    lcor = [' est l\'image de ', ' a pour image ', u' est un antécédent de ']  # liste pour le corrigé
208    i = random.randrange(0, 2)
209    j = i
210    if i == 1:
211        j = i + random.randrange(0, 2)
212    res = []
213    res.append('Donner ' + l[j] + '$' + decimaux(str(A[i])) + '$' + ' par la fonction ' + '\\textit{' + fonc + '}.')
214    res.append('$' + decimaux(str(A[abs(i - 1)])) + '$' + lcor[j] + '$' + decimaux(str(A[i])) + '$' + ' par la \\hbox{fonction ' + '\\textit{' + fonc + '}}.')
215    if i == 0:
216        res.append(doublefleche((A[0], 0), A))
217        res.append(doublefleche(A, (0, A[1])))
218
219    else:
220        res.append(doublefleche((0, A[1]), A))
221        res.append(doublefleche(A, (A[0], 0)))
222    i = abs(i - 1)
223    j = i
224    if i == 1:
225        j = i + random.randrange(0, 2)
226    res.append('Donner ' + l[j] + '$' + decimaux(str(B[i])) + '$' + ' par la fonction ' + '\\textit{' + fonc + '}.')
227    res.append('$' + decimaux(str(B[abs(i - 1)])) + '$' + lcor[j] + '$' + decimaux(str(B[i])) + '$' + ' par la \\hbox{fonction ' + '\\textit{' + fonc + '}}.')
228    if i == 0:
229        res.append(doublefleche((B[0], 0), B))
230        res.append(doublefleche(B, (0, B[1])))
231    else:
232        res.append(doublefleche((0, B[1]), B))
233        res.append(doublefleche(B, (B[0], 0)))
234    return res
235
236def tracefonc(f, i, A, B, xmin, xmax, ymin, ymax):
237    """**tracefonc\ (*f*\ , *i*\ , *A*\ , *B*\ , *xmin*\ , *xmax*\ , *ymin*\ , *ymax*\ )
238
239        *A* est sur l'axe des ordonnées, *f* est le nom de la fonction
240        Génère la 2e queston et sa réponse
241
242        >>> from pyromaths.classes.Fractions import Fraction
243        >>> affine.tracefonc('f', 1, (0,-2),(3,2),-4,4,-4,-4)
244        [u'Tracer la droite repr\xe9sentative ($d_1$) de la fonction $f:x\\longmapsto \\
245            dfrac{4}{3}\\,x-2$.', 'On sait que $f(0)=-2$ et $f(-3)=\\dfrac{4}{3}\\times \\le
246            ft( -3\\right) -2=\\dfrac{4\\times \\cancel{3}\\times -1}{\\cancel{3}\\times 1}-
247            2=-4-2=-6', '\\psdot [dotsize=4.5pt,dotstyle=x](0, -2)', '\\psdot [dotsize=4.5pt
248            ,dotstyle=x](-3, -6.0)']
249
250        :rtype: list of string
251        """
252    u = coefdir(A, B)
253    if isinstance(u, int) or u.d == 1:
254        x1 = decimaux(B[0])
255    else:
256        B = (u.d, u.n + float(A[1]))
257        if not dansrep(B, xmin, xmax, ymin, ymax):
258            B = (-u.d, -u.n + float(A[1]))
259        x1 = decimaux(str(B[0]))
260    l = Priorites3.texify([Polynome([[u, 1], [A[1], 0]], "x")(B[0])])
261    l.extend(Priorites3.texify(Priorites3.priorites(Polynome([[u, 1], [A[1], 0]], "x")(B[0]))))
262    l = [u'Tracer la droite représentative ($d_' + str(i) + '$) de la fonction $' + f + ':x\\longmapsto ' + str(Polynome([[u, 1], [A[1], 0]], "x")) + '$.',
263       'On sait que $' + f + '(0)=' + decimaux(str(A[1])) + '$ et $' + f + '(' + x1 + ')=' + "=".join(l) + "$.",
264       '\\psdot [dotsize=4.5pt,dotstyle=x]' + str(A),
265       '\\psdot [dotsize=4.5pt,dotstyle=x]' + str(B),
266       ]
267    return l
268
269def exprfonc(f, i, A, B):
270# Génère la 3e question.
271# A est sur l'axe des ordonnées, f est le nom de la fonction
272    u = coefdir(A, B)
273    if isinstance(u, int): u = Fraction(u, 1)
274    Polynome([[u, 1], [A[1], 0]], "x")(B[0])
275    #===========================================================================
276    # if A[1] >= 0:
277    #     b = '+' + decimaux(str(A[1]))
278    # else:
279    #     b = decimaux(str(A[1]))
280    # if u.d == 1:
281    #     coef = decimaux(str(u.n))
282    #     if u.n == -1:
283    #         coef = '-'  # utilisé dans l'expression de la fonction
284    #     if u.n == 1:
285    #         coef = ''
286    #     coefres = decimaux(str(u.n))  # résultat utilisé pour a
287    # else:
288    #     if u.n > 0:
289    #         coef = '\\dfrac{' + decimaux(str(u.n)) + '}{' + decimaux(str(u.d)) + '}'
290    #     else:
291    #         coef = '-\\dfrac{' + decimaux(str(abs(u.n))) + '}{' + decimaux(str(u.d)) + '}'
292    #     coefres = coef
293    #===========================================================================
294
295    if A[1] - B[1] > 0:
296        deltay = '+' + decimaux(str(A[1] - B[1]))
297    else :
298        deltay = decimaux(str(A[1] - B[1]))
299    if A[0] - B[0] > 0:
300        deltax = '+' + decimaux(str(A[0] - B[0]))
301    else:
302        deltax = decimaux(str(A[0] - B[0]))
303
304    if float(B[0]) < 0 :
305        mid11 = float(B[0]) - 0.75
306        mid12 = float((B[1] + A[1])) / 2  # milieu de la flèche verticale
307    else:
308        mid11 = float(B[0]) + 0.75
309        mid12 = float((B[1] + A[1])) / 2
310    if float(B[0]) * float(u.d / u.n) > 0 :
311        mid21 = float((A[0] + B[0])) / 2
312        mid22 = A[1] - 0.6  # milieu de la flèche horizontale
313    else :
314        mid21 = float((A[0] + B[0])) / 2
315        mid22 = A[1] + 0.5
316    if mid12 < 0 and mid12 > -0.8:
317        mid12 = -1
318    if mid12 >= 0 and mid12 < 0.5:
319        mid12 = 0.5
320    if mid11 < 0 and mid11 > -0.8:
321        mid11 = -1
322    if mid11 >= 0 and mid11 < 0.5:
323        mid11 = 0.5
324    if mid21 < 0 and mid21 > -0.8:
325        mid21 = -1
326    if mid21 >= 0 and mid21 < 0.5:
327        mid21 = 0.5
328    if mid22 < 0 and mid22 > -0.8:
329        mid22 = -1
330    if mid22 >= 0 and mid22 < 0.5:
331        mid22 = 0.5
332    mid1 = (mid11, mid12)
333    mid2 = (mid21, mid22)
334    l = [u'Déterminer l\'expression de la fonction $' + f + u'$ représentée ci-contre par la droite ($d_' + str(i) + '$).',
335       u'On lit l\'ordonnée à l\'origine et le coefficient de la fonction affine sur le graphique.\\\ ',
336       '$' + f + '(x)=a\\,x+b$ ' + 'avec $b=' + decimaux(str(A[1])) + '$ et $a=' + '\\dfrac{' + deltay + '}{' + deltax + '}=' + str(u) + '$.\\\ ',
337       'L\'expression de la fonction $' + f + '$ est $' + f + '(x)=' + str(Polynome([[u, 1], [A[1], 0]], "x")) + '$.',
338       doublefleche(B, (B[0], A[1])),
339       doublefleche((B[0], A[1]), A),
340       '\\rput' + str(mid1) + '{(' + deltay + ')}',
341       '\\rput' + str(mid2) + '{(' + deltax + ')}']
342
343    return l
344
345
346def affine():
347    # Génère l'exercice
348    xmin, xmax, ymin, ymax = -5, 5, -5, 5
349    f = ['f', 'g', 'h', 'k', 'l', 'u']
350    rgfonc1 = random.randrange(0, 6)
351    fonc1 = f[rgfonc1]
352    (A, B, C, D, E, F) = couples()
353    l = anteimage(fonc1, A, B)  # lecture d'image d'antécédent
354    fonc2 = f[(rgfonc1 + 1) % 6]
355    l2 = tracefonc(fonc2, 2, C, D, xmin, xmax, ymin, ymax)  # représenter une fonction
356    fonc3 = f[(rgfonc1 + 2) % 6]
357    l3 = exprfonc(fonc3, 3, E, F)
358    noms = nom3droites(A, B, C, D, E, F, xmin, xmax, ymin, ymax)
359    exo = ["\\exercice", "\\parbox{0.5\\linewidth}{",
360         u"($d_1$) est la droite représentative de la fonction $" + fonc1 + "$.",
361         "\\begin{enumerate}",
362         "\\item " + l[0],
363         "\\item " + l[4],
364         "\\item " + l2[0],
365         "\\item " + l3[0],
366         "\\end{enumerate}}\\hfill",
367         "\\parbox{0.45\\linewidth}{",
368         "\\psset{unit=0.8cm}",
369         "\\begin{pspicture}" + str((xmin, ymin)) + str((xmax, ymax)),
370         "\\psgrid[subgriddiv=2, gridlabels=8pt](0,0)" + str((xmin, ymin)) + str((xmax, ymax)),
371         "\\psline[linewidth=1.2pt]{->}" + str((xmin, 0)) + str((xmax, 0)),
372         "\\psline[linewidth=1.2pt]{->}" + str((0, ymin)) + str((0, ymax)),
373         tracedroite(A, B, xmin, xmax, ymin, ymax),
374         noms[0],
375         tracedroite(E, F, xmin, xmax, ymin, ymax),
376         noms[2],
377         "\\end{pspicture}}"]
378
379    cor = ["\\exercice*", "\\setlength{\\columnsep}{2mm}",
380         "\\begin{multicols}{2}\\noindent \\small",
381         u"($d_1$) est la droite représentative de la fonction $" + fonc1 + "$.",
382         "\\begin{enumerate}",
383         "\\item " + l[1],
384         "\\item " + l[5],
385         "\\item\n\\begin{flushleft}\n" + l2[1] + "\n\\end{flushleft}",
386         "\\item\n\\begin{flushleft}\n" + l3[1],
387         l3[2],
388         l3[3] + "\n\\end{flushleft}",
389         "\\end{enumerate}",
390         "\\end{multicols}",
391         "\\vspace{0.45cm}",
392         "\\begin{minipage}{0.5\\linewidth}",
393         "\\psset{unit=0.7cm}",
394         "\\begin{center}",
395         "\\begin{pspicture}" + str((xmin, ymin)) + str((xmax, ymax)),
396         "\\psgrid[subgriddiv=2, gridlabels=8pt](0,0)" + str((xmin, ymin)) + str((xmax, ymax)),
397         "\\psline[linewidth=1.2pt]{->}" + str((xmin, 0)) + str((xmax, 0)),
398         "\\psline[linewidth=1.2pt]{->}" + str((0, ymin)) + str((0, ymax)),
399         tracedroite(A, B, xmin, xmax, ymin, ymax),
400         noms[0],
401         tracedroite(C, D, xmin, xmax, ymin, ymax),
402         noms[1],
403         l[2],
404         l[3],
405         l[6],
406         l[7],
407         l2[2],
408         l2[3],
409         "\\end{pspicture}",
410         "\\end{center}",
411         "\\end{minipage}",
412         "\\begin{minipage}{0.5\\linewidth}",
413         "\\psset{unit=0.7cm}",
414         "\\begin{center}",
415         "\\begin{pspicture}" + str((xmin, ymin)) + str((xmax, ymax)),
416         "\\psgrid[subgriddiv=2, gridlabels=8pt](0,0)" + str((xmin, ymin)) + str((xmax, ymax)),
417         "\\psline[linewidth=1.2pt]{->}" + str((xmin, 0)) + str((xmax, 0)),
418         "\\psline[linewidth=1.2pt]{->}" + str((0, ymin)) + str((0, ymax)),
419         tracedroite(E, F, xmin, xmax, ymin, ymax),
420         noms[2],
421         l3[4],
422         l3[5],
423         l3[6],
424         l3[7],
425         "\\end{pspicture}",
426         "\\end{center}",
427         "\\end{minipage}",
428         "\\vspace{0.45cm}"]
429    return exo, cor
430
431affine.description = u'Fonctions affines'
Note: See TracBrowser for help on using the repository browser.