Exercises and their correction script for Genepy https://genepy.org
  • Python 99.6%
  • C 0.4%
Find a file
2026-05-07 15:35:22 +02:00
C Bump black. 2026-03-22 15:13:47 +01:00
exercises FIX: Avoid crashing when user return a list. 2026-05-07 15:35:22 +02:00
locale Bump i18n 2025-11-13 22:58:37 +01:00
nsi Bump black. 2026-03-22 15:13:47 +01:00
rust tox is passing again (and a bit of i18n). 2025-03-27 10:12:15 +01:00
tests FIX: Avoid crashing when user return a list. 2026-05-07 15:35:22 +02:00
.flake8 Initial import 2021-12-02 09:56:26 +01:00
.gitignore Easier for me to have a separate account for tests and genepy-cli. 2025-03-19 17:23:10 +01:00
LICENSE s/hackinscience/genepy/ 2025-11-14 08:34:10 +01:00
Makefile i18n and quality on characters-counting. 2024-10-28 16:10:20 +01:00
pyproject.toml mypy adoption. 2026-03-22 15:13:01 +01:00
README.md Importing all xfails to the repo. 2025-11-15 17:01:56 +01:00
requirements.txt Hello 'expect:' in xfails. 2025-11-15 18:07:29 +01:00
run.py Small too to run an solution locally. 2025-10-06 15:56:03 +02:00

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.md and wording_fr.md contains 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 make to update the .po file.
  • Translate the .po file (in locales/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.conf file.
  • Save your login only in auth.conf, and store your password in passwordstore as genepy/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.