From 3a863a58994c8d632925dcc59eab39f372035eb2 Mon Sep 17 00:00:00 2001 From: Tue Herlau <tuhe@dtu.dk> Date: Thu, 2 Sep 2021 16:31:02 +0200 Subject: [PATCH] Version committed to pypi --- README.md | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9faf7d6..dfb8b4e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,100 @@ -# Snip -A lightweight framework for removing code from student solutions. Currently used at DTU. +# Snipper +A lightweight framework for removing code from student solutions. +## Installation +```bash +pip install codesnipper +``` +## What it does +This project address the following three challenges for administering a python-based course + - You need to maintain a (working) version for debugging as well as a version handed out to students (with code missing) + - You ideally want to make references in source code to course material *"(see equation 2.1 in exercise 5)"* but these tend to go out of date + - You want to include code snippets and code output in lectures notes/exercises/beamer slides + - You want to automatically create student solutions + +This framework address these problems and allow you to maintain a **single**, working project repository. + +The project is currently used in **02465** at DTU. An example of student code can be found at: + - https://gitlab.gbar.dtu.dk/02465material/02465students/blob/master/irlc/ex02/dp.py + +A set of lectures notes where all code examples/output are automatically generated from the working repository can be found a +- https://lab.compute.dtu.dk/tuhe/books (see **Sequential decision making**) + +## How it works +The basic functionality is quite simple. You start with your working script in your private repository and add special tags to the script. +In this case I have added the tags `#!b` (cut a block) and `#!f` (cut function scope). +```python +def myfun(): #!f The error I am going to raise + """ The function docstring will not be removed""" + print("This is a function") + return 42 + +def a_long_function(): + a = 234 + print("a line") + print("a line") #!b + print("a line") + print("a line") #!b Insert three missing print statements. + print("a line") + return a + +if __name__ == "__main__": + myfun() +``` +This will produce the following file: +```python +def myfun(): + """ The function docstring will not be removed""" + # TODO: 2 lines missing. + raise NotImplementedError("The error I am going to raise") + +def a_long_function(): + a = 234 + print("a line") + # TODO: 3 lines missing. + raise NotImplementedError("Insert three missing print statements.") + print("a line") + return a + +if __name__ == "__main__": + myfun() +``` +You can also use the framework to capture code snippets, outputs and interactive python output. +To do this, save the following in `foo.py` +```python +def myfun(): #!s This snippet will be saved to foo.py in the output directory. + print("Hello") #!s + +print("Do not capture me") +for i in range(4): #!o + print("Output", i) +print("Goodbuy world") #!o +print("don't capture me") + +# Interactive pythong example +print("Hello World") #!i #!i # this is a single-line cutout. +```` +These block-tags will create a file `foo.py` (in the output directory) containing +```python +def myfun(): + print("Hello") +``` +A file `foo.txt` containing the captured output +```txt +Output 0 +Output 1 +Output 2 +Output 3 +Goodbuy world +``` +and a typeset version of an interactive python session in `foo.pyi` +```ipython +>>> print("hello world") +Hello World" +``` +All these files can be directly imported into `LaTeX` using e.g. `minted`: You never need to mix `LaTeX` code and python again! + +## Additional features: +- Include references using `\cite` and `\ref`: This works by parsing your `LaTeX` `.aux` files and automatically keep your +references in code synchronized with your written material. See the 02465 students repository for examples: None of the references to the exercise material or lecture notes are hard-coded! +- You can name tags using `#!s=bar` to get a `foo_bar.py` snippet. This is useful when you need to cut multiple sessions. This also works for the other tags. -- GitLab