math-exercises 3.0.126 → 3.0.127

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 (64) hide show
  1. package/lib/exercises/math/calcul/mentalCaluls/mentalProgramSolve.d.ts +1 -1
  2. package/lib/exercises/math/calcul/mentalCaluls/mentalProgramSolve.d.ts.map +1 -1
  3. package/lib/exercises/math/calcul/mentalCaluls/mentalProgramSolve.js +56 -42
  4. package/lib/exercises/math/calcul/ordering/compareABUsingQuotient.d.ts.map +1 -1
  5. package/lib/exercises/math/calcul/ordering/compareABUsingQuotient.js +5 -103
  6. package/lib/exercises/math/calcul/ordering/compareFracABWithFracAPlusCBPlusC.d.ts.map +1 -1
  7. package/lib/exercises/math/calcul/ordering/compareFracABWithFracAPlusCBPlusC.js +22 -8
  8. package/lib/exercises/math/calcul/ordering/compareFracAndDec.d.ts.map +1 -1
  9. package/lib/exercises/math/calcul/ordering/compareFracAndDec.js +7 -6
  10. package/lib/exercises/math/calcul/ordering/compareWithSquareRoots.d.ts.map +1 -1
  11. package/lib/exercises/math/calcul/ordering/compareWithSquareRoots.js +4 -4
  12. package/lib/exercises/math/calculLitteral/equation/equationFromProblem.d.ts.map +1 -1
  13. package/lib/exercises/math/calculLitteral/equation/equationFromProblem.js +57 -17
  14. package/lib/exercises/math/calculLitteral/isolate/isolateUInInvXPlusInvYEqualsInvU.d.ts.map +1 -1
  15. package/lib/exercises/math/calculLitteral/isolate/isolateUInInvXPlusInvYEqualsInvU.js +6 -27
  16. package/lib/exercises/math/calculLitteral/ordering/compareAMinusB.d.ts.map +1 -1
  17. package/lib/exercises/math/calculLitteral/ordering/compareAMinusB.js +3 -5
  18. package/lib/exercises/math/calculLitteral/ordering/compareFromPiMinusFrac.js +1 -1
  19. package/lib/exercises/math/calculLitteral/writing/writeLitExpFromFrenchExp.d.ts.map +1 -1
  20. package/lib/exercises/math/calculLitteral/writing/writeLitExpFromFrenchExp.js +69 -23
  21. package/lib/exercises/math/conversion/kmPerMinToKmPerHourConversion.d.ts +4 -1
  22. package/lib/exercises/math/conversion/kmPerMinToKmPerHourConversion.d.ts.map +1 -1
  23. package/lib/exercises/math/conversion/kmPerMinToKmPerHourConversion.js +52 -34
  24. package/lib/exercises/math/conversion/prefixToNumber.d.ts.map +1 -1
  25. package/lib/exercises/math/conversion/prefixToNumber.js +14 -4
  26. package/lib/exercises/math/conversion/secondsToHours.js +1 -1
  27. package/lib/exercises/math/dataRepresentations/barChartInterpreting.d.ts +5 -2
  28. package/lib/exercises/math/dataRepresentations/barChartInterpreting.d.ts.map +1 -1
  29. package/lib/exercises/math/dataRepresentations/barChartInterpreting.js +47 -31
  30. package/lib/exercises/math/dataRepresentations/cartesianGraphExtremaReading.d.ts.map +1 -1
  31. package/lib/exercises/math/dataRepresentations/cartesianGraphExtremaReading.js +5 -4
  32. package/lib/exercises/math/dataRepresentations/dataToGraphGraphToData.js +4 -4
  33. package/lib/exercises/math/dataRepresentations/graphReading.js +13 -13
  34. package/lib/exercises/math/dataRepresentations/histogramReading.d.ts.map +1 -1
  35. package/lib/exercises/math/dataRepresentations/histogramReading.js +32 -32
  36. package/lib/exercises/math/dataRepresentations/plausibleGraph.d.ts.map +1 -1
  37. package/lib/exercises/math/dataRepresentations/plausibleGraph.js +53 -4
  38. package/lib/exercises/math/functions/affines/coordsOfPointOnAffineFindX.d.ts.map +1 -1
  39. package/lib/exercises/math/functions/affines/coordsOfPointOnAffineFindX.js +17 -3
  40. package/lib/exercises/math/functions/affines/coordsOfPointOnAffineFindY.d.ts.map +1 -1
  41. package/lib/exercises/math/functions/affines/coordsOfPointOnAffineFindY.js +27 -9
  42. package/lib/exercises/math/functions/affines/drawAffineFromProgCalc.d.ts.map +1 -1
  43. package/lib/exercises/math/functions/affines/drawAffineFromProgCalc.js +33 -16
  44. package/lib/exercises/math/functions/affines/representationOfAffine.d.ts +3 -0
  45. package/lib/exercises/math/functions/affines/representationOfAffine.d.ts.map +1 -1
  46. package/lib/exercises/math/functions/affines/representationOfAffine.js +121 -30
  47. package/lib/exercises/math/functions/basics/coordsOfPointOnCurveFindY.d.ts.map +1 -1
  48. package/lib/exercises/math/functions/basics/coordsOfPointOnCurveFindY.js +29 -10
  49. package/lib/exercises/math/functions/composition/functionComposition.d.ts.map +1 -1
  50. package/lib/exercises/math/functions/composition/functionComposition.js +2 -2
  51. package/lib/exercises/math/probaStat/basicProbas/possibleValuesForProba.d.ts.map +1 -1
  52. package/lib/exercises/math/probaStat/basicProbas/possibleValuesForProba.js +24 -9
  53. package/lib/exercises/math/probaStat/conditionalProbaWriteFromFrench.d.ts.map +1 -1
  54. package/lib/exercises/math/probaStat/conditionalProbaWriteFromFrench.js +9 -5
  55. package/lib/exercises/math/probaStat/probaAsSumOfProbas.d.ts +0 -1
  56. package/lib/exercises/math/probaStat/probaAsSumOfProbas.d.ts.map +1 -1
  57. package/lib/exercises/math/probaStat/probaAsSumOfProbas.js +13 -14
  58. package/lib/exercises/math/probaStat/stats1var/interpretIndicatorsForLists.d.ts.map +1 -1
  59. package/lib/exercises/math/probaStat/stats1var/interpretIndicatorsForLists.js +2 -3
  60. package/lib/exercises/math/probaStat/stats1var/plausibilityOfAverage.d.ts.map +1 -1
  61. package/lib/exercises/math/probaStat/stats1var/plausibilityOfAverage.js +26 -25
  62. package/lib/index.d.ts +10 -5
  63. package/lib/index.d.ts.map +1 -1
  64. package/package.json +1 -1
