math-exercises 3.0.131 → 3.0.132

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 (82) hide show
  1. package/lib/exercises/exercise.d.ts +37 -30
  2. package/lib/exercises/exercise.d.ts.map +1 -1
  3. package/lib/exercises/math/calcul/mentalCaluls/mentalProgramSolve.d.ts +3 -3
  4. package/lib/exercises/math/calcul/mentalCaluls/mentalProgramSolve.d.ts.map +1 -1
  5. package/lib/exercises/math/calcul/mentalCaluls/mentalProgramSolve.js +48 -44
  6. package/lib/exercises/math/calcul/ordering/compareA10N.d.ts +1 -1
  7. package/lib/exercises/math/calcul/ordering/compareA10N.js +3 -3
  8. package/lib/exercises/math/calcul/ordering/compareFracABWithFracAPlusCBPlusC.d.ts.map +1 -1
  9. package/lib/exercises/math/calcul/ordering/compareFracABWithFracAPlusCBPlusC.js +0 -1
  10. package/lib/exercises/math/calcul/ordering/compareFracAndDec.d.ts +1 -1
  11. package/lib/exercises/math/calcul/ordering/compareFracAndDec.js +1 -1
  12. package/lib/exercises/math/calcul/proportionality/findCoeffInProportionalTableNonIntegers.js +1 -1
  13. package/lib/exercises/math/calcul/proportionality/isTableProportionalNonInteger.d.ts.map +1 -1
  14. package/lib/exercises/math/calcul/proportionality/isTableProportionalNonInteger.js +2 -0
  15. package/lib/exercises/math/calcul/rounding/rounding.d.ts +1 -1
  16. package/lib/exercises/math/calcul/rounding/rounding.d.ts.map +1 -1
  17. package/lib/exercises/math/calcul/rounding/rounding.js +7 -6
  18. package/lib/exercises/math/calculLitteral/writing/writeLitExpFromFrenchExp.d.ts.map +1 -1
  19. package/lib/exercises/math/calculLitteral/writing/writeLitExpFromFrenchExp.js +15 -60
  20. package/lib/exercises/math/conversion/kmPerMinToKmPerHourConversion.js +14 -10
  21. package/lib/exercises/math/conversion/lengthConversion.d.ts.map +1 -1
  22. package/lib/exercises/math/conversion/lengthConversion.js +1 -0
  23. package/lib/exercises/math/conversion/prefixToNumber.d.ts.map +1 -1
  24. package/lib/exercises/math/conversion/prefixToNumber.js +10 -8
  25. package/lib/exercises/math/conversion/secondsToHours.js +1 -1
  26. package/lib/exercises/math/functions/affines/drawAffineFromPointAndLeadingCoeff.d.ts.map +1 -1
  27. package/lib/exercises/math/functions/affines/drawAffineFromPointAndLeadingCoeff.js +2 -1
  28. package/lib/exercises/math/functions/affines/drawAffineFromProgCalc.d.ts +1 -1
  29. package/lib/exercises/math/functions/affines/drawAffineFromProgCalc.d.ts.map +1 -1
  30. package/lib/exercises/math/functions/affines/drawAffineFromProgCalc.js +4 -5
  31. package/lib/exercises/math/functions/affines/leadingCoefficient.js +1 -1
  32. package/lib/exercises/math/geometry/angles/anglesUsingIsParallel.d.ts +1 -1
  33. package/lib/exercises/math/geometry/angles/anglesUsingIsParallel.d.ts.map +1 -1
  34. package/lib/exercises/math/geometry/angles/anglesUsingIsParallel.js +10 -11
  35. package/lib/exercises/math/geometry/angles/isParallelUsingAngles.d.ts +1 -1
  36. package/lib/exercises/math/geometry/angles/isParallelUsingAngles.d.ts.map +1 -1
  37. package/lib/exercises/math/geometry/angles/isParallelUsingAngles.js +8 -8
  38. package/lib/exercises/math/percent/evolutions/globalPercent.d.ts +4 -1
  39. package/lib/exercises/math/percent/evolutions/globalPercent.d.ts.map +1 -1
  40. package/lib/exercises/math/percent/evolutions/globalPercent.js +37 -21
  41. package/lib/exercises/math/percent/findProportion.d.ts.map +1 -1
  42. package/lib/exercises/math/percent/findProportion.js +24 -26
  43. package/lib/exercises/math/percent/percentToDecimal.d.ts +4 -1
  44. package/lib/exercises/math/percent/percentToDecimal.d.ts.map +1 -1
  45. package/lib/exercises/math/percent/percentToDecimal.js +55 -35
  46. package/lib/exercises/math/powers/calculateNegativePower.d.ts +1 -1
  47. package/lib/exercises/math/powers/calculateNegativePower.d.ts.map +1 -1
  48. package/lib/exercises/math/powers/calculateNegativePower.js +17 -10
  49. package/lib/exercises/math/probaStat/basicStats/calculateFrequencyInList.d.ts +5 -1
  50. package/lib/exercises/math/probaStat/basicStats/calculateFrequencyInList.d.ts.map +1 -1
  51. package/lib/exercises/math/probaStat/basicStats/calculateFrequencyInList.js +76 -12
  52. package/lib/exercises/math/probaStat/conditionalProbaWriteFromFrench.js +1 -1
  53. package/lib/exercises/math/probaStat/probaAsSumOfProbas.d.ts +3 -3
  54. package/lib/exercises/math/probaStat/probaAsSumOfProbas.d.ts.map +1 -1
  55. package/lib/exercises/math/probaStat/probaAsSumOfProbas.js +17 -45
  56. package/lib/exercises/math/probaStat/probaFromTableWithContext.d.ts +12 -5
  57. package/lib/exercises/math/probaStat/probaFromTableWithContext.d.ts.map +1 -1
  58. package/lib/exercises/math/probaStat/probaFromTableWithContext.js +354 -94
  59. package/lib/exercises/math/probaStat/stats1var/medianWithList.d.ts +4 -1
  60. package/lib/exercises/math/probaStat/stats1var/medianWithList.d.ts.map +1 -1
  61. package/lib/exercises/math/probaStat/stats1var/medianWithList.js +43 -23
  62. package/lib/exercises/math/probaStat/stats1var/quartilesList.d.ts +1 -1
  63. package/lib/exercises/math/probaStat/stats1var/quartilesList.d.ts.map +1 -1
  64. package/lib/exercises/math/probaStat/stats1var/quartilesList.js +4 -4
  65. package/lib/exercises/pc/motion/averageSpeed.d.ts.map +1 -1
  66. package/lib/exercises/pc/motion/averageSpeed.js +13 -10
  67. package/lib/exercises/pc/optics/lensFormula.d.ts +1 -2
  68. package/lib/exercises/pc/optics/lensFormula.d.ts.map +1 -1
  69. package/lib/exercises/pc/optics/lensFormula.js +7 -10
  70. package/lib/exercises/pc/weight/calculateWeight.d.ts +1 -2
  71. package/lib/exercises/pc/weight/calculateWeight.d.ts.map +1 -1
  72. package/lib/exercises/pc/weight/calculateWeight.js +15 -14
  73. package/lib/index.d.ts +932 -919
  74. package/lib/index.d.ts.map +1 -1
  75. package/lib/math/progCalc/progCalc.d.ts +2 -2
  76. package/lib/math/progCalc/progCalc.d.ts.map +1 -1
  77. package/lib/math/progCalc/progCalc.js +4 -11
  78. package/lib/tests/exoTest.d.ts.map +1 -1
  79. package/lib/tests/exoTest.js +13 -0
  80. package/lib/types/keyIds.d.ts +1 -1
  81. package/lib/types/keyIds.d.ts.map +1 -1
  82. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"findProportion.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/percent/findProportion.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAarC,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAgOF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,CAehD,CAAC"}
