math-exercises 3.0.131 → 3.0.133

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 (109) 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 +2 -2
  4. package/lib/exercises/math/calcul/mentalCaluls/mentalProgramSolve.d.ts.map +1 -1
  5. package/lib/exercises/math/calcul/mentalCaluls/mentalProgramSolve.js +44 -40
  6. package/lib/exercises/math/calcul/ordering/compareA10N.d.ts +1 -1
  7. package/lib/exercises/math/calcul/ordering/compareA10N.d.ts.map +1 -1
  8. package/lib/exercises/math/calcul/ordering/compareA10N.js +15 -10
  9. package/lib/exercises/math/calcul/ordering/compareFracABWithFracAPlusCBPlusC.d.ts.map +1 -1
  10. package/lib/exercises/math/calcul/ordering/compareFracABWithFracAPlusCBPlusC.js +0 -1
  11. package/lib/exercises/math/calcul/ordering/compareFracAndDec.d.ts +1 -1
  12. package/lib/exercises/math/calcul/ordering/compareFracAndDec.js +1 -1
  13. package/lib/exercises/math/calcul/proportionality/findCoeffInProportionalTableNonIntegers.js +1 -1
  14. package/lib/exercises/math/calcul/proportionality/isTableProportionalNonInteger.d.ts.map +1 -1
  15. package/lib/exercises/math/calcul/proportionality/isTableProportionalNonInteger.js +2 -0
  16. package/lib/exercises/math/calcul/rounding/estimatePow10NPlusPow10MinusN.d.ts.map +1 -1
  17. package/lib/exercises/math/calcul/rounding/estimatePow10NPlusPow10MinusN.js +8 -6
  18. package/lib/exercises/math/calcul/rounding/rounding.d.ts +1 -1
  19. package/lib/exercises/math/calcul/rounding/rounding.d.ts.map +1 -1
  20. package/lib/exercises/math/calcul/rounding/rounding.js +7 -6
  21. package/lib/exercises/math/calculLitteral/equation/equationFromProblem.d.ts.map +1 -1
  22. package/lib/exercises/math/calculLitteral/equation/equationFromProblem.js +8 -9
  23. package/lib/exercises/math/calculLitteral/simplifying/compareATimes0.d.ts.map +1 -1
  24. package/lib/exercises/math/calculLitteral/simplifying/compareATimes0.js +4 -4
  25. package/lib/exercises/math/calculLitteral/writing/writeLitExpFromFrenchExp.d.ts.map +1 -1
  26. package/lib/exercises/math/calculLitteral/writing/writeLitExpFromFrenchExp.js +15 -60
  27. package/lib/exercises/math/conversion/kmPerMinToKmPerHourConversion.js +14 -10
  28. package/lib/exercises/math/conversion/lengthConversion.d.ts.map +1 -1
  29. package/lib/exercises/math/conversion/lengthConversion.js +1 -0
  30. package/lib/exercises/math/conversion/prefixToNumber.d.ts +0 -2
  31. package/lib/exercises/math/conversion/prefixToNumber.d.ts.map +1 -1
  32. package/lib/exercises/math/conversion/prefixToNumber.js +31 -24
  33. package/lib/exercises/math/conversion/secondsToHours.js +1 -1
  34. package/lib/exercises/math/functions/affines/drawAffineFromPointAndLeadingCoeff.js +2 -2
  35. package/lib/exercises/math/functions/affines/drawAffineFromProgCalc.d.ts +1 -1
  36. package/lib/exercises/math/functions/affines/drawAffineFromProgCalc.d.ts.map +1 -1
  37. package/lib/exercises/math/functions/affines/drawAffineFromProgCalc.js +4 -5
  38. package/lib/exercises/math/functions/affines/leadingCoefficient.js +1 -1
  39. package/lib/exercises/math/geometry/angles/anglesUsingIsParallel.d.ts +1 -1
  40. package/lib/exercises/math/geometry/angles/anglesUsingIsParallel.d.ts.map +1 -1
  41. package/lib/exercises/math/geometry/angles/anglesUsingIsParallel.js +10 -11
  42. package/lib/exercises/math/geometry/angles/isParallelUsingAngles.d.ts +1 -1
  43. package/lib/exercises/math/geometry/angles/isParallelUsingAngles.d.ts.map +1 -1
  44. package/lib/exercises/math/geometry/angles/isParallelUsingAngles.js +8 -8
  45. package/lib/exercises/math/geometry/cartesian/index.d.ts +1 -0
  46. package/lib/exercises/math/geometry/cartesian/index.d.ts.map +1 -1
  47. package/lib/exercises/math/geometry/cartesian/index.js +1 -0
  48. package/lib/exercises/math/geometry/cartesian/placeAbscissOnSemiLine.d.ts +6 -9
  49. package/lib/exercises/math/geometry/cartesian/placeAbscissOnSemiLine.d.ts.map +1 -1
  50. package/lib/exercises/math/geometry/cartesian/placeAbscissOnSemiLine.js +60 -137
  51. package/lib/exercises/math/geometry/cartesian/placeAbscissOnSemiLineV2.d.ts +16 -0
  52. package/lib/exercises/math/geometry/cartesian/placeAbscissOnSemiLineV2.d.ts.map +1 -0
  53. package/lib/exercises/math/geometry/cartesian/placeAbscissOnSemiLineV2.js +213 -0
  54. package/lib/exercises/math/percent/evolutions/globalPercent.d.ts +4 -1
  55. package/lib/exercises/math/percent/evolutions/globalPercent.d.ts.map +1 -1
  56. package/lib/exercises/math/percent/evolutions/globalPercent.js +37 -21
  57. package/lib/exercises/math/percent/findProportion.d.ts.map +1 -1
  58. package/lib/exercises/math/percent/findProportion.js +24 -26
  59. package/lib/exercises/math/percent/percentToDecimal.d.ts +4 -1
  60. package/lib/exercises/math/percent/percentToDecimal.d.ts.map +1 -1
  61. package/lib/exercises/math/percent/percentToDecimal.js +55 -35
  62. package/lib/exercises/math/powers/calculateNegativePower.d.ts +1 -1
  63. package/lib/exercises/math/powers/calculateNegativePower.d.ts.map +1 -1
  64. package/lib/exercises/math/powers/calculateNegativePower.js +17 -10
  65. package/lib/exercises/math/probaStat/basicProbas/possibleValuesForProba.js +2 -2
  66. package/lib/exercises/math/probaStat/basicStats/calculateFrequencyInList.d.ts +5 -1
  67. package/lib/exercises/math/probaStat/basicStats/calculateFrequencyInList.d.ts.map +1 -1
  68. package/lib/exercises/math/probaStat/basicStats/calculateFrequencyInList.js +76 -12
  69. package/lib/exercises/math/probaStat/conditionalProbaWriteFromFrench.js +7 -7
  70. package/lib/exercises/math/probaStat/probaAsSumOfProbas.d.ts +2 -3
  71. package/lib/exercises/math/probaStat/probaAsSumOfProbas.d.ts.map +1 -1
  72. package/lib/exercises/math/probaStat/probaAsSumOfProbas.js +60 -95
  73. package/lib/exercises/math/probaStat/probaFromTableWithContext.d.ts +12 -5
  74. package/lib/exercises/math/probaStat/probaFromTableWithContext.d.ts.map +1 -1
  75. package/lib/exercises/math/probaStat/probaFromTableWithContext.js +354 -94
  76. package/lib/exercises/math/probaStat/stats1var/medianWithList.d.ts +4 -1
  77. package/lib/exercises/math/probaStat/stats1var/medianWithList.d.ts.map +1 -1
  78. package/lib/exercises/math/probaStat/stats1var/medianWithList.js +43 -23
  79. package/lib/exercises/math/probaStat/stats1var/plausibilityOfAverage.d.ts.map +1 -1
  80. package/lib/exercises/math/probaStat/stats1var/plausibilityOfAverage.js +70 -23
  81. package/lib/exercises/math/probaStat/stats1var/quartilesList.d.ts +1 -1
  82. package/lib/exercises/math/probaStat/stats1var/quartilesList.d.ts.map +1 -1
  83. package/lib/exercises/math/probaStat/stats1var/quartilesList.js +4 -4
  84. package/lib/exercises/pc/index.d.ts +0 -1
  85. package/lib/exercises/pc/index.d.ts.map +1 -1
  86. package/lib/exercises/pc/index.js +0 -1
  87. package/lib/exercises/pc/motion/averageSpeed.d.ts +0 -2
  88. package/lib/exercises/pc/motion/averageSpeed.d.ts.map +1 -1
  89. package/lib/exercises/pc/motion/averageSpeed.js +40 -45
  90. package/lib/exercises/pc/optics/lensFormula.d.ts +1 -2
  91. package/lib/exercises/pc/optics/lensFormula.d.ts.map +1 -1
  92. package/lib/exercises/pc/optics/lensFormula.js +7 -10
  93. package/lib/exercises/pc/weight/calculateWeight.d.ts +1 -3
  94. package/lib/exercises/pc/weight/calculateWeight.d.ts.map +1 -1
  95. package/lib/exercises/pc/weight/calculateWeight.js +38 -30
  96. package/lib/index.d.ts +932 -948
  97. package/lib/index.d.ts.map +1 -1
  98. package/lib/math/progCalc/progCalc.d.ts +2 -2
  99. package/lib/math/progCalc/progCalc.d.ts.map +1 -1
  100. package/lib/math/progCalc/progCalc.js +4 -11
  101. package/lib/playgroundUtils.d.ts +3 -0
  102. package/lib/playgroundUtils.d.ts.map +1 -0
  103. package/lib/playgroundUtils.js +13 -0
  104. package/lib/server.js +121 -0
  105. package/lib/tests/exoTest.d.ts.map +1 -1
  106. package/lib/tests/exoTest.js +13 -0
  107. package/lib/types/keyIds.d.ts +1 -1
  108. package/lib/types/keyIds.d.ts.map +1 -1
  109. package/package.json +1 -1
