Skip to main content

Assignment generator scaffold project

Project description

agen

agen (assignment-generator) is a Python 3.12 CLI tool that reads a source-code template file and generates two output files:

  • an assignment file for students (placeholders replace solution blocks)
  • a solution file for instructors (full content with solution markers)

Templates are ordinary source files (.py, .c, etc.) annotated with special comment-tagged blocks that control what appears in each output.


Installation

agen requires Python 3.12+ and is managed with uv.

From package index

uv tool install assignment-generator-sebastian-stigler
agen --help

From source

git clone <repository-url>
cd agen
uv sync

This installs the package and all dependencies into a local virtual environment. The agen command is then available via:

uv run agen --help

To install the tool globally (into a dedicated isolated environment):

uv tool install .
agen --help

Configuration

Configuration is resolved by layered merging:

  1. Built-in defaults (always applied)
  2. Global config~/.config/agen/agen-config.json (overrides defaults)
  3. Local config.agen-config.json in the current working directory (overrides global)

comment_tokens entries are merged key-by-key; all other keys are replaced wholesale by the later layer.

Generating a starter config

agen generate-config > .agen-config.json

Config file format

{
  "comment_tokens": {
    ".py": "#",
    ".c": "//"
  },
  "assignment_marker":      "TODO",
  "solution_marker_begin":  "BEGIN SOLUTION",
  "solution_marker_end":    "END SOLUTION",
  "template_file_prefix":   "template_",
  "assignment_file_prefix": "assignment_",
  "solution_file_prefix":   "solution_",
  "assignment_only_begin":  "BEGIN ASSIGNMENT ONLY",
  "assignment_only_end":    "END ASSIGNMENT ONLY",
  "solution_only_begin":    "BEGIN SOLUTION ONLY",
  "solution_only_end":      "END SOLUTION ONLY",
  "assignment_begin":       "BEGIN ASSIGNMENT",
  "assignment_end":         "END ASSIGNMENT"
}

comment_tokens

A mapping of file extensions (including the leading dot) to the line-comment token for that language. agen uses this token when writing marker lines into the output files. Add an entry for every extension you use in templates, for example ".js": "//" or ".sql": "--".

comment_tokens is the only key that is merged key-by-key across config layers — a later layer can add or override individual extensions without replacing the whole map.

Output markers (assignment_marker, solution_marker_begin, solution_marker_end)