1
+ {"version":3,"file":"findProportion.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/percent/findProportion.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAarC,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AA4NF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,CAehD,CAAC"}
@@ -6,10 +6,10 @@ import { round } from "../../../math/utils/round.js";
6
6
  import { frac } from "../../../tree/nodes/operators/fractionNode.js";
7
7
  import { multiply } from "../../../tree/nodes/operators/multiplyNode.js";
8
8
  import { substract } from "../../../tree/nodes/operators/substractNode.js";
9
- import { parseAlgebraic } from "../../../tree/parsers/latexParser.js";
9
+ import { percentParser } from "../../../tree/parsers/percentParser.js";
10
+ import { valueParser } from "../../../tree/parsers/valueParser.js";
10
11
  import { random } from "../../../utils/alea/random.js";
11
12
  import { handleVEAError } from "../../../utils/errors/handleVEAError.js";
12
- import { alignTex } from "../../../utils/latex/alignTex.js";
13
13
  const situations = [
14
14
  {
15
15
  instruction: (total, lefties) => `${random([
@@ -114,14 +114,10 @@ const getHint = (identifiers) => {
114
114
  const situation = situations[indexSituation];
115
115
  return `${situation.hint}
116
116
 
117
- Rappel :
117
+ Pour transformer un nombre décimal en pourcentage, on le multiplie par $100$. Par exemple,
118
118
 
119
119
  $$
120
- 2\\% = 0,02
121
- $$
122
-
123
- $$
124
- 2,01\\% = 0,0201
120
+ 0,345 = 34,5\\%
125
121
  $$
126
122
 
127
123
  `;
@@ -135,16 +131,9 @@ const getCorrection = (identifiers) => {
135
131
  const middleSymbol = isEqual ? "=" : "\\approx";
136
132
  return `On a :
137
133
 
138
- ${alignTex([
139
- [`${fractionNode.toTex()}`, middleSymbol, `${roundedProportion.frenchify()}`],
140
- [
141
- "",
142
- middleSymbol,
143
- `${roundedProportion.frenchify()} \\times 100 \\times \\frac{1}{100}`,
144
- ],
145
- ["", middleSymbol, `${roundedProportion.frenchify()} \\times 100 \\ \\%`],
146
- ["", middleSymbol, `${getAnswer(identifiers)}`],
147
- ])}
134
+ $$
135
+ ${fractionNode.toTex()} ${middleSymbol} ${roundedProportion.frenchify()}
136
+ $$
148
137
 
149
138
  ${situation.correction} $${getAnswer(identifiers)}$.`;
150
139
  };
@@ -163,14 +152,19 @@ const getPropositions = (n, { answer, total, lefties }) => {
163
152
  });
164
153
  return shuffleProps(propositions, n);
165
154
  };
166
- const isAnswerValid = (ans, { answer, ...identifiers }) => {
167
- const { lefties, total } = identifiers;
155
+ const isAnswerValid = (ans, { answer, lefties, total }) => {
168
156
  try {
169
- const percentNode = frac(1, 100);
170
- const refinedAns = ans.replaceAll("\\%", `({${percentNode.toTex()}})`);
171
- const nodeAns = parseAlgebraic(refinedAns);
172
- const nodeAnswer = round(lefties / total, 4);
173
- return substract(nodeAns, nodeAnswer).simplify().evaluate() === 0;
157
+ if (ans.includes("\\%")) {
158
+ const parsed = percentParser(ans);
159
+ return parsed === answer;
160
+ }
161
+ else {
162
+ const answerValue = round(lefties / total, 4);
163
+ const studentAns = valueParser(ans);
164
+ if (!studentAns)
165
+ return false;
166
+ return answerValue === studentAns;
167
+ }
174
168
  }
175
169
  catch (err) {
176
170
  return handleVEAError(err);
@@ -181,7 +175,11 @@ const getFindProportionQuestion = () => {
181
175
  const situation = situations[indexSituation];
182
176
  const total = situation.randTotal();
183
177
  const lefties = round(randfloat(0.1, 0.9) * total, 0);
184
- return getQuestionFromIdentifiers({ indexSituation, total, lefties });
178
+ return getQuestionFromIdentifiers({
179
+ indexSituation,
180
+ total,
181
+ lefties,
182
+ });
185
183
  };
186
184
  const getQuestionFromIdentifiers = (identifiers) => {
187
185
  const question = {
@@ -3,6 +3,9 @@ type Identifiers = {
3
3
  isPercentToDecimal: boolean;
4
4
  nb: number;
5
5
  };
6
- export declare const percentToDecimal: Exercise<Identifiers>;
6
+ type Options = {
7
+ conversionType: string;
8
+ };
9
+ export declare const percentToDecimal: Exercise<Identifiers, Options>;
7
10
  export {};
8
11
  //# sourceMappingURL=percentToDecimal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"percentToDecimal.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/percent/percentToDecimal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAgBT,MAAM,6BAA6B,CAAC;AAgBrC,KAAK,WAAW,GAAG;IACjB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AA8IF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,WAAW,CAclD,CAAC"}
1
+ {"version":3,"file":"percentToDecimal.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/percent/percentToDecimal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAmBT,MAAM,6BAA6B,CAAC;AAiBrC,KAAK,WAAW,GAAG;IACjB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AA4JF,KAAK,OAAO,GAAG;IACb,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAsBF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAe3D,CAAC"}
@@ -1,4 +1,4 @@
1
- import { addValidProp, propWhile, shuffleProps, tryToAddWrongProp, } from "../../../exercises/exercise.js";
1
+ import { GeneratorOptionTarget, GeneratorOptionType, addValidProp, propWhile, shuffleProps, tryToAddWrongProp, } from "../../../exercises/exercise.js";
2
2
  import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
3
  import { Decimal, DecimalConstructor, } from "../../../math/numbers/decimals/decimal.js";
4
4
  import { Integer, IntegerConstructor, } from "../../../math/numbers/integer/integer.js";
@@ -7,6 +7,7 @@ import { round } from "../../../math/utils/round.js";
7
7
  import { numberParser } from "../../../tree/parsers/numberParser.js";
8
8
  import { coinFlip } from "../../../utils/alea/coinFlip.js";
9
9
  import { probaFlip } from "../../../utils/alea/probaFlip.js";
10
+ import { random } from "../../../utils/alea/random.js";
10
11
  const getAnswer = ({ nb, isPercentToDecimal }) => {
11
12
  const dec = new Decimal(nb);
12
13
  const tex = dec.toTree().toTex();
@@ -48,39 +49,6 @@ En effet, on a bien $${answer} = \\frac{${answer.replace("\\%", "")}}{100} = ${n
48
49
  const getKeys = () => {
49
50
  return ["percent"];
50
51
  };
51
- const getPercentToDecimalQuestion = () => {
52
- const isPercentToDecimal = coinFlip();
53
- const isNatural = coinFlip();
54
- const percentNb = probaFlip(0.3)
55
- ? isNatural
56
- ? new Integer(IntegerConstructor.random(1, [0]))
57
- : DecimalConstructor.random(0, 10)
58
- : coinFlip()
59
- ? isNatural
60
- ? new Integer(IntegerConstructor.random(2))
61
- : DecimalConstructor.random(10, 100)
62
- : isNatural
63
- ? new Integer(IntegerConstructor.random(3))
64
- : DecimalConstructor.random(100, 200);
65
- const nb = percentNb.times(0.01);
66
- const identifiers = {
67
- isPercentToDecimal,
68
- nb: round(nb.value, 10),
69
- };
70
- return getQuestionFromIdentifiers(identifiers);
71
- };
72
- const getQuestionFromIdentifiers = (identifiers) => {
73
- const question = {
74
- answer: getAnswer(identifiers),
75
- instruction: getInstruction(identifiers),
76
- keys: getKeys(identifiers),
77
- answerFormat: "tex",
78
- identifiers,
79
- hint: getHint(identifiers),
80
- correction: getCorrection(identifiers),
81
- };
82
- return question;
83
- };
84
52
  const getPropositions = (n, { answer, isPercentToDecimal, nb }) => {
85
53
  const propositions = [];
86
54
  addValidProp(propositions, answer);
@@ -113,12 +81,64 @@ const isAnswerValid = (ans, { answer, isPercentToDecimal }) => {
113
81
  return parsed + "\\%" === answer;
114
82
  }
115
83
  };
84
+ const getPercentToDecimalQuestion = (optsIn) => {
85
+ const arrayedOptions = optsIn ?? optsDefault;
86
+ const opts = {
87
+ conversionType: random(arrayedOptions.conversionType),
88
+ };
89
+ const isPercentToDecimal = opts.conversionType === "Pourcentage vers Décimal";
90
+ const isNatural = coinFlip();
91
+ const percentNb = probaFlip(0.3)
92
+ ? isNatural
93
+ ? new Integer(IntegerConstructor.random(1, [0]))
94
+ : DecimalConstructor.random(0, 10)
95
+ : coinFlip()
96
+ ? isNatural
97
+ ? new Integer(IntegerConstructor.random(2))
98
+ : DecimalConstructor.random(10, 100)
99
+ : isNatural
100
+ ? new Integer(IntegerConstructor.random(3))
101
+ : DecimalConstructor.random(100, 200);
102
+ const nb = percentNb.times(0.01);
103
+ const identifiers = {
104
+ isPercentToDecimal,
105
+ nb: round(nb.value, 10),
106
+ };
107
+ return getQuestionFromIdentifiers(identifiers, opts);
108
+ };
109
+ const getQuestionFromIdentifiers = (identifiers, opts) => {
110
+ const question = {
111
+ answer: getAnswer(identifiers),
112
+ instruction: getInstruction(identifiers),
113
+ keys: getKeys(identifiers),
114
+ answerFormat: "tex",
115
+ identifiers,
116
+ hint: getHint(identifiers),
117
+ correction: getCorrection(identifiers),
118
+ options: opts,
119
+ };
120
+ return question;
121
+ };
122
+ const optsDefault = {
123
+ conversionType: ["Pourcentage vers Décimal", "Décimal vers Pourcentage"],
124
+ };
125
+ const options = [
126
+ {
127
+ id: "conversionType",
128
+ label: "Type de conversion",
129
+ target: GeneratorOptionTarget.generation,
130
+ type: GeneratorOptionType.multiselect,
131
+ values: ["Pourcentage vers Décimal", "Décimal vers Pourcentage"],
132
+ defaultValue: optsDefault.conversionType,
133
+ },
134
+ ];
116
135
  export const percentToDecimal = {
117
136
  id: "percentToDecimal",
118
137
  connector: "=",
119
138
  label: "Écrire un pourcentage sous forme décimale et vice-versa",
120
139
  isSingleStep: true,
121
- generator: (nb) => getDistinctQuestions(getPercentToDecimalQuestion, nb),
140
+ generator: (nb, opts) => getDistinctQuestions(() => getPercentToDecimalQuestion(opts), nb),
141
+ options,
122
142
  qcmTimer: 60,
123
143
  freeTimer: 60,
124
144
  getPropositions,
@@ -2,7 +2,7 @@ import { Exercise } from "../../../exercises/exercise.js";
2
2
  type Identifiers = {
3
3
  int: number;
4
4
  power: number;
5
- opts: Options;
5
+ isPowerAllowed: boolean;
6
6
  };
7
7
  type Options = {
8
8
  isPowerAllowed: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"calculateNegativePower.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/powers/calculateNegativePower.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAkBT,MAAM,6BAA6B,CAAC;AA0CrC,KAAK,WAAW,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AA4JF,KAAK,OAAO,GAAG;IACb,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAeF,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAgBjE,CAAC"}
1
+ {"version":3,"file":"calculateNegativePower.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/powers/calculateNegativePower.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAmBT,MAAM,6BAA6B,CAAC;AA0CrC,KAAK,WAAW,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AA4KF,KAAK,OAAO,GAAG;IACb,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAcF,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAiBjE,CAAC"}
@@ -25,8 +25,14 @@ const isNodeContainingOperatorId = (node, opId) => {
25
25
  return false;
26
26
  }
27
27
  };
28
+ const rebuildIdentifiers = (oldIds) => {
29
+ const newIds = Object.assign({}, oldIds, {
30
+ isPowerAllowed: true,
31
+ });
32
+ return newIds;
33
+ };
28
34
  const getInstruction = (identifiers) => {
29
- const { int, power, opts } = identifiers;
35
+ const { int, power, isPowerAllowed } = identifiers;
30
36
  const statement = new PowerNode(new NumberNode(int), new NumberNode(power)).toTex();
31
37
  return `Calculer et donner le résultat sous la forme d'une fraction ou d'un entier :
32
38
 
@@ -34,14 +40,14 @@ $$
34
40
  ${statement}
35
41
  $$
36
42
 
37
- ${opts.isPowerAllowed
43
+ ${isPowerAllowed
38
44
  ? `La réponse pourra comporter un exposant.`
39
45
  : `La réponse ne devra comporter aucun exposant.`}`;
40
46
  };
41
47
  const getAnswer = (identifiers) => {
42
- const { int, power, opts } = identifiers;
48
+ const { int, power, isPowerAllowed } = identifiers;
43
49
  const powerNode = new PowerNode(int.toTree(), Math.abs(power).toTree());
44
- const fraction = frac(1, opts.isPowerAllowed ? powerNode : powerNode.evaluate().toTree());
50
+ const fraction = frac(1, isPowerAllowed ? powerNode : powerNode.evaluate().toTree());
45
51
  const answer = fraction.simplify();
46
52
  return answer.toTex();
47
53
  };
@@ -53,7 +59,7 @@ a^{-x} = \\frac{1}{a^x}
53
59
  $$`;
54
60
  };
55
61
  const getCorrection = (identifiers) => {
56
- const { int, power, opts } = identifiers;
62
+ const { int, power, isPowerAllowed } = identifiers;
57
63
  const statement = new PowerNode(new NumberNode(int), new NumberNode(power)).toTex();
58
64
  const fraction = frac(1, new PowerNode(int.toTree(), Math.abs(power).toTree()));
59
65
  const simplificationTex = fraction.toSimplificationTex();
@@ -64,7 +70,7 @@ ${statement} = ${simplificationTex}
64
70
  $$
65
71
 
66
72
  ${(() => {
67
- if (!opts.isPowerAllowed) {
73
+ if (!isPowerAllowed) {
68
74
  const fractionNoPower = frac(1, new PowerNode(int.toTree(), Math.abs(power).toTree()).evaluate().toTree());
69
75
  const texNoPower = fractionNoPower.toTex();
70
76
  return !simplificationTex.includes(texNoPower)
@@ -105,12 +111,12 @@ const getPropositions = (n, { answer, int, power }) => {
105
111
  });
106
112
  return shuffleProps(propositions, n);
107
113
  };
108
- const isAnswerValid = (ans, { answer, opts }) => {
114
+ const isAnswerValid = (ans, { answer, isPowerAllowed }) => {
109
115
  try {
110
116
  const parsed = parseAlgebraic(ans);
111
117
  if (!isNumberNode(parsed) &&
112
118
  !(isFractionNode(parsed) &&
113
- (opts.isPowerAllowed ||
119
+ (isPowerAllowed ||
114
120
  !isNodeContainingOperatorId(parsed, OperatorIds.power)))) {
115
121
  return false;
116
122
  }
@@ -122,9 +128,10 @@ const isAnswerValid = (ans, { answer, opts }) => {
122
128
  };
123
129
  const getCalculatePowerQuestion = (optsIn) => {
124
130
  const opts = optsIn ?? optsDefault;
131
+ const isPowerAllowed = opts.isPowerAllowed;
125
132
  const int = randint(1, 11);
126
133
  const power = randint(-5, 0);
127
- const identifiers = { int, power, opts };
134
+ const identifiers = { int, power, isPowerAllowed };
128
135
  return getQuestionFromIdentifiers(identifiers, opts);
129
136
  };
130
137
  const getQuestionFromIdentifiers = (identifiers, opts) => {
@@ -149,7 +156,6 @@ const options = [
149
156
  label: "Exposant accepté dans la réponse",
150
157
  target: GeneratorOptionTarget.generation,
151
158
  type: GeneratorOptionType.checkbox,
152
- values: [true, false],
153
159
  defaultValue: optsDefault.isPowerAllowed,
154
160
  },
155
161
  ];
@@ -168,4 +174,5 @@ export const calculateNegativePower = {
168
174
  getQuestionFromIdentifiers,
169
175
  hasHintAndCorrection: true,
170
176
  shouldHaveCalculator: false,
177
+ rebuildIdentifiers: rebuildIdentifiers,
171
178
  };
@@ -2,7 +2,11 @@ import { Exercise } from "../../../../exercises/exercise.js";
2
2
  type Identifiers = {
3
3
  values: number[];
4
4
  target: number;
5
+ allowedAnsType: string[];
5
6
  };
6
- export declare const calculateFrequencyInList: Exercise<Identifiers>;
7
+ type Options = {
8
+ allowedAnsType: string[];
9
+ };
10
+ export declare const calculateFrequencyInList: Exercise<Identifiers, Options>;
7
11
  export {};
8
12
  //# sourceMappingURL=calculateFrequencyInList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"calculateFrequencyInList.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/basicStats/calculateFrequencyInList.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AASrC,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAoHF,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,WAAW,CAc1D,CAAC"}
1
+ {"version":3,"file":"calculateFrequencyInList.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/basicStats/calculateFrequencyInList.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAmBT,MAAM,6BAA6B,CAAC;AAYrC,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AA8LF,KAAK,OAAO,GAAG;IACb,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAsBF,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAgBnE,CAAC"}
@@ -1,11 +1,19 @@
1
- import { addValidProp, shuffleProps, tryToAddWrongProp, propWhile, } from "../../../../exercises/exercise.js";
1
+ import { addValidProp, shuffleProps, tryToAddWrongProp, propWhile, GeneratorOptionTarget, GeneratorOptionType, } from "../../../../exercises/exercise.js";
2
2
  import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
3
3
  import { RationalConstructor } from "../../../../math/numbers/rationals/rational.js";
4
4
  import { randint } from "../../../../math/utils/random/randint.js";
5
+ import { round } from "../../../../math/utils/round.js";
5
6
  import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
7
+ import { substract } from "../../../../tree/nodes/operators/substractNode.js";
6
8
  import { parseAlgebraic } from "../../../../tree/parsers/latexParser.js";
7
9
  import { probaFlip } from "../../../../utils/alea/probaFlip.js";
8
10
  import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
11
+ const rebuildIdentifiers = (oldIds) => {
12
+ const newIds = Object.assign({}, oldIds, {
13
+ allowedAnsType: ["exacte", "arrondie à 2 décimales"],
14
+ });
15
+ return newIds;
16
+ };
9
17
  const getPropositions = (n, { answer, ...identifiers }) => {
10
18
  const propositions = [];
11
19
  addValidProp(propositions, answer);
@@ -17,13 +25,17 @@ const getPropositions = (n, { answer, ...identifiers }) => {
17
25
  });
18
26
  return shuffleProps(propositions, n);
19
27
  };
20
- const getAnswer = (identifiers) => {
21
- const { target, values } = identifiers;
28
+ const getAnswerNode = (identifiers) => {
29
+ const { target, values, allowedAnsType } = identifiers;
22
30
  const nb = values.filter((v) => v === target).length;
23
- return frac(nb, values.length).simplify({ fractionsToDecimal: true }).toTex();
31
+ const exactNode = frac(nb, values.length);
32
+ return createFormattedNode(exactNode, getStrInternalAllowedAnswerTypes(allowedAnsType));
33
+ };
34
+ const getAnswer = (identifiers) => {
35
+ return getAnswerNode(identifiers).toTex();
24
36
  };
25
37
  const getInstruction = (identifiers) => {
26
- const { target, values } = identifiers;
38
+ const { target, values, allowedAnsType } = identifiers;
27
39
  const length = values.length;
28
40
  return `Voici une liste de nombres :
29
41
 
@@ -35,7 +47,7 @@ $$
35
47
 
36
48
  Quelle est la fréquence d'apparition du nombre $${target}$ dans cette liste ?
37
49
 
38
- Donner la réponse sous forme de fraction, ou si possible de nombre décimal ou de pourcentage.`;
50
+ Donner ${getStrAllowedAnswerTypes(getStrInternalAllowedAnswerTypes(allowedAnsType))}.`;
39
51
  };
40
52
  const getHint = (identifiers) => {
41
53
  const { target } = identifiers;
@@ -59,25 +71,32 @@ $$
59
71
  const getKeys = () => {
60
72
  return ["percent"];
61
73
  };
62
- const isAnswerValid = (ans, { answer }) => {
74
+ const isAnswerValid = (ans, { answer, ...identifiers }) => {
63
75
  try {
76
+ let ansNode;
64
77
  if (ans.includes("%")) {
65
78
  const formated = ans.replace("\\%", "");
66
79
  const nb = formated.unfrenchify();
67
80
  if (isNaN(nb))
68
81
  return false;
69
- return (frac(nb, 100).simplify({ fractionsToDecimal: true }).toTex() === answer);
82
+ ansNode = frac(nb, 100);
70
83
  }
71
84
  else {
72
- const parsed = parseAlgebraic(ans);
73
- return parsed.simplify({ fractionsToDecimal: true }).toTex() === answer;
85
+ ansNode = parseAlgebraic(ans);
74
86
  }
87
+ if (!ansNode)
88
+ return false;
89
+ return getAllValidNodes(identifiers).some((answerNode) => {
90
+ return substract(ansNode, answerNode).simplify().evaluate() === 0;
91
+ });
75
92
  }
76
93
  catch (err) {
77
94
  return handleVEAError(err);
78
95
  }
79
96
  };
80
- const getCalculateFrequencyInListQuestion = () => {
97
+ const getCalculateFrequencyInListQuestion = (optsIn) => {
98
+ const opts = optsIn ?? optsDefault;
99
+ const allowedAnsType = opts.allowedAnsType;
81
100
  const target = randint(1, 10);
82
101
  const length = randint(6, 13);
83
102
  const values = [];
@@ -87,10 +106,11 @@ const getCalculateFrequencyInListQuestion = () => {
87
106
  const identifiers = {
88
107
  target,
89
108
  values,
109
+ allowedAnsType,
90
110
  };
91
111
  return getQuestionFromIdentifiers(identifiers);
92
112
  };
93
- const getQuestionFromIdentifiers = (identifiers) => {
113
+ const getQuestionFromIdentifiers = (identifiers, opts) => {
94
114
  return {
95
115
  answer: getAnswer(identifiers),
96
116
  instruction: getInstruction(identifiers),
@@ -99,14 +119,57 @@ const getQuestionFromIdentifiers = (identifiers) => {
99
119
  identifiers,
100
120
  hint: getHint(identifiers),
101
121
  correction: getCorrection(identifiers),
122
+ options: opts,
102
123
  };
103
124
  };
125
+ const getStrInternalAllowedAnswerTypes = (allowedAnsType) => {
126
+ return allowedAnsType.toSorted((a, b) => a.localeCompare(b)).join(" | ");
127
+ };
128
+ const getStrAllowedAnswerTypes = (strInternalAllowedAnswerTypes) => {
129
+ switch (strInternalAllowedAnswerTypes) {
130
+ case "arrondie à 2 décimales | exacte":
131
+ return "la valeur exacte ou la valeur arrondie à $2$ décimales";
132
+ case "arrondie à 2 décimales":
133
+ return "la valeur arrondie à $2$ décimales";
134
+ case "exacte":
135
+ return "la valeur exacte";
136
+ }
137
+ };
138
+ const createFormattedNode = (exactNode, strInternalAllowedAnswerTypes) => {
139
+ switch (strInternalAllowedAnswerTypes) {
140
+ case "arrondie à 2 décimales":
141
+ return round(exactNode.evaluate(), 2).toTree();
142
+ default:
143
+ return exactNode;
144
+ }
145
+ };
146
+ const getAllValidNodes = (identifiers) => {
147
+ return identifiers.allowedAnsType.map((ansType) => getAnswerNode((() => {
148
+ const identifiersCopy = Object.assign({}, identifiers);
149
+ identifiersCopy.allowedAnsType = [ansType];
150
+ return identifiersCopy;
151
+ })()));
152
+ };
153
+ const optsDefault = {
154
+ allowedAnsType: ["exacte", "arrondie à 2 décimales"],
155
+ };
156
+ const options = [
157
+ {
158
+ id: "allowedAnsType",
159
+ label: "Forme de réponse acceptée",
160
+ target: GeneratorOptionTarget.generation,
161
+ type: GeneratorOptionType.multiselect,
162
+ values: ["exacte", "arrondie à 2 décimales"],
163
+ defaultValue: optsDefault.allowedAnsType,
164
+ },
165
+ ];
104
166
  export const calculateFrequencyInList = {
105
167
  id: "calculateFrequencyInList",
106
168
  connector: "=",
107
169
  label: "Calculer la fréquence d'apparition d'un nombre dans une liste",
108
170
  isSingleStep: true,
109
171
  generator: (nb, opts) => getDistinctQuestions(() => getCalculateFrequencyInListQuestion(opts), nb),
172
+ options,
110
173
  qcmTimer: 60,
111
174
  freeTimer: 60,
112
175
  getPropositions,
@@ -114,4 +177,5 @@ export const calculateFrequencyInList = {
114
177
  subject: "Mathématiques",
115
178
  getQuestionFromIdentifiers,
116
179
  hasHintAndCorrection: true,
180
+ rebuildIdentifiers: rebuildIdentifiers,
117
181
  };
@@ -207,7 +207,7 @@ const isAnswerValid = (ans, { answer, ...identifiers }) => {
207
207
  export const conditionalProbaWriteFromFrench = {
208
208
  id: "conditionalProbaWriteFromFrench",
209
209
  connector: "=",
210
- label: "Ecrire une probabilité en langage mathématique",
210
+ label: "Écrire une probabilité en langage mathématique",
211
211
  isSingleStep: false,
212
212
  generator: (nb) => getDistinctQuestions(getConditionalProbaWriteFromFrenchQuestion, nb),
213
213
  qcmTimer: 60,
@@ -20,9 +20,9 @@ type EventIdentifiers = {
20
20
  isTailoredStr: boolean;
21
21
  };
22
22
  type Options = {
23
- nbElem: number[];
24
- unionLength: number[];
25
- isProbasAreNumbers: boolean[];
23
+ nbElem: string[];
24
+ unionLength: string[];
25
+ isProbasAreNumbers: boolean;
26
26
  };
27
27
  export declare const probaAsSumOfProbas: Exercise<Identifiers, Options>;
28
28
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"probaAsSumOfProbas.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/probaStat/probaAsSumOfProbas.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EAkBT,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAc7C,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B,CAAC;AAEF,KAAK,gBAAgB,GACjB;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,eAAe,CAAC;CACpB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,eAAe,CAAC;IACnB,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AA4eN,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,EAAE,OAAO,EAAE,CAAC;CAC/B,CAAC;AAyTF,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAe7D,CAAC"}
1
+ {"version":3,"file":"probaAsSumOfProbas.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/probaStat/probaAsSumOfProbas.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EAkBT,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAa7C,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B,CAAC;AAEF,KAAK,gBAAgB,GACjB;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,eAAe,CAAC;CACpB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,eAAe,CAAC;IACnB,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AA4eN,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CAAC;AAqRF,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAe7D,CAAC"}
@@ -112,7 +112,7 @@ class SituationConstructor {
112
112
  const str = `On lance un dé à $${nbSides}$ faces numérotées de $1$ à $${nbSides}$.
113
113
  Le dé n'est pas équilibré.`;
114
114
  const strElem = `Pour $i$ allant de $1$ à $${nbSides}$, on note $E_i$ l'évènement:
115
- "Le résultat est $i$.".`;
115
+ "Le résultat est $i$".`;
116
116
  const nbPickSomeElem = Math.min(nbSides, 6);
117
117
  const allIndexesElem = [...Array(nbSides).keys()].map((i) => i + 1);
118
118
  const dictAllElem = Object.fromEntries(allIndexesElem.map((index) => [
@@ -342,9 +342,9 @@ $$`;
342
342
  return strCorrection;
343
343
  };
344
344
  const optsDefault = {
345
- nbElem: [4, 6, 10, 12],
346
- unionLength: [2, 3, 4, 5],
347
- isProbasAreNumbers: [true, false],
345
+ nbElem: ["4", "6", "10", "12"],
346
+ unionLength: ["2", "3", "4", "5"],
347
+ isProbasAreNumbers: true,
348
348
  };
349
349
  const options = [
350
350
  {
@@ -352,7 +352,7 @@ const options = [
352
352
  label: "Nombre d'évènements élémentaires",
353
353
  type: GeneratorOptionType.multiselect,
354
354
  target: GeneratorOptionTarget.generation,
355
- values: [4, 6, 10, 12],
355
+ values: ["4", "6", "10", "12"],
356
356
  defaultValue: optsDefault.nbElem,
357
357
  },
358
358
  {
@@ -360,47 +360,19 @@ const options = [
360
360
  label: "Longueur de l'union",
361
361
  type: GeneratorOptionType.multiselect,
362
362
  target: GeneratorOptionTarget.generation,
363
- values: [2, 3, 4, 5, 6],
363
+ values: ["2", "3", "4", "5", "6"],
364
364
  defaultValue: optsDefault.unionLength,
365
365
  },
366
- {
367
- id: "isProbasAreNumbers",
368
- label: "Probabilités sous forme de nombres ?",
369
- type: GeneratorOptionType.multiselect,
370
- target: GeneratorOptionTarget.generation,
371
- values: [true, false],
372
- defaultValue: optsDefault.isProbasAreNumbers,
373
- },
366
+ // {
367
+ // id: "isProbasAreNumbers",
368
+ // label: "Probabilités sous forme de nombres ?",
369
+ // type: GeneratorOptionType.checkbox,
370
+ // target: GeneratorOptionTarget.generation,
371
+ // defaultValue: optsDefault.isProbasAreNumbers,
372
+ // },
374
373
  ];
375
- const getKeys = (identifiers) => {
376
- const { indexSituation, arrProba } = identifiers;
377
- const isProbasAreNumbers = true;
378
- const situation = arrayOfSituations[indexSituation];
379
- return [
380
- ...[
381
- ...new Set(situation.someElem
382
- .map((event) => {
383
- if (isProbasAreNumbers) {
384
- const finiteProbDistr = FiniteProbDistrConstructor.fromArrProba(arrProba.map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds)));
385
- return finiteProbDistr.getPForIndex(event.index).simplify();
386
- }
387
- else {
388
- return event.p;
389
- }
390
- })
391
- .map((node) => node.toTex())),
392
- ].map((tex) => {
393
- return {
394
- id: "custom",
395
- label: tex,
396
- labelType: "tex",
397
- mathfieldInstructions: {
398
- method: "write",
399
- content: tex,
400
- },
401
- };
402
- }),
403
- ];
374
+ const getKeys = () => {
375
+ return [];
404
376
  };
405
377
  const getPropositions = (n, { answer, ...identifiers }) => {
406
378
  const { eventIds, arrProba } = identifiers;
@@ -499,7 +471,7 @@ const isAnswerValid = (ans, { answer, ...identifiers }) => {
499
471
  };
500
472
  const getProbaAsSumOfProbasQuestion = (optsIn) => {
501
473
  const opts = Object.assign(optsDefault, optsIn) ?? optsDefault;
502
- const unionLength = random(opts.unionLength);
474
+ const unionLength = Number(random(opts.unionLength));
503
475
  const indexSituation = random([...Array(arrayOfSituations.length).keys()].filter((indexSituation) => {
504
476
  const situation = arrayOfSituations[indexSituation];
505
477
  return situation.someElem.length >= unionLength;
@@ -509,7 +481,7 @@ const getProbaAsSumOfProbasQuestion = (optsIn) => {
509
481
  const eventIds = evUnion.toIdentifiers();
510
482
  const nbUnique = Math.min(randint(3, 7), situation.allElem.length - 1);
511
483
  const finiteProbDistr = FiniteProbDistrConstructor.randomDistr(situation.allElem.length, nbUnique);
512
- const isProbasAreNumbers = random(opts.isProbasAreNumbers);
484
+ const isProbasAreNumbers = opts.isProbasAreNumbers;
513
485
  const identifiers = {
514
486
  indexSituation,
515
487
  eventIds,