@@ -1,26 +1,235 @@
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 { Rational } 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";
6
- import { rationalParser } from "../../../tree/parsers/rationalParser.js";
7
+ import { substract } from "../../../tree/nodes/operators/substractNode.js";
8
+ import { parseAlgebraic } from "../../../tree/parsers/latexParser.js";
7
9
  import { random } from "../../../utils/alea/random.js";
8
10
  import { handleVEAError } from "../../../utils/errors/handleVEAError.js";
9
11
  import { dollarize } from "../../../utils/latex/dollarize.js";
10
12
  import { mdTable } from "../../../utils/markdown/mdTable.js";
11
- const getInstruction = ({ aBarreCapB, aBarreCapBBarre, aCapB, aCapBBarre, event, }) => {
12
- return `Le tableau suivant donne le nombre de filles et de garçons portant des lunettes dans un lycée :
13
+ const rebuildIdentifiers = (oldIds) => {
14
+ const newIds = {
15
+ indexSituation: 0,
16
+ values: {
17
+ "A \\cap B": oldIds.aCapB,
18
+ "A \\cap \\overline{B}": oldIds.aCapBBarre,
19
+ "\\overline{A} \\cap B": oldIds.aBarreCapB,
20
+ "\\overline{A} \\cap \\overline{B}": oldIds.aBarreCapBBarre,
21
+ },
22
+ event: oldIds.event,
23
+ type: oldIds.type,
24
+ probaFrac: oldIds.probaFrac,
25
+ allowedAnsType: ["exacte", "arrondie à 2 décimales"],
26
+ };
27
+ return newIds;
28
+ };
29
+ const situations = [
30
+ //genre et lunettes
31
+ {
32
+ events: {
33
+ //single
34
+ A: "une fille",
35
+ "\\overline{A}": "un garçon",
36
+ B: "un élève qui porte des lunettes",
37
+ "\\overline{B}": "un élève qui ne porte pas de lunettes",
38
+ //intersection
39
+ "A \\cap B": "une fille qui porte des lunettes",
40
+ "A \\cap \\overline{B}": "une fille qui ne porte pas de lunettes",
41
+ "\\overline{A} \\cap B": "un garçon qui porte des lunettes",
42
+ "\\overline{A} \\cap \\overline{B}": "un garçon qui ne porte pas de lunettes",
43
+ //union
44
+ "A \\cup B": "une fille ou un élève qui porte des lunettes",
45
+ "A \\cup \\overline{B}": "une fille ou un élève qui ne porte pas de lunettes",
46
+ "\\overline{A} \\cup B": "un garçon ou un élève qui porte des lunettes",
47
+ "\\overline{A} \\cup \\overline{B}": "un garçon ou un élève qui ne porte pas de lunettes",
48
+ },
49
+ instruction: {
50
+ context: `Le tableau suivant donne le nombre de filles et de garçons portant des lunettes dans un lycée`,
51
+ table: {
52
+ A: `Une fille`,
53
+ "\\overline{A}": `Un garçon`,
54
+ B: `Porte des lunettes`,
55
+ "\\overline{B}": `Ne porte pas de lunettes`,
56
+ },
57
+ beforeQuestion: `On choisit un élève au hasard.`,
58
+ },
59
+ hint: {
60
+ single: `On lit le total d'élèves correspondant au cas demandé, puis on divise par le total des élèves.`,
61
+ intersection: `On lit la case des élèves correspondant à la fois aux deux cas demandés.`,
62
+ union: `On compte tous les élèves qui sont soit dans le premier cas,
63
+ soit dans le second (ou à la fois dans les deux). Attention à ne pas compter certains élèves en double.`,
64
+ },
65
+ correction: {
66
+ total: `Le total des élèves se lit à l'intersection de la ligne "Total" et de la colonne "Total"`,
67
+ },
68
+ },
69
+ //chien et sport
70
+ {
71
+ events: {
72
+ A: "une personne qui possède un chien",
73
+ "\\overline{A}": "une personne qui ne possède pas de chien",
74
+ B: "une personne qui fait du sport",
75
+ "\\overline{B}": "une personne qui ne fait pas de sport",
76
+ "A \\cap B": "une personne qui possède un chien et fait du sport",
77
+ "A \\cap \\overline{B}": "une personne qui possède un chien mais ne fait pas de sport",
78
+ "\\overline{A} \\cap B": "une personne qui n’a pas de chien mais fait du sport",
79
+ "\\overline{A} \\cap \\overline{B}": "une personne qui n’a pas de chien et ne fait pas de sport",
80
+ "A \\cup B": "une personne qui possède un chien ou qui fait du sport",
81
+ "A \\cup \\overline{B}": "une personne qui possède un chien ou ne fait pas de sport",
82
+ "\\overline{A} \\cup B": "une personne qui n’a pas de chien ou qui fait du sport",
83
+ "\\overline{A} \\cup \\overline{B}": "une personne qui n’a pas de chien ou ne fait pas de sport",
84
+ },
85
+ instruction: {
86
+ context: "Le tableau suivant donne les résultats d’une enquête sur la possession d’un chien et la pratique du sport",
87
+ table: {
88
+ A: "Possède un chien",
89
+ "\\overline{A}": "Ne possède pas de chien",
90
+ B: "Fait du sport",
91
+ "\\overline{B}": "Ne fait pas de sport",
92
+ },
93
+ beforeQuestion: "On choisit une personne au hasard parmi les sondés.",
94
+ },
95
+ hint: {
96
+ single: "On lit le total des personnes correspondant au cas demandé, puis on divise par le total des sondés.",
97
+ intersection: "On repère la case correspondant aux deux caractéristiques simultanées.",
98
+ union: "On additionne les individus appartenant à l’un ou l’autre des groupes, sans double comptage.",
99
+ },
100
+ correction: {
101
+ total: `Le total des élèves se lit à l'intersection de la ligne "Total" et de la colonne "Total"`,
102
+ },
103
+ },
104
+ //vélo et ponctualité
105
+ {
106
+ events: {
107
+ A: "un élève qui vient au lycée à vélo",
108
+ "\\overline{A}": "un élève qui ne vient pas au lycée à vélo",
109
+ B: "un élève qui arrive à l'heure",
110
+ "\\overline{B}": "un élève qui arrive en retard",
111
+ "A \\cap B": "un élève qui vient à vélo et arrive à l'heure",
112
+ "A \\cap \\overline{B}": "un élève qui vient à vélo et arrive en retard",
113
+ "\\overline{A} \\cap B": "un élève qui ne vient pas à vélo et arrive à l'heure",
114
+ "\\overline{A} \\cap \\overline{B}": "un élève qui ne vient pas à vélo et arrive en retard",
115
+ "A \\cup B": "un élève qui vient à vélo ou qui arrive à l'heure",
116
+ "A \\cup \\overline{B}": "un élève qui vient à vélo ou arrive en retard",
117
+ "\\overline{A} \\cup B": "un élève qui ne vient pas à vélo ou arrive à l'heure",
118
+ "\\overline{A} \\cup \\overline{B}": "un élève qui ne vient pas à vélo ou arrive en retard",
119
+ },
120
+ instruction: {
121
+ context: "Le tableau suivant indique le mode de transport et la ponctualité des élèves d'un lycée",
122
+ table: {
123
+ A: "Vient à vélo",
124
+ "\\overline{A}": "Ne vient pas à vélo",
125
+ B: "Arrive à l'heure",
126
+ "\\overline{B}": "Arrive en retard",
127
+ },
128
+ beforeQuestion: "On choisit un élève au hasard.",
129
+ },
130
+ hint: {
131
+ single: `On lit le total d'élèves correspondant au cas demandé, puis on divise par le total des élèves.`,
132
+ intersection: `On lit la case des élèves correspondant à la fois aux deux cas demandés.`,
133
+ union: `On compte tous les élèves qui sont soit dans le premier cas,
134
+ soit dans le second (ou à la fois dans les deux). Attention à ne pas compter certains élèves en double.`,
135
+ },
136
+ correction: {
137
+ total: `Le total des élèves se lit à l'intersection de la ligne "Total" et de la colonne "Total"`,
138
+ },
139
+ },
140
+ //révision et réussite
141
+ {
142
+ events: {
143
+ A: "un élève qui a révisé pour le contrôle",
144
+ "\\overline{A}": "un élève qui n’a pas révisé pour le contrôle",
145
+ B: "un élève qui a réussi le contrôle",
146
+ "\\overline{B}": "un élève qui a échoué au contrôle",
147
+ "A \\cap B": "un élève qui a révisé et a réussi",
148
+ "A \\cap \\overline{B}": "un élève qui a révisé mais a échoué",
149
+ "\\overline{A} \\cap B": "un élève qui n’a pas révisé mais a réussi",
150
+ "\\overline{A} \\cap \\overline{B}": "un élève qui n’a pas révisé et a échoué",
151
+ "A \\cup B": "un élève qui a révisé ou qui a réussi le contrôle",
152
+ "A \\cup \\overline{B}": "un élève qui a révisé ou a échoué",
153
+ "\\overline{A} \\cup B": "un élève qui n’a pas révisé ou a réussi",
154
+ "\\overline{A} \\cup \\overline{B}": "un élève qui n’a pas révisé ou a échoué",
155
+ },
156
+ instruction: {
157
+ context: "Le tableau suivant présente les résultats d’un contrôle selon que les élèves ont révisé ou non",
158
+ table: {
159
+ A: "A révisé",
160
+ "\\overline{A}": "N’a pas révisé",
161
+ B: "A réussi",
162
+ "\\overline{B}": "A échoué",
163
+ },
164
+ beforeQuestion: "On choisit un élève au hasard.",
165
+ },
166
+ hint: {
167
+ single: `On lit le total d'élèves correspondant au cas demandé, puis on divise par le total des élèves.`,
168
+ intersection: `On lit la case des élèves correspondant à la fois aux deux cas demandés.`,
169
+ union: `On compte tous les élèves qui sont soit dans le premier cas,
170
+ soit dans le second (ou à la fois dans les deux). Attention à ne pas compter certains élèves en double.`,
171
+ },
172
+ correction: {
173
+ total: `Le total des élèves se lit à l'intersection de la ligne "Total" et de la colonne "Total"`,
174
+ },
175
+ },
176
+ //cinéma et lecture
177
+ {
178
+ events: {
179
+ A: "un élève qui va souvent au cinéma",
180
+ "\\overline{A}": "un élève qui ne va pas souvent au cinéma",
181
+ B: "un élève qui lit régulièrement des livres",
182
+ "\\overline{B}": "un élève qui ne lit pas régulièrement de livres",
183
+ "A \\cap B": "un élève qui va souvent au cinéma et lit régulièrement",
184
+ "A \\cap \\overline{B}": "un élève qui va souvent au cinéma mais ne lit pas régulièrement",
185
+ "\\overline{A} \\cap B": "un élève qui ne va pas au cinéma mais lit régulièrement",
186
+ "\\overline{A} \\cap \\overline{B}": "un élève qui ne va pas au cinéma et ne lit pas régulièrement",
187
+ "A \\cup B": "un élève qui va souvent au cinéma ou lit régulièrement",
188
+ "A \\cup \\overline{B}": "un élève qui va au cinéma ou ne lit pas régulièrement",
189
+ "\\overline{A} \\cup B": "un élève qui ne va pas au cinéma ou lit régulièrement",
190
+ "\\overline{A} \\cup \\overline{B}": "un élève qui ne va pas au cinéma ou ne lit pas régulièrement",
191
+ },
192
+ instruction: {
193
+ context: "Le tableau suivant décrit les habitudes culturelles des élèves d’un lycée",
194
+ table: {
195
+ A: "Va au cinéma",
196
+ "\\overline{A}": "Ne va pas au cinéma",
197
+ B: "Lit",
198
+ "\\overline{B}": "Ne lit pas",
199
+ },
200
+ beforeQuestion: "On choisit un élève au hasard parmi ceux du lycée.",
201
+ },
202
+ hint: {
203
+ single: `On lit le total d'élèves correspondant au cas demandé, puis on divise par le total des élèves.`,
204
+ intersection: `On lit la case des élèves correspondant à la fois aux deux cas demandés.`,
205
+ union: `On compte tous les élèves qui sont soit dans le premier cas,
206
+ soit dans le second (ou à la fois dans les deux). Attention à ne pas compter certains élèves en double.`,
207
+ },
208
+ correction: {
209
+ total: `Le total des élèves se lit à l'intersection de la ligne "Total" et de la colonne "Total"`,
210
+ },
211
+ },
212
+ ];
213
+ const getInstruction = ({ indexSituation, values, event, allowedAnsType, }) => {
214
+ const situation = situations[indexSituation];
215
+ const { "A \\cap B": aCapB, "A \\cap \\overline{B}": aCapBBarre, "\\overline{A} \\cap B": aBarreCapB, "\\overline{A} \\cap \\overline{B}": aBarreCapBBarre, } = values;
216
+ return `${situation.instruction.context} :
13
217
 
14
218
  ${mdTable([
15
- [" ", "Porte des lunettes", "Ne porte pas de lunettes", "Total"],
16
219
  [
17
- "Filles",
220
+ " ",
221
+ situation.instruction.table.B,
222
+ situation.instruction.table["\\overline{B}"],
223
+ "Total",
224
+ ],
225
+ [
226
+ situation.instruction.table.A,
18
227
  dollarize(aCapB),
19
228
  dollarize(aCapBBarre),
20
229
  dollarize(aCapB + aCapBBarre),
21
230
  ],
22
231
  [
23
- "Garçons",
232
+ situation.instruction.table["\\overline{A}"],
24
233
  dollarize(aBarreCapB),
25
234
  dollarize(aBarreCapBBarre),
26
235
  dollarize(aBarreCapB + aBarreCapBBarre),
@@ -33,23 +242,34 @@ ${mdTable([
33
242
  ],
34
243
  ])}
35
244
 
36
- On choisit un élève au hasard. Quelle est la probabilité de tomber sur ${event} ?
245
+ ${situation.instruction.beforeQuestion}
246
+ Quelle est la probabilité de tomber sur ${situation.events[event]} ?
37
247
 
38
- Donner la valeur exacte.`;
248
+ Donner ${getStrAllowedAnswerTypes(getStrInternalAllowedAnswerTypes(allowedAnsType))}.`;
39
249
  };
40
- const getAnswer = (identifiers) => {
41
- const { probaFrac } = identifiers;
42
- const answer = new Rational(probaFrac[0], probaFrac[1])
250
+ const getAnswerNode = (identifiers) => {
251
+ const { probaFrac, allowedAnsType } = identifiers;
252
+ const exactNode = new Rational(probaFrac[0], probaFrac[1])
43
253
  .simplify()
44
- .toTree()
45
- .toTex();
46
- return answer;
254
+ .toTree();
255
+ return createFormattedNode(exactNode, getStrInternalAllowedAnswerTypes(allowedAnsType));
47
256
  };
48
- const getProbaFromTableWithContextQuestion = () => {
257
+ const getAnswer = (identifiers) => {
258
+ return getAnswerNode(identifiers).toTex();
259
+ };
260
+ const getProbaFromTableWithContextQuestion = (optsIn) => {
261
+ const opts = optsIn ?? optsDefault;
262
+ const allowedAnsType = opts.allowedAnsType;
49
263
  const aCapB = randint(1, 20);
50
264
  const aCapBBarre = randint(1, 20, [aCapB]);
51
265
  const aBarreCapB = randint(1, 20, [aCapB, aCapBBarre]);
52
266
  const aBarreCapBBarre = randint(1, 20, [aCapB, aCapBBarre, aBarreCapB]);
267
+ const values = {
268
+ "A \\cap B": aCapB,
269
+ "A \\cap \\overline{B}": aCapBBarre,
270
+ "\\overline{A} \\cap B": aBarreCapB,
271
+ "\\overline{A} \\cap \\overline{B}": aBarreCapBBarre,
272
+ };
53
273
  const total = aBarreCapB + aBarreCapBBarre + aCapB + aCapBBarre;
54
274
  const aTotal = aCapB + aCapBBarre;
55
275
  const bTotal = aCapB + aBarreCapB;
@@ -65,53 +285,41 @@ const getProbaFromTableWithContextQuestion = () => {
65
285
  switch (type) {
66
286
  case "singleEvent":
67
287
  [event, proba] = random([
68
- ["une fille", [aTotal, total]],
69
- ["un élève qui porte des lunettes", [bTotal, total]],
70
- ["un garçon", [aBarreTotal, total]],
71
- ["un élève qui ne porte pas de lunettes", [bBarreTotal, total]],
288
+ ["A", [aTotal, total]],
289
+ ["B", [bTotal, total]],
290
+ ["\\overline{A}", [aBarreTotal, total]],
291
+ ["\\overline{B}", [bBarreTotal, total]],
72
292
  ]);
73
293
  break;
74
294
  case "intersection":
75
295
  [event, proba] = random([
76
- ["une fille qui porte des lunettes", [aCapB, total]],
77
- ["un garçon qui porte des lunettes", [aBarreCapB, total]],
78
- ["une fille qui ne porte pas de lunettes", [aCapBBarre, total]],
79
- ["un garçon qui ne porte pas de lunettes", [aBarreCapBBarre, total]],
296
+ ["A \\cap B", [aCapB, total]],
297
+ ["\\overline{A} \\cap B", [aBarreCapB, total]],
298
+ ["A \\cap \\overline{B}", [aCapBBarre, total]],
299
+ ["\\overline{A} \\cap \\overline{B}", [aBarreCapBBarre, total]],
80
300
  ]);
81
301
  break;
82
302
  case "union":
83
303
  [event, proba] = random([
84
- [
85
- "une fille ou un élève qui porte des lunettes",
86
- [total - aBarreCapBBarre, total],
87
- ],
88
- [
89
- "une fille ou un élève qui ne porte pas de lunettes",
90
- [total - aBarreCapB, total],
91
- ],
92
- [
93
- "un garçon ou un élève qui porte des lunettes",
94
- [total - aCapBBarre, total],
95
- ],
96
- [
97
- "un garçon ou un élève qui ne porte pas de lunettes",
98
- [total - aCapB, total],
99
- ],
304
+ ["A \\cup B", [total - aBarreCapBBarre, total]],
305
+ ["A \\cup \\overline{B}", [total - aBarreCapB, total]],
306
+ ["\\overline{A} \\cup B", [total - aCapBBarre, total]],
307
+ ["\\overline{A} \\cup \\overline{B}", [total - aCapB, total]],
100
308
  ]);
101
309
  break;
102
310
  }
311
+ const indexSituation = randint(0, situations.length);
103
312
  const identifiers = {
104
- aBarreCapB,
105
- aBarreCapBBarre,
106
- aCapB,
107
- aCapBBarre,
313
+ values,
314
+ indexSituation,
108
315
  event,
109
316
  type,
110
317
  probaFrac: proba,
318
+ allowedAnsType,
111
319
  };
112
320
  return getQuestionFromIdentifiers(identifiers);
113
321
  };
114
- const getQuestionFromIdentifiers = (identifiers) => {
322
+ const getQuestionFromIdentifiers = (identifiers, opts) => {
115
323
  const question = {
116
324
  answer: getAnswer(identifiers),
117
325
  instruction: getInstruction(identifiers),
@@ -120,119 +328,170 @@ const getQuestionFromIdentifiers = (identifiers) => {
120
328
  identifiers,
121
329
  hint: getHint(identifiers),
122
330
  correction: getCorrection(identifiers),
331
+ options: opts,
123
332
  };
124
333
  return question;
125
334
  };
126
- const getPropositions = (n, { answer, aBarreCapB, aBarreCapBBarre, aCapB, aCapBBarre }) => {
335
+ const getPropositions = (n, { answer, values, allowedAnsType }) => {
336
+ const { "A \\cap B": aCapB, "A \\cap \\overline{B}": aCapBBarre, "\\overline{A} \\cap B": aBarreCapB, "\\overline{A} \\cap \\overline{B}": aBarreCapBBarre, } = values;
127
337
  const propositions = [];
128
338
  addValidProp(propositions, answer);
129
- propWhile(propositions, n, () => {
130
- tryToAddWrongProp(propositions, new Rational(random([aBarreCapB, aBarreCapBBarre, aCapB, aCapBBarre]), random([aBarreCapB, aBarreCapBBarre, aCapB, aCapBBarre]) +
339
+ function createWrongNode() {
340
+ const exactNode = new Rational(random([aBarreCapB, aBarreCapBBarre, aCapB, aCapBBarre]), random([aBarreCapB, aBarreCapBBarre, aCapB, aCapBBarre]) +
131
341
  random([aBarreCapB, aBarreCapBBarre, aCapB, aCapBBarre]))
132
342
  .simplify()
133
- .toTree()
134
- .toTex());
343
+ .toTree();
344
+ return createFormattedNode(exactNode, getStrInternalAllowedAnswerTypes(allowedAnsType));
345
+ }
346
+ propWhile(propositions, n, () => {
347
+ tryToAddWrongProp(propositions, createWrongNode().toTex());
135
348
  });
136
349
  return shuffleProps(propositions, n);
137
350
  };
138
351
  // const options: GeneratorOption[] = [allowNonIrreductibleOption];
139
- const isAnswerValid = (ans, { answer }) => {
352
+ const isAnswerValid = (ans, { answer, ...identifiers }) => {
140
353
  try {
141
- const parsed = rationalParser(ans);
142
- if (!parsed)
354
+ const ansNode = parseAlgebraic(ans);
355
+ if (!ansNode)
143
356
  return false;
144
- return parsed.simplify({ decimalToFractions: true }).toTex() === answer;
357
+ return getAllValidNodes(identifiers).some((answerNode) => {
358
+ return substract(ansNode, answerNode).simplify().evaluate() === 0;
359
+ });
145
360
  }
146
361
  catch (err) {
147
362
  return handleVEAError(err);
148
363
  }
149
364
  };
150
365
  const getHint = (identifiers) => {
151
- const { type } = identifiers;
366
+ const { indexSituation, type } = identifiers;
367
+ const situation = situations[indexSituation];
152
368
  switch (type) {
153
369
  case "singleEvent":
154
- return `Lit le total d'élèves correspondant au cas demandé, puis divise par le total des élèves.`;
370
+ return situation.hint.single;
155
371
  case "union":
156
- return `Compte tous les élèves qui sont soit dans le premier cas, soit dans le second (ou à la fois dans les deux). Attention à ne pas compter certains élèves en double.`;
372
+ return situation.hint.union;
157
373
  case "intersection":
158
374
  default:
159
- return `Lit la case des élèves correspondant à la fois aux deux cas demandés.`;
375
+ return situation.hint.intersection;
160
376
  }
