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.
@@ -6,6 +6,9 @@ type Identifiers = {
6
6
  angleIndex: number;
7
7
  apexIndex: number;
8
8
  };
9
- export declare const recognizeAngleType: Exercise<Identifiers>;
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,EAcT,MAAM,6BAA6B,CAAC;AAKrC,OAAO,EAGL,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAUtC,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;AAmVF,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,WAAW,CAcpD,CAAC"}
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
- // let validAngles: string[] = [answer];
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 angleType = random([
215
- "alterne-interne",
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,CA2B7D,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,WAAW,CAYrD,CAAC"}
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(ans);
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
- }, object, string | number | boolean | string[]> | Exercise<{
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<{
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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
+ {"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;;;CAiO3B,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,2 @@
1
+ export declare const reverseString: (str: string) => string;
2
+ //# sourceMappingURL=reverseString.d.ts.map
@@ -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"}
@@ -0,0 +1,3 @@
1
+ export const reverseString = (str) => {
2
+ return str.split('').reverse().join('');
3
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "math-exercises",
3
3
  "type": "module",
4
- "version": "3.0.114",
4
+ "version": "3.0.115",
5
5
  "description": "Math exercises generator for middle school and high school",
6
6
  "main": "lib/index.js",
7
7
  "files": [