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.0.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.0.tar.gz.

File metadata

  • Download URL: assignment_generator_sebastian_stigler-0.3.0.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.0.tar.gz
Algorithm Hash digest
SHA256 d44f18c043b19cbfd89cf138aa5cb616d4cf4b6b56e9f0903c0ca3cf295f0955
MD5 e62c2853ef8b7cbf414d75013a0d4b83
BLAKE2b-256 b17fc8171d3f4ab2265ba6badb38d78cd1348e46423a4e38d20441fe42315463

See more details on using hashes here.

File details

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

File metadata

  • Download URL: assignment_generator_sebastian_stigler-0.3.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 591030a0a833aa925395b9642332c10c7dc0bb47c4d1a1982bea7c87c7faae96
MD5 9ad7116d71c91d97ebcf6e23799d121c
BLAKE2b-256 d365cb1cb04679cfcedd9c0e4ede5dd39d0d8a07b600bb3aec7516d61c43a8b5

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