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.
Files changed (40) hide show
  1. package/lib/exercises/exercise.d.ts +12 -4
  2. package/lib/exercises/exercise.d.ts.map +1 -1
  3. package/lib/exercises/math/dataRepresentations/compareBoxPlot.d.ts +13 -0
  4. package/lib/exercises/math/dataRepresentations/compareBoxPlot.d.ts.map +1 -0
  5. package/lib/exercises/math/dataRepresentations/compareBoxPlot.js +192 -0
  6. package/lib/exercises/math/dataRepresentations/index.d.ts +1 -0
  7. package/lib/exercises/math/dataRepresentations/index.d.ts.map +1 -1
  8. package/lib/exercises/math/dataRepresentations/index.js +1 -0
  9. package/lib/exercises/math/derivation/tangent/derivativeNumberReading.d.ts.map +1 -1
  10. package/lib/exercises/math/derivation/tangent/derivativeNumberReading.js +0 -1
  11. package/lib/exercises/math/functions/affines/index.d.ts +1 -0
  12. package/lib/exercises/math/functions/affines/index.d.ts.map +1 -1
  13. package/lib/exercises/math/functions/affines/index.js +1 -0
  14. package/lib/exercises/math/functions/affines/recognizeAffineGraph.d.ts +18 -0
  15. package/lib/exercises/math/functions/affines/recognizeAffineGraph.d.ts.map +1 -0
  16. package/lib/exercises/math/functions/affines/recognizeAffineGraph.js +144 -0
  17. package/lib/exercises/math/geometry/angles/recognizeAngleType.d.ts +4 -1
  18. package/lib/exercises/math/geometry/angles/recognizeAngleType.d.ts.map +1 -1
  19. package/lib/exercises/math/geometry/angles/recognizeAngleType.js +21 -47
  20. package/lib/exercises/math/primitive/polynomialPrimitive.d.ts.map +1 -1
  21. package/lib/exercises/math/primitive/polynomialPrimitive.js +2 -2
  22. package/lib/exercises/math/probaStat/basicProbas/possibleValuesForProba.d.ts +13 -0
  23. package/lib/exercises/math/probaStat/basicProbas/possibleValuesForProba.d.ts.map +1 -0
  24. package/lib/exercises/math/probaStat/basicProbas/possibleValuesForProba.js +293 -0
  25. package/lib/index.d.ts +779 -760
  26. package/lib/index.d.ts.map +1 -1
  27. package/lib/latexTester.d.ts.map +1 -1
  28. package/lib/latexTester.js +3 -1
  29. package/lib/math/polynomials/trinom.d.ts +1 -0
  30. package/lib/math/polynomials/trinom.d.ts.map +1 -1
  31. package/lib/math/polynomials/trinom.js +5 -0
  32. package/lib/tests/questionTest.d.ts.map +1 -1
  33. package/lib/tests/questionTest.js +4 -0
  34. package/lib/utils/strings/capitalize.d.ts +2 -0
  35. package/lib/utils/strings/capitalize.d.ts.map +1 -0
  36. package/lib/utils/strings/capitalize.js +3 -0
  37. package/lib/utils/strings/reverseString.d.ts +2 -0
  38. package/lib/utils/strings/reverseString.d.ts.map +1 -0
  39. package/lib/utils/strings/reverseString.js +3 -0
  40. 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
+ };