161
377
  };
162
378
  const getCorrection = (identifiers) => {
163
- const { aBarreCapB, aBarreCapBBarre, aCapB, aCapBBarre, probaFrac, type, event, } = identifiers;
379
+ const { values, probaFrac, type, event, indexSituation, allowedAnsType } = identifiers;
380
+ const situation = situations[indexSituation];
381
+ const { "A \\cap B": aCapB, "A \\cap \\overline{B}": aCapBBarre, "\\overline{A} \\cap B": aBarreCapB, "\\overline{A} \\cap \\overline{B}": aBarreCapBBarre, } = values;
164
382
  const aTotal = aCapB + aCapBBarre;
165
383
  const bTotal = aCapB + aBarreCapB;
166
384
  const aBarreTotal = aBarreCapB + aBarreCapBBarre;
167
385
  const bBarreTotal = aBarreCapBBarre + aCapBBarre;
386
+ const strRoundTo = allowedAnsType.length === 1 &&
387
+ allowedAnsType[0] === "arrondie à 2 décimales"
388
+ ? `Arrondi à $2$ décimales, cela donne $${getAnswerNode(identifiers).toTex()}$.`
389
+ : "";
168
390
  switch (type) {
169
391
  case "singleEvent": {
170
- const singleEvnmt = event === "une fille"
171
- ? "Filles"
172
- : event === "un garçon"
173
- ? "Garçons"
174
- : event === "un élève qui porte des lunettes"
175
- ? "Porte des lunettes"
176
- : "Ne porte pas de lunettes";
177
- const isLine = event === "une fille" || event === "un garçon";
178
- return `On lit le total de la ${isLine ? "ligne" : "colonne"} "${singleEvnmt}" : c'est $${probaFrac[0]}$.
392
+ const tableLabel = situation.instruction.table[event];
393
+ const isLine = event === "A" || event === "\\overline{A}";
394
+ return `On lit le total de la ${isLine ? "ligne" : "colonne"} "${tableLabel}" : c'est $${probaFrac[0]}$.
179
395
 
180
- Le total des élèves se lit à l'intersection de la ligne "Total" et de la colonne "Total" : c'est $${probaFrac[1]}$.
396
+ ${situation.correction.total} : c'est $${probaFrac[1]}$.
181
397
 
182
398
  La probabilité recherchée vaut donc :
183
399
 
184
400
  $$
185
401
  ${frac(probaFrac[0], probaFrac[1]).toSimplificationTex()}
186
- $$`;
402
+ $$
403
+
404
+ ${strRoundTo}
405
+ `;
187
406
  }
188
407
  case "union": {
189
- const unionEvements = event.split(" ou ");
190
- const rowTotal = unionEvements[0] === "une fille" ? aTotal : aBarreTotal;
191
- const columnTotal = unionEvements[1] === "un élève qui porte des lunettes"
192
- ? bTotal
193
- : bBarreTotal;
194
- unionEvements[0] = unionEvements[0]
195
- .replace("une", "")
196
- .replace("un", "")
197
- .trim();
198
- unionEvements[1] = unionEvements[1].replace("un élève qui ", "");
199
- return `On additionne les totaux de la ligne "${unionEvements[0]}" et de la colonne "${unionEvements[1]}" : cela donne $${rowTotal} + ${columnTotal} = ${rowTotal + columnTotal}$.
408
+ const unionEvements = event.split(" \\cup ");
409
+ const rowTotal = unionEvements[0] === "A" ? aTotal : aBarreTotal;
410
+ const columnTotal = unionEvements[1] === "B" ? bTotal : bBarreTotal;
411
+ const tableLabels = unionEvements.map((event) => situation.instruction.table[event]);
412
+ return `On additionne les totaux de la ligne "${tableLabels[0]}" et de la colonne "${tableLabels[1]}" : cela donne $${rowTotal} + ${columnTotal} = ${rowTotal + columnTotal}$.
200
413
 
201
- On doit ensuite soustraire la case à l'intersection de la ligne "${unionEvements[0]}" et de la colonne "${unionEvements[1]}", car on l'a compté deux fois dans les totaux. Cela donne $${rowTotal + columnTotal} - ${rowTotal + columnTotal - probaFrac[0]} = ${probaFrac[0]}
414
+ On doit ensuite soustraire la case à l'intersection de la ligne "${tableLabels[0]}" et de la colonne "${tableLabels[1]}", car on l'a compté deux fois dans les totaux. Cela donne $${rowTotal + columnTotal} - ${rowTotal + columnTotal - probaFrac[0]} = ${probaFrac[0]}
202
415
  $.
203
416
 
204
- Le total des élèves se lit à l'intersection de la ligne "Total" et de la colonne "Total" : c'est $${probaFrac[1]}$.
417
+ ${situation.correction.total} : c'est $${probaFrac[1]}$.
205
418
 
206
- La probabilité de tomber sur ${event} vaut donc :
419
+ La probabilité de tomber sur ${situation.events[event]} vaut donc :
207
420
 
208
421
  $$
209
422
  ${frac(probaFrac[0], probaFrac[1]).toSimplificationTex()}
210
- $$`;
423
+ $$
424
+
425
+ ${strRoundTo}
426
+ `;
211
427
  }
212
428
  case "intersection":
213
429
  default: {
214
- const interEvemnts = event.split(" qui ");
215
- return `On lit la case à l'intersection de la colonne "${interEvemnts[1]}" et de la ligne "${interEvemnts[0]
216
- .replace("une", "")
217
- .replace("un", "")
218
- .trim()}s" : c'est $${probaFrac[0]}$.
430
+ const interEvemnts = event.split(" \\cap ");
431
+ const tableLabels = interEvemnts.map((event) => situation.instruction.table[event]);
432
+ return `On lit la case à l'intersection de la colonne "${tableLabels[1]}" et de la ligne "${tableLabels[0]}" : c'est $${probaFrac[0]}$.
219
433
 
220
- Le total des élèves se lit à l'intersection de la ligne "Total" et de la colonne "Total" : c'est $${probaFrac[1]}$.
434
+ ${situation.correction.total} : c'est $${probaFrac[1]}$.
221
435
 
222
- La probabilité de tomber sur ${event} vaut donc :
436
+ La probabilité de tomber sur ${situation.events[event]} vaut donc :
223
437
 
224
438
  $$
225
439
  ${frac(probaFrac[0], probaFrac[1]).toSimplificationTex()}
226
- $$`;
440
+ $$
441
+
442
+ ${strRoundTo}
443
+ `;
227
444
  }
228
445
  }
229
446
  };
