def ecr_sc(): from math import log10, floor exo = ["\\exercice", u"Compléter par le nombre qui convient :", "\\begin{multicols}{3}", " \\noindent%", " \\begin{enumerate}"] cor = ["\\exercice*", u"Compléter par le nombre qui convient :", "\\begin{multicols}{3}", " \\noindent%", " \\begin{enumerate}"] for dummy in range(6): a = val_sc() exp = int(floor(log10(a))) a_sc = (a * 1.) / 10 ** exp s_a = decimaux(a, 1) s_a_sc = decimaux(a_sc, 1) if randrange(2): # forme : a=a_sc*... exo.append("\\item $%s=%s\\times\\dotfill$" % (s_a, s_a_sc)) cor.append("\\item $%s=%s\\times\\mathbf{10^{%s}}$" % (s_a, s_a_sc, decimaux(exp, 1))) else: # forme : a_sc*...=a exo.append("\\item $%s\\times\\dotfill=%s$" % (s_a_sc, s_a)) cor.append("\\item $%s\\times\\mathbf{10^{%s}}=%s$" % (s_a_sc, decimaux(exp, 1), s_a)) exo.append("\\end{enumerate}") exo.append("\\end{multicols}\n") cor.append("\\end{enumerate}") cor.append("\\end{multicols}\n") return (exo, cor)
def tex_answer(self): cor = ["\\exercice*", '\\begin{enumerate}'] for k in range(4): arrondi = round(self.nombres[k], -self.choix_precision[k] + 3) if (arrondi > self.nombres[k]): defaut = arrondi - 10 ** (self.choix_precision[k] - 3) exc = arrondi if (arrondi <= self.nombres[k]): defaut = arrondi exc = arrondi + 10 ** (self.choix_precision[k] - 3) if (self.choix_supinf[k] == 0): solution = arrondi elif (self.choix_supinf[k] == 1): solution = defaut elif (self.choix_supinf[k] == 2): solution = exc cor.append('\\item L\'encadrement de ' + decimaux(self.nombres[k]) + ' ' + precision[self.choix_precision[k]] + ' est :\\par') cor.append(decimaux(defaut) + ' < ' + decimaux(self.nombres[k]) + ' < ' + decimaux(exc) + '\\par') cor.append(u'On en déduit que son arrondi ' + precision[self.choix_precision[k]] + ' ' + supinf[self.choix_supinf[k]] + ' est : ' + decimaux(solution) + '.') cor.append("\\end{enumerate}") return cor
def tracefonc(f, i, A, B, xmin, xmax, ymin, ymax): """**tracefonc\ (*f*\ , *i*\ , *A*\ , *B*\ , *xmin*\ , *xmax*\ , *ymin*\ , *ymax*\ ) *A* est sur l'axe des ordonnées, *f* est le nom de la fonction Génère la 2e queston et sa réponse >>> from pyromaths.classes.Fractions import Fraction >>> affine.tracefonc('f', 1, (0,-2),(3,2),-4,4,-4,-4) [u'Tracer la droite repr\xe9sentative ($d_1$) de la fonction $f:x\\longmapsto \\ dfrac{4}{3}\\,x-2$.', 'On sait que $f(0)=-2$ et $f(-3)=\\dfrac{4}{3}\\times \\le ft( -3\\right) -2=\\dfrac{4\\times \\cancel{3}\\times -1}{\\cancel{3}\\times 1}- 2=-4-2=-6', '\\psdot [dotsize=4.5pt,dotstyle=x](0, -2)', '\\psdot [dotsize=4.5pt ,dotstyle=x](-3, -6.0)'] :rtype: list of string """ u = coefdir(A, B) if isinstance(u, int) or u.d == 1: x1 = decimaux(B[0]) else: B = (u.d, u.n + float(A[1])) if not dansrep(B, xmin, xmax, ymin, ymax): B = (-u.d, -u.n + float(A[1])) x1 = decimaux(str(B[0])) l = Priorites3.texify([Polynome([[u, 1], [A[1], 0]], "x")(B[0])]) l.extend(Priorites3.texify(Priorites3.priorites(Polynome([[u, 1], [A[1], 0]], "x")(B[0])))) l = [u'Tracer la droite représentative ($d_' + str(i) + '$) de la fonction $' + f + ':x\\longmapsto ' + str(Polynome([[u, 1], [A[1], 0]], "x")) + '$.', 'On sait que $' + f + '(0)=' + decimaux(str(A[1])) + '$ et $' + f + '(' + x1 + ')=' + "=".join(l) + "$.", '\\psdot [dotsize=4.5pt,dotstyle=x]' + str(A), '\\psdot [dotsize=4.5pt,dotstyle=x]' + str(B), ] return l
def elements_intervalle(variations, sens): """Renvoie deux nombres appartenant à un intervalle sur lequel la fonction est monotone, ainsi que l'intervalle monotone auquel ils appartiennent""" while True: index = randrange(len(variations)) if variations[index][0] == sens: break 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) 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) return [x0, x1, [variations[index][1], variations[index][2]]]
def reperage(): nbpts = 13 noms_pts = (noms_sommets(nbpts)) coord_pts = coordo_pts(nbpts) voc = [_('abscisse'), _(u'ordonnée')] rg1 = random.randrange(0, 2) rg2 = abs(rg1 - 1) while len(coord_pts) < nbpts: coord_pts = coordo_pts(nbpts) exo = [ "\\exercice", "\\parbox{0.4\\linewidth}{", "\\begin{enumerate}", _(u"\\item Donner les coordonnées des points %s, %s, %s, %s, %s et %s." ) % tuple(noms_pts[0:6]), _(u"\\item Placer dans le repère les points %s, %s, %s, %s, %s et %s") % noms_pts[6:12] + _(u" de coordonnées respectives %s, %s, %s, %s, %s et %s. ") % tuple(tex_liste_co(coord_pts[6:12])), _(u"\\item Placer dans le repère le point %s d'%s %s et d'%s %s") % (noms_pts[12], voc[rg1], decimaux(str( coord_pts[12][rg1])), voc[rg2], decimaux(str(coord_pts[12][rg2]))), "\\end{enumerate}}\\hfill ", "\\parbox{0.55\\linewidth}{", "\\psset{unit=0.8cm}", "\\begin{pspicture}(-4.95,-4.95)(4.95,4.95)", "\\psgrid[subgriddiv=2, subgridcolor=lightgray, gridlabels=8pt](0,0)(-5,-5)(5,5)", "\\psline[linewidth=1.2pt]{->}(-5,0)(5,0)", "\\psline[linewidth=1.2pt]{->}(0,-5)(0,5)", place_points(coord_pts[0:6], noms_pts[0:6]), "\\end{pspicture}}" ] cor = [ "\\exercice*", "\\parbox{0.4\\linewidth}{", "\\psset{unit=0.8cm}", "\\begin{pspicture}(-5,-5)(5,5)", "\\psgrid[subgriddiv=2, subgridcolor=lightgray, gridlabels=8pt](0,0)(-5,-5)(5,5)", "\\psline[linewidth=1.2pt]{->}(-5,0)(5,0)", "\\psline[linewidth=1.2pt]{->}(0,-5)(0,5)", place_points(coord_pts[0:13], noms_pts[0:13]), "\\end{pspicture}}\\hfill", "\\parbox{0.5\\linewidth}{", "\\begin{enumerate}", _(u"\\item Donner les coordonnées des points %s, %s, %s, %s, %s et %s." ) % tuple(noms_pts[0:6]) ] i = 0 while i < 6: cor.append( _(u"Les coordonnées du point %s sont %s \n") % (noms_pts[i], affiche_coord(coord_pts[i]))) i = i + 1 cor[len(cor):len(cor)] = [ _(u"\\item Placer dans le repère les points %s, %s, %s, %s, %s et %s") % noms_pts[6:12] + _(u" de coordonnées respectives %s, %s, %s, %s, %s et %s. ") % tuple(tex_liste_co(coord_pts[6:12])), _(u"\\item Placer dans le repère le point %s d'%s %s et d'%s %s") % (noms_pts[12], voc[rg1], decimaux(str(coord_pts[12][rg1])), voc[rg2], decimaux(str(coord_pts[12][rg2]))), "\\end{enumerate}" ] cor.append("}") return (exo, cor)
def tex_proprietes_neg(): exo = ["\\exercice", u"Écrire sous la forme d'une puissance de 10 puis donner l'écriture", u" décimale de ces nombres :", "\\begin{multicols}{2}", " \\noindent%", " \\begin{enumerate}"] cor = ["\\exercice*", u"Écrire sous la forme d'une puissance de 10 puis donner l'écriture", u" décimale de ces nombres :", "\\begin{multicols}{2}", " \\noindent%", " \\begin{enumerate}"] lexos = [0, 1, 2, 3, 0, 1, 2, 3] # 0: a^n*a^p ; 1: (a^n)^p ; 2:a^n/a^p for dummy in range(len(lexos)): lexp = [randrange(-6, 6) for dummy in range(2)] j = lexos.pop(randrange(len(lexos))) # FIXME : À finir if j == 0: while abs(lexp[0] + lexp[1]) > 10: lexp = [randrange(-6, 6) for dummy in range(2)] exo.append("\\item $10^{%s} \\times 10^{%s} = \\dotfill$" % tuple(lexp)) cor.append("\\item $10^{%s}\\times 10^{%s}=" % tuple(lexp)) cor.append("10^{%s+%s}=" % (lexp[0], tex_coef(lexp[1], '', bpn=1))) cor.append("10^{%s}=%s$" % (lexp[0] + lexp[1], decimaux(10 ** (lexp[0] + lexp[1]), 1))) elif j == 1: while abs(lexp[0] * lexp[1]) > 10: lexp = [randrange(-6, 6) for dummy in range(2)] exo.append("\\item $(10^{%s})^{%s}=\\dotfill$" % (lexp[0], lexp[1])) cor.append("\\item $(10^{%s})^{%s}=" % tuple(lexp)) cor.append("10^{%s \\times %s}=" % (lexp[0], tex_coef(lexp[1], '', bpn=1))) cor.append("10^{%s}=%s$" % (lexp[0] * lexp[1], decimaux(10 ** (lexp[0] * lexp[1]), 1))) elif j == 2: while abs(lexp[0] - lexp[1]) > 10: lexp = [randrange(-6, 6) for dummy in range(2)] exo.append("\\item $\\dfrac{10^{%s}}{10^{%s}}=\\dotfill$" % tuple(lexp)) cor.append("\\item $\\dfrac{10^{%s}}{10^{%s}}=" % tuple(lexp)) cor.append("10^{%s-%s}=" % (lexp[0], tex_coef(lexp[1], '', bpn=1))) cor.append("10^{%s}=%s$" % (lexp[0] - lexp[1], decimaux(10 ** (lexp[0] - lexp[1]), 1))) exo.append("\\end{enumerate}") exo.append("\\end{multicols}\n") cor.append("\\end{enumerate}") cor.append("\\end{multicols}\n") return (exo, cor)
def tex_statement(self): exo = ["\\exercice", '\\begin{enumerate}'] for k in range(4): exo.append("\\item Arrondir " + decimaux(self.nombres[k]) + " " + precision[self.choix_precision[k]] + supinf[self.choix_supinf[k]] + '.') exo.append("\\end{enumerate}") return exo
def tex_answer(self): exo = [r'\exercice*'] exo.append(r'\begin{enumerate}') exo.append(r'\item') exo.append(r'\begin{enumerate}') for i in range(3): 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])) exo.append(r'\end{enumerate}') for i in range(2): if self.non_comparable[i][0][1] * self.non_comparable[i][1][1] <= 0: 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]$).') % \ (decimaux(self.non_comparable[i][0][0], 1), ['<', '>'][self.non_comparable[i][0][1] > 0], decimaux(self.non_comparable[i][1][0], 1), \ decimaux(self.non_comparable[i][0][0], 1), ['<', '>'][self.non_comparable[i][0][1] > 0], decimaux(self.non_comparable[i][1][0], 1), \ ['<', '>'][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))) else: 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]$.') % \ (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))) exo.append(r'\end{enumerate}') return exo
def tex_answer(self): exo = [r'\exercice*'] exo.append(r'\begin{enumerate}') exo.append(r'\item') exo.append(r'\begin{multicols}{2}') exo.append(r'\begin{enumerate}') extr = extrema(self.lX, self.lY, [self.lX[0], self.lX[-1]]) 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])) 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])) 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]])) exo.append(r'\end{enumerate}') exo.append(r'\end{multicols}') exo.append(r'\item') exo.append(r'\begin{enumerate}') 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])) 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))) exo.append(r'\end{enumerate}') exo.append(r'\end{enumerate}') return exo
def anteimage(fonc, A, B): # Génère la 1ère question et sa réponse l = [' l\'image de ', ' un nombre qui a pour image ', u' un antécédent de '] lcor = [' est l\'image de ', ' a pour image ', u' est un antécédent de '] # liste pour le corrigé i = random.randrange(0, 2) j = i if i == 1: j = i + random.randrange(0, 2) res = [] res.append('Donner ' + l[j] + '$' + decimaux(str(A[i])) + '$' + ' par la fonction ' + '\\textit{' + fonc + '}.') res.append('$' + decimaux(str(A[abs(i - 1)])) + '$' + lcor[j] + '$' + decimaux(str(A[i])) + '$' + ' par la \\hbox{fonction ' + '\\textit{' + fonc + '}}.') if i == 0: res.append(doublefleche((A[0], 0), A)) res.append(doublefleche(A, (0, A[1]))) else: res.append(doublefleche((0, A[1]), A)) res.append(doublefleche(A, (A[0], 0))) i = abs(i - 1) j = i if i == 1: j = i + random.randrange(0, 2) res.append('Donner ' + l[j] + '$' + decimaux(str(B[i])) + '$' + ' par la fonction ' + '\\textit{' + fonc + '}.') res.append('$' + decimaux(str(B[abs(i - 1)])) + '$' + lcor[j] + '$' + decimaux(str(B[i])) + '$' + ' par la \\hbox{fonction ' + '\\textit{' + fonc + '}}.') if i == 0: res.append(doublefleche((B[0], 0), B)) res.append(doublefleche(B, (0, B[1]))) else: res.append(doublefleche((0, B[1]), B)) res.append(doublefleche(B, (B[0], 0))) return res
def tracefonc(f, i, A, B, xmin, xmax, ymin, ymax): """**tracefonc\ (*f*\ , *i*\ , *A*\ , *B*\ , *xmin*\ , *xmax*\ , *ymin*\ , *ymax*\ ) *A* est sur l'axe des ordonnées, *f* est le nom de la fonction Génère la 2e queston et sa réponse >>> from pyromaths.classes.Fractions import Fraction >>> affine.tracefonc('f', 1, (0,-2),(3,2),-4,4,-4,-4) [u'Tracer la droite repr\xe9sentative ($d_1$) de la fonction $f:x\\longmapsto \\ dfrac{4}{3}\\,x-2$.', 'On sait que $f(0)=-2$ et $f(-3)=\\dfrac{4}{3}\\times \\le ft( -3\\right) -2=\\dfrac{4\\times \\cancel{3}\\times -1}{\\cancel{3}\\times 1}- 2=-4-2=-6', '\\psdot [dotsize=4.5pt,dotstyle=x](0, -2)', '\\psdot [dotsize=4.5pt ,dotstyle=x](-3, -6.0)'] :rtype: list of string """ u = coefdir(A, B) if isinstance(u, int) or u.d == 1: x1 = decimaux(B[0]) else: B = (u.d, u.n + float(A[1])) if not dansrep(B, xmin, xmax, ymin, ymax): B = (-u.d, -u.n + float(A[1])) x1 = decimaux(str(B[0])) l = Priorites3.texify([Polynome([[u, 1], [A[1], 0]], "x")(B[0])]) l.extend( Priorites3.texify( Priorites3.priorites(Polynome([[u, 1], [A[1], 0]], "x")(B[0])))) l = [ u'Tracer la droite représentative ($d_' + str(i) + '$) de la fonction $' + f + ':x\\longmapsto ' + str(Polynome([[u, 1], [A[1], 0]], "x")) + '$.', 'On sait que $' + f + '(0)=' + decimaux(str(A[1])) + '$ et $' + f + '(' + x1 + ')=' + "=".join(l) + "$.", '\\psdot [dotsize=4.5pt,dotstyle=x]' + str(A), '\\psdot [dotsize=4.5pt,dotstyle=x]' + str(B), ] return l
def anteimage(fonc, A, B): # Génère la 1ère question et sa réponse l = [ ' l\'image de ', ' un nombre qui a pour image ', u' un antécédent de ' ] lcor = [' est l\'image de ', ' a pour image ', u' est un antécédent de '] # liste pour le corrigé i = random.randrange(0, 2) j = i if i == 1: j = i + random.randrange(0, 2) res = [] res.append('Donner ' + l[j] + '$' + decimaux(str(A[i])) + '$' + ' par la fonction ' + '\\textit{' + fonc + '}.') res.append('$' + decimaux(str(A[abs(i - 1)])) + '$' + lcor[j] + '$' + decimaux(str(A[i])) + '$' + ' par la \\hbox{fonction ' + '\\textit{' + fonc + '}}.') if i == 0: res.append(doublefleche((A[0], 0), A)) res.append(doublefleche(A, (0, A[1]))) else: res.append(doublefleche((0, A[1]), A)) res.append(doublefleche(A, (A[0], 0))) i = abs(i - 1) j = i if i == 1: j = i + random.randrange(0, 2) res.append('Donner ' + l[j] + '$' + decimaux(str(B[i])) + '$' + ' par la fonction ' + '\\textit{' + fonc + '}.') res.append('$' + decimaux(str(B[abs(i - 1)])) + '$' + lcor[j] + '$' + decimaux(str(B[i])) + '$' + ' par la \\hbox{fonction ' + '\\textit{' + fonc + '}}.') if i == 0: res.append(doublefleche((B[0], 0), B)) res.append(doublefleche(B, (0, B[1]))) else: res.append(doublefleche((0, B[1]), B)) res.append(doublefleche(B, (B[0], 0))) return res
def tex_statement(self): exo = [r'\exercice'] exo.append(r'\begin{enumerate}') 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}')) exo.append(r'\begin{multicols}{3}') exo.append(r'\begin{enumerate}') exo.append(r'\item $f\,(%s) \ldots{} f\,(%s)$' % tuple(self.comparaison[0][:2])) exo.append(r'\item $f\,(%s) \ldots{} f\,(%s)$' % tuple(self.comparaison[1][:2])) exo.append(r'\item $f\,(%s) \ldots{} f\,(%s)$' % tuple(self.comparaison[2][:2])) exo.append(r'\end{enumerate}\vspace{-2ex}') exo.append(r'\end{multicols}') 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]))) 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]))) exo.append(r'\end{enumerate}') exo.append(r'\begin{center}') variations = list(self.variations) lY = list(self.lY) exo.append(r'\begin{tikzpicture}[scale=1]') 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])]))) ans = r'\tkzTabVar{' # %-/$-2$,+/$5$,-/$-3$,+/$-1$,-/$-4$}' trois_niv = False for index in range(len(variations)): yindex = variations[index][1] - self.lX[0] if variations[index][0] == 1: if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex] trois_niv = False else: ans += r'-/$%s$,' % lY[yindex] if variations[index][0] == -1: if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex] trois_niv = False else: ans += r'+/$%s$,' % lY[yindex] if variations[index][0] == 0: if index > 0 and index < len(variations) - 1 and variations[index - 1][0] * variations[index + 1][0] > 0: trois_niv = True if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex] elif index > 0: if variations[index - 1][0] == 1: ans += r'+/$%s$,' % lY[yindex] else: ans += r'-/$%s$,' % lY[yindex] elif index < len(variations) - 1: if variations[index + 1][0] == 1: ans += r'-/$%s$,' % lY[yindex] else: ans += r'+/$%s$,' % lY[yindex] if variations[-1][0] == 1: ans += r'+/$%s$}' % lY[-1] elif variations[-1][0] == -1: ans += r'-/$%s$}' % lY[-1] elif variations[-1][0] == 0: if variations[-2][0] == 1: ans += r'+/$%s$}' % lY[-1] elif variations[-2][0] == -1: ans += r'-/$%s$}' % lY[-1] exo.append(ans) # Place les zéros for absc in range(self.lX[0], self.lX[-1] + 1): if lY[absc - self.lX[0]] == 0: for index in range(len(variations)): if variations[index][1] < absc < variations[index][2]: if variations[index][0] != 0: exo.append(r'\tkzTabVal{%s}{%s}{0.5}{\scriptsize $%s$}{$0$}' % (index + 1, index + 2, absc)) break if variations[index][1] == absc or variations[index][2] == absc: break exo.append(r'\end{tikzpicture}') exo.append(r'\end{center}') return exo
def Arithmetique(): """Exercice de décomposition de nombres en facteurs premiers, puis de recherche du PGCD et du PPCM, et d'applications aux fractions""" # ## Question 1 exo = ["\\exercice", '\\begin{enumerate}', u"\\item Donner la décomposition" + u" en facteurs premiers des nombres suivants, et préciser quand il" + u" s\'agit d\'un nombre premier :\\par"] cor = ["\\exercice*", '\\begin{enumerate}', u"\\item Donner la décomposition" + u" en facteurs premiers des nombres suivants, et préciser quand il" + u" s\'agit d\'un nombre premier :\\par"] prime = premiers[randint(10, 167)] fauxpgcd = randint(1, 101) fauxpgcdfactor = factoriseTex(fauxpgcd)[0] complementaires = [randint(6, 50), randint(6, 50)] pgcdcompl = pgcd(complementaires[0], complementaires[1]) pgcdcomplfact = factoriseTex(pgcdcompl)[0] if pgcdcompl != 1: facteurs = pgcdcomplfact + fauxpgcdfactor facteurs.sort() else: facteurs = fauxpgcdfactor autresnombres = [randint(51, 999), randint(51, 999)] listenombres = [prime, complementaires[0] * fauxpgcd, complementaires[1] * fauxpgcd, ] + autresnombres melange = [prime, complementaires[0] * fauxpgcd, complementaires[1] * fauxpgcd, ] + autresnombres shuffle(melange) exo.append(decimaux(melange[0]) + " ; " + decimaux(melange[1]) + " ; " + decimaux(melange[2]) + " ; " + decimaux(melange[3]) + " ; " + decimaux(melange[4]) + " ;") cor.append("\\begin{multicols}{2}") for i in range(5): cor += factoriseTex(melange[i])[1] cor.append("\\end{multicols}") # ## Question 2 exo.append(u'\\item En déduire le PGCD et le PPCM des nombres ' + decimaux(listenombres[1]) + " et " + decimaux(listenombres[2]) + ".") cor.append(u'\\item En déduire le PGCD et le PPCM des nombres ' + decimaux(listenombres[1]) + " et " + decimaux(listenombres[2]) + ".\\par") cor.append(u"D'après la question 1), on sait que les nombres " + decimaux(listenombres[1]) + " et " + decimaux(listenombres[2]) + " ont comme facteurs premiers communs : ") for j in range(len(facteurs)): if j == 0: temp = "$" if j != len(facteurs) - 1: temp += decimaux(facteurs[j]) + " , " else: temp += decimaux(facteurs[j]) + "$.\\par" cor.append(temp) cor.append(u"On en déduit que le PGCD des nombres " + decimaux(listenombres[1]) + " et " + decimaux(listenombres[2]) + " est : ") temp = "$" if len(facteurs) > 1: for j in range(len(facteurs)): if j != len(facteurs) - 1: temp += decimaux(facteurs[j]) + " \\times " else: temp += decimaux(facteurs[j]) + " = " temp += decimaux(fauxpgcd * pgcdcompl) + ".$\\par" cor.append(temp) vraippcm = (listenombres[1] * listenombres[2]) / (fauxpgcd * pgcdcompl) if (listenombres[1] % listenombres[2] == 0): cor.append(decimaux(listenombres[1]) + u" est un multiple de " + decimaux(listenombres[2]) + u", donc leur PPCM est directement " + decimaux(listenombres[1]) + ".") elif (listenombres[2] % listenombres[1] == 0): cor.append(decimaux(listenombres[2]) + u" est un multiple de " + decimaux(listenombres[1]) + u", donc leur PPCM est directement " + decimaux(listenombres[2]) + ".") else: cor.append(u"Il existe plusieurs méthodes pour calculer le PPCM de " + decimaux(listenombres[1]) + " et de " + decimaux(listenombres[2]) + ".\\par") cor.append(u"En voici deux :") cor.append("\\begin{enumerate}") cor.append(u"\\item On peut simplement utiliser la formule :") cor.append(u"$a \\times b = PGCD(a;~b) \\times PPCM(a;~b)$.\\par") cor.append(u"Donc : $PPCM(" + decimaux(listenombres[1]) + ";~" + decimaux(listenombres[2]) + ") = " + "\\dfrac{" + decimaux(listenombres[1]) + "\\times" + decimaux(listenombres[2]) + "}{" + decimaux(fauxpgcd * pgcdcompl) + "} = " + decimaux(vraippcm) + ".$") cor.append(u"\\item On peut aussi multiplier un nombre par les \"facteurs " + u"complémentaires\" de l'autre.\n" + u"Ces \"facteurs " + u"complémentaires\" sont les facteurs qui complètent le PGCD pour " + u"former le nombre.\\par") temp = u"Comme $PGCD(" + decimaux(listenombres[1]) + ";~" + \ decimaux(listenombres[2]) + ") = " + decimaux(fauxpgcd * pgcdcompl) if len(facteurs) > 1: temp += " = " for j in range(len(facteurs)): if j != len(facteurs) - 1: temp += decimaux(facteurs[j]) + " \\times " else: temp += decimaux(facteurs[j]) factornb1 = factoriseTex(listenombres[1])[0] if len(factornb1) > 1: textcompl = u"$, alors les \"facteurs complémentaires\" de $" else: textcompl = u"$, alors le \"facteur complémentaire\" de $" temp += textcompl + decimaux(listenombres[1]) + " = " for j in range(len(factornb1)): if j != len(factornb1) - 1: temp += decimaux(factornb1[j]) + " \\times " else: temp += decimaux(factornb1[j]) factcompl = factoriseTex(listenombres[1] / (fauxpgcd * pgcdcompl))[0] if len(factcompl) == 1: temp += u"$ est : " else: temp += u"$ sont : " for j in range(len(factcompl)): if j != len(factcompl) - 1: temp += decimaux(factcompl[j]) + " , " else: temp += decimaux(factcompl[j]) + ".\n" temp += u"On en déduit que $PPCM(" + decimaux(listenombres[1]) + ";~" + \ decimaux(listenombres[2]) + ") = " + decimaux(listenombres[2]) + \ " \\times " for j in range(len(factcompl)): if j != len(factcompl) - 1: temp += decimaux(factcompl[j]) + " \\times " else: temp += decimaux(factcompl[j]) + " = " temp += decimaux(vraippcm) + ".$" cor.append(temp) cor.append("\\end{enumerate}") # ## Question 3 exo.append(u"\\item Quel est le plus petit nombre par lequel il faut " + u"multiplier " + decimaux(autresnombres[0]) + u" pour obtenir un carré parfait ?") cor.append(u" \\item Pour obtenir un carré parfait, il faut que sa " + u"décomposition en facteurs premiers ne contienne que des facteurs " + u"apparaissant un nombre pair de fois. D'après la question 1, " + u"la décomposition en facteurs premiers de " + decimaux(autresnombres[0])) decompautre = factoriseTex(autresnombres[0])[1] if len(decompautre) == 1: cor.append(u" est lui-même, car c'est un nombre premier.") else: cor.append(" est : \\par\n$" + decimaux(autresnombres[0]) + " = " + decompautre[-2][5:-2] + ".$\\par") cor.append(u"Il faut donc encore multiplier ce nombre par ") carre = carrerise(autresnombres[0]) factsup = factoriseTex(carre)[0] if len(factsup) == 1: cor.append(" le facteur ") else: cor.append(" les facteurs ") for j in range(len(factsup)): if (j != len(factsup) - 1) and (j != len(factsup) - 2): cor.append(decimaux(factsup[j]) + " , ") elif (j == len(factsup) - 2): cor.append(decimaux(factsup[j]) + " et ") else: cor.append(decimaux(factsup[j]) + ".\\par") cor.append(u"Le nombre cherché est par conséquent " + decimaux(carre) + u" et le carré parfait obtenu est " + decimaux(carre * autresnombres[0]) + ".") # ## Question 4 exo.append(u"\\item Rendre la fraction $\\dfrac{" + decimaux(listenombres[1]) + "}{" + decimaux(listenombres[2]) + u"}$ irréductible.") cor.append(u"\\item Le moyen le plus rapide de simplifier cette fraction est" + u"de diviser le numérateur et le dénominateur par leur PGCD." + u" D'après la question 2), PGCD(" + decimaux(listenombres[1]) + ";~" + decimaux(listenombres[2]) + ") = " + decimaux(fauxpgcd * pgcdcompl) + ", donc on obtient :\\par") cor.append(u"$\dfrac{" + decimaux(listenombres[1]) + "{\\scriptstyle \\div " + decimaux(fauxpgcd * pgcdcompl) + "}}{" + decimaux(listenombres[2]) + "{\\scriptstyle \\div " + decimaux(fauxpgcd * pgcdcompl) + "}} = \dfrac{" + decimaux(listenombres[1] / (fauxpgcd * pgcdcompl)) + "}{" + decimaux(listenombres[2] / (fauxpgcd * pgcdcompl)) + "}.$") # ## Question 5 num = [randint(6, 50), randint(6, 50)] exo.append(u"\\item Calculer $\\dfrac{" + decimaux(num[0]) + "}{" + decimaux(listenombres[1]) + "} + \\dfrac{" + decimaux(num[1]) + "}{" + decimaux(listenombres[2]) + "}$.") mult1 = vraippcm / listenombres[1] mult2 = vraippcm / listenombres[2] num1 = mult1 * num[0] num2 = mult2 * num[1] simplfin = pgcd(num1 + num2, vraippcm) if simplfin != 1: simpl = "{\\scriptstyle \\div " + decimaux(simplfin) + "}" result = " = \\dfrac{" + decimaux((num1 + num2) / simplfin) + "}{" + \ decimaux((vraippcm) / simplfin) + "}" else: simpl = "" result = "" cor.append(u"\\item Il faut mettre les fractions au même dénominateur. Grâce" + u"à la question 2), nous avons déjà un dénominateur commun : " + u"le PPCM des nombres " + decimaux(listenombres[1]) + " et " + decimaux(listenombres[2]) + u", qui est par définition le plus petit" + u"multiple commun de ces deux nombres.\\par") cor.append(u"$\\dfrac{" + decimaux(num[0]) + "{\\scriptstyle \\times " + decimaux(mult1) + "}}{" + decimaux(listenombres[1]) + "{\\scriptstyle \\times " + decimaux(mult1) + "}} + \\dfrac{" + decimaux(num[1]) + "{\\scriptstyle \\times " + decimaux(mult2) + "}}{" + decimaux(listenombres[2]) + "{\\scriptstyle \\times " + decimaux(mult2) + "}} = \\dfrac{" + decimaux(num1) + "}{" + decimaux(vraippcm) + "} + \\dfrac{" + decimaux(num2) + "}{" + decimaux(vraippcm) + "} = \\dfrac{" + decimaux(num1 + num2) + simpl + "}{" + decimaux(vraippcm) + simpl + "}" + result + ".$") exo.append("\\end{enumerate}") cor.append("\\end{enumerate}") return (exo, cor)
def exprfonc(f, i, A, B): # Génère la 3e question. # A est sur l'axe des ordonnées, f est le nom de la fonction u = coefdir(A, B) if isinstance(u, int): u = Fraction(u, 1) Polynome([[u, 1], [A[1], 0]], "x")(B[0]) #=========================================================================== # if A[1] >= 0: # b = '+' + decimaux(str(A[1])) # else: # b = decimaux(str(A[1])) # if u.d == 1: # coef = decimaux(str(u.n)) # if u.n == -1: # coef = '-' # utilisé dans l'expression de la fonction # if u.n == 1: # coef = '' # coefres = decimaux(str(u.n)) # résultat utilisé pour a # else: # if u.n > 0: # coef = '\\dfrac{' + decimaux(str(u.n)) + '}{' + decimaux(str(u.d)) + '}' # else: # coef = '-\\dfrac{' + decimaux(str(abs(u.n))) + '}{' + decimaux(str(u.d)) + '}' # coefres = coef #=========================================================================== if A[1] - B[1] > 0: deltay = '+' + decimaux(str(A[1] - B[1])) else: deltay = decimaux(str(A[1] - B[1])) if A[0] - B[0] > 0: deltax = '+' + decimaux(str(A[0] - B[0])) else: deltax = decimaux(str(A[0] - B[0])) if float(B[0]) < 0: mid11 = float(B[0]) - 0.75 mid12 = float((B[1] + A[1])) / 2 # milieu de la flèche verticale else: mid11 = float(B[0]) + 0.75 mid12 = float((B[1] + A[1])) / 2 if float(B[0]) * float(u.d / u.n) > 0: mid21 = float((A[0] + B[0])) / 2 mid22 = A[1] - 0.6 # milieu de la flèche horizontale else: mid21 = float((A[0] + B[0])) / 2 mid22 = A[1] + 0.5 if mid12 < 0 and mid12 > -0.8: mid12 = -1 if mid12 >= 0 and mid12 < 0.5: mid12 = 0.5 if mid11 < 0 and mid11 > -0.8: mid11 = -1 if mid11 >= 0 and mid11 < 0.5: mid11 = 0.5 if mid21 < 0 and mid21 > -0.8: mid21 = -1 if mid21 >= 0 and mid21 < 0.5: mid21 = 0.5 if mid22 < 0 and mid22 > -0.8: mid22 = -1 if mid22 >= 0 and mid22 < 0.5: mid22 = 0.5 mid1 = (mid11, mid12) mid2 = (mid21, mid22) l = [ u'Déterminer l\'expression de la fonction $' + f + u'$ représentée ci-contre par la droite ($d_' + str(i) + '$).', u'On lit l\'ordonnée à l\'origine et le coefficient de la fonction affine sur le graphique.\\\ ', '$' + f + '(x)=a\\,x+b$ ' + 'avec $b=' + decimaux(str(A[1])) + '$ et $a=' + '\\dfrac{' + deltay + '}{' + deltax + '}=' + str(u) + '$.\\\ ', 'L\'expression de la fonction $' + f + '$ est $' + f + '(x)=' + str(Polynome([[u, 1], [A[1], 0]], "x")) + '$.', doublefleche(B, (B[0], A[1])), doublefleche((B[0], A[1]), A), '\\rput' + str(mid1) + '{(' + deltay + ')}', '\\rput' + str(mid2) + '{(' + deltax + ')}' ] return l
def affiche_coord(coord): """Affiche les coordonnées des points au format LaTeX""" return '\\hbox{$(' + decimaux(str(coord[0]), 1) + '~;~' + \ decimaux(str(coord[1]), 1) + ')$}'
def tex_statement(self): exo = [r'\exercice'] exo.append(r'\begin{enumerate}') 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}')) exo.append(r'\begin{multicols}{2}') exo.append(r'\begin{enumerate}') exo.append(r'\item Pour $x \in [%s~;~%s],\quad f\,(x) %s \ldots{}$' % (self.lX[0], self.lX[-1], self.inegalites[0])) exo.append(r'\item Pour $x \in [%s~;~%s],\quad f\,(x) %s \ldots{}$' % (self.lX[0], self.lX[-1], self.inegalites[1])) 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])) exo.append(r'\end{enumerate}') exo.append(r'\end{multicols}') exo.append(u'\\item') exo.append(r'\begin{enumerate}') exo.append(_(u'\\item Donner un encadrement de la fonction $f$ sur l’intervalle $[%s~;~%s]$.') % (self.lX[0], self.lX[-1])) 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))) exo.append(r'\end{enumerate}') exo.append(r'\end{enumerate}') exo.append(r'\begin{center}') variations = list(self.variations) lY = list(self.lY) exo.append(r'\begin{tikzpicture}[scale=1]') 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])]))) ans = r'\tkzTabVar{' # %-/$-2$,+/$5$,-/$-3$,+/$-1$,-/$-4$}' trois_niv = False for index in range(len(variations)): yindex = variations[index][1] - self.lX[0] if variations[index][0] == 1: if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex] trois_niv = False else: ans += r'-/$%s$,' % lY[yindex] if variations[index][0] == -1: if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex] trois_niv = False else: ans += r'+/$%s$,' % lY[yindex] if variations[index][0] == 0: if index > 0 and index < len(variations) - 1 and variations[index - 1][0] * variations[index + 1][0] > 0: trois_niv = True if trois_niv: ans += r'+/ \raisebox{-2.7cm}{}\raisebox{-1.5cm}{$%s$},' % lY[yindex] elif index > 0: if variations[index - 1][0] == 1: ans += r'+/$%s$,' % lY[yindex] else: ans += r'-/$%s$,' % lY[yindex] elif index < len(variations) - 1: if variations[index + 1][0] == 1: ans += r'-/$%s$,' % lY[yindex] else: ans += r'+/$%s$,' % lY[yindex] if variations[-1][0] == 1: ans += r'+/$%s$}' % lY[-1] elif variations[-1][0] == -1: ans += r'-/$%s$}' % lY[-1] elif variations[-1][0] == 0: if variations[-2][0] == 1: ans += r'+/$%s$}' % lY[-1] elif variations[-2][0] == -1: ans += r'-/$%s$}' % lY[-1] exo.append(ans) # Place les zéros for absc in range(self.lX[0], self.lX[-1] + 1): if lY[absc - self.lX[0]] == 0: for index in range(len(variations)): if variations[index][1] < absc < variations[index][2]: if variations[index][0] != 0: exo.append(r'\tkzTabVal{%s}{%s}{0.5}{\scriptsize $%s$}{$0$}' % (index + 1, index + 2, absc)) break if variations[index][1] == absc or variations[index][2] == absc: break exo.append(r'\end{tikzpicture}') exo.append(r'\end{center}') return exo
def main(): nbpts = 13 noms_pts = (noms_sommets(nbpts)) coord_pts = coordo_pts(nbpts) voc = ['abscisse', u'ordonnée'] rg1 = random.randrange(0, 2) rg2 = abs(rg1 - 1) while len(coord_pts) < nbpts: coord_pts = coordo_pts(nbpts) exo = ["\\exercice", "\\parbox{0.4\\linewidth}{", "\\begin{enumerate}", u"\\item Donner les coordonnées des points %s, %s, %s, %s, %s et %s." % tuple(noms_pts[0:6]), u"\\item Placer dans le repère les points %s, %s, %s, %s, %s et %s" % noms_pts[6:12] + u" de coordonnées respectives %s, %s, %s, %s, %s et %s. " % tuple(tex_liste_co(coord_pts[6:12])), u"\\item Placer dans le repère le point %s d'%s %s et d'%s %s" % (noms_pts[12], voc[rg1], decimaux(str(coord_pts[12][rg1])), voc[rg2], decimaux(str(coord_pts[12][rg2]))), "\\end{enumerate}}\\hfill ", "\\parbox{0.55\\linewidth}{", "\\psset{unit=0.8cm}", "\\begin{pspicture}(-4.95,-4.95)(4.95,4.95)", "\\psgrid[subgriddiv=2, subgridcolor=lightgray, gridlabels=8pt](0,0)(-5,-5)(5,5)", "\\psline[linewidth=1.2pt]{->}(-5,0)(5,0)", "\\psline[linewidth=1.2pt]{->}(0,-5)(0,5)", place_points(coord_pts[0:6], noms_pts[0:6]), "\\end{pspicture}}"] cor = ["\\exercice*", "\\parbox{0.4\\linewidth}{", "\\psset{unit=0.8cm}", "\\begin{pspicture}(-5,-5)(5,5)", "\\psgrid[subgriddiv=2, subgridcolor=lightgray, gridlabels=8pt](0,0)(-5,-5)(5,5)", "\\psline[linewidth=1.2pt]{->}(-5,0)(5,0)", "\\psline[linewidth=1.2pt]{->}(0,-5)(0,5)", place_points(coord_pts[0:13], noms_pts[0:13]), "\\end{pspicture}}\\hfill", "\\parbox{0.5\\linewidth}{", "\\begin{enumerate}", u"\\item Donner les coordonnées des points %s, %s, %s, %s, %s et %s." % tuple(noms_pts[0:6])] i = 0 while i < 6: cor.append(u"Les coordonnées du point %s sont %s \n" % (noms_pts[i], affiche_coord(coord_pts[i]))) i = i + 1 cor[len(cor):len(cor)] = [u"\\item Placer dans le repère les points %s, %s, %s, %s, %s et %s" % noms_pts[6:12] + u" de coordonnées respectives %s, %s, %s, %s, %s et %s. " % tuple(tex_liste_co(coord_pts[6:12])), u"\\item Placer dans le repère le point %s d'%s %s et d'%s %s" % (noms_pts[12], voc[rg1], decimaux(str(coord_pts[12][rg1])), voc[rg2], decimaux(str(coord_pts[12][rg2]))), "\\end{enumerate}"] cor.append("}") return(exo, cor)
def exprfonc(f, i, A, B): # Génère la 3e question. # A est sur l'axe des ordonnées, f est le nom de la fonction u = coefdir(A, B) if isinstance(u, int): u = Fraction(u, 1) Polynome([[u, 1], [A[1], 0]], "x")(B[0]) #=========================================================================== # if A[1] >= 0: # b = '+' + decimaux(str(A[1])) # else: # b = decimaux(str(A[1])) # if u.d == 1: # coef = decimaux(str(u.n)) # if u.n == -1: # coef = '-' # utilisé dans l'expression de la fonction # if u.n == 1: # coef = '' # coefres = decimaux(str(u.n)) # résultat utilisé pour a # else: # if u.n > 0: # coef = '\\dfrac{' + decimaux(str(u.n)) + '}{' + decimaux(str(u.d)) + '}' # else: # coef = '-\\dfrac{' + decimaux(str(abs(u.n))) + '}{' + decimaux(str(u.d)) + '}' # coefres = coef #=========================================================================== if A[1] - B[1] > 0: deltay = '+' + decimaux(str(A[1] - B[1])) else : deltay = decimaux(str(A[1] - B[1])) if A[0] - B[0] > 0: deltax = '+' + decimaux(str(A[0] - B[0])) else: deltax = decimaux(str(A[0] - B[0])) if float(B[0]) < 0 : mid11 = float(B[0]) - 0.75 mid12 = float((B[1] + A[1])) / 2 # milieu de la flèche verticale else: mid11 = float(B[0]) + 0.75 mid12 = float((B[1] + A[1])) / 2 if float(B[0]) * float(u.d / u.n) > 0 : mid21 = float((A[0] + B[0])) / 2 mid22 = A[1] - 0.6 # milieu de la flèche horizontale else : mid21 = float((A[0] + B[0])) / 2 mid22 = A[1] + 0.5 if mid12 < 0 and mid12 > -0.8: mid12 = -1 if mid12 >= 0 and mid12 < 0.5: mid12 = 0.5 if mid11 < 0 and mid11 > -0.8: mid11 = -1 if mid11 >= 0 and mid11 < 0.5: mid11 = 0.5 if mid21 < 0 and mid21 > -0.8: mid21 = -1 if mid21 >= 0 and mid21 < 0.5: mid21 = 0.5 if mid22 < 0 and mid22 > -0.8: mid22 = -1 if mid22 >= 0 and mid22 < 0.5: mid22 = 0.5 mid1 = (mid11, mid12) mid2 = (mid21, mid22) l = [u'Déterminer l\'expression de la fonction $' + f + u'$ représentée ci-contre par la droite ($d_' + str(i) + '$).', u'On lit l\'ordonnée à l\'origine et le coefficient de la fonction affine sur le graphique.\\\ ', '$' + f + '(x)=a\\,x+b$ ' + 'avec $b=' + decimaux(str(A[1])) + '$ et $a=' + '\\dfrac{' + deltay + '}{' + deltax + '}=' + str(u) + '$.\\\ ', 'L\'expression de la fonction $' + f + '$ est $' + f + '(x)=' + str(Polynome([[u, 1], [A[1], 0]], "x")) + '$.', doublefleche(B, (B[0], A[1])), doublefleche((B[0], A[1]), A), '\\rput' + str(mid1) + '{(' + deltay + ')}', '\\rput' + str(mid2) + '{(' + deltax + ')}'] return l