math-exercises 2.0.17 → 2.0.19
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.
- package/lib/exercises/calculLitteral/equation/firstDegreeEquation.js +1 -1
- package/lib/exercises/functions/affines/index.d.ts +1 -0
- package/lib/exercises/functions/affines/index.d.ts.map +1 -1
- package/lib/exercises/functions/affines/index.js +1 -0
- package/lib/exercises/functions/affines/interceptReading.d.ts +8 -0
- package/lib/exercises/functions/affines/interceptReading.d.ts.map +1 -0
- package/lib/exercises/functions/affines/interceptReading.js +58 -0
- package/lib/exercises/limits/limitReading.js +1 -1
- package/lib/exercises/percent/applyPercent.js +1 -1
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/server.js +7 -12
- package/lib/tree/parsers/latexParser.d.ts +3 -0
- package/lib/tree/parsers/latexParser.d.ts.map +1 -0
- package/lib/tree/parsers/latexParser.js +180 -0
- package/package.json +1 -1
|
@@ -48,7 +48,7 @@ exports.firstDegreeEquation = {
|
|
|
48
48
|
connector: "=",
|
|
49
49
|
label: "Résoudre une équation du premier degré du type $\\frac{a}{x} = b$",
|
|
50
50
|
levels: ["2nde", "1reESM", "1reSpé"],
|
|
51
|
-
sections: ["Équations"],
|
|
51
|
+
sections: ["Équations", "Fonction inverse", "Fonctions de référence"],
|
|
52
52
|
isSingleStep: false,
|
|
53
53
|
generator: (nb) => (0, getDistinctQuestions_1.getDistinctQuestions)(getFirstDegreeEquation, nb),
|
|
54
54
|
getPropositions,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/exercises/functions/affines/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/exercises/functions/affines/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC"}
|
|
@@ -19,3 +19,4 @@ __exportStar(require("./leadingCoefficientCalculV1"), exports);
|
|
|
19
19
|
__exportStar(require("./leadingCoefficientCalculV2"), exports);
|
|
20
20
|
__exportStar(require("./signFunction"), exports);
|
|
21
21
|
__exportStar(require("./affineExpressionReading"), exports);
|
|
22
|
+
__exportStar(require("./interceptReading"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interceptReading.d.ts","sourceRoot":"","sources":["../../../../src/exercises/functions/affines/interceptReading.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EASb,MAAM,0BAA0B,CAAC;AAalC,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AA+CF,eAAO,MAAM,gBAAgB,EAAE,YAAY,CAAC,WAAW,CAatD,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.interceptReading = void 0;
|
|
4
|
+
const exercise_1 = require("../../../exercises/exercise");
|
|
5
|
+
const getDistinctQuestions_1 = require("../../../exercises/utils/getDistinctQuestions");
|
|
6
|
+
const randint_1 = require("../../../math/utils/random/randint");
|
|
7
|
+
const getInterceptReadingQuestion = () => {
|
|
8
|
+
const b = (0, randint_1.randint)(-5, 6);
|
|
9
|
+
const secondPoint = [(0, randint_1.randint)(-5, 6, [0]), (0, randint_1.randint)(-5, 6)];
|
|
10
|
+
const answer = b + "";
|
|
11
|
+
let xMin = Math.min(0, secondPoint[0]);
|
|
12
|
+
if (xMin > 0)
|
|
13
|
+
xMin = -0.5;
|
|
14
|
+
let xMax = Math.max(0, secondPoint[0]);
|
|
15
|
+
if (xMax < 0)
|
|
16
|
+
xMax = 0.5;
|
|
17
|
+
let yMin = Math.min(b, secondPoint[1]);
|
|
18
|
+
if (yMin > 0)
|
|
19
|
+
yMin = -0.5;
|
|
20
|
+
let yMax = Math.max(b, secondPoint[1]);
|
|
21
|
+
if (yMax < 0)
|
|
22
|
+
yMax = 0.5;
|
|
23
|
+
const coords = [xMin - 1, xMax + 1, yMin - 1, yMax + 1];
|
|
24
|
+
const question = {
|
|
25
|
+
answer,
|
|
26
|
+
instruction: `Ci-dessous est tracée la courbe représentative d'une fonction affine $f$. Déterminer graphiquement l'ordonnée à l'origine $b$ de la fonction $f$.`,
|
|
27
|
+
keys: [],
|
|
28
|
+
commands: [`Line((0, ${b}), (${secondPoint[0]}, ${secondPoint[1]}))`],
|
|
29
|
+
coords,
|
|
30
|
+
answerFormat: "tex",
|
|
31
|
+
identifiers: { b, secondPoint },
|
|
32
|
+
};
|
|
33
|
+
return question;
|
|
34
|
+
};
|
|
35
|
+
const getPropositions = (n, { answer, b, secondPoint }) => {
|
|
36
|
+
const propositions = [];
|
|
37
|
+
(0, exercise_1.addValidProp)(propositions, answer);
|
|
38
|
+
while (propositions.length < n) {
|
|
39
|
+
(0, exercise_1.tryToAddWrongProp)(propositions, (0, randint_1.randint)(-5, 6) + "");
|
|
40
|
+
}
|
|
41
|
+
return (0, exercise_1.shuffleProps)(propositions, n);
|
|
42
|
+
};
|
|
43
|
+
const isAnswerValid = (ans, { answer, secondPoint, b }) => {
|
|
44
|
+
return ans === answer;
|
|
45
|
+
};
|
|
46
|
+
exports.interceptReading = {
|
|
47
|
+
id: "interceptReading",
|
|
48
|
+
connector: "=",
|
|
49
|
+
label: "Lire graphiquement l'ordonnée à l'origine",
|
|
50
|
+
levels: ["2nde", "1reESM", "1rePro", "1reSpé", "1reTech"],
|
|
51
|
+
isSingleStep: true,
|
|
52
|
+
sections: ["Droites", "Fonctions affines"],
|
|
53
|
+
generator: (nb) => (0, getDistinctQuestions_1.getDistinctQuestions)(getInterceptReadingQuestion, nb),
|
|
54
|
+
qcmTimer: 60,
|
|
55
|
+
freeTimer: 60,
|
|
56
|
+
getPropositions,
|
|
57
|
+
isAnswerValid,
|
|
58
|
+
};
|
|
@@ -72,7 +72,7 @@ const getLimitReadingQuestion = () => {
|
|
|
72
72
|
const question = {
|
|
73
73
|
answer,
|
|
74
74
|
instruction: `Ci-dessous est tracée la courbe représentative d'une fonction $f$. Déterminer la limite: $\\displaystyle ${new limitNode_1.LimitNode(to, new variableNode_1.VariableNode("f(x)"), from).toTex()}$`,
|
|
75
|
-
keys: [],
|
|
75
|
+
keys: ["infty"],
|
|
76
76
|
commands: [fct],
|
|
77
77
|
coords: [-10, 10, -10, 10],
|
|
78
78
|
answerFormat: "tex",
|
|
@@ -56,7 +56,7 @@ const isAnswerValid = (ans, { answer }) => {
|
|
|
56
56
|
exports.applyPercent = {
|
|
57
57
|
id: "applyPercent",
|
|
58
58
|
connector: "=",
|
|
59
|
-
label: "Appliquer un pourcentage d'augmentation ou de diminution
|
|
59
|
+
label: "Appliquer un pourcentage d'augmentation ou de diminution",
|
|
60
60
|
levels: [
|
|
61
61
|
"4ème",
|
|
62
62
|
"3ème",
|
package/lib/index.d.ts
CHANGED
|
@@ -330,6 +330,9 @@ declare const mathExercises: (import("./exercises/exercise").MathExercise<{
|
|
|
330
330
|
}> | import("./exercises/exercise").MathExercise<{
|
|
331
331
|
b: number;
|
|
332
332
|
secondPoint: number[];
|
|
333
|
+
}> | import("./exercises/exercise").MathExercise<{
|
|
334
|
+
b: number;
|
|
335
|
+
secondPoint: number[];
|
|
333
336
|
}> | import("./exercises/exercise").MathExercise<{
|
|
334
337
|
rand: boolean;
|
|
335
338
|
poly1: number[];
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqCA,QAAA,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqCA,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAA2B,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/lib/server.js
CHANGED
|
@@ -35,24 +35,19 @@ const express_1 = __importDefault(require("express"));
|
|
|
35
35
|
const body_parser_1 = __importDefault(require("body-parser"));
|
|
36
36
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
37
37
|
const cors_1 = __importDefault(require("cors"));
|
|
38
|
-
const addNode_1 = require("./tree/nodes/operators/addNode");
|
|
39
|
-
const numberNode_1 = require("./tree/nodes/numbers/numberNode");
|
|
40
|
-
const powerNode_1 = require("./tree/nodes/operators/powerNode");
|
|
41
|
-
const sqrtNode_1 = require("./tree/nodes/functions/sqrtNode");
|
|
42
|
-
const multiplyNode_1 = require("./tree/nodes/operators/multiplyNode");
|
|
43
38
|
const jsonParser = body_parser_1.default.json();
|
|
44
39
|
const allExercises = [...exercises];
|
|
45
40
|
const runServer = () => {
|
|
46
41
|
dotenv_1.default.config();
|
|
47
42
|
const app = (0, express_1.default)();
|
|
48
43
|
app.use((0, cors_1.default)());
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
// const latex = "\\sqrt{3,230982}";
|
|
45
|
+
// try {
|
|
46
|
+
// const res = parseLatex(latex);
|
|
47
|
+
// console.log(res.toTex());
|
|
48
|
+
// } catch (err) {
|
|
49
|
+
// throw err;
|
|
50
|
+
// }
|
|
56
51
|
app.get("/", (req, res) => {
|
|
57
52
|
res.json(allExercises);
|
|
58
53
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"latexParser.d.ts","sourceRoot":"","sources":["../../../src/tree/parsers/latexParser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AA2BvD,eAAO,MAAM,UAAU,UAAW,MAAM,kBAgBvC,CAAC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseLatex = void 0;
|
|
4
|
+
const isLetter_1 = require("../../utils/isLetter");
|
|
5
|
+
const sqrtNode_1 = require("../nodes/functions/sqrtNode");
|
|
6
|
+
const numberNode_1 = require("../nodes/numbers/numberNode");
|
|
7
|
+
const isDyck = (latex) => {
|
|
8
|
+
const brackets = latex.split("").filter((el) => el === "(" || el === ")");
|
|
9
|
+
while (brackets.length) {
|
|
10
|
+
const rightIndex = brackets.findIndex((el) => el == ")");
|
|
11
|
+
if (rightIndex === -1 || rightIndex === 0)
|
|
12
|
+
return false;
|
|
13
|
+
let leftIndex = -1;
|
|
14
|
+
for (let i = rightIndex - 1; i > -1; i--) {
|
|
15
|
+
if (brackets[i] === "(") {
|
|
16
|
+
leftIndex = i;
|
|
17
|
+
}
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
if (leftIndex === -1)
|
|
21
|
+
return false;
|
|
22
|
+
brackets.splice(rightIndex, 1);
|
|
23
|
+
brackets.splice(leftIndex, 1);
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
};
|
|
27
|
+
const parseLatex = (latex) => {
|
|
28
|
+
const formattedLatex = latex
|
|
29
|
+
.replaceAll("\\left", "")
|
|
30
|
+
.replaceAll("\\right", "");
|
|
31
|
+
const isWellBracketed = isDyck(latex);
|
|
32
|
+
if (!isWellBracketed)
|
|
33
|
+
throw Error("Problème de parenthèses.");
|
|
34
|
+
let currentTree;
|
|
35
|
+
let currentItem;
|
|
36
|
+
const length = formattedLatex.length;
|
|
37
|
+
try {
|
|
38
|
+
const parsed = parseString(latex);
|
|
39
|
+
return parsed.node;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
exports.parseLatex = parseLatex;
|
|
46
|
+
const parseString = (latex) => {
|
|
47
|
+
let currentTree;
|
|
48
|
+
let currentItem;
|
|
49
|
+
let currentAddCandidate;
|
|
50
|
+
const length = latex.length;
|
|
51
|
+
let jump = 0;
|
|
52
|
+
try {
|
|
53
|
+
for (let i = 0; i < length; i++) {
|
|
54
|
+
const char = latex[i];
|
|
55
|
+
const parsed = parseItem(latex);
|
|
56
|
+
currentItem = parsed.node;
|
|
57
|
+
currentTree = parsed.node;
|
|
58
|
+
jump = parsed.jump;
|
|
59
|
+
i += parsed.jump;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
node: currentTree,
|
|
63
|
+
jump,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const parseItem = (latex) => {
|
|
71
|
+
const length = latex.length;
|
|
72
|
+
const char = latex[0];
|
|
73
|
+
if (charIsNumber(char)) {
|
|
74
|
+
return parseNumber(latex);
|
|
75
|
+
}
|
|
76
|
+
else if (char === "\\") {
|
|
77
|
+
const cmdData = parseCommand(latex);
|
|
78
|
+
switch (cmdData.cmd) {
|
|
79
|
+
case "sqrt":
|
|
80
|
+
const childLatex = getChildLatex(latex.substring(cmdData.jump));
|
|
81
|
+
const parsedChild = parseString(childLatex);
|
|
82
|
+
return {
|
|
83
|
+
node: new sqrtNode_1.SqrtNode(parsedChild.node),
|
|
84
|
+
jump: parsedChild.jump,
|
|
85
|
+
};
|
|
86
|
+
default:
|
|
87
|
+
throw Error(`Commande ${cmdData.cmd} non gérée`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else if (char === "+") {
|
|
91
|
+
}
|
|
92
|
+
throw Error(`Symbole ${char} non géré`);
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
*
|
|
96
|
+
* @param latex latex[0] must be {
|
|
97
|
+
*
|
|
98
|
+
*
|
|
99
|
+
* cette fonction extrait le latex d'un child,
|
|
100
|
+
* par ex elle renverra "x" dans \\sqrt{x}
|
|
101
|
+
*/
|
|
102
|
+
const getChildLatex = (latex) => {
|
|
103
|
+
const childStartIndex = 1;
|
|
104
|
+
let leftBracesCount = 0;
|
|
105
|
+
let childEndIndex = -1;
|
|
106
|
+
for (let i = childStartIndex; i < latex.length; i++) {
|
|
107
|
+
if (latex[i] === "{")
|
|
108
|
+
leftBracesCount++;
|
|
109
|
+
if (latex[i] === "}") {
|
|
110
|
+
if (leftBracesCount === 0) {
|
|
111
|
+
return latex.substring(1, i);
|
|
112
|
+
}
|
|
113
|
+
else
|
|
114
|
+
leftBracesCount--;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
throw Error(`Erreur en récupérant un child dans ${latex}`);
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
*
|
|
121
|
+
* @param latex latex[0] must be \
|
|
122
|
+
*/
|
|
123
|
+
const parseCommand = (latex) => {
|
|
124
|
+
let nextChar = latex[1];
|
|
125
|
+
const length = latex.length;
|
|
126
|
+
if (!nextChar)
|
|
127
|
+
throw Error("Antislash mais pas de nom de commande");
|
|
128
|
+
let j = 1;
|
|
129
|
+
let cmd = "";
|
|
130
|
+
while (j < length && (0, isLetter_1.isLetter)(nextChar)) {
|
|
131
|
+
cmd += nextChar;
|
|
132
|
+
j++;
|
|
133
|
+
nextChar = latex[j];
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
cmd,
|
|
137
|
+
jump: 1 + cmd.length,
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
*
|
|
142
|
+
* @param latex latex[0] must be a number
|
|
143
|
+
* @returns
|
|
144
|
+
*/
|
|
145
|
+
const parseNumber = (latex) => {
|
|
146
|
+
const char = latex[0];
|
|
147
|
+
const length = latex.length;
|
|
148
|
+
let numberString = char;
|
|
149
|
+
let j = 1;
|
|
150
|
+
let nextChar = latex[j];
|
|
151
|
+
while (j < length && (charIsNumber(nextChar) || nextChar === ",")) {
|
|
152
|
+
numberString += nextChar;
|
|
153
|
+
j++;
|
|
154
|
+
nextChar = latex[j];
|
|
155
|
+
}
|
|
156
|
+
if (numberString[numberString.length - 1] === ",")
|
|
157
|
+
throw Error(`Nombre ${numberString} avec virgule mais sans partie décimale`);
|
|
158
|
+
if (numberString.split(",").length > 2)
|
|
159
|
+
throw Error(`Trop de virgules dans le nombre ${numberString}`);
|
|
160
|
+
const number = Number(numberString.replace(",", "."));
|
|
161
|
+
return {
|
|
162
|
+
node: new numberNode_1.NumberNode(number),
|
|
163
|
+
jump: numberString.length,
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
/***
|
|
167
|
+
* Nombres
|
|
168
|
+
* Constantes
|
|
169
|
+
* Opérations :
|
|
170
|
+
* - +
|
|
171
|
+
* - -
|
|
172
|
+
* - *
|
|
173
|
+
* - /
|
|
174
|
+
* Fonctions :
|
|
175
|
+
* - exp
|
|
176
|
+
* - ln
|
|
177
|
+
*/
|
|
178
|
+
const charIsNumber = (s) => {
|
|
179
|
+
return ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(s);
|
|
180
|
+
};
|