447
+ const getStrInternalAllowedAnswerTypes = (allowedAnsType) => {
448
+ return allowedAnsType.toSorted((a, b) => a.localeCompare(b)).join(" | ");
449
+ };
450
+ const getStrAllowedAnswerTypes = (strInternalAllowedAnswerTypes) => {
451
+ switch (strInternalAllowedAnswerTypes) {
452
+ case "arrondie à 2 décimales | exacte":
453
+ return "la valeur exacte ou la valeur arrondie à $2$ décimales";
454
+ case "arrondie à 2 décimales":
455
+ return "la valeur arrondie à $2$ décimales";
456
+ case "exacte":
457
+ return "la valeur exacte";
458
+ }
459
+ };
460
+ const createFormattedNode = (exactNode, strInternalAllowedAnswerTypes) => {
461
+ switch (strInternalAllowedAnswerTypes) {
462
+ case "arrondie à 2 décimales":
463
+ return round(exactNode.evaluate(), 2).toTree();
464
+ default:
465
+ return exactNode;
466
+ }
467
+ };
468
+ const getAllValidNodes = (identifiers) => {
469
+ return identifiers.allowedAnsType.map((ansType) => getAnswerNode((() => {
470
+ const identifiersCopy = Object.assign({}, identifiers);
471
+ identifiersCopy.allowedAnsType = [ansType];
472
+ return identifiersCopy;
473
+ })()));
474
+ };
475
+ const optsDefault = {
476
+ allowedAnsType: ["exacte", "arrondie à 2 décimales"],
477
+ };
478
+ const options = [
479
+ {
480
+ id: "allowedAnsType",
481
+ label: "Forme de réponse acceptée",
482
+ target: GeneratorOptionTarget.generation,
483
+ type: GeneratorOptionType.multiselect,
484
+ values: ["exacte", "arrondie à 2 décimales"],
485
+ defaultValue: optsDefault.allowedAnsType,
486
+ },
487
+ ];
230
488
  export const probaFromTableWithContext = {
231
489
  id: "probaFromTableWithContext",
232
490
  connector: "=",
233
491
  label: "Utiliser un tableau à double entrée pour calculer une probabilité (avec contexte)",
234
492
  isSingleStep: true,
235
- generator: (nb, options) => getDistinctQuestions(() => getProbaFromTableWithContextQuestion(options), nb),
493
+ generator: (nb, opts) => getDistinctQuestions(() => getProbaFromTableWithContextQuestion(opts), nb),
494
+ options,
236
495
  qcmTimer: 60,
237
496
  freeTimer: 60,
238
497
  getPropositions,
@@ -240,4 +499,5 @@ export const probaFromTableWithContext = {
240
499
  subject: "Mathématiques",
241
500
  getQuestionFromIdentifiers,
242
501
  hasHintAndCorrection: true,
502
+ rebuildIdentifiers: rebuildIdentifiers,
243
503
  };
@@ -2,6 +2,9 @@ import { Exercise } from "../../../exercise.js";
2
2
  type Identifiers = {
3
3
  sortedValues: number[];
4
4
  };
5
- export declare const medianWithList: Exercise<Identifiers>;
5
+ type Options = {
6
+ nbValues: string;
7
+ };
8
+ export declare const medianWithList: Exercise<Identifiers, Options>;
6
9
  export {};
7
10
  //# sourceMappingURL=medianWithList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"medianWithList.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/medianWithList.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EAeT,MAAM,sBAAsB,CAAC;AAE9B,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAkFF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,CAahD,CAAC"}
1
+ {"version":3,"file":"medianWithList.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/stats1var/medianWithList.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,QAAQ,EAkBT,MAAM,sBAAsB,CAAC;AAE9B,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AA2FF,KAAK,OAAO,GAAG;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAsBF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAezD,CAAC"}