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.1.0.tar.gz (43.8 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.1.0.tar.gz.

File metadata

  • Download URL: assignment_generator_sebastian_stigler-0.1.0.tar.gz
  • Upload date:
  • Size: 43.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","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.1.0.tar.gz
Algorithm Hash digest
SHA256 e3671fe569ac4cd9842b227bf161792c5a7b28386ffcc366478118e26fcce01e
MD5 d194659100748ee8308d83c3d8ff066b
BLAKE2b-256 7402553063ecb4bb5b9b245b57a20ec9c035a5c88caa86d3ed26cfdc6fea311b

See more details on using hashes here.

File details

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

File metadata

  • Download URL: assignment_generator_sebastian_stigler-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 19.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 55b2e4513d569beab2f90604f4abc9a4150a45ab8a5d312a3b826f35a3f361a7
MD5 327eca036b63301a715b494988f2336c
BLAKE2b-256 bb4c52c381b578f27db866b85a2b38ec69ed961d258f579b2560ff6b416044df

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