math-exercises 3.0.190 → 3.0.191

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 (76) hide show
  1. package/lib/exercises/math/dataRepresentations/scatterPlot/index.d.ts +6 -0
  2. package/lib/exercises/math/dataRepresentations/scatterPlot/index.d.ts.map +1 -0
  3. package/lib/exercises/math/dataRepresentations/scatterPlot/index.js +5 -0
  4. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotBuildScatterPlotFromDataTable.d.ts +12 -0
  5. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotBuildScatterPlotFromDataTable.d.ts.map +1 -0
  6. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotBuildScatterPlotFromDataTable.js +206 -0
  7. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotCommenting.d.ts +9 -0
  8. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotCommenting.d.ts.map +1 -0
  9. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotCommenting.js +210 -0
  10. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotFillDataTableFromScatterPlotData.d.ts +10 -0
  11. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotFillDataTableFromScatterPlotData.d.ts.map +1 -0
  12. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotFillDataTableFromScatterPlotData.js +252 -0
  13. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotFillDataTableWithDataClassesFromScatterPlotData.d.ts +12 -0
  14. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotFillDataTableWithDataClassesFromScatterPlotData.d.ts.map +1 -0
  15. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotFillDataTableWithDataClassesFromScatterPlotData.js +352 -0
  16. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotInterpreting.d.ts +11 -0
  17. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotInterpreting.d.ts.map +1 -0
  18. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotInterpreting.js +403 -0
  19. package/lib/exercises/math/derivation/tangent/tangentEquationFromFunctionExpression.js +1 -1
  20. package/lib/exercises/math/derivation/variations/signVarTableFromFunctionExpression.d.ts.map +1 -1
  21. package/lib/exercises/math/derivation/variations/signVarTableFromFunctionExpression.js +4 -1
  22. package/lib/exercises/math/functions/affines/affineCompareTwoImagesFromVariations.d.ts +13 -0
  23. package/lib/exercises/math/functions/affines/affineCompareTwoImagesFromVariations.d.ts.map +1 -0
  24. package/lib/exercises/math/functions/affines/affineCompareTwoImagesFromVariations.js +205 -0
  25. package/lib/exercises/math/functions/affines/affineVarTableOnBoundedInterval.d.ts +9 -0
  26. package/lib/exercises/math/functions/affines/affineVarTableOnBoundedInterval.d.ts.map +1 -0
  27. package/lib/exercises/math/functions/affines/affineVarTableOnBoundedInterval.js +157 -0
  28. package/lib/exercises/math/functions/affines/affineVariations.d.ts +12 -0
  29. package/lib/exercises/math/functions/affines/affineVariations.d.ts.map +1 -0
  30. package/lib/exercises/math/functions/affines/affineVariations.js +176 -0
  31. package/lib/exercises/math/functions/affines/affineVariationsFromGraph.d.ts +8 -0
  32. package/lib/exercises/math/functions/affines/affineVariationsFromGraph.d.ts.map +1 -0
  33. package/lib/exercises/math/functions/affines/affineVariationsFromGraph.js +203 -0
  34. package/lib/exercises/math/functions/affines/affineVariationsFromTwoImages.d.ts +12 -0
  35. package/lib/exercises/math/functions/affines/affineVariationsFromTwoImages.d.ts.map +1 -0
  36. package/lib/exercises/math/functions/affines/affineVariationsFromTwoImages.js +259 -0
  37. package/lib/exercises/math/functions/exponentials/exponentialFunctionImage.d.ts +9 -0
  38. package/lib/exercises/math/functions/exponentials/exponentialFunctionImage.d.ts.map +1 -0
  39. package/lib/exercises/math/functions/exponentials/exponentialFunctionImage.js +99 -0
  40. package/lib/exercises/math/functions/exponentials/index.d.ts +5 -0
  41. package/lib/exercises/math/functions/exponentials/index.d.ts.map +1 -1
  42. package/lib/exercises/math/functions/exponentials/index.js +5 -0
  43. package/lib/exercises/math/functions/exponentials/realPowersFraction.d.ts +10 -0
  44. package/lib/exercises/math/functions/exponentials/realPowersFraction.d.ts.map +1 -0
  45. package/lib/exercises/math/functions/exponentials/realPowersFraction.js +125 -0
  46. package/lib/exercises/math/functions/exponentials/realPowersMixOperations.d.ts +12 -0
  47. package/lib/exercises/math/functions/exponentials/realPowersMixOperations.d.ts.map +1 -0
  48. package/lib/exercises/math/functions/exponentials/realPowersMixOperations.js +148 -0
  49. package/lib/exercises/math/functions/exponentials/realPowersPower.d.ts +10 -0
  50. package/lib/exercises/math/functions/exponentials/realPowersPower.d.ts.map +1 -0
  51. package/lib/exercises/math/functions/exponentials/realPowersPower.js +128 -0
  52. package/lib/exercises/math/functions/exponentials/realPowersProduct.d.ts +10 -0
  53. package/lib/exercises/math/functions/exponentials/realPowersProduct.d.ts.map +1 -0
  54. package/lib/exercises/math/functions/exponentials/realPowersProduct.js +128 -0
  55. package/lib/exercises/math/sequences/geometric/geometricFindNextTermFromTwoConsecutiveTerms.d.ts +12 -0
  56. package/lib/exercises/math/sequences/geometric/geometricFindNextTermFromTwoConsecutiveTerms.d.ts.map +1 -0
  57. package/lib/exercises/math/sequences/geometric/geometricFindNextTermFromTwoConsecutiveTerms.js +217 -0
  58. package/lib/exercises/math/sequences/geometric/geometricFindRecurrenceFormula.d.ts +10 -0
  59. package/lib/exercises/math/sequences/geometric/geometricFindRecurrenceFormula.d.ts.map +1 -0
  60. package/lib/exercises/math/sequences/geometric/geometricFindRecurrenceFormula.js +186 -0
  61. package/lib/exercises/math/sequences/geometric/graph/geometricPlaceFirstPoints.d.ts +14 -0
  62. package/lib/exercises/math/sequences/geometric/graph/geometricPlaceFirstPoints.d.ts.map +1 -0
  63. package/lib/exercises/math/sequences/geometric/graph/geometricPlaceFirstPoints.js +189 -0
  64. package/lib/exercises/math/sequences/geometric/graph/index.d.ts +2 -0
  65. package/lib/exercises/math/sequences/geometric/graph/index.d.ts.map +1 -0
  66. package/lib/exercises/math/sequences/geometric/graph/index.js +1 -0
  67. package/lib/index.d.ts +21 -0
  68. package/lib/index.d.ts.map +1 -1
  69. package/lib/tree/nodes/algebraicNode.d.ts +3 -0
  70. package/lib/tree/nodes/algebraicNode.d.ts.map +1 -1
  71. package/lib/tree/nodes/operators/fractionNode.d.ts.map +1 -1
  72. package/lib/tree/nodes/operators/fractionNode.js +5 -3
  73. package/lib/tree/nodes/operators/multiplyNode.d.ts.map +1 -1
  74. package/lib/tree/nodes/operators/multiplyNode.js +5 -3
  75. package/lib/tree/nodes/operators/powerNode.js +1 -1
  76. package/package.json +1 -1
