Newer
Older
# Snipper
A lightweight framework for removing code from student solutions.
## Installation
pip install codesnipper
```
## What it does
This project address the following three challenges for administering a python-based course
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
- 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.