source: pyromaths/trunk/fuentes/src/pyromaths/ex/lycee/VariationsFonctions.py @ 423

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

add sources from pyromaths 15.10

File size: 49.6 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#
23from pyromaths import ex
24from random import randrange, shuffle
25#===============================================================================
26# from pyromaths.outils import Priorites3
27# from pyromaths.classes.Fractions import Fraction
28# from pyromaths.classes.PolynomesCollege import Polynome, factoriser
29# from pyromaths.classes.SquareRoot import SquareRoot
30from pyromaths.outils.Arithmetique import valeur_alea
31from pyromaths.outils.Affichage import decimaux
32from string import zfill
33#===============================================================================
34
35def PointsCourbes(sens_var=(-1, -1, 0, 1, 1), nb_var=(3, 5), absc=(-5, 5), ordo=(-4, 4), cstes=(0, 1)):
36    """Définit les ordonnées entières dans [-5 ; 5] de points d'abscisses entières dans [-5 ; 5]
37    de telle sorte que la fonction sur chaque intervalle comporte entre 3 et 5 variations différentes,
38    une seule section pouvant être constante.
39    La fonction doit avoir des images positives et négatives.
40    variations= [[-1, -6, -2], [1, -2, 1], [-1, 1, 2], [0, 2, 4]]
41    """
42    while True:
43        lY, sens, variations = [valeur_alea(ordo[0], ordo[1])], [], []
44        nb_cste = 0
45        for dummy in range(absc[1] - absc[0]):
46            while True:
47                lg = valeur_alea(1, 4)
48                # pente maximale entre deux points consécutifs
49                sens.append(sens_var[randrange(len(sens_var))])
50                nY = lY[-1] + lg * sens[-1]
51                if ordo[0] <= nY <= ordo[1]:
52                    if nY * lY[-1] < 0: lY.append(0)
53                    else: lY.append(nY)
54                    if not variations or sens[-1] != variations[-1][0]:
55                        variations.append([sens[-1], dummy + absc[0], dummy + absc[0] + 1])
56                    else:
57                        variations[-1][2] = dummy + absc[0] + 1
58                    break
59                else:
60                    sens.pop(-1)
61        if nb_var[0] <= len(variations) <= nb_var[1]:
62            extremums = []
63            gextr = [100, -100]  # extrema sur l'esnble de définition
64            for i in range(len(variations)):
65                if lY[variations[i][1] - absc[0]] > gextr[1]: gextr[1] = lY[variations[i][1] - absc[0]]
66                elif lY[variations[i][1] - absc[0]] < gextr[0]: gextr[0] = lY[variations[i][1] - absc[0]]
67                if extremums.count(lY[variations[i][1] - absc[0]]) > 0 and variations[i - 1][0] != 0:
68                    nb_cste = cstes[1] + 1
69                else:
70                    extremums.append(lY[variations[i][1] - absc[0]])
71                if variations[i][0] == 0:nb_cste += 1
72            if extremums.count(lY[-1]): nb_cste = cstes[1] + 1
73            if lY[-1] > gextr[1]: gextr[1] = lY[-1]
74            elif lY[-1] < gextr[0]: gextr[0] = lY[-1]
75            if gextr[0] * gextr[1] >= 0: nb_cste = cstes[1] + 1
76            if cstes[0] <= nb_cste <= cstes[1]: break
77    variations[-1][2] = absc[1]
78    return lY, variations
79
80def remplissage_tableau(lX, lY, variations):
81    """Renvoie la liste des abscisses, des ordonnées et des zéros (position et abscisse)
82    pour compléter un tableau de variations"""
83    lAbsc = [str(v[1]) for v in variations] + [str(variations[-1][2])]
84    lOrdo = []
85    for index in range(len(variations)):
86        lOrdo.append(lY[variations[index][1] - lX[0]])
87    lOrdo.append(lY[-1])
88    lZeros = []
89    for absc in range(lX[0], lX[-1] + 1):
90        if lY[absc - lX[0]] == 0:
91            for index in range(len(variations)):
92                if variations[index][1] < absc < variations[index][2]:
93                    if variations[index][0] != 0:
94                        lZeros.append([index + 1, index + 2, absc])
95                    break
96                if variations[index][1] == absc or variations[index][2] == absc:
97                    break
98    return lAbsc, lOrdo, lZeros
99
100def integration_zeros(lX, lY, variations):
101    """Renvoie la liste des abscisses et des ordonnées des extrema locaux et des zéros"""
102    lAbs, lOrd, lZeros = remplissage_tableau(lX, lY, variations)
103    lZeros.reverse()
104    for z in lZeros:
105        lAbs.insert(z[0], z[2])
106        lOrd.insert(z[0], 0)
107    return lAbs, lOrd
108
109
110class Vf1SensEtTableau(ex.TexExercise):
111
112    description = _(u'Sens et Tableau de variations')
113    level = _(u"2.Seconde")
114
115    def __init__(self):
116        lX = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
117        self.lX = lX
118        self.lY1, self.variations1 = PointsCourbes(sens_var=(-1, 1))
119        self.lY2, self.variations2 = PointsCourbes()
120
121
122
123    def tex_statement(self):
124        exo = [r'\exercice']
125        exo.append(r'\begin{enumerate}')
126        exo.append(_(u'\\item Quel est le sens de variation de la fonction $f$ ? Répondre par une phrase en précisant les intervalles.'))
127        exo.append(_(r'\item Tracer les tableaux de variation des fonctions $f$ et $g$.'))
128        exo.append(r'\end{enumerate}')
129        exo.append(r'\begin{center}')
130        exo.append('\\begin{asy}\n import graph;\n import interpolate;\n unitsize(5mm);')
131        exo.append(r'defaultpen(fontsize(9pt));')
132        exo.append(r'real[] xpt,ypt;')
133        exo.append(r'real [] xpt={%s};' % (",".join([zfill(str(a), 2) for a in self.lX])))
134        exo.append(r'real [] ypt={%s};' % (",".join([zfill(str(a), 2) for a in self.lY1])))
135        exo.append(r'xlimits(-6.2, 6.2);')
136        exo.append(r'ylimits(-5.2, 5.2);')
137        exo.append(r'xaxis(axis=BottomTop, p=invisible,')
138        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
139        exo.append(r'pTick=gray+.5, ptick=dotted)')
140        exo.append(r');')
141        exo.append(r'yaxis(axis=LeftRight, p=invisible,')
142        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
143        exo.append(r'pTick=gray+.5, ptick=dotted)')
144        exo.append(r');')
145        exo.append(r'xequals(L="$y$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
146        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
147        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
148        exo.append(r'yequals(L="$x$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
149        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
150        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
151        exo.append(r'draw(graph(xpt,ypt,Hermite(monotonic)),brown+1.5);')
152        exo.append(r'labelx(L=scale(.7)*"$0$", (0,0), align=SW);')
153        exo.append(r'label(L="$\mathcal{C}_f$", (%s,%s), align=%s);' % (self.lX[0], self.lY1[0], ('SE', 'NW', 'SW')[self.variations1[0][0]]))
154        exo.append(r'\end{asy}')
155        exo.append(r'\kern1cm')
156        exo.append('\\begin{asy}\n import graph;\n import interpolate;\n unitsize(5mm);')
157        exo.append(r'defaultpen(fontsize(9pt));')
158        exo.append(r'real[] xpt,ypt;')
159        exo.append(r'real [] xpt={%s};' % (",".join([zfill(str(a), 2) for a in self.lX])))
160        exo.append(r'real [] ypt={%s};' % (",".join([zfill(str(a), 2) for a in self.lY2])))
161        exo.append(r'xlimits(-6.2, 6.2);')
162        exo.append(r'ylimits(-5.2, 5.2);')
163        exo.append(r'xaxis(axis=BottomTop, p=invisible,')
164        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
165        exo.append(r'pTick=gray+.5, ptick=dotted)')
166        exo.append(r');')
167        exo.append(r'yaxis(axis=LeftRight, p=invisible,')
168        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
169        exo.append(r'pTick=gray+.5, ptick=dotted)')
170        exo.append(r');')
171        exo.append(r'xequals(L="$y$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
172        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
173        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
174        exo.append(r'yequals(L="$x$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
175        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
176        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
177        exo.append(r'draw(graph(xpt,ypt,Hermite(monotonic)),brown+1.5);')
178        exo.append(r'labelx(L=scale(.7)*"$0$", (0,0), align=SW);')
179        exo.append(r'label(L="$\mathcal{C}_g$", (%s,%s), align=%s);' % (self.lX[0], self.lY2[0], ('SE', 'NW', 'SW')[self.variations2[0][0]]))
180        exo.append(r'\end{asy}')
181        exo.append(r'\end{center}')
182
183        return exo
184
185    def tex_answer(self):
186        exo = [r'\exercice*']
187        exo.append(r'\begin{enumerate}')
188        ans = _(u'\\item la fonction $f$ est')
189        dvar = {_(u'décroissante'): [], _(u'croissante'): [], _(u'constante'):[]}
190        for v in self.variations1:
191            if v[0] == 1: dvar[_(u'croissante')].append('$[%s~;~%s]$' % (v[1], v[2]))
192            elif v[0] == -1: dvar[_(u'décroissante')].append('$[%s~;~%s]$' % (v[1], v[2]))
193            elif v[0] == 0: dvar[_(u'constante')].append('$[%s~;~%s]$' % (v[1], v[2]))
194            else: raise ValueError(_('variation non attendue'))
195        if dvar[_(u'décroissante')]: ans += u' décroissante sur %s,' % ' et '.join(dvar[_(u'décroissante')])
196        if dvar[_(u'croissante')]: ans += u' croissante sur %s' % ' et '.join(dvar[_(u'croissante')])
197        if dvar[_(u'constante')]: ans += u' constante sur %s' % ' et '.join(dvar[_(u'constante')])
198        ans += '.'
199        exo.append(ans)
200        exo.append(r'\item')
201        exo.append(r'\begin{tabular}[t]{ll}')
202        for j in range(2):
203            variations = [self.variations1, self.variations2][j]
204            lY = [self.lY1, self.lY2][j]
205            exo.append(r'\begin{tikzpicture}[scale=1]')
206            exo.append(r'\tkzTabInit[lgt=1.2,espcl=1.2]{$x$/1,$%s\,(x)$/3}{$%s$}' % (['f', 'g'][j], '$,$'.join([str(v[1]) for v in variations] + [str(variations[-1][2])])))
207            ans = r'\tkzTabVar{'  # %-/$-2$,+/$5$,-/$-3$,+/$-1$,-/$-4$}'
208            trois_niv = False
209            for index in range(len(variations)):
210                yindex = variations[index][1] + 5
211                if variations[index][0] == 1:
212                    if trois_niv:
213                        ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
214                        trois_niv = False
215                    else: ans += r'-/$%s$,' % lY[yindex]
216                if variations[index][0] == -1:
217                    if trois_niv:
218                        ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
219                        trois_niv = False
220                    else: ans += r'+/$%s$,' % lY[yindex]
221                if variations[index][0] == 0:
222                    if index > 0 and index < len(variations) - 1 and variations[index - 1][0] * variations[index + 1][0] > 0:
223                        trois_niv = True
224                    if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
225                    elif index > 0:
226                        if variations[index - 1][0] == 1: ans += r'+/$%s$,' % lY[yindex]
227                        else: ans += r'-/$%s$,' % lY[yindex]
228                    elif index < len(variations) - 1:
229                        if variations[index + 1][0] == 1: ans += r'-/$%s$,' % lY[yindex]
230                        else: ans += r'+/$%s$,' % lY[yindex]
231            if variations[-1][0] == 1:  ans += r'+/$%s$}' % lY[-1]
232            elif variations[-1][0] == -1:  ans += r'-/$%s$}' % lY[-1]
233            elif variations[-1][0] == 0:
234                if variations[-2][0] == 1:  ans += r'+/$%s$}' % lY[-1]
235                elif variations[-2][0] == -1:  ans += r'-/$%s$}' % lY[-1]
236            exo.append(ans)
237            # Place les zéros
238            for absc in range(-5, 6):
239                if lY[absc + 5] == 0:
240                    for index in range(len(variations)):
241                        if variations[index][1] < absc < variations[index][2]:
242                            if variations[index][0] != 0:
243                                exo.append(r'\tkzTabVal{%s}{%s}{0.5}{\scriptsize $%s$}{$0$}' % (index + 1, index + 2, absc))
244                            break
245                        if variations[index][1] == absc or variations[index][2] == absc:
246                            break
247            exo.append(r'\end{tikzpicture}')
248            exo.append(r'&')
249        exo.pop(-1)
250        exo.append(r'\end{tabular}')
251        exo.append(r'\end{enumerate}')
252
253        return exo
254
255def extrema(lX, lY, intervalle):
256    extremums = [[None, 1000], [None, -1000]]
257    for i in range(intervalle[0] - lX[0], intervalle[1] + 1 - lX[0]):
258        if lY[i] < extremums[0][1]:
259            extremums[0][0] = lX[i]
260            extremums[0][1] = lY[i]
261        if lY[i] > extremums[1][1]:
262            extremums[1][0] = lX[i]
263            extremums[1][1] = lY[i]
264    return extremums
265
266class Vf2ExtremaGraphiques(ex.TexExercise):
267    description = _(u'Extrema et représentation graphique')
268    level = _(u"2.Seconde")
269
270    def __init__(self):
271        fin = False
272        while not fin:  # Évite les boucles infinies
273            lX = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
274            self.lX = list(lX)
275            self.lY1, self.variations1 = PointsCourbes(sens_var=(-1, 1))
276            self.lY2, self.variations2 = PointsCourbes()
277            self.extremum = (u'maximum', u'minimum')[randrange(2)]
278            for dummy in range(20):
279                lX = list(self.lX)
280                intervalle1 = [lX.pop(randrange(len(lX)))]
281                intervalle1.append(lX.pop(randrange(len(lX))))
282                intervalle1 = sorted(intervalle1)
283                [gmin, gmax] = extrema(self.lX, self.lY1, [-5, 5])
284                [lmin, lmax] = extrema(self.lX, self.lY1, intervalle1)
285                if abs(lmin[0] - lmax[0]) > 1 and lmin[1] != gmin[1] and lmax[1] != gmax[1]:
286                    fin = True
287                    break
288            if fin:
289                fin = False
290                for dummy in range(20):
291                    lX = list(self.lX)
292                    lX.remove(intervalle1[0])
293                    lX.remove(intervalle1[1])
294                    intervalle2 = [lX.pop(randrange(len(lX)))]
295                    intervalle2.append(lX.pop(randrange(len(lX))))
296                    intervalle2 = sorted(intervalle2)
297                    [gmin, gmax] = extrema(self.lX, self.lY1, [-5, 5])
298                    [lmin, lmax] = extrema(self.lX, self.lY1, intervalle2)
299                    if abs(lmin[0] - lmax[0]) > 1 and lmin[1] != gmin[1] and lmax[1] != gmax[1]:
300                        fin = True
301                        break
302        self.intervalle1 = intervalle1
303        self.intervalle2 = intervalle2
304
305    def tex_statement(self):
306        exo = [r'\exercice']
307        exo.append(r'\begin{multicols}{2}')
308        exo.append(r'\begin{enumerate}')
309        exo.append(_(u'\\item Quels sont les extrema de la fonction $f$ ?'))
310        exo.append(_(u'\\item Quel est le %s de $f$ sur l\'intervalle $[%s~;~%s]$ ?') % (self.extremum, self.intervalle1[0], self.intervalle1[1]))
311        exo.append(_(u'\\item Quels sont les extrema de la fonction $g$ ?'))
312        exo.append(_(u'\\item Quels sont les extrema de $g$ sur l\'intervalle $[%s~;~%s]$ ?') % (self.intervalle2[0], self.intervalle2[1]))
313        exo.append(r'\end{enumerate}')
314        exo.append(r'\end{multicols}')
315        exo.append(r'\begin{center}')
316        exo.append('\\begin{asy}\n import graph;\n import interpolate;\n unitsize(5mm);')
317        exo.append(r'defaultpen(fontsize(9pt));')
318        exo.append(r'real[] xpt,ypt;')
319        exo.append(r'real [] xpt={%s};' % (",".join([zfill(str(a), 2) for a in self.lX])))
320        exo.append(r'real [] ypt={%s};' % (",".join([zfill(str(a), 2) for a in self.lY1])))
321        exo.append(r'xlimits(-6.2, 6.2);')
322        exo.append(r'ylimits(-5.2, 5.2);')
323        exo.append(r'xaxis(axis=BottomTop, p=invisible,')
324        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
325        exo.append(r'pTick=gray+.5, ptick=dotted)')
326        exo.append(r');')
327        exo.append(r'yaxis(axis=LeftRight, p=invisible,')
328        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
329        exo.append(r'pTick=gray+.5, ptick=dotted)')
330        exo.append(r');')
331        exo.append(r'xequals(L="$y$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
332        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
333        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
334        exo.append(r'yequals(L="$x$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
335        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
336        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
337        exo.append(r'draw(graph(xpt,ypt,Hermite(monotonic)),brown+1.5);')
338        exo.append(r'labelx(L=scale(.7)*"$0$", (0,0), align=SW);')
339        exo.append(r'label(L="$\mathcal{C}_f$", (%s,%s), align=%s);' % (self.lX[0], self.lY1[0], ('SE', 'NW', 'SW')[self.variations1[0][0]]))
340        exo.append(r'\end{asy}')
341        exo.append(r'\kern1cm')
342        exo.append('\\begin{asy}\n import graph;\n import interpolate;\n unitsize(5mm);')
343        exo.append(r'defaultpen(fontsize(9pt));')
344        exo.append(r'real[] xpt,ypt;')
345        exo.append(r'real [] xpt={%s};' % (",".join([zfill(str(a), 2) for a in self.lX])))
346        exo.append(r'real [] ypt={%s};' % (",".join([zfill(str(a), 2) for a in self.lY2])))
347        exo.append(r'xlimits(-6.2, 6.2);')
348        exo.append(r'ylimits(-5.2, 5.2);')
349        exo.append(r'xaxis(axis=BottomTop, p=invisible,')
350        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
351        exo.append(r'pTick=gray+.5, ptick=dotted)')
352        exo.append(r');')
353        exo.append(r'yaxis(axis=LeftRight, p=invisible,')
354        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
355        exo.append(r'pTick=gray+.5, ptick=dotted)')
356        exo.append(r');')
357        exo.append(r'xequals(L="$y$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
358        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
359        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
360        exo.append(r'yequals(L="$x$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
361        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
362        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
363        exo.append(r'draw(graph(xpt,ypt,Hermite(monotonic)),brown+1.5);')
364        exo.append(r'labelx(L=scale(.7)*"$0$", (0,0), align=SW);')
365        exo.append(r'label(L="$\mathcal{C}_g$", (%s,%s), align=%s);' % (self.lX[0], self.lY2[0], ('SE', 'NW', 'SW')[self.variations2[0][0]]))
366        exo.append(r'\end{asy}')
367        exo.append(r'\end{center}')
368        return exo
369
370    def tex_answer(self):
371        exo = [r'\exercice*']
372        exo.append(r'\begin{enumerate}')
373        extr = extrema(self.lX, self.lY1, [self.lX[0], self.lX[-1]])
374        exo.append(u'\\item ')
375        exo.append(r'\begin{itemize}[leftmargin=*]')
376        exo.append(_(u'\\item Sur $[%s~;~%s]$ , le \\textbf{maximum} de $f$ est $y = %s$. Il est \\textbf{atteint en} $x = %s$.') % (self.lX[0], self.lX[-1], extr[1][1], extr[1][0]))
377        exo.append(_(u'\\item Sur $[%s~;~%s]$ , le \\textbf{minimum} de $f$ est $y = %s$. Il est \\textbf{atteint en} $x = %s$.') % (self.lX[0], self.lX[-1], extr[0][1], extr[0][0]))
378        exo.append(r'\end{itemize}')
379        extr = extrema(self.lX, self.lY1, self.intervalle1)
380        extr = extr[self.extremum == "maximum"]
381        exo.append(_(u'\\item Sur $[%s~;~%s]$, le \\textbf{%s} de $f$ est $y = %s$. Il est \\textbf{atteint en} $x = %s$. ') % (self.intervalle1[0], self.intervalle1[1], self.extremum, extr[1], extr[0]))
382        extr = extrema(self.lX, self.lY2, [self.lX[0], self.lX[-1]])
383        exo.append(u'\\item ')
384        exo.append(r'\begin{itemize}[leftmargin=*]')
385        exo.append(_(u'\\item Sur $[%s~;~%s]$ , le \\textbf{maximum} de $g$ est $y = %s$. Il est \\textbf{atteint en} $x = %s$.') % (self.lX[0], self.lX[-1], extr[1][1], extr[1][0]))
386        exo.append(_(u'\\item Sur $[%s~;~%s]$ , le \\textbf{minimum} de $g$ est $y = %s$. Il est \\textbf{atteint en} $x = %s$.') % (self.lX[0], self.lX[-1], extr[0][1], extr[0][0]))
387        exo.append(r'\end{itemize}')
388        extr = extrema(self.lX, self.lY2, self.intervalle2)
389        exo.append(u'\\item ')
390        exo.append(r'\begin{itemize}[leftmargin=*]')
391        exo.append(_(u'\\item Sur $[%s~;~%s]$ , le \\textbf{maximum} de $g$ est $y = %s$. Il est \\textbf{atteint en} $x = %s$.') % (self.intervalle2[0], self.intervalle2[1], extr[1][1], extr[1][0]))
392        exo.append(_(u'\\item Sur $[%s~;~%s]$ , le \\textbf{minimum} de $g$ est $y = %s$. Il est \\textbf{atteint en} $x = %s$.') % (self.intervalle2[0], self.intervalle2[1], extr[0][1], extr[0][0]))
393        exo.append(r'\end{itemize}')
394        exo.append(r'\end{enumerate}')
395        return exo
396
397class Vf3VariationVersCourbe(ex.TexExercise):
398    description = _(u'Tableaux de variations et courbe')
399    level = _(u"2.Seconde")
400
401    def __init__(self):
402        lX = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
403        self.lX = list(lX)
404        self.lY1, self.variations1 = PointsCourbes(sens_var=(-1, 1))
405        self.lY2, self.variations2 = PointsCourbes()
406
407    def tex_statement(self):
408        exo = [r'\exercice']
409        exo.append(r'\begin{enumerate}')
410        exo.append(_(u'\\item Pour chaque question, répondre avec une phrase en précisant les intervalles.\\vspace{-2ex}'))
411        exo.append(r'\begin{multicols}{2}')
412        exo.append(r'\begin{enumerate}')
413        exo.append(_(u'\\item Quel est le signe de la fonction $f$ ?'))
414        exo.append(_(u'\\item Quels sont les extrema de la fonction $g$ ?'))
415        exo.append(r'\end{enumerate}')
416        exo.append(r'\end{multicols}')
417        exo.append(_(u'\\item Tracer une représentation graphique de $f$ et $g$ sur leurs ensembles de définition.'))
418        exo.append(r'\end{enumerate}')
419        exo.append(r'\begin{center}')
420        exo.append(r'\begin{tabular}[t]{ll}')
421        for j in range(2):
422            variations = [self.variations1, self.variations2][j]
423            lY = [self.lY1, self.lY2][j]
424            exo.append(r'\begin{tikzpicture}[scale=1]')
425            exo.append(r'\tkzTabInit[lgt=1.2,espcl=1.2]{$x$/1,$%s\,(x)$/3}{$%s$}' % (['f', 'g'][j], '$,$'.join([str(v[1]) for v in variations] + [str(variations[-1][2])])))
426            ans = r'\tkzTabVar{'  # %-/$-2$,+/$5$,-/$-3$,+/$-1$,-/$-4$}'
427            trois_niv = False
428            for index in range(len(variations)):
429                yindex = variations[index][1] + 5
430                if variations[index][0] == 1:
431                    if trois_niv:
432                        ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
433                        trois_niv = False
434                    else: ans += r'-/$%s$,' % lY[yindex]
435                if variations[index][0] == -1:
436                    if trois_niv:
437                        ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
438                        trois_niv = False
439                    else: ans += r'+/$%s$,' % lY[yindex]
440                if variations[index][0] == 0:
441                    if index > 0 and index < len(variations) - 1 and variations[index - 1][0] * variations[index + 1][0] > 0:
442                        trois_niv = True
443                    if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
444                    elif index > 0:
445                        if variations[index - 1][0] == 1: ans += r'+/$%s$,' % lY[yindex]
446                        else: ans += r'-/$%s$,' % lY[yindex]
447                    elif index < len(variations) - 1:
448                        if variations[index + 1][0] == 1: ans += r'-/$%s$,' % lY[yindex]
449                        else: ans += r'+/$%s$,' % lY[yindex]
450            if variations[-1][0] == 1:  ans += r'+/$%s$}' % lY[-1]
451            elif variations[-1][0] == -1:  ans += r'-/$%s$}' % lY[-1]
452            elif variations[-1][0] == 0:
453                if variations[-2][0] == 1:  ans += r'+/$%s$}' % lY[-1]
454                elif variations[-2][0] == -1:  ans += r'-/$%s$}' % lY[-1]
455            exo.append(ans)
456            # Place les zéros
457            for absc in range(-5, 6):
458                if lY[absc + 5] == 0:
459                    for index in range(len(variations)):
460                        if variations[index][1] < absc < variations[index][2]:
461                            if variations[index][0] != 0:
462                                exo.append(r'\tkzTabVal{%s}{%s}{0.5}{\scriptsize $%s$}{$0$}' % (index + 1, index + 2, absc))
463                            break
464                        if variations[index][1] == absc or variations[index][2] == absc:
465                            break
466            exo.append(r'\end{tikzpicture}')
467            exo.append(r'&')
468        exo.pop(-1)
469        exo.append(r'\end{tabular}')
470        exo.append(r'\end{center}')
471
472        return exo
473
474    def tex_answer(self):
475        exo = [r'\exercice*']
476        exo.append(r'\begin{enumerate}')
477        exo.append(r'\item')
478        exo.append(r'\begin{enumerate}')
479        lneg, lpos = [], []
480        for index in range(len(self.lX)):
481            absc = self.lX[index]
482            if self.lY1[index] < 0:
483                if lneg and absc - lneg[-1][1] == 1:
484                    lneg[-1][1] = absc
485                else:
486                    lneg.append([absc, absc])
487            elif self.lY1[index] > 0:
488                if lpos and absc - lpos[-1][1] == 1:
489                    lpos[-1][1] = absc
490                else:
491                    lpos.append([absc, absc])
492            else:  # nul
493                if lneg and absc - lneg[-1][1] == 1:
494                    lneg[-1][1] = absc
495                    lpos.append([absc, absc])
496                elif lpos and absc - lpos[-1][1] == 1:
497                    lpos[-1][1] = absc
498                    lneg.append([absc, absc])
499                else:
500                    lneg.append([absc, absc])
501                    lpos.append([absc, absc])
502        sneg, spos = '', ''
503        for i in lneg:
504            if i[1] == i[0]: lneg.remove(i)
505            else: sneg += '$[%s~;~%s]$, ' % (i[0], i[1])
506        sneg = sneg[:-2]
507        for i in lpos:
508            if i[1] == i[0]: lpos.remove(i)
509            else: spos += '$[%s~;~%s]$, ' % (i[0], i[1])
510        spos = spos[:-2]
511
512        exo.append(_(u'\\item La fonction $f$ est \\textbf{négative} sur %s et \\textbf{positive} sur %s.') % (sneg, spos))
513        extr = extrema(self.lX, self.lY2, [self.lX[0], self.lX[-1]])
514        exo.append(r'\item')
515        exo.append(r'\begin{itemize}[leftmargin=*]')
516        exo.append(_(u'\\item Sur $[%s~;~%s]$ , le \\textbf{maximum} de $g$ est $y = %s$. Il est \\textbf{atteint en} $x = %s$.') % (self.lX[0], self.lX[-1], extr[1][1], extr[1][0]))
517        exo.append(_(u'\\item Sur $[%s~;~%s]$ , le \\textbf{minimum} de $g$ est $y = %s$. Il est \\textbf{atteint en} $x = %s$.') % (self.lX[0], self.lX[-1], extr[0][1], extr[0][0]))
518        exo.append(r'\end{itemize}')
519        exo.append(r'\end{enumerate}')
520        exo.append(r'\item\ ')
521        exo.append(r'\begin{center}')
522        exo.append(r'\begin{tabular}[t]{cc}')
523        exo.append(r'\begin{adjustbox}{valign=t}')
524        exo.append('\\begin{asy}\n import graph;\n import interpolate;\n unitsize(5mm);')
525        exo.append(r'defaultpen(fontsize(9pt));')
526        exo.append(r'real[] xpt,ypt;')
527        lAbsc, lOrdo = integration_zeros(self.lX, self.lY1, self.variations1)
528        exo.append(r'real [] xpt={%s};' % (",".join([zfill(str(a), 2) for a in lAbsc])))
529        exo.append(r'real [] ypt={%s};' % (",".join([zfill(str(a), 2) for a in lOrdo])))
530        exo.append(r'xlimits(-6.2, 6.2);')
531        exo.append(r'ylimits(-5.2, 5.2);')
532        exo.append(r'xaxis(axis=BottomTop, p=invisible,')
533        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
534        exo.append(r'pTick=gray+.5, ptick=dotted)')
535        exo.append(r');')
536        exo.append(r'yaxis(axis=LeftRight, p=invisible,')
537        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
538        exo.append(r'pTick=gray+.5, ptick=dotted)')
539        exo.append(r');')
540        exo.append(r'xequals(L="$y$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
541        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
542        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
543        exo.append(r'yequals(L="$x$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
544        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
545        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
546        exo.append(r'draw(graph(xpt,ypt,Hermite(monotonic)),brown+1.5);')
547        exo.append(r'labelx(L=scale(.7)*"$0$", (0,0), align=SW);')
548        exo.append(r'label(L="$\mathcal{C}_f$", (%s,%s), align=%s);' % (self.lX[0], self.lY1[0], ('SE', 'NW', 'SW')[self.variations1[0][0]]))
549        exo.append(r'\end{asy}')
550        exo.append(r'\end{adjustbox}')
551        exo.append(r'&')
552        exo.append(r'\begin{adjustbox}{valign=t}')
553        exo.append('\\begin{asy}\n import graph;\n import interpolate;\n unitsize(5mm);')
554        exo.append(r'defaultpen(fontsize(9pt));')
555        exo.append(r'real[] xpt,ypt;')
556        lAbsc, lOrdo = integration_zeros(self.lX, self.lY2, self.variations2)
557        exo.append(r'real [] xpt={%s};' % (",".join([zfill(str(a), 2) for a in lAbsc])))
558        exo.append(r'real [] ypt={%s};' % (",".join([zfill(str(a), 2) for a in lOrdo])))
559        exo.append(r'xlimits(-6.2, 6.2);')
560        exo.append(r'ylimits(-5.2, 5.2);')
561        exo.append(r'xaxis(axis=BottomTop, p=invisible,')
562        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
563        exo.append(r'pTick=gray+.5, ptick=dotted)')
564        exo.append(r');')
565        exo.append(r'yaxis(axis=LeftRight, p=invisible,')
566        exo.append(r'ticks=Ticks(format="%%", Step=1, extend=true,')
567        exo.append(r'pTick=gray+.5, ptick=dotted)')
568        exo.append(r');')
569        exo.append(r'xequals(L="$y$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
570        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
571        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
572        exo.append(r'yequals(L="$x$", 0, extend=false, arrow=Arrow(HookHead, size=9pt), p=black+1,')
573        exo.append(r'ticks=Ticks(scale(.7)*Label(filltype=Fill(white)), Step=1, Size=3pt,')
574        exo.append(r'end=false, endlabel=false, beginlabel=false, NoZero));')
575        exo.append(r'draw(graph(xpt,ypt,Hermite(monotonic)),brown+1.5);')
576        exo.append(r'labelx(L=scale(.7)*"$0$", (0,0), align=SW);')
577        exo.append(r'label(L="$\mathcal{C}_g$", (%s,%s), align=%s);' % (self.lX[0], self.lY2[0], ('SE', 'NW', 'SW')[self.variations2[0][0]]))
578        exo.append(r'\end{asy}')
579        exo.append(r'\end{adjustbox}')
580        exo.append(r'\end{tabular}')
581        exo.append(r'\end{center}')
582        exo.append(r'\end{enumerate}')
583        return exo
584
585def elements_intervalle(variations, sens):
586    """Renvoie deux nombres appartenant à un intervalle sur lequel la fonction est monotone, ainsi que l'intervalle monotone auquel ils appartiennent"""
587    while True:
588        index = randrange(len(variations))
589        if variations[index][0] == sens:
590            break
591    x0 = decimaux(randrange(50 * variations[index][1] // 6 + 10 * variations[index][2] // 6, 20 * variations[index][1] // 3 + 10 * variations[index][2] // 3 + 1) / 10., True)
592    x1 = decimaux(randrange(10 * variations[index][1] // 3 + 20 * variations[index][2] // 3, 10 * variations[index][1] // 6 + 50 * variations[index][2] // 6, +1) / 10., True)
593    return [x0, x1, [variations[index][1], variations[index][2]]]
594
595def non_monotone(variations, lX, lY, signe):
596    """Donne un intervalle sur lequel la fonction n'est pas monotone. On peut malgré tout comparer
597    les extrémités de cet intervalle par le signe de leurs images si signe=True"""
598    for dummy in range(20):
599        tirage = [a for a in range(len(variations))]
600        try:
601            i0 = tirage.pop(randrange(len(tirage)))
602            while lY[i0] == lY[i0 + 1]:
603                # intervalle constant
604                i0 = tirage.pop(randrange(len(tirage)))
605            i1 = tirage.pop(randrange(len(tirage)))
606            while lY[i1] == lY[i1 + 1]:
607                # intervalle constant
608                i1 = tirage.pop(randrange(len(tirage)))
609        except ValueError:
610            return None
611        x0 = randrange(10 * variations[i0][1] + 1, 10 * variations[i0][2]) / 10.
612        x1 = randrange(10 * variations[i1][1] + 1, 10 * variations[i1][2]) / 10.
613        for i in range(len(lX)):
614            if x0 <= lX[i]:
615                if x0 == lX[i]: y0 = lY[i]
616                else: y0 = (lY[i - 1] + lY[i]) / 2.
617                break
618        for i in range(len(lX)):
619            if x1 <= lX[i]:
620                if x1 == lX[i]: y1 = lY[i]
621                else: y1 = (lY[i - 1] + lY[i]) / 2.
622                break
623        if signe and y0 * y1 <= 0: return ([x0, y0], [x1, y1])
624        if not signe and y0 * y1 > 0:
625            I = intersection_intervalles(variations[i0][1:], variations[i1][1:])
626            if I and I[0] != I[1]: return ([x0, y0], [x1, y1])
627    return None
628
629def intersection_intervalles(I0, I1):
630    "renvoie l'intersection entre 2 intervalles, None si vide."
631    x0, x1 = min(I0), max(I0)
632    y0, y1 = min(I1), max(I1)
633    x = max(x0, x1)
634    y = min(y0, y1)
635    if x <= y:return (x, y)
636    else: return None
637
638class Vf4ComparerImages(ex.TexExercise):
639    description = _(u'Comparer des images à partir du sens de variation')
640    level = _(u"2.Seconde")
641
642    def __init__(self):
643        fin = False
644        while not fin:
645            lX = [i for i in range(-10 + randrange(6), 10 - randrange(6))]
646            self.lX = list(lX)
647            lY, variations = PointsCourbes(nb_var=(4, 5), absc=(lX[0], lX[-1]), ordo=(lX[0], lX[-1]), cstes=(1, 1))
648            self.lY = list(lY)
649            self.variations = list(variations)
650            lx = elements_intervalle(self.variations, -1)
651            lx.append(-1)
652            comparaison = [lx]
653            lx = elements_intervalle(self.variations, 1)
654            lx.append(1)
655            comparaison.append(lx)
656            lx = elements_intervalle(self.variations, 0)
657            lx.append(0)
658            comparaison.append(lx)
659            shuffle(comparaison)
660            self.comparaison = comparaison
661            non_comparable = [non_monotone(self.variations, lX, self.lY, True)]
662            non_comparable.append(non_monotone(self.variations, lX, self.lY, False))
663            if non_comparable[0] != None and non_comparable[1] != None:
664                fin = True
665        shuffle(non_comparable)
666        self.non_comparable = non_comparable
667
668    def tex_statement(self):
669        exo = [r'\exercice']
670        exo.append(r'\begin{enumerate}')
671        exo.append(_(u'\\item À partir du tableau de variation ci-dessous, recopier et compléter les égalités ou inégalités suivantes en justifiant :\\vspace{-2ex}'))
672        exo.append(r'\begin{multicols}{3}')
673        exo.append(r'\begin{enumerate}')
674        exo.append(r'\item $f\,(%s) \ldots{} f\,(%s)$' % tuple(self.comparaison[0][:2]))
675        exo.append(r'\item $f\,(%s) \ldots{} f\,(%s)$' % tuple(self.comparaison[1][:2]))
676        exo.append(r'\item $f\,(%s) \ldots{} f\,(%s)$' % tuple(self.comparaison[2][:2]))
677        exo.append(r'\end{enumerate}\vspace{-2ex}')
678        exo.append(r'\end{multicols}')
679        exo.append(_(u'\\item Peut-on comparer l’image des nombres $%s$ et $%s$ ? Justifier.') % (decimaux(self.non_comparable[0][0][0]), decimaux(self.non_comparable[0][1][0])))
680        exo.append(_(u'\\item Peut-on comparer l’image des nombres $%s$ et $%s$ ? Justifier.') % (decimaux(self.non_comparable[1][0][0]), decimaux(self.non_comparable[1][1][0])))
681        exo.append(r'\end{enumerate}')
682        exo.append(r'\begin{center}')
683        variations = list(self.variations)
684        lY = list(self.lY)
685        exo.append(r'\begin{tikzpicture}[scale=1]')
686        exo.append(r'\tkzTabInit[lgt=1.2,espcl=2]{$x$/1,$f\,(x)$/3}{$%s$}' % ('$,$'.join([str(v[1]) for v in variations] + [str(variations[-1][2])])))
687        ans = r'\tkzTabVar{'  # %-/$-2$,+/$5$,-/$-3$,+/$-1$,-/$-4$}'
688        trois_niv = False
689        for index in range(len(variations)):
690            yindex = variations[index][1] - self.lX[0]
691            if variations[index][0] == 1:
692                if trois_niv:
693                    ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
694                    trois_niv = False
695                else: ans += r'-/$%s$,' % lY[yindex]
696            if variations[index][0] == -1:
697                if trois_niv:
698                    ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
699                    trois_niv = False
700                else: ans += r'+/$%s$,' % lY[yindex]
701            if variations[index][0] == 0:
702                if index > 0 and index < len(variations) - 1 and variations[index - 1][0] * variations[index + 1][0] > 0:
703                    trois_niv = True
704                if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
705                elif index > 0:
706                    if variations[index - 1][0] == 1: ans += r'+/$%s$,' % lY[yindex]
707                    else: ans += r'-/$%s$,' % lY[yindex]
708                elif index < len(variations) - 1:
709                    if variations[index + 1][0] == 1: ans += r'-/$%s$,' % lY[yindex]
710                    else: ans += r'+/$%s$,' % lY[yindex]
711        if variations[-1][0] == 1:  ans += r'+/$%s$}' % lY[-1]
712        elif variations[-1][0] == -1:  ans += r'-/$%s$}' % lY[-1]
713        elif variations[-1][0] == 0:
714            if variations[-2][0] == 1:  ans += r'+/$%s$}' % lY[-1]
715            elif variations[-2][0] == -1:  ans += r'-/$%s$}' % lY[-1]
716        exo.append(ans)
717        # Place les zéros
718        for absc in range(self.lX[0], self.lX[-1] + 1):
719            if lY[absc - self.lX[0]] == 0:
720                for index in range(len(variations)):
721                    if variations[index][1] < absc < variations[index][2]:
722                        if variations[index][0] != 0:
723                            exo.append(r'\tkzTabVal{%s}{%s}{0.5}{\scriptsize $%s$}{$0$}' % (index + 1, index + 2, absc))
724                        break
725                    if variations[index][1] == absc or variations[index][2] == absc:
726                        break
727        exo.append(r'\end{tikzpicture}')
728        exo.append(r'\end{center}')
729        return exo
730
731    def tex_answer(self):
732        exo = [r'\exercice*']
733        exo.append(r'\begin{enumerate}')
734        exo.append(r'\item')
735        exo.append(r'\begin{enumerate}')
736        for i in range(3):
737            exo.append(_(u'\\item $f\\,(%s) %s f\\,(%s)$ car $%s < %s$ et $f$ est %s sur $[%s~;~%s]$.') % (self.comparaison[i][0], ['=', '<', '>'][self.comparaison[i][3]], self.comparaison[i][1], self.comparaison[i][0], self.comparaison[i][1], [_(u'constante'), _(u'croissante'), _(u'décroissante')][self.comparaison[i][3]], self.comparaison[i][2][0], self.comparaison[i][2][1]))
738        exo.append(r'\end{enumerate}')
739        for i in range(2):
740            if self.non_comparable[i][0][1] * self.non_comparable[i][1][1] <= 0:
741                exo.append(_(u'\\item $f\\,(%s) %s f\\,(%s)$ car d’après le signe de la fonction $f\\,(%s) %s 0$ et $f\\,(%s) %s 0$ (par contre, on ne peut pas utiliser le sens de variation qui change sur l’intervalle $[%s~;~%s]$).') % \
742                           (decimaux(self.non_comparable[i][0][0], 1), ['<', '>'][self.non_comparable[i][0][1] > 0], decimaux(self.non_comparable[i][1][0], 1), \
743                            decimaux(self.non_comparable[i][0][0], 1), ['<', '>'][self.non_comparable[i][0][1] > 0], decimaux(self.non_comparable[i][1][0], 1), \
744                            ['<', '>'][self.non_comparable[i][1][1] > 0], decimaux(min(self.non_comparable[i][0][0], self.non_comparable[i][1][0]), 1), decimaux(max(self.non_comparable[i][0][0], self.non_comparable[i][1][0]), 1)))
745            else:
746                exo.append(_(u'\\item On ne peut pas comparer $f\\,(%s)$ et $f\\,(%s)$ car la fonction $f$ n\'est pas monotone (elle change de sens de variation) sur $[%s~;~%s]$.') % \
747                           (decimaux(self.non_comparable[i][0][0], 1), decimaux(self.non_comparable[i][1][0], 1), decimaux(self.non_comparable[i][0][0], 1), decimaux(self.non_comparable[i][1][0], 1)))
748        exo.append(r'\end{enumerate}')
749        return exo
750
751def extrema_locaux(variations, lX, lY):
752    """Donne un intervalle sur lequel la fonction n'est pas monotone et ou les extrema
753    sont différents de ceux sur l'ensemble de définition."""
754    [gmin, gmax] = extrema(lX, lY, [lX[0], lX[-1]])
755    gmin = gmin[1]
756    gmax = gmax[1]
757    for i in range(20):
758        tirage = [a for a in range(len(variations))]
759        i0 = tirage.pop(randrange(len(tirage)))
760        i1 = tirage.pop(randrange(len(tirage)))
761        x0 = randrange(10 * variations[i0][1] + 1, 10 * variations[i0][2]) / 10.
762        x1 = randrange(10 * variations[i1][1] + 1, 10 * variations[i1][2]) / 10.
763        for i in range(len(lX)):
764            if x0 <= lX[i]:
765                if x0 == lX[i]: y0 = lY[i]
766                else: y0 = (lY[i - 1] + lY[i]) / 2.
767                break
768        for i in range(len(lX)):
769            if x1 <= lX[i]:
770                if x1 == lX[i]: y1 = lY[i]
771                else: y1 = (lY[i - 1] + lY[i]) / 2.
772                break
773        extremums = [100, -100]
774        # extremums = [min(variations[i0][1], variations[i1][1]), max(variations[i0][2], variations[i1][2])]
775        if i0 > i1: i0, x0, y0, i1, x1, y1 = i1, x1, y1, i0, x0, y0
776        if y0 < 0 and variations[i0][0] == -1:
777            extremums[1] = min(lY[variations[i0][1] - lX[0]], 0)
778            extremums[0] = min(lY[variations[i0][1] - lX[0]], lY[variations[i0][2] - lX[0]])
779        elif y0 > 0 and variations[i0][0] == 1:
780            extremums[0] = max(lY[variations[i0][2] - lX[0]], 0)
781            extremums[1] = max(lY[variations[i0][1] - lX[0]], lY[variations[i0][2] - lX[0]])
782        else:
783            extremums[1] = max(lY[variations[i0][1] - lX[0]], lY[variations[i0][2] - lX[0]])
784            extremums[0] = min(lY[variations[i0][1] - lX[0]], lY[variations[i0][2] - lX[0]])
785        if y1 < 0 and variations[i1][0] == 1: extremums[1] = max(min(0, lY[variations[i1][2] - lX[0]]), extremums[1])
786        elif y1 > 0 and variations[i1][0] == -1: extremums[0] = min(max(0, lY[variations[i1][2] - lX[0]]), extremums[0])
787        else:
788            extremums[1] = max(lY[variations[i1][1] - lX[0]], lY[variations[i1][2] - lX[0]], extremums[1])
789            extremums[0] = min(lY[variations[i1][1] - lX[0]], lY[variations[i1][2] - lX[0]], extremums[0])
790        for index in range(i0 + 1, i1):
791            extremums[0] = min(extremums[0], extrema(lX, lY, variations[index][1:])[0][1])
792            extremums[1] = max(extremums[1], extrema(lX, lY, variations[index][1:])[1][1])
793        if extremums[0] != gmin and extremums[1] != gmax:
794            return [[x0, y0], [x1, y1], extremums]
795    return None
796
797class Vf5Extrema_Tableau(ex.TexExercise):
798    description = _(u'Extrema locaux à partir du tableau de variation')
799    level = _(u"2.Seconde")
800
801    def __init__(self):
802        fin = False
803        while not fin:
804            lX = [i for i in range(-10 + randrange(6), 10 - randrange(6))]
805            self.lX = list(lX)
806            lY, variations = PointsCourbes(nb_var=(4, 5), absc=(lX[0], lX[-1]), ordo=(lX[0], lX[-1]), cstes=(1, 1))
807            self.lY = list(lY)
808            self.variations = list(variations)
809            comparaison = [extrema_locaux(variations, lX, lY)]
810            comparaison.append(extrema_locaux(variations, lX, lY))
811            if comparaison[0] != None and comparaison[1] != None:
812                fin = True
813        self.comparaison = comparaison
814        inegalites = ['\\ge', '\\le']
815        shuffle(inegalites)
816        inegalites.append(['\\le', '\\ge'][randrange(2)])
817        self.inegalites = inegalites
818
819    def tex_statement(self):
820        exo = [r'\exercice']
821        exo.append(r'\begin{enumerate}')
822        exo.append(_(u'\\item À partir du tableau de variation de la fonction $f$, compléter les égalités ou inégalités suivantes :\\vspace{-2ex}'))
823        exo.append(r'\begin{multicols}{2}')
824        exo.append(r'\begin{enumerate}')
825        exo.append(r'\item Pour $x \in [%s~;~%s],\quad f\,(x) %s \ldots{}$' % (self.lX[0], self.lX[-1], self.inegalites[0]))
826        exo.append(r'\item Pour $x \in [%s~;~%s],\quad f\,(x) %s \ldots{}$' % (self.lX[0], self.lX[-1], self.inegalites[1]))
827        exo.append(r'\item Pour $x \in [%s~;~%s],\quad f\,(x) %s \ldots{}$' % (decimaux(self.comparaison[0][0][0], 1), decimaux(self.comparaison[0][1][0], 1), self.inegalites[2]))
828        exo.append(r'\end{enumerate}')
829        exo.append(r'\end{multicols}')
830        exo.append(u'\\item')
831        exo.append(r'\begin{enumerate}')
832        exo.append(_(u'\\item Donner un encadrement de la fonction $f$ sur l’intervalle $[%s~;~%s]$.') % (self.lX[0], self.lX[-1]))
833        exo.append(_(u'\\item Donner un encadrement de la fonction $f$ sur l’intervalle $[%s~;~%s]$.') % (decimaux(self.comparaison[1][0][0], 1), decimaux(self.comparaison[1][1][0], 1)))
834        exo.append(r'\end{enumerate}')
835        exo.append(r'\end{enumerate}')
836        exo.append(r'\begin{center}')
837        variations = list(self.variations)
838        lY = list(self.lY)
839        exo.append(r'\begin{tikzpicture}[scale=1]')
840        exo.append(r'\tkzTabInit[lgt=1.2,espcl=2]{$x$/1,$f\,(x)$/3}{$%s$}' % ('$,$'.join([str(v[1]) for v in variations] + [str(variations[-1][2])])))
841        ans = r'\tkzTabVar{'  # %-/$-2$,+/$5$,-/$-3$,+/$-1$,-/$-4$}'
842        trois_niv = False
843        for index in range(len(variations)):
844            yindex = variations[index][1] - self.lX[0]
845            if variations[index][0] == 1:
846                if trois_niv:
847                    ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
848                    trois_niv = False
849                else: ans += r'-/$%s$,' % lY[yindex]
850            if variations[index][0] == -1:
851                if trois_niv:
852                    ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
853                    trois_niv = False
854                else: ans += r'+/$%s$,' % lY[yindex]
855            if variations[index][0] == 0:
856                if index > 0 and index < len(variations) - 1 and variations[index - 1][0] * variations[index + 1][0] > 0:
857                    trois_niv = True
858                if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex]
859                elif index > 0:
860                    if variations[index - 1][0] == 1: ans += r'+/$%s$,' % lY[yindex]
861                    else: ans += r'-/$%s$,' % lY[yindex]
862                elif index < len(variations) - 1:
863                    if variations[index + 1][0] == 1: ans += r'-/$%s$,' % lY[yindex]
864                    else: ans += r'+/$%s$,' % lY[yindex]
865        if variations[-1][0] == 1:  ans += r'+/$%s$}' % lY[-1]
866        elif variations[-1][0] == -1:  ans += r'-/$%s$}' % lY[-1]
867        elif variations[-1][0] == 0:
868            if variations[-2][0] == 1:  ans += r'+/$%s$}' % lY[-1]
869            elif variations[-2][0] == -1:  ans += r'-/$%s$}' % lY[-1]
870        exo.append(ans)
871        # Place les zéros
872        for absc in range(self.lX[0], self.lX[-1] + 1):
873            if lY[absc - self.lX[0]] == 0:
874                for index in range(len(variations)):
875                    if variations[index][1] < absc < variations[index][2]:
876                        if variations[index][0] != 0:
877                            exo.append(r'\tkzTabVal{%s}{%s}{0.5}{\scriptsize $%s$}{$0$}' % (index + 1, index + 2, absc))
878                        break
879                    if variations[index][1] == absc or variations[index][2] == absc:
880                        break
881        exo.append(r'\end{tikzpicture}')
882        exo.append(r'\end{center}')
883        return exo
884
885    def tex_answer(self):
886        exo = [r'\exercice*']
887        exo.append(r'\begin{enumerate}')
888        exo.append(r'\item')
889        exo.append(r'\begin{multicols}{2}')
890        exo.append(r'\begin{enumerate}')
891        extr = extrema(self.lX, self.lY, [self.lX[0], self.lX[-1]])
892        exo.append(_(r'\item Pour $x \in [%s~;~%s],\quad f\,(x) %s %s$') % (self.lX[0], self.lX[-1], self.inegalites[0], extr['\\le' == self.inegalites[0]][1]))
893        exo.append(_(r'\item Pour $x \in [%s~;~%s],\quad f\,(x) %s %s$') % (self.lX[0], self.lX[-1], self.inegalites[1], extr['\\le' == self.inegalites[1]][1]))
894        exo.append(_(r'\item Pour $x \in [%s~;~%s],\quad f\,(x) %s %s$') % (decimaux(self.comparaison[0][0][0], 1), decimaux(self.comparaison[0][1][0], 1), self.inegalites[2], self.comparaison[0][2]['\\le' == self.inegalites[2]]))
895        exo.append(r'\end{enumerate}')
896        exo.append(r'\end{multicols}')
897        exo.append(r'\item')
898        exo.append(r'\begin{enumerate}')
899        exo.append(_(u'\\item Sur $[%s~;~%s],\\quad %s \\le f\\,(x) \\le %s$.') % (self.lX[0], self.lX[-1], extr[0][1], extr[1][1]))
900        exo.append(_(u'\\item Sur $[%s~;~%s],\\quad %s \\le f\\,(x) \\le %s$.') % (decimaux(self.comparaison[1][0][0], 1), decimaux(self.comparaison[1][1][0], 1), decimaux(self.comparaison[1][2][0], 1), decimaux(self.comparaison[1][2][1], 1)))
901        exo.append(r'\end{enumerate}')
902        exo.append(r'\end{enumerate}')
903
904        return exo
Note: See TracBrowser for help on using the repository browser.