@@ -0,0 +1,403 @@
1
+ import { tryToAddWrongProp, addValidProp, propWhile, shuffleProps, } from "../../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
3
+ import { numberVEA } from "../../../../exercises/vea/numberVEA.js";
4
+ import { greenMain, orange, red } from "../../../../geogebra/colors.js";
5
+ import { GeogebraConstructor } from "../../../../geogebra/geogebraConstructor.js";
6
+ import { Point, PointConstructor, } from "../../../../math/geometry/point.js";
7
+ import { randint } from "../../../../math/utils/random/randint.js";
8
+ import { NodeConstructor, } from "../../../../tree/nodes/nodeConstructor.js";
9
+ import { add } from "../../../../tree/nodes/operators/addNode.js";
10
+ import { ClosureType } from "../../../../tree/nodes/sets/closure.js";
11
+ import { IntervalNode } from "../../../../tree/nodes/sets/intervalNode.js";
12
+ import { NodeComparator } from "../../../../tree/utilities/nodeComparator.js";
13
+ import { coinFlip } from "../../../../utils/alea/coinFlip.js";
14
+ import { probaFlip } from "../../../../utils/alea/probaFlip.js";
15
+ import { probaLawFlip } from "../../../../utils/alea/probaLawFlip.js";
16
+ import { random } from "../../../../utils/alea/random.js";
17
+ import { shuffle } from "../../../../utils/alea/shuffle.js";
18
+ import { getCartesiansProducts } from "../../../../utils/arrays/cartesianProducts.js";
19
+ const getComponentOfPointForStrGroupBy = (point, strGroupBy) => {
20
+ switch (strGroupBy) {
21
+ case "x":
22
+ return point.x;
23
+ case "y":
24
+ return point.y;
25
+ default:
26
+ throw new Error("Unsupported strGroupBy: " + strGroupBy);
27
+ }
28
+ };
29
+ const getTexCondition = (strGroupBy, nodeDataClass) => {
30
+ if (NodeComparator.isEqualViaSub(nodeDataClass.a, nodeDataClass.b)) {
31
+ return `${strGroupBy} = ${nodeDataClass.a.toTex()}`;
32
+ }
33
+ else {
34
+ switch (nodeDataClass.closure) {
35
+ case ClosureType.FF:
36
+ return `${nodeDataClass.a.toTex()} \\leq ${strGroupBy} \\leq ${nodeDataClass.b.toTex()}`;
37
+ case ClosureType.FO:
38
+ return `${nodeDataClass.a.toTex()} \\leq ${strGroupBy} < ${nodeDataClass.b.toTex()}`;
39
+ case ClosureType.OF:
40
+ return `${nodeDataClass.a.toTex()} < ${strGroupBy} \\leq ${nodeDataClass.b.toTex()}`;
41
+ case ClosureType.OO:
42
+ return `${nodeDataClass.a.toTex()} < ${strGroupBy} < ${nodeDataClass.b.toTex()}`;
43
+ }
44
+ }
45
+ };
46
+ const getInstruction = (identifiers) => {
47
+ const { strGroupBy, nodeIdsDataClass } = identifiers;
48
+ const nodeDataClass = NodeConstructor.fromIdentifiers(nodeIdsDataClass);
49
+ return `Si l'on considère le nuage de points ci-dessous,
50
+ combien y a-t-il d'éléments avec $${getTexCondition(strGroupBy, nodeDataClass)}$ ?`;
51
+ };
52
+ const getAnswerNode = (identifiers) => {
53
+ const { pointIds, strGroupBy, nodeIdsDataClass } = identifiers;
54
+ const arrPoint = pointIds.map((pointIds) => PointConstructor.fromIdentifiers(pointIds));
55
+ const nodeDataClass = NodeConstructor.fromIdentifiers(nodeIdsDataClass);
56
+ const count = arrPoint.filter((point) => {
57
+ const nodeComponent = getComponentOfPointForStrGroupBy(point, strGroupBy);
58
+ return nodeDataClass.includes(nodeComponent);
59
+ }).length;
60
+ return count.toTree();
61
+ };
62
+ const getAnswer = (identifiers) => {
63
+ return getAnswerNode(identifiers).toTex();
64
+ };
65
+ const getHint = (identifiers) => {
66
+ const { strGroupBy, nodeIdsDataClass } = identifiers;
67
+ const nodeDataClass = NodeConstructor.fromIdentifiers(nodeIdsDataClass);
68
+ return `Compte le nombre de points qui ont $${getTexCondition(strGroupBy, nodeDataClass)}$.`;
69
+ };
70
+ const getCorrection = (identifiers) => {
71
+ const { strGroupBy, nodeIdsDataClass } = identifiers;
72
+ const nodeDataClass = NodeConstructor.fromIdentifiers(nodeIdsDataClass);
73
+ return `On compte le nombre de points qui ont $${getTexCondition(strGroupBy, nodeDataClass)}$.
74
+
75
+ Il y en a $${getAnswer(identifiers)}$.
76
+ `;
77
+ };
78
+ const getCorrectionGGBOptions = (identifiers) => {
79
+ const { pointIds, strGroupBy, nodeIdsDataClass } = identifiers;
80
+ const arrPoint = pointIds.map((pointIds) => PointConstructor.fromIdentifiers(pointIds));
81
+ const nodeDataClass = NodeConstructor.fromIdentifiers(nodeIdsDataClass);
82
+ const [arrPointFiltered, arrPointDropped] = arrPoint.reduce((acc, point) => {
83
+ const nodeComponent = getComponentOfPointForStrGroupBy(point, strGroupBy);
84
+ if (nodeDataClass.includes(nodeComponent)) {
85
+ acc[0].push(point);
86
+ }
87
+ else {
88
+ acc[1].push(point);
89
+ }
90
+ return acc;
91
+ }, [[], []]);
92
+ const commands = [
93
+ ...[arrPointFiltered, arrPointDropped].flatMap((arrPoint, i) => arrPoint.flatMap((point) => point.toGGBCommand({
94
+ isFixed: true,
95
+ isSelectionnable: true,
96
+ showLabel: false,
97
+ size: 6,
98
+ style: 3,
99
+ color: i % 2 === 0 ? greenMain : "#000000",
100
+ }))),
101
+ ...(() => {
102
+ switch (strGroupBy) {
103
+ case "x":
104
+ return [nodeDataClass].flatMap((nodeInterval, i) => {
105
+ return [
106
+ ...(() => {
107
+ const value = nodeInterval.a.evaluate();
108
+ return [
109
+ `l${i}l = Line((${value}, 0),(${value}, 1))`,
110
+ `SetColor(l${i}l, "${(() => {
111
+ switch (nodeInterval.closure) {
112
+ case ClosureType.FF:
113
+ case ClosureType.FO:
114
+ return orange;
115
+ case ClosureType.OF:
116
+ case ClosureType.OO:
117
+ return red;
118
+ }
119
+ })()}")`,
120
+ ];
121
+ })(),
122
+ ...(() => {
123
+ const value = nodeInterval.b.evaluate();
124
+ return [
125
+ `l${i}h = Line((${value}, 0),(${value}, 1))`,
126
+ `SetColor(l${i}h, "${(() => {
127
+ switch (nodeInterval.closure) {
128
+ case ClosureType.FF:
129
+ case ClosureType.OF:
130
+ return orange;
131
+ case ClosureType.FO:
132
+ case ClosureType.OO:
133
+ return red;
134
+ }
135
+ })()}")`,
136
+ ];
137
+ })(),
138
+ ];
139
+ });
140
+ case "y":
141
+ return [nodeDataClass].flatMap((nodeInterval, i) => {
142
+ return [
143
+ ...(() => {
144
+ const value = nodeInterval.a.evaluate();
145
+ return [
146
+ `l${i}l = Line((0, ${value}),(1,${value}))`,
147
+ `SetColor(l${i}l, "${(() => {
148
+ switch (nodeInterval.closure) {
149
+ case ClosureType.FF:
150
+ case ClosureType.FO:
151
+ return orange;
152
+ case ClosureType.OF:
153
+ case ClosureType.OO:
154
+ return red;
155
+ }
156
+ })()}")`,
157
+ ];
158
+ })(),
159
+ ...(() => {
160
+ const value = nodeInterval.b.evaluate();
161
+ return [
162
+ `l${i}h = Line((0, ${value}),(1,${value}))`,
163
+ `SetColor(l${i}h, "${(() => {
164
+ switch (nodeInterval.closure) {
165
+ case ClosureType.FF:
166
+ case ClosureType.OF:
167
+ return orange;
168
+ case ClosureType.FO:
169
+ case ClosureType.OO:
170
+ return red;
171
+ }
172
+ })()}")`,
173
+ ];
174
+ })(),
175
+ ];
176
+ });
177
+ default:
178
+ throw new Error("Unsupported strGroupBy: " + strGroupBy);
179
+ }
180
+ })(),
181
+ ];
182
+ const ggb = new GeogebraConstructor({
183
+ commands,
184
+ hideGrid: true,
185
+ fontSize: 16,
186
+ xAxis: {
187
+ showPositive: true,
188
+ label: "x",
189
+ steps: 1,
190
+ },
191
+ yAxis: {
192
+ showPositive: true,
193
+ label: "y",
194
+ steps: 1,
195
+ },
196
+ });
197
+ return ggb.getOptions({
198
+ coords: ggb.getAdaptedCoords({
199
+ xMin: -1,
200
+ xMax: 6,
201
+ yMin: -1,
202
+ yMax: 6,
203
+ }),
204
+ });
205
+ };
206
+ const getGGBOptions = (identifiers) => {
207
+ const { pointIds } = identifiers;
208
+ const arrPoint = pointIds.map((pointIds) => PointConstructor.fromIdentifiers(pointIds));
209
+ const commands = [
210
+ ...arrPoint.flatMap((point) => point.toGGBCommand({
211
+ isFixed: true,
212
+ isSelectionnable: true,
213
+ showLabel: false,
214
+ size: 5,
215
+ style: 3,
216
+ })),
217
+ ];
218
+ const ggb = new GeogebraConstructor({
219
+ commands,
220
+ hideGrid: false,
221
+ fontSize: 16,
222
+ xAxis: {
223
+ showPositive: true,
224
+ label: "x",
225
+ steps: 1,
226
+ },
227
+ yAxis: {
228
+ showPositive: true,
229
+ label: "y",
230
+ steps: 1,
231
+ },
232
+ });
233
+ return ggb.getOptions({
234
+ coords: ggb.getAdaptedCoords({
235
+ xMin: -1,
236
+ xMax: 6,
237
+ yMin: -1,
238
+ yMax: 6,
239
+ }),
240
+ });
241
+ };
242
+ const getPropositions = (n, { answer, ...identifiers }) => {
243
+ const { strGroupBy, nodeIdsDataClass } = identifiers;
244
+ const nodeDataClass = NodeConstructor.fromIdentifiers(nodeIdsDataClass);
245
+ const propositions = [];
246
+ addValidProp(propositions, answer);
247
+ const arrTerror = [answer];
248
+ //student: wrong groupBy
249
+ {
250
+ const identifiersWrong = {
251
+ ...identifiers,
252
+ strGroupBy: strGroupBy === "x" ? "y" : "x",
253
+ };
254
+ const texWrong = getAnswer(identifiersWrong);
255
+ tryToAddWrongProp(propositions, texWrong);
256
+ arrTerror.push(texWrong);
257
+ }
258
+ //student: wrong closure
259
+ {
260
+ [ClosureType.FF, ClosureType.FO, ClosureType.OF].forEach((closure) => {
261
+ const nodeDataClassWrong = new IntervalNode(nodeDataClass.a, nodeDataClass.b, closure);
262
+ const identifiersWrong = {
263
+ ...identifiers,
264
+ nodeIdsDataClass: nodeDataClassWrong.toIdentifiers(),
265
+ };
266
+ const texWrong = getAnswer(identifiersWrong);
267
+ tryToAddWrongProp(propositions, texWrong);
268
+ arrTerror.push(texWrong);
269
+ });
270
+ }
271
+ //filler
272
+ {
273
+ propWhile(propositions, n, () => {
274
+ const vTerrorTarget = parseInt(random(arrTerror));
275
+ const vTerrorAround = vTerrorTarget + randint(-5, 5);
276
+ if (vTerrorAround >= 0) {
277
+ tryToAddWrongProp(propositions, vTerrorAround.frenchify());
278
+ }
279
+ });
280
+ }
281
+ return shuffleProps(propositions, n);
282
+ };
283
+ const getKeys = () => {
284
+ return [];
285
+ };
286
+ const isAnswerValid = (ans, { answer }) => {
287
+ return numberVEA(ans, answer);
288
+ };
289
+ const getScatterPlotInterpretingQuestion = () => {
290
+ const length = 6;
291
+ const height = 6;
292
+ const arrArrDict1 = getCartesiansProducts([
293
+ [...Array(length).keys()].map((i) => i + 1),
294
+ [...Array(height).keys()].map((i) => i + 1),
295
+ ]).map(([x, y]) => {
296
+ return {
297
+ x,
298
+ y,
299
+ isActivated: probaFlip(0.14),
300
+ };
301
+ });
302
+ const arrArrDict2 = getCartesiansProducts([
303
+ [...Array(length - 1).keys()].map((i) => i + 1),
304
+ [...Array(height - 1).keys()].map((i) => i + 1),
305
+ ]).map(([x, y]) => {
306
+ return {
307
+ x: x + 0.333,
308
+ y: y + 0.333,
309
+ isActivated: probaFlip(0.14),
310
+ };
311
+ });
312
+ const arrArrDict3 = getCartesiansProducts([
313
+ [...Array(length - 1).keys()].map((i) => i + 1),
314
+ [...Array(height - 1).keys()].map((i) => i + 1),
315
+ ]).map(([x, y]) => {
316
+ return {
317
+ x: x + 0.666,
318
+ y: y + 0.666,
319
+ isActivated: probaFlip(0.14),
320
+ };
321
+ });
322
+ //at least one point should be activated
323
+ {
324
+ const dictRandom = random(arrArrDict1);
325
+ dictRandom.isActivated = true;
326
+ }
327
+ const arrPoint = [...arrArrDict1, ...arrArrDict2, ...arrArrDict3]
328
+ .filter(({ isActivated }) => isActivated)
329
+ .map(({ x, y }, i) => new Point(`P${i}`, x, y));
330
+ const strGroupBy = coinFlip() ? "x" : "y";
331
+ const nodeDataClass = (() => {
332
+ if (coinFlip()) {
333
+ const nodeV = randint(1, 1 + length).toTree();
334
+ return new IntervalNode(nodeV, nodeV, ClosureType.FF);
335
+ }
336
+ else {
337
+ const templateArrLengthDataClass = probaLawFlip([
338
+ [[1, 1, 1, 2], 0.2],
339
+ [[1, 2, 2], 0.4],
340
+ [[1, 1, 3], 0.3],
341
+ [[2, 3], 0.1],
342
+ ]);
343
+ const arrLengthDataClass = shuffle(templateArrLengthDataClass);
344
+ const arrDataClass = arrLengthDataClass.reduce((acc, lengthDataClass) => {
345
+ const nodeBoundLow = acc.nodeBoundLowWork;
346
+ const nodeBoundHigh = add(nodeBoundLow, lengthDataClass).simplify({
347
+ towardsDistribute: true,
348
+ });
349
+ const closure = random([
350
+ ClosureType.FF,
351
+ ClosureType.FO,
352
+ ClosureType.OF,
353
+ ]);
354
+ const nodeDataClass = new IntervalNode(nodeBoundLow, nodeBoundHigh, closure);
355
+ acc.dataClasses.push(nodeDataClass);
356
+ acc.nodeBoundLowWork = nodeBoundHigh;
357
+ return acc;
358
+ }, {
359
+ nodeBoundLowWork: (1).toTree(),
360
+ dataClasses: [],
361
+ }).dataClasses;
362
+ return random(arrDataClass);
363
+ }
364
+ })();
365
+ const identifiers = {
366
+ pointIds: arrPoint.map((point) => point.toIdentifiers()),
367
+ strGroupBy,
368
+ nodeIdsDataClass: nodeDataClass.toIdentifiers(),
369
+ };
370
+ return getQuestionFromIdentifiers(identifiers);
371
+ };
372
+ const getQuestionFromIdentifiers = (identifiers) => {
373
+ return {
374
+ instruction: getInstruction(identifiers),
375
+ answer: getAnswer(identifiers),
376
+ answerFormat: "tex",
377
+ keys: getKeys(identifiers),
378
+ identifiers,
379
+ hint: getHint(identifiers),
380
+ correction: getCorrection(identifiers),
381
+ correctionGgbOptions: getCorrectionGGBOptions(identifiers),
382
+ ggbOptions: getGGBOptions(identifiers),
383
+ };
384
+ };
385
+ export const scatterPlotInterpreting = {
386
+ id: "scatterPlotInterpreting",
387
+ label: "Interpréter un nuage de points",
388
+ isSingleStep: true,
389
+ generator: (nb, opts) => getDistinctQuestions(() => getScatterPlotInterpretingQuestion(opts), nb),
390
+ qcmTimer: 60,
391
+ freeTimer: 60,
392
+ subject: "Mathématiques",
393
+ getAnswer,
394
+ isAnswerValid,
395
+ getPropositions,
396
+ getInstruction,
397
+ getGGBOptions,
398
+ hasGeogebra: true,
399
+ getQuestionFromIdentifiers,
400
+ getHint,
401
+ getCorrection,
402
+ hasHintAndCorrection: true,
403
+ };
@@ -254,7 +254,7 @@ const getPropositions = (n, { answer, ...identifiers }) => {
254
254
  ]);
