- JavaScript 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
samathgen 0.1.3 offers the answer with one option 2 or 3 above it, one 2 or 3 below it and a fourth near it, so the answer is never the smallest or the largest of the four. Over 20 000 tasks from /gen it was the second smallest 49.9% of the time, the third 50.1% and nothing else: a pupil can rule out two options at a glance, and one who always picks the second smallest is right half the time. The server now draws the options itself, four of six numbers in a row with the answer's rank among them drawn first. Over the same 20 000 tasks the answer is the smallest, second, third and largest 24.9%, 25.0%, 25.1% and 24.9% of the time, and the test checks that this holds for each of the ten shapes four options can take, not only overall. The generator is still asked for its own options, which are thrown away, because the tasks a seed gives depend on every number it draws: 3000 seeded requests give the same tasks as before, with new options. The README examples are what the server gives now. |
||
| .forgejo/workflows | ||
| .github/workflows | ||
| test | ||
| .gitignore | ||
| .sample.env | ||
| app.js | ||
| evaluate.js | ||
| index.js | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
SaMath API
A bridge between SaMathGen and SaMathCLI
Usage
npm install
cp .sample.env .env # optional
npm start
npm test runs the endpoint tests with Node's built-in runner; there is
nothing extra to install.
Endpoints
| Endpoint | Returns |
|---|---|
GET / |
Hello World |
GET /healthz |
{"ok":true} |
GET /gen |
the full task as JSON |
GET /gen?c=true |
plain text <task> <opt1>,<opt2>,<opt3>,<opt4> <answer>, the shape SaMathCLI parses |
Only the exact string true turns c on; anything else, false included,
returns JSON.
The task as JSON
curl 'http://localhost:3000/gen?brackets=true&seed=5'
# {"task":[3,"*",9,"*",2,"/","(4-1)"],"answer":18,"quizOptions":[21,17,20,18]}
| Field | Meaning |
|---|---|
task |
The task in pieces, numbers as numbers and the rest as strings. task.join('') is the text to show, 3*9*2/(4-1). |
answer |
What the task works out to, a whole number. |
quizOptions |
Four whole numbers to choose from, one of them answer, in no particular order. They are four of six numbers in a row, and answer is as likely to be the smallest of them as the largest or either between, so a pupil cannot pick it by its size. |
Read the task by joining it rather than piece by piece: samathgen 0.1.3, which
is what npm serves, sends a bracketed group as a single string such as
"(4-1)", where later versions send "(" and ")" on their own. A number
can be negative, as -10 in -10+1*5*4.
/gen also takes:
| Parameter | Values | Default |
|---|---|---|
length |
how many numbers the task has, 2 to 12 |
a random length between lengthFrom and lengthTo |
brackets |
true or false |
the brackets setting |
count |
how many tasks, 1 to 100 |
one task |
seed |
a whole number from 0 to 4294967295 |
none: every request is different |
curl 'http://localhost:3000/gen?length=6&brackets=true'
A value outside those is answered with 400 and the reason, as
{"error":"length must be a whole number from 2 to 12"}, or as the bare
message with c=true. A task that cannot be generated is a 500 in the same
two formats, with the message could not generate a task. With brackets=true, samathgen 0.1.3 puts one or two
more numbers inside the bracket than length asks for.
Many tasks in one request
With count the answer is a list: a JSON array of the same objects /gen
returns for one task, or with c=true one line per task, each ending in a
newline. A client that wants a whole quiz asks once instead of once per
question; fetching 20 questions with curl took 62 ms as 20 requests and
5 ms as one, against a server on the same machine, and over a real network
the saving is 19 round trips on top of that.
curl 'http://localhost:3000/gen?c=true&count=3'
# -2+3*5 13,18,16,14 13
# 1*1*5+15 21,23,19,20 20
# 5*4 15,19,17,20 20
Without a length, every task draws its own from the configured range. The
list shape follows the parameter and not the number: count=1 is a list of
one.
The same quiz twice
With a seed a request gives the same answer every time, so a teacher can
hand a class one quiz and everyone's ?seed=2024 is the same set of
questions. Task i of a count is exactly the task a request for
seed + i gives, so a worksheet can be rerun, split or resumed from its seed,
and after 4294967295 the seed wraps to 0.
curl 'http://localhost:3000/gen?c=true&count=3&seed=2024'
# -10+1*5*4 12,9,11,10 10
# 8*4/2 18,20,17,16 16
# 9-2+6 12,17,15,13 13
A seeded task goes through the same check as any other. What a seed gives is fixed for a given server and samathgen version; upgrading samathgen can change the quiz a seed names.
Every task is checked before it is served: it has to work out to its answer
with whole numbers only, * and / before + and -, and a minus sign of
its own only at the start or just inside a bracket. A task that fails is
drawn again. The samathgen release on npm (0.1.3) gets about 3% of its tasks
wrong and writes another few percent as 3*-1*3+20; none of those reach a
client.
Configuration
Read from the environment, or from a .env file. Any value that is not a
whole number falls back to its default, as does a PORT outside 1..65535,
and lengths are clamped to 2..12 so a stray setting cannot produce a task
longer than a client will read.
| Variable | Default | Meaning |
|---|---|---|
PORT |
3000 |
Port to listen on |
lengthFrom |
2 |
Fewest terms in a generated task |
lengthTo |
4 |
Most terms in a generated task |
brackets |
false |
Set to true to wrap part of the task in brackets |