source: pyromaths/trunk/fuentes/src/pyromaths/ex/lycee/ExoPolynome.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: 50.3 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
24from random import randrange
25from pyromaths.classes.Polynome import Polynome, TeX, RacineDegre2
26from pyromaths.classes.Racine import simplifie_racine
27from pyromaths.outils.Priorites3 import priorites
28from pyromaths.outils.Polynomes import poly_racines_entieres, poly_racines_fractionnaires, poly_racines_quelconques, poly_id_remarquables, poly_degre3_racines_entieres, TeX_division, poly_degre3_racines_fractionnaires, randint
29# from pyromaths.outils.decimaux import decimaux
30from pyromaths.outils.Affichage import pTeX, radicalTeX, fTeX
31from pyromaths.outils.Arithmetique import pgcd
32from math import sqrt
33
34
35
36def exo_racines_degre2():
37    '''exercice recherche de racines second degré'''
38
39    exo = ["\\exercice"]
40    cor = ["\\exercice*"]
41    # intervalle pour les racines entières ou fractionnaire
42    rac_min = -10
43    rac_max = 10
44    # denominateur maximmum pour les racines fractionnaires
45    denom_max = 12
46    # Valeurs absolues maximales des coefficients d'un polynôme quelconque
47    abs_a = 1
48    abs_b = 10
49    abs_c = 10
50    # X est le polynome P=x pour faciliter la construction des polynômes,
51    inconnues = ['x', 'y', 'z', 't']
52#     nom_poly = ['P', 'Q', 'R', 'S']
53
54    exo.append(_(u"Résoudre les équations suivantes :"))
55    cor.append(_(u"Résoudre les équations suivantes :"))
56    exo.append("\\begin{enumerate}")
57    cor.append("\\begin{enumerate}")
58
59
60    # Racines entières
61    nomP = 'P'
62    var = inconnues[randrange(4)]
63    X = Polynome({1:1}, var)
64    P = poly_racines_entieres(rac_min, rac_max, X)
65
66    exo.append("\\item $%s=0$\\par" % (P(var)))
67    cor.append("\\item $%s=0$\\par" % (P(var)))
68    cor = redaction_racines(P, nomP, var, cor)
69
70    # Racines fractionnaires
71    nomP = 'P'
72    var = inconnues[randrange(4)]
73    X = Polynome({1:1}, var)
74    P = poly_racines_fractionnaires(rac_min, rac_max, denom_max, X)
75
76    exo.append("\\item $%s=0$\\par" % (P(var)))
77    cor.append("\\item $%s=0$\\par" % (P(var)))
78    cor = redaction_racines(P, nomP, var, cor)
79
80    # Racines quelconques
81    nomP = 'P'
82    var = inconnues[randrange(4)]
83    X = Polynome({1:1}, var)
84    P = poly_racines_quelconques(abs_a, abs_b, abs_c, X)
85
86    exo.append("\\item $%s=0$\\par" % (P(var)))
87    cor.append("\\item $%s=0$\\par" % (P(var)))
88    redaction_racines(P, nomP, var, cor)
89
90    exo.append("\\end{enumerate}")
91    cor.append("\\end{enumerate}")
92    return exo, cor
93
94exo_racines_degre2.description = _(u'Équations 2° degré')
95exo_racines_degre2.level = _(u'1.1èreS')
96
97
98def exo_factorisation_degre2():
99    '''exercice recherche de racines second degré'''
100
101    exo = ["\\exercice"]
102    cor = ["\\exercice*"]
103    # intervalle pour les racines entières ou fractionnaire
104    rac_min = -10
105    rac_max = 10
106
107    # X est le polynome P(x)=x pour faciliter la construction des polynômes,
108    inconnues = ['x', 'y', 'z', 't']
109    nom_poly = ['P', 'Q', 'R', 'S']
110
111    exo.append(_(u"Factoriser les polynômes suivants :"))
112    # cor=[]u"Factoriser les polynômes suivants :"]
113    exo.append("\\begin{enumerate}")
114    cor.append("\\begin{enumerate}")
115
116####identites remarquables
117
118    nomP = nom_poly[randrange(4)]
119    var = inconnues[randrange(4)]
120    X = Polynome({1:1}, var)
121    P, sgns = poly_id_remarquables(rac_min, rac_max, X)  # sgns=-2,0 ou 2
122    exo.append(_(u"\\item Factoriser  $%s(%s)=%s$ à l'aide d'une identité remarquable.") % (nomP, var, P(var)))
123    cor.append(_("\\item Factoriser $%s(%s)=%s$") % (nomP, var, P(var)))
124
125    factorisation, dummy = factorise_identites_remarquables(P, sgns, var, racines=True)
126
127    factorise = "$$%s" % P
128    for i in range(len(factorisation)):
129        factorise += "=" + factorisation[i]
130    cor.append(factorise + "$$")
131
132####Racines entières
133    nomP = nom_poly[randrange(4)]
134    var = inconnues[randrange(4)]
135    X = Polynome({1:1}, var)
136    P = poly_racines_entieres(rac_min, rac_max, X)
137
138    exo.append("\\item $%s(%s)=%s$" % (nomP, var, P(var)))
139    cor.append(_("\\item Factoriser $%s(%s)=%s$\\par") % (nomP, var, P(var)))
140    exo, cor = redaction_factorisation(P, nomP, exo, cor)
141
142####Racines fractionnaires
143    nomP = nom_poly[randrange(4)]
144    var = inconnues[randrange(4)]
145    X = Polynome({1:1}, var)
146    # denominateur maximmum pour les racines fractionnaires
147    denom_max = 12
148    P = poly_racines_fractionnaires(rac_min, rac_max, denom_max, X)
149
150    exo.append("\\item $%s(%s)=%s$" % (nomP, var, P(var)))
151    cor.append(_("\\item Factoriser $%s(%s)=%s$\\par") % (nomP, var, P(var)))
152    exo, cor = redaction_factorisation(P, nomP, exo, cor)
153
154
155####Racines quelconques
156    nomP = nom_poly[randrange(4)]
157    var = inconnues[randrange(4)]
158    X = Polynome({1:1}, var)
159    # Valeurs absolues maximales des coefficients d'un polynôme quelconque
160    abs_a = 1
161    abs_b = 10
162    abs_c = 10
163    P = poly_racines_quelconques(abs_a, abs_b, abs_c, X)
164
165    exo.append("\\item $%s(%s)=%s$" % (nomP, var, P(var)))
166    cor.append(_("\\item Factoriser $%s(%s)=%s$\\par") % (nomP, var, P(var)))
167    exo, cor = redaction_factorisation(P, nomP, exo, cor)
168
169    exo.append("\\end{enumerate}")
170    cor.append("\\end{enumerate}")
171    return exo, cor
172
173exo_factorisation_degre2.description = _(u'Factorisations 2° degré')
174exo_factorisation_degre2.level = _(u'1.1èreS')
175
176
177def exo_factorisation_degre3():
178    '''exercice de factorisation degre3'''
179
180    # intervalle pour les racines entières ou fractionnaire
181    rac_min = -10
182    rac_max = 10
183    # denominateur maximmum pour les racines fractionnaires
184    denom1 = 12
185    # Valeurs absolues maximales des coefficients d'un polynôme quelconque
186#     abs_a = 1
187#     abs_b = 10
188#     abs_c = 10
189    # X est le polynome P=x pour faciliter la construction des polynômes, TODO : changer  l'inconnue
190#     inconnues = ['x', 'y', 'z', 't']
191#     nom_poly = ['P', 'Q', 'R', 'S']
192    exo = ["\\exercice",
193        "\\begin{enumerate}"]
194    cor = ["\\exercice*",
195         "\\begin{enumerate}"]
196
197    X = Polynome({1:1}, var="x")
198    racines_quelconques = [i for i in range(-10, 11)]
199    E = poly_degre3_racines_entieres(rac_min, rac_max, X, racines=racines_quelconques)
200    exo, cor = factorisation_degre3(E, "E", exo, cor, racines=racines_quelconques)
201    F = poly_degre3_racines_fractionnaires(rac_min, rac_max, denom1, X)
202    exo, cor = factorisation_degre3(F, "F", exo, cor)
203
204    exo.append("\\end{enumerate}")
205    cor.append("\\end{enumerate}")
206    return exo, cor
207
208exo_factorisation_degre3.description = _(u'Factorisations degré 3')
209exo_factorisation_degre3.level = _(u'1.1èreS')
210
211
212def exo_tableau_de_signe():
213    # intervalle pour les racines entières ou fractionnaire
214    rac_min = -10
215    rac_max = 10
216    # denominateur maximmum pour les racines fractionnaires
217    denom1 = 12
218    # Valeurs absolues maximales des coefficients d'un polynôme quelconque
219    abs_a = 1
220    abs_b = 10
221    abs_c = 10
222    # X est le polynome P=x pour faciliter la construction des polynômes, TODO : changer  l'inconnue
223#     inconnues = ['x', 'y', 'z', 't']
224#     nom_poly = ['P', 'Q', 'R', 'S']
225    borneinf = -5  # float("-inf")
226    bornesup = 5  # float("inf")
227    var = "x"
228    X = Polynome({1:1}, var=var)
229    Poly = [poly_racines_entieres(rac_min, rac_max, X),
230          poly_racines_fractionnaires(rac_min, rac_max, denom1, X),
231          poly_racines_quelconques(abs_a, abs_b, abs_c, X)]
232    intervalles = [[0, 5], [-5, 5], [float("-inf"), float("inf")]]
233    exo = ["\\exercice",
234        "\\begin{enumerate}"]
235    cor = ["\\exercice*",
236         "\\begin{enumerate}"]
237    nomP = "P"
238    for i in range(len(Poly)):
239        P = Poly[i]
240        borneinf, bornesup = intervalles[i]
241        if borneinf == float("-inf") and bornesup == float("inf"):
242            TeXintervalle = "\\mathbb R"
243        else:
244            if borneinf != float("-inf"):
245                TeXintervalle = "["
246            else:
247                TeXintervalle = "]"
248            TeXintervalle += "%s~;~%s" % (TeX(borneinf), TeX(bornesup))
249            if bornesup == float("inf"):
250                TeXintervalle += "["
251            else:
252                TeXintervalle += "]"
253        exo.append(_(u"\\item Étudier le signe du polynôme $%s=%s$ sur $I=%s$.") % (nomP, P, TeXintervalle))
254        cor.append(_(u"\\item Étudier le signe du polynôme $%s=%s$ sur $I=%s$.\\par") % (nomP, P, TeXintervalle))
255
256        delta, dummy, racines, dummy, dummy = factorisation_degre2(P, factorisation=False)
257        redaction_racines(P, nomP, var, cor)
258        tableau_de_signe(P, nomP, delta, racines, cor, borneinf, bornesup, detail=False)
259    exo.append("\\end{enumerate}")
260    cor.append("\\end{enumerate}")
261    return exo, cor
262
263exo_tableau_de_signe.description = _(u'Étude de signe')
264exo_tableau_de_signe.level = _(u'1.1èreS')
265
266
267def exo_variation():
268
269    exo = ["\\exercice",
270         "\\begin{enumerate}"]
271    cor = ["\\exercice*",
272         "\\begin{enumerate}"]
273    quest1, cor1 = quest_fonctions_rationnelles()
274    quest2, cor2 = quest_variation_degre3(borneinf=-10, bornesup=10)
275
276    exo += quest1 + quest2
277    cor += cor1 + cor2
278
279    exo.append("\\end{enumerate}")
280    cor.append("\\end{enumerate}")
281    return exo, cor
282
283exo_variation.description = _(u"Sens de variations")
284exo_variation.level = [_(u"1.1èreS"), _(u"0.Term STG")]
285
286
287def exo_variation_lim():
288    """Étude de fonctions avec calculs de limites"""
289    exo = ["\\exercice",
290         "\\begin{enumerate}"]
291    cor = ["\\exercice*",
292         "\\begin{enumerate}"]
293    quest3, cor3 = quest_variation_degre3(borneinf=float("-inf"), bornesup=float("+inf"))
294    quest4, cor4 = quest_fonctions_rationnelles_sur_R()
295    exo += quest3 + quest4
296    cor += cor3 + cor4
297
298    exo.append("\\end{enumerate}")
299    cor.append("\\end{enumerate}")
300    return exo, cor
301
302exo_variation_lim.description = _(u"Étude de fonctions")
303exo_variation_lim.level = _(u"0.Term S")
304
305def quest_fonctions_rationnelles():
306    from pyromaths.classes.Fractions import Fraction
307    from pyromaths.outils import Priorites3
308
309    nomf = ['f', 'g', 'h', 'k'][randrange(4)]
310    var = ['t', 'x'][randrange(2)]
311    X = Polynome({1:1}, var)
312    # intervalle pour les racines entières ou fractionnaire
313
314    rac_min = -9
315    rac_max = 9
316    b1 = b2 = a1 = a2 = 0
317    while b1 == 0 or b2 == 0 or a1 == 0 or a2 == 0:
318        b1 = randint(rac_min, rac_max)
319        b2 = randint(rac_min, rac_max)
320        a1 = randint(-5, 5)
321        a2 = randint(-5, 5)
322    P = a1 * X + b1
323    Q = a2 * X + b2
324
325    borneinf = -10
326    bornesup = 10
327    racine = eval(Priorites3.priorites("-%r/%r" % (Q[0], Q[1]))[-1][0])
328    # Je veux que f soit définie et dérivable sur I=Intervalle
329    if (racine >= borneinf) and (racine <= bornesup):
330        if (racine - borneinf) < (bornesup - racine):
331            Intervalle = [int(round(racine)) + 1, bornesup]
332        else:
333            Intervalle = [borneinf, int(round(racine)) - 1]
334    else:
335        Intervalle = [borneinf, bornesup]
336
337    # dérivée
338    numerateur = "%s\\times%s-%s\\times%s" % (P.derive().TeX(parenthese=True), Q.TeX(parenthese=True),
339                                          P.TeX(parenthese=True), Q.derive().TeX(parenthese=True))
340    numerateur_simplifie = (P.derive() * Q - P * Q.derive()).simplifie()
341    denominateur = u"%s^2" % (Q.TeX(parenthese=True))
342    f_derivee = "\\dfrac{%s}{%s}" % (numerateur, denominateur)
343    f_derivee_simplifiee = "\\dfrac{%s}{%s}" % (numerateur_simplifie, denominateur)
344    VI = eval(priorites('-%r*Fraction(1)/%r' % (Q[0], Q[1]))[-1][0])
345    if isinstance(VI, (Fraction, RacineDegre2)): VI = VI.simplifie()
346    exo = [_(u"\\item On considère la fonction $%s$ définie sur $I=[%s~;~%s]$ par $%s(%s)=\dfrac{%s}{%s}$.") % (nomf, Intervalle[0], Intervalle[1], nomf, var, P, Q),
347         "\\begin{enumerate}"]
348    cor = [_(u"\\item On considère la fonction $%s$ définie sur $I=[%s~;~%s]$ par $%s(%s)=\dfrac{%s}{%s}$.") % (nomf, Intervalle[0], Intervalle[1], nomf, var, P, Q),
349         "\\begin{enumerate}"]
350
351    exo.append(_(u"\\item Justifier que $%s$ est définie et dérivable sur $I$.") % (nomf))
352    cor.append(_(u"\\item Justifier que $%s$ est définie et dérivable sur $I$.") % (nomf))
353    cor.append(_(u" Pour déterminer la valeur interdite, on doit résoudre $%s=0$.") % (Q(var)))
354    cor.append("\\begin{align*}")
355    cor.append("%s&=0\\\\" % Q)
356    cor.append("%s&=%s" % ((Q - Q[0]), TeX(-Q[0])))
357    cor.append("\\\\")
358    if Q[1] != 1:
359        x0 = eval(priorites('-%r*Fraction(1)/%r' % (Q[0], Q[1]))[-1][0])
360        if isinstance(x0, (Fraction, RacineDegre2)):
361            x1 = x0.simplifie()
362        else:
363            x1 = x0
364        cor.append("%s&=%s" % (var, Fraction(-Q[0], Q[1])))
365        cor.append("\\\\")
366        if isinstance(x0, (Fraction, RacineDegre2)) and (not isinstance(x1, (Fraction, RacineDegre2)) or x0.d != x1.d):
367            cor.append("%s&=%s" % (var, TeX(x1)))
368            cor.append("\\\\")
369    cor.pop(-1)
370    cor.append("\\end{align*}")
371    cor.append(_(u"Or $%s$ n'est pas dans l'intervalle $[%s~;~%s]$ et comme $%s$ est un quotient de polynômes, alors $%s$ est définie et dérivable sur $I$.") % \
372               (TeX(VI), Intervalle[0], Intervalle[1], nomf, nomf))
373    exo.append(_(u"\\item Déterminer $%s'(%s)$ pour tout $%s\in[%s~;~%s]$.") % \
374          (nomf, var, var, Intervalle[0], Intervalle[1]))
375    cor.append(_(u"\\item Déterminer $%s'(%s)$ pour tout $%s\in[%s~;~%s]$.") % \
376          (nomf, var, var, Intervalle[0], Intervalle[1]))
377    cor.append(u"$$%s'(%s)=%s=%s$$" % (nomf, var, f_derivee, f_derivee_simplifiee))
378    exo.append(_(u"\\item En déduire le sens de variations de $%s$ sur $I$.") % (nomf))
379    cor.append(_(u"\\item En déduire le sens de variations de $%s$ sur $I$.\\par") % (nomf))
380    if numerateur_simplifie.degre_max == 0:
381        cor.append(_(u" Comme $%s$ est un carré, il est toujours positif.\\\\") % (denominateur))
382        f_xmin = eval(priorites('%r*Fraction(1)/%r' % (P(Intervalle[0]), Q(Intervalle[0])))[-1][0])
383        f_xmax = eval(priorites('%r*Fraction(1)/%r' % (P(Intervalle[1]), Q(Intervalle[1])))[-1][0])
384        if isinstance(f_xmin, (Fraction, RacineDegre2)): f_xmin = f_xmin.simplifie()
385        if isinstance(f_xmax, (Fraction, RacineDegre2)): f_xmax = f_xmax.simplifie()
386        f_xmin = TeX(f_xmin)
387        f_xmax = TeX(f_xmax)
388        if numerateur_simplifie[0] < 0:
389            cor.append(_(u" De plus, $%s<0$ donc pour tout $%s$ de $I$, $%s'(%s)<0$. Ainsi, on obtient \\par") % \
390                  (numerateur_simplifie[0], var, nomf, var))
391            cor.append("\\begin{tikzpicture}\n\\tkzTabInit[espcl=2.5]")
392            cor.append("{$%s$ /1, $%s'\\,(x)$/1, $%s\\,(x)$/1.5}" % (var, nomf, nomf))
393            cor.append("{$%s$,$%s$}" % (TeX(Intervalle[0]), TeX(Intervalle[1])))
394            cor.append("\\tkzTabLine{,-,}")
395            cor.append("\\tkzTabVar{+/$%s$/, -/$%s$/}" % (f_xmin, f_xmax))
396            cor.append(r'\end{tikzpicture}\par')
397            #===================================================================
398            # cor.append("$$\\tabvar{")
399            # cor.append("\\tx{%s}&\\tx{%s}&&\\tx{%s}\\cr" % (var, TeX(Intervalle[0]), TeX(Intervalle[1])))
400            # cor.append("\\tx{%s'(%s)}&&\\tx{-}&&\\cr" % (nomf, var))
401            # cor.append("\\tx{%s}&\\txh{%s}&\\fd&\\txb{%s}\\cr" % (nomf, f_xmin, f_xmax))
402            # cor.append("}$$")
403            #===================================================================
404        else:
405            cor.append(_(u" De plus, $%s>0$ donc pour tout $%s$ de $I$, $%s'(%s)>0$.\\par") % \
406                  (numerateur_simplifie[0], var, nomf, var))
407            cor.append("\\begin{tikzpicture}\n\\tkzTabInit[espcl=2.5]")
408            cor.append("{$%s$ /1, $%s'\\,(x)$/1, $%s\\,(x)$/1.5}" % (var, nomf, nomf))
409            cor.append("{$%s$,$%s$}" % (TeX(Intervalle[0]), TeX(Intervalle[1])))
410            cor.append("\\tkzTabLine{,+,}")
411            cor.append("\\tkzTabVar{-/$%s$/, +/$%s$/}" % (f_xmin, f_xmax))
412            cor.append(r'\end{tikzpicture}\par')
413            #===================================================================
414            # cor.append("$$\\tabvar{")
415            # cor.append("\\tx{%s}&\\tx{%s}&&\\tx{%s}\\cr" % (var, TeX(Intervalle[0]), TeX(Intervalle[1])))
416            # cor.append("\\tx{%s'(%s)}&&\\tx{+}&&\\cr" % (nomf, var))
417            # cor.append("\\tx{%s}&\\txb{%s}&\\fm&\\txh{%s}\\cr" % (nomf, f_xmin, f_xmax))
418            # cor.append("}$$")
419            #===================================================================
420    else:
421        cor.append(_(u" Je ne sais pas faire avec un tel numérateur $%s$.") % (numerateur_simplifie))
422    exo.append("\\end{enumerate}")
423    cor.append("\\end{enumerate}")
424    return exo, cor
425
426def quest_fonctions_rationnelles_sur_R():
427    from pyromaths.classes.Fractions import Fraction
428
429    nomf = ['f', 'g', 'h', 'k'][randrange(4)]
430    var = ['t', 'x'][randrange(2)]
431    X = Polynome({1:1}, var)
432    # intervalle pour les racines entières ou fractionnaire
433
434    rac_min = -9
435    rac_max = 9
436    b1 = b2 = a1 = a2 = 0
437    while b1 == 0 or b2 == 0 or a1 == 0 or a2 == 0 or a1 * (-float(b2) / a1) + b1 == 0 or (a1 * b2 / a2 - b1) == 0:
438        # (a1*b2/a2 - b1)==0 on teste que la racine de Q n'annule pas P donc on ne peut pas simplifier
439        b1 = randint(rac_min, rac_max)
440        b2 = randint(rac_min, rac_max)
441        a1 = randint(-5, 5)
442        a2 = randint(-5, 5)
443    P = a1 * X + b1
444    Q = a2 * X + b2
445
446    borneinf = float("-inf")
447    bornesup = float("+inf")
448    Intervalle = [borneinf, bornesup]
449#     TeXintervalle = "\\mathbb R"
450
451    # dérivée
452    numerateur = "%s\\times%s-%s\\times%s" % (P.derive().TeX(parenthese=True), Q.TeX(parenthese=True),
453                                          P.TeX(parenthese=True), Q.derive().TeX(parenthese=True))
454    numerateur_simplifie = (P.derive() * Q - P * Q.derive()).simplifie()
455    # VI = (-Q[0] * Fraction(1) / Q[1]).simplifie()
456    #===========================================================================
457    # print "A simplifier : ", priorites('-%r*Fraction(1)/%r' % (Q[0], Q[1]))[-1][0]
458    #===========================================================================
459    VI = eval(priorites('-%r*Fraction(1)/%r' % (Q[0], Q[1]))[-1][0])
460    if isinstance(VI, (Fraction, RacineDegre2)): VI.simplifie()
461    denominateur = u"%s^2" % (Q.TeX(parenthese=True))
462    f_derivee = "\\dfrac{%s}{%s}" % (numerateur, denominateur)
463    f_derivee_simplifiee = "\\dfrac{%s}{%s}" % (numerateur_simplifie, denominateur)
464
465    exo = [_(u"\\item On considère la fonction $%s$ définie  par $%s(%s)=\\dfrac{%s}{%s}$.") % (nomf, nomf, var, P, Q),
466         "\\begin{enumerate}"]
467    cor = [_(u"\\item On considère la fonction $%s$ définie  par $%s(%s)=\\dfrac{%s}{%s}$.") % (nomf, nomf, var, P, Q),
468         "\\begin{enumerate}"]
469
470    exo.append(_(u"\\item Déterminer l'ensemble de définition $\\mathcal{D}_{%s}$ de $%s$.") % (nomf, nomf))
471    cor.append(_(u"\\item Déterminer l'ensemble de définition $\\mathcal{D}_{%s}$ de $%s$.\par") % (nomf, nomf))
472    cor.append(_(u" La fonction rationnelle $%s$ est définie et dérivable en $%s$ si $%s\\neq0$.") % (nomf, var, Q(var)))
473    cor.append("\\begin{align*}\n\
474            %s&=0\\\\\n\
475            %s&=%s\\\\\n\
476            %s&=%s\\\\\n\
477            %s&=%s\n\
478            \\end{align*}" % (Q, (Q - Q[0]), TeX(-Q[0]), var, TeX(-Q[0] * Fraction(1) / Q[1]), var, TeX(VI)))
479    cor.append(_(u"On en déduit que $\\mathcal{D}_{%s}=\\mathcal{D'}_{%s}=]-\\infty~;~%s[\cup]%s~;~+\\infty[$.") % \
480          (nomf, nomf, TeX(VI), TeX(VI)))
481    exo.append(_(u"\\item Déterminer $%s'(%s)$ pour tout $%s\in\\mathcal{D'}_{%s}$.") % \
482          (nomf, var, var, nomf))
483    cor.append(_(u"\\item Déterminer $%s'(%s)$ pour tout $%s\in\\mathcal{D'}_{%s}$.") % \
484          (nomf, var, var, nomf))
485    cor.append(u"$$%s'(%s)=%s=%s$$" % (nomf, var, f_derivee, f_derivee_simplifiee))
486    exo.append(_(u"\\item Déterminer les limites de $%s$ aux bornes de $\\mathcal{D}_{%s}$.") % (nomf, nomf))
487    cor.append(_(u"\\item Déterminer les limites de $%s$ aux bornes de $\\mathcal{D}_{%s}$.") % (nomf, nomf))
488    #===========================================================================
489    # limite = P[1] / Q[1]
490    #===========================================================================
491    limite = eval(priorites('-%r*Fraction(1)/%r' % (P[1], Q[1]))[-1][0])
492    if isinstance(limite, (Fraction, RacineDegre2)):
493        limite_simple = limite.simplifie()
494    else:
495        limite_simple = limite
496
497    cor.append("$$\\lim_{%s\\to -\\infty}\\dfrac{%s}{%s}= " % (var, P, Q))
498
499    cor.append("\\lim_{%s\\to -\\infty}\\dfrac{%s%s}{%s%s} = %s" % (var, coeffTeX(P[1]), var, coeffTeX(Q[1]), var, limite))
500    if isinstance(limite, (int, float)) or (isinstance(limite_simple, (Fraction, RacineDegre2)) and limite.n == limite_simple.n):
501        cor.append("$$")
502    else:
503        cor.append("= %s $$" % (TeX(limite_simple)))
504    cor.append("$$\\lim_{%s\\to +\\infty}\\dfrac{%s}{%s}= " % (var, P, Q))
505    cor.append("\\lim_{%s\\to +\\infty}\\dfrac{%s%s}{%s%s} = %s" % (var, coeffTeX(P[1]), var, coeffTeX(Q[1]), var, limite))
506    if isinstance(limite, (int, float)) or (isinstance(limite_simple, (Fraction, RacineDegre2)) and limite.n == limite_simple.n):
507        cor.append("$$")
508    else:
509        cor.append("= %s $$" % (TeX(limite_simple)))
510    cor.append("Pour $%s=%s$, on a $%s=%s" % (var, TeX(VI), P, TeX(P(VI))))
511    if P(VI) < 0:
512        limites = ["-\\infty", "+\\infty"]
513        cor.append("<0$.\\\\")
514    elif P(VI) > 0:
515        limites = ["+\\infty", "-\\infty"]
516        cor.append(">0$.\\\\")
517    else:cor.append("$.\\\\")
518        # Impossible car on test (a1*b2/a2 - b1)!=0
519
520    VIplus = "\\substack{%s\\to %s\\\\%s>%s}" % (var, fTeX(VI), var, fTeX(VI))
521    VImoins = "\\substack{%s\\to %s\\\\%s<%s}" % (var, fTeX(VI), var, fTeX(VI))
522    if Q[1] < 0:
523        cor.append(_("De plus, $%s>0$ si $%s<%s$") % (Q, var, TeX(VI)))
524        cor.append(_("et  $%s<0$ si $%s>%s$.\\\\") % (Q, var, TeX(VI)))
525    else:
526        cor.append(_("De plus, $%s<0$ si $%s<%s$") % (Q, var, TeX(VI)))
527        cor.append(_("et  $%s>0$ si $%s>%s$.\\\\") % (Q, var, TeX(VI)))
528
529    cor.append(u"$$\\lim_{%s}\\dfrac{%s}{%s}=%s $$" % (VImoins, P, Q, limites[0]))
530    cor.append(u"$$\\lim_{%s}\\dfrac{%s}{%s}=%s $$" % (VIplus, P, Q, limites[1]))
531
532
533
534    exo.append(_(u"\\item Dresser le tableau de variations de $%s$ sur $\\mathcal{D}_{%s}$.") % (nomf, nomf))
535    cor.append(_(u"\\item Dresser le tableau de variations de $%s$ sur $\\mathcal{D}_{%s}$.\\par") % (nomf, nomf))
536    if numerateur_simplifie.degre_max == 0:
537        cor.append(_(u" Comme $%s$ est un carré, il est toujours positif.\\\\") % (denominateur))
538        f_xmin = eval(priorites('-%r*Fraction(1)/%r' % (P[1], Q[1]))[-1][0])
539        if isinstance(f_xmin, (Fraction, RacineDegre2)):
540            f_xmin = f_xmin.simplifie()
541        f_xmax = f_xmin
542        if numerateur_simplifie[0] < 0:
543            cor.append(_(u" De plus, $%s<0$ donc pour tout $%s$ de $I$, $%s'(%s)<0$. Ainsi, on obtient \\par") % \
544                  (numerateur_simplifie[0], var, nomf, var))
545            cor.append("\\begin{tikzpicture}\n\\tkzTabInit[espcl=2.5]")
546            cor.append("{$%s$ /1, $%s'\\,(x)$/1, $%s\\,(x)$/1.5}" % (var, nomf, nomf))
547            cor.append("{$%s$,$%s$,$%s$}" % (TeX(Intervalle[0]), TeX(VI), TeX(Intervalle[1])))
548            cor.append("\\tkzTabLine{,-,d,-}")
549            cor.append("\\tkzTabVar{+/$%s$ / ,-D+/ $-\\infty$ /$+\infty$, -/$%s$/}" % (f_xmin, f_xmax))
550            cor.append(r'\end{tikzpicture}\par')
551            #===================================================================
552            # cor.append("$$\\tabvar{")
553            # cor.append("\\tx{%s}&\\tx{%s}&&&\\tx{%s}&&&\\tx{%s}\\cr" % (var, TeX(Intervalle[0]), TeX(VI), TeX(Intervalle[1])))
554            # cor.append("\\tx{%s'(%s)}&&\\tx{-}&&\\dbt &&\\tx{-}&\\cr" % (nomf, var))
555            # cor.append("\\tx{%s}&\\txh{%s}&\\fd&\\txb{-\\infty}&\\dbt&\\txh{+\\infty}&\\fd&\\txb{%s}\\cr" % (nomf, f_xmin, f_xmax))
556            # cor.append("}$$")
557            #===================================================================
558        else:
559            cor.append(_(u" De plus, $%s>0$ donc pour tout $%s$ de $I$, $%s'(%s)>0$. \\par") % \
560                  (numerateur_simplifie[0], var, nomf, var))
561            cor.append("\\begin{tikzpicture}\n\\tkzTabInit[espcl=2.5]")
562            cor.append("{$%s$ /1, $%s'\\,(x)$/1, $%s\\,(x)$/1.5}" % (var, nomf, nomf))
563            cor.append("{$%s$,$%s$,$%s$}" % (TeX(Intervalle[0]), TeX(VI), TeX(Intervalle[1])))
564            cor.append("\\tkzTabLine{,+,d,+}")
565            cor.append("\\tkzTabVar{-/$-\\infty$ / ,+D-/ $%s$ /$%s$, +/$+\\infty$/}" % (f_xmin, f_xmax))
566            cor.append(r'\end{tikzpicture}\par')
567            #===================================================================
568            # cor.append("$$\\tabvar{")
569            # cor.append("\\tx{%s}&\\tx{%s}&&&\\tx{%s}&&&\\tx{%s}\\cr" % (var, TeX(Intervalle[0]), TeX(VI), TeX(Intervalle[1])))
570            # cor.append("\\tx{%s'(%s)}&&\\tx{+}&&\\dbt&&\\tx{+}&\\cr" % (nomf, var))
571            # cor.append("\\tx{%s}&\\txb{%s}&\\fm&\\txh{+\\infty}&\\dbt&\\txb{-\\infty}&\\fm&\\txh{%s}\\cr" % (nomf, f_xmin, f_xmax))
572            # cor.append("}$$")
573            #===================================================================
574    else:
575        cor.append(_(u" Je ne sais pas faire avec un tel numérateur $%s$.") % (numerateur_simplifie))
576    exo.append("\\end{enumerate}")
577    cor.append("\\end{enumerate}")
578    return exo, cor
579
580def coeffTeX(a):
581        if a == 1:return ""
582        if a == -1:return "-"
583        return a
584
585def quest_variation_degre3(borneinf=float("-inf"), bornesup=float("+inf")):
586    '''Question qui propose l'étude du sens de variation d'un polynôme de degré 3'''
587#     Intervalle = [borneinf, bornesup]
588    if borneinf == float("-inf") and bornesup == float("+inf"):
589        TeX_intervalle = "\\mathbb R"
590    else:
591        TeX_intervalle = "\\left[%s~;~%s\\right]" % (TeX(borneinf), TeX(bornesup))
592    # intervalle pour les racines entières ou fractionnaire
593    a = 3 * randint(1, 3)
594    rac_min = -9
595    rac_max = 9
596    # denominateur maximmum pour les racines fractionnaires
597#     denom_max = denom1 = 12
598    # Valeurs absolues maximales des coefficients d'un polynôme quelconque
599#     abs_a = 6
600#     abs_b = 10
601    abs_c = 10
602    # X est le polynome P=x pour faciliter la construction des polynômes,
603#     inconnues = ['x', 'y', 'z', 't']
604#     nom_poly = ['P', 'Q', 'R', 'S']
605    var = "x"
606    X = Polynome({1:1}, var=var)
607    nomP = ["f", "g", "h", "k", "p", "q"][randrange(6)]
608    Pprime = poly_racines_entieres(rac_min, rac_max, X, a1=a)
609    P = Pprime.primitive() + randint(-abs_c, abs_c)
610    P = P.simplifie()
611    exo = [_(u"\\item Étudier le sens de variations de $%s$ définie par $%s(x)=%s$ sur $%s$.") % (nomP, nomP, P(var), TeX_intervalle)]
612    cor = [_(u"\\item Étudier le sens de variations de $%s$ définie par $%s(x)=%s$ sur $%s$.") % (nomP, nomP, P(var), TeX_intervalle)]
613
614    cor.append("\\par $%s'(x)=%s$\\\\" % (nomP, Pprime(var)))
615    cor.append(_(u"Je dois étudier le signe de $%s'(%s)$ qui est un polynôme du second degré.\\par") % (nomP, var))
616
617    delta, simplrac, racines, str_racines, factorisation = factorisation_degre2(Pprime, factorisation=False)
618    # cor=redaction_factorisation(Pprime,nomP+"'",exo=[],cor=cor)[1]
619    # cor.pop(-5)
620    redaction_racines(Pprime, nomP + "'", var, cor)
621    str_variables, str_signes, str_valeurs, signes, ligne_valeurs = tableau_de_signe(Pprime, nomP + "'", delta, racines, cor, borneinf, bornesup, detail=True)
622
623    # cor.append(tab_signe)
624
625
626    if (delta <= 0 and P[3] < 0):
627        cor += _(u"Donc la fonction polynômiale $%s$ est décroissante sur $%s$.") % (nomP, TeX_intervalle)
628    elif (delta <= 0 and P[3] > 0):
629        cor.append(_(u"Donc la fonction polynômiale $%s$ est croissante sur $%s$.") % (nomP, TeX_intervalle))
630    else:
631        cor.append(_("On obtient ainsi le tableau de variation de $%s$.\\par") % nomP)
632#         [x1, x2] = racines
633        # macro=[["txb","txh"],["fm","fd"]]
634        cor.append("\\begin{tikzpicture}\n\\tkzTabInit[espcl=2.5]")
635        cor.append(str_variables[:-1] + ', $%s\\,(x)$/1.5}' % nomP)
636        cor.append(str_valeurs)
637        cor.append(str_signes)
638        var_de_P = "\\tkzTabVar{%s/$%s$, " % (["-", "+"]["-" == signes[0]], TeX(P(ligne_valeurs[0])))  # +/$%s$/, -/$%s$/}" % (f_xmin, f_xmax))
639        #=======================================================================
640        # var_de_P = "\\tx{%s}& \\%s{\\rnode{neu0}{%s}}&&" % (nomP, ["txb", "txh"]["-" == signes[0]], TeX(P(ligne_valeurs[0])))
641        #=======================================================================
642        compteur = 0
643        for i in range(0, len(signes) - 1):
644            if signes[i] == '+':
645                if 0 and signes[i + 1] == "+":
646                    var_de_P += "&&"
647                else:
648                    compteur += 1
649                    var_de_P += "+/$%s$/, " % TeX(P(ligne_valeurs[i + 1]))
650                    #===========================================================
651                    # var_de_P += "\\txh{\\rnode{neu%s}{%s}}&&" % (compteur, TeX(P(ligne_valeurs[i + 1])))
652                    #===========================================================
653            else:
654                if 0 and signes[i + 1] == "-":
655                    var_de_P += "&&"
656                else:
657                    compteur += 1
658                    var_de_P += "-/$%s$/, " % TeX(P(ligne_valeurs[i + 1]))
659                    #===========================================================
660                    # var_de_P += "\\txb{\\rnode{neu%s}{%s}}&&" % (compteur, TeX(P(ligne_valeurs[i + 1])))
661                    #===========================================================
662        compteur += 1
663        if signes[-1] == "+":
664            var_de_P += "+/$%s$/} " % TeX(P(ligne_valeurs[-1]))
665            #===================================================================
666            # var_de_P += "\\txh{\\rnode{neu%s}{%s}}\\cr" % (compteur, TeX(P(ligne_valeurs[-1])))
667            #===================================================================
668        else:
669            var_de_P += "-/$%s$/} " % TeX(P(ligne_valeurs[-1]))
670            #===================================================================
671            # var_de_P += "\\txb{\\rnode{neu%s}{%s}}\\cr" % (compteur, TeX(P(ligne_valeurs[-1])))
672            #===================================================================
673
674        cor.append(var_de_P)
675        #=======================================================================
676        # cor.append("$$ \\tabvar{\n %s\n %s\n %s}$$" % \
677        #            (str_valeurs, str_signes, var_de_P))
678        #=======================================================================
679        #=======================================================================
680        # for i in range(1, compteur + 1):
681        #     cor.append("\\ncline[nodesep=0.15,linewidth=0.5pt]{->}{neu%s}{neu%s}" % (i - 1, i))
682        #=======================================================================
683        cor.append(r'\end{tikzpicture}\par')
684
685        if borneinf == float("-inf"):
686            cor.append(u"$$\\lim_{%s\\to %s} %s= \\lim_{%s\\to %s} %s%s^3=%s $$  " % (var, "-\\infty", P, var, "-\\infty", P[3], var, TeX(P(float("-inf")))))
687        if bornesup == float("+inf"):
688            cor.append(u"$$\\lim_{%s\\to %s} %s= \\lim_{%s\\to %s} %s%s^3=%s  $$ " % (var, "+\\infty", P, var, "+\\infty", P[3], var, TeX(P(float("inf")))))
689    return exo, cor
690
691
692                ###############################################
693                #                                             #
694                #   Fonctions étudiant les polynômes          #
695                #                                             #
696                ###############################################
697
698def tableau_de_signe(P, nomP, delta, racines, cor, borneinf=float("-inf"), bornesup=float("+inf"), detail=False):
699    '''Étudie le signe d'un polynôme de degré2'''
700    ''' ne fonctionne pas si on a pas borneinf < x1< x2 <bornesup'''
701    '''detail=True permet de récupérer la dernière ligne avec le signe de P'''
702    var = P.var
703    signe_moinsa, signe_a = [('+', '-'), ('-', '+')][P[2] > 0]  # Ca donne bien ce qu'on veut...
704    signes = []
705    str_variables = "{$%s$/1, $%s\\,(x)$/1}" % (var, nomP)
706    if delta < 0:
707        cor.append(_("Comme $\\Delta <0$, $%s(%s)$ ne s'annule pas et est toujours du signe de $a$") % (nomP, var))
708        cor.append(_("Ainsi "))
709        str_valeurs = "{$%s$,$%s$}" % (TeX(borneinf), TeX(bornesup))
710        str_signes = "\\tkzTabLine{,%s}" % signe_a
711        # str_valeurs = "\\tx{%s}&\\tx{%s}&& \\tx{%s}\\cr" % (var, TeX(borneinf), TeX(bornesup))
712        # str_signe = "\\tx{%s(%s)}&&\\tx{%s}&\\cr" % (nomP, var, signe_a)
713        signes = [signe_a]
714        ligne_valeurs = [borneinf, bornesup]
715    elif delta == 0:
716        cor.append(_("Comme $\\Delta =0$, $%s(%s)$ s'annule une seule fois pour $%s_0=%s$ et est toujours du signe de $a$.\\par") % (nomP, var, var, racines[0]))
717        if racines[0] < borneinf or racines[0] > bornesup:
718            if borneinf != float("-inf"):
719                intervalle = "["
720            else:
721                intervalle = "]"
722            intervalle += "%s~;~%s" % (TeX(borneinf), TeX(bornesup))
723            if bornesup == float("inf"):
724                intervalle += "["
725            else:
726                intervalle += "]"
727            cor.append(_("Or $%s$ n'est pas dans l'intervalle $%s$ donc ") % (TeX(racines[0]), intervalle))
728            ligne_valeurs = [borneinf, bornesup]
729
730            str_valeurs = "{$%s$,$%s$}" % (TeX(borneinf), TeX(bornesup))
731            str_signes = "\\tkzTabLine{,%s}" % signe_a
732#===============================================================================
733#             str_valeurs = "\\tx{%s}&\\tx{%s}&& \\tx{%s}\\cr" % (var, TeX(borneinf), TeX(bornesup))
734#
735#             str_signe = "\\tx{%s(%s)}&&\\tx{%s}&\\cr" % (nomP, var, signe_a)
736#===============================================================================
737            signes = [signe_a]
738        else:
739
740            ligne_valeurs = [borneinf, racines[0], bornesup]
741            str_valeurs = "{$%s$,$%s$,$%s$}" % (TeX(borneinf), TeX(racines[0]), TeX(bornesup))
742            str_signes = "\\tkzTabLine{,%s,0,%s}" % (signe_a, signe_a)
743            #===================================================================
744            # str_valeurs = "\\tx{%s}&\\tx{%s}&& \\tx{%s}&& \\tx{%s}\\cr" % (var, TeX(borneinf), TeX(racines[0]), TeX(bornesup))
745            # str_signe = "\\tx{%s(%s)}&&\\tx{%s}&\\tx{0}&\\tx{%s}&\\cr" % (nomP, var, signe_a, signe_a)
746            #===================================================================
747            signes = [signe_a, signe_a]
748    elif delta > 0:
749        [x1, x2] = racines
750        cor.append(_("Comme $\\Delta >0$, $%s(%s)$ est du signe de $-a$ entre les racines.") % (nomP, var))
751        compare = [(x1 <= borneinf) + (x2 <= borneinf), (x2 >= bornesup) + (x1 >= bornesup)]
752        # x_x1=x_x2=sign_x1=sign_x2=""
753        if compare != [0, 0]:
754            if borneinf != float("-inf"):
755                intervalle = "["
756            else:
757                intervalle = "]"
758            intervalle += "%s~;~%s" % (TeX(borneinf), TeX(bornesup))
759            if bornesup == float("inf"):
760                intervalle += "["
761            else:
762                intervalle += "]"
763
764        ligne_valeurs = [borneinf]
765        if compare[0] >= 1 or compare[1] == 2:
766            x_x1 = sign_x1 = ""
767        else:
768            x_x1 = "$%s$," % (TeX(x1))
769            ligne_valeurs += [x1]
770            sign_x1 = ",%s,0" % (signe_a)
771            signes += [signe_a]
772
773        if 2 in compare:
774            entreracines = ",%s" % (signe_a)
775            signes += [signe_a]
776        else:
777            entreracines = ",%s" % (signe_moinsa)
778            signes += [signe_moinsa]
779
780        if compare[1] >= 1 or compare[0] == 2:
781            x_x2 = sign_x2 = ""
782        else:
783            x_x2 = "$%s$," % (TeX(x2))
784            ligne_valeurs += [x2]
785            sign_x2 = ",0,%s" % (signe_a)
786            signes += [signe_a]
787        ligne_valeurs += [bornesup]
788        # Ne rien dire si une racine est égale à une borne
789        compare = [compare[0] - (x1 == borneinf) - (x2 == borneinf), compare[1] - (x1 == bornesup) - (x2 == bornesup)]
790
791        if sum(compare) == 2 :
792            # les deux racines sont à supprimer
793            cor.append(_("\\par Or $%s$ et $%s$ ne sont pas dans $%s$.") % (TeX(x1), TeX(x2), intervalle))
794
795        elif compare[0] == 1:
796            cor.append(_("\\par Or $%s$ n'est pas dans $%s$.") % (TeX(x1), intervalle))
797        elif compare[1] == 1:
798            cor.append(_("\\par Or $%s$ n'est pas dans $%s$.") % (TeX(x2), intervalle))
799        cor.append("Ainsi \\par")
800
801        str_valeurs = "{$%s$, %s %s $%s$}" % (TeX(borneinf), x_x1, x_x2, TeX(bornesup))
802        str_signes = "\\tkzTabLine{%s%s%s}" % (sign_x1, entreracines, sign_x2)
803
804#===============================================================================
805#         str_valeurs = "\\tx{%s}& \\tx{%s}& %s %s & \\tx{%s}\\cr" % (var, TeX(borneinf), x_x1, x_x2, TeX(bornesup))
806#
807#         str_signe = "\\tx{%s(%s)}&%s %s %s&\\cr" % (nomP, var, sign_x1, entreracines, sign_x2)
808#===============================================================================
809
810    cor.append("\\begin{tikzpicture}\n\\tkzTabInit[espcl=2.5]")
811    cor.append(str_variables)
812    cor.append(str_valeurs)
813    cor.append(str_signes)
814    cor.append(r'\end{tikzpicture}\par')
815    #===========================================================================
816    # cor.append("$$\\tabvar{")
817    # cor.append(str_valeurs)
818    # cor.append("%s}$$" % (str_signe))
819    #===========================================================================
820    if detail:
821        return str_variables, str_signes, str_valeurs, signes, ligne_valeurs
822
823def factorise_identites_remarquables(pol1, sgns, var='', racines=True):
824    '''Factorise un polynomes grâce aux identités remarquables'''
825    from pyromaths.classes.Fractions import Fraction
826    if var == '':
827        var = pol1.var
828    X = Polynome({1:1}, var)
829    a1 = pgcd(int(pol1[0]), pgcd(int(pol1[1]), int(pol1[2])))  # du signe de a=pol1[2]
830    if a1 != 1 or a1 != -1:
831        pol2 = pol1 / a1
832    else:
833        pol2 = pol1
834    # coeff=coeff/int(math.sqrt(a1))
835    # pol2=(cx)^2 ±2× cx × b + b^2
836    # pol2[2]=c^2
837    # pol2[1]=2× cx × b
838    # pol2[0] = b^2
839    c = int(sqrt(pol2[2]))  # problème d'arrondi ?
840
841    factorisation = []
842    if a1 != 1:
843        pol_temp = (pol1 / a1).simplifie()
844        pol_temp.var = var
845        factorisation.append("%s \\times\\big[ %s \\big]" % (TeX(a1), pol_temp))
846        facteur2 = "%s\\times \\big[" % (TeX(a1))
847    else:
848        facteur2 = ""
849    if c != 1:
850        facteur2 += u"(%s %s)^2" % (TeX(c), var)
851    else:
852        facteur2 += u"%s^2" % var
853    if sgns:
854        if sgns == -2:  # -2 => (a-b)²
855            facteur2 += "-2 \\times "
856        else:  # +2 => (a+b)²
857            facteur2 += "+2 \\times "
858        if c == 1:
859            facteur2 += var
860        else:
861            facteur2 += TeX(c) + var
862        b = int(sqrt(pol2[0]))
863        facteur2 += " \\times %s +" % (TeX(b))
864    else:
865        # a²-b²
866        facteur2 += "-"
867        b = int(sqrt(-(pol2[0])))
868    facteur2 += u"%s^2" % (TeX(b))
869    if a1 != 1:
870        facteur2 += "\\big]"
871    factorisation.append(facteur2)
872    facteur3 = ""
873    if a1 != 1:
874        facteur3 += TeX(a1)
875    sgns = sgns / 2
876    if sgns:  # (cx-b)² ou (cx+b)²
877        liste_racines = [Fraction(-(sgns)) * b / c]
878        facteur3 += "{(%s)}^2" % (c * X + sgns * b)
879    else:  # (cx-b)(cx+b)
880        liste_racines = [Fraction(-1) * b / c, Fraction(1) * b / c]
881        facteur3 += "(%s)(%s)" % (c * X + b, c * X - b)
882    factorisation.append(facteur3)
883    if racines:
884        return factorisation, liste_racines
885    return factorisation
886
887def racines_degre2(P):
888    """renvoie les racines d'un polynôme de degré 2"""
889    from pyromaths.classes.Fractions import Fraction
890    delta = int(P[1] ** 2 - 4 * P[2] * P[0])
891    if delta == 0:
892        x0 = eval(priorites('Fraction(-1, 2)*%r/%r' % (P[1], P[2]))[-1][0])
893        if isinstance(x0, (Fraction, RacineDegre2)):
894            liste_racines = [x0.simplifie()]
895        else:
896            liste_racines = [x0]
897        liste_str_racines = ["\\dfrac{-%s}{2\\times %s}" % (pTeX(P[1]), pTeX(P[2]))]
898        simplrac = [False]
899    elif delta > 0:
900        simplrac, strx1, x1, strx2, x2 = listeracines(P[2], P[1], delta, parentheses=False)
901        liste_racines = [x1, x2]
902        liste_str_racines = [strx1, strx2]
903    else:
904        simplrac = [False]
905        liste_racines = liste_str_racines = []
906    return delta, simplrac, liste_racines, liste_str_racines
907    # delta
908    # simplrac[0] est True si racine de Delta se simplifie, alors simplrac[1] est la racine de delta simplifiée
909    # liste_racines donne la liste des racines sous la forme simplifiée, sous forme numérique si possible
910    # liste_str_racine est la liste des racines au format TeX, non simplifié.
911
912def listeracines(a, b, delta, parentheses=False):
913    '''renvoie racsimple,simplifie,formule_x1,x_1,formule_x2,x2'''
914    '''avec x_1<x_2
915       si parenthese=True, renvoie deux booleens
916          parenthesex1=True signifie qu'il faut mettre des parenthese autour de x1
917       On suppose delta >0
918       simplrac est True si racine de delta se simplifie'''
919    a = int(a)
920    b = int(b)
921#     parenthesex1 = parenthesex2 = True  # par défaut
922    # simplrac=True
923    strx1 = "\\dfrac{-%s-\\sqrt{%s}}{2\\times %s}" % (pTeX(b), TeX(delta), pTeX(a))
924    strx2 = "\\dfrac{-%s+\\sqrt{%s}}{2\\times %s}" % (pTeX(b), TeX(delta), pTeX(a))
925    # #on a strx1<strx2
926    coeff, radicande = simplifie_racine(delta)
927
928    # x1,x2 simplifiés ont une écriture fractionnaire donc
929    parenthesex1 = parenthesex2 = False
930    if coeff == 1:  # delta n'a pas de facteur carré, on ne peut rien simplifier
931        rac_delta = radicalTeX(delta)
932        simplrac = [False]
933    else:
934        if radicande == 1:
935            rac_delta = TeX(coeff)
936        else:
937            rac_delta = TeX(coeff) + radicalTeX(radicande)
938        simplrac = [True, rac_delta]
939    x1 = RacineDegre2(-b, 2 * a, -1, delta)
940    x2 = RacineDegre2(-b, 2 * a, 1, delta)
941    if b == 0:
942        parenthesex1 = (coeff * a > 0)
943        parenthesex2 = (coeff * a < 0)
944    if a < 0:
945        strx1, strx2, x1, x2, parenthesex1, parenthesex2 = strx2, strx1, x2, x1, parenthesex2, parenthesex1
946    if parentheses:
947        return simplrac, strx1, x1, strx2, x2, parenthesex1, parenthesex2
948    else:
949        return simplrac, strx1, x1, strx2, x2
950        # simplrac[0] est True si racine de Delta se simplifie, alors simplrac[1] est la racine de delta simplifiée
951
952def factorisation_degre2(P, factorisation=True):
953    # x1=x2=0
954    from pyromaths.classes.Fractions import Fraction
955
956    var = P.var
957    X = Polynome({1:1}, var)
958    delta = int(eval(priorites('%r**2-4*%r*%r' % (P[1], P[2], P[0]))[-1][0]))
959    if delta < 0:
960        factorisation = []
961        str_racines = []
962        racines = []
963        simplrac = [False]
964    elif delta == 0:
965        x0 = eval(priorites('Fraction(-1, 2)*%r/%r' % (P[1], P[2]))[-1][0])
966        simplrac = [False]
967        if isinstance(x0, (Fraction, RacineDegre2)):
968            racines = [x0.simplifie()]
969        else:
970            racines = [x0]
971        str_racines = ["\\dfrac{-%s}{2\\times %s}" % (pTeX(P[1]), pTeX(P[2]))]
972
973
974        P0 = "%s-%s" % (var, pTeX(racines[0]))
975        factorisation = [[P0, P0]]  # non simplifiée
976
977        if 0 > racines[0]:
978            P0 = X - racines[0]
979            factorisation.append([P0, P0])
980    else:  # delta>0
981        simplrac, strx1, x1, strx2, x2 = listeracines(P[2], P[1], delta)
982        if isinstance(x1, RacineDegre2):
983            x1 = x1.simplifie()
984            x2 = x2.simplifie()
985        racines = [x1, x2]
986        str_racines = [strx1, strx2]
987        P1 = "%s-%s" % (var, pTeX(x1))
988        P2 = "%s-%s" % (var, pTeX(x2))
989        factorisation = [[P1, P2]]  # non simplifiée
990        # Peut-on simplifier les parenthèses ?
991        if x1.radicande == 0 and (x1.numerateur < 0 or x2.numerateur < 0):
992            P1 = (X - x1)(var)
993            P2 = (X - x2)(var)
994            factorisation.append([P1, P2])
995    return delta, simplrac, racines, str_racines, factorisation
996
997
998def factorisation_degre3(E, nomE, exo=[], cor=[], racines=[0, 1, -1, 2, -2]):
999    '''Factorise un polynôme de degré 3 avec une racine évidente'''
1000    var = E.var
1001    X = Polynome({1:1}, var)
1002    exo.append(_("\\item Soit $%s =%s $") % (nomE, E))
1003    cor.append(_("\\item Soit $%s=%s $)") % (nomE, E))
1004    exo.append("\\begin{enumerate}")
1005    cor.append("\\begin{enumerate}")
1006    for x0 in racines:
1007        if E(x0) == 0:
1008            break
1009    if x0 in [-2, -1, 0, 1, 2]:
1010        exo.append(_(u"\\item Vérifier si $%s $ possède une racine évidente.") % (nomE))
1011    else:
1012        exo.append(_(u"\\item Vérifier que $%s$ est une racine de $%s$.") % (TeX(x0), nomE))
1013    exo.append(_("\\item Factoriser $%s $.") % (nomE))
1014    cor.append("\\item ")
1015
1016    if x0 == 0:
1017        degre_facteur = min(E.puiss)
1018        # degre_facteur=1
1019        E2 = (E / (X ** degre_facteur))[0]
1020        if degre_facteur == 1:
1021            cor.append(_("On remarque que $%s$ peut se factoriser par $%s$ et $%s=%s\\left(%s\\right)$") % (nomE, var, nomE, var, E2))
1022        elif degre_facteur == 2:
1023            cor.append(_(u"On remarque que $%s$ peut se factoriser par $%s^2$ et $%s=%s^2\\left(%s\\right)$")\
1024            % (nomE, E.var, nomE, E.var, E2))
1025            exo.append("\\end{enumerate}")
1026            cor.append("\\end{enumerate}")
1027            return exo, cor
1028    else:
1029        cor.append(_("Comme $%s(%s)=0$, on peut diviser $%s$ par $%s$") % (nomE, TeX(x0), nomE, X - x0))
1030        cor.append(TeX_division(E, (X - x0)) + "")
1031        E2, reste = E / (X - x0)
1032    cor.append(_("\\item On doit maintenant factoriser le polynome $%s_2=%s$\\\\") % (nomE, E2))
1033    delta, simplrac, racines, str_racines, factorisation = factorisation_degre2(E2, factorisation=True)
1034    cor = redaction_factorisation(E2, nomP=nomE + "_2", exo=[], cor=cor)[1]
1035    cor.append("\\par")
1036    cor.append(_("On en conclue donc que $%s=") % (nomE))
1037#     final = 0
1038    if x0 == 0:
1039        P0 = E.var
1040    else:
1041        P0 = "\\left(%s\\right)" % (X - x0)
1042    if E[3] == -1:
1043        cor.append("-")
1044    elif E[3] != 1:
1045        cor.append(TeX(E[3]))
1046    if delta < 0:
1047        # P1 = factorisation[-1][0]
1048        E_factorise = "%s\\times%s$" % (P0, E2)
1049    elif delta == 0:
1050        P1 = factorisation[-1][0]
1051        E_factorise = "%s\\times{\\left(%s\\right)}^2$" % (P0, P1)
1052    else:
1053        P1 = factorisation[-1][0]
1054        P2 = factorisation[-1][1]
1055        E_factorise = "%s\\left(%s\\right)\\left(%s\\right)$" % (P0, P1, P2)
1056    cor.append(E_factorise)
1057
1058    exo.append("\\end{enumerate}")
1059    cor.append("\\end{enumerate}")
1060    return exo, cor
1061
1062
1063#----------------- redaction ---------------------------------------------------------
1064
1065def redaction_factorisation(P, nomP="P", exo=[], cor=[]):
1066    var = P.var
1067    delta, simpl_delta, racines, str_racines, factorisation = factorisation_degre2(P)
1068    redaction_racines(P, nomP, var, cor)
1069
1070    # factorisation
1071    if delta < 0:
1072        cor.append(_(u"On ne peut pas factoriser $%s(%s)$.") % (nomP, var))
1073    elif delta == 0:
1074        cor.append(_(u"On peut donc écrire "))
1075        ligne_factorisation = "$$%s(%s)" % (nomP, var)
1076        for etape in factorisation:
1077            ligne_factorisation += " = "
1078            if P[2] != 1:
1079                ligne_factorisation += "%s \\times " % (TeX(P[2]))
1080
1081            ligne_factorisation += "{\\left(%s\\right)}^2" % (etape[0])
1082        ligne_factorisation += "$$"
1083        cor.append(ligne_factorisation)
1084    else:
1085        cor.append(_(u"On peut donc écrire "))
1086        ligne_factorisation = "$$%s(%s)" % (nomP, var)
1087        for etape in factorisation:
1088            ligne_factorisation += " = "
1089            if P[2] != 1:
1090                ligne_factorisation += "%s \\times " % (TeX(P[2]))
1091            if len(etape) == 1:
1092                ligne_factorisation += etape[0]
1093            else:
1094                ligne_factorisation += "\\left(%s\\right)\left(%s\\right)" % (etape[0], etape[1])
1095        ligne_factorisation += "$$"
1096        cor.append(ligne_factorisation)
1097    return exo, cor
1098
1099def redaction_racines(P, nomP, var, cor=[]):
1100    delta, simpl_delta, liste_racines, liste_str_racines = racines_degre2(P)
1101    ligne_delta = _(u"Je calcule $\\Delta=%s^2-4\\times %s\\times %s=%s$") % (pTeX(P[1]), pTeX(P[2]), pTeX(P[0]), TeX(delta))
1102    if simpl_delta[0]:
1103        ligne_delta += _(" et $%s=%s$.\\par") % (radicalTeX(delta), simpl_delta[1])
1104    else:
1105        ligne_delta += ".\\par"
1106    cor.append(ligne_delta)
1107    if delta < 0:
1108        cor.append(_("Comme $\\Delta <0$, $%s(%s)$ n'a pas de racines.") % (nomP, var))
1109    elif delta == 0:
1110        cor.append(_("Comme $\\Delta=0$, $%s(%s)$ a une seule racine $%s_0=%s=%s$.\\par") % (nomP, var, var, liste_str_racines[0], TeX(liste_racines[0])))
1111    else:  # delta>0
1112        [x1, x2] = liste_racines
1113        cor.append(_("Comme $\\Delta>0$, $%s(%s)$ a deux racines :") % (nomP, var))
1114        if isinstance(x1, RacineDegre2):
1115#             simplification1 = simplification2 = ""
1116            x1, detail1 = x1.simplifie(True)
1117            x2, detail2 = x2.simplifie(True)
1118            max_len = max(len(detail1), len(detail2))
1119            cor.append("\\begin{align*}")
1120            cor.append("%s &= %s  &%s &= %s" % \
1121                       (liste_str_racines[0], liste_racines[0], liste_str_racines[1], liste_racines[1]))
1122            cor.append("\\\\")
1123            for i in range(0, max_len):
1124                if i < len(detail1):
1125                    cor.append("&= %s&" % (detail1[i]))
1126                else:
1127                    cor.append("&&")
1128                if i < len(detail2):
1129                    cor.append("&= %s" % (detail2[i]))
1130                else:
1131                    cor.append("& ")
1132                cor.append("\\\\")
1133            cor.pop(-1)
1134            cor.append("\\end{align*}")
1135            cor.append(_("Les racines de $%s$ sont $%s_1=%s$ et $%s_2=%s$.\\par") % (nomP, var, x1, var, x2))
1136        else:
1137            [strx1, strx2] = liste_str_racines
1138            cor.append(_("Les racines de $%s$ sont $%s_1=%s=%s$ et $%s_2=%s=%s$.") % (nomP, var, strx1, x1, var, strx2, x2))
1139
1140    return cor
Note: See TracBrowser for help on using the repository browser.