Compare commits

..

2 Commits

Author SHA1 Message Date
03024beac3 Feat: add drone tests
Some checks failed
continuous-integration/drone/push Build is failing
2020-08-20 15:36:39 +02:00
c2d667ee2f Feat: import snippets and create first tests 2020-08-20 15:35:33 +02:00
7 changed files with 462 additions and 0 deletions

9
.drone.yml Normal file
View File

@ -0,0 +1,9 @@
kind: pipeline
name: default
steps:
- name: testing
image: python
commands:
- pip install bopytex
- python test_no_compile.py

Binary file not shown.

View File

@ -0,0 +1,121 @@
% vim:ft=tex:
%
\documentclass[12pt]{article}
\usepackage[utf8x]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{graphicx}
\title{%
Snippets pour Opytex \\
Pythagore et Thalès
}
\author{%
Benjamin Bertrand
}
\begin{document}
\maketitle
\section{Pythagore}
\section{Thalès}
\section{Mélange des 2}
\subsection{Longueur du parcours}
% exo de geometrie comme au brevet blanc.
%- set AD, AC, DC = random_pythagore()
%- set tourACDA = AC+AD+DC
%- set AE, AF = round(tourACDA/2*random(), 1), round(tourACDA/2*random(), 1)
%- set EF = round(tourACDA - AE - AF - randint(20,40)*0.2, 1)
%- set tourAEFA = round(AE+EF+AF, 1)
%- set rapport = randint(2,5)
%- set AE1, AF1, EF1 = round(AE/rapport,2) , round(AF/rapport,2), round(EF/rapport,2)
%- set objectif = randint(floor(tourAEFA), tourACDA)
%- if objectif > 100
%- set unit = "m"
%- else
%- set unit = "km"
%- endif
Une commune souhaite aménager des parcours de santé sur son territoire. On fait deux propositions au conseil municipale, schématisés ci-dessous:
\begin{itemize}
\item Le parcours ACDA
\item Le parcours AEFA
\end{itemize}
Ils souhaitent faire un parcours dont la longueur s'approche le plus possible de \Var{objectif}\Var{unit}.
Peux-tu les aider à choisir le parcours? Justifie
\textbf{Attention: La figure proposée au conseil municipale n'est pas à l'échelle, mais les codages et les dimension données sont correctes.}
\begin{minipage}{0.6\textwidth}
\includegraphics[scale = 0.4]{./fig/parcours}
\end{minipage}
\begin{minipage}{0.4\textwidth}
\begin{itemize}
\item $AC = \Var{AC}\Var{unit}$
\item $CD = \Var{DC}\Var{unit}$
\item $AE' = \Var{AE1}\Var{unit}$
\item $AE = \Var{AE}\Var{unit}$
\item $AF = \Var{AF}\Var{unit}$
\item $E'F' = \Var{EF1}\Var{unit}$
\item $(E'F') // (EF)$
\item L'angle $\widehat{EAF}$ vaut $30^o$
\end{itemize}
\end{minipage}
\begin{solution}
\begin{itemize}
\item Parcours ACDA:
D'après la figure, on voit que le triangle $ACD$ est rectangle en $C$ donc d'après le théorème de Pythagore, on a
\begin{align*}
AD^2 &= AC^2 + DC^2 \\
AD^2 &= \Var{AC}^2 + \Var{DC}^2 \\
AD^2 &= \Var{AC**2} + \Var{DC**2} \\
AD^2 &= \Var{AC**2 + DC**2} \\
AD &= \sqrt{\Var{AC**2 + DC**2}} = \Var{AD}\Var{unit}
\end{align*}
Donc le parcours ACDA mesure
\begin{align*}
AD + AC + CD = \Var{AD} + \Var{AC} + \Var{DC} = \Var{tourACDA}\Var{unit}
\end{align*}
\item Parcours AEFA:
D'après les données, on sait que $(EF) // (E'F')$. On voit aussi que $A$, $E'$ et $E$ sont alignés. Il en est de même pour les points $A$, $F'$ et $F$. Donc d'après le théorème de Thalès
\begin{tabular}{|c|c|c|c|}
\hline
Triangle AEF & AE = \Var{AE} & AF = \Var{AF} & EF \\
\hline
Triangle AE'F' & AE' = \Var{AE1} & AF' & E'F' = \Var{EF1} \\
\hline
\end{tabular}
est un tableau de proportionnalité. Donc on peut faire un produit en croix pour calcul $EF$.
\begin{align*}
EF = \frac{E'F' \times AE}{AE'} = \frac{\Var{EF1} \times \Var{AE}}{\Var{AE1}} = \Var{EF} \Var{unit}
\end{align*}
Donc le parcours AEFA mesure
\begin{align*}
AF + AE + EF = \Var{AF} + \Var{AE} + \Var{EF} = \Var{tourAEFA}\Var{unit}
\end{align*}
\item Choix du parcours:
%- if abs(tourACDA - objectif) < abs(tourAEFA - objectif)
Il faudra choisir le tour $ACDA$ car sa longueur est plus proche de \Var{objectif}\Var{unit}.
%- else
Il faudra choisir le tour $AFEA$ car sa longueur est plus proche de \Var{objectif}\Var{unit}.
%- endif
\end{itemize}
\end{solution}
\end{document}

View File

@ -0,0 +1,96 @@
% vim:ft=tex:
%
\documentclass[12pt]{article}
\usepackage[utf8x]{inputenc}
\usepackage[francais]{babel}
\usepackage[T1]{fontenc}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{amsfonts}
\title{
Snippets pour Opytex \\
Fonctions
}
\author{
Benjamin Bertrand
}
\begin{document}
\maketitle
\section{Calculer des images}
\begin{enumerate}
%-set f = Expression.random("{a}*x^2 + {b}*x + {c}")
\item $\forall x \in \mathbb{R} \qquad f(x) = \Var{f}$
Solution:
\begin{align*}
f(0) &= \Var{f(0).explain() | join('=')} \\
f(1) &= \Var{f(1).explain() | join('=')} \\
f(2) &= \Var{f(2).explain() | join('=')} \\
f({10}) &= \Var{f(10).explain() | join('=')} \\
f({100}) &= \Var{f(100).explain() | join('=')}
\end{align*}
\end{enumerate}
\section{Résolution d'équation du 2nd degré}
%- macro solveEquation(P)
On commence par calculer le discriminant de $P(x) = \Var{P}$.
\begin{eqnarray*}
\Delta & = & b^2-4ac \\
\Var{P.delta.explain()|calculus(name="\\Delta")}
\end{eqnarray*}
\Block{if P.delta > 0}
comme $\Delta = \Var{P.delta} > 0$ donc $P$ a deux racines
\begin{eqnarray*}
x_1 & = & \frac{-b - \sqrt{\Delta}}{2a} = \frac{\Var{-P.b} - \sqrt{\Var{P.delta}}}{2 \times \Var{P.a}} = \Var{P.roots[0] } \\
x_2 & = & \frac{-b + \sqrt{\Delta}}{2a} = \frac{\Var{-P.b} + \sqrt{\Var{P.delta}}}{2 \times \Var{P.a}} = \Var{P.roots[1] }
\end{eqnarray*}
Les solutions de l'équation $\Var{P} = 0$ sont donc $\mathcal{S} = \left\{ \Var{P.roots[0]}; \Var{P.roots[1]} \right\}$
\Block{elif P.delta == 0}
Comme $\Delta = 0$ donc $P$ a une racine
\begin{eqnarray*}
x_1 = \frac{-b}{2a} = \frac{-\Var{P.b}}{2\times \Var{P.a}} = \Var{P.roots[0]} \\
\end{eqnarray*}
La solution de $\Var{P} = 0$ est donc $\mathcal{S} = \left\{ \Var{P.roots[0]}\right\}$
\Block{else}
Alors $\Delta = \Var{P.delta} < 0$ donc $P$ n'a pas de racine donc l'équation $\Var{P} = 0$ n'a pas de solution.
\Block{endif}
%- endmacro
\begin{enumerate}
%-set P = Expression.random("{a}*x^2 + {b}*x + {c}", ["b**2-4*a*c>0"])
\item Étude du polynôme $P$, $\forall x \in \mathbb{R} \quad P(x) = \Var{P}$
Solution:
\Var{solveEquation(P)}
%-set P = Expression.random("{a}*x^2 + {b}*x + {c}", ["b**2-4*a*c==0"])
\item Étude du polynôme $P$, $\forall x \in \mathbb{R} \quad P(x) = \Var{P}$
Solution:
\Var{solveEquation(P)}
%-set P = Expression.random("{a}*x^2 + {b}*x + {c}", ["b**2-4*a*c<0"])
\item Étude du polynôme $P$, $\forall x \in \mathbb{R} \quad P(x) = \Var{P}$
Solution:
\Var{solveEquation(P)}
\end{enumerate}
\end{document}

133
snippets/tpl_fraction.tex Normal file
View File

@ -0,0 +1,133 @@
% vim:ft=tex:
%
\documentclass[12pt]{article}
\usepackage[utf8x]{inputenc}
\usepackage[francais]{babel}
\usepackage[T1]{fontenc}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{amsfonts}
\title{
Snippets pour Opytex \\
Fractions
}
\author{
Benjamin Bertrand
}
\begin{document}
\maketitle
\section{Simplifications de fractions}
\begin{itemize}
\item Trouver le numérateur quand le dénominateur augmente
\Block{set a,b,ans,c = random_str("{a},{b},{a*c},{b*c}", conditions = ["{a} != {b}"], val_min = 2, val_max = 10).split(',')}%
\begin{align*}
\dfrac{\Var{a}}{\Var{b}} = \dfrac{\ldots}{\Var{c}}
\end{align*}
Solution
\begin{align*}
\dfrac{\Var{a}}{\Var{b}} = \dfrac{\Var{ans}}{\Var{c}}
\end{align*}
\item Trouver le numérateur quand le dénominateur diminue
\Block{set a,b,ans,c = random_str("{a*c},{b*c},{a},{b}", conditions = ["{a} != {b}"], val_min = 2, val_max = 10).split(',')}%
\begin{align*}
\dfrac{\Var{a}}{\Var{b}} = \dfrac{\cdots}{\Var{c}}
\end{align*}
Solution
\begin{align*}
\dfrac{\Var{a}}{\Var{b}} = \dfrac{\Var{ans}}{\Var{c}}
\end{align*}
Explications
\Block{set f = Expression(a + "/" +b)}
\begin{align*}
\Var{f.simplify().explain()|join('=')}
\end{align*}
\end{itemize}
\section{Ajouts de fractions}
\begin{itemize}
\item Fraction avec le même dénominateur
\Block{set e = Expression.random("{a} / {b} + {c} / {b}", ["{b} > 1"], val_min = 1)}
\begin{align*}
A = \Var{e}
\end{align*}
Solution
\begin{align*}
\Var{e.simplify().explain() | join('=')}
\end{align*}
\item Fraction avec un denominateur multiple de l'autre
\Block{set e = Expression.random("{a} / {b} + {c} / {b*d}", ["{b} > 1","{d} > 1"], val_min = 1)}
\begin{align*}
A = \Var{e}
\end{align*}
Solution
\begin{align*}
\Var{e.simplify().explain() | join('=')}
\end{align*}
\item Fraction avec des dénominateurs premiers entre eux
\Block{set e = Expression.random("{a} / {b} + {c} / {d}", ["{b} > 1","{d} > 1", "gcd({b},{d}) == 1"], val_min = 1)}
\begin{align*}
A = \Var{e}
\end{align*}
Solution
\begin{align*}
\Var{e.simplify().explain() | join('=')}
\end{align*}
\item Une fraction et un entier
\Block{set e = Expression.random("{a} / {b} + {c}", ["{b} > 1"], val_min = 1)}
\begin{align*}
A = \Var{e}
\end{align*}
Solution
\begin{align*}
\Var{e.simplify().explain() | join('=')}
\end{align*}
\item Une fraction et un entier
\Block{set e = Expression.random("{c} + {a} / {b}", ["{b} > 1"], val_min = 1)}
\begin{align*}
A = \Var{e}
\end{align*}
Solution
\begin{align*}
\Var{e.simplify().explain() | join('=')}
\end{align*}
\end{itemize}
\section{Multiplications de fractions}
\begin{itemize}
\item Une fraction et un entier
\Block{set e = Expression.random("{c} * {a} / {b}", ["{b} > 1"], val_min = 1)}
\begin{align*}
A = \Var{e}
\end{align*}
Solution
\begin{align*}
\Var{e.simplify().explain() | join('=')}
\end{align*}
\item Fraction avec des dénominateurs quelconques
\Block{set e = Expression.random("{a} / {b} * {c} / {d}", ["{b} > 1","{d} > 1"], val_min = 1)}
\begin{align*}
A = \Var{e}
\end{align*}
Solution
\begin{align*}
\Var{e.simplify().explain() | join('=')}
\end{align*}
\end{itemize}
\end{document}

87
snippets/tpl_suite.tex Normal file
View File

@ -0,0 +1,87 @@
% vim:ft=tex:
%
\documentclass[12pt]{article}
\usepackage[utf8x]{inputenc}
\usepackage[francais]{babel}
\usepackage[T1]{fontenc}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{amsfonts}
\title{
Snippets pour Opytex \\
Suites
}
\author{
Benjamin Bertrand
}
\begin{document}
\maketitle
\section{Calculs de termes}
\begin{enumerate}
\item Calculer les termes $u_0$, $u_1$, $u_2$, $u_{10}$ et $u_{100}$ pour les suites suivantes
\begin{enumerate}
%-set u = Expression.random("{a}*n+{b}")
\item $\forall n \in \mathbb{N} \qquad u_n = \Var{u}$
Solution:
\begin{align*}
u_0 &= \Var{u(0).explain() | join('=')} \\
u_1 &= \Var{u(1).explain() | join('=')} \\
u_2 &= \Var{u(2).explain() | join('=')} \\
u_{10} &= \Var{u(10).explain() | join('=')} \\
u_{100} &= \Var{u(100).explain() | join('=')}
\end{align*}
%-set v = Expression.random("({a}*n+{b})/{c}", ["c>1"])
\item $\forall n \in \mathbb{N} \qquad v_n = \Var{v|replace("frac","dfrac")}$
Solution:
\begin{align*}
v_0 &= \Var{v(0).explain() | join('=')} \\
v_1 &= \Var{v(1).explain() | join('=')} \\
v_2 &= \Var{v(2).explain() | join('=')} \\
v_{10} &= \Var{v(10).explain() | join('=')} \\
v_{100} &= \Var{v(100).explain() | join('=')}
\end{align*}
%-set v = Expression.random("({a}*n+{b})/{c}", ["c>1"])
\item $\forall n \in \mathbb{N} \qquad v_n = \Var{v}$
Solution:
\begin{align*}
%- for j in [0, 1, 2, 10, 100]
v_{\Var{j}} &= \Var{v(j).explain() | join('=')} \\
%- endfor
\end{align*}
%-set f = Expression.random("{a}*x")
%-set v0 = randint(0, 10)
\item $\forall n \in \mathbb{N} \qquad v_{n+1} = \Var{f("v_n")} \mbox{ et } v_0 = \Var{v0}$
Solution:
\begin{align*}
v_0 &= \Var{v0} \\
%-set v = f(v0)
v_1 &= \Var{v.explain() | join('=')} \\
%-set v = f(v)
v_2 &= \Var{v.explain() | join('=')} \\
\end{align*}
Pour le terme 10, il faut calculer tous les autres avant!
\begin{align*}
%#- Trick to move around scoping rules
%#- https://stackoverflow.com/a/49699589
%- set v = namespace(val = v)
%- for i in range(8)
%- set v.val = f(v.val)
v_{\Var{i+3}} &= \Var{v.val.explain() | join('=')} \\
%- endfor
\end{align*}
\end{enumerate}
\end{enumerate}
\end{document}

16
test_no_compile.py Normal file
View File

@ -0,0 +1,16 @@
from pathlib import Path
import os
import shutil
SNIPPETS_DIR = "./snippets"
OUTPUT = "./output"
if __name__ == "__main__":
output = Path(OUTPUT)
shutil.rmtree(output)
output.mkdir()
snippets_dir = Path(SNIPPETS_DIR)
for snippet in snippets_dir.rglob("tpl_*.tex"):
print(snippet)
assert os.system(f"bopytex -n {snippet}") == 0