These strings control the text that agen writes into the output files:

  • assignment_marker — the placeholder comment text inserted into the assignment file wherever an ASSIGNMENT block appears.
  • solution_marker_begin / solution_marker_end — comments wrapped around the original block content in the solution file (e.g. # BEGIN SOLUTION# END SOLUTION).

assignment_marker can be a single line (for example TODO) or multiline text.

assignment_marker supports multiline text. Each non-empty line becomes a commented placeholder line using the configured comment token; empty lines stay empty.

Example config value:

{
  "assignment_marker": "YOUR CODE STARTS HERE >>>\n\n<<<< YOUR CODE ENDS HERE"
}

Example assignment output snippet (for a Python template):

def add(a, b):
    # YOUR CODE STARTS HERE >>>

    # <<<< YOUR CODE ENDS HERE

File prefixes (template_file_prefix, assignment_file_prefix, solution_file_prefix)

These prefixes control automatic output file naming. When agen derives an output path from the template filename it:

  1. Strips template_file_prefix from the start of the template basename (if present).
  2. Prepends assignment_file_prefix or solution_file_prefix to the remainder.

For example, with the defaults a template named template_exercise.py produces assignment_exercise.py and solution_exercise.py. You can override the output path entirely with -a / -s on the command line.

Template block tags (assignment_only_begin/end, solution_only_begin/end, assignment_begin/end)

These are the tag strings that agen looks for inside the template file to delimit the three special block types. Each pair marks where a block starts and ends. They must appear as the sole content of a comment line (after the comment token). Change them only if the defaults conflict with existing comments in your codebase.

Environment variables

Variable Default Description
AGEN_CONFIG_BASENAME agen-config.json Config file basename (both global and local)
AGEN_GLOBAL_CONFIG_PATH ~/.config/agen Directory for the global config file

Template format

Template files are normal source files with specially tagged comment blocks. The file extension determines which line-comment token is used.

Block types

Block tag Assignment output Solution output
ASSIGNMENT_ONLY written as-is omitted
SOLUTION_ONLY omitted written as-is
ASSIGNMENT replaced by a placeholder comment (TODO) wrapped in begin/end solution markers + original content
(unmarked) written as-is written as-is

Example template (template_exercise.py)

def add(a, b):
    # BEGIN ASSIGNMENT
    return a + b
    # END ASSIGNMENT

# BEGIN ASSIGNMENT ONLY
# Implement the add() function above.
# END ASSIGNMENT ONLY

# BEGIN SOLUTION ONLY
# Reference implementation — do not distribute.
# END SOLUTION ONLY

Running agen create both template_exercise.py produces:

assignment_exercise.py

def add(a, b):
    # TODO

# Implement the add() function above.

solution_exercise.py

def add(a, b):
    # BEGIN SOLUTION
    return a + b
    # END SOLUTION

# Reference implementation — do not distribute.

File naming

By default, agen strips a template_ prefix from the template basename and adds assignment_ or solution_ prefixes to the output files. This is configurable — see Configuration.


Usage

agen [COMMAND] [OPTIONS] [ARGS]

Global options

agen --version

Print the installed agen version.

agen check <templatefile>

Validate and summarise a template file without writing any output.

agen check template_exercise.py

Prints block statistics and any warnings.


agen create assignment <templatefile>

Generate the assignment output file only.

agen create assignment template_exercise.py
agen create assignment template_exercise.py -a custom_assignment.py   # custom output path
agen create assignment template_exercise.py -f                        # overwrite existing file
agen create assignment template_exercise.py --dry-run                 # preview without writing
agen create assignment template_exercise.py --anyway                  # skip the no-ASSIGNMENT-block guard
agen create assignment template_exercise.py -v                        # show template stats

agen create solution <templatefile>

Generate the solution output file only.

agen create solution template_exercise.py
agen create solution template_exercise.py -s custom_solution.py       # custom output path
agen create solution template_exercise.py -f                          # overwrite existing file
agen create solution template_exercise.py --dry-run                   # preview without writing
agen create solution template_exercise.py -v                          # show template stats

agen create both <templatefile>

Generate both assignment and solution output files in one command.

agen create both template_exercise.py
agen create both template_exercise.py -f
agen create both template_exercise.py -a out_a.py -s out_s.py
agen create both template_exercise.py --dry-run
agen create both template_exercise.py -v                              # show template stats

agen current-config

Print the effective merged configuration, colour-coded by origin (default / global / local).

agen current-config

agen generate-config

Print a complete default config JSON document, suitable for redirecting into a config file.

agen generate-config > .agen-config.json

Development

uv sync                  # install dependencies
uv run pytest            # run the test suite

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

assignment_generator_sebastian_stigler-0.3.1.tar.gz (44.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file assignment_generator_sebastian_stigler-0.3.1.tar.gz.

File metadata

  • Download URL: assignment_generator_sebastian_stigler-0.3.1.tar.gz
  • Upload date:
  • Size: 44.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"11","id":"bullseye","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for assignment_generator_sebastian_stigler-0.3.1.tar.gz
Algorithm Hash digest
SHA256 8edee6dba35709c9df7de58e2ee82bfa5e078122db43613b62e1699f87a3282c
MD5 470d26b9f099a29a78c524be563b886c
BLAKE2b-256 a0ddcbaa33b415e94e24f86404662020b50b1d6badb375d9422001a550e0f11f

See more details on using hashes here.

File details

Details for the file assignment_generator_sebastian_stigler-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: assignment_generator_sebastian_stigler-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 20.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"11","id":"bullseye","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for assignment_generator_sebastian_stigler-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 013b62e2497adda8a1c06785f3d4aeaa18d669bc8462fe5dd8d1f0a0e2bd590c
MD5 2c9f895b6fc97cc76549a1ef39351508
BLAKE2b-256 9c8509bfe08212a715c604e9e5804da77cb05471399444bca180f29adb592d08

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page