- Python 99.6%
- C 0.4%
| C | ||
| exercises | ||
| locale | ||
| nsi | ||
| rust | ||
| tests | ||
| .flake8 | ||
| .gitignore | ||
| LICENSE | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
| requirements.txt | ||
| run.py | ||
genepy.org exercises mirror
This is a mirror of exercises as found in Genepy.org database.
It is synchronized using genepy-cli via two commands, the first
one to download exercises from genepy.org:
$ genepy pull
And the second one to upload them back (it's faster to tell which one to upload):
$ genepy push exercises/is-prime/
The hierarchy
The hierarchy on the repo is the same than the one on the website, meaning:
https://genepy.org/exercises/dirichlet-solver
is stored in:
exercises/dirichlet-solver/.
In each exercises directory there's a bunch of files:
check.py: The actual tests ran against student answers.wording_en.mdandwording_fr.mdcontains the wording (and translation) for the given exercise.initial_solution.py: The code prefilled when a student joins an exercise.meta: Other informations about the exercise (title, slug, category, author, ...)
How to write a check.py
Write it like you'd write a unit test with pytest or unittest but instead of just raising an AssertionError please explain what's wrong so the student don't get stuck.
For example if you'd have to implement a test for a function returning emojis characters containing hearts, in pytest you'd write:
def test_it_contains_heart():
for char in hearts_emojis():
assert 'HEART' in unicodedata.name(char, '')
But here we'd better do:
def test_it_contains_heart():
with correction_helper.student_code():
result = hearts_emojis()
for char in result:
charname = f"({name(char)})" if name(char, "") else ""
correction_helper.fail(
f"Why are you printing `{char}` {charname}?",
"It does not looks like a heart to me.",
"Your `hearts_emojis` function returned:",
code(result),
)
Always give back the full output so students can do some tests and see what change.
The student_code, fail, and code functions come from correction-hepler.
Avoid writing a reference implementation in the check.py:
- It often give unhelpful failure messages like "We do not agree, my reference implementation gives X for Y while your implementation gives X'".
- The checks are public, so you can bet someone will just copy-paste from here.
Pitfalls
Beware of those common patterns of failing checks:
- Students modifying a mutable argument.
- Students returning unexpected things (functions, classes, None, instances, ints, complex, ...).
i18n
po files are compiled to mo files on the correction servers via an ansible playbook.
To work on translations:
- run
maketo update the.pofile. - Translate the
.pofile (inlocales/fr/LC_MESSAGES/)
Testing
To ensure the checks stability, some tests are implemented in the
tests/ directory.
Failing answers are versionned in the tests/fixtures/xfail/
directory.
For good answers we use your account: gathering your answers to run them against the current checkers, ensuring that what was passing before still pass.
So test needs your login and password, there's two way to provide it:
- Save your login and password as two separate lines in an
auth.conffile. - Save your login only in
auth.conf, and store your password inpasswordstoreasgenepy/YOUR_USERNAME.
To test everything run:
tox -p auto
Or to check a single exercise by part of its english name or path:
pytest -vv -k primes
To run coverage on a single exercise:
coverage run -m pytest -vv -k primes && coverage combine --quiet && coverage report
Using pass one can do:
Licenses
The Genepy Website uses an MIT license, most of this repo use an MIT license too.
But exercise come from various authors an may have different licenses, if you're an author, feel free to place a LICENSE file at the root of your exercise directory.
Unless stated differently, exericses use a CC BY-NC 4.0 license.