math-exercises 3.0.114 → 3.0.116
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/exercise.d.ts +12 -4
- package/lib/exercises/exercise.d.ts.map +1 -1
- package/lib/exercises/math/dataRepresentations/compareBoxPlot.d.ts +13 -0
- package/lib/exercises/math/dataRepresentations/compareBoxPlot.d.ts.map +1 -0
- package/lib/exercises/math/dataRepresentations/compareBoxPlot.js +192 -0
- package/lib/exercises/math/dataRepresentations/index.d.ts +1 -0
- package/lib/exercises/math/dataRepresentations/index.d.ts.map +1 -1
- package/lib/exercises/math/dataRepresentations/index.js +1 -0
- package/lib/exercises/math/derivation/tangent/derivativeNumberReading.d.ts.map +1 -1
- package/lib/exercises/math/derivation/tangent/derivativeNumberReading.js +0 -1
- package/lib/exercises/math/functions/affines/index.d.ts +1 -0
- package/lib/exercises/math/functions/affines/index.d.ts.map +1 -1
- package/lib/exercises/math/functions/affines/index.js +1 -0
- package/lib/exercises/math/functions/affines/recognizeAffineGraph.d.ts +18 -0
- package/lib/exercises/math/functions/affines/recognizeAffineGraph.d.ts.map +1 -0
- package/lib/exercises/math/functions/affines/recognizeAffineGraph.js +144 -0
- package/lib/exercises/math/geometry/angles/recognizeAngleType.d.ts +4 -1
- package/lib/exercises/math/geometry/angles/recognizeAngleType.d.ts.map +1 -1
- package/lib/exercises/math/geometry/angles/recognizeAngleType.js +21 -47
- package/lib/exercises/math/primitive/polynomialPrimitive.d.ts.map +1 -1
- package/lib/exercises/math/primitive/polynomialPrimitive.js +2 -2
- package/lib/exercises/math/probaStat/basicProbas/possibleValuesForProba.d.ts +13 -0
- package/lib/exercises/math/probaStat/basicProbas/possibleValuesForProba.d.ts.map +1 -0
- package/lib/exercises/math/probaStat/basicProbas/possibleValuesForProba.js +293 -0
- package/lib/index.d.ts +779 -760
- package/lib/index.d.ts.map +1 -1
- package/lib/latexTester.d.ts.map +1 -1
- package/lib/latexTester.js +3 -1
- package/lib/math/polynomials/trinom.d.ts +1 -0
- package/lib/math/polynomials/trinom.d.ts.map +1 -1
- package/lib/math/polynomials/trinom.js +5 -0
- package/lib/tests/questionTest.d.ts.map +1 -1
- package/lib/tests/questionTest.js +4 -0
- package/lib/utils/strings/capitalize.d.ts +2 -0
- package/lib/utils/strings/capitalize.d.ts.map +1 -0
- package/lib/utils/strings/capitalize.js +3 -0
- package/lib/utils/strings/reverseString.d.ts +2 -0
- package/lib/utils/strings/reverseString.d.ts.map +1 -0
- package/lib/utils/strings/reverseString.js +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Exercise } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { NodeIdentifiers } from "../../../../tree/nodes/nodeConstructor.js";
|
|
3
|
+
type Identifiers = {
|
|
4
|
+
arrayOfNodeIds: NodeIdentifiers[];
|
|
5
|
+
isFilterPossibleProba: boolean;
|
|
6
|
+
};
|
|
7
|
+
type Options = {
|
|
8
|
+
numberTypes: string[];
|
|
9
|
+
nbValues: number;
|
|
10
|
+
};
|
|
11
|
+
export declare const possibleValuesForProba: Exercise<Identifiers, Options>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=possibleValuesForProba.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"possibleValuesForProba.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/basicProbas/possibleValuesForProba.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAkBT,MAAM,6BAA6B,CAAC;AAUrC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAa7C,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAkHF,KAAK,OAAO,GAAG;IACb,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAgNF,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAgBjE,CAAC"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { GeneratorOptionTarget, GeneratorOptionType, addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
|
+
import { randfloat } from "../../../../math/utils/random/randfloat.js";
|
|
4
|
+
import { randint } from "../../../../math/utils/random/randint.js";
|
|
5
|
+
import { abs } from "../../../../tree/nodes/functions/absNode.js";
|
|
6
|
+
import { cos } from "../../../../tree/nodes/functions/cosNode.js";
|
|
7
|
+
import { exp } from "../../../../tree/nodes/functions/expNode.js";
|
|
8
|
+
import { sin } from "../../../../tree/nodes/functions/sinNode.js";
|
|
9
|
+
import { sqrt } from "../../../../tree/nodes/functions/sqrtNode.js";
|
|
10
|
+
import { NodeConstructor, } from "../../../../tree/nodes/nodeConstructor.js";
|
|
11
|
+
import { PiNode } from "../../../../tree/nodes/numbers/piNode.js";
|
|
12
|
+
import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
|
|
13
|
+
import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
|
|
14
|
+
import { power } from "../../../../tree/nodes/operators/powerNode.js";
|
|
15
|
+
import { substract } from "../../../../tree/nodes/operators/substractNode.js";
|
|
16
|
+
import { parseLatex } from "../../../../tree/parsers/latexParser.js";
|
|
17
|
+
import { coinFlip } from "../../../../utils/alea/coinFlip.js";
|
|
18
|
+
import { probaFlip } from "../../../../utils/alea/probaFlip.js";
|
|
19
|
+
import { random } from "../../../../utils/alea/random.js";
|
|
20
|
+
import { shuffle } from "../../../../utils/alea/shuffle.js";
|
|
21
|
+
const getAnswer = (identifiers) => {
|
|
22
|
+
const { arrayOfNodeIds, isFilterPossibleProba } = identifiers;
|
|
23
|
+
const arrayOfPossibleProbas = arrayOfNodeIds
|
|
24
|
+
.map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds))
|
|
25
|
+
.filter((node) => {
|
|
26
|
+
return isFilterPossibleProba
|
|
27
|
+
? node.evaluate() >= 0 && substract(node, 1).evaluate() <= 0
|
|
28
|
+
: node.evaluate() < 0 || substract(node, 1).evaluate() > 0;
|
|
29
|
+
})
|
|
30
|
+
.toSorted((nodeA, nodeB) => substract(nodeA, nodeB).evaluate());
|
|
31
|
+
const answer = arrayOfPossibleProbas.map((node) => node.toTex()).join(";");
|
|
32
|
+
return answer;
|
|
33
|
+
};
|
|
34
|
+
const getInstruction = (identifiers) => {
|
|
35
|
+
const { arrayOfNodeIds, isFilterPossibleProba } = identifiers;
|
|
36
|
+
const arrNode = arrayOfNodeIds.map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
37
|
+
return `Parmi les valeurs de la liste ci-dessous, donner celles qui sont des valeurs ${isFilterPossibleProba ? "possibles" : "impossibles"} pour une probabilité
|
|
38
|
+
(séparer les valeurs par des points-virgules) :
|
|
39
|
+
$$
|
|
40
|
+
${arrNode.map((node) => node.toTex()).join(" \\hspace{2mm} ; \\hspace{2mm} ")}
|
|
41
|
+
$$
|
|
42
|
+
`;
|
|
43
|
+
};
|
|
44
|
+
const getHint = () => {
|
|
45
|
+
return "Une probabilité est toujours comprise entre $0\\%$ et $100\\%$.";
|
|
46
|
+
};
|
|
47
|
+
const getCorrection = (identifiers) => {
|
|
48
|
+
return `Les valeurs possibles pour une probabilité sont comprises entre $0$ inclus et $1$ inclus.
|
|
49
|
+
La liste à constituer était donc :
|
|
50
|
+
|
|
51
|
+
$$
|
|
52
|
+
${getAnswer(identifiers)}
|
|
53
|
+
$$
|
|
54
|
+
`;
|
|
55
|
+
};
|
|
56
|
+
const getPropositions = (n, { answer, ...identifiers }) => {
|
|
57
|
+
const { arrayOfNodeIds, isFilterPossibleProba } = identifiers;
|
|
58
|
+
const propositions = [];
|
|
59
|
+
// addValidProp(propositions, answer);
|
|
60
|
+
const allProbas = arrayOfNodeIds.map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
61
|
+
const possibleNodes = allProbas.filter((node) => node.evaluate() >= 0 && substract(node, 1).evaluate() <= 0);
|
|
62
|
+
const impossibleNodes = allProbas.filter((node) => node.evaluate() < 0 || substract(node, 1).evaluate() > 0);
|
|
63
|
+
const validNodes = isFilterPossibleProba ? possibleNodes : impossibleNodes;
|
|
64
|
+
//we keep the order of the question
|
|
65
|
+
addValidProp(propositions, validNodes.map((node) => node.toTex()).join(" ; "));
|
|
66
|
+
while (propositions.length < n) {
|
|
67
|
+
const pickedNodes = allProbas.filter(coinFlip);
|
|
68
|
+
tryToAddWrongProp(propositions, pickedNodes.map((node) => node.toTex()).join(" ; "));
|
|
69
|
+
}
|
|
70
|
+
return shuffleProps(propositions, n);
|
|
71
|
+
};
|
|
72
|
+
const isAnswerValid = (ans, { answer }) => {
|
|
73
|
+
const ansWithoutTrailingSemicolon = ans.slice(-1) === ";" ? ans.slice(0, -1) : ans;
|
|
74
|
+
const arrTex = ansWithoutTrailingSemicolon.split(";");
|
|
75
|
+
const arrNode = arrTex
|
|
76
|
+
.map((tex) => parseLatex(tex))
|
|
77
|
+
.toSorted((nodeA, nodeB) => substract(nodeA, nodeB).evaluate());
|
|
78
|
+
const arrTexSorted = arrNode.map((node) => node.toTex());
|
|
79
|
+
const ansRefined = arrTexSorted.join(";");
|
|
80
|
+
return ansRefined === answer;
|
|
81
|
+
};
|
|
82
|
+
const getKeys = (identifiers) => {
|
|
83
|
+
const { arrayOfNodeIds } = identifiers;
|
|
84
|
+
const arrNode = arrayOfNodeIds.map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
85
|
+
return [
|
|
86
|
+
"semicolon",
|
|
87
|
+
...arrNode.map((node) => {
|
|
88
|
+
return {
|
|
89
|
+
id: "custom",
|
|
90
|
+
label: node.toTex(),
|
|
91
|
+
labelType: "tex",
|
|
92
|
+
mathfieldInstructions: {
|
|
93
|
+
method: "write",
|
|
94
|
+
content: node.toTex(),
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}),
|
|
98
|
+
];
|
|
99
|
+
};
|
|
100
|
+
const optsDefault = {
|
|
101
|
+
numberTypes: ["Entier", "Décimal", "Fraction", "Puiss10", "Sci", "Réel"],
|
|
102
|
+
nbValues: 8,
|
|
103
|
+
};
|
|
104
|
+
const options = [
|
|
105
|
+
{
|
|
106
|
+
id: "numberTypes",
|
|
107
|
+
label: "Types de nombres",
|
|
108
|
+
type: GeneratorOptionType.multiselect,
|
|
109
|
+
target: GeneratorOptionTarget.generation,
|
|
110
|
+
values: ["Entier", "Décimal", "Fraction", "Puiss10", "Sci", "Réel"],
|
|
111
|
+
defaultValue: optsDefault.numberTypes,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: "nbValues",
|
|
115
|
+
label: "Longueur de la liste",
|
|
116
|
+
type: GeneratorOptionType.select,
|
|
117
|
+
target: GeneratorOptionTarget.generation,
|
|
118
|
+
values: [5, 6, 7, 8, 9, 10],
|
|
119
|
+
defaultValue: optsDefault.nbValues,
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
const createRandomNode = (numberType, isPossibleProba) => {
|
|
123
|
+
if (isPossibleProba) {
|
|
124
|
+
switch (numberType) {
|
|
125
|
+
case "Décimal":
|
|
126
|
+
return randfloat(0, 1, randint(1, 7)).toTree();
|
|
127
|
+
case "Fraction": {
|
|
128
|
+
if (probaFlip(0.7)) {
|
|
129
|
+
const num = randint(0, 10_000);
|
|
130
|
+
const den = randint(num, 20_000);
|
|
131
|
+
return frac(num, den);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const num = randfloat(0, 100, randint(1, 3));
|
|
135
|
+
const den = randfloat(100, 200, randint(1, 3));
|
|
136
|
+
return frac(num, den);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
case "Puiss10":
|
|
140
|
+
return power(10, randint(-15, 1));
|
|
141
|
+
case "Sci":
|
|
142
|
+
if (probaFlip(0.7)) {
|
|
143
|
+
return multiply(randfloat(1, 10, randint(1, 5)), power(10, randint(-15, 0)));
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
return multiply(randint(1, 10), power(10, randint(-15, 0)));
|
|
147
|
+
}
|
|
148
|
+
case "Réel":
|
|
149
|
+
return random([
|
|
150
|
+
frac(PiNode, randint(4, 14)),
|
|
151
|
+
sin(randfloat(0, PiNode.value, 2)),
|
|
152
|
+
cos(randfloat(-frac(PiNode, 2).evaluate(), frac(PiNode, 2).evaluate(), 2)),
|
|
153
|
+
exp(randint(-10, 0)),
|
|
154
|
+
sqrt(randfloat(0, 1)),
|
|
155
|
+
]);
|
|
156
|
+
case "Entier":
|
|
157
|
+
default:
|
|
158
|
+
return randint(0, 2).toTree();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
switch (numberType) {
|
|
163
|
+
case "Décimal":
|
|
164
|
+
return coinFlip()
|
|
165
|
+
? randfloat(-100, 0, randint(1, 7), [0]).toTree()
|
|
166
|
+
: randfloat(1, 100, randint(1, 7), [1]).toTree();
|
|
167
|
+
case "Fraction": {
|
|
168
|
+
if (probaFlip(0.7)) {
|
|
169
|
+
const num = coinFlip()
|
|
170
|
+
? randint(10_000, 20_000)
|
|
171
|
+
: randint(-20_000, -10_000);
|
|
172
|
+
const den = randint(0, abs(num).evaluate());
|
|
173
|
+
return frac(num, den);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
const num = coinFlip()
|
|
177
|
+
? randfloat(1, 200, randint(1, 3), [1])
|
|
178
|
+
: randfloat(-200, -1, randint(1, 3));
|
|
179
|
+
const den = randfloat(1, abs(num).evaluate(), randint(1, 3));
|
|
180
|
+
return frac(num, den);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
case "Puiss10":
|
|
184
|
+
return power(10, randint(1, 15));
|
|
185
|
+
case "Sci":
|
|
186
|
+
if (probaFlip(0.7)) {
|
|
187
|
+
return coinFlip()
|
|
188
|
+
? multiply(randfloat(1, 10, randint(1, 5), [1]), power(10, randint(0, 15)))
|
|
189
|
+
: multiply(randfloat(-10, -1, randint(1, 5), [-10]), power(10, randint(0, 15)));
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
return coinFlip()
|
|
193
|
+
? multiply(randint(2, 10), power(10, randint(0, 15)))
|
|
194
|
+
: multiply(randint(-10, -1, [-10]), power(10, randint(0, 15)));
|
|
195
|
+
}
|
|
196
|
+
case "Réel":
|
|
197
|
+
return random([
|
|
198
|
+
PiNode,
|
|
199
|
+
frac(PiNode, randint(2, 4)),
|
|
200
|
+
exp(randint(1, 10)),
|
|
201
|
+
sqrt(randfloat(1, 100, randint(1, 5), [1])),
|
|
202
|
+
]);
|
|
203
|
+
case "Entier":
|
|
204
|
+
default:
|
|
205
|
+
return randint(-100, 100, [0, 1]).toTree();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
const getPossibleValuesForProbaQuestion = (optsIn) => {
|
|
210
|
+
const opts = Object.assign(optsDefault, optsIn) ?? optsDefault;
|
|
211
|
+
const isFilterPossibleProba = coinFlip();
|
|
212
|
+
//create numberType list
|
|
213
|
+
const dictNumberTypeToPriority = {
|
|
214
|
+
Entier: 1,
|
|
215
|
+
Puiss10: 2,
|
|
216
|
+
Décimal: 3,
|
|
217
|
+
Fraction: 4,
|
|
218
|
+
Réel: 5,
|
|
219
|
+
};
|
|
220
|
+
let arrNumberType = [...opts.numberTypes];
|
|
221
|
+
//filler
|
|
222
|
+
while (arrNumberType.length < opts.nbValues) {
|
|
223
|
+
arrNumberType.push(...shuffle(opts.numberTypes));
|
|
224
|
+
}
|
|
225
|
+
arrNumberType = arrNumberType
|
|
226
|
+
.slice(0, opts.nbValues)
|
|
227
|
+
.toSorted((numberType1, numberType2) => dictNumberTypeToPriority[numberType1] -
|
|
228
|
+
dictNumberTypeToPriority[numberType2]);
|
|
229
|
+
//create list
|
|
230
|
+
let arrNode = [];
|
|
231
|
+
const arrIsPossibleProba = [];
|
|
232
|
+
let is0And1AlreadyPicked = false;
|
|
233
|
+
for (let i = 0; i < arrNumberType.length; i++) {
|
|
234
|
+
const numberType = arrNumberType[i];
|
|
235
|
+
//ensure answer is neither an empty list, nor the whole list
|
|
236
|
+
const isLast = i === arrNumberType.length - 1;
|
|
237
|
+
const isPossibleProba = numberType === "Entier" && is0And1AlreadyPicked
|
|
238
|
+
? false
|
|
239
|
+
: isLast &&
|
|
240
|
+
(arrIsPossibleProba.every((b) => b) ||
|
|
241
|
+
arrIsPossibleProba.every((b) => !b))
|
|
242
|
+
? !arrIsPossibleProba[0]
|
|
243
|
+
: coinFlip();
|
|
244
|
+
arrIsPossibleProba.push(isPossibleProba);
|
|
245
|
+
//ensure distinct values
|
|
246
|
+
let nodeCandidate;
|
|
247
|
+
let isAlreadyInList = true;
|
|
248
|
+
do {
|
|
249
|
+
nodeCandidate = createRandomNode(numberType, isPossibleProba);
|
|
250
|
+
isAlreadyInList = arrNode
|
|
251
|
+
.map((node) => node.evaluate())
|
|
252
|
+
.includes(nodeCandidate.evaluate());
|
|
253
|
+
} while (isAlreadyInList);
|
|
254
|
+
arrNode.push(nodeCandidate);
|
|
255
|
+
is0And1AlreadyPicked ||=
|
|
256
|
+
arrNode.map((node) => node.evaluate()).filter((v) => v === 0 || v === 1)
|
|
257
|
+
.length === 2;
|
|
258
|
+
}
|
|
259
|
+
arrNode = shuffle(arrNode);
|
|
260
|
+
const identifiers = {
|
|
261
|
+
arrayOfNodeIds: arrNode.map((node) => node.toIdentifiers()),
|
|
262
|
+
isFilterPossibleProba,
|
|
263
|
+
};
|
|
264
|
+
return getQuestionFromIdentifiers(identifiers, opts);
|
|
265
|
+
};
|
|
266
|
+
const getQuestionFromIdentifiers = (identifiers) => {
|
|
267
|
+
const question = {
|
|
268
|
+
answer: getAnswer(identifiers),
|
|
269
|
+
instruction: getInstruction(identifiers),
|
|
270
|
+
keys: getKeys(identifiers),
|
|
271
|
+
answerFormat: "tex",
|
|
272
|
+
identifiers,
|
|
273
|
+
hint: getHint(identifiers),
|
|
274
|
+
correction: getCorrection(identifiers),
|
|
275
|
+
};
|
|
276
|
+
return question;
|
|
277
|
+
};
|
|
278
|
+
export const possibleValuesForProba = {
|
|
279
|
+
id: "possibleValuesForProba",
|
|
280
|
+
label: "Déterminer les valeurs possibles pour une probabilité",
|
|
281
|
+
isSingleStep: true,
|
|
282
|
+
generator: (nb, opts) => getDistinctQuestions(() => getPossibleValuesForProbaQuestion(opts), nb, 30),
|
|
283
|
+
options,
|
|
284
|
+
qcmTimer: 60,
|
|
285
|
+
freeTimer: 60,
|
|
286
|
+
getPropositions,
|
|
287
|
+
isAnswerValid,
|
|
288
|
+
subject: "Mathématiques",
|
|
289
|
+
maxAllowedQuestions: 30,
|
|
290
|
+
getQuestionFromIdentifiers,
|
|
291
|
+
answerType: "QCM",
|
|
292
|
+
hasHintAndCorrection: true,
|
|
293
|
+
};
|