math-exercises 3.0.114 → 3.0.115
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/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 +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/tests/questionTest.d.ts.map +1 -1
- package/lib/tests/questionTest.js +4 -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
|
@@ -6,6 +6,9 @@ type Identifiers = {
|
|
|
6
6
|
angleIndex: number;
|
|
7
7
|
apexIndex: number;
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
type Options = {
|
|
10
|
+
angleTypes: string[];
|
|
11
|
+
};
|
|
12
|
+
export declare const recognizeAngleType: Exercise<Identifiers, Options>;
|
|
10
13
|
export {};
|
|
11
14
|
//# sourceMappingURL=recognizeAngleType.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recognizeAngleType.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/angles/recognizeAngleType.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"recognizeAngleType.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/angles/recognizeAngleType.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAiBT,MAAM,6BAA6B,CAAC;AAKrC,OAAO,EAGL,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAWtC,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AA+SF,KAAK,OAAO,GAAG;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAeF,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAe7D,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
|
|
1
|
+
import { addValidProp, shuffleProps, tryToAddWrongProp, GeneratorOptionTarget, GeneratorOptionType, } from "../../../../exercises/exercise.js";
|
|
2
2
|
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
3
|
import { GeogebraConstructor } from "../../../../geogebra/geogebraConstructor.js";
|
|
4
4
|
import { Angle } from "../../../../math/geometry/angle.js";
|
|
@@ -9,6 +9,7 @@ import { randint } from "../../../../math/utils/random/randint.js";
|
|
|
9
9
|
import { NumberNode } from "../../../../tree/nodes/numbers/numberNode.js";
|
|
10
10
|
import { random } from "../../../../utils/alea/random.js";
|
|
11
11
|
import { randomLetter } from "../../../../utils/strings/randomLetter.js";
|
|
12
|
+
import { reverseString } from "../../../../utils/strings/reverseString.js";
|
|
12
13
|
const getAngle = (identifiers) => {
|
|
13
14
|
const indexes = getAnglePointsIndexes(identifiers.angleIndex, identifiers.apexIndex);
|
|
14
15
|
return new Angle(indexes.map((i) => PointConstructor.fromIdentifiers(identifiers.points[i])));
|
|
@@ -168,54 +169,13 @@ const isAnswerValid = (ans, { answer }) => {
|
|
|
168
169
|
formated = formated.replaceAll("\\widehat{", "").replaceAll("}", "");
|
|
169
170
|
}
|
|
170
171
|
//TODO fix vea
|
|
171
|
-
return "\\widehat{" + formated + "}" === answer
|
|
172
|
-
|
|
173
|
-
// switch (angleType) {
|
|
174
|
-
// case "opposé par le sommet":
|
|
175
|
-
// // return studentAngle.isSummitOpposite(answerAngle);
|
|
176
|
-
// case "alterne-interne":
|
|
177
|
-
// // return studentAngle.isAlterneInterne(answerAngle);
|
|
178
|
-
// break;
|
|
179
|
-
// case "correspondant":
|
|
180
|
-
// default:
|
|
181
|
-
// // return studentAngle.isCorrespondant(answerAngle);
|
|
182
|
-
// break;
|
|
183
|
-
// }
|
|
184
|
-
// return validAngles.includes(formated);
|
|
185
|
-
// let formated = ans;
|
|
186
|
-
// if (ans.includes("widehat")) {
|
|
187
|
-
// formated = formated.replaceAll("\\widehat{", "").replaceAll("}", "");
|
|
188
|
-
// }
|
|
189
|
-
// const pointsNames = Array.from(new Set(formated.split("")));
|
|
190
|
-
// if (pointsNames.length !== 3 || pointsNames.some((char) => !isLetter(char)))
|
|
191
|
-
// return false;
|
|
192
|
-
// const studentPoints = pointsNames.map((char) =>
|
|
193
|
-
// PointConstructor.fromIdentifiers(points.find((p) => p.name === char)!),
|
|
194
|
-
// );
|
|
195
|
-
// const answerAngle = getAngle({ angleIndex, apexIndex, points });
|
|
196
|
-
// const studentAngle = new Angle(studentPoints);
|
|
197
|
-
// //? on va accpter aussi des angles correspondants ou alternes-internes qui ne sont pas définis par les sécantes tracées
|
|
198
|
-
// //? c'est chelou mais dans le fond ça fait sens (c'est vrai mathémtiquement)
|
|
199
|
-
// switch (angleType) {
|
|
200
|
-
// case "opposé par le sommet":
|
|
201
|
-
// return studentAngle.isSummitOpposite(answerAngle);
|
|
202
|
-
// case "alterne-interne":
|
|
203
|
-
// return studentAngle.isAlterneInterne(answerAngle);
|
|
204
|
-
// break;
|
|
205
|
-
// case "correspondant":
|
|
206
|
-
// default:
|
|
207
|
-
// return studentAngle.isCorrespondant(answerAngle);
|
|
208
|
-
// break;
|
|
209
|
-
// }
|
|
210
|
-
return false;
|
|
172
|
+
return ("\\widehat{" + formated + "}" === answer ||
|
|
173
|
+
"\\widehat{" + reverseString(formated) + "}" === answer);
|
|
211
174
|
};
|
|
212
175
|
//deux paires de sécantes
|
|
213
|
-
const getRecognizeAngleTypeQuestion = () => {
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
"correspondant",
|
|
217
|
-
"opposé par le sommet",
|
|
218
|
-
]);
|
|
176
|
+
const getRecognizeAngleTypeQuestion = (optsIn) => {
|
|
177
|
+
const opts = optsIn ?? optsDefault;
|
|
178
|
+
const angleType = random(opts.angleTypes);
|
|
219
179
|
const names = [];
|
|
220
180
|
for (let i = 0; i < 12; i++) {
|
|
221
181
|
names.push(randomLetter(true, names));
|
|
@@ -273,11 +233,25 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
273
233
|
};
|
|
274
234
|
return question;
|
|
275
235
|
};
|
|
236
|
+
const optsDefault = {
|
|
237
|
+
angleTypes: ["alterne-interne", "correspondant", "opposé par le sommet"],
|
|
238
|
+
};
|
|
239
|
+
const options = [
|
|
240
|
+
{
|
|
241
|
+
id: "angleTypes",
|
|
242
|
+
label: "Type d'angles demandés",
|
|
243
|
+
target: GeneratorOptionTarget.generation,
|
|
244
|
+
type: GeneratorOptionType.multiselect,
|
|
245
|
+
values: ["alterne-interne", "correspondant", "opposé par le sommet"],
|
|
246
|
+
defaultValue: optsDefault.angleTypes,
|
|
247
|
+
},
|
|
248
|
+
];
|
|
276
249
|
export const recognizeAngleType = {
|
|
277
250
|
id: "recognizeAngleType",
|
|
278
251
|
label: "Reconnaître un angle alterne-interne, correspondant, opposé par le sommet",
|
|
279
252
|
isSingleStep: true,
|
|
280
253
|
generator: (nb, opts) => getDistinctQuestions(() => getRecognizeAngleTypeQuestion(opts), nb),
|
|
254
|
+
options,
|
|
281
255
|
qcmTimer: 60,
|
|
282
256
|
freeTimer: 60,
|
|
283
257
|
getPropositions,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polynomialPrimitive.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/primitive/polynomialPrimitive.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGR,0BAA0B,EAE1B,YAAY,EAEZ,iBAAiB,EACjB,GAAG,EAGJ,MAAM,6BAA6B,CAAC;AAWrC,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAiBF,eAAO,MAAM,sBAAsB,EAAE,iBAAiB,CAAC,WAAW,CAKjE,CAAC;AAEF,eAAO,MAAM,6CAA6C,EAAE,0BAA0B,CACpF,WAAW,CAYZ,CAAC;AAEF,eAAO,MAAM,kCAAkC,EAAE,YAAY,CAAC,WAAW,CAexE,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,GAAG,CAAC,WAAW,
|
|
1
|
+
{"version":3,"file":"polynomialPrimitive.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/primitive/polynomialPrimitive.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGR,0BAA0B,EAE1B,YAAY,EAEZ,iBAAiB,EACjB,GAAG,EAGJ,MAAM,6BAA6B,CAAC;AAWrC,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAiBF,eAAO,MAAM,sBAAsB,EAAE,iBAAiB,CAAC,WAAW,CAKjE,CAAC;AAEF,eAAO,MAAM,6CAA6C,EAAE,0BAA0B,CACpF,WAAW,CAYZ,CAAC;AAEF,eAAO,MAAM,kCAAkC,EAAE,YAAY,CAAC,WAAW,CAexE,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,GAAG,CAAC,WAAW,CA8B7D,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,WAAW,CAYrD,CAAC"}
|
|
@@ -46,12 +46,12 @@ export const getPolynomialPrimitivePropositions = (n, { answer, coeffs }) => {
|
|
|
46
46
|
}
|
|
47
47
|
return shuffle(propositions);
|
|
48
48
|
};
|
|
49
|
-
export const isPolynomialPrimitiveAnswerValid = (ans) => {
|
|
49
|
+
export const isPolynomialPrimitiveAnswerValid = (ans, { answer }) => {
|
|
50
50
|
try {
|
|
51
51
|
const parsed = parseAlgebraic(ans);
|
|
52
52
|
if (!parsed)
|
|
53
53
|
return false;
|
|
54
|
-
const ansParsed = parseAlgebraic(
|
|
54
|
+
const ansParsed = parseAlgebraic(answer);
|
|
55
55
|
return (parsed
|
|
56
56
|
.simplify({
|
|
57
57
|
towardsDistribute: true,
|
|
@@ -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
|
+
};
|
package/lib/index.d.ts
CHANGED
|
@@ -1706,7 +1706,9 @@ declare const mathExercises: (Exercise<{
|
|
|
1706
1706
|
angleType: string;
|
|
1707
1707
|
angleIndex: number;
|
|
1708
1708
|
apexIndex: number;
|
|
1709
|
-
},
|
|
1709
|
+
}, {
|
|
1710
|
+
angleTypes: string[];
|
|
1711
|
+
}, string | number | boolean | string[]> | Exercise<{
|
|
1710
1712
|
doubleAngle: number;
|
|
1711
1713
|
singleAngle: number;
|
|
1712
1714
|
}, object, string | number | boolean | string[]> | Exercise<{
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAE3D,OAAO,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,QAAA,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAE3D,OAAO,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mDAA+B,CAAC;AACnD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mDAA6B,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questionTest.d.ts","sourceRoot":"","sources":["../../src/tests/questionTest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAIjE,eAAO,MAAM,YAAY,GACvB,KAAK,QAAQ,CAAC,MAAM,CAAC,EACrB,UAAU,QAAQ,CAAC,MAAM,CAAC;;;
|
|
1
|
+
{"version":3,"file":"questionTest.d.ts","sourceRoot":"","sources":["../../src/tests/questionTest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAIjE,eAAO,MAAM,YAAY,GACvB,KAAK,QAAQ,CAAC,MAAM,CAAC,EACrB,UAAU,QAAQ,CAAC,MAAM,CAAC;;;CAuO3B,CAAC"}
|
|
@@ -130,6 +130,8 @@ export const questionTest = (exo, question) => {
|
|
|
130
130
|
// };
|
|
131
131
|
// }
|
|
132
132
|
// }
|
|
133
|
+
if (exo.answerType !== "QCM" && exo.isQCM)
|
|
134
|
+
throw new Error("exo " + exo.id + " has isQCM but answerType is not QCM");
|
|
133
135
|
if (exo.answerType !== "QCM" &&
|
|
134
136
|
exo.answerType !== "QCU" &&
|
|
135
137
|
exo.answerType !== "GGB" &&
|
|
@@ -152,6 +154,8 @@ export const questionTest = (exo, question) => {
|
|
|
152
154
|
exo.answerType !== "valueTable" &&
|
|
153
155
|
exo.answerType !== "varTable" &&
|
|
154
156
|
exo.answerType !== "signTable") {
|
|
157
|
+
if (exo.answerType === "QCM" && !exo.isQCM)
|
|
158
|
+
throw new Error("exo " + exo.id + " has answerType QCM but not isQCM");
|
|
155
159
|
const before = Date.now();
|
|
156
160
|
console.log("will generate props : ", exo.id, "ids :", question.identifiers);
|
|
157
161
|
const props = exo.getPropositions(4, {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reverseString.d.ts","sourceRoot":"","sources":["../../../src/utils/strings/reverseString.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,KAAG,MAE3C,CAAC"}
|