math-exercises 3.0.74 → 3.0.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/exercises/math/calcul/arithmetics/isInequalityTrue.js +2 -2
- package/lib/exercises/math/calcul/operations/operationsPrioritiesParenthesis.js +1 -1
- package/lib/exercises/math/calculLitteral/inequations/squareFunctionInequation.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/inequations/squareFunctionInequation.js +15 -0
- package/lib/exercises/math/functions/affines/leadingCoefficientCalculV1.d.ts.map +1 -1
- package/lib/exercises/math/functions/affines/leadingCoefficientCalculV1.js +52 -0
- package/lib/exercises/math/functions/basics/inverseImageFunctionGeogebra.d.ts.map +1 -1
- package/lib/exercises/math/functions/basics/inverseImageFunctionGeogebra.js +24 -0
- package/lib/exercises/math/functions/parity/parityFromAlgebra.d.ts.map +1 -1
- package/lib/exercises/math/functions/parity/parityFromAlgebra.js +57 -2
- package/lib/exercises/math/geometry/euclidian/pythagoreOrThales.js +34 -31
- package/lib/exercises/math/geometry/thales/thalesCalcul.d.ts.map +1 -1
- package/lib/exercises/math/geometry/thales/thalesCalcul.js +79 -8
- package/lib/exercises/math/geometry/vectors/paralellismViaColinearity.d.ts.map +1 -1
- package/lib/exercises/math/geometry/vectors/paralellismViaColinearity.js +39 -1
- package/lib/exercises/math/geometry/vectors/parallelogramViaEqualVectors.d.ts.map +1 -1
- package/lib/exercises/math/geometry/vectors/parallelogramViaEqualVectors.js +32 -1
- package/lib/exercises/math/geometry/vectors/vectorLinearCombination.d.ts.map +1 -1
- package/lib/exercises/math/geometry/vectors/vectorLinearCombination.js +40 -2
- package/lib/exercises/math/probaStat/stats1var/choseReasoningForIndicator.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/choseReasoningForIndicator.js +17 -10
- package/lib/exercises/math/probaStat/stats1var/median.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/median.js +35 -0
- package/lib/exercises/math/probaStat/stats1var/medianList.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/medianList.js +18 -0
- package/lib/exercises/math/probaStat/stats1var/quartiles.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/quartiles.js +37 -0
- package/lib/exercises/math/probaStat/stats1var/quartilesList.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/quartilesList.js +23 -0
- package/package.json +1 -1
|
@@ -37,10 +37,10 @@ $$
|
|
|
37
37
|
${leftNode.toTex()} ${inequalitySign ? "<" : ">"} ${rightNode.toTex()}
|
|
38
38
|
$$
|
|
39
39
|
|
|
40
|
-
Cette inéquation est-elle vraie pour
|
|
40
|
+
Cette inéquation est-elle vraie pour $x = ${x}$ ?`;
|
|
41
41
|
};
|
|
42
42
|
const getHint = (identifiers) => {
|
|
43
|
-
return `
|
|
43
|
+
return `Remplace $x$ par $${identifiers.x}$ dans les deux membres. Ensuite, vérifie si l'inégalité est vraie ou non.`;
|
|
44
44
|
};
|
|
45
45
|
const reverseSign = (sign) => {
|
|
46
46
|
let x = "";
|
|
@@ -86,7 +86,7 @@ const getOperationsPrioritiesParenthesisQuestion = () => {
|
|
|
86
86
|
const isAdd2 = coinFlip();
|
|
87
87
|
statement = new (isAdd ? AddNode : SubstractNode)(a.toTree(), new (isAdd2 ? AddNode : SubstractNode)(b.toTree(), new (isDivide ? DivideNode : MultiplyNode)(c.toTree(), d.toTree(), {
|
|
88
88
|
forceTimesSign: true,
|
|
89
|
-
}), { forceParenthesis:
|
|
89
|
+
}), { forceParenthesis: true }));
|
|
90
90
|
break;
|
|
91
91
|
}
|
|
92
92
|
const identifiers = { nodeIds: statement.toIdentifiers(), type };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"squareFunctionInequation.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calculLitteral/inequations/squareFunctionInequation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"squareFunctionInequation.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calculLitteral/inequations/squareFunctionInequation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,gBAAgB,EAGjB,MAAM,sCAAsC,CAAC;AAa9C,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,CAAC;AA6GF,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,WAAW,CAa1D,CAAC"}
|
|
@@ -30,6 +30,19 @@ $$
|
|
|
30
30
|
x^2 ${inequationSymbol} ${k}
|
|
31
31
|
$$`;
|
|
32
32
|
};
|
|
33
|
+
// const getHint: GetHint<Identifiers> = (identifiers) => {
|
|
34
|
+
// return ``;
|
|
35
|
+
// };
|
|
36
|
+
// const getCorrection: GetCorrection<Identifiers> = (identifiers) => {
|
|
37
|
+
// const { k, inequationSymbol } = identifiers;
|
|
38
|
+
// return `On applique la fonction racine carrée à l'inégalité :
|
|
39
|
+
// ${alignTex([
|
|
40
|
+
// ["x^2", inequationSymbol, k.frenchify()],
|
|
41
|
+
// ["\\sqrt{x^2}", inequationSymbol, sqrt(k).toTex()],
|
|
42
|
+
// ["|x|", inequationSymbol, sqrt(k).simplify().toTex()],
|
|
43
|
+
// ])}
|
|
44
|
+
// `;
|
|
45
|
+
// };
|
|
33
46
|
const getSquareFunctionInequationQuestion = () => {
|
|
34
47
|
const k = coinFlip() ? randint(1, 11) ** 2 : randint(1, 100);
|
|
35
48
|
const inequationSymbol = InequationSymbolConstructor.random();
|
|
@@ -43,6 +56,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
43
56
|
keys: ["S", "equal", "lbracket", "rbracket", "semicolon", "infty", "cup"],
|
|
44
57
|
answerFormat: "tex",
|
|
45
58
|
identifiers,
|
|
59
|
+
// hint: getHint(identifiers),
|
|
60
|
+
// correction: getCorrection(identifiers),
|
|
46
61
|
};
|
|
47
62
|
return question;
|
|
48
63
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leadingCoefficientCalculV1.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/affines/leadingCoefficientCalculV1.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"leadingCoefficientCalculV1.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/affines/leadingCoefficientCalculV1.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAgBT,MAAM,6BAA6B,CAAC;AASrC,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAuKF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,WAAW,CAe5D,CAAC"}
|
|
@@ -3,6 +3,8 @@ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQue
|
|
|
3
3
|
import { rationalVEA } from "../../../../exercises/vea/rationalVEA.js";
|
|
4
4
|
import { Rational } from "../../../../math/numbers/rationals/rational.js";
|
|
5
5
|
import { randint } from "../../../../math/utils/random/randint.js";
|
|
6
|
+
import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
|
|
7
|
+
import { substract } from "../../../../tree/nodes/operators/substractNode.js";
|
|
6
8
|
import { shuffle } from "../../../../utils/alea/shuffle.js";
|
|
7
9
|
const getInstruction = (identifiers, opts) => {
|
|
8
10
|
const { xA, yA, xB, yB } = identifiers;
|
|
@@ -42,6 +44,53 @@ const getLeadingCoefficientCalculV1Question = (opts) => {
|
|
|
42
44
|
const identifiers = { xA, xB, yA, yB };
|
|
43
45
|
return getQuestionFromIdentifiers(identifiers, opts);
|
|
44
46
|
};
|
|
47
|
+
const getHint = (identifiers, opts) => {
|
|
48
|
+
const { xA, yA, xB, yB } = identifiers;
|
|
49
|
+
const usePoints = opts?.usePoints;
|
|
50
|
+
const useLinear = opts?.useLinear;
|
|
51
|
+
if (useLinear) {
|
|
52
|
+
if (usePoints) {
|
|
53
|
+
return `Pour déterminer le coefficient directeur $a$ d'une fonction linéaire à partir d'un point $A(x_A; y_A)$ de sa droite représentative, on utilise la formule :
|
|
54
|
+
|
|
55
|
+
$$
|
|
56
|
+
a = \\frac{y_A}{x_A}
|
|
57
|
+
$$`;
|
|
58
|
+
}
|
|
59
|
+
return `Pour déterminer le coefficient directeur $a$ d'une fonction linéaire $f$ à partir d'une image $f(x)$, on utilise la formule :
|
|
60
|
+
|
|
61
|
+
$$
|
|
62
|
+
a = \\frac{f(x)}{x}
|
|
63
|
+
$$`;
|
|
64
|
+
}
|
|
65
|
+
if (usePoints)
|
|
66
|
+
return `Pour déterminer le coefficient directeur $a$ d'une fonction affine à partir de deux points $A(x_A; y_A)$ et $B(x_B;y_B)$ de sa droite représentative, on utilise la formule :
|
|
67
|
+
|
|
68
|
+
$$
|
|
69
|
+
a = \\frac{y_B-y_A}{x_B-x_A}
|
|
70
|
+
$$`;
|
|
71
|
+
return `Pour déterminer le coefficient directeur $a$ d'une fonction affine $f$ à partir de deux images $f(x_1)$ et $f(x_2)$, on utilise la formule :
|
|
72
|
+
|
|
73
|
+
$$
|
|
74
|
+
a = \\frac{f(x_2)-f(x_1)}{x_2-x_1}
|
|
75
|
+
$$`;
|
|
76
|
+
};
|
|
77
|
+
const getCorrection = (identifiers, opts) => {
|
|
78
|
+
const { xA, yA, xB, yB } = identifiers;
|
|
79
|
+
const usePoints = opts?.usePoints;
|
|
80
|
+
const useLinear = opts?.useLinear;
|
|
81
|
+
if (useLinear) {
|
|
82
|
+
return `Le coefficient directeur $a$ est égal à :
|
|
83
|
+
|
|
84
|
+
$$
|
|
85
|
+
a = ${frac(yB, xB).toSimplificationTex()}
|
|
86
|
+
$$`;
|
|
87
|
+
}
|
|
88
|
+
return `Le coefficient directeur $a$ est égal à :
|
|
89
|
+
|
|
90
|
+
$$
|
|
91
|
+
a = ${frac(substract(yB, yA), substract(xB, xA)).toSimplificationTex()}
|
|
92
|
+
$$`;
|
|
93
|
+
};
|
|
45
94
|
const getQuestionFromIdentifiers = (identifiers, opts) => {
|
|
46
95
|
const question = {
|
|
47
96
|
instruction: getInstruction(identifiers, opts),
|
|
@@ -50,6 +99,8 @@ const getQuestionFromIdentifiers = (identifiers, opts) => {
|
|
|
50
99
|
answerFormat: "tex",
|
|
51
100
|
keys: [],
|
|
52
101
|
identifiers,
|
|
102
|
+
hint: getHint(identifiers, opts),
|
|
103
|
+
correction: getCorrection(identifiers, opts),
|
|
53
104
|
};
|
|
54
105
|
return question;
|
|
55
106
|
};
|
|
@@ -97,4 +148,5 @@ export const leadingCoefficientCalculV1 = {
|
|
|
97
148
|
subject: "Mathématiques",
|
|
98
149
|
options,
|
|
99
150
|
getQuestionFromIdentifiers,
|
|
151
|
+
hasHintAndCorrection: true,
|
|
100
152
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inverseImageFunctionGeogebra.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/basics/inverseImageFunctionGeogebra.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"inverseImageFunctionGeogebra.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/basics/inverseImageFunctionGeogebra.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAmBrC,KAAK,WAAW,GAAG;IAEjB,MAAM,EAAE,MAAM,CAAC;IAIf,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;CACpB,CAAC;AA6OF,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,WAAW,CAmB9D,CAAC"}
|
|
@@ -152,6 +152,27 @@ const getInverseImageFunctionGeogebra = () => {
|
|
|
152
152
|
};
|
|
153
153
|
return getQuestionFromIdentifiers(identifiers);
|
|
154
154
|
};
|
|
155
|
+
const getHint = (identifiers) => {
|
|
156
|
+
const { points, yValue } = identifiers;
|
|
157
|
+
return `Repère, s'il y en a, les points de la courbe qui ont pour ordonnée $${yValue}$. Les antécédents de $${yValue}$ sont alors les abscisses de ces points.`;
|
|
158
|
+
};
|
|
159
|
+
const getCorrection = (identifiers) => {
|
|
160
|
+
const { points, yValue } = identifiers;
|
|
161
|
+
const validPoints = points.filter((p) => p[1] === yValue);
|
|
162
|
+
const pts = validPoints.map((e) => new Point("A", e[0], e[1]));
|
|
163
|
+
if (!validPoints.length) {
|
|
164
|
+
return `Aucun point de la courbe n'a pour ordonnée $${yValue}$ : cela signifie que $${yValue}$ n'a pas d'antécédent par $f$.`;
|
|
165
|
+
}
|
|
166
|
+
return `On lit les points de la courbe qui ont pour ordonnée $${yValue}$ : ${validPoints.length === 1
|
|
167
|
+
? `il n'y a que le point de coordonnées $${pts[0].toCoords()}$`
|
|
168
|
+
: `ce sont les points de coordonnées $${pts[0].toCoords()}$ et $${pts[1].toCoords()}$`}.
|
|
169
|
+
|
|
170
|
+
Les antécédents par $f$ de $${yValue}$ sont donc :
|
|
171
|
+
|
|
172
|
+
$$
|
|
173
|
+
${getAnswer(identifiers)}
|
|
174
|
+
$$`;
|
|
175
|
+
};
|
|
155
176
|
const getQuestionFromIdentifiers = (identifiers) => {
|
|
156
177
|
const question = {
|
|
157
178
|
instruction: getInstruction(identifiers),
|
|
@@ -160,6 +181,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
160
181
|
ggbOptions: getGGBOptions(identifiers),
|
|
161
182
|
answerFormat: "tex",
|
|
162
183
|
identifiers,
|
|
184
|
+
hint: getHint(identifiers),
|
|
185
|
+
correction: getCorrection(identifiers),
|
|
163
186
|
};
|
|
164
187
|
return question;
|
|
165
188
|
};
|
|
@@ -218,4 +241,5 @@ export const inverseImageFunctionGeogebra = {
|
|
|
218
241
|
getGGBOptions,
|
|
219
242
|
getQuestionFromIdentifiers,
|
|
220
243
|
rebuildIdentifiers,
|
|
244
|
+
hasHintAndCorrection: true,
|
|
221
245
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parityFromAlgebra.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/parity/parityFromAlgebra.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"parityFromAlgebra.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/parity/parityFromAlgebra.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAerC,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAkLF,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,WAAW,CAcnD,CAAC"}
|
|
@@ -9,9 +9,18 @@ import { coinFlip } from "../../../../utils/alea/coinFlip.js";
|
|
|
9
9
|
import { doWhile } from "../../../../utils/doWhile.js";
|
|
10
10
|
import { probaFlip } from "../../../../utils/alea/probaFlip.js";
|
|
11
11
|
import { probaLawFlip } from "../../../../utils/alea/probaLawFlip.js";
|
|
12
|
+
import { parseAlgebraic } from "../../../../tree/parsers/latexParser.js";
|
|
13
|
+
import { opposite } from "../../../../tree/nodes/functions/oppositeNode.js";
|
|
14
|
+
import { alignTex } from "../../../../utils/latex/alignTex.js";
|
|
12
15
|
const getInstruction = (identifiers) => {
|
|
13
16
|
const fct = identifiers.fctTex;
|
|
14
|
-
return `Soit $f
|
|
17
|
+
return `Soit $f$ la fonction définie par :
|
|
18
|
+
|
|
19
|
+
$$
|
|
20
|
+
f(x) = ${fct}
|
|
21
|
+
$$
|
|
22
|
+
|
|
23
|
+
La fonction $f$ est-elle paire, impaire, ou ni paire ni impaire ?`;
|
|
15
24
|
};
|
|
16
25
|
const getAnswer = (identifiers) => {
|
|
17
26
|
const type = identifiers.type;
|
|
@@ -30,8 +39,10 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
30
39
|
answer: getAnswer(identifiers),
|
|
31
40
|
instruction: getInstruction(identifiers),
|
|
32
41
|
keys: [],
|
|
33
|
-
answerFormat: "
|
|
42
|
+
answerFormat: "raw",
|
|
34
43
|
identifiers,
|
|
44
|
+
hint: getHint(identifiers),
|
|
45
|
+
correction: getCorrection(identifiers),
|
|
35
46
|
};
|
|
36
47
|
return question;
|
|
37
48
|
};
|
|
@@ -104,6 +115,49 @@ const getParityFromAlgebraQuestion = () => {
|
|
|
104
115
|
const identifiers = { type, fctTex: fct };
|
|
105
116
|
return getQuestionFromIdentifiers(identifiers);
|
|
106
117
|
};
|
|
118
|
+
const getHint = (identifiers) => {
|
|
119
|
+
return `Une fonction $f$ est paire si pour tout $x$ de son ensemble de définition, on a : $f(-x) = f(x)$.
|
|
120
|
+
|
|
121
|
+
Une fonction $f$ est impaire si pour tout $x$ de son ensemble de définition, on a : $f(-x) = -f(x)$.`;
|
|
122
|
+
};
|
|
123
|
+
const getCorrection = (identifiers) => {
|
|
124
|
+
const type = identifiers.type;
|
|
125
|
+
const fct = parseAlgebraic(identifiers.fctTex);
|
|
126
|
+
const fctEv = fct.toDetailedEvaluation({ x: opposite("x") });
|
|
127
|
+
const fctEvSimp = fctEv.simplify({ calculatePowers: true });
|
|
128
|
+
const fctEvIsSimplifiable = fctEv.toTex() !== fctEvSimp.toTex();
|
|
129
|
+
const oppFct = opposite(fct);
|
|
130
|
+
const oppFctSimp = oppFct.simplify({
|
|
131
|
+
calculatePowers: true,
|
|
132
|
+
towardsDistribute: true,
|
|
133
|
+
forbidFactorize: true,
|
|
134
|
+
});
|
|
135
|
+
const oppFctIsSimplifiable = oppFct.toTex() !== oppFctSimp.toTex();
|
|
136
|
+
return `On exprime $f(-x)$ :
|
|
137
|
+
|
|
138
|
+
${alignTex([
|
|
139
|
+
["f(-x)", "=", fctEv.toTex()],
|
|
140
|
+
["", "=", fctEvSimp.toTex()],
|
|
141
|
+
])}
|
|
142
|
+
|
|
143
|
+
${type === "even"
|
|
144
|
+
? "Puisque $f(-x) = f(x)$, la fonction $f$ est paire."
|
|
145
|
+
: `Puisque $f(-x)\\neq f(x)$, la fonction $f$ n'est pas paire.
|
|
146
|
+
|
|
147
|
+
On calcule alors $-f(x)$ :
|
|
148
|
+
|
|
149
|
+
${alignTex([
|
|
150
|
+
["-f(x)", "=", oppFct.toTex()],
|
|
151
|
+
oppFctIsSimplifiable ? ["", "=", oppFctSimp.toTex()] : [],
|
|
152
|
+
])}`}
|
|
153
|
+
|
|
154
|
+
${type === "uneven"
|
|
155
|
+
? "Puisque $f(-x) = -f(x)$, la fonction $f$ est impaire."
|
|
156
|
+
: type === "neither"
|
|
157
|
+
? "Puisque $f(-x)\\neq -f(x)$, la fonction $f$ n'est pas impaire. La fonction $f$ n'est donc ni paire, ni impaire."
|
|
158
|
+
: ""}
|
|
159
|
+
`;
|
|
160
|
+
};
|
|
107
161
|
const getPropositions = (n, { answer }) => {
|
|
108
162
|
const propositions = [];
|
|
109
163
|
addValidProp(propositions, answer, "raw");
|
|
@@ -128,4 +182,5 @@ export const parityFromAlgebra = {
|
|
|
128
182
|
answerType: "QCU",
|
|
129
183
|
subject: "Mathématiques",
|
|
130
184
|
getQuestionFromIdentifiers,
|
|
185
|
+
hasHintAndCorrection: true,
|
|
131
186
|
};
|
|
@@ -55,37 +55,40 @@ const getInstruction = (identifiers) => {
|
|
|
55
55
|
|
|
56
56
|
Pour ${instruction}, il faut utiliser... `;
|
|
57
57
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
//
|
|
88
|
-
|
|
58
|
+
const getHint = (identifiers) => {
|
|
59
|
+
return `Voici les énoncés des théorèmes de Pythagore et de Thalès, et leurs réciproques :
|
|
60
|
+
|
|
61
|
+
- **Théorème de Pythagore** : Dans un triangle rectangle, le carré de l'hypoténuse est égal à la somme des carrés des deux autres côtés.
|
|
62
|
+
- **Réciproque du théorème de Pythagore** : Si dans un triangle, le carré de l'hypoténuse est égal à la somme des carrés des deux autres côtés, alors le triangle est rectangle.
|
|
63
|
+
- **Théorème de Thalès** : Soit un triangle $ABC$, et $D$ un point sur la droite $(AB)$ et $E$ un point sur la droite $(AC)$. Si les droites $(DE)$ et $(BC)$ sont parallèles, alors :
|
|
64
|
+
|
|
65
|
+
$$
|
|
66
|
+
\\frac{AD}{AB}=\\frac{AE}{AC}=\\frac{DE}{BC}
|
|
67
|
+
$$
|
|
68
|
+
- **Réciproque du théorème de Thalès** : Soit un triangle $ABC$, et $D$ un point sur la droite $(AB)$ et $E$ un point sur la droite $(AC)$. Si $\\frac{AD}{AB}=\\frac{AE}{AC}$, alors les droites $(AB)$ et $(AC)$ sont parallèles.`;
|
|
69
|
+
};
|
|
70
|
+
const getCorrection = (identifiers) => {
|
|
71
|
+
const { isAskingLength, pointsIdentifiers, isSegmentHeight } = identifiers;
|
|
72
|
+
const points = pointsIdentifiers.map((p) => PointConstructor.fromIdentifiers(p));
|
|
73
|
+
if (isSegmentHeight) {
|
|
74
|
+
if (isAskingLength) {
|
|
75
|
+
// ("Pythagore");
|
|
76
|
+
return ``;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// ("Recip pythagore");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
if (isAskingLength) {
|
|
84
|
+
// ("Thales");
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// ("Recip thales");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return ``;
|
|
91
|
+
};
|
|
89
92
|
const getGGBOptions = (identifiers) => {
|
|
90
93
|
const { isAskingLength, lengths, pointsIdentifiers, isSegmentHeight } = identifiers;
|
|
91
94
|
const points = pointsIdentifiers.map((p) => PointConstructor.fromIdentifiers(p));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thalesCalcul.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/thales/thalesCalcul.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAsBT,MAAM,6BAA6B,CAAC;AAMrC,OAAO,EAGL,mBAAmB,EACpB,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"thalesCalcul.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/thales/thalesCalcul.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAsBT,MAAM,6BAA6B,CAAC;AAMrC,OAAO,EAGL,mBAAmB,EACpB,MAAM,2CAA2C,CAAC;AAanD,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AA2OF,KAAK,OAAO,GAAG;IACb,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAqEF,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CA0BvD,CAAC"}
|
|
@@ -6,9 +6,14 @@ import { Segment } from "../../../../math/geometry/segment.js";
|
|
|
6
6
|
import { Triangle, TriangleConstructor, } from "../../../../math/geometry/triangles/triangle.js";
|
|
7
7
|
import { VectorConstructor } from "../../../../math/geometry/vector.js";
|
|
8
8
|
import { randfloat } from "../../../../math/utils/random/randfloat.js";
|
|
9
|
+
import { randint } from "../../../../math/utils/random/randint.js";
|
|
9
10
|
import { round } from "../../../../math/utils/round.js";
|
|
11
|
+
import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
|
|
12
|
+
import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
|
|
10
13
|
import { coinFlip } from "../../../../utils/alea/coinFlip.js";
|
|
11
14
|
import { random } from "../../../../utils/alea/random.js";
|
|
15
|
+
import { alignTex } from "../../../../utils/latex/alignTex.js";
|
|
16
|
+
import { approxOrEqual } from "../../../../utils/latex/approxOrEqual.js";
|
|
12
17
|
import { randomLetter } from "../../../../utils/strings/randomLetter.js";
|
|
13
18
|
const getSubTriangle = ({ triangle, insidePointsNames, ratio, isPapillon, }) => {
|
|
14
19
|
const [A, B, C] = triangle.points;
|
|
@@ -25,7 +30,7 @@ const getPropositions = (n, { answer }) => {
|
|
|
25
30
|
const propositions = [];
|
|
26
31
|
addValidProp(propositions, answer);
|
|
27
32
|
while (propositions.length < n) {
|
|
28
|
-
tryToAddWrongProp(propositions, randfloat(3, 20,
|
|
33
|
+
tryToAddWrongProp(propositions, randfloat(3, 20, 2).frenchify());
|
|
29
34
|
}
|
|
30
35
|
return shuffleProps(propositions, n);
|
|
31
36
|
};
|
|
@@ -65,12 +70,77 @@ On sait de plus que : ${allSides
|
|
|
65
70
|
.map((e) => `$${e.toLengthTex()}$`)
|
|
66
71
|
.join(" , ")}.
|
|
67
72
|
|
|
68
|
-
Calculer $${segmentAskedName.slice(1, 3)}$ (arrondir
|
|
73
|
+
Calculer $${segmentAskedName.slice(1, 3)}$ (arrondir au centième).`;
|
|
74
|
+
};
|
|
75
|
+
const getHint = (identifiers) => {
|
|
76
|
+
const { triangleIdentifiers, insidePointsNames, ratio, isPapillon, segmentAskedName, } = identifiers;
|
|
77
|
+
const triangle = TriangleConstructor.fromIdentifiers(triangleIdentifiers);
|
|
78
|
+
const subTriangle = getSubTriangle({
|
|
79
|
+
triangle,
|
|
80
|
+
insidePointsNames: identifiers.insidePointsNames,
|
|
81
|
+
ratio,
|
|
82
|
+
isPapillon: identifiers.isPapillon,
|
|
83
|
+
});
|
|
84
|
+
const oppositeSegment = triangle.sides[2].toInsideName();
|
|
85
|
+
return `Puisque les droites $\\left(${subTriangle.sides[2].toInsideName()}\\right)$ et $\\left(${oppositeSegment}\\right)$ sont parallèles, d'après le théorème de Thalès, on a :
|
|
86
|
+
|
|
87
|
+
$$
|
|
88
|
+
\\frac{${triangle.sides[0].toInsideName()}}{${subTriangle.sides[0].toInsideName()}}=\\frac{${triangle.sides[1].toInsideName()}}{${subTriangle.sides[1].toInsideName()}}=\\frac{${triangle.sides[2].toInsideName()}}{${subTriangle.sides[2].toInsideName()}}
|
|
89
|
+
$$
|
|
90
|
+
|
|
91
|
+
Remplace dans cette égalité les longueurs par les valeurs données dans l'énoncé.
|
|
92
|
+
`;
|
|
93
|
+
};
|
|
94
|
+
const getCorrection = (identifiers) => {
|
|
95
|
+
const { triangleIdentifiers, insidePointsNames, ratio, isPapillon, segmentAskedName, } = identifiers;
|
|
96
|
+
const triangle = TriangleConstructor.fromIdentifiers(triangleIdentifiers);
|
|
97
|
+
const subTriangle = getSubTriangle({
|
|
98
|
+
triangle,
|
|
99
|
+
insidePointsNames: identifiers.insidePointsNames,
|
|
100
|
+
ratio,
|
|
101
|
+
isPapillon: identifiers.isPapillon,
|
|
102
|
+
});
|
|
103
|
+
const oppositeSegment = triangle.sides[2].toInsideName();
|
|
104
|
+
const ratios = [0, 1, 2].map((i) => [
|
|
105
|
+
triangle.sides[i],
|
|
106
|
+
subTriangle.sides[i],
|
|
107
|
+
]);
|
|
108
|
+
const names = ratios.map((arr) => [
|
|
109
|
+
arr[0].toInsideName(),
|
|
110
|
+
arr[1].toInsideName(),
|
|
111
|
+
]);
|
|
112
|
+
const lengths = ratios.map((arr) => [
|
|
113
|
+
arr[0].getLength().frenchify(),
|
|
114
|
+
arr[1].getLength().frenchify(),
|
|
115
|
+
]);
|
|
116
|
+
const lengthAsked = segmentAskedName.slice(1, 3);
|
|
117
|
+
const lengthAskedColumn = names.findIndex((e) => e.some((s) => s === lengthAsked));
|
|
118
|
+
const lengthAskedRow = names[lengthAskedColumn].findIndex((s) => s === lengthAsked);
|
|
119
|
+
lengths[lengthAskedColumn][lengthAskedRow] = lengthAsked;
|
|
120
|
+
const chosenSecondColumn = randint(0, 3, [lengthAskedColumn]);
|
|
121
|
+
const fraction = frac(multiply(lengths[lengthAskedColumn][1 - lengthAskedRow].unfrenchify(), lengths[chosenSecondColumn][lengthAskedRow].unfrenchify()), lengths[chosenSecondColumn][1 - lengthAskedRow].unfrenchify());
|
|
122
|
+
const fracEv = fraction.evaluate();
|
|
123
|
+
return `Puisque les droites $\\left(${subTriangle.sides[2].toInsideName()}\\right)$ et $\\left(${oppositeSegment}\\right)$ sont parallèles, d'après le théorème de Thalès, on a :
|
|
124
|
+
|
|
125
|
+
$$
|
|
126
|
+
\\frac{${triangle.sides[0].toInsideName()}}{${subTriangle.sides[0].toInsideName()}}=\\frac{${triangle.sides[1].toInsideName()}}{${subTriangle.sides[1].toInsideName()}}=\\frac{${triangle.sides[2].toInsideName()}}{${subTriangle.sides[2].toInsideName()}}
|
|
127
|
+
$$
|
|
128
|
+
|
|
129
|
+
On remplace les longueurs par les valeurs données dans l'énoncé :
|
|
130
|
+
|
|
131
|
+
$$
|
|
132
|
+
${[0, 1, 2].map((i) => `\\frac{${lengths[i][0]}}{${lengths[i][1]}}`).join("=")}
|
|
133
|
+
$$
|
|
134
|
+
|
|
135
|
+
Pour déterminer $${lengthAsked}$, on peut donc faire le calcul suivant :
|
|
136
|
+
|
|
137
|
+
${alignTex([
|
|
138
|
+
[lengthAsked, "=", fraction.toTex()],
|
|
139
|
+
["", ...approxOrEqual(fracEv, 2)],
|
|
140
|
+
])}
|
|
141
|
+
|
|
142
|
+
`;
|
|
69
143
|
};
|
|
70
|
-
// const getHint : GetHint<Identifiers> = (identifiers)=>{
|
|
71
|
-
// }
|
|
72
|
-
// const getCorrection : GetCorrection<Identifiers> = (identifiers)=>{
|
|
73
|
-
// }
|
|
74
144
|
const getGGBOptions = (identifiers) => {
|
|
75
145
|
const triangle = TriangleConstructor.fromIdentifiers(identifiers.triangleIdentifiers);
|
|
76
146
|
const subTriangle = getSubTriangle({
|
|
@@ -164,8 +234,8 @@ const getQuestionFromIdentifiers = (identifiers, opts) => {
|
|
|
164
234
|
keys: getKeys(identifiers, opts),
|
|
165
235
|
answerFormat: "tex",
|
|
166
236
|
identifiers,
|
|
167
|
-
|
|
168
|
-
|
|
237
|
+
hint: getHint(identifiers),
|
|
238
|
+
correction: getCorrection(identifiers),
|
|
169
239
|
ggbOptions: getGGBOptions(identifiers, opts),
|
|
170
240
|
};
|
|
171
241
|
return question;
|
|
@@ -194,4 +264,5 @@ export const thalesCalcul = {
|
|
|
194
264
|
};
|
|
195
265
|
},
|
|
196
266
|
getQuestionFromIdentifiers,
|
|
267
|
+
hasHintAndCorrection: true,
|
|
197
268
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paralellismViaColinearity.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/vectors/paralellismViaColinearity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"paralellismViaColinearity.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/vectors/paralellismViaColinearity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAgBrC,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AA4HF,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,WAAW,CAa3D,CAAC"}
|
|
@@ -2,9 +2,10 @@ import { addValidProp, tryToAddWrongProp, } from "../../../../exercises/exercise
|
|
|
2
2
|
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
3
|
import { Line } from "../../../../math/geometry/line.js";
|
|
4
4
|
import { Point, PointConstructor } from "../../../../math/geometry/point.js";
|
|
5
|
-
import { VectorConstructor } from "../../../../math/geometry/vector.js";
|
|
5
|
+
import { Vector, VectorConstructor } from "../../../../math/geometry/vector.js";
|
|
6
6
|
import { randint } from "../../../../math/utils/random/randint.js";
|
|
7
7
|
import { NumberNode } from "../../../../tree/nodes/numbers/numberNode.js";
|
|
8
|
+
import { substract, } from "../../../../tree/nodes/operators/substractNode.js";
|
|
8
9
|
import { coinFlip } from "../../../../utils/alea/coinFlip.js";
|
|
9
10
|
import { shuffle } from "../../../../utils/alea/shuffle.js";
|
|
10
11
|
const getInstruction = (identifiers) => {
|
|
@@ -27,6 +28,40 @@ const getAnswer = (identifiers) => {
|
|
|
27
28
|
const answer = isParallele ? "Oui" : "Non";
|
|
28
29
|
return answer;
|
|
29
30
|
};
|
|
31
|
+
const getHint = (identifiers) => {
|
|
32
|
+
return `Les droites $(AB)$ et $(CD)$ sont parallèles si et seulement si les vecteurs $\\overrightarrow{AB}$ et $\\overrightarrow{CD}$ sont colinéaires. Calcule donc les coordonnées puis le déterminant des vecteurs $\\overrightarrow{AB}$ et $\\overrightarrow{CD}$.`;
|
|
33
|
+
};
|
|
34
|
+
const getCorrection = (identifiers) => {
|
|
35
|
+
const A = new Point("A", identifiers.xA, identifiers.yA);
|
|
36
|
+
const B = new Point("B", identifiers.xB, identifiers.yB);
|
|
37
|
+
const C = new Point("C", identifiers.xC, identifiers.yC);
|
|
38
|
+
const D = new Point("D", identifiers.xD, identifiers.yD);
|
|
39
|
+
const vec1 = new Vector("AB", substract(B.x, A.x), substract(B.y, A.y));
|
|
40
|
+
const vec2 = new Vector("CD", substract(D.x, C.x), substract(D.y, C.y));
|
|
41
|
+
const vec1Simp = vec1.simplify();
|
|
42
|
+
const vec2Simp = vec2.simplify();
|
|
43
|
+
const det = vec1Simp.determinant(vec2Simp);
|
|
44
|
+
const isParallel = vec1.isColinear(vec2);
|
|
45
|
+
return `Les droites $(AB)$ et $(CD)$ sont parallèles si et seulement si les vecteurs $\\overrightarrow{AB}$ et $\\overrightarrow{CD}$ sont colinéaires. On calcule donc d'abord les coordonnées de ces vecteurs :
|
|
46
|
+
|
|
47
|
+
$$
|
|
48
|
+
${vec1.toTexWithCoords()}=${vec1Simp.toBinomCoords().toTex()}
|
|
49
|
+
$$
|
|
50
|
+
|
|
51
|
+
$$
|
|
52
|
+
${vec2.toTexWithCoords()}=${vec2Simp.toBinomCoords().toTex()}
|
|
53
|
+
$$
|
|
54
|
+
|
|
55
|
+
Puis, on calcule le déterminant des vecteurs $\\overrightarrow{AB}$ et $\\overrightarrow{CD}$ :
|
|
56
|
+
|
|
57
|
+
$$
|
|
58
|
+
\\det(${vec1.toTex()};${vec2.toTex()})=${det.toTex()}=${det.simplify().toTex()}
|
|
59
|
+
$$
|
|
60
|
+
|
|
61
|
+
${isParallel
|
|
62
|
+
? `Puisque le déterminant est nul, les vecteurs sont colinéaires. Les droites $(AB)$ et $(CD)$ sont donc parallèles.`
|
|
63
|
+
: `Puisque le déterminant n'est pas nul, les vecteurs ne sont pas colinéaires. Les droites $(AB)$ et $(CD)$ ne sont donc pas parallèles.`}`;
|
|
64
|
+
};
|
|
30
65
|
const getQuestionFromIdentifiers = (identifiers) => {
|
|
31
66
|
const question = {
|
|
32
67
|
answer: getAnswer(identifiers),
|
|
@@ -34,6 +69,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
34
69
|
keys: [],
|
|
35
70
|
answerFormat: "raw",
|
|
36
71
|
identifiers,
|
|
72
|
+
hint: getHint(identifiers),
|
|
73
|
+
correction: getCorrection(identifiers),
|
|
37
74
|
};
|
|
38
75
|
return question;
|
|
39
76
|
};
|
|
@@ -92,4 +129,5 @@ export const paralellismViaColinearity = {
|
|
|
92
129
|
answerType: "QCU",
|
|
93
130
|
subject: "Mathématiques",
|
|
94
131
|
getQuestionFromIdentifiers,
|
|
132
|
+
hasHintAndCorrection: true,
|
|
95
133
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parallelogramViaEqualVectors.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/vectors/parallelogramViaEqualVectors.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"parallelogramViaEqualVectors.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/vectors/parallelogramViaEqualVectors.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAcrC,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AA4GF,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,WAAW,CAa9D,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { addValidProp, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
|
|
2
2
|
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
3
|
import { Point, PointConstructor } from "../../../../math/geometry/point.js";
|
|
4
|
-
import { VectorConstructor } from "../../../../math/geometry/vector.js";
|
|
4
|
+
import { Vector, VectorConstructor } from "../../../../math/geometry/vector.js";
|
|
5
|
+
import { substract, } from "../../../../tree/nodes/operators/substractNode.js";
|
|
5
6
|
import { coinFlip } from "../../../../utils/alea/coinFlip.js";
|
|
6
7
|
import { shuffle } from "../../../../utils/alea/shuffle.js";
|
|
7
8
|
const getInstruction = (identifiers) => {
|
|
@@ -24,6 +25,33 @@ const getAnswer = (identifiers) => {
|
|
|
24
25
|
const answer = isParallelogram ? "Oui" : "Non";
|
|
25
26
|
return answer;
|
|
26
27
|
};
|
|
28
|
+
const getHint = (identifiers) => {
|
|
29
|
+
return `$ABCD$ est un parallélogramme si et seulement si les vecteurs $\\overrightarrow{AB}$ et $\\overrightarrow{DC}$ sont égaux.`;
|
|
30
|
+
};
|
|
31
|
+
const getCorrection = (identifiers) => {
|
|
32
|
+
const A = new Point("A", identifiers.xA, identifiers.yA);
|
|
33
|
+
const B = new Point("B", identifiers.xB, identifiers.yB);
|
|
34
|
+
const C = new Point("C", identifiers.xC, identifiers.yC);
|
|
35
|
+
const D = new Point("D", identifiers.xD, identifiers.yD);
|
|
36
|
+
const vec1 = new Vector("AB", substract(B.x, A.x), substract(B.y, A.y));
|
|
37
|
+
const vec2 = new Vector("DC", substract(C.x, D.x), substract(C.y, D.y));
|
|
38
|
+
const vec1Simp = vec1.simplify();
|
|
39
|
+
const vec2Simp = vec2.simplify();
|
|
40
|
+
const isParallelogram = vec1Simp.equals(vec2Simp);
|
|
41
|
+
return `$ABCD$ est un parallélogramme si et seulement si les vecteurs $\\overrightarrow{AB}$ et $\\overrightarrow{DC}$ sont égaux. On calcule donc les coordonnées de ces vecteurs :
|
|
42
|
+
|
|
43
|
+
$$
|
|
44
|
+
${vec1.toTexWithCoords()}=${vec1Simp.toBinomCoords().toTex()}
|
|
45
|
+
$$
|
|
46
|
+
|
|
47
|
+
$$
|
|
48
|
+
${vec2.toTexWithCoords()}=${vec2Simp.toBinomCoords().toTex()}
|
|
49
|
+
$$
|
|
50
|
+
|
|
51
|
+
${isParallelogram
|
|
52
|
+
? `Puisque les vecteurs sont égaux, $ABCD$ est un parallélogramme.`
|
|
53
|
+
: `Puisque les vecteurs ne sont pas égaux, $ABCD$ n'est pas un parallélogramme.`}`;
|
|
54
|
+
};
|
|
27
55
|
const getQuestionFromIdentifiers = (identifiers) => {
|
|
28
56
|
const question = {
|
|
29
57
|
answer: getAnswer(identifiers),
|
|
@@ -31,6 +59,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
31
59
|
keys: [],
|
|
32
60
|
answerFormat: "raw",
|
|
33
61
|
identifiers,
|
|
62
|
+
hint: getHint(identifiers),
|
|
63
|
+
correction: getCorrection(identifiers),
|
|
34
64
|
};
|
|
35
65
|
return question;
|
|
36
66
|
};
|
|
@@ -82,4 +112,5 @@ export const parallelogramViaEqualVectors = {
|
|
|
82
112
|
answerType: "QCU",
|
|
83
113
|
subject: "Mathématiques",
|
|
84
114
|
getQuestionFromIdentifiers,
|
|
115
|
+
hasHintAndCorrection: true,
|
|
85
116
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vectorLinearCombination.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/vectors/vectorLinearCombination.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"vectorLinearCombination.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/vectors/vectorLinearCombination.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAYrC,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,YAAY,CAAC;IAChB,CAAC,EAAE,YAAY,CAAC;CACjB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAyMF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,WAAW,CAczD,CAAC"}
|
|
@@ -3,8 +3,8 @@ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQue
|
|
|
3
3
|
import { Vector, VectorConstructor } from "../../../../math/geometry/vector.js";
|
|
4
4
|
import { randint } from "../../../../math/utils/random/randint.js";
|
|
5
5
|
import { NumberNode } from "../../../../tree/nodes/numbers/numberNode.js";
|
|
6
|
-
import { AddNode } from "../../../../tree/nodes/operators/addNode.js";
|
|
7
|
-
import { MultiplyNode } from "../../../../tree/nodes/operators/multiplyNode.js";
|
|
6
|
+
import { add, AddNode } from "../../../../tree/nodes/operators/addNode.js";
|
|
7
|
+
import { multiply, MultiplyNode, } from "../../../../tree/nodes/operators/multiplyNode.js";
|
|
8
8
|
import { VariableNode } from "../../../../tree/nodes/variables/variableNode.js";
|
|
9
9
|
const getInstruction = (identifiers) => {
|
|
10
10
|
const { a, b } = identifiers;
|
|
@@ -26,6 +26,41 @@ const getAnswer = (identifiers) => {
|
|
|
26
26
|
const correctAnswer = new Vector("au+bv", aUPlusBv.x, aUPlusBv.y);
|
|
27
27
|
return `${correctAnswer.toInlineCoordsTex()}`;
|
|
28
28
|
};
|
|
29
|
+
const getHint = (identifiers) => {
|
|
30
|
+
return `Calcule d'abord les coordonnées de chaque vecteur de la somme. Puis, additionne ces coordonnées.`;
|
|
31
|
+
};
|
|
32
|
+
const getCorrection = (identifiers) => {
|
|
33
|
+
const { a, b, u, v } = identifiers;
|
|
34
|
+
const uVec = new Vector("u", u.x.toTree(), u.y.toTree());
|
|
35
|
+
const coeffedU = new Vector("au", multiply(a, uVec.x), multiply(a, uVec.y));
|
|
36
|
+
const vVec = new Vector("v", v.x.toTree(), v.y.toTree());
|
|
37
|
+
const coeffedV = new Vector("bv", multiply(b, vVec.x), multiply(b, vVec.y));
|
|
38
|
+
const sum = add(multiply(a, "\\overrightarrow{u}"), multiply(b, "\\overrightarrow{v}")).toTex();
|
|
39
|
+
const sumVec = new Vector("sum", add(coeffedU.x.simplify(), coeffedV.x.simplify()), add(coeffedU.y.simplify(), coeffedV.y.simplify()));
|
|
40
|
+
return `${a !== 1
|
|
41
|
+
? `Les coordonnées du vecteur $${multiply(a, "\\overrightarrow{u}").toTex()}$ sont :
|
|
42
|
+
|
|
43
|
+
$$
|
|
44
|
+
${coeffedU.toCoords()} = ${coeffedU.simplify().toCoords()}
|
|
45
|
+
$$`
|
|
46
|
+
: ""}
|
|
47
|
+
|
|
48
|
+
${a !== 1
|
|
49
|
+
? `Les coordonnées du vecteur $${multiply(b, "\\overrightarrow{v}").toTex()}$ sont :
|
|
50
|
+
|
|
51
|
+
$$
|
|
52
|
+
${coeffedV.toCoords()} = ${coeffedV.simplify().toCoords()}
|
|
53
|
+
$$`
|
|
54
|
+
: ""}
|
|
55
|
+
|
|
56
|
+
En additionnant, on obtient donc les coordonnées du vecteur $${sum}$ :
|
|
57
|
+
|
|
58
|
+
$$
|
|
59
|
+
${sumVec.toCoords()} = ${sumVec.simplify().toCoords()}
|
|
60
|
+
$$
|
|
61
|
+
|
|
62
|
+
`;
|
|
63
|
+
};
|
|
29
64
|
const getQuestionFromIdentifiers = (identifiers) => {
|
|
30
65
|
const question = {
|
|
31
66
|
answer: getAnswer(identifiers),
|
|
@@ -33,6 +68,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
33
68
|
keys: ["semicolon"],
|
|
34
69
|
answerFormat: "tex",
|
|
35
70
|
identifiers,
|
|
71
|
+
hint: getHint(identifiers),
|
|
72
|
+
correction: getCorrection(identifiers),
|
|
36
73
|
};
|
|
37
74
|
return question;
|
|
38
75
|
};
|
|
@@ -112,4 +149,5 @@ export const vectorLinearCombination = {
|
|
|
112
149
|
isAnswerValid,
|
|
113
150
|
subject: "Mathématiques",
|
|
114
151
|
getQuestionFromIdentifiers,
|
|
152
|
+
hasHintAndCorrection: true,
|
|
115
153
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"choseReasoningForIndicator.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/choseReasoningForIndicator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAUrC,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;
|
|
1
|
+
{"version":3,"file":"choseReasoningForIndicator.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/choseReasoningForIndicator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAUrC,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAgIF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,WAAW,CAa5D,CAAC"}
|
|
@@ -38,13 +38,20 @@ La ${indicatorAsked} de cette série est $${avg}$.
|
|
|
38
38
|
|
|
39
39
|
Quelle est la justification correcte ?`;
|
|
40
40
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
const getHint = (identifiers) => {
|
|
42
|
+
const { values, indicatorAsked } = identifiers;
|
|
43
|
+
return indicatorAsked === "moyenne"
|
|
44
|
+
? `La moyenne est la somme des valeurs, divisée par le nombre de valeurs.`
|
|
45
|
+
: `La médiane est la valeur centrale de la série.`;
|
|
46
|
+
};
|
|
47
|
+
const getCorrection = (identifiers) => {
|
|
48
|
+
const { values, indicatorAsked } = identifiers;
|
|
49
|
+
return indicatorAsked === "moyenne"
|
|
50
|
+
? `La moyenne est la somme des valeurs, divisée par le nombre de valeurs. Ici, ${getAnswer(identifiers).toLocaleLowerCase()}.
|
|
51
|
+
`
|
|
52
|
+
: `La médiane est la valeur centrale de la série : c'est à dire qu'il y a autant de valeurs inférieures à elle que de valeurs supérieures. Ici, ${getAnswer(identifiers).toLocaleLowerCase()}.
|
|
53
|
+
`;
|
|
54
|
+
};
|
|
48
55
|
const getChoseReasoningForIndicatorQuestion = (ops) => {
|
|
49
56
|
const max = 2 * randint(5, 20);
|
|
50
57
|
const x = max / 2;
|
|
@@ -77,8 +84,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
77
84
|
instruction: getInstruction(identifiers),
|
|
78
85
|
answerFormat: "raw",
|
|
79
86
|
identifiers,
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
hint: getHint(identifiers),
|
|
88
|
+
correction: getCorrection(identifiers),
|
|
82
89
|
};
|
|
83
90
|
return question;
|
|
84
91
|
};
|
|
@@ -93,5 +100,5 @@ export const choseReasoningForIndicator = {
|
|
|
93
100
|
subject: "Mathématiques",
|
|
94
101
|
answerType: "QCU",
|
|
95
102
|
getQuestionFromIdentifiers,
|
|
96
|
-
|
|
103
|
+
hasHintAndCorrection: true,
|
|
97
104
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"median.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/median.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"median.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/median.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,QAAQ,EAaT,MAAM,sBAAsB,CAAC;AAG9B,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAuHF,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,WAAW,CAajD,CAAC"}
|
|
@@ -36,6 +36,38 @@ const getMedianWithTable = () => {
|
|
|
36
36
|
const identifiers = { randomValues, randomEffectives };
|
|
37
37
|
return getQuestionFromIdentifiers(identifiers);
|
|
38
38
|
};
|
|
39
|
+
const getHint = (identifiers) => {
|
|
40
|
+
return `Dresse le tableau des effectifs cumulés croissants. Cela permet de trouver l'effectif total $N$. Puis :
|
|
41
|
+
|
|
42
|
+
- Si $N$ est pair, alors la médiane est la valeur comprise entre la valeur de rang $\\frac{N}{2}$ et celle de rang $\\frac{N}{2}+1$;
|
|
43
|
+
- Si $N$ est impair, alors la médiane est la valeur de rang $\\frac{N+1}{2}$.`;
|
|
44
|
+
};
|
|
45
|
+
const getCorrection = (identifiers) => {
|
|
46
|
+
const { randomEffectives, randomValues } = identifiers;
|
|
47
|
+
const eccs = [];
|
|
48
|
+
let s = 0;
|
|
49
|
+
for (let i = 0; i < randomEffectives.length; i++) {
|
|
50
|
+
s += randomEffectives[i];
|
|
51
|
+
eccs.push(s);
|
|
52
|
+
}
|
|
53
|
+
const total = eccs[eccs.length - 1];
|
|
54
|
+
const rank = total / 2;
|
|
55
|
+
return `On dresse le tableau des effectifs cumulés croissants (ECC) :
|
|
56
|
+
|
|
57
|
+
${mdTable([
|
|
58
|
+
["Valeur", ...randomValues.map((e) => dollarize(e))],
|
|
59
|
+
["Effectif", ...randomEffectives.map((e) => dollarize(e))],
|
|
60
|
+
["ECC", ...eccs.map((e) => dollarize(e))],
|
|
61
|
+
])}
|
|
62
|
+
|
|
63
|
+
L'effectif total est donc $${total}$.
|
|
64
|
+
|
|
65
|
+
Puisque $\\frac{${total}}{2} = ${rank.frenchify()}$, la médiane est ${rank % 1 === 0
|
|
66
|
+
? `entre la $${rank}$ème et la $${rank + 1}$ème valeur.`
|
|
67
|
+
: `la $${Math.ceil(rank)}$ème valeur.`}
|
|
68
|
+
|
|
69
|
+
La médiane est donc $${getAnswer(identifiers)}$.`;
|
|
70
|
+
};
|
|
39
71
|
const getQuestionFromIdentifiers = (identifiers) => {
|
|
40
72
|
const question = {
|
|
41
73
|
instruction: getInstruction(identifiers),
|
|
@@ -44,6 +76,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
44
76
|
answerFormat: "tex",
|
|
45
77
|
identifiers,
|
|
46
78
|
style: { tableHasNoHeader: true },
|
|
79
|
+
hint: getHint(identifiers),
|
|
80
|
+
correction: getCorrection(identifiers),
|
|
47
81
|
};
|
|
48
82
|
return question;
|
|
49
83
|
};
|
|
@@ -70,4 +104,5 @@ export const medianWithTable = {
|
|
|
70
104
|
isAnswerValid,
|
|
71
105
|
subject: "Mathématiques",
|
|
72
106
|
getQuestionFromIdentifiers,
|
|
107
|
+
hasHintAndCorrection: true,
|
|
73
108
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"medianList.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/medianList.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"medianList.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/medianList.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EAcT,MAAM,sBAAsB,CAAC;AAE9B,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAkFF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,CAahD,CAAC"}
|
|
@@ -25,6 +25,21 @@ const getMedianList = () => {
|
|
|
25
25
|
const identifiers = { sortedValues };
|
|
26
26
|
return getQuestionFromIdentifiers(identifiers);
|
|
27
27
|
};
|
|
28
|
+
const getHint = (identifiers) => {
|
|
29
|
+
return `La médiane est la valeur centrale de la série : il y a autant de valeur inférieures à la médiane que de valeurs supérieures à la médiane.`;
|
|
30
|
+
};
|
|
31
|
+
const getCorrection = (identifiers) => {
|
|
32
|
+
const { sortedValues } = identifiers;
|
|
33
|
+
const total = sortedValues.length;
|
|
34
|
+
const rank = total / 2;
|
|
35
|
+
return `Il y a $${total}$ valeurs dans la liste.
|
|
36
|
+
|
|
37
|
+
Puisque $\\frac{${total}}{2} = ${rank.frenchify()}$, la médiane est ${rank % 1 === 0
|
|
38
|
+
? `entre la $${rank}$ème et la $${rank + 1}$ème valeur.`
|
|
39
|
+
: `la $${Math.ceil(rank)}$ème valeur.`}
|
|
40
|
+
|
|
41
|
+
La médiane est donc $${getAnswer(identifiers)}$.`;
|
|
42
|
+
};
|
|
28
43
|
const getQuestionFromIdentifiers = (identifiers) => {
|
|
29
44
|
const question = {
|
|
30
45
|
instruction: getInstruction(identifiers),
|
|
@@ -32,6 +47,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
32
47
|
keys: [],
|
|
33
48
|
answerFormat: "tex",
|
|
34
49
|
identifiers,
|
|
50
|
+
hint: getHint(identifiers),
|
|
51
|
+
correction: getCorrection(identifiers),
|
|
35
52
|
};
|
|
36
53
|
return question;
|
|
37
54
|
};
|
|
@@ -59,4 +76,5 @@ export const medianWithList = {
|
|
|
59
76
|
isAnswerValid,
|
|
60
77
|
subject: "Mathématiques",
|
|
61
78
|
getQuestionFromIdentifiers,
|
|
79
|
+
hasHintAndCorrection: true,
|
|
62
80
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quartiles.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/quartiles.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"quartiles.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/quartiles.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,QAAQ,EAaT,MAAM,sBAAsB,CAAC;AAG9B,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AA6HF,eAAO,MAAM,SAAS,EAAE,QAAQ,CAAC,WAAW,CAa3C,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { randint } from "../../../../math/utils/random/randint.js";
|
|
2
2
|
import { firstQuartile, thirdQuartile, } from "../../../../math/utils/stats/quartiles.js";
|
|
3
|
+
import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
|
|
4
|
+
import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
|
|
3
5
|
import { shuffle } from "../../../../utils/alea/shuffle.js";
|
|
4
6
|
import { dollarize } from "../../../../utils/latex/dollarize.js";
|
|
5
7
|
import { mdTable } from "../../../../utils/markdown/mdTable.js";
|
|
@@ -41,6 +43,38 @@ const getQuartiles = () => {
|
|
|
41
43
|
const identifiers = { randomValues, randomEffectives, randomQuartile };
|
|
42
44
|
return getQuestionFromIdentifiers(identifiers);
|
|
43
45
|
};
|
|
46
|
+
const getHint = (identifiers) => {
|
|
47
|
+
const { randomEffectives, randomValues, randomQuartile } = identifiers;
|
|
48
|
+
if (randomQuartile === 0)
|
|
49
|
+
return `Le premier quartile est la valeur de la série telle qu'au moins un quart des valeurs lui sont inférieures. Dresse le tableau des effectifs cumulés croissants de la série, puis calcule ce que vaut un quart de l'effectif total.`;
|
|
50
|
+
return `Le troisième quartile est la valeur de la série telle qu'au moins un trois quarts des valeurs lui sont inférieures. Dresse le tableau des effectifs cumulés croissants de la série, puis calcule ce que vaut un trois quarts de l'effectif total.`;
|
|
51
|
+
};
|
|
52
|
+
const getCorrection = (identifiers) => {
|
|
53
|
+
const { randomEffectives, randomValues, randomQuartile } = identifiers;
|
|
54
|
+
const eccs = [];
|
|
55
|
+
let s = 0;
|
|
56
|
+
for (let i = 0; i < randomEffectives.length; i++) {
|
|
57
|
+
s += randomEffectives[i];
|
|
58
|
+
eccs.push(s);
|
|
59
|
+
}
|
|
60
|
+
const total = eccs[eccs.length - 1];
|
|
61
|
+
const rank = randomQuartile === 0 ? frac(total, 4) : frac(multiply(3, total), 4);
|
|
62
|
+
const rankEv = rank.evaluate();
|
|
63
|
+
const numeral = randomQuartile === 0 ? "premier" : "troisième";
|
|
64
|
+
return `On dresse le tableau des effectifs cumulés croissants (ECC) :
|
|
65
|
+
|
|
66
|
+
${mdTable([
|
|
67
|
+
["Valeur", ...randomValues.map((e) => dollarize(e))],
|
|
68
|
+
["Effectif", ...randomEffectives.map((e) => dollarize(e))],
|
|
69
|
+
["ECC", ...eccs.map((e) => dollarize(e))],
|
|
70
|
+
])}
|
|
71
|
+
|
|
72
|
+
L'effectif total est donc $${total}$.
|
|
73
|
+
|
|
74
|
+
Puisque $${rank.toTex()} = ${rankEv.frenchify()}$, le ${numeral} quartile est la $${Math.ceil(rankEv)}$-ème valeur.
|
|
75
|
+
|
|
76
|
+
Le ${numeral} quartile est donc $${getAnswer(identifiers)}$.`;
|
|
77
|
+
};
|
|
44
78
|
const getQuestionFromIdentifiers = (identifiers) => {
|
|
45
79
|
const question = {
|
|
46
80
|
instruction: getInstruction(identifiers),
|
|
@@ -49,6 +83,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
49
83
|
answerFormat: "tex",
|
|
50
84
|
identifiers,
|
|
51
85
|
style: { tableHasNoHeader: true },
|
|
86
|
+
hint: getHint(identifiers),
|
|
87
|
+
correction: getCorrection(identifiers),
|
|
52
88
|
};
|
|
53
89
|
return question;
|
|
54
90
|
};
|
|
@@ -75,4 +111,5 @@ export const quartiles = {
|
|
|
75
111
|
isAnswerValid,
|
|
76
112
|
subject: "Mathématiques",
|
|
77
113
|
getQuestionFromIdentifiers,
|
|
114
|
+
hasHintAndCorrection: true,
|
|
78
115
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quartilesList.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/quartilesList.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"quartilesList.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/quartilesList.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,QAAQ,EAcT,MAAM,sBAAsB,CAAC;AAG9B,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAgGF,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,WAAW,CAa/C,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { randint } from "../../../../math/utils/random/randint.js";
|
|
2
2
|
import { firstQuartile, thirdQuartile, } from "../../../../math/utils/stats/quartiles.js";
|
|
3
|
+
import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
|
|
4
|
+
import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
|
|
3
5
|
import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../exercise.js";
|
|
4
6
|
import { getDistinctQuestions } from "../../../utils/getDistinctQuestions.js";
|
|
5
7
|
const getInstruction = ({ randomQuartile, randomValues, }) => {
|
|
@@ -34,6 +36,24 @@ const getQuartiles = () => {
|
|
|
34
36
|
};
|
|
35
37
|
return getQuestionFromIdentifiers(identifiers);
|
|
36
38
|
};
|
|
39
|
+
const getHint = (identifiers) => {
|
|
40
|
+
const { randomValues, randomQuartile } = identifiers;
|
|
41
|
+
if (randomQuartile === 0)
|
|
42
|
+
return `Le premier quartile est la valeur de la série telle qu'au moins un quart des valeurs lui sont inférieures. `;
|
|
43
|
+
return `Le troisième quartile est la valeur de la série telle qu'au moins un trois quarts des valeurs lui sont inférieures.`;
|
|
44
|
+
};
|
|
45
|
+
const getCorrection = (identifiers) => {
|
|
46
|
+
const { randomValues, randomQuartile } = identifiers;
|
|
47
|
+
const total = randomValues.length;
|
|
48
|
+
const rank = randomQuartile === 0 ? frac(total, 4) : frac(multiply(3, total), 4);
|
|
49
|
+
const rankEv = rank.evaluate();
|
|
50
|
+
const numeral = randomQuartile === 0 ? "premier" : "troisième";
|
|
51
|
+
return `Il y a $${total}$ valeurs dans la série.
|
|
52
|
+
|
|
53
|
+
Puisque $${rank.toTex()} = ${rankEv.frenchify()}$, le ${numeral} quartile est la $${Math.ceil(rankEv)}$-ème valeur.
|
|
54
|
+
|
|
55
|
+
Le ${numeral} quartile est donc $${getAnswer(identifiers)}$.`;
|
|
56
|
+
};
|
|
37
57
|
const getQuestionFromIdentifiers = (identifiers) => {
|
|
38
58
|
const question = {
|
|
39
59
|
instruction: getInstruction(identifiers),
|
|
@@ -41,6 +61,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
41
61
|
keys: [],
|
|
42
62
|
answerFormat: "tex",
|
|
43
63
|
identifiers,
|
|
64
|
+
hint: getHint(identifiers),
|
|
65
|
+
correction: getCorrection(identifiers),
|
|
44
66
|
};
|
|
45
67
|
return question;
|
|
46
68
|
};
|
|
@@ -71,4 +93,5 @@ export const quartilesList = {
|
|
|
71
93
|
isAnswerValid,
|
|
72
94
|
subject: "Mathématiques",
|
|
73
95
|
getQuestionFromIdentifiers,
|
|
96
|
+
hasHintAndCorrection: true,
|
|
74
97
|
};
|