255
255
  };
256
256
  const getKeys = () => {
257
- return [];
257
+ return ["x", "y", "equal"];
258
258
  };
259
259
  const isAnswerValid = (ans, { answer }) => {
260
260
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"signVarTableFromFunctionExpression.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/derivation/variations/signVarTableFromFunctionExpression.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;AAarC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAgM7C,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAkXF,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAyCF,eAAO,MAAM,kCAAkC,EAAE,QAAQ,CACvD,WAAW,EACX,OAAO,CAuBR,CAAC"}
1
+ {"version":3,"file":"signVarTableFromFunctionExpression.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/derivation/variations/signVarTableFromFunctionExpression.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;AAarC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAgM7C,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAqXF,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAyCF,eAAO,MAAM,kCAAkC,EAAE,QAAQ,CACvD,WAAW,EACX,OAAO,CAuBR,CAAC"}
@@ -266,7 +266,10 @@ const getAnswerTable = (identifiers) => {
266
266
  [
267
267
  "$f'(x)$",
268
268
  "\\ ",
269
- ...arrSignOutsideRoots.flatMap((sign) => [sign > 0 ? "+" : "-", "\\ "]),
269
+ ...arrSignOutsideRoots.flatMap((sign, i, arr) => [
270
+ sign > 0 ? "+" : "-",
271
+ i === arr.length - 1 ? "\\ " : "0",
272
+ ]),
270
273
  ],
271
274
  [
272
275
  "$\\ $",
@@ -0,0 +1,13 @@
1
+ import { Exercise } from "../../../../exercises/exercise.js";
2
+ import { NodeIdentifiers } from "../../../../tree/nodes/nodeConstructor.js";
3
+ type Identifiers = {
4
+ nodeIdsAbscissa: NodeIdentifiers[];
5
+ nodeIdsSlope: NodeIdentifiers;
6
+ typeAbscissa: string;
7
+ };
8
+ type Options = {
9
+ typeAbscissa: string;
10
+ };
11
+ export declare const affineCompareTwoImagesFromVariations: Exercise<Identifiers, Options>;
12
+ export {};
13
+ //# sourceMappingURL=affineCompareTwoImagesFromVariations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"affineCompareTwoImagesFromVariations.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/affines/affineCompareTwoImagesFromVariations.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAKrC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAiB7C,KAAK,WAAW,GAAG;IACjB,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,YAAY,EAAE,eAAe,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAwNF,KAAK,OAAO,GAAG;IACb,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAiBF,eAAO,MAAM,oCAAoC,EAAE,QAAQ,CACzD,WAAW,EACX,OAAO,CAoBR,CAAC"}
@@ -0,0 +1,205 @@
1
+ import { GeneratorOptionTarget, GeneratorOptionType, addValidProp, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
3
+ import { randfloat } from "../../../../math/utils/random/randfloat.js";
4
+ import { randint } from "../../../../math/utils/random/randint.js";
5
+ import { NodeConstructor, } from "../../../../tree/nodes/nodeConstructor.js";
6
+ import { substract } from "../../../../tree/nodes/operators/substractNode.js";
7
+ import { VariableNode } from "../../../../tree/nodes/variables/variableNode.js";
8
+ import { probaLawFlip } from "../../../../utils/alea/probaLawFlip.js";
9
+ import { zip } from "../../../../utils/arrays/arrayZip.js";
10
+ const strTypeFFromNodeSlope = (nodeSlope) => {
11
+ const valueSlope = nodeSlope.evaluate();
12
+ if (valueSlope === 0) {
13
+ return "Constante";
14
+ }
15
+ else if (valueSlope > 0) {
16
+ return "Strictement croissante";
17
+ }
18
+ else {
19
+ return "Strictement décroissante";
20
+ }
21
+ };
22
+ const getInstruction = (identifiers) => {
23
+ const { nodeIdsAbscissa, nodeIdsSlope, typeAbscissa } = identifiers;
24
+ const [nodeX1, nodeX2] = nodeIdsAbscissa.map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
25
+ const [nodeX1Display, nodeX2Display] = typeAbscissa === "Nombres"
26
+ ? [nodeX1, nodeX2]
27
+ : ["a", "b"].map((varName) => new VariableNode(varName));
28
+ const nodeSlope = NodeConstructor.fromIdentifiers(nodeIdsSlope);
29
+ const strVariationsF = strTypeFFromNodeSlope(nodeSlope);
30
+ return `Soit $f$ une fonction affine ${strVariationsF.toLocaleLowerCase()}.
31
+
32
+ ${(() => {
33
+ switch (typeAbscissa) {
34
+ case "Lettres": {
35
+ const [nodeXDisplaySmall, nodeXDisplayBig] = zip([nodeX1Display, nodeX2Display], [nodeX1, nodeX2])
36
+ .toSorted(([, node1], [_, node2]) => substract(node1, node2).evaluate())
37
+ .map(([nodeXDisplay]) => nodeXDisplay);
38
+ return `Soient deux nombres $${nodeX1Display.toTex()}$ et $${nodeX2Display.toTex()}$ tels que :
39
+
40
+ $$
41
+ ${nodeXDisplaySmall.toTex()} < ${nodeXDisplayBig.toTex()}
42
+ $$
43
+
44
+ `;
45
+ }
46
+ default:
47
+ return "";
48
+ }
49
+ })()}
50
+
51
+ Comparer $f(${nodeX1Display.toTex()})$ et $f(${nodeX2Display.toTex()})$.`;
52
+ };
53
+ const getAnswer = (identifiers) => {
54
+ const { nodeIdsAbscissa, nodeIdsSlope, typeAbscissa } = identifiers;
55
+ const [nodeX1, nodeX2] = nodeIdsAbscissa.map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
56
+ const [nodeX1Display, nodeX2Display] = typeAbscissa === "Nombres"
57
+ ? [nodeX1, nodeX2]
58
+ : ["a", "b"].map((varName) => new VariableNode(varName));
59
+ const nodeSlope = NodeConstructor.fromIdentifiers(nodeIdsSlope);
60
+ const strVariationsF = strTypeFFromNodeSlope(nodeSlope);
61
+ const [nodeXDisplaySmall, nodeXDisplayBig] = zip([nodeX1Display, nodeX2Display], [nodeX1, nodeX2])
62
+ .toSorted(([, node1], [_, node2]) => substract(node1, node2).evaluate())
63
+ .map(([nodeXDisplay]) => nodeXDisplay);
64
+ switch (strVariationsF) {
65
+ case "Constante":
66
+ return `f(${nodeXDisplaySmall.toTex()}) = f(${nodeXDisplayBig.toTex()})`;
67
+ case "Strictement croissante":
68
+ return `f(${nodeXDisplaySmall.toTex()}) < f(${nodeXDisplayBig.toTex()})`;
69
+ case "Strictement décroissante":
70
+ return `f(${nodeXDisplaySmall.toTex()}) > f(${nodeXDisplayBig.toTex()})`;
71
+ default:
72
+ throw new Error("Unsupported strVariationsF: " + strVariationsF);
73
+ }
74
+ };
75
+ const getHint = () => {
76
+ return `Soit $f$ une fonction affine et $x_{1}$ et $x_{2}$ deux réels distincts tels que :
77
+
78
+ $$
79
+ x_{1}<x_{2}
80
+ $$
81
+
82
+ Si la fonction $f$ est strictement croissante alors :
83
+
84
+ $$
85
+ f(x_{1})<f(x_{2})
86
+ $$
87
+
88
+ Si la fonction $f$ est strictement décroissante alors :
89
+
90
+ $$
91
+ f(x_{1})>f(x_{2})
92
+ $$
93
+
94
+ Si la fonction $f$ est constante alors :
95
+
96
+ $$
97
+ f(x_{1})=f(x_{2})
98
+ $$
99
+
100
+ `;
101
+ };
102
+ const getCorrection = (identifiers) => {
103
+ const { nodeIdsAbscissa, nodeIdsSlope, typeAbscissa } = identifiers;
104
+ const [nodeX1, nodeX2] = nodeIdsAbscissa.map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
105
+ const [nodeX1Display, nodeX2Display] = typeAbscissa === "Nombres"
106
+ ? [nodeX1, nodeX2]
107
+ : ["a", "b"].map((varName) => new VariableNode(varName));
108
+ const nodeSlope = NodeConstructor.fromIdentifiers(nodeIdsSlope);
109
+ const strVariationsF = strTypeFFromNodeSlope(nodeSlope);
110
+ const [nodeXDisplaySmall, nodeXDisplayBig] = zip([nodeX1Display, nodeX2Display], [nodeX1, nodeX2])
111
+ .toSorted(([, node1], [_, node2]) => substract(node1, node2).evaluate())
112
+ .map(([nodeXDisplay]) => nodeXDisplay);
113
+ return `$f$ est une fonction affine ${strVariationsF.toLocaleLowerCase()}.
114
+
115
+ On a :
116
+
117
+ $$
118
+ ${nodeXDisplaySmall.toTex()} < ${nodeXDisplayBig.toTex()}
119
+ $$
120
+
121
+ Par conséquent :
122
+
123
+ $$
124
+ ${getAnswer(identifiers)}
125
+ $$
126
+
127
+ `;
128
+ };
129
+ const getPropositions = (_n, { answer, ...identifiers }) => {
130
+ const { nodeIdsAbscissa, typeAbscissa } = identifiers;
131
+ const [nodeX1, nodeX2] = nodeIdsAbscissa.map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
132
+ const [nodeX1Display, nodeX2Display] = typeAbscissa === "Nombres"
133
+ ? [nodeX1, nodeX2]
134
+ : ["a", "b"].map((varName) => new VariableNode(varName));
135
+ const [nodeXDisplaySmall, nodeXDisplayBig] = zip([nodeX1Display, nodeX2Display], [nodeX1, nodeX2])
136
+ .toSorted(([, node1], [_, node2]) => substract(node1, node2).evaluate())
137
+ .map(([nodeXDisplay]) => nodeXDisplay);
138
+ const propositions = [];
139
+ ["<", ">", "="].map((strSymbol) => {
140
+ const tex = `f(${nodeXDisplaySmall.toTex()}) ${strSymbol} f(${nodeXDisplayBig.toTex()})`;
141
+ if (tex === answer) {
142
+ addValidProp(propositions, answer);
143
+ }
144
+ else {
145
+ tryToAddWrongProp(propositions, tex);
146
+ }
147
+ });
148
+ return propositions;
149
+ };
150
+ const getAffineCompareTwoImagesFromVariationsQuestion = (optsIn) => {
151
+ const opts = optsIn ?? optsDefault;
152
+ const { typeAbscissa } = opts;
153
+ const xA = randint(-9, 10);
154
+ const xB = randint(-9, 10, [xA]);
155
+ const slope = probaLawFlip([
156
+ [randfloat(0, 3, 2, [0]), 0.45],
157
+ [randfloat(-3, 0, 2, [0]), 0.45],
158
+ [0, 0.1],
159
+ ]);
160
+ const identifiers = {
161
+ nodeIdsAbscissa: [xA, xB].map((v) => v.toTree().toIdentifiers()),
162
+ nodeIdsSlope: slope.toTree().toIdentifiers(),
163
+ typeAbscissa,
164
+ };
165
+ return getQuestionFromIdentifiers(identifiers, opts);
166
+ };
167
+ const getQuestionFromIdentifiers = (identifiers) => {
168
+ const question = {
169
+ instruction: getInstruction(identifiers),
170
+ answer: getAnswer(identifiers),
171
+ hint: getHint(identifiers),
172
+ correction: getCorrection(identifiers),
173
+ answerFormat: "tex",
174
+ identifiers,
175
+ };
176
+ return question;
177
+ };
178
+ const optsDefault = {
179
+ typeAbscissa: "Nombres",
180
+ };
181
+ const options = [
182
+ {
183
+ id: "typeAbscissa",
184
+ label: "Type d'abscisses :",
185
+ target: GeneratorOptionTarget.generation,
186
+ type: GeneratorOptionType.select,
187
+ values: ["Nombres", "Lettres"],
188
+ defaultValue: optsDefault.typeAbscissa,
189
+ },
190
+ ];
191
+ export const affineCompareTwoImagesFromVariations = {
192
+ id: "affineCompareTwoImagesFromVariations",
193
+ connector: "=",
194
+ label: "Comparer deux images d'une fonction affine dont on connaît le sens de variation",
195
+ isSingleStep: true,
196
+ generator: (nb, opts) => getDistinctQuestions(() => getAffineCompareTwoImagesFromVariationsQuestion(opts), nb),
197
+ options,
198
+ qcmTimer: 60,
199
+ freeTimer: 60,
200
+ getPropositions,
201
+ subject: "Mathématiques",
202
+ hasHintAndCorrection: true,
203
+ getQuestionFromIdentifiers,
204
+ answerType: "QCU",
205
+ };
@@ -0,0 +1,9 @@
1
+ import { Exercise } from "../../../../exercises/exercise.js";
2
+ import { NodeIdentifiers } from "../../../../tree/nodes/nodeConstructor.js";
3
+ type Identifiers = {
4
+ nodeIdsBounds: NodeIdentifiers[];
5
+ nodeIdsF: NodeIdentifiers;
6
+ };
7
+ export declare const affineVarTableOnBoundedInterval: Exercise<Identifiers>;
8
+ export {};
9
+ //# sourceMappingURL=affineVarTableOnBoundedInterval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"affineVarTableOnBoundedInterval.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/affines/affineVarTableOnBoundedInterval.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAST,MAAM,6BAA6B,CAAC;AAMrC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAK7C,KAAK,WAAW,GAAG;IACjB,aAAa,EAAE,eAAe,EAAE,CAAC;IACjC,QAAQ,EAAE,eAAe,CAAC;CAC3B,CAAC;AA8KF,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CAAC,WAAW,CAqBjE,CAAC"}