@@ -11,6 +11,8 @@ import { substract } from "../../../../tree/nodes/operators/substractNode.js";
11
11
  import { random, randomMany } from "../../../../utils/alea/random.js";
12
12
  import { isOperatorNode, OperatorIds, } from "../../../../tree/nodes/operators/operatorNode.js";
13
13
  import { parseLatex } from "../../../../tree/parsers/latexParser.js";
14
+ import { mdTable } from "../../../../utils/markdown/mdTable.js";
15
+ import { alignTex } from "../../../../utils/latex/alignTex.js";
14
16
  class ProblemConstructor {
15
17
  static byHydratingSkeleton(skeleton, groupNameToVarNameToValue, mysteryVarPath, shuffleArrays) {
16
18
  const shuffleFuncs = shuffleArrays.map((shuffleArray) => {
@@ -70,6 +72,16 @@ class Problem {
70
72
  .filter((node) => !!node);
71
73
  });
72
74
  }
75
+ getExplanationString() {
76
+ const arrArr = Object.values(this.groups).map((group) => [
77
+ `\\text{${group.getScalarString(this.mysteryVar).replaceAll("$", "")}}`,
78
+ `:`,
79
+ `${group
80
+ .getNode(this.mysteryVar, this.groups, this.shuffleFuncs)
81
+ .toTex()}`,
82
+ ]);
83
+ return alignTex(arrArr, false);
84
+ }
73
85
  }
74
86
  class ProblemVarGroup {
75
87
  skeleton;
@@ -84,6 +96,9 @@ class ProblemVarGroup {
84
96
  getNode(mysteryVar, groups, shuffleFuncs) {
85
97
  return this.skeleton.nodeFunc(this, mysteryVar, groups, shuffleFuncs);
86
98
  }
99
+ getScalarString(mysteryVar) {
100
+ return `${this.skeleton.strToScalar} ${this.toTex(mysteryVar)}`;
101
+ }
87
102
  }
88
103
  class ProblemVar {
89
104
  skeleton;
@@ -101,12 +116,14 @@ class ProblemVar {
101
116
  }
102
117
  class ProblemVarSkeletonGroup {
103
118
  vars;
119
+ strToScalar;
104
120
  strFunc;
105
121
  nodeFunc;
106
122
  isCanBeMysteryGroup;
107
123
  isComputed;
108
- constructor(vars, strFunc, nodeFunc, isCanBeMysteryGroup, isComputed) {
124
+ constructor(vars, strToScalar, strFunc, nodeFunc, isCanBeMysteryGroup, isComputed) {
109
125
  this.vars = vars;
126
+ this.strToScalar = strToScalar;
110
127
  this.strFunc = strFunc;
111
128
  this.nodeFunc = nodeFunc;
112
129
  this.isCanBeMysteryGroup = isCanBeMysteryGroup;
@@ -154,14 +171,11 @@ const skeletons = [
154
171
  Elle a pris trois pâtes à pizza à 1,95 € l’unité et deux pots de sauce tomate.
155
172
  Elle a payé au total 8,37 €.
156
173
  Quel est le prix, noté a, d'un pot de sauce ?`, (_group, mysteryVar, groups, shuffleFuncs) => {
157
- const { pizza, sauce, total } = groups;
158
- const [gp1, gp2] = shuffleFuncs[0]([pizza, sauce]);
159
- return `Clara a acheté des ingrédients pour réaliser des pizzas.
160
- Elle a pris ${gp1.toTex(mysteryVar)} et, dans un autre rayon, ${gp2.toTex(mysteryVar)}.
161
- Elle a payé au total $${total
174
+ const { total, ...groupsWithoutTotal } = groups;
175
+ const [gp1, gp2] = shuffleFuncs[0](Object.values(groupsWithoutTotal));
176
+ return `Clara a acheté des ingrédients pour réaliser des pizzas. Elle a pris ${gp1.toTex(mysteryVar)} et, dans un autre rayon, ${gp2.toTex(mysteryVar)}. Elle a payé au total $${total
162
177
  .getNode(mysteryVar, groups, shuffleFuncs)
163
- .toTex()}$ €.
164
- ${mysteryVar.skeleton.question}`;
178
+ .toTex()}$ €. ${mysteryVar.skeleton.question}`;
165
179
  }, (_group, mysteryVar, groups, shuffleFuncs) => {
166
180
  const { pizza, sauce } = groups;
167
181
  const [gp1, gp2] = shuffleFuncs[0]([pizza, sauce]);
@@ -184,7 +198,7 @@ ${mysteryVar.skeleton.question}`;
184
198
  return randfloat(0.5, 4, 2, []).toTree();
185
199
  },
186
200
  },
187
- }, (group, mysteryVar) => {
201
+ }, "le coût pour", (group, mysteryVar) => {
188
202
  switch (mysteryVar?.skeleton.varName) {
189
203
  case "n":
190
204
  return `des pâtes à pizza à $${group.vars.price.value.toTex()}$ € l’unité`;
@@ -223,7 +237,7 @@ ${mysteryVar.skeleton.question}`;
223
237
  return randfloat(0.5, 4, 2, []).toTree();
224
238
  },
225
239
  },
226
- }, (group, mysteryVar) => {
240
+ }, "le coût pour", (group, mysteryVar) => {
227
241
  switch (mysteryVar?.skeleton.varName) {
228
242
  case "m":
229
243
  return `des boîtes de sauce tomate à $${group.vars.price.value.toTex()}$ € l’unité`;
@@ -251,11 +265,11 @@ ${mysteryVar.skeleton.question}`;
251
265
  str: "le coût total",
252
266
  question: `Quel est le coût total, noté $t$, de ses achats ?`,
253
267
  },
254
- }, () => {
255
- return "le coût total";
268
+ }, "le", () => {
269
+ return "coût total";
256
270
  }, (_group, _mysteryVar, groups, shuffleFuncs) => {
257
- const { pizza, sauce } = groups;
258
- const orderedNodes = shuffleFuncs[0]([pizza, sauce]).map((group) => group.getNode());
271
+ const { total, ...groupsWithoutTotal } = groups;
272
+ const orderedNodes = shuffleFuncs[0](Object.values(groupsWithoutTotal)).map((group) => group.getNode());
259
273
  // console.log(
260
274
  // "orderedNodes[0].leftChild",
261
275
  // (orderedNodes[0] as MultiplyNode).leftChild,
@@ -278,11 +292,34 @@ const getInstruction = (identifiers) => {
278
292
  const { problemSkeletonIndex, groupNameToVarNameToValue, mysteryVarPath, shuffleArrays, } = identifiers;
279
293
  const skeleton = skeletons[problemSkeletonIndex];
280
294
  const problem = ProblemConstructor.byHydratingSkeleton(skeleton, groupNameToVarNameToValue, mysteryVarPath, shuffleArrays);
281
- return `Traduire par une équation le problème suivant :
282
- ${problem.frenchStr}`;
295
+ return `${mdTable([[""], [problem.frenchStr]])}
296
+
297
+ Parmi les équations suivantes, laquelle modélise cette situation ?`;
298
+ };
299
+ const getHint = (identifiers) => {
300
+ const { problemSkeletonIndex, groupNameToVarNameToValue, mysteryVarPath, shuffleArrays, } = identifiers;
301
+ const skeleton = skeletons[problemSkeletonIndex];
302
+ const problem = ProblemConstructor.byHydratingSkeleton(skeleton, groupNameToVarNameToValue, mysteryVarPath, shuffleArrays);
303
+ return `${Object.values(problem.groups).map((group) => `Quel est ${group.getScalarString(problem.mysteryVar)} ?`).join(`
304
+
305
+ `)}`;
306
+ };
307
+ const getCorrection = (identifiers) => {
308
+ const { problemSkeletonIndex, groupNameToVarNameToValue, mysteryVarPath, shuffleArrays, } = identifiers;
309
+ const skeleton = skeletons[problemSkeletonIndex];
310
+ const problem = ProblemConstructor.byHydratingSkeleton(skeleton, groupNameToVarNameToValue, mysteryVarPath, shuffleArrays);
311
+ return `On peut former les expressions suivantes:
312
+ ${problem.getExplanationString()}
313
+
314
+ L'équation qui modélise la situation est donc:
315
+
316
+ $$
317
+ ${getAnswer(identifiers)}
318
+ $$
319
+
320
+ `;
283
321
  };
284
322
  const getAnswerNode = (identifiers) => {
285
- console.log("getAnswerNode", identifiers);
286
323
  const { problemSkeletonIndex, groupNameToVarNameToValue, mysteryVarPath, shuffleArrays, } = identifiers;
287
324
  const skeleton = skeletons[problemSkeletonIndex];
288
325
  const problem = ProblemConstructor.byHydratingSkeleton(skeleton, groupNameToVarNameToValue, mysteryVarPath, shuffleArrays);
@@ -333,6 +370,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
333
370
  const question = {
334
371
  answer: getAnswer(identifiers),
335
372
  instruction: getInstruction(identifiers),
373
+ hint: getHint(identifiers),
374
+ correction: getCorrection(identifiers),
336
375
  keys: getKeys(identifiers),
337
376
  answerFormat: "tex",
338
377
  identifiers,
@@ -411,4 +450,5 @@ export const equationFromProblem = {
411
450
  subject: "Mathématiques",
412
451
  getQuestionFromIdentifiers,
413
452
  answerType: "QCU",
453
+ hasHintAndCorrection: true,
414
454
  };
@@ -1 +1 @@
1
- {"version":3,"file":"isolateUInInvXPlusInvYEqualsInvU.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calculLitteral/isolate/isolateUInInvXPlusInvYEqualsInvU.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;AAIrC,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AA2FF,eAAO,MAAM,gCAAgC,EAAE,QAAQ,CAAC,WAAW,CAmBlE,CAAC;AAUF,eAAO,MAAM,kCAAkC,EAAE,QAAQ,CAAC,WAAW,CAoBpE,CAAC"}
1
+ {"version":3,"file":"isolateUInInvXPlusInvYEqualsInvU.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calculLitteral/isolate/isolateUInInvXPlusInvYEqualsInvU.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;AAKrC,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAqEF,eAAO,MAAM,gCAAgC,EAAE,QAAQ,CAAC,WAAW,CAmBlE,CAAC;AAUF,eAAO,MAAM,kCAAkC,EAAE,QAAQ,CAAC,WAAW,CAoBpE,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
2
2
  import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
3
3
  import { randomMany } from "../../../../utils/alea/random.js";
4
+ import { alignTex } from "../../../../utils/latex/alignTex.js";
4
5
  const getInstruction = (identifiers) => {
5
6
  const { varNames } = identifiers;
6
7
  const [x, y, u] = varNames;
@@ -20,33 +21,11 @@ const getHint = (identifiers) => {
20
21
  const getCorrection = (identifiers) => {
21
22
  const { varNames } = identifiers;
22
23
  const [x, y, u] = varNames;
23
- return `L'inverse de $\\frac{1}{${u}}$ est $${u}$.
24
-
25
- L'inverse de $\\frac{1}{${x}}+\\frac{1}{${y}}$ est $\\frac{1}{\\frac{1}{${x}}+\\frac{1}{${y}}}$.
26
-
27
- Il faut donc mettre ces deux fractions au même dénominateur.
28
-
29
- On obtient :
30
-
31
- $$
32
- \\frac{1}{\\frac{1}{${x}}+\\frac{1}{${y}}}
33
- $$
34
-
35
- $$
36
- = \\frac{1}{\\frac{${x}+${y}}{${x}${y}}}
37
- $$
38
-
39
- $$
40
- = \\frac{${x}${y}}{${x}+${y}}
41
- $$
42
-
43
- Conclusion :
44
-
45
- $$
46
- \\frac{1}{${u}} = \\frac{${x}${y}}{${x}+${y}}
47
- $$
48
-
49
- `;
24
+ return alignTex([
25
+ [`${u}`, "=", `\\frac{1}{\\frac{1}{${x}}+\\frac{1}{${y}}}`],
26
+ [``, "=", `\\frac{1}{\\frac{${x}+${y}}{${x}${y}}}`],
27
+ [``, "=", `\\frac{${x}${y}}{${x}+${y}}`],
28
+ ]);
50
29
  };
51
30
  const getPropositions = (nbProps, { answer, ...identifiers }) => {
52
31
  const { varNames } = identifiers;
@@ -1 +1 @@
1
- {"version":3,"file":"compareAMinusB.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calculLitteral/ordering/compareAMinusB.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AAMrC,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAkMF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,CAgBhD,CAAC"}
1
+ {"version":3,"file":"compareAMinusB.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calculLitteral/ordering/compareAMinusB.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AAMrC,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AA+LF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,CAgBhD,CAAC"}
@@ -12,9 +12,8 @@ $$
12
12
 
13
13
  alors on peut dire que :`;
14
14
  };
15
- const getHint = (identifiers) => {
16
- const { names } = identifiers;
17
- return `Il s'agit de comparer $${names[0]}$ et $${names[1]}$.`;
15
+ const getHint = () => {
16
+ return `Essaye d’isoler chaque variable de chaque côté de l’inégalité.`;
18
17
  };
19
18
  const getCorrection = (identifiers) => {
20
19
  const { names, texInstruction, texsCorrection } = identifiers;
@@ -67,7 +66,7 @@ const isAnswerValid = (ans, { texsAnswer }) => {
67
66
  };
68
67
  const getCompareAMinusBQuestion = () => {
69
68
  const namesPool = ["a", "b", "c", "d", "r", "s", "t", "u", "v"];
70
- let names = randomMany(namesPool, 2);
69
+ const names = randomMany(namesPool, 2);
71
70
  const compareSymbol = random(["inf", "sup", "leq", "geq"]);
72
71
  let texsObjectArray = [];
73
72
  switch (compareSymbol) {
@@ -144,7 +143,6 @@ const getCompareAMinusBQuestion = () => {
144
143
  texInstruction = replaceVarNames(texInstruction);
145
144
  texsCorrection = texsCorrection.map((tex) => replaceVarNames(tex));
146
145
  texsAnswer = texsAnswer.map((tex) => replaceVarNames(tex));
147
- names = order.map((i) => names[i]);
148
146
  return getQuestionFromIdentifiers({
149
147
  names,
150
148
  texInstruction,
@@ -129,7 +129,7 @@ const getQuestionFromIdentifiers = (identifiers, opts) => {
129
129
  };
130
130
  export const compareFromPiMinusFrac = {
131
131
  id: "compareFromPiMinusFrac",
132
- label: "Comparer deux nombres (Pi et une fraction approximante) par le calcul de leur différence",
132
+ label: "Comparer deux nombres ($\\pi$ et une fraction approximante) par le calcul de leur différence",
133
133
  isSingleStep: true,
134
134
  generator: (nb, opts) => getDistinctQuestions(() => getCompareFromPiMinusFracQuestion(opts), nb, 30),
135
135
  qcmTimer: 60,
@@ -1 +1 @@
1
- {"version":3,"file":"writeLitExpFromFrenchExp.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calculLitteral/writing/writeLitExpFromFrenchExp.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAmCrC,KAAK,QAAQ,GACT,UAAU,GACV,SAAS,GACT,KAAK,GACL,UAAU,GACV,UAAU,GACV,QAAQ,CAAC;AAoEb,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,QAAQ,CAAC;IACvB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC/B,wBAAwB,EAAE,OAAO,CAAC;CACnC,CAAC;AAyNF,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,WAAW,CAkBxD,CAAC"}
1
+ {"version":3,"file":"writeLitExpFromFrenchExp.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calculLitteral/writing/writeLitExpFromFrenchExp.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAmCrC,KAAK,QAAQ,GACT,UAAU,GACV,SAAS,GACT,KAAK,GACL,UAAU,GACV,UAAU,GACV,QAAQ,CAAC;AAoEb,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,QAAQ,CAAC;IACvB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC/B,wBAAwB,EAAE,OAAO,CAAC;CACnC,CAAC;AAuRF,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,WAAW,CAmBxD,CAAC"}
@@ -40,27 +40,27 @@ class ExpressionConstructor {
40
40
  case "opposite":
41
41
  return {
42
42
  node: opposite(a),
43
- str__french: `L'opposé de $ ${a} $`,
43
+ strFrench: `L'opposé de $ ${a} $`,
44
44
  };
45
45
  case "inverse":
46
46
  return {
47
47
  node: frac(1, a),
48
- str__french: `L'inverse de $ ${a} $`,
48
+ strFrench: `L'inverse de $ ${a} $`,
49
49
  };
50
50
  case "add":
51
51
  return {
52
52
  node: add(a, b),
53
- str__french: `La somme de $ ${a} $ et de $ ${b} $`,
53
+ strFrench: `La somme de $ ${a} $ et de $ ${b} $`,
54
54
  };
55
55
  case "subtract":
56
56
  return {
57
57
  node: substract(a, b),
58
- str__french: `La différence entre $ ${a} $ et $ ${b} $`,
58
+ strFrench: `La différence entre $ ${a} $ et $ ${b} $`,
59
59
  };
60
60
  case "multiply":
61
61
  return {
62
62
  node: multiply(a, b),
63
- str__french: typeof b === "string" && isUsingFrenchFactorNouns
63
+ strFrench: typeof b === "string" && isUsingFrenchFactorNouns
64
64
  ? dictTexFactorToFrenchFactor[a.frenchify()]
65
65
  ? `${dictTexFactorToFrenchFactor[a.frenchify()]} de $ ${b} $`
66
66
  : `Le produit de $ ${a} $ par $ ${b} $`
@@ -69,7 +69,7 @@ class ExpressionConstructor {
69
69
  case "divide":
70
70
  return {
71
71
  node: frac(a, b),
72
- str__french: typeof a === "string" && isUsingFrenchFactorNouns
72
+ strFrench: typeof a === "string" && isUsingFrenchFactorNouns
73
73
  ? dictTexFactorToFrenchFactor[frac(1, b).toTex()]
74
74
  ? `${dictTexFactorToFrenchFactor[frac(1, b).toTex()]} de $ ${a} $`
75
75
  : `Le quotient de $ ${a} $ par $ ${b} $`
@@ -145,7 +145,7 @@ const getAnswer = (identifiers) => {
145
145
  return node.toTex();
146
146
  };
147
147
  const getInstruction = (identifiers) => {
148
- const statementString = ExpressionConstructor.fromIdentifiers(identifiers).str__french;
148
+ const statementString = ExpressionConstructor.fromIdentifiers(identifiers).strFrench;
149
149
  return `Écrire l'expression littérale pour :
150
150
 
151
151
  ${statementString}
@@ -157,32 +157,77 @@ const getHint = (identifiers) => {
157
157
  case "opposite":
158
158
  return `La somme d'un nombre et de son opposé donne $0$.`;
159
159
  case "inverse":
160
- return `L'inverse de $8$ est $0.25$.`;
160
+ return `L'inverse de $8$ est $0,25$.`;
161
161
  case "add":
162
- return `La somme de $8457$ et de $6567$ est $${8457 + 6567}$.`;
162
+ return `La somme de $8$ et de $6$ est $14$.`;
163
163
  case "subtract":
164
- return `La différence entre $8457$ est $6567$ est $${8457 - 6567}$.`;
165
- case "multiply":
166
- return `Le produit de $8457$ par $6567$ est $${8457 * 6567}$ .`;
167
- case "divide":
168
- return `Le quotient de $200$ par $8$ est $25$.`;
164
+ return `La différence entre $8$ et $6$ est $2$.`;
165
+ case "multiply": {
166
+ const statementString = ExpressionConstructor.fromIdentifiers(identifiers).strFrench;
167
+ if (!statementString.includes("produit")) {
168
+ const bHint = randint(2, 10, typeof identifiers.b === "number" ? [identifiers.b] : []);
169
+ const exprHint1 = ExpressionConstructor.fromIdentifiers(Object.assign({}, identifiers, {
170
+ b: "" + bHint,
171
+ }));
172
+ const exprHint2 = ExpressionConstructor.fromIdentifiers(Object.assign({}, identifiers, {
173
+ b: bHint,
174
+ }));
175
+ return `${capitalize(exprHint1.strFrench)} est $${exprHint2.node
176
+ .simplify()
177
+ .toTex()}$.`;
178
+ }
179
+ else {
180
+ return `Le produit de $8$ par $6$ est $48$.`;
181
+ }
182
+ }
183
+ case "divide": {
184
+ const statementString = ExpressionConstructor.fromIdentifiers(identifiers).strFrench;
185
+ if (!statementString.includes("quotient")) {
186
+ const aHint = randint(2, 10, typeof identifiers.a === "number" ? [identifiers.a] : []);
187
+ const exprHint1 = ExpressionConstructor.fromIdentifiers(Object.assign({}, identifiers, {
188
+ a: "" + aHint,
189
+ }));
190
+ const exprHint2 = ExpressionConstructor.fromIdentifiers(Object.assign({}, identifiers, {
191
+ a: aHint,
192
+ }));
193
+ return `${capitalize(exprHint1.strFrench)} est $${exprHint2.node.toTex()}$.`;
194
+ }
195
+ else {
196
+ return `Le quotient de $200$ par $8$ est $25$.`;
197
+ }
198
+ }
169
199
  }
170
200
  };
171
201
  const getCorrection = (identifiers) => {
202
+ const { a, operatorName, b } = identifiers;
172
203
  const expression = ExpressionConstructor.fromIdentifiers(identifiers);
173
- const statementString = expression.str__french;
174
- let outString = `${capitalize(statementString)} est $ ${getAnswer(identifiers)} $.`;
204
+ const statementString = expression.strFrench;
175
205
  //explain rewriting if needed
176
206
  const nodeRaw = expression.node;
177
207
  const nodeRefined = nodeRaw.simplify();
178
- const texRaw = nodeRaw.toTex({
179
- allowDoubleMinus: true,
180
- forceTimesSign: true,
181
- forceParenthesis: true,
182
- forceNoSimplification: true,
183
- allowMinusAnywhereInFraction: true,
184
- });
208
+ let texRaw;
209
+ switch (operatorName) {
210
+ case "add":
211
+ {
212
+ const [texA, texB] = [a, b].map((c) => parseAlgebraic("" + c).toTex());
213
+ const isWrapWithParenthesis = ("" + b).startsWith("-");
214
+ texRaw = `${texA}+${isWrapWithParenthesis ? `(${texB})` : `${texB}`}`;
215
+ }
216
+ break;
217
+ default:
218
+ {
219
+ texRaw = nodeRaw.toTex({
220
+ allowDoubleMinus: true,
221
+ forceTimesSign: true,
222
+ forceParenthesis: true,
223
+ forceNoSimplification: true,
224
+ allowMinusAnywhereInFraction: true,
225
+ });
226
+ }
227
+ break;
228
+ }
185
229
  const texRefined = nodeRefined.toTex();
230
+ let outString = `${capitalize(statementString)} est $ ${texRefined} $.`;
186
231
  if (texRaw !== texRefined) {
187
232
  outString += `
188
233
 
@@ -282,4 +327,5 @@ export const writeLitExprFromFrench = {
282
327
  getAnswer,
283
328
  getQuestionFromIdentifiers,
284
329
  hasHintAndCorrection: true,
330
+ answerType: "QCU",
285
331
  };
@@ -3,6 +3,9 @@ type Identifiers = {
3
3
  distance: number;
4
4
  minutes: number;
5
5
  };
6
- export declare const kmPerMinToKmPerHourConversion: Exercise<Identifiers>;
6
+ type Options = {
7
+ unitTex: string;
8
+ };
9
+ export declare const kmPerMinToKmPerHourConversion: Exercise<Identifiers, Options>;
7
10
  export {};
8
11
  //# sourceMappingURL=kmPerMinToKmPerHourConversion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"kmPerMinToKmPerHourConversion.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/conversion/kmPerMinToKmPerHourConversion.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAWrC,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAkHF,eAAO,MAAM,6BAA6B,EAAE,QAAQ,CAAC,WAAW,CAiB/D,CAAC"}
1
+ {"version":3,"file":"kmPerMinToKmPerHourConversion.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/conversion/kmPerMinToKmPerHourConversion.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAiBT,MAAM,6BAA6B,CAAC;AAWrC,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AA2IF,KAAK,OAAO,GAAG;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAgBF,eAAO,MAAM,6BAA6B,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAqBxE,CAAC"}
@@ -1,4 +1,4 @@
1
- import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../exercises/exercise.js";
1
+ import { GeneratorOptionTarget, GeneratorOptionType, addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../exercises/exercise.js";
2
2
  import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
3
  import { dividersOf } from "../../../math/utils/arithmetic/dividersOf.js";
4
4
  import { randint } from "../../../math/utils/random/randint.js";
@@ -7,85 +7,103 @@ import { multiply } from "../../../tree/nodes/operators/multiplyNode.js";
7
7
  import { substract } from "../../../tree/nodes/operators/substractNode.js";
8
8
  import { parseAlgebraic } from "../../../tree/parsers/latexParser.js";
9
9
  import { random } from "../../../utils/alea/random.js";
10
- const getInstruction = (identifiers) => {
10
+ const getInstruction = (identifiers, optsIn) => {
11
11
  const { distance, minutes } = identifiers;
12
- return `Si on parcourt $${distance.frenchify()}$ km en $${minutes.frenchify()}$ min,
13
- quelle est la vitesse moyenne en km/h ( $km.h^{-1}$ ) ?`;
12
+ const opts = optsIn ?? optsDefault;
13
+ const { unitTex } = opts;
14
+ return `Si on parcourt $${distance.frenchify()} \\ \\textrm{km}$ en $${minutes.frenchify()} \\ \\textrm{min}$,
15
+ quelle est la vitesse moyenne en $${unitTex}$ ?`;
14
16
  };
15
- const getAnswer = (identifiers) => {
17
+ const getAnswer = (identifiers, optsIn) => {
16
18
  const { distance, minutes } = identifiers;
19
+ const opts = optsIn ?? optsDefault;
20
+ const { unitTex } = opts;
17
21
  const nodeAnswer = multiply(distance, frac(60, minutes));
18
- return `${nodeAnswer.simplify().toTex()}km.h^{-1}`;
22
+ return `${nodeAnswer.simplify().toTex()} \\ ${unitTex}`;
19
23
  };
20
24
  const isAnswerValid = (ans, { distance, minutes }) => {
21
25
  const nodeAnswer = multiply(distance, frac(60, minutes));
22
- const nodeAns = parseAlgebraic(ans.replace("$km.h^{-1}$", "").replace("km/h", ""));
26
+ const nodeAns = parseAlgebraic(["\\textrm{km/h}", "\\textrm{km}.\\textrm{h}^{-1}"].reduce((acc, x) => acc.replace(x, ""), ans));
23
27
  return substract(nodeAns, nodeAnswer).evaluate() === 0;
24
28
  };
25
29
  const getHint = () => {
26
30
  return `Combien de minutes constituent une heure ?`;
27
31
  };
28
- const getCorrection = (identifiers) => {
32
+ const getCorrection = (identifiers, optsIn) => {
29
33
  const { distance, minutes } = identifiers;
30
- return `En $60$ minutes, on parcourt $${multiply(distance, frac(60, minutes)).toTex()}$ km
34
+ const opts = optsIn ?? optsDefault;
35
+ const { unitTex } = opts;
36
+ return `En $60$ minutes, on parcourt $${multiply(distance, frac(60, minutes)).toTex()} \\ \\textrm{km}$
31
37
  donc la vitesse est de $${multiply(distance, frac(60, minutes).simplify()).toTex()} = ${multiply(distance, frac(60, minutes))
32
38
  .simplify()
33
- .toTex()}$ $km.h^{-1}$`;
39
+ .toTex()} \\ ${unitTex}$`;
34
40
  };
35
- const getPropositions = (n, { answer, distance, minutes }) => {
41
+ const getPropositions = (n, { answer, distance, minutes }, optsIn) => {
42
+ const opts = optsIn ?? optsDefault;
43
+ const { unitTex } = opts;
36
44
  const propositions = [];
37
45
  addValidProp(propositions, answer);
38
- tryToAddWrongProp(propositions, `${multiply(60, minutes).simplify().toTex()}km.h^{-1}`);
39
- tryToAddWrongProp(propositions, `${frac(distance, minutes).simplify().toTex()}km.h^{-1}`);
40
- tryToAddWrongProp(propositions, `${multiply(3.6, frac(distance, minutes)).simplify().toTex()}km.h^{-1}`);
46
+ tryToAddWrongProp(propositions, `${multiply(60, minutes).simplify().toTex()} \\ ${unitTex}`);
47
+ tryToAddWrongProp(propositions, `${frac(distance, minutes).simplify().toTex()} \\ ${unitTex}`);
48
+ tryToAddWrongProp(propositions, `${multiply(3.6, frac(distance, minutes))
49
+ .simplify()
50
+ .toTex()} \\ ${unitTex}`);
41
51
  return shuffleProps(propositions, n);
42
52
  };
43
- const getKmPerMinToKmPerHourConversionQuestion = () => {
53
+ const getKmPerMinToKmPerHourConversionQuestion = (optsIn) => {
54
+ const opts = optsIn ?? optsDefault;
44
55
  const distance = randint(1, 101);
45
56
  const minutes = random(dividersOf(60));
46
57
  const identifiers = {
47
58
  distance,
48
59
  minutes,
49
60
  };
50
- return getQuestionFromIdentifiers(identifiers);
61
+ return getQuestionFromIdentifiers(identifiers, opts);
51
62
  };
52
- const getQuestionFromIdentifiers = (identifiers) => {
63
+ const getQuestionFromIdentifiers = (identifiers, optsIn) => {
64
+ const opts = optsIn ?? optsDefault;
53
65
  const question = {
54
- answer: getAnswer(identifiers),
55
- instruction: getInstruction(identifiers),
66
+ answer: getAnswer(identifiers, opts),
67
+ instruction: getInstruction(identifiers, opts),
56
68
  keys: [
57
69
  {
58
70
  id: "custom",
59
- label: "{km}.{h}^{-1}",
71
+ label: opts.unitTex,
60
72
  labelType: "tex",
61
73
  mathfieldInstructions: {
62
74
  method: "write",
63
- content: "{km}.{h}^{-1}",
64
- },
65
- },
66
- {
67
- id: "custom",
68
- label: "km/h",
69
- labelType: "raw",
70
- mathfieldInstructions: {
71
- method: "write",
72
- content: "km/h",
75
+ content: opts.unitTex,
73
76
  },
74
77
  },
75
78
  ],
76
79
  answerFormat: "tex",
77
80
  identifiers,
78
- hint: getHint(identifiers),
79
- correction: getCorrection(identifiers),
81
+ hint: getHint(identifiers, opts),
82
+ correction: getCorrection(identifiers, opts),
83
+ options: opts,
80
84
  };
81
85
  return question;
82
86
  };
87
+ const optsDefault = {
88
+ unitTex: "\\textrm{km/h}",
89
+ };
90
+ const options = [
91
+ {
92
+ id: "unitTex",
93
+ label: "Unité affichée",
94
+ target: GeneratorOptionTarget.generation,
95
+ type: GeneratorOptionType.select,
96
+ values: ["\\textrm{km/h}", "\\textrm{km}.\\textrm{h}^{-1}"],
97
+ defaultValue: optsDefault.unitTex,
98
+ },
99
+ ];
83
100
  export const kmPerMinToKmPerHourConversion = {
84
101
  id: "kmPerMinToKmPerHourConversion",
85
102
  connector: "=",
86
- label: "Effectuer des conversions de vitesse ( $x$ km en $y$ min donne une vitesse $V$ en km/h)",
103
+ label: "Effectuer des conversions de vitesse ( $x$ km en $y$ min donne une vitesse $V$ en \\textrm{km/h})",
87
104
  isSingleStep: true,
88
- generator: (nb) => getDistinctQuestions(getKmPerMinToKmPerHourConversionQuestion, nb),
105
+ generator: (nb, opts) => getDistinctQuestions(() => getKmPerMinToKmPerHourConversionQuestion(opts), nb),
106
+ options,
89
107
  qcmTimer: 60,
90
108
  freeTimer: 60,
91
109
  getPropositions,
@@ -1 +1 @@
1
- {"version":3,"file":"prefixToNumber.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/conversion/prefixToNumber.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,QAAQ,EAiBT,MAAM,mBAAmB,CAAC;AAG3B,KAAK,WAAW,GAAG;IACjB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAsLF,KAAK,OAAO,GAAG;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AA+EF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAiBzD,CAAC"}
1
+ {"version":3,"file":"prefixToNumber.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/conversion/prefixToNumber.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,QAAQ,EAiBT,MAAM,mBAAmB,CAAC;AAG3B,KAAK,WAAW,GAAG;IACjB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAoMF,KAAK,OAAO,GAAG;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AA+EF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAiBzD,CAAC"}
@@ -92,9 +92,12 @@ const getMdTable = (prefixes, indexBold = -1) => {
92
92
  function boldify(str) {
93
93
  return `**${str}**`;
94
94
  }
95
+ const isBolded = 0 <= indexBold && indexBold < prefixes.length;
95
96
  return mdTable([
96
97
  ["Préfixe", "Symbole", "Signification", "Puissance"],
97
- ...prefixes.map((prefix, i) => [
98
+ ...prefixes
99
+ .filter((_, i) => (isBolded ? i === indexBold : true))
100
+ .map((prefix, i) => [
98
101
  prefix.name,
99
102
  `$${prefix.symbol}$`,
100
103
  prefix.meaning,
@@ -107,7 +110,7 @@ const getInstruction = (identifiers) => {
107
110
  const prefix = prefixes[prefixIndex];
108
111
  return `Quelle est la valeur du préfixe ${isFromSymbol ? `$${prefix.symbol}$` : prefix.name} ?
109
112
 
110
- Ecris la réponse sous la forme ${isToPow10 ? `d'une puissance de $10$` : `d'un nombre décimal`}.`;
113
+ Ecrire la réponse sous la forme ${isToPow10 ? `d'une puissance de $10$` : `d'un nombre décimal`}.`;
111
114
  };
112
115
  const getHint = (identifiers) => {
113
116
  const { prefixIndexesPool } = identifiers;
@@ -115,7 +118,8 @@ const getHint = (identifiers) => {
115
118
  return getMdTable(prefixPool);
116
119
  };
117
120
  const getCorrection = (identifiers) => {
118
- const { prefixIndexesPool, prefixIndex } = identifiers;
121
+ const { prefixIndexesPool, prefixIndex, isToPow10 } = identifiers;
122
+ const prefix = prefixes[prefixIndex];
119
123
  const prefixPool = prefixIndexesPool.map((i) => prefixes[i]);
120
124
  const indexBold = (() => {
121
125
  for (let i = 0; i < prefixIndexesPool.length; i++) {
@@ -123,7 +127,13 @@ const getCorrection = (identifiers) => {
123
127
  return i;
124
128
  }
125
129
  })();
126
- return getMdTable(prefixPool, indexBold);
130
+ return `Voici un tableau récapitulatif :
131
+
132
+ ${getMdTable(prefixPool, indexBold)}
133
+
134
+ ${!isToPow10
135
+ ? `$${prefix.texPow10}$ correspond à l'écriture décimale $${prefix.texValue}$.`
136
+ : ``}`;
127
137
  };
128
138
  const getAnswer = (identifiers) => {
129
139
  const { prefixIndex, isToPow10 } = identifiers;
@@ -46,7 +46,7 @@ const isAnswerValid = (ans, { isSecondsToHours, nodeIdsSeconds, nodeIdsHours })
46
46
  const getHint = (identifiers) => {
47
47
  const { isSecondsToHours } = identifiers;
48
48
  if (isSecondsToHours) {
49
- return `Combien y-a-t-il d'heures dans $7200$ secondes ?`;
49
+ return `Combien d'heures font $7200$ secondes ?`;
50
50
  }
51
51
  else {
52
52
  return `Combien y-a-t-il de secondes dans une heure ?`;