Skip to content
Snippets Groups Projects
README.md 3.62 KiB
Newer Older
  • Learn to ignore specific revisions
  • tuhe's avatar
    tuhe committed
    # Snipper
    A lightweight framework for removing code from student solutions.
    ## Installation
    
    tuhe's avatar
    tuhe committed
    ```shell
    
    tuhe's avatar
    tuhe committed
    pip install codesnipper
    ```
    ## What it does
    This project address the following three challenges for administering a python-based course
    
    tuhe's avatar
    tuhe committed
    
    
    tuhe's avatar
    tuhe committed
     - 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.