From acc45dbea61cd2587c5fd4c9db77d036edc61672 Mon Sep 17 00:00:00 2001
From: Tue Herlau <tuhe@dtu.dk>
Date: Thu, 2 Sep 2021 14:40:53 +0200
Subject: [PATCH] Updates

---
 LICENSE                                       |  19 +
 README.md                                     |  40 +-
 autolab/__pycache__/autolab.cpython-38.pyc    | Bin 5899 -> 0 bytes
 autolab/report_autolab.py                     |   0
 build.md                                      |  18 +
 cs202courseware/ascimenu.py                   |  43 ++
 cs202courseware/ug2report1.py                 |  14 +-
 cs202courseware/ug2report1_nohidden.py        |  13 +-
 dist/unitgrade-devel-0.0.1.tar.gz             | Bin 0 -> 17133 bytes
 dist/unitgrade_devel-0.0.1-py3-none-any.whl   | Bin 0 -> 18848 bytes
 .../docker_tango_python/Dockerfile            |   0
 .../docker_tango_python/requirements.txt      |   1 +
 .../unitgrade-docker/Dockerfile               |   4 +-
 .../home/cs103/Report3_handin_5_of_30.token   | Bin 0 -> 113733 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 922 -> 923 bytes
 .../report3_complete_grade.cpython-38.pyc     | Bin 0 -> 50864 bytes
 .../unitgrade-docker/home}/cs103/homework1.py |   0
 .../unitgrade-docker/home}/cs103/report3.py   |   6 +-
 .../home/cs103/report3_complete_grade.py      | 338 ++++++++++++
 .../home/cs103/report3_grade.py               | 340 ++++++++++++
 .../unitgrade-docker/requirements.txt         |   1 +
 .../unitgrade-docker/tmp/cs103/homework1.py   |  21 +
 .../unitgrade-docker/tmp/cs103/report3.py     |  29 +
 .../tmp/cs103/report3_complete_grade.py       | 338 ++++++++++++
 .../tmp/cs103/report3_grade.py                | 340 ++++++++++++
 examples/02471/instructor/02471/report1.py    |   2 +-
 examples/02631/instructor/programs/.coverage  | Bin 0 -> 53248 bytes
 .../__pycache__/looping.cpython-38.pyc        | Bin 0 -> 2019 bytes
 .../__pycache__/report1intro.cpython-38.pyc   | Bin 0 -> 7198 bytes
 examples/02631/instructor/programs/deploy.py  |  62 +++
 examples/02631/instructor/programs/looping.py |  64 +++
 .../02631/instructor/programs/report1intro.py | 139 +++++
 .../instructor/programs/report1intro_grade.py | 337 ++++++++++++
 .../programs/unitgrade/Bacteria.pkl           | Bin 0 -> 2050 bytes
 .../programs/unitgrade/ClusterAnalysis.pkl    | Bin 0 -> 763 bytes
 .../programs/unitgrade/FermentationRate.pkl   | Bin 0 -> 618 bytes
 .../programs/unitgrade/RemoveIncomplete.pkl   | Bin 0 -> 1444 bytes
 examples/02631/students/programs/.coverage    | Bin 0 -> 53248 bytes
 .../__pycache__/looping.cpython-38.pyc        | Bin 0 -> 2019 bytes
 .../__pycache__/report1intro.cpython-38.pyc   | Bin 0 -> 7198 bytes
 examples/02631/students/programs/looping.py   |  62 +++
 .../02631/students/programs/report1intro.py   | 142 +++++
 .../students/programs/report1intro_grade.py   | 339 ++++++++++++
 .../students/programs/unitgrade/Bacteria.pkl  | Bin 0 -> 2050 bytes
 .../programs/unitgrade/ClusterAnalysis.pkl    | Bin 0 -> 763 bytes
 .../programs/unitgrade/FermentationRate.pkl   | Bin 0 -> 618 bytes
 .../programs/unitgrade/RemoveIncomplete.pkl   | Bin 0 -> 1444 bytes
 examples/autolab_example/autolab_example.py   |   4 +-
 examples/autolab_example/tmp/cs101/cs101.yml  |   6 +-
 .../tmp/cs101/src/driver_python.py            |   6 +-
 .../tmp/cs101/src/report1_grade.py            |   2 +-
 .../tmp/cs102/src/driver_python.py            |   4 +-
 .../tmp/cs103/src/driver_python.py            |   4 +-
 .../example_docker/instructor/cs103/.coverage | Bin 0 -> 53248 bytes
 .../cs103/Report3_handin_25_of_30.token       | Bin 0 -> 117485 bytes
 .../cs103/Report3_handin_30_of_30.token       | Bin 0 -> 117467 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 833 -> 833 bytes
 .../cs103/__pycache__/report3.cpython-38.pyc  | Bin 1384 -> 1384 bytes
 .../report3_complete.cpython-38.pyc           | Bin 1748 -> 1737 bytes
 .../example_docker/instructor/cs103/deploy.py |  18 +-
 .../instructor/cs103/report3.py               |   6 +-
 .../instructor/cs103/report3_complete.py      |   4 +-
 .../cs103/report3_complete_grade.py           |  69 ++-
 .../instructor/cs103/report3_grade.py         |  69 ++-
 .../cs103/unitgrade/AutomaticPass.pkl         | Bin 93 -> 4 bytes
 .../instructor/cs103/unitgrade/Week1.pkl      | Bin 87 -> 62 bytes
 .../tmp/cs103/Report3_handin_5_of_30.token    | Bin 128198 -> 0 bytes
 .../tmp/cs103/report3_complete_grade.py       | 345 ------------
 .../tmp/cs103/report3_grade.py                | 347 ------------
 examples/example_docker/run_all_docker.py     |  57 ++
 .../example_docker/students/cs103/.coverage   | Bin 0 -> 53248 bytes
 .../cs103/Report3_handin_10_of_30.token       | Bin 65286 -> 57954 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 992 -> 992 bytes
 .../__pycache__/homework1.cpython-39.pyc      | Bin 833 -> 833 bytes
 .../cs103/__pycache__/report3.cpython-38.pyc  | Bin 1384 -> 1384 bytes
 .../report3_complete.cpython-38.pyc           | Bin 1748 -> 1748 bytes
 .../report3_complete.cpython-39.pyc           | Bin 1246 -> 1764 bytes
 .../report3_complete_grade.cpython-39.pyc}    | Bin 57824 -> 57973 bytes
 .../__pycache__/report3_grade.cpython-38.pyc  | Bin 57968 -> 50620 bytes
 .../example_docker/students/cs103/report3.py  |   6 +-
 .../students/cs103/report3_grade.py           |  69 ++-
 .../cs103/unitgrade/AutomaticPass.pkl         | Bin 93 -> 4 bytes
 .../students/cs103/unitgrade/Week1.pkl        | Bin 87 -> 62 bytes
 .../Report1Flat_handin_10_of_10.token         | Bin 0 -> 65761 bytes
 .../__pycache__/deploy.cpython-38.pyc         | Bin 0 -> 581 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 0 -> 835 bytes
 .../__pycache__/report1flat.cpython-38.pyc    | Bin 0 -> 1204 bytes
 .../instructor/cs101flat/deploy.py            |  15 +
 .../instructor/cs101flat/homework1.py         |  16 +
 .../instructor/cs101flat/report1flat.py       |  24 +
 .../instructor/cs101flat/report1flat_grade.py | 349 ++++++++++++
 .../Report1Flat_handin_0_of_10.token          | Bin 0 -> 65468 bytes
 .../__pycache__/deploy.cpython-38.pyc         | Bin 0 -> 581 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 0 -> 994 bytes
 .../__pycache__/report1flat.cpython-38.pyc    | Bin 0 -> 1204 bytes
 .../report1flat_grade.cpython-38.pyc          | Bin 0 -> 57893 bytes
 .../students/cs101flat/homework1.py           |  21 +
 .../students/cs101flat/report1flat.py         |  27 +
 .../students/cs101flat/report1flat_grade.py   | 351 ++++++++++++
 .../instructor/cs102/.coverage                | Bin 0 -> 53248 bytes
 .../cs102/Report2_handin_10_of_18.token       | Bin 80985 -> 0 bytes
 .../cs102/Report2_handin_13_of_18.token       | Bin 0 -> 60507 bytes
 .../cs102/Report2_handin_18_of_18.token       | Bin 80175 -> 61089 bytes
 .../cs102/Report2_handin_28_of_28.token       | Bin 81409 -> 0 bytes
 .../cs102/Report2_handin_5_of_18.token        | Bin 78385 -> 0 bytes
 .../cs102/Report2_handin_5_of_28.token        | Bin 80005 -> 0 bytes
 .../cs102/__pycache__/deploy.cpython-38.pyc   | Bin 0 -> 760 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 836 -> 836 bytes
 .../__pycache__/report2_grade.cpython-38.pyc  | Bin 65513 -> 59749 bytes
 .../instructor/cs102/deploy.py                |   6 +-
 .../instructor/cs102/report2.py               |  16 +-
 .../instructor/cs102/report2_grade.py         | 182 +------
 .../instructor/cs102/unitgrade/Question2.pkl  | Bin 384 -> 360 bytes
 .../instructor/cs102/unitgrade/Week1.pkl      | Bin 215 -> 101 bytes
 .../students/cs102/.coverage                  | Bin 0 -> 53248 bytes
 .../cs102/Report2_handin_0_of_18.token        | Bin 79868 -> 0 bytes
 .../cs102/__pycache__/deploy.cpython-38.pyc   | Bin 0 -> 760 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 995 -> 836 bytes
 .../cs102/__pycache__/report2.cpython-38.pyc  | Bin 2048 -> 2165 bytes
 .../__pycache__/report2_grade.cpython-38.pyc  | Bin 65631 -> 59749 bytes
 .../students/cs102/report2.py                 |  16 +-
 .../students/cs102/report2_grade.py           | 182 +------
 .../students/cs102/unitgrade/Question2.pkl    | Bin 384 -> 360 bytes
 .../students/cs102/unitgrade/Week1.pkl        | Bin 215 -> 101 bytes
 .../instructor/cs105/.coverage                | Bin 0 -> 53248 bytes
 .../Report1Jupyter_handin_18_of_18.token      | Bin 0 -> 58736 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 0 -> 187 bytes
 .../cs105/__pycache__/report5.cpython-38.pyc  | Bin 0 -> 2312 bytes
 .../cs105/__pycache__/week2.cpython-38.pyc    | Bin 0 -> 466 bytes
 .../instructor/cs105/deploy.py                |  15 +
 .../instructor/cs105/homework1.py             |   1 +
 .../instructor/cs105/report5.py               |  49 ++
 .../instructor/cs105/report5_grade.py         | 336 ++++++++++++
 .../instructor/cs105/unitgrade/Question2.pkl  | Bin 0 -> 58 bytes
 .../instructor/cs105/unitgrade/Week1.pkl      |   1 +
 .../instructor/cs105}/week2.ipynb             |   0
 .../example_jupyter/students/cs105/.coverage  | Bin 0 -> 53248 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 0 -> 187 bytes
 .../cs105/__pycache__/report5.cpython-38.pyc  | Bin 0 -> 2312 bytes
 .../cs105/__pycache__/week2.cpython-38.pyc    | Bin 0 -> 466 bytes
 .../students/cs105/homework1.py               |   4 +
 .../example_jupyter/students/cs105/report5.py |  52 ++
 .../students/cs105/report5_grade.py           | 338 ++++++++++++
 .../students/cs105/unitgrade/Question2.pkl    | Bin 0 -> 58 bytes
 .../students/cs105/unitgrade/Week1.pkl        |   1 +
 .../students/cs105/week2.ipynb                |  69 +++
 .../cs101/Report1_handin_10_of_10.token       | Bin 77365 -> 58016 bytes
 .../cs101/__pycache__/deploy.cpython-38.pyc   | Bin 0 -> 911 bytes
 .../__pycache__/report1_grade.cpython-38.pyc  | Bin 63801 -> 57383 bytes
 .../instructor/cs101/deploy.py                |  17 +-
 .../instructor/cs101/report1.py               |   4 +-
 .../instructor/cs101/report1_grade.py         | 180 +------
 .../cs101/Report1_handin_0_of_10.token        | Bin 77002 -> 0 bytes
 .../cs101/__pycache__/deploy.cpython-38.pyc   | Bin 0 -> 911 bytes
 .../__pycache__/homework1.cpython-38.pyc      | Bin 994 -> 835 bytes
 .../cs101/__pycache__/report1.cpython-38.pyc  | Bin 1209 -> 1228 bytes
 .../__pycache__/report1_grade.cpython-38.pyc  | Bin 63919 -> 57383 bytes
 .../students/cs101/report1.py                 |   5 +-
 .../students/cs101/report1_grade.py           | 180 +------
 pyproject.toml                                |   6 +
 pytransform/__init__.py                       | 454 ----------------
 .../__pycache__/__init__.cpython-36.pyc       | Bin 11679 -> 0 bytes
 .../__pycache__/__init__.cpython-38.pyc       | Bin 11349 -> 0 bytes
 pytransform/_pytransform.dll                  | Bin 1368590 -> 0 bytes
 setup.py                                      |  49 ++
 src/unitgrade_devel.egg-info/PKG-INFO         | 317 +++++++++++
 src/unitgrade_devel.egg-info/SOURCES.txt      |  18 +
 .../dependency_links.txt                      |   1 +
 src/unitgrade_devel.egg-info/requires.txt     |   9 +
 src/unitgrade_devel.egg-info/top_level.txt    |   1 +
 .../unitgrade_private2}/__init__.py           |   1 +
 .../unitgrade_private2/autolab}/__init__.py   |   0
 .../unitgrade_private2/autolab}/autolab.py    |  41 +-
 .../autolab}/lab_template/Makefile            |   0
 .../autolab}/lab_template/autograde-Makefile  |   0
 .../autolab}/lab_template/autograde.tar       | Bin
 .../autolab}/lab_template/hello.rb            |   0
 .../autolab}/lab_template/hello.yml           |   0
 .../autolab}/lab_template/src/Makefile        |   0
 .../lab_template/src/Makefile-handout         |   0
 .../autolab}/lab_template/src/README          |   0
 .../autolab}/lab_template/src/README-handout  |   0
 .../autolab}/lab_template/src/driver.sh       |   0
 .../lab_template/src/driver_python.py         |   4 +-
 .../autolab}/lab_template/src/hello.c         |   0
 .../autolab}/lab_template/src/hello.c-handout |   0
 .../unitgrade_private2}/deployment.py         |   3 +-
 .../unitgrade_private2}/docker_helpers.py     |  83 +--
 .../unitgrade_private2}/example/report0.py    |   0
 .../hidden_create_files.py                    |  18 +-
 .../hidden_gather_upload.py                   |  39 +-
 .../unitgrade_private2}/token_loader.py       |   1 -
 src/unitgrade_private2/version.py             |   1 +
 tutorial/ncode.py                             | 499 ++++++++++++++++++
 tutorial/ncode2.py                            | 363 +++++++++++++
 tutorial/submission_autograder.py             |   5 +
 tutorial/tutorial.token                       |   2 +-
 .../__pycache__/__init__.cpython-36.pyc       | Bin 888 -> 0 bytes
 .../__pycache__/__init__.cpython-38.pyc       | Bin 918 -> 0 bytes
 .../__pycache__/__init__.cpython-39.pyc       | Bin 944 -> 0 bytes
 .../__pycache__/deployment.cpython-38.pyc     | Bin 1392 -> 0 bytes
 .../__pycache__/deployment.cpython-39.pyc     | Bin 1425 -> 0 bytes
 .../__pycache__/docker_helpers.cpython-38.pyc | Bin 3165 -> 0 bytes
 .../__pycache__/docker_helpers.cpython-39.pyc | Bin 3217 -> 0 bytes
 .../hidden_create_files.cpython-36.pyc        | Bin 3954 -> 0 bytes
 .../hidden_create_files.cpython-38.pyc        | Bin 4588 -> 0 bytes
 .../hidden_create_files.cpython-39.pyc        | Bin 4665 -> 0 bytes
 .../hidden_gather_upload.cpython-36.pyc       | Bin 2775 -> 0 bytes
 .../hidden_gather_upload.cpython-38.pyc       | Bin 4107 -> 0 bytes
 .../hidden_gather_upload.cpython-39.pyc       | Bin 4210 -> 0 bytes
 .../__pycache__/token_loader.cpython-38.pyc   | Bin 978 -> 0 bytes
 .../__pycache__/__init__.cpython-38.pyc       | Bin 181 -> 0 bytes
 .../codejudge_example/codejudge_sum.py        |  35 --
 .../codejudge_example/sumfac.py               |   6 -
 214 files changed, 6013 insertions(+), 2128 deletions(-)
 create mode 100644 LICENSE
 delete mode 100644 autolab/__pycache__/autolab.cpython-38.pyc
 delete mode 100644 autolab/report_autolab.py
 create mode 100644 build.md
 create mode 100644 cs202courseware/ascimenu.py
 create mode 100644 dist/unitgrade-devel-0.0.1.tar.gz
 create mode 100644 dist/unitgrade_devel-0.0.1-py3-none-any.whl
 rename {autolab => docker_images}/docker_tango_python/Dockerfile (100%)
 rename {autolab => docker_images}/docker_tango_python/requirements.txt (86%)
 rename {examples/example_docker/instructor => docker_images}/unitgrade-docker/Dockerfile (93%)
 create mode 100644 docker_images/unitgrade-docker/home/cs103/Report3_handin_5_of_30.token
 rename {examples/example_docker/instructor/unitgrade-docker/tmp => docker_images/unitgrade-docker/home}/cs103/__pycache__/homework1.cpython-38.pyc (73%)
 create mode 100644 docker_images/unitgrade-docker/home/cs103/__pycache__/report3_complete_grade.cpython-38.pyc
 rename {examples/example_docker/instructor/unitgrade-docker/tmp => docker_images/unitgrade-docker/home}/cs103/homework1.py (100%)
 rename {examples/example_docker/instructor/unitgrade-docker/tmp => docker_images/unitgrade-docker/home}/cs103/report3.py (74%)
 create mode 100644 docker_images/unitgrade-docker/home/cs103/report3_complete_grade.py
 create mode 100644 docker_images/unitgrade-docker/home/cs103/report3_grade.py
 rename {examples/example_docker/instructor => docker_images}/unitgrade-docker/requirements.txt (86%)
 create mode 100644 docker_images/unitgrade-docker/tmp/cs103/homework1.py
 create mode 100644 docker_images/unitgrade-docker/tmp/cs103/report3.py
 create mode 100644 docker_images/unitgrade-docker/tmp/cs103/report3_complete_grade.py
 create mode 100644 docker_images/unitgrade-docker/tmp/cs103/report3_grade.py
 create mode 100644 examples/02631/instructor/programs/.coverage
 create mode 100644 examples/02631/instructor/programs/__pycache__/looping.cpython-38.pyc
 create mode 100644 examples/02631/instructor/programs/__pycache__/report1intro.cpython-38.pyc
 create mode 100644 examples/02631/instructor/programs/deploy.py
 create mode 100644 examples/02631/instructor/programs/looping.py
 create mode 100644 examples/02631/instructor/programs/report1intro.py
 create mode 100644 examples/02631/instructor/programs/report1intro_grade.py
 create mode 100644 examples/02631/instructor/programs/unitgrade/Bacteria.pkl
 create mode 100644 examples/02631/instructor/programs/unitgrade/ClusterAnalysis.pkl
 create mode 100644 examples/02631/instructor/programs/unitgrade/FermentationRate.pkl
 create mode 100644 examples/02631/instructor/programs/unitgrade/RemoveIncomplete.pkl
 create mode 100644 examples/02631/students/programs/.coverage
 create mode 100644 examples/02631/students/programs/__pycache__/looping.cpython-38.pyc
 create mode 100644 examples/02631/students/programs/__pycache__/report1intro.cpython-38.pyc
 create mode 100644 examples/02631/students/programs/looping.py
 create mode 100644 examples/02631/students/programs/report1intro.py
 create mode 100644 examples/02631/students/programs/report1intro_grade.py
 create mode 100644 examples/02631/students/programs/unitgrade/Bacteria.pkl
 create mode 100644 examples/02631/students/programs/unitgrade/ClusterAnalysis.pkl
 create mode 100644 examples/02631/students/programs/unitgrade/FermentationRate.pkl
 create mode 100644 examples/02631/students/programs/unitgrade/RemoveIncomplete.pkl
 create mode 100644 examples/example_docker/instructor/cs103/.coverage
 create mode 100644 examples/example_docker/instructor/cs103/Report3_handin_25_of_30.token
 create mode 100644 examples/example_docker/instructor/cs103/Report3_handin_30_of_30.token
 delete mode 100644 examples/example_docker/instructor/unitgrade-docker/tmp/cs103/Report3_handin_5_of_30.token
 delete mode 100644 examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3_complete_grade.py
 delete mode 100644 examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3_grade.py
 create mode 100644 examples/example_docker/run_all_docker.py
 create mode 100644 examples/example_docker/students/cs103/.coverage
 rename examples/example_docker/{instructor/unitgrade-docker/tmp/cs103/__pycache__/report3_complete_grade.cpython-38.pyc => students/cs103/__pycache__/report3_complete_grade.cpython-39.pyc} (90%)
 create mode 100644 examples/example_flat/instructor/cs101flat/Report1Flat_handin_10_of_10.token
 create mode 100644 examples/example_flat/instructor/cs101flat/__pycache__/deploy.cpython-38.pyc
 create mode 100644 examples/example_flat/instructor/cs101flat/__pycache__/homework1.cpython-38.pyc
 create mode 100644 examples/example_flat/instructor/cs101flat/__pycache__/report1flat.cpython-38.pyc
 create mode 100644 examples/example_flat/instructor/cs101flat/deploy.py
 create mode 100644 examples/example_flat/instructor/cs101flat/homework1.py
 create mode 100644 examples/example_flat/instructor/cs101flat/report1flat.py
 create mode 100644 examples/example_flat/instructor/cs101flat/report1flat_grade.py
 create mode 100644 examples/example_flat/students/cs101flat/Report1Flat_handin_0_of_10.token
 create mode 100644 examples/example_flat/students/cs101flat/__pycache__/deploy.cpython-38.pyc
 create mode 100644 examples/example_flat/students/cs101flat/__pycache__/homework1.cpython-38.pyc
 create mode 100644 examples/example_flat/students/cs101flat/__pycache__/report1flat.cpython-38.pyc
 create mode 100644 examples/example_flat/students/cs101flat/__pycache__/report1flat_grade.cpython-38.pyc
 create mode 100644 examples/example_flat/students/cs101flat/homework1.py
 create mode 100644 examples/example_flat/students/cs101flat/report1flat.py
 create mode 100644 examples/example_flat/students/cs101flat/report1flat_grade.py
 create mode 100644 examples/example_framework/instructor/cs102/.coverage
 delete mode 100644 examples/example_framework/instructor/cs102/Report2_handin_10_of_18.token
 create mode 100644 examples/example_framework/instructor/cs102/Report2_handin_13_of_18.token
 delete mode 100644 examples/example_framework/instructor/cs102/Report2_handin_28_of_28.token
 delete mode 100644 examples/example_framework/instructor/cs102/Report2_handin_5_of_18.token
 delete mode 100644 examples/example_framework/instructor/cs102/Report2_handin_5_of_28.token
 create mode 100644 examples/example_framework/instructor/cs102/__pycache__/deploy.cpython-38.pyc
 create mode 100644 examples/example_framework/students/cs102/.coverage
 delete mode 100644 examples/example_framework/students/cs102/Report2_handin_0_of_18.token
 create mode 100644 examples/example_framework/students/cs102/__pycache__/deploy.cpython-38.pyc
 create mode 100644 examples/example_jupyter/instructor/cs105/.coverage
 create mode 100644 examples/example_jupyter/instructor/cs105/Report1Jupyter_handin_18_of_18.token
 create mode 100644 examples/example_jupyter/instructor/cs105/__pycache__/homework1.cpython-38.pyc
 create mode 100644 examples/example_jupyter/instructor/cs105/__pycache__/report5.cpython-38.pyc
 create mode 100644 examples/example_jupyter/instructor/cs105/__pycache__/week2.cpython-38.pyc
 create mode 100644 examples/example_jupyter/instructor/cs105/deploy.py
 create mode 100644 examples/example_jupyter/instructor/cs105/homework1.py
 create mode 100644 examples/example_jupyter/instructor/cs105/report5.py
 create mode 100644 examples/example_jupyter/instructor/cs105/report5_grade.py
 create mode 100644 examples/example_jupyter/instructor/cs105/unitgrade/Question2.pkl
 create mode 100644 examples/example_jupyter/instructor/cs105/unitgrade/Week1.pkl
 rename examples/{02471/instructor/02471/week02 => example_jupyter/instructor/cs105}/week2.ipynb (100%)
 create mode 100644 examples/example_jupyter/students/cs105/.coverage
 create mode 100644 examples/example_jupyter/students/cs105/__pycache__/homework1.cpython-38.pyc
 create mode 100644 examples/example_jupyter/students/cs105/__pycache__/report5.cpython-38.pyc
 create mode 100644 examples/example_jupyter/students/cs105/__pycache__/week2.cpython-38.pyc
 create mode 100644 examples/example_jupyter/students/cs105/homework1.py
 create mode 100644 examples/example_jupyter/students/cs105/report5.py
 create mode 100644 examples/example_jupyter/students/cs105/report5_grade.py
 create mode 100644 examples/example_jupyter/students/cs105/unitgrade/Question2.pkl
 create mode 100644 examples/example_jupyter/students/cs105/unitgrade/Week1.pkl
 create mode 100644 examples/example_jupyter/students/cs105/week2.ipynb
 create mode 100644 examples/example_simplest/instructor/cs101/__pycache__/deploy.cpython-38.pyc
 delete mode 100644 examples/example_simplest/students/cs101/Report1_handin_0_of_10.token
 create mode 100644 examples/example_simplest/students/cs101/__pycache__/deploy.cpython-38.pyc
 create mode 100644 pyproject.toml
 delete mode 100644 pytransform/__init__.py
 delete mode 100644 pytransform/__pycache__/__init__.cpython-36.pyc
 delete mode 100644 pytransform/__pycache__/__init__.cpython-38.pyc
 delete mode 100644 pytransform/_pytransform.dll
 create mode 100644 setup.py
 create mode 100644 src/unitgrade_devel.egg-info/PKG-INFO
 create mode 100644 src/unitgrade_devel.egg-info/SOURCES.txt
 create mode 100644 src/unitgrade_devel.egg-info/dependency_links.txt
 create mode 100644 src/unitgrade_devel.egg-info/requires.txt
 create mode 100644 src/unitgrade_devel.egg-info/top_level.txt
 rename {unitgrade_private2 => src/unitgrade_private2}/__init__.py (97%)
 rename {unitgrade_private2/codejudge_example => src/unitgrade_private2/autolab}/__init__.py (100%)
 rename {autolab => src/unitgrade_private2/autolab}/autolab.py (89%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/Makefile (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/autograde-Makefile (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/autograde.tar (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/hello.rb (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/hello.yml (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/src/Makefile (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/src/Makefile-handout (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/src/README (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/src/README-handout (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/src/driver.sh (100%)
 mode change 100755 => 100644
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/src/driver_python.py (96%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/src/hello.c (100%)
 rename {autolab => src/unitgrade_private2/autolab}/lab_template/src/hello.c-handout (100%)
 rename {unitgrade_private2 => src/unitgrade_private2}/deployment.py (94%)
 rename {unitgrade_private2 => src/unitgrade_private2}/docker_helpers.py (58%)
 rename {unitgrade_private2 => src/unitgrade_private2}/example/report0.py (100%)
 rename {unitgrade_private2 => src/unitgrade_private2}/hidden_create_files.py (91%)
 rename {unitgrade_private2 => src/unitgrade_private2}/hidden_gather_upload.py (85%)
 rename {unitgrade_private2 => src/unitgrade_private2}/token_loader.py (99%)
 create mode 100644 src/unitgrade_private2/version.py
 create mode 100644 tutorial/ncode.py
 create mode 100644 tutorial/ncode2.py
 delete mode 100644 unitgrade_private2/__pycache__/__init__.cpython-36.pyc
 delete mode 100644 unitgrade_private2/__pycache__/__init__.cpython-38.pyc
 delete mode 100644 unitgrade_private2/__pycache__/__init__.cpython-39.pyc
 delete mode 100644 unitgrade_private2/__pycache__/deployment.cpython-38.pyc
 delete mode 100644 unitgrade_private2/__pycache__/deployment.cpython-39.pyc
 delete mode 100644 unitgrade_private2/__pycache__/docker_helpers.cpython-38.pyc
 delete mode 100644 unitgrade_private2/__pycache__/docker_helpers.cpython-39.pyc
 delete mode 100644 unitgrade_private2/__pycache__/hidden_create_files.cpython-36.pyc
 delete mode 100644 unitgrade_private2/__pycache__/hidden_create_files.cpython-38.pyc
 delete mode 100644 unitgrade_private2/__pycache__/hidden_create_files.cpython-39.pyc
 delete mode 100644 unitgrade_private2/__pycache__/hidden_gather_upload.cpython-36.pyc
 delete mode 100644 unitgrade_private2/__pycache__/hidden_gather_upload.cpython-38.pyc
 delete mode 100644 unitgrade_private2/__pycache__/hidden_gather_upload.cpython-39.pyc
 delete mode 100644 unitgrade_private2/__pycache__/token_loader.cpython-38.pyc
 delete mode 100644 unitgrade_private2/codejudge_example/__pycache__/__init__.cpython-38.pyc
 delete mode 100644 unitgrade_private2/codejudge_example/codejudge_sum.py
 delete mode 100644 unitgrade_private2/codejudge_example/sumfac.py

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..335ea9d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2018 The Python Packaging Authority
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 410439e..577ac9a 100644
--- a/README.md
+++ b/README.md
@@ -55,41 +55,48 @@ if __name__ == "__main__":
 ```
 ### The test: 
 The test consists of individual problems and a report-class. The tests themselves are just regular Unittest (we will see a slightly smarter idea in a moment). For instance:
+
 ```python
-from homework1 import reverse_list, add
+from looping import reverse_list, add
 import unittest
 
+
 class Week1(unittest.TestCase):
     def test_add(self):
-        self.assertEqual(add(2,2), 4)
+        self.assertEqual(add(2, 2), 4)
         self.assertEqual(add(-100, 5), -95)
 
     def test_reverse(self):
-        self.assertEqual(reverse_list([1,2,3]), [3,2,1])
+        self.assertEqual(reverse_list([1, 2, 3]), [3, 2, 1])
 
 ```
 A number of tests can be collected into a `Report`, which will allow us to assign points to the tests and use the more advanced features of the framework later. A complete, minimal example:
 
 ```python
-from unitgrade2.unitgrade2 import Report
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
-from homework1 import reverse_list, add
+from src.unitgrade2.unitgrade2 import Report
+from src.unitgrade2 import evaluate_report_student
+from looping import reverse_list, add
 import unittest
 
+
 class Week1(unittest.TestCase):
     def test_add(self):
-        self.assertEqual(add(2,2), 4)
+        self.assertEqual(add(2, 2), 4)
         self.assertEqual(add(-100, 5), -95)
 
     def test_reverse(self):
-        self.assertEqual(reverse_list([1,2,3]), [3,2,1])
+        self.assertEqual(reverse_list([1, 2, 3]), [3, 2, 1])
+
 
 import cs101
+
+
 class Report1(Report):
     title = "CS 101 Report 1"
     questions = [(Week1, 10)]  # Include a single question for 10 credits.
     pack_imports = [cs101]
 
+
 if __name__ == "__main__":
     # Uncomment to simply run everything as a unittest:
     # unittest.main(verbosity=2)
@@ -109,7 +116,7 @@ if __name__ == "__main__":
     setup_grade_file_report(Report1, minify=False, obfuscate=False, execute=False)
 
     # Deploy the files using snipper: https://gitlab.compute.dtu.dk/tuhe/snipper
-    snip_dir.snip_dir(source_dir="../cs101", dest_dir="../../students/cs101", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
+    snip_dir.snip_dir(source_dir="../programs", dest_dir="../../students/programs", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
 
 ```
  - The first line creates the `report1_grade.py` script and any additional data files needed by the tests (none in this case)
@@ -193,15 +200,18 @@ also that the students implementations didn't just detect what input was being u
 return the correct answer. To do that you need hidden tests and external validation.
 
 Our new testclass looks like this:
+
 ```python
-from unitgrade2.unitgrade2 import UTestCase, Report, hide
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
+from src.unitgrade2.unitgrade2 import UTestCase, Report, hide
+from src.unitgrade2 import evaluate_report_student
+
 
 class Week1(UTestCase):
     """ The first question for week 1. """
+
     def test_add(self):
         from cs103.homework1 import add
-        self.assertEqualC(add(2,2))
+        self.assertEqualC(add(2, 2))
         self.assertEqualC(add(-100, 5))
 
     @hide
@@ -209,14 +219,18 @@ class Week1(UTestCase):
         # This is a hidden test. The @hide-decorator will allow unitgrade to remove the test.
         # See the output in the student directory for more information.
         from cs103.homework1 import add
-        self.assertEqualC(add(2,2))
+        self.assertEqualC(add(2, 2))
+
 
 import cs103
+
+
 class Report3(Report):
     title = "CS 101 Report 3"
     questions = [(Week1, 20)]  # Include a single question for 10 credits.
     pack_imports = [cs103]
 
+
 if __name__ == "__main__":
     evaluate_report_student(Report3())
 ```
diff --git a/autolab/__pycache__/autolab.cpython-38.pyc b/autolab/__pycache__/autolab.cpython-38.pyc
deleted file mode 100644
index 86ad4a1d06d4f3267ad22b37b7839b186984db04..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5899
zcmWIL<>g{vU|?AKS10kX3IoGq5C<8vGcYhXFfcF_i!m}Vq%cG=q%fv1<uFDurZA>3
z=P>0mM=>)(#8{$OQW#TMa#(ZOqS#Qxm~z;o*i#r&SaUdXIiompxuUqB^4w9}VDosQ
zcv2Ws*m8Jt`J(usau7S%bNF)wq68QjQaGXnQ(3Zv76_+`EM$xlO%+Yy6laJMOW{i4
zZefTLPvJ@7ZDEL#Na0K2Z()d%Oc6*CY+;C!N)bvCZefU$P7z5FZDEL#0ow;MTOma(
zMZASEN;Xw4MIxJN0%MU-s(gxMs$eq{BSWf0GXo<-id2+Bigc7>icFMJifoi}s%(l}
zs$!}_s#2<QihM6?lu8OyFoULIRXJC3ib9>fV`)i#PGXXRnwmmVX<kZBszPc-YO+F6
zVrEXULa~Bwfr5pBfq{aqZc=7mN@iZVt$`jGa&d*^D-@;X=9i@^<W?#aXJnR?R4QcV
zCZ?xaai!!ZXQvh^6y;_rlqBY*=f@XRmSp7T#g~+(a=ipam7gZ#E%vC)0=LYZR87WP
z97&1Asd<UHshUi;xLxzgGK=!_a#Qn4ZV7-C1XmW9q~`kMC#IwpX)@ko3ra1>FDlVw
zyu}BxCq5%Jry#YcxJpAmBR@A)zoaxH73MGf<owd2;?!a=KOn!LG$*knHKmGIKPNFM
zz9cob0K`vb2Du4}IT#oiI2jlioIxq5jDdlngdvM@0aFd*LdGHmFq^rCp@wlGQ;|Xm
zOEW_gBUp^JhG8LN3{x$0ElUYo4RbSNEo%vT4QmQxFJmoR4ch{a8kU8O3pi_-7Bbed
zmvGfErZ6=#^$XOp)UYhzu3=xu$jA`RV9F545X2C{P{SU~pvephBeoo{uWvDyYx3M;
z$}hgfQjl1Zaf>arBD1)p_!dWTVs2_$W=`rYPS=X$)Pj=C{JdMN#RWN;B}J?Z3=Bmq
z3=9lWJn5+=aKA>e6{Y5-q!!&`$uCIFyTw{wlv$Fh$#ILVIKQ+gIrSDxN@{V*EtZtT
zlEhogDVasL7}KJ-K~}^=ox+@&S9XgnzqF*Fv}7eikt72H!!H|WtC-N@)S}`TP}s+~
z<R_PcqOUlnG%vFxy(lpyHNK!Ivn;VBH6{^~-e9y|LFFx`tSl)|U<-j_fKiH(jZuJ+
zgOQ6-fRTq$gt17Pfq@|zB!!GYz5~aQ7&wL&Fs3k;FwJI2VVcVf3d<A*a0vclPEJv%
zvek#C6XdiAO7IY2g{0EVoD>CJ-IBy~jO41Ir^#FdDsFDE6@!!EEjH)SAQ#Udu*Z=I
zkPmJNK}?JXn-~wy3~C^sfuezdQHZff9^@C~)CQ7)`$Yll7f|Y|VQOZsWiA1yyBfw6
zMsbFPOpFXQ%)tzrOny}yx*3UiDfy)(n#|zPxy4qTQCgCjbBiT8zo1f+r3e&~MZ%y2
zAOcDN%=x7y=uYLz%8G}Yq6Kmy8z^)cc^Cy4i<HnE3Ca#23=Z%Fh$9(O7@L{;eV~qH
zSjgzY5Nj2~T+33+3QF)U46$0Z>@`d^?9GftDkY3r%nMj*SZdf8GSza_FfU-O;V5CN
z;b>+Ad8<&RPz;gy!BNNLR|K+9lf8%u<O^^Fu#_j}WEXKWFfiO=$;!{nD-r}rfdW&L
zGm1SWv&b(oH#Lg83R0?oIJel+GIL5&i=x=7G7J2ZvZA=s@^eyBAqu&QOOqhn;wVl~
z0tb~p#kV+M%qTD`Ah9F^J?MC$Rup^Yxnvd@fI^Q45_(J`j2w&{Ongj5>Yy+Lxg8_{
z!k}UWR55|Wu!DhtA%$@PLkVLR(*oui#uSDWrdB3Nh8l*2Obb{_7_(RxGA?ASWlCXA
zVaZ|3Wv^uhMScxa4P!IY0*-|YwJar^3%Ec<3OLl6Kw)0Oxq!QdZ6RZkM-5vRPYp{J
zZ#GkrM+sjITM2(Nh$T?NQp4KJRLfq&&cwjT5X?~M0S;?czgvuYFaQ4k|G$Wlfq_Aj
z@s>a^xGVsbz0guuut)_I*r0fT!~lCyY7VF<D&hyl2Xk?1L6mT2E~s42$xPDAO-#<n
z%u6k*ECQviTil?cBR)4jr8Fn?7JFu1aY1TwNfcLlYDsQtZc=JdaTI%IadJ*#aq%s#
zc&NJg_*)$D@t`<~kH5v0SzKJ21XfW5N~pKk(^E?lOG=6~Ic{-+>W+AjTcWs&z%@fW
zC<<>e=jNw?t&d_(%g?{X0y63rbAD15s00K#6g^sbKxPyhLCmlQ#VRQCFfgjH@i6kS
z3Ndmq@-T9NVUam{?1Hi}D2BnY>jlms;7S8rQPeVls|aRL;h(~g!U&4#1uP{DpjfVD
zE@4=}mcmrSIGX_!+Y8uhm=`k6W|+$YFUDB?iZnriFT=pVP{ju-w;;8tf^M!tkp?Kn
zIKU+oIAV&lLGi(nmtT|%@(wt9igZBQWkCce7ByLJv4BH}1r&0(IEqqp5=%16Qj1JL
zDnR8qBxJxP8c$JaUOY@i04PvE;m^Rx$0);CWCIEYP@)DUa1a(}U|;}cP;fACvB2w2
zriF~f0wv7Qx{?W$aEle-d=^mMT5N#CXI{uy>;U4|u%$3$GuN_%X{Ms05{3n=3mHJ=
zVJ#atP}x99z8ECV4q`DvYHN-fHc(co<tX8VWEw_>60QYYU>)4xXkZd&Sjd>dEXh#I
zS;AApnZg3DjX6tr7x2|^E@Z6bLKH|P{3)y{Y&Bdd?2-&A9FhzvoGDzrEa{B3+%;S&
z+>#6n1Qs&5FvP0GFxB$Z^44%K5G>)Z;Z5O@WJqDF;Z5O{WJuuy=>SD&;j0p%8t!IB
zMurqtsEN#y3~5a1j4Avn0xb;4CN?vQGt}~>2rl4A5dzEcxiB<?iUs}@;TnE%h7=KT
zhFXCVp&9{@c_o}REH%uab|8{ZSr#&;Abcta_P=nA;6lb)p%Rf4(PmJgEm136Bb35W
zBeXy?MQkBBan=e=U@TlzBa|X;&QL2<B9tOgBLp^?A&YSVTMfrT#tDo?&q~A=h=bUm
zFkiq9V}VqZNGxQWz*Nixiop^FkX(u+D7+aNYM4?OQlwg$BpFhq#TjZvQe<jHYZyu-
zYZz-pnwhesYJ^f`Q{+<QYlI+fEs@TWSqN!i34`J-ofRSuVuM+-p!i+LRKuO3Fo&a7
ztVFIvB1KW0p@suYiZwGcGJwUDz+xa0A*Ku#1Ca<Z6|fkHgow$PNTjHO#XuxNObsjs
zBE?eFdqK8<RBC`kXEUT|)-cRwNYR?hQiCk3jUuaqBrCQ+p@yl3V>UyIF4$LKzs_cu
z%M7X>OF*)M5ZM|bglLvx4M&QeI75nl4RZ}cia{?6BLhe+D9j+LA!dR2;35TL8YDgp
zA@Ko?9V0kTDa9D9*Q7)lRtVLwPhc)O2dXM+SW_6XIVLa{y@BRKO>u@A262WIQ*nk`
z))KKSMUaXVGjRNxgYqE6RW+=^44M{xRV?}?xdl}m`dWG=`Pr#?;OZudsVFImH6*_z
zG3ORT6l)2H@e))IMX{zO<`k!DvJ{zu+A!QHsl~}fncyaF6lZQ?MSO8`eo<-^M?P36
zF(-;WCA9?9Yq`Z*l39|I8pTnNUtFA-l#_akrKG4dH5p_msE`6-P^$sd><R{zXrN|S
zIztUZtV9e`En_VcD3MBnk}4x8YffY;WC1n1itIto;K)xZNzBYkO#zpYn#{MD^bBq>
zX5V5g1Pee2aLLJKlapColANDgVAl<@g@u8EfsKKUp-MF+wIC<IGCr}mI5QpG&C#>T
z$xlwqDYnx?=&54TQNVCAsO-h+<P-*Q1;SXv1d277lYcQPRWU1BDS%z2$z0?Jsv8(f
zZZQ^vMIZ#ou|+Nn3=BOeuH>m!0taxhl9fVr6;o~POHi2IVvMh1gT!8ysGS0+k)@EI
zrT}V4X67k?YLzM${o<nJ%<upI|F2@!E2w<=3KVPt$W3ohH?T?|r3h5#KzoLI1(j98
z#U-UFsd**wke*1fUR7oRynYAO-cdX$nZ*S;iIw1H!7YA>t>D@oEX@z<TR?gn;HGz!
zNO4gzSh_gABp=q=jS|hwD=sN2O)kkViifBMxjRZ8!G>3O@u1F7W?mw=U&T>Sl%JH7
znp<4O4f3LXkgKDMuWOYkn1kUPUa+ulVm7#cR>cSALR9G$XH;?O!=;4v;qKOj32HJH
zff^rGT>2TQIXU@ymAN^;81<`IK#VF*s9;f26|-JZQWY!M>?#p3g%*gnm_eb)6va`L
zpI;K6l35f5?rVcsRqXnZ5Udi=FG(#f(S<vss0iHF;0Lueauc&tK{Ti%#iCb|SoHGG
z|NsA^m`f6iG*uAoj$3S*#h_rk#phUDoLU45FxR4@{GwZ|nZ=-9BwKoFNpg8g5vZYj
zi#0bpC9??9qy)7gZn322<R{$%wc$Y#StI~Tr)&k8$=RUH3u-*xVoAwNF1f{;S(2Jt
ze2Xoypdd9b<rZr}QD$CA5jbJ87A5ATr`}>MO3TbkDFS8bD7K>9lA_eqTf8Bzz5zat
zA+GUGj=`?r#v3>@7lE2CpjIZx;qmd{rW3gH1MXBsaez8gAgL%GP$0x77A0qZk}S9(
zB?oGEi5Gc;T*~k17aS54>Kx)91h(OpD3XACkfV!hyql+w>n)z(kWd#_zYvHbAs7!y
z1s9}S9bb}Ibc@H?KQt)VH5jZqiXU2Nq+}MQCYR(?MsfH!I>o!V28R@Zdce1si&Be=
zd_fI3ClCQ@fJHGCCr2?A7e}!{GIA8$#t?sRS3j_uihMw-JwaJi49U?!t^xi*Az&4^
z7!$!s5mH!yTZf<$<CY-QL5NZ;3sio9dNvF!0*qkD#KFYD$OCFNGx4!;F-n2@^UP9=
zB8&=*984OFB8)tY9PAKr9!4=n4kj)}K5zqDh=q?yfRTlniHVDmiIIs>h>`0*h|R;u
z^o@;Agb@sxL>R>w<rw9d<ru{n#Tb<s`55^a#hBO_S(vyOMVO=*i$E>{#cyt6W?p=J
z6^{$J;LXfSS18G^N<tbef)7~eV+>g6r&c897UZNB!x-_!nP7g2KB64aPcAkzFw}>1
z9Sk9*3aCi)rlK8Ho)jAfEgOof5~yYr4xdM{fy*ruO~#^BP)=d;^V3wl#U3A@lAjzO
zU!(_0aO_o?1)%JO=;BAQ=NIdNyDgwB4b8+^nR!`>M&OYw$e30bD9J{EOb~^~mXRKU
z3GN|A3Bd(mLr+HF{9cp}(hlmR6orFWi68=$n~OjL8{nJ|9;Ja41fXs_q`&}`Q{V&z
z?(i4Ig0z7~rHYb3tP~Id@@Y{Thy~6j2m+j8IBXytU^`Gdq!^S-S=d0i1A;lgV_pz8
p4-*R$4<iRN2M-4e2O9@BhbRXdhbRLh!#}PpPzRKaiG`5`i~+*o6yE><

diff --git a/autolab/report_autolab.py b/autolab/report_autolab.py
deleted file mode 100644
index e69de29..0000000
diff --git a/build.md b/build.md
new file mode 100644
index 0000000..4ba0737
--- /dev/null
+++ b/build.md
@@ -0,0 +1,18 @@
+# Unitgrade build info
+
+See https://packaging.python.org/tutorials/packaging-projects/
+
+- Build the distribution package using:
+```
+py -m pip install --upgrade build && py -m build
+```
+- Upload to test repo
+```
+py -m pip install --upgrade twine && py -m twine upload --repository testpypi dist/*
+```
+
+### build and upload (to actual pypi; remember the .pypi token. you can find it in personal dtu repo)
+```
+rm -f dists/* && py -m build &&  twine upload dist/*
+```
+
diff --git a/cs202courseware/ascimenu.py b/cs202courseware/ascimenu.py
new file mode 100644
index 0000000..c5f1561
--- /dev/null
+++ b/cs202courseware/ascimenu.py
@@ -0,0 +1,43 @@
+from prompt_toolkit.application import Application
+from prompt_toolkit.application.current import get_app
+from prompt_toolkit.key_binding import KeyBindings
+from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous
+from prompt_toolkit.layout import Dimension, HSplit, Layout, ScrollablePane
+from prompt_toolkit.widgets import Frame, Label, TextArea
+
+print("hello")
+
+z = 234
+def main():
+    # Create a big layout of many text areas, then wrap them in a `ScrollablePane`.
+    root_container = Frame(
+        ScrollablePane(
+            HSplit(
+                [
+                    Frame(TextArea(text=f"label-{i}"), width=Dimension())
+                    for i in range(20)
+                ]
+            )
+        )
+        # ScrollablePane(HSplit([TextArea(text=f"label-{i}") for i in range(20)]))
+    )
+
+    layout = Layout(container=root_container)
+
+    # Key bindings.
+    kb = KeyBindings()
+
+    @kb.add("c-c")
+    def exit(event) -> None:
+        get_app().exit()
+
+    kb.add("down")(focus_next)
+    kb.add("up")(focus_previous)
+
+    # Create and run application.
+    application = Application(layout=layout, key_bindings=kb, full_screen=True)
+    application.run()
+
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/cs202courseware/ug2report1.py b/cs202courseware/ug2report1.py
index 586a004..e0e7e05 100644
--- a/cs202courseware/ug2report1.py
+++ b/cs202courseware/ug2report1.py
@@ -1,16 +1,13 @@
 # from unitgrade.unitgrade import QuestionGroup, Report, QPrintItem
 # from unitgrade.unitgrade_helpers import evaluate_report_student
 
-from cs202courseware import homework1
-import unittest
-
-from unitgrade2.unitgrade2 import wrapper, UTestCase, cache
+from src.unitgrade2.unitgrade2 import UTestCase, cache
 from unittest import TestCase
 # from unitgrade2.unitgrade2 import cache
-from unitgrade2.unitgrade2 import methodsWithDecorator, hide
+from src.unitgrade2.unitgrade2 import hide
 
 import random
-from cs202courseware.homework1 import reverse_list, my_sum
+from cs202courseware.homework1 import my_sum
 
 class TestPartial(TestCase):
     def test_a(self):
@@ -83,7 +80,7 @@ class ListQuestion(UTestCase):
         """ ccc test_integers-short """
         self.assertEqual(2,2)
 
-from unitgrade2.unitgrade2 import Report
+from src.unitgrade2.unitgrade2 import Report
 
 class Report1(Report):
     title = "CS 202 Report 1"
@@ -97,7 +94,6 @@ class Report1(Report):
     pack_imports = [cs202courseware]  # Include this file in .token file
     a = 234
 
-import coverage
 
 if __name__ == "__main__":
     """
@@ -113,7 +109,7 @@ if __name__ == "__main__":
     #     print(inspect.getsourcelines(f) ) # How to get all hidden questions.
 
 
-    from unitgrade2.unitgrade_helpers2 import evaluate_report_student
+    from src.unitgrade2 import evaluate_report_student
     # cov = coverage.Coverage()
     # cov.start()
 
diff --git a/cs202courseware/ug2report1_nohidden.py b/cs202courseware/ug2report1_nohidden.py
index 180417c..3e94a57 100644
--- a/cs202courseware/ug2report1_nohidden.py
+++ b/cs202courseware/ug2report1_nohidden.py
@@ -1,17 +1,14 @@
 # from unitgrade.unitgrade import QuestionGroup, Report, QPrintItem
 # from unitgrade.unitgrade_helpers import evaluate_report_student
 
-from cs202courseware import homework1
-import unittest
-
-from unitgrade2.unitgrade2 import wrapper, UTestCase, cache
+from src.unitgrade2.unitgrade2 import UTestCase, cache
 # from unitgrade2.unitgrade2 import cache
-from unitgrade2.unitgrade2 import methodsWithDecorator, hide
+from src.unitgrade2.unitgrade2 import methodsWithDecorator, hide
 
 
 
 import random
-from cs101courseware_example.homework1 import reverse_list, my_sum
+from cs101courseware_example.homework1 import my_sum
 
 class GeneratorQuestion(UTestCase):
     def genTest(self, n):
@@ -57,7 +54,7 @@ class ListQuestion(UTestCase):
         """ ccc test_integers-short """
         self.assertEqual(2,2)
 
-from unitgrade2.unitgrade2 import Report
+from src.unitgrade2.unitgrade2 import Report
 
 class Report1(Report):
     title = "CS 202 Report 1"
@@ -103,7 +100,7 @@ if __name__ == "__main__":
     for f in ls:
         print(inspect.getsourcelines(f) ) # How to get all hidden questions.
 
-    from unitgrade2.unitgrade_helpers2 import evaluate_report_student
+    from src.unitgrade2 import evaluate_report_student
 
     evaluate_report_student( Report1() )
 
diff --git a/dist/unitgrade-devel-0.0.1.tar.gz b/dist/unitgrade-devel-0.0.1.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..9a8b82a9d4e5c3c61bd6ced6cace4b2a6bfb40b9
GIT binary patch
literal 17133
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
I;9z0^0CmcBxc~qF

literal 0
HcmV?d00001

diff --git a/dist/unitgrade_devel-0.0.1-py3-none-any.whl b/dist/unitgrade_devel-0.0.1-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..6e566dfa026e00890940fe2102371f73794be2be
GIT binary patch
literal 18848
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%0Dr|
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%0Dv<2BZ>`#AK
zZ_dws(f*|T;lr?E$NB%t!=4;tD)8xj`}*0r!{+7B8qfXBZ+gGoXnx<j#s86Ja9I<T
zf}`x0J2WvdFgUX?FsP$6OH)$IQgd_-^bGV2^-?m6OLQ~y((?6vJe^(rf?Z>Sy!&q%
z2<&q|RWDI^YwDu6k3+tuHASvzvnV<g)Td^6B)22*jmXFM*1|XL=BX~pIQDsOn#bLr
zRyUHRA1thESwDY&P4g<#fEef3RT?FKqvdn!S<I4>H$0SbFASOSFlFy{i$vQkX$HTw
zW!UesUsfrQ=wU2x*md>rMHK;=7yr1@jVoAo)Lz)8?!{}`bzHEoO{{W{bxXG#kDvL1
zz2#f4dT{ivK0f(nGoMPuhPfX<2wZrwW{+}O|75S^5^?u!>{T_j&E2lglN%2HFt{<x
zLuf<o-Co|E6}9i)oV=&XVfXgPaluP{a?TU3viPmr$o^}V=FQ4G<=3`znoQgAJ^8@0
z<!QN9PKlHJ^BD52Oxi@m*7_IT|Lg1g<e!f>?|0M6S20oLzh)d=wD_>a7mX~nfX4;7
zlb`7av%k9V=V0mF-2uC9eeGQu@XuPd&u{hjcl|Rz-FbI!cSBje-V2`R-yh$bU$c5Q
z-?wM`Ohb;zzOGm1eR6>P4|BxbgEx66KlvXxUyWOvZ)r?e^fHSMAuiSUBTf1V$Gq00
zbLO~ioiv-Pz-i;2Ta7VHr^`P$Kj~)qao*|UCYF_tJl1sk6y$W-oHgT~Xn$CyapxKZ
z;p{-gY}H1Q_c2Y=k8FFU6`OeSnUe5Tz0So;R}>}1da?3wEz_EqXS8g=jTKJQWO#KZ
zn2Y}mTF4Xsc~6y7<QvBNgG{GHPa9q8Qr>oup-aa}t9!1{`PE!uM$rX1=Pav|Klj|<
zVh}#daHC(s!E0}3`fGHWNc2C;V@urq=!&vy+x{&=M$1)Jp3!biZE_6#+IF{VlKO!u
z8ky?es@G>sEb9`m+^Asi++6CGd5r~kU%+0?pVG=Y7N;kyQTZ_CQ|YglNCO0*WUO0X
zeWXo{fuYrofkA_aWbEr2;^^WS;`lZ?yZE--w7-4v7nQH~d9=3ZXs*2bbV}Oe!a1E~
z!s%wyj&FThG|_i~r_!NjN9IL4qd(t&ey4hOBb%mnm$tn5(;F%m`fq<Pe7E{%b7sjZ
zY1_ZMSLTLIH7=EmcUfPWn6^rHb6V`{D?Y)+`JYxuf3m6TbIiZB=)%{!WpNtWQlV=@
zf<t#6z29{_{B|8{=<M83^RSmjq0i!;ug&YpGF#TMZ#9?k-B+e&cTCP+J9qAU@!p=v
zt8Q%T?Yz9K_ww$~%kIwjoVWAmwsY?`I(=D`YZhu7ynSup{h3zR*H)XDwx0Vmb5Ujd
zX{n3fBa^(kYwLFG?EM!OZa;g;%zb}f{+{{Edw1COt$y!(Y=6EDnUj8P+cCHL)1{kN
zy-HekZ{NT5*X{RJ%kDk1b?Z$nV+BF!q_Du0r%|=*PnUKpua=zm-Z9^E{yMhDvRl7A
zI&N<M>S$SX_;<CX?-$(PFX!{KFgxq+1-ATe+YDRJgqo*jZDXsS>icE#&!uOxl9z9K
z>+|>LFRg#uUq~lUwz_R5@cv6`sF{S--n;n+S0Ag%Ij8u1_m*2z=e1tW-z@Wf-~P&<
zufEO>|GVgZ%C?y+H|cKseYjorI$yj>Xjab5T*u!JSG(!oo^zz;$Diq2ENZshUB9U`
zZ`R|dpSg0bA3y*8;F_<@Peh_?Heb%2cIT;D*SwY6=gL-WeLZhQPe|0uZ7aD7><X*&
zvi=2%$6Y@dzLiNbE&OWvh3dN+!LL&D)|~RXeI@r&i0N#<tx+>~#Rok9xzBh;NG`Lg
z($4j#nHFu@*mb30S?cVkD-SJ;7TX-k{ir@UXEVo(4O1sDS%-W%w~D1bQYv-3n&Mn9
z$GMlXmUio$FIoF$U(OeIySsX)i}&R6d~4BszbUQxd3C76oYIwf`zl3Omv5=Kc4DT(
zl$+r*BquO=W#;ca^6BinKK{a|2Hx&`W#11NHl?!Gy!&aDR^+h#V%hom`t$7ni>H1)
zwc?P9bZpwT0267Z^I_FVvbkBar|BF@V!!>2Z`Pz+9gHtc&SsR(Wfs^ZqTISfB4hj7
zvSo2wEq6@4;FOd-A!Mty(DQ%^d-i;&TIIbvd0j?!L`c-cfQ;hkr@Fa(8{M+Bo);Pj
z8uXipYCCskTzJjJb-m%MR7t36&%(8H?;Q+#>+?4~TYBqi<2UP@Q}5i_rc>H1x%1R!
zrR)kdwY{ti6GOHia66=3urYXk#N9Pl_GLw8IxRF47P8`H+&yKH?7yhjLd$q~jXa|#
zukrM6I4{Wd;IFiPkEzYcZL!Y;3b!wb-S8t~-?_~bu1!Avan2_GwTl@QSQApYI1g_#
zT_&I(an?m(TdWvEew4#ovq&b<b-h{JD_O0*?#?oAbeVkNM&y!3A<n&@LRMbeq_;9(
zt4R0Nd;1NOuI5@^&`i3Z``Y>~pNZGI4mYW9n%>N}vo~$ju(Ga>H9hd?HgC_#o53fR
zR2SYlvWBn8`sBsBTbFGEZ_C&mv+PM!=aAoVZdQD0^T(T#i&f@tZT}f9;3Tj^bwcru
zO{;EAGHhKDGw1j9=iF17nmUjEw&SWeb#E^BH}A$t=^_(SzMOq8|Dbf?`yPYL(1{1F
z6k3l9^{Pky;WwOqN9d#RX9=%-jtd8F&ziYixph&(a;rAq+;%syy(c!h?Y_5SQ&xk;
zo1&m?lY0a>+I3DiFW+P2B>q5WV`g|Olgg&fb&|KQaI^B9`X1abRrf%nTQN~%IrBx`
zbLP`H&u#j1LL@9O{q!^&ZoW$|-=9!Y6Xv_JY{80To4!TTLeeWredex^4m>NSwYfm9
zrg5kLB{}oDGr!-RP6-ZA{kGpNCa^xsddoJ8U-wLwhdm7~U0!l{h5nTzDyE@QRwtLS
zarRVQOxoB{<znam=IH0{&%RF?a(0KGKT^;z<4A$^mSp=66`UWv#J3!3_U?$4_jQ(;
z7G6DXsfX{}Z)F=)-ZzVO)Mc3DCRP<4(qCe4FT6$AC%oX-qP0r4VV74Oy<A#$-n!*^
z_totUp-Ms1J7-=@^Sc_nx#@`~TiQHlPq(A<{z;y{ve|x(gqXjd-;ewIlVXcvzeLSF
zwITRStG?pHlf@g_7-mellDV;!KTyqFW^c#r=XW0@2-qEY6}qRd@-L(4dwsR(lUMU6
zr<&Jj+;rQ!|Ip)Z{;VZ``yN*~ERjB*y@NHlUPZ%fuGqi2CF-Xia^8LEAuo7Y?_{+8
zmnO%`jWHdjYi=1Ot|>P${PgDUG>dGu<=4fG<369iYxgSZrT(;bkw<|dsoJLVrzc#f
zS+{Qe)sr=T6$bO?pO8AQF}dNg{*|LXdyD_=S$wE+qY3ZIXO$PWZjxN<CvjKhnPO(l
zD*X@txBjwU^rooD^55~36$by*(`NiIj22iUaNkdjeNkhATD<SSugnr&Uaw21U6Ckw
zYF`z)VM}S)vYWNjwsBZ(D^lS+w1xZEGR~)Fh1>aNhb8*f<sS*%bnklF*@;J^*|%kF
zF=p~<aamw_{@QFdCB~1YOe#~Cx_QS$hb*ao>}<`!lNcJ#y726@bNnZRa^&Y#JFV%v
z!_EIaP{i=*tGR~d;>!Om)a3sQ@s;T`scc>Ry!erg-`1k@FYSLxC36Owudiclc2klq
zwVby?|9C(DY^At4E7ltn{dynoxR<@!@=<;1e&^l6H)N)nD<&^KFD`%V%<>nl!A9HO
z7_=8mw0SNd!m;|Ozs}X8M>I80cPviZA<#F~a-n0zTtN+s4U<egbx)kXFnQ6U6{>sH
z6PISCYUG(-Q}&*JH{e-B@E*T^>@yW@#6B(K(RwrY*v1vPbC1Lp6iU{7IW*na#^gr-
zhm*Hrrc}JU@a=!-%fQf2?CJJ5=SJ<QHJns`SB-ZO7xNLT%Aag2FSbfA(PQzf&vcY_
z=ez#uZ^z9x-Ff}?0!8<xc=BZmXgP50eCbx)RQPeuC#EO0VRzV7ZHpInhbP~%bMbe0
zv3)5^iHv+ze?!4M3&z~Z3xq=|Dt}eZt;yUg$fmE|o$~Tm(33BmSEVY=EZ?Ml_}k{p
zxv24AxW3@A!mUhh+rKXiQp;>ue1Uz-y$e;rNlBg?f>rjMyu0T7<`Xwwrr4RJdOsBq
zNZV^H(vrt>X`7C#Q8&k=zt*{%OkST+_c(mk;`-~;Y7WJmuXnBSU9I{kt&OpBeZqf3
zoff6Sb?G|a^(KAl-o2_vLzGW><Nmp_v-WepZaY?|_`a{G?{vhZ9XltOKJU2fzqR1S
z?VUZ##r;zFEL48HJ@)9e4CjRHjJqAb&G^4+R&5gZdfuk8)qlTkx7vPSU)Ij7TqdW#
z%%25!?)d+z=l1K~juw6ur6Lu3P3zBBZPYH!)%_+vA$m(`(u>DmJ!R(a?waQ6Fi~jL
zkLN!gKfY4n(<HKW&gBzpQvN>R++KQ`J?Ztnx_Ybm`QKya%slU}{_2ZP-YV<hOULz?
z?7#B$Ov<;*>Aj(N-s|xdAEuwJ!JH3`pXp8s@ru2gDId}$B6>;ox<~55EvFS`gfHH7
z=+#W`#X?Q_`**vtb$qR;)>^jxcB0y)rN_Anq9lrT2yg1?Ra-3<;+@*HzT=N0SMsC-
zwlVWJOfsFwyE)c6dScOx)0cL8Zjj_U%Nl#nE@3;9(7D?`OT9n6i}4pM+x30<!Op%-
zlWrH>W=Ih5<W}}=%QrO?&-YrCa`1+Xb)v4!N6G6RD>7V*ZcKijI=Mfl&qVi1!aQ$r
z*%_j(WlEi@hnuCA<vMLt4-wrN=U2LWTjRgq51JqQ&vK2Qb4}<)5$pQ(*LP-VhDC0B
zZOW?o-t1Y!U6K2FU&K}_@lU(F<E})IZL(X^0>!;0NisEmUL?9Mu4I|dmtCl9z4))@
z-FLgJj(qNnN_yPD%)N1C>*-j2*Jr75g{ppcvexX`b@+ge$D!!3gipG6c2%6YXVfY9
zel<_obQLGH6)CL8_s_d@BmdKZpmRYv0kR)2DP^=CUq72&$y2KNtu>49(Zg#@c$S(g
za&Y^JM7nlA5bImn6jHS6$i=1yG07^fhhqe1I!;>spuU7Rew)Rz*^)L1#qRbO*;74M
z_zAy|J90$c*e1{9nJ>$-f~e)JP5ajEQq_8%wR@w|_cLv+&dc*O?_G2KqAR-Uq_y)!
zjZEczk7R`Fww?WIwR+_hzS{-rOZUE<TkX_wkTtSKDE7meW~-E+{~8Z43zety>6}&H
z9VS-UoROTV(Ys);#=8SL87|Xy$vrMy8Sn7Mn&+t*<8)u+-|`nv_iF#2eAe>Ymm?f3
zI$wpB=$*V2e5kl1_=jV!R1qtm#NI}qnXOHZwbhQg*;UpX4B3q%E8`2hxbyB^JiYXx
zsbFc!p6(5kPqnXB$UnNl#h5*E{ml&>eX`n0Yi4h8Iy1vrozqO<Q{vGV4)@tb^Dgll
z&gi||7|>~PZ?(pxHwWfROttXaBzE=8qfJgNCky&_oD6t5Ioc}qf{|ldL}B51t?Sc@
zgdTU9*7h@nq(&KOl}@!U|H|)nZJqCtsFjhrxm&Z!9Ikr0&z`U?DXn6jej?+9-izh#
ze0fH11m>>O$g_Goccpi>uBrc;bh#4;j15;O|F{15A=oK@J4eat)T!@gawz{@d{4jo
z-{e!m9tj@KKUEgmuGari>Kqkw@8ZIPqU%_{9bbMSet{=bddjVvTrN&AOVXV<Uw#e{
zWw^uhW2>Xp+pLbFS!+!$>^#3%iOr?RA+}nVMe6oZjVqUu0=>33t$MiZ$sr3>rA1q;
za~_`hXzSE*`gzo5_cM-O1!ZnKuilho>J~lcdUb6Iv*3)PT$hU-Nvke=HZ)szGyZBU
z_vuu}er5J18SV~E)<OZ^!2J)WP7%KH)W^y5{N5MGH#Mh!(~sGj!LaR3idd}I#(*om
zZVub$cv(*{nQ`BNd(*Mf%-v#w=gwp}^KN{wjn(tQcD@Ex(cKMo{tHz$%UJ9>98_JR
z>pt~Khuv4rlCY+iDJ!OIO;~<3I=&)e#l-1~$AT1>=a-jU?QCsXVEs|yN>w7`FTZ1I
z8S{_5YUMrkGcnbT*GnOv-%CDZ+1tn89qslXW+@dccfEFel}e3MSO0{oJ5N<jXA6pb
z7JRjLx^lev-xAHIPZv!4bj0XXGE1xI)I27`N9y6O<)!6SUwrm@tX!fMI(fkgF?*-?
z&7tL*dI8%vp0;tRy_9!0GrV0b)iP@OR5rFhldS)%DEVD-@xHXn>6%9N%>HOi*{+*A
zXR|EaTkz3ftx_k~VQE*PmieKN_VUk8b`*b`vnb}9)rsn+f>qt~G?v|%;q*$Z!%^_}
z<)^&o{WMHPrEa>WO*>o`Tqb#C(P_)w5z|_Cr(9>|*qO@j+4lC3{@&-ok&lyt<-fJ>
zu3c5CyzSHdb9{R8Tc(>&%H6f7I$b_~vx(JPoo{~TrRPpr2JYk)33>H<xe@12nQJaA
z{#$2XDsr4A+j*V6{p*ws7ANOa=GcBtTG709<;%R7OD}3Y3?$zRl})V65<kBCoSRy$
z|IWyV#w!wP-yc46W$lDAE`zyR?-uagwq8@<;+T7Fm*2$4n^)zynC`l8{Pex0W(WK3
zOk7qalYjMg_@AF@?{~Q|XSepqvCXh#I`Jg0zQfpZs+qew2lv6Fq5JG-uFzM1l_bNn
z;G4khq7{Ox9J|sptWCe^283Ts|696p(TNr-gL~7OTi44)?s)yRcW3A<<zr8zRqKVO
zCR}e6<y1d$>4aU$-n^$)SClV&d)XY5w7z+<O7D@cJer4P#H}Rdxs<loTAlUsUdVK{
zl7;<9h}hnhU(A<WI<-Ontkn98W?O3JPpnEkGJkJO5XYALu?~+S6pPXX7^WRwz3-&I
zwwwVUqY~e)B~KP)NH^`+=<UVj^6nag&MK3sDo*S40xm2yQ@ekuR^!yM7|)q^n}24!
zQrUb=P<6XNXT_#CL&wG&@2p(iW5cC9gf^M5*Rt0&{x}q>87k2b|H`>wUBAFl7Rw+d
z?jHU#%P$4*oBriuY%6E?{n#eUDLZ54B_%xLn!8MU=54Fb;k$I0d0pJ@mYw@#ai6oR
zDDX>e^yQ73Z1W3t$cFW;h}ibfXjZUBQFht|edSEPO`F&Kc)r&+!l2`-g5BO(E8jo4
zH!<X;@PjS8GYYiT`D1m2n~t1exu~(Zt5`*F`u?*|g~UDI`%1+G6)pAu(W?CFO~exU
zmo|GkZ+zS>JnN3zVl}7ATOQZLixLXj-n37xSibi36ifXlt-tm5Oy4yryIe-@cbVgL
zK2H7Ao!WEWxy|+Fdf^u*^0y;-YTEI~NA7x^nw4JOw)a^27g1|-+rn7(ePtPT%P&g&
zmHYVVGV`<5=ecKG&F`DBKdnvXlBxJY*-78m>=sz=ywR(0X85dcg5Ebe-{o~(<lVEc
z%&up~{KAWx3@;Kl+Gykz@AT2)DKWjX^1}O5M;zaOd9|Rt>g$qwFRv=^y?pxq+VZNe
zE%#nN);+g+-O-bmQZGE=*|O^CrMau;#+|J_KY!7?h{8)sb~9Y$cRUb?mcG8uX3t99
z?OrvCQ)Q~lnK=vIZ1E0Ck)P+@9JhRZcH56bkvk+5ll$KVO__T5)V=o>>zy<^ijS{T
zdd)pyPJ3zV@y9jFIhArTpC=uhcmC25ncn%A68HRCE9(|@$+!360bk>yX?qX7w0XC8
z@?k6c(ziJmB7ffb`Ewo<kLsy){&OA_W|h~!EPTX%yXKsuPR<;jmkUBqR@E70)XJ6F
zq<UO<w`6JE`EzRfWM&<l`MQGbpw`=8Q+D&@OKo1dI?XY8$9vAA^})A#<}T;8supQ~
ztFd$Gg_Vj|*SDDZ-Tt-k`uu<+b_>3(G@i{fxBEL^)t0}Rzx&Q#IV)vpY<_p@)x!9y
zUZy$aYOfx9uKUqe{na!ka>wo81>PwyCMYYJXl`c>kEu0VmGk6p>zA<F1@4In<+HcA
zObB}IqSYo6z^kz&WolE*D&0$e&xZz7e|=O~aLIhRrk09%gwmdajS6vDdAWbj%WCYn
zzq9&9Nv@vu4|fZ9##tpi%ole=&5zl8ex=acL*E>)h>K}!NqhgyFPXF?E5qwme|^Z|
zYfnRM63pJ*(dO1auf^;d_57;Qvi)wyv%a-jS(cj>8`b^)<GeoZ-7A~*jm{tDesJWy
zvDGBD{#WCP4ZD9Vdu=uO+K1!=-0w<H`PrrViJjjsEOGKYYsZvME4xMIPw&__-Tm;u
zQulg4=d>BmLl1q4Wj|du@#x3;*<2g0i15T-7q}2+K3ifwr*c#3@iX2%)|ELMlV7dx
zm$%*Ka9_G8KyTNzhkrMowf>Q=y?R1HUxo6aBTrw>U^U|YRHpeeM*HX1a33MLwQLqI
zkJ*T7PE6h_av<Sp;r>4-xU>%RuX<V=wpA?bsHVDOU}%v0`bk;Ap=!_kYpSOgt6!hF
zRjB(@KHHLg7i+$R&#7*FAkcnkR`=uC-D?t}59(W0-mA2at+_VQQSO|=>XP|S%+oGs
zF24RMBckTgU5%t|HI|R(@8B^E;R(#?JJ38qS>veR&#xgukx5!pJyfSZj@P)w;B|LW
zV_0X%j{3AqJGW0ezul@{<|k{D`*9To?GL;nADuJi%o9>!TIBvndgq1(uWS21h=g2I
zGrzKo^D@iyTc@A$9hvj7G0r~0V}I<)r_;W7?ml1sD%0J__ObRoo3DQ}gH5fzGq%kB
z%q%LuD}GvA__saMQlFT!=lQfTaf+1%?p=6a-Z61a`R>2#m(SsS+g{FgBBJbHy5-!1
zKc>{ZsV_*qdQ;Np)f*q(n8%+M796ZLieL0D`$~Fqo7&$?4e!IhB-XD#mHa+_V%y1H
zBQ1d!j+M8Li_U#z(7xi6%pJbsRxv#rZZX^P>5J9xzTG^fZeLi+&SyqF-p+fE{8mxb
z=2A(2a`b5*!}mCj+^qk~&c~nVUUiL3i|uh&_t6e={^eOZO`xf8dF9yyUpy2yEq8e}
z;XuwhuFtX>OLVvETZnc3<3y}C0*z&N2N<o2VPIeYVbqmE*r#N|JzQOVxX*j|p1sHm
zS<AFJ$l!|cgChU4-nw2oC-pZ4d3c@F(d*P_Um1A8;DWK)b>j<9xK5qdzxY+>8n1?~
z*V&Ukn}RenwS1p)dHQS*(pX_~?d<9E-dBCktbXzcc{vowd8VH@o{2IrFn|_V=@K#2
zUXouBpOadanxj`zQKEhJw2r5~myc(!zQ!pXZyirl4D(M;d%gS+69dCj7WCy-*u5X*
z>g*rn(mKg|{VER;x98utH;8w&8@yoDXLWIOu&`3(U={f!#LZG)TRhoLcCuNm+tgKF
z*G~QWW^Tgqymro^6|XN!By-fc3r5K;&bWH^$l?yh<Nrga9n)Uf|IhM+Ly%<Lh1y=N
z(A_I;Sp-=fe0}iHwQE04O%_%(cpZPZex>G{Rb}fEoA2*n)M9e9irOkG`pVBV>Euq;
zP1X0?Wv!21_nJ_$q0DmU5l%;Aldpnz)XZ<Vv#znaVSn#|+zq2us*^4<hxoEDs9o5;
z<+|=JGvoJKXZm+rZirFgJ~uhxI?sR3xCJJyzEi#w>~xb{^<eiy#dE?OE?L=;{2z7Z
ztv;*Rb#vbIlV@2sR3~1}TgqK*@#c*B!A_>n_H8!Djv5`^&?2%tze{V{-5GWtCoknJ
zbTi%Zvfx64jO(lLmi&@L-sg9Ai>yf&usOPEzQ~Tfx^4CeH}<#BuUs0>@N}wye)7p1
zz7gMloXR<{&+q%@TbjMO(gwHK-*qlvWSD>9v5;lf?C)2M7hh8=v18w%``1HKSTlV3
zt`~W6GM@@IUEwLe7;~!A;ez~ZA^sg}AH7~Kw<$Z+x@_r!({Vm-`vTil(zOaKoW6$@
zx7Vh(P1g;sIQ-0|M(4Eo@A;p3b*CmC)I4fs+4ogbGeqB-QB7mh-CJhe(-M`s{g3?P
zzLDg|u}EXz#bAp=T}#5Qbj2-w(dc<4<!%1yfGy3-Yd`<IEt<P$&E8+rzlyeHTz_%b
zaY@6x)54kiJ}qgRV*c*k(RV%<rg;26aX)+C60dz<bRBZ5osA@wFBO>ix^BvQ(LJr9
zePiNL$?5Jw6SmpB>d6o=@ejPy-xhG)<h3;aeE-~r6-z}wu$I<;d0DEwWcuWpw;!)*
z;aYa+L4xK~<!vn-bt#Xxb+59w*S2|BU!KrYvG}atA)d`=R-X^--TvZ)!tx7WJM)(P
zZk-Z&FymRB<iqE@J7y*A)^hywOFF=tkx7IB_X#M_6^IPm8bK`l=b<2*1zLQFey#_|
z1Q6cVSjLF;Y!#GKK9Ehrc02>fBoN-#_?H>GY3PSFAe#tsANoFGkZB;it#KJARui%B
zDn>UJeTNaqND$uE_*f91vFT|0jgZa7wj3E`CJ1k9<dec`F52Q`Wb?4CR|S~`!rK~c
zWw4ruSiOpD6t=~xAY(vyTVpqNqo9jTk(aI_n+b{?^rfpH^FVl8<3;>tLe17Is6;jr
zREeN3I{+C6!rK}%)RBFRy~u|yLO?eZeG(XCAP8@3)Yl?xC~Qg?-Bk4I7-S*{Z)^PR
zK-g4p<&175dKC&X4urQg&T=GdBua&fZZvxB2{IOhw=n)9!e~fc8sN>!2GYaFz{k+V
L!oa}b3gQ6(fkJ0l

literal 0
HcmV?d00001

diff --git a/autolab/docker_tango_python/Dockerfile b/docker_images/docker_tango_python/Dockerfile
similarity index 100%
rename from autolab/docker_tango_python/Dockerfile
rename to docker_images/docker_tango_python/Dockerfile
diff --git a/autolab/docker_tango_python/requirements.txt b/docker_images/docker_tango_python/requirements.txt
similarity index 86%
rename from autolab/docker_tango_python/requirements.txt
rename to docker_images/docker_tango_python/requirements.txt
index 9db6120..0a73d68 100644
--- a/autolab/docker_tango_python/requirements.txt
+++ b/docker_images/docker_tango_python/requirements.txt
@@ -4,3 +4,4 @@ jinja2
 tabulate
 compress_pickle
 pyfiglet
+colorama
\ No newline at end of file
diff --git a/examples/example_docker/instructor/unitgrade-docker/Dockerfile b/docker_images/unitgrade-docker/Dockerfile
similarity index 93%
rename from examples/example_docker/instructor/unitgrade-docker/Dockerfile
rename to docker_images/unitgrade-docker/Dockerfile
index 08764b5..98a4007 100644
--- a/examples/example_docker/instructor/unitgrade-docker/Dockerfile
+++ b/docker_images/unitgrade-docker/Dockerfile
@@ -5,7 +5,7 @@ FROM python:3.8-slim-buster
 RUN apt-get -y update
 RUN apt-get -y install git
 
-WORKDIR /app
+WORKDIR /home
 
 # Remember to include requirements.
 COPY requirements.txt requirements.txt
@@ -16,6 +16,6 @@ RUN pip3 install -r requirements.txt
 
 COPY . .
 
-ADD . /app
+ADD . /home
 
 # CMD [ "python3", "app.py"]
diff --git a/docker_images/unitgrade-docker/home/cs103/Report3_handin_5_of_30.token b/docker_images/unitgrade-docker/home/cs103/Report3_handin_5_of_30.token
new file mode 100644
index 0000000000000000000000000000000000000000..a861bfbfbcc029d09e49a0a278598a0e2355ee66
GIT binary patch
literal 113733
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

literal 0
HcmV?d00001

diff --git a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/__pycache__/homework1.cpython-38.pyc b/docker_images/unitgrade-docker/home/cs103/__pycache__/homework1.cpython-38.pyc
similarity index 73%
rename from examples/example_docker/instructor/unitgrade-docker/tmp/cs103/__pycache__/homework1.cpython-38.pyc
rename to docker_images/unitgrade-docker/home/cs103/__pycache__/homework1.cpython-38.pyc
index 6403436716a672ff6c51a7026fc0edf847aa3213..d57142a7eeb21f6b172586b47613efbfeadc1082 100644
GIT binary patch
delta 32
ocmbQmKAW98l$V!_fq{X+Z?3^c?$?ZL68ahWxv86fGtOrO0C~&^&;S4c

delta 31
ncmbQuK8u|@l$V!_fq{X+^q<Z~?$?a0;`)gN1)Kjc&SwMwb(09I

diff --git a/docker_images/unitgrade-docker/home/cs103/__pycache__/report3_complete_grade.cpython-38.pyc b/docker_images/unitgrade-docker/home/cs103/__pycache__/report3_complete_grade.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..aa3a3187faae8d51a53e55a82bd75e0521299a19
GIT binary patch
literal 50864
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
OIXGDuSr}QEKq>*r9~HI$

literal 0
HcmV?d00001

diff --git a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/homework1.py b/docker_images/unitgrade-docker/home/cs103/homework1.py
similarity index 100%
rename from examples/example_docker/instructor/unitgrade-docker/tmp/cs103/homework1.py
rename to docker_images/unitgrade-docker/home/cs103/homework1.py
diff --git a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3.py b/docker_images/unitgrade-docker/home/cs103/report3.py
similarity index 74%
rename from examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3.py
rename to docker_images/unitgrade-docker/home/cs103/report3.py
index c97b5a4..f83bb53 100644
--- a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3.py
+++ b/docker_images/unitgrade-docker/home/cs103/report3.py
@@ -1,8 +1,8 @@
 """
 Example student code. This file is automatically generated from the files in the instructor-directory
 """
-from unitgrade2.unitgrade2 import UTestCase, Report, hide
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
+from src.unitgrade2.unitgrade2 import UTestCase, Report
+from src.unitgrade2 import evaluate_report_student
 
 class Week1(UTestCase):
     """ The first question for week 1. """
@@ -24,4 +24,6 @@ class Report3(Report):
     pack_imports = [cs103]
 
 if __name__ == "__main__":
+    # from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
+    # gather_upload_to_campusnet(Report3())
     evaluate_report_student(Report3())
diff --git a/docker_images/unitgrade-docker/home/cs103/report3_complete_grade.py b/docker_images/unitgrade-docker/home/cs103/report3_complete_grade.py
new file mode 100644
index 0000000..8ea5f2e
--- /dev/null
+++ b/docker_images/unitgrade-docker/home/cs103/report3_complete_grade.py
@@ -0,0 +1,338 @@
+
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+import inspect
+import os
+import argparse
+import time
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print(s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+        UTextResult.nL = report.nL
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f" * q{n+1})   Total"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+    print("")
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f" * {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.normpath(os.path.join(output_dir, token))
+
+
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single unmodified file: ")
+        print(">", token)
+        # print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            # print(self.questions)\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                print("q is", q())\n                q()._cache_put(\'time\', q.time) # = q.time\n                report_cache[q.__qualname__] = q._cache2\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            # self._stdout = sys.stdout\n            # sys._stdout = io.StringIO()\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f" * q{n+1})   Total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.normpath(os.path.join(output_dir, token))\n\n\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n    @hide\n    def test_add_hidden(self):\n        # This is a hidden test. The @hide-decorator will allow unitgrade to remove the test.\n        # See the output in the student directory for more information.\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n    @hide\n    def test_hidden_fail(self):\n        self.assertEqual(2,3)\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
+report1_payload = '80049589000000000000007d94288c055765656b31947d942868018c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b047568018c0f746573745f6164645f68696464656e948694680586947d944b004b04738c0474696d6594473fe3b8a400000000758c0d4175746f6d6174696350617373947d94680c473fc45a520000000073752e'
+name="Report3"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
\ No newline at end of file
diff --git a/docker_images/unitgrade-docker/home/cs103/report3_grade.py b/docker_images/unitgrade-docker/home/cs103/report3_grade.py
new file mode 100644
index 0000000..3c64c04
--- /dev/null
+++ b/docker_images/unitgrade-docker/home/cs103/report3_grade.py
@@ -0,0 +1,340 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+import inspect
+import os
+import argparse
+import time
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print(s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+        UTextResult.nL = report.nL
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f" * q{n+1})   Total"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+    print("")
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f" * {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.normpath(os.path.join(output_dir, token))
+
+
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single unmodified file: ")
+        print(">", token)
+        # print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            # print(self.questions)\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                print("q is", q())\n                q()._cache_put(\'time\', q.time) # = q.time\n                report_cache[q.__qualname__] = q._cache2\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            # self._stdout = sys.stdout\n            # sys._stdout = io.StringIO()\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f" * q{n+1})   Total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.normpath(os.path.join(output_dir, token))\n\n\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
+report1_payload = '80049568000000000000007d94288c055765656b31947d942868018c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b04758c0474696d6594473fb71ac800000000758c0d4175746f6d6174696350617373947d946808473fb127100000000073752e'
+name="Report3"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
diff --git a/examples/example_docker/instructor/unitgrade-docker/requirements.txt b/docker_images/unitgrade-docker/requirements.txt
similarity index 86%
rename from examples/example_docker/instructor/unitgrade-docker/requirements.txt
rename to docker_images/unitgrade-docker/requirements.txt
index 9db6120..0a73d68 100644
--- a/examples/example_docker/instructor/unitgrade-docker/requirements.txt
+++ b/docker_images/unitgrade-docker/requirements.txt
@@ -4,3 +4,4 @@ jinja2
 tabulate
 compress_pickle
 pyfiglet
+colorama
\ No newline at end of file
diff --git a/docker_images/unitgrade-docker/tmp/cs103/homework1.py b/docker_images/unitgrade-docker/tmp/cs103/homework1.py
new file mode 100644
index 0000000..3543f1b
--- /dev/null
+++ b/docker_images/unitgrade-docker/tmp/cs103/homework1.py
@@ -0,0 +1,21 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+def reverse_list(mylist): 
+    """
+    Given a list 'mylist' returns a list consisting of the same elements in reverse order. E.g.
+    reverse_list([1,2,3]) should return [3,2,1] (as a list).
+    """
+    # TODO: 1 lines missing.
+    raise NotImplementedError("Implement function body")
+
+def add(a,b): 
+    """ Given two numbers `a` and `b` this function should simply return their sum:
+    > add(a,b) = a+b """
+    # TODO: 1 lines missing.
+    raise NotImplementedError("Implement function body")
+
+if __name__ == "__main__":
+    # Problem 1: Write a function which add two numbers
+    print(f"Your result of 2 + 2 = {add(2,2)}")
+    print(f"Reversing a small list", reverse_list([2,3,5,7]))
diff --git a/docker_images/unitgrade-docker/tmp/cs103/report3.py b/docker_images/unitgrade-docker/tmp/cs103/report3.py
new file mode 100644
index 0000000..f83bb53
--- /dev/null
+++ b/docker_images/unitgrade-docker/tmp/cs103/report3.py
@@ -0,0 +1,29 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+from src.unitgrade2.unitgrade2 import UTestCase, Report
+from src.unitgrade2 import evaluate_report_student
+
+class Week1(UTestCase):
+    """ The first question for week 1. """
+    def test_add(self):
+        from cs103.homework1 import add
+        self.assertEqualC(add(2,2))
+        self.assertEqualC(add(-100, 5))
+
+
+class AutomaticPass(UTestCase):
+    def test_student_passed(self):
+        self.assertEqual(2,2)
+
+
+import cs103
+class Report3(Report):
+    title = "CS 101 Report 3"
+    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.
+    pack_imports = [cs103]
+
+if __name__ == "__main__":
+    # from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
+    # gather_upload_to_campusnet(Report3())
+    evaluate_report_student(Report3())
diff --git a/docker_images/unitgrade-docker/tmp/cs103/report3_complete_grade.py b/docker_images/unitgrade-docker/tmp/cs103/report3_complete_grade.py
new file mode 100644
index 0000000..1101b26
--- /dev/null
+++ b/docker_images/unitgrade-docker/tmp/cs103/report3_complete_grade.py
@@ -0,0 +1,338 @@
+
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+import inspect
+import os
+import argparse
+import time
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print(s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+        UTextResult.nL = report.nL
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f" * q{n+1})   Total"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+    print("")
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f" * {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.normpath(os.path.join(output_dir, token))
+
+
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single unmodified file: ")
+        print(">", token)
+        # print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            # print(self.questions)\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                print("q is", q())\n                q()._cache_put(\'time\', q.time) # = q.time\n                report_cache[q.__qualname__] = q._cache2\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            # self._stdout = sys.stdout\n            # sys._stdout = io.StringIO()\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f" * q{n+1})   Total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.normpath(os.path.join(output_dir, token))\n\n\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n    @hide\n    def test_add_hidden(self):\n        # This is a hidden test. The @hide-decorator will allow unitgrade to remove the test.\n        # See the output in the student directory for more information.\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n    @hide\n    def test_hidden_fail(self):\n        self.assertEqual(2,3)\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
+report1_payload = '80049589000000000000007d94288c055765656b31947d942868018c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b047568018c0f746573745f6164645f68696464656e948694680586947d944b004b04738c0474696d6594473fda6e8700000000758c0d4175746f6d6174696350617373947d94680c473fb8d5140000000073752e'
+name="Report3"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
\ No newline at end of file
diff --git a/docker_images/unitgrade-docker/tmp/cs103/report3_grade.py b/docker_images/unitgrade-docker/tmp/cs103/report3_grade.py
new file mode 100644
index 0000000..85573c9
--- /dev/null
+++ b/docker_images/unitgrade-docker/tmp/cs103/report3_grade.py
@@ -0,0 +1,340 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+import inspect
+import os
+import argparse
+import time
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print(s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+        UTextResult.nL = report.nL
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f" * q{n+1})   Total"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+    print("")
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f" * {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.normpath(os.path.join(output_dir, token))
+
+
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single unmodified file: ")
+        print(">", token)
+        # print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            # print(self.questions)\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                print("q is", q())\n                q()._cache_put(\'time\', q.time) # = q.time\n                report_cache[q.__qualname__] = q._cache2\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            # self._stdout = sys.stdout\n            # sys._stdout = io.StringIO()\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f" * q{n+1})   Total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.normpath(os.path.join(output_dir, token))\n\n\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
+report1_payload = '80049568000000000000007d94288c055765656b31947d942868018c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b04758c0474696d6594473fb1eb1c00000000758c0d4175746f6d6174696350617373947d946808473fa78d300000000073752e'
+name="Report3"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
diff --git a/examples/02471/instructor/02471/report1.py b/examples/02471/instructor/02471/report1.py
index 1ed131f..96bb952 100644
--- a/examples/02471/instructor/02471/report1.py
+++ b/examples/02471/instructor/02471/report1.py
@@ -114,7 +114,7 @@ if __name__ == "__main__":
 
     # from week02 import Week_2_sol
     import importnb
-    file = "week02/week2.ipynb"
+    file = "../../../example_jupyter/instructor/cs105/week2.ipynb"
     file2 = 'week02/Week_2_sol.ipynb'
     m = importnb.Notebook.load(file)
     # importnb.Notebook.l
diff --git a/examples/02631/instructor/programs/.coverage b/examples/02631/instructor/programs/.coverage
new file mode 100644
index 0000000000000000000000000000000000000000..11b2ec620c9b142ae8ee79c7a6f5afa297121530
GIT binary patch
literal 53248
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

literal 0
HcmV?d00001

diff --git a/examples/02631/instructor/programs/__pycache__/looping.cpython-38.pyc b/examples/02631/instructor/programs/__pycache__/looping.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fa302e5a102c505ba4b62aa5eab3205ca2683298
GIT binary patch
literal 2019
zcmWIL<>g{vU|@KAPd`zBoq^#oh=YuI7#J8F7#J9elNcBnQW#Pga~Pr+!8B78QwmcG
za|=Tha|%leYYRgZOA1>GdkaGpYYImSXA46VTPk}BS2j~oTq;K@YbxUc&J^wxo)q2`
zz7+lxffT_Mp>&Rgj48q?BF)UrjEoE^jKK_=qAx+V`z5o0C@5xSU|?WlU|?_txx<Zt
zfuV+>hB=$1hzF#jgkb^WLIxLxSdChi6s8)+6s8)68YXE52?h}cafTWO5r$frdJ#s3
zLc2nd8kQ6$afV<9P3EeHTnY*b3eJf+$)!1oC8-J}nYpP7rFkWpISNUM$t9^pnTZPN
zMfv3=849Tt$*HL+3VsU3C5c5PnR)37X+`<D3W*8@`2`@&nfZAN`DqGy25_BvV8b&q
z^Gb@Xz)X-`S_;YedBvG2sYMET21ufbIRzPs3U&$*F{^^aqQqQ<JOhYEC>N{-MZ_D0
z=Lh8#rIwTy<v}<_j0_A6FF}MR(=E=-lGLJ-{QR8aTdc|XrFkWqthbo*3~sT4O}@qG
zeT&iW7Guduh9Xd+_!aJK6%$&VT2vfUQksz(<C33Tnwy$eQXEs7msyftl$eqlUr>};
zmROP+lUk9OTac4l9AjW)W^5RfnO9s=RGM6pUldbNl%HOdm|Gl^lb>IZnU}6tP<e|F
z7P#)<um#0+F&`+hc{mtZ7<m{a7&#c(7>ht@FB#-?kQ4}m6mq~4!VCrm22kYJFf3%O
z1+kb)m}?lC85c69Fp4pxFl95<GJ@nw7#6V9Fw`*eGe|Nl1c`uoAa**_LdIIA5{4|+
z5{3nAHK63p&<f(Sr!h$~)PPwj3@Hq)Od!4l!$L+-g70Mlo6TIpQNvurn9bD8SkzTG
zp@zAZu}}e&{J=?z#qT8(0|P@5h|pxb#gbT&S**!<iz%<*7JFiGVo_0I<t?_vqQt!P
z)LYCssd=|pa#IuYKtk!cnR&OE6O)Q>vFD|hgY?~EPRz;CWQpP~N=?g2O)g2yOHPeq
z@-)1~m>b3HX&4WVEC|8Pz`$^eKRKtgxFog6F)uNvvN*F?0+ek8K;g&8#VE$4!f3(B
z!^i{*U`YlBhGb@t3>1Udpxg$ci>06e+|JO>n8uXCn8MV;QN!Q@4q{O5@k5ClkWWEc
zg+aDyFfcHrGt@A|D%3J|Fw`)zFfcP@GZe{mFlI9pvE;EZG8D4ZFivDDWC@0(HL&wF
znQk%Z8QfwlTFG>aD<{7^wa6*IG%w{AS7|{3lnqu_1okGEO-^QUNpgN}ft@PIPEe9%
zV_;%nV&G!nVW?6`ODzJW*2I#`{JfyVl2kpLoc!d(oMJmYghoxKB7RUbfgG*L9L1BH
znpj*~l$rukUnC2XkpmGRql;ufEU?W2=te7p><0w^15=R#C`^$PEhsEO0Ry6o{h(nA
zNwnz<wTvZ9phWA!5UUfzRLj)KP{Q2Kkj97{+Rcn9%-KvuVl|8lSUMOMGBPq0ih&Y#
z4dX&kiOEuBr{IAoWV94Q60=hk5*2dt^RpEaOB6~nQWc=tQz0`C%1tdw&MZ!alu)>%
z5#$$eG)jQ7QVnA>V+lhCLo;JGQxR(PX)@ko&de*(WGVtBnp=z&D;aMwmLVdmNS=X#
z!4MQmpmH1(O9Bj4Dn+Te`DLk|d7wDVNyQ#RFG0bk$qI=kP$Is?nVMIcn_84ul3FAL
zO73il1qG>jDVof;m@-qMm@`w1ZZT#;tOmskB(Vsf+oc6^45)x%VBun9VH9ALV&q{g
z0*T(@h>y=r%*>0APoFh&=FFLrCJyOm&zw1P#>dzJA~N%%eY!Ci7&$-~n~fdP(?Gy2
z4yM?|Asv#bOdMW<(%4H-X4B-l#hO=|TTlt{56ExeQmzOj2~Ik2C*&pOrpCwLVl61j
w%qzLY3NA7rz5=I4Fab`D95%W6DWy57cA!KDE=D;RIhZ&^IJi03Ie0i&0HrYEG5`Po

literal 0
HcmV?d00001

diff --git a/examples/02631/instructor/programs/__pycache__/report1intro.cpython-38.pyc b/examples/02631/instructor/programs/__pycache__/report1intro.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ddadca6243eeebd021c63d8d875e9092033e1190
GIT binary patch
literal 7198
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
D4<0BP

literal 0
HcmV?d00001

diff --git a/examples/02631/instructor/programs/deploy.py b/examples/02631/instructor/programs/deploy.py
new file mode 100644
index 0000000..6099792
--- /dev/null
+++ b/examples/02631/instructor/programs/deploy.py
@@ -0,0 +1,62 @@
+from report1intro import Report1Flat
+from unitgrade_private2.hidden_create_files import setup_grade_file_report
+from snipper import snip_dir
+
+if __name__ == "__main__":
+    setup_grade_file_report(Report1Flat, minify=False, obfuscate=False, execute=False, with_coverage=True)
+
+    # from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
+    # gather_upload_to_campusnet((Report1Flat()))
+
+    # Deploy the files using snipper: https://gitlab.compute.dtu.dk/tuhe/snipper
+    snip_dir.snip_dir(source_dir="", dest_dir="../../students/programs", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
+
+    import os
+    os.system("python report1intro_grade.py")
+
+
+"""
+from coverage import CoverageData
+import coverage
+cov2 = coverage.Coverage()
+
+    def setUp(self):
+        import trace
+        self.cov = cov2
+        self.cov.start()
+
+
+
+        # self.tracer.start()
+
+        # using obj_to_trace
+
+    def tearDown(self) -> None:
+
+        self.cov.stop()
+        print()
+
+        data = CoverageData()
+
+        # data.measured_files()
+        # data.lines()
+        data = self.cov.get_data()
+        # data.
+        for file in data.measured_files():
+            print(file)
+            print(data.lines(file))
+            print(data.arcs(file))
+            print(        data.contexts_by_lineno(file))
+
+            # print(data[file])
+
+
+
+- Idea: Measure coverage in setup/teardown. This gives a handful of covered lines. 
+- During setup, supply a dicionary to UTestCase of files, along with the lines that are removed. 
+- When running setup: Take the coverage report, and compare against files. Write functions/lines encountered to the cache dictionary. Rquires you to 
+- inspect the functions that are edited to figure out what is removed. This can probably be done by going upwars towards the first sensible class or function definition (which has not been removed).
+- Supply a dictionary to UTestCase of files, along with the lines edited. Allow UTestCase to write this information to the 
+  cache dictionary (i.e. lines removed). Then use this information when displaying helpful hints later. 
+
+"""
\ No newline at end of file
diff --git a/examples/02631/instructor/programs/looping.py b/examples/02631/instructor/programs/looping.py
new file mode 100644
index 0000000..59a1485
--- /dev/null
+++ b/examples/02631/instructor/programs/looping.py
@@ -0,0 +1,64 @@
+import numpy as np
+import itertools
+
+def bacteriaGrowth(n0, alpha, K, N): #!f
+    """
+    Calculate time until bacteria growth exceed N starting from a population of n0 bacteria.
+    hints:
+        * consider n0
+        * alpha > 0
+    :param n0:
+    :param alpha:
+    :param K:
+    :param N:
+    :return:
+    """
+    if n0 > N:
+        return 0
+    for t in itertools.count():
+        n0 = (1 + alpha * (1-n0 / K) ) * n0
+        if n0 > N:
+            break
+    return t+1
+
+def clusterAnalysis(reflectance):
+    reflectance = np.asarray(reflectance)
+    I1 = np.arange(len(reflectance)) % 2 == 1
+    while True:
+        m = np.asarray( [np.mean( reflectance[~I1] ),  np.mean( reflectance[I1] ) ] )
+        I1_ = np.argmin( np.abs( reflectance[:, np.newaxis] - m[np.newaxis, :] ), axis=1) == 1
+        if all(I1_ == I1):
+            break
+        I1 = I1_
+    return I1 + 1
+
+def fermentationRate(measuredRate, lowerBound, upperBound):
+    # Insert your code here
+    return np.mean( [r for r in measuredRate if lowerBound < r < upperBound] )
+
+
+
+
+def removeIncomplete(id):
+    """ Hints:
+    * Take a look at the example in the exercise.
+    """
+    id = np.asarray(id)
+    id2 = []
+    for i, v in enumerate(id):
+        if len( [x for x in id if int(x) == int(v) ] ) == 3:
+            id2.append(v)
+    return np.asarray(id2)
+
+
+if __name__ == "__main__":
+    # I = clusterAnalysis([1.7, 1.6, 1.3, 1.3, 2.8, 1.4, 2.8, 2.6, 1.6, 2.7])
+    # print(I)
+
+    print(fermentationRate(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 15, 25))
+
+
+    # print(removeIncomplete(np.array([1.3, 2.2, 2.3, 4.2, 5.1, 3.2, 5.3, 3.3, 2.1, 1.1, 5.2, 3.1])))
+
+    # Problem 1: Write a function which add two numbers
+    # clusterAnalysis([2, 1, 2, 4, 5])
\ No newline at end of file
diff --git a/examples/02631/instructor/programs/report1intro.py b/examples/02631/instructor/programs/report1intro.py
new file mode 100644
index 0000000..10b1898
--- /dev/null
+++ b/examples/02631/instructor/programs/report1intro.py
@@ -0,0 +1,139 @@
+from src.unitgrade2.unitgrade2 import Report, UTestCase, cache
+from src.unitgrade2 import evaluate_report_student
+import numpy as np
+import looping
+from looping import bacteriaGrowth, clusterAnalysis, removeIncomplete, fermentationRate
+
+def trlist(x):
+    s = str(list(x))
+    if len(s) > 30:
+        s = s[:30] + "...]"
+    return s
+
+class Bacteria(UTestCase):
+    """ Bacteria growth rates """
+
+    def stest(self, n0, alpha, K, N):
+        g = bacteriaGrowth(n0=n0, alpha=alpha, K=K, N=N)
+        self.title = f"bacteriaGrowth({n0}, {alpha}, {K}, {N}) = {g} ?"
+        self.assertEqualC(g)
+
+    def test_growth1(self):
+        """ Hints:
+        * Make sure to frobulate the frobulator.
+        """
+        self.stest(100, 0.4, 1000, 500)
+
+    def test_growth2(self):
+        self.stest(10, 0.4, 1000, 500)
+
+    def test_growth3(self):
+        self.stest(100, 1.4, 1000, 500)
+
+    def test_growth4(self):
+        self.stest(100, 0.0004, 1000, 500)
+
+    def test_growth5(self):
+        """
+        hints:
+        * What happens when n0 > N? (in this case return t=0) """
+        self.stest(100, 0.4, 1000, 99)
+
+class ClusterAnalysis(UTestCase):
+    """ Test the cluster analysis method """
+
+    def stest(self, n, seed):
+        np.random.seed(seed)
+        x = np.round(np.random.rand(n), 1)
+        I = clusterAnalysis(x)
+        self.title = f"clusterAnalysis({list(x)}) = {list(I)} ?"
+        self.assertEqualC(list(I))
+
+    def test_cluster1(self):
+        """ Hints:
+        * Make sure to frobulate the frobulator.
+        * Just try harder
+        """
+        self.stest(3, 10)
+
+    def test_cluster2(self):
+        self.stest(4, 146)
+
+    def test_cluster3(self):
+        self.stest(5, 12)
+
+    def test_cluster4(self):
+        """
+        Cluster analysis for tied lists
+        Hints:
+        * It may be that an observations has the same distance to the two clusters. Where do you assign it in this case?
+        """
+        x = np.array([10.0, 12.0, 10.0, 12.0, 9.0, 11.0, 11.0, 13.0])
+        self.assertEqualC(list(clusterAnalysis(x) ) )
+
+
+class RemoveIncomplete(UTestCase):
+    """ Remove incomplete IDs """
+
+    def stest(self, x):
+        I = list( removeIncomplete(x) )
+        self.title = f"removeId({trlist(x)}) = {trlist(I)} ?"
+        self.assertEqualC(I)
+
+    @cache
+    def rseq(self, max, n):
+        np.random.seed(42)
+        return np.random.randint(max, size=(n,) ) + (np.random.randint(2, size=(n,) )+1)/10
+
+    def test_incomplete1(self):
+        self.stest( np.array([1.3, 2.2, 2.3, 4.2, 5.1, 3.2, 5.3, 3.3, 2.1, 1.1, 5.2, 3.1]) )
+
+    def test_incomplete2(self):
+        self.stest( np.array([1.1, 1.2, 1.3, 2.1, 2.2, 2.3]) )
+
+    def test_incomplete3(self):
+        self.stest(np.array([5.1, 5.2, 4.1, 4.3, 4.2, 8.1, 8.2, 8.3]) )
+
+    def test_incomplete4(self):
+        self.stest(np.array([1.1, 1.3, 2.1, 2.2, 3.1, 3.3, 4.1, 4.2, 4.3]) )
+
+    def test_incomplete5(self):
+        self.stest(self.rseq(10, 40))
+
+
+class FermentationRate(UTestCase):
+    """ Test the fermentation rate question """
+
+    def stest(self, x, lower, upper):
+        I =  fermentationRate(x, lower, upper)
+        s = trlist(x)
+        self.title = f"fermentationRate({s}, {lower}, {upper}) = {I:.3f} ?"
+        self.assertEqualC(I)
+
+    @cache
+    def rseq(self, max, n):
+        np.random.seed(42)
+        return np.random.randint(max, size=(n,) ) + (np.random.randint(3, size=(n,) )+1)/n
+
+    def test_rate1(self):
+        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 15, 25)
+
+    def test_rate2(self):
+        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 1, 200)
+
+    def test_rate3(self):
+        self.stest(np.array([1.75]), 1, 2)
+
+    def test_rate4(self):
+        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 18.2, 20)
+
+
+class Report1Flat(Report):
+    title = "Week 4: Looping"
+    questions = [(ClusterAnalysis, 10), (RemoveIncomplete, 10), (Bacteria, 10),  (FermentationRate, 10),]
+    pack_imports = [looping]
+
+if __name__ == "__main__":
+    # Uncomment to simply run everything as a unittest:
+    # unittest.main(verbosity=2)
+    evaluate_report_student(Report1Flat())
diff --git a/examples/02631/instructor/programs/report1intro_grade.py b/examples/02631/instructor/programs/report1intro_grade.py
new file mode 100644
index 0000000..4381d55
--- /dev/null
+++ b/examples/02631/instructor/programs/report1intro_grade.py
@@ -0,0 +1,337 @@
+
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+import inspect
+import os
+import argparse
+import time
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print(s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    # nL =
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+        UTextResult.nL = report.nL
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f"Question {n+1} total"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+    print("")
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f" * {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.join(output_dir, token)
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single unmodified file: ")
+        print(">", token)
+        # print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        return Capturing2(stdout=self._stdout)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    # nL =\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"Question {n+1} total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nimport numpy as np\nimport looping\nfrom looping import bacteriaGrowth, clusterAnalysis, removeIncomplete, fermentationRate\n\ndef trlist(x):\n    s = str(list(x))\n    if len(s) > 30:\n        s = s[:30] + "...]"\n    return s\n\nclass Bacteria(UTestCase):\n    """ Bacteria growth rates """\n\n    def stest(self, n0, alpha, K, N):\n        g = bacteriaGrowth(n0=n0, alpha=alpha, K=K, N=N)\n        self.title = f"bacteriaGrowth({n0}, {alpha}, {K}, {N}) = {g} ?"\n        self.assertEqualC(g)\n\n    def test_growth1(self):\n        """ Hints:\n        * Make sure to frobulate the frobulator.\n        """\n        self.stest(100, 0.4, 1000, 500)\n\n    def test_growth2(self):\n        self.stest(10, 0.4, 1000, 500)\n\n    def test_growth3(self):\n        self.stest(100, 1.4, 1000, 500)\n\n    def test_growth4(self):\n        self.stest(100, 0.0004, 1000, 500)\n\n    def test_growth5(self):\n        """\n        hints:\n        * What happens when n0 > N? (in this case return t=0) """\n        self.stest(100, 0.4, 1000, 99)\n\nclass ClusterAnalysis(UTestCase):\n    """ Test the cluster analysis method """\n\n    def stest(self, n, seed):\n        np.random.seed(seed)\n        x = np.round(np.random.rand(n), 1)\n        I = clusterAnalysis(x)\n        self.title = f"clusterAnalysis({list(x)}) = {list(I)} ?"\n        self.assertEqualC(list(I))\n\n    def test_cluster1(self):\n        """ Hints:\n        * Make sure to frobulate the frobulator.\n        * Just try harder\n        """\n        self.stest(3, 10)\n\n    def test_cluster2(self):\n        self.stest(4, 146)\n\n    def test_cluster3(self):\n        self.stest(5, 12)\n\n    def test_cluster4(self):\n        """\n        Cluster analysis for tied lists\n        Hints:\n        * It may be that an observations has the same distance to the two clusters. Where do you assign it in this case?\n        """\n        x = np.array([10.0, 12.0, 10.0, 12.0, 9.0, 11.0, 11.0, 13.0])\n        self.assertEqualC(list(clusterAnalysis(x) ) )\n\n\nclass RemoveIncomplete(UTestCase):\n    """ Remove incomplete IDs """\n\n    def stest(self, x):\n        I = list( removeIncomplete(x) )\n        self.title = f"removeId({trlist(x)}) = {trlist(I)} ?"\n        self.assertEqualC(I)\n\n    @cache\n    def rseq(self, max, n):\n        np.random.seed(42)\n        return np.random.randint(max, size=(n,) ) + (np.random.randint(2, size=(n,) )+1)/10\n\n    def test_incomplete1(self):\n        self.stest( np.array([1.3, 2.2, 2.3, 4.2, 5.1, 3.2, 5.3, 3.3, 2.1, 1.1, 5.2, 3.1]) )\n\n    def test_incomplete2(self):\n        self.stest( np.array([1.1, 1.2, 1.3, 2.1, 2.2, 2.3]) )\n\n    def test_incomplete3(self):\n        self.stest(np.array([5.1, 5.2, 4.1, 4.3, 4.2, 8.1, 8.2, 8.3]) )\n\n    def test_incomplete4(self):\n        self.stest(np.array([1.1, 1.3, 2.1, 2.2, 3.1, 3.3, 4.1, 4.2, 4.3]) )\n\n    def test_incomplete5(self):\n        self.stest(self.rseq(10, 40))\n\n\nclass FermentationRate(UTestCase):\n    """ Test the fermentation rate question """\n\n    def stest(self, x, lower, upper):\n        I =  fermentationRate(x, lower, upper)\n        s = trlist(x)\n        self.title = f"fermentationRate({s}, {lower}, {upper}) = {I:.3f} ?"\n        self.assertEqualC(I)\n\n    @cache\n    def rseq(self, max, n):\n        np.random.seed(42)\n        return np.random.randint(max, size=(n,) ) + (np.random.randint(3, size=(n,) )+1)/n\n\n    def test_rate1(self):\n        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 15, 25)\n\n    def test_rate2(self):\n        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 1, 200)\n\n    def test_rate3(self):\n        self.stest(np.array([1.75]), 1, 2)\n\n    def test_rate4(self):\n        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 18.2, 20)\n\n\nclass Report1Flat(Report):\n    title = "Week 4: Looping"\n    questions = [(ClusterAnalysis, 10), (RemoveIncomplete, 10), (Bacteria, 10),  (FermentationRate, 10),]\n    pack_imports = [looping]'
+report1_payload = '80049592150000000000007d94288c0f436c7573746572416e616c79736973947d94288c0f436c7573746572416e616c79736973948c0d746573745f636c7573746572319486948c057469746c659486948c2e636c7573746572416e616c79736973285b302e382c20302e302c20302e365d29203d205b312c20322c20315d203f946803680486948c066173736572749486947d944b005d94288c156e756d70792e636f72652e6d756c74696172726179948c067363616c61729493948c056e756d7079948c0564747970659493948c02693494898887945294284b038c013c944e4e4e4affffffff4affffffff4b007494624304010000009486945294681068164304020000009486945294681068164304010000009486945294657368038c0d746573745f636c757374657232948694680686948c36636c7573746572416e616c79736973285b302e352c20302e362c20302e332c20302e335d29203d205b322c20322c20312c20315d203f94680368228694680a86947d944b005d9428681068164304020000009486945294681068164304020000009486945294681068164304010000009486945294681068164304010000009486945294657368038c0d746573745f636c757374657233948694680686948c3e636c7573746572416e616c79736973285b302e322c20302e372c20302e332c20302e352c20302e305d29203d205b312c20322c20312c20322c20315d203f94680368368694680a86947d944b005d9428681068164304010000009486945294681068164304020000009486945294681068164304010000009486945294681068164304020000009486945294681068164304010000009486945294657368038c0d746573745f636c757374657234948694680a86947d944b005d942868106816430401000000948694529468106816430402000000948694529468106816430401000000948694529468106816430402000000948694529468106816430401000000948694529468106816430401000000948694529468106816430401000000948694529468106816430402000000948694529465738c0474696d6594473fdf6c8500000000758c1052656d6f7665496e636f6d706c657465947d94288c1052656d6f7665496e636f6d706c657465948c10746573745f696e636f6d706c657465319486948c057469746c659486948c5372656d6f76654964285b312e332c20322e322c20322e332c20342e322c20352e312c20332e322c2e2e2e5d29203d205b322e322c20322e332c20352e312c20332e322c20352e332c20332e332c2e2e2e5d203f94686d686e86948c066173736572749486947d944b005d9428681068138c02663894898887945294284b0368174e4e4e4affffffff4affffffff4b0074946243089a9999999999014094869452946810687a4308666666666666024094869452946810687a4308666666666666144094869452946810687a43089a9999999999094094869452946810687a4308333333333333154094869452946810687a43086666666666660a4094869452946810687a4308cdcccccccccc004094869452946810687a4308cdcccccccccc144094869452946810687a4308cdcccccccccc084094869452946573686d8c10746573745f696e636f6d706c65746532948694687086948c4b72656d6f76654964285b312e312c20312e322c20312e332c20322e312c20322e322c20322e335d29203d205b312e312c20312e322c20312e332c20322e312c20322e322c20322e335d203f94686d68978694687486947d944b005d94286810687a43089a9999999999f13f94869452946810687a4308333333333333f33f94869452946810687a4308cdccccccccccf43f94869452946810687a4308cdcccccccccc004094869452946810687a43089a9999999999014094869452946810687a4308666666666666024094869452946573686d8c10746573745f696e636f6d706c65746533948694687086948c4f72656d6f76654964285b352e312c20352e322c20342e312c20342e332c20342e322c20382e312c2e2e2e5d29203d205b342e312c20342e332c20342e322c20382e312c20382e322c20382e335d203f94686d68b18694687486947d944b005d94286810687a4308666666666666104094869452946810687a4308333333333333114094869452946810687a4308cdcccccccccc104094869452946810687a4308333333333333204094869452946810687a4308666666666666204094869452946810687a43089a9999999999204094869452946573686d8c10746573745f696e636f6d706c65746534948694687086948c4072656d6f76654964285b312e312c20312e332c20322e312c20322e322c20332e312c20332e332c2e2e2e5d29203d205b342e312c20342e322c20342e335d203f94686d68cb8694687486947d944b005d94286810687a4308666666666666104094869452946810687a4308cdcccccccccc104094869452946810687a4308333333333333114094869452946573686d8c10746573745f696e636f6d706c657465359486948c06406361636865948c0472736571948c0966756e63746f6f6c73948c0a5f486173686564536571949394298194284b0a4b28654e7d948c096861736876616c7565948a0884d8ef03874d7f467386946287948694680e8c0c5f7265636f6e73747275637494939468118c076e6461727261799493944b0085944301629487945294284b014b28859468138c02663894898887945294284b0368174e4e4e4affffffff4affffffff4b0074946289424001000066666666666618409a99999999990940cdcccccccccc1c40cdcccccccccc1040cdcccccccccc184033333333333322409a999999999901406666666666661840cdcccccccccc1c40cdcccccccccc10409a999999999909406666666666661c40cdcccccccccc1c40cdcccccccccc0040cdcccccccccc14406666666666661040333333333333f33f6666666666661c406666666666661440333333333333f33f66666666666610409a9999999999c93f6666666666662240cdcccccccccc144066666666666620409a9999999999c93f66666666666622409a99999999990140cdcccccccccc18409a9999999999094066666666666620409a999999999901406666666666661040cdcccccccccc0040cdcccccccccc1840cdcccccccccc10406666666666662040cdcccccccccc1840333333333333f33f9a9999999999094094749462686d68dc8694687086948c5372656d6f76654964285b362e312c20332e322c20372e322c20342e322c20362e322c20392e312c2e2e2e5d29203d205b392e312c20352e322c20312e322c20352e312c20312e322c20392e322c2e2e2e5d203f94686d68dc8694687486947d944b005d94286810687a4308333333333333224094869452946810687a4308cdcccccccccc144094869452946810687a4308333333333333f33f94869452946810687a4308666666666666144094869452946810687a4308333333333333f33f94869452946810687a4308666666666666224094869452946810687a4308cdcccccccccc144094869452946810687a4308666666666666204094869452946810687a4308666666666666224094869452946810687a4308666666666666204094869452946810687a4308666666666666204094869452946810687a4308333333333333f33f94869452946573686a473fcf9dc400000000758c084261637465726961947d94288c084261637465726961948c0c746573745f67726f777468319486948c057469746c659486948c29626163746572696147726f777468283130302c20302e342c20313030302c2035303029203d2037203f946a250100006a2601000086948c066173736572749486947d944b004b07736a250100006a2601000086948c08636f7665726167659486947d94286a250100006a2601000086947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b158ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a2020202022222294869473736a250100008c0c746573745f67726f777468329486947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b158ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a2020202022222294869473736a250100008c0c746573745f67726f777468339486947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b158ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a2020202022222294869473736a250100008c0c746573745f67726f777468349486947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b158ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a2020202022222294869473736a250100008c0c746573745f67726f777468359486947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b118ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a202020202222229486947373756a250100006a3a01000086946a2801000086948c29626163746572696147726f7774682831302c20302e342c20313030302c2035303029203d203134203f946a250100006a3a01000086946a2c01000086947d944b004b0e736a250100006a3a01000086946a3001000086946a320100006a250100006a4201000086946a2801000086948c29626163746572696147726f777468283130302c20312e342c20313030302c2035303029203d2033203f946a250100006a4201000086946a2c01000086947d944b004b03736a250100006a4201000086946a3001000086946a320100006a250100006a4a01000086946a2801000086948c2f626163746572696147726f777468283130302c20302e303030342c20313030302c2035303029203d2035343934203f946a250100006a4a01000086946a2c01000086947d944b004d7615736a250100006a4a01000086946a3001000086946a320100006a250100006a5201000086946a2801000086948c28626163746572696147726f777468283130302c20302e342c20313030302c20393929203d2030203f946a250100006a5201000086946a2c01000086947d944b004b00736a250100006a5201000086946a3001000086946a32010000686a473fcf9d9a00000000758c104665726d656e746174696f6e52617465947d94288c104665726d656e746174696f6e52617465948c0a746573745f72617465319486948c057469746c659486948c476665726d656e746174696f6e52617465285b32302e312c2031392e332c20312e312c2031382e322c2031392e372c202e2e2e5d2c2031352c20323529203d2031392e363030203f946a7c0100006a7d01000086948c066173736572749486947d944b006810687a43089a999999999933409486945294736a7c0100008c0a746573745f72617465329486946a7f01000086948c476665726d656e746174696f6e52617465285b32302e312c2031392e332c20312e312c2031382e322c2031392e372c202e2e2e5d2c20312c2032303029203d2032392e393735203f946a7c0100006a8901000086946a8301000086947d944b006810687a43089899999999f93d409486945294736a7c0100008c0a746573745f72617465339486946a7f01000086948c286665726d656e746174696f6e52617465285b312e37355d2c20312c203229203d20312e373530203f946a7c0100006a9301000086946a8301000086947d944b006810687a4308000000000000fc3f9486945294736a7c0100008c0a746573745f72617465349486946a7f01000086948c496665726d656e746174696f6e52617465285b32302e312c2031392e332c20312e312c2031382e322c2031392e372c202e2e2e5d2c2031382e322c20323029203d2031392e353030203f946a7c0100006a9d01000086946a8301000086947d944b006810687a43080000000000803340948694529473686a473fc74c0a0000000075752e'
+name="Report1Flat"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
\ No newline at end of file
diff --git a/examples/02631/instructor/programs/unitgrade/Bacteria.pkl b/examples/02631/instructor/programs/unitgrade/Bacteria.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..b246df45c63387d95bc69cc26deba7770d8249c5
GIT binary patch
literal 2050
zcmZo*nfjfb0Ss!VX!LM6B_@}o7G)+*>ES6!EiQ>qFUl`3$uOMKHl>HPB(o$Z6~xj^
zf~s-{%W4=J80aV%=$Ys!7#e_>rUnL@3bqR73ieYn7&DmKru48S78j=$l}u@yQai<)
z!JEApD$bFdUzS>wm<}?wc8Uf>w024lS5AI@L1tdMUP0xQ+9^G%DXD1+XqM&~=qM!S
z6l5goD0u5A_-R@xOz{@&d9I|S#HFC1px~UClU$mUSdywxl9`*TP?}egnFBXM0pcx%
z)QaTP)D#6jh2oOLqLR$KbcM8{{9J`Zg@XJ7kmk(%Jcax;g**eePCc;U8JT${#a3V@
z$Sy5~<ovwi%#_q3g**c!QLytA>=YnkRt1SgiMa}S1`v%<E?5nUh&Kw)56UY_Eh#O^
zgK(6Tl%}*zDK5@nM2RIMaPW?Xoq_^1Y)J?^<I%7qJKdR#h8@{qXG&4n368Att~7%&
zL#%B|220zN9?UujTNPwz0;z*Qx;UVf4<D%V0SWN5P08TPV9b!iX{3RUf+0q=W(+YB
zqzh&wGssAg0L(}=sFC_;l@_$7G%zqguPjYXETL`%>4h5XTP6xJ86*NTSr2Nm26mI-
c##&l}s$c_%TS1zjMtU=VOauvlO)S*|044x_qW}N^

literal 0
HcmV?d00001

diff --git a/examples/02631/instructor/programs/unitgrade/ClusterAnalysis.pkl b/examples/02631/instructor/programs/unitgrade/ClusterAnalysis.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..36635371f6e86d5f841a3827696a5909e766532b
GIT binary patch
literal 763
zcmZo*nfif=0Ss!VX!P(q=ad$gq!u~mCFWEXXBJQC;VnrmE{RWu2pdjmo6^Htl39|I
z3S#L&g<+~Sq7C#cbQBEq3_yfgtfqpkLbRcdf{~7bVXT7vlnllUrnV_PY>CCisYNAI
z+NRV_@n(pfqR}IoSDIT;sh6Bzl&Y6onp2XQSX7i)Ii-iKI5{yVv1rQVDLt%UB~yA>
zQ%WieQb8h2nI=;@JKCoNP0{dX?qRf<;^*h*_5c6>|6szKp=3&uGYcaF1H+WIDM3>*
z_%cMCSwLPz;=*N9i!&Hey=pY2ZAu19+ms$NES@w4`wv7Ig9(UFjUYZncvhipN(Kkq
zmsnkZ%Rvyuc-&_UbDtd+_Zfj)Wey_1?gKm50OCk!bU>U6jT93s?u1(naS48R;*!M-
aRuho3(Zhr)c0t^UW)vD1?#|TWQau35`|pDQ

literal 0
HcmV?d00001

diff --git a/examples/02631/instructor/programs/unitgrade/FermentationRate.pkl b/examples/02631/instructor/programs/unitgrade/FermentationRate.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..9f5cea13c96d67ff2704de398cd66b78a2db463b
GIT binary patch
literal 618
zcmZo*nHtZ;00y;FG<pQwQj2m^^GXs+GV}9-5=&C2^l+7=7MH{qC6=TbPHCIc!&;JA
zl9LKzxu>D2)rdAS&@<FgFtpS&)=@A7GcELtzyjtv3VM2au{sKdraB5nrkV=2AZ2C-
z1`765G8i+M+NSidB^DQ_7L`nCn^HT)o1sTEuQa!yQZG5bC{-`FG^Zppv8X7qa!L<d
zadKi#V$qbzQ+imzN~ZL%rj%3`q=H14(k!NQcC=3knxf&&+{0)y#m~>r>;M1%|G|Ve
zL&=mRXO3AjLBQByO52p6Da9F#NM1CW(l#Z7rEN+NnV!>8FfuRzdCtgE&(ho!;yKB-
zDH$9PUuE!S2s?Ak0NMZ37MlZ%VGhv13|&J#b5l?V>L?h2tN?ML!KaLF12{q%{@7#j
jq6y3fPfQz#i9c|R8i74&XsKrki$PtiPH2FIa;Y8w7Y@sc

literal 0
HcmV?d00001

diff --git a/examples/02631/instructor/programs/unitgrade/RemoveIncomplete.pkl b/examples/02631/instructor/programs/unitgrade/RemoveIncomplete.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..30edf2db7bc0e41f0ada9c1c7443ac1d487a6d9a
GIT binary patch
literal 1444
zcmZo*nL3k|0Ss!VX!HmKrRL_BrF!Ni=jRsWq?V*k=@BSNEiQ@Ago_wXX`9l+T9R3k
zlL}%57eRESXha+88S5w*=^23tV;uz(5X)50P)EU7&qzm4PcK$e!B!y}p#UzYU<%S{
ztY-{XrC>iLgE51tZAuSYVsUY5QOT6HDYa9)8Dghs^oZt_<`z`yCFd8V>gAT^lw>9r
z6(v?q>0v8QPRvOxnlgDx4=Y&7lpfZUlFEWqkO)(n#gxvD_9;PAG`yL67;UEb`T2SM
z|Ns9#nDAyOnUdtpF>59WFgi?Wn-Vl7gD*qGnIjDhm@tJzkcA)`Igy2o!9WyQ2y9du
z7qZaVGa$f#DTHD?L=^`_RcdhtBSwT6O=+8w!O}LR#~V2+40RL?K@k9r6hly?Kw<_G
z4ThkI!KDHc1x9UCGC1I24+#^9Z$H{21ryk_#-EXeAddcmDTLx%h*`LU9IJ1QVZQZ8
z_!gXyOhLXi0r|=Vl$yY)&qB`-oTR`B4~v|F1xS;Ho^dS1$39qm42d}bNCZFv0pepp
zWFd%;v8Yl&Rs}H&MF<iIP$8^7Hi7xr0pVk4?1A$eENYEGeurfuWFH%W@*>QOX~cOE
zr+=Wn#_Cd2m`jlg1v7}NjC2&tL17J!7Bdjb5;<-_90hO;f|DdTLcuIcXwd<QpK>gY
zheU=Faxg<2kCKfbs!$RsBr=FoMaX!FS<qO7Boc@aibjYK7F8%hC{9f+F4Y47-%{y-

literal 0
HcmV?d00001

diff --git a/examples/02631/students/programs/.coverage b/examples/02631/students/programs/.coverage
new file mode 100644
index 0000000000000000000000000000000000000000..11b2ec620c9b142ae8ee79c7a6f5afa297121530
GIT binary patch
literal 53248
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

literal 0
HcmV?d00001

diff --git a/examples/02631/students/programs/__pycache__/looping.cpython-38.pyc b/examples/02631/students/programs/__pycache__/looping.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fa302e5a102c505ba4b62aa5eab3205ca2683298
GIT binary patch
literal 2019
zcmWIL<>g{vU|@KAPd`zBoq^#oh=YuI7#J8F7#J9elNcBnQW#Pga~Pr+!8B78QwmcG
za|=Tha|%leYYRgZOA1>GdkaGpYYImSXA46VTPk}BS2j~oTq;K@YbxUc&J^wxo)q2`
zz7+lxffT_Mp>&Rgj48q?BF)UrjEoE^jKK_=qAx+V`z5o0C@5xSU|?WlU|?_txx<Zt
zfuV+>hB=$1hzF#jgkb^WLIxLxSdChi6s8)+6s8)68YXE52?h}cafTWO5r$frdJ#s3
zLc2nd8kQ6$afV<9P3EeHTnY*b3eJf+$)!1oC8-J}nYpP7rFkWpISNUM$t9^pnTZPN
zMfv3=849Tt$*HL+3VsU3C5c5PnR)37X+`<D3W*8@`2`@&nfZAN`DqGy25_BvV8b&q
z^Gb@Xz)X-`S_;YedBvG2sYMET21ufbIRzPs3U&$*F{^^aqQqQ<JOhYEC>N{-MZ_D0
z=Lh8#rIwTy<v}<_j0_A6FF}MR(=E=-lGLJ-{QR8aTdc|XrFkWqthbo*3~sT4O}@qG
zeT&iW7Guduh9Xd+_!aJK6%$&VT2vfUQksz(<C33Tnwy$eQXEs7msyftl$eqlUr>};
zmROP+lUk9OTac4l9AjW)W^5RfnO9s=RGM6pUldbNl%HOdm|Gl^lb>IZnU}6tP<e|F
z7P#)<um#0+F&`+hc{mtZ7<m{a7&#c(7>ht@FB#-?kQ4}m6mq~4!VCrm22kYJFf3%O
z1+kb)m}?lC85c69Fp4pxFl95<GJ@nw7#6V9Fw`*eGe|Nl1c`uoAa**_LdIIA5{4|+
z5{3nAHK63p&<f(Sr!h$~)PPwj3@Hq)Od!4l!$L+-g70Mlo6TIpQNvurn9bD8SkzTG
zp@zAZu}}e&{J=?z#qT8(0|P@5h|pxb#gbT&S**!<iz%<*7JFiGVo_0I<t?_vqQt!P
z)LYCssd=|pa#IuYKtk!cnR&OE6O)Q>vFD|hgY?~EPRz;CWQpP~N=?g2O)g2yOHPeq
z@-)1~m>b3HX&4WVEC|8Pz`$^eKRKtgxFog6F)uNvvN*F?0+ek8K;g&8#VE$4!f3(B
z!^i{*U`YlBhGb@t3>1Udpxg$ci>06e+|JO>n8uXCn8MV;QN!Q@4q{O5@k5ClkWWEc
zg+aDyFfcHrGt@A|D%3J|Fw`)zFfcP@GZe{mFlI9pvE;EZG8D4ZFivDDWC@0(HL&wF
znQk%Z8QfwlTFG>aD<{7^wa6*IG%w{AS7|{3lnqu_1okGEO-^QUNpgN}ft@PIPEe9%
zV_;%nV&G!nVW?6`ODzJW*2I#`{JfyVl2kpLoc!d(oMJmYghoxKB7RUbfgG*L9L1BH
znpj*~l$rukUnC2XkpmGRql;ufEU?W2=te7p><0w^15=R#C`^$PEhsEO0Ry6o{h(nA
zNwnz<wTvZ9phWA!5UUfzRLj)KP{Q2Kkj97{+Rcn9%-KvuVl|8lSUMOMGBPq0ih&Y#
z4dX&kiOEuBr{IAoWV94Q60=hk5*2dt^RpEaOB6~nQWc=tQz0`C%1tdw&MZ!alu)>%
z5#$$eG)jQ7QVnA>V+lhCLo;JGQxR(PX)@ko&de*(WGVtBnp=z&D;aMwmLVdmNS=X#
z!4MQmpmH1(O9Bj4Dn+Te`DLk|d7wDVNyQ#RFG0bk$qI=kP$Is?nVMIcn_84ul3FAL
zO73il1qG>jDVof;m@-qMm@`w1ZZT#;tOmskB(Vsf+oc6^45)x%VBun9VH9ALV&q{g
z0*T(@h>y=r%*>0APoFh&=FFLrCJyOm&zw1P#>dzJA~N%%eY!Ci7&$-~n~fdP(?Gy2
z4yM?|Asv#bOdMW<(%4H-X4B-l#hO=|TTlt{56ExeQmzOj2~Ik2C*&pOrpCwLVl61j
w%qzLY3NA7rz5=I4Fab`D95%W6DWy57cA!KDE=D;RIhZ&^IJi03Ie0i&0HrYEG5`Po

literal 0
HcmV?d00001

diff --git a/examples/02631/students/programs/__pycache__/report1intro.cpython-38.pyc b/examples/02631/students/programs/__pycache__/report1intro.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ddadca6243eeebd021c63d8d875e9092033e1190
GIT binary patch
literal 7198
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
D4<0BP

literal 0
HcmV?d00001

diff --git a/examples/02631/students/programs/looping.py b/examples/02631/students/programs/looping.py
new file mode 100644
index 0000000..34517b1
--- /dev/null
+++ b/examples/02631/students/programs/looping.py
@@ -0,0 +1,62 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+import numpy as np
+import itertools
+
+def bacteriaGrowth(n0, alpha, K, N): 
+    """
+    Calculate time until bacteria growth exceed N starting from a population of n0 bacteria.
+    hints:
+        * consider n0
+        * alpha > 0
+    :param n0:
+    :param alpha:
+    :param K:
+    :param N:
+    :return:
+    """
+    # TODO: 7 lines missing.
+    raise NotImplementedError("Implement function body")
+
+def clusterAnalysis(reflectance):
+    reflectance = np.asarray(reflectance)
+    I1 = np.arange(len(reflectance)) % 2 == 1
+    while True:
+        m = np.asarray( [np.mean( reflectance[~I1] ),  np.mean( reflectance[I1] ) ] )
+        I1_ = np.argmin( np.abs( reflectance[:, np.newaxis] - m[np.newaxis, :] ), axis=1) == 1
+        if all(I1_ == I1):
+            break
+        I1 = I1_
+    return I1 + 1
+
+def fermentationRate(measuredRate, lowerBound, upperBound):
+    # Insert your code here
+    return np.mean( [r for r in measuredRate if lowerBound < r < upperBound] )
+
+
+
+
+def removeIncomplete(id):
+    """ Hints:
+    * Take a look at the example in the exercise.
+    """
+    id = np.asarray(id)
+    id2 = []
+    for i, v in enumerate(id):
+        if len( [x for x in id if int(x) == int(v) ] ) == 3:
+            id2.append(v)
+    return np.asarray(id2)
+
+
+if __name__ == "__main__":
+    # I = clusterAnalysis([1.7, 1.6, 1.3, 1.3, 2.8, 1.4, 2.8, 2.6, 1.6, 2.7])
+    # print(I)
+
+    print(fermentationRate(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 15, 25))
+
+
+    # print(removeIncomplete(np.array([1.3, 2.2, 2.3, 4.2, 5.1, 3.2, 5.3, 3.3, 2.1, 1.1, 5.2, 3.1])))
+
+    # Problem 1: Write a function which add two numbers
+    # clusterAnalysis([2, 1, 2, 4, 5])
diff --git a/examples/02631/students/programs/report1intro.py b/examples/02631/students/programs/report1intro.py
new file mode 100644
index 0000000..587129b
--- /dev/null
+++ b/examples/02631/students/programs/report1intro.py
@@ -0,0 +1,142 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+from src.unitgrade2.unitgrade2 import Report, UTestCase, cache
+from src.unitgrade2 import evaluate_report_student
+import numpy as np
+import looping
+from looping import bacteriaGrowth, clusterAnalysis, removeIncomplete, fermentationRate
+
+def trlist(x):
+    s = str(list(x))
+    if len(s) > 30:
+        s = s[:30] + "...]"
+    return s
+
+class Bacteria(UTestCase):
+    """ Bacteria growth rates """
+
+    def stest(self, n0, alpha, K, N):
+        g = bacteriaGrowth(n0=n0, alpha=alpha, K=K, N=N)
+        self.title = f"bacteriaGrowth({n0}, {alpha}, {K}, {N}) = {g} ?"
+        self.assertEqualC(g)
+
+    def test_growth1(self):
+        """ Hints:
+        * Make sure to frobulate the frobulator.
+        """
+        self.stest(100, 0.4, 1000, 500)
+
+    def test_growth2(self):
+        self.stest(10, 0.4, 1000, 500)
+
+    def test_growth3(self):
+        self.stest(100, 1.4, 1000, 500)
+
+    def test_growth4(self):
+        self.stest(100, 0.0004, 1000, 500)
+
+    def test_growth5(self):
+        """
+        hints:
+        * What happens when n0 > N? (in this case return t=0) """
+        self.stest(100, 0.4, 1000, 99)
+
+class ClusterAnalysis(UTestCase):
+    """ Test the cluster analysis method """
+
+    def stest(self, n, seed):
+        np.random.seed(seed)
+        x = np.round(np.random.rand(n), 1)
+        I = clusterAnalysis(x)
+        self.title = f"clusterAnalysis({list(x)}) = {list(I)} ?"
+        self.assertEqualC(list(I))
+
+    def test_cluster1(self):
+        """ Hints:
+        * Make sure to frobulate the frobulator.
+        * Just try harder
+        """
+        self.stest(3, 10)
+
+    def test_cluster2(self):
+        self.stest(4, 146)
+
+    def test_cluster3(self):
+        self.stest(5, 12)
+
+    def test_cluster4(self):
+        """
+        Cluster analysis for tied lists
+        Hints:
+        * It may be that an observations has the same distance to the two clusters. Where do you assign it in this case?
+        """
+        x = np.array([10.0, 12.0, 10.0, 12.0, 9.0, 11.0, 11.0, 13.0])
+        self.assertEqualC(list(clusterAnalysis(x) ) )
+
+
+class RemoveIncomplete(UTestCase):
+    """ Remove incomplete IDs """
+
+    def stest(self, x):
+        I = list( removeIncomplete(x) )
+        self.title = f"removeId({trlist(x)}) = {trlist(I)} ?"
+        self.assertEqualC(I)
+
+    @cache
+    def rseq(self, max, n):
+        np.random.seed(42)
+        return np.random.randint(max, size=(n,) ) + (np.random.randint(2, size=(n,) )+1)/10
+
+    def test_incomplete1(self):
+        self.stest( np.array([1.3, 2.2, 2.3, 4.2, 5.1, 3.2, 5.3, 3.3, 2.1, 1.1, 5.2, 3.1]) )
+
+    def test_incomplete2(self):
+        self.stest( np.array([1.1, 1.2, 1.3, 2.1, 2.2, 2.3]) )
+
+    def test_incomplete3(self):
+        self.stest(np.array([5.1, 5.2, 4.1, 4.3, 4.2, 8.1, 8.2, 8.3]) )
+
+    def test_incomplete4(self):
+        self.stest(np.array([1.1, 1.3, 2.1, 2.2, 3.1, 3.3, 4.1, 4.2, 4.3]) )
+
+    def test_incomplete5(self):
+        self.stest(self.rseq(10, 40))
+
+
+class FermentationRate(UTestCase):
+    """ Test the fermentation rate question """
+
+    def stest(self, x, lower, upper):
+        I =  fermentationRate(x, lower, upper)
+        s = trlist(x)
+        self.title = f"fermentationRate({s}, {lower}, {upper}) = {I:.3f} ?"
+        self.assertEqualC(I)
+
+    @cache
+    def rseq(self, max, n):
+        np.random.seed(42)
+        return np.random.randint(max, size=(n,) ) + (np.random.randint(3, size=(n,) )+1)/n
+
+    def test_rate1(self):
+        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 15, 25)
+
+    def test_rate2(self):
+        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 1, 200)
+
+    def test_rate3(self):
+        self.stest(np.array([1.75]), 1, 2)
+
+    def test_rate4(self):
+        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 18.2, 20)
+
+
+class Report1Flat(Report):
+    title = "Week 4: Looping"
+    questions = [(ClusterAnalysis, 10), (RemoveIncomplete, 10), (Bacteria, 10),  (FermentationRate, 10),]
+    pack_imports = [looping]
+
+if __name__ == "__main__":
+    # Uncomment to simply run everything as a unittest:
+    # unittest.main(verbosity=2)
+    evaluate_report_student(Report1Flat())
diff --git a/examples/02631/students/programs/report1intro_grade.py b/examples/02631/students/programs/report1intro_grade.py
new file mode 100644
index 0000000..e7ffde8
--- /dev/null
+++ b/examples/02631/students/programs/report1intro_grade.py
@@ -0,0 +1,339 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+import inspect
+import os
+import argparse
+import time
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print(s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    # nL =
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+        UTextResult.nL = report.nL
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f"Question {n+1} total"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+    print("")
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f" * {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.join(output_dir, token)
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single unmodified file: ")
+        print(">", token)
+        # print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        return Capturing2(stdout=self._stdout)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    # nL =\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"Question {n+1} total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nimport numpy as np\nimport looping\nfrom looping import bacteriaGrowth, clusterAnalysis, removeIncomplete, fermentationRate\n\ndef trlist(x):\n    s = str(list(x))\n    if len(s) > 30:\n        s = s[:30] + "...]"\n    return s\n\nclass Bacteria(UTestCase):\n    """ Bacteria growth rates """\n\n    def stest(self, n0, alpha, K, N):\n        g = bacteriaGrowth(n0=n0, alpha=alpha, K=K, N=N)\n        self.title = f"bacteriaGrowth({n0}, {alpha}, {K}, {N}) = {g} ?"\n        self.assertEqualC(g)\n\n    def test_growth1(self):\n        """ Hints:\n        * Make sure to frobulate the frobulator.\n        """\n        self.stest(100, 0.4, 1000, 500)\n\n    def test_growth2(self):\n        self.stest(10, 0.4, 1000, 500)\n\n    def test_growth3(self):\n        self.stest(100, 1.4, 1000, 500)\n\n    def test_growth4(self):\n        self.stest(100, 0.0004, 1000, 500)\n\n    def test_growth5(self):\n        """\n        hints:\n        * What happens when n0 > N? (in this case return t=0) """\n        self.stest(100, 0.4, 1000, 99)\n\nclass ClusterAnalysis(UTestCase):\n    """ Test the cluster analysis method """\n\n    def stest(self, n, seed):\n        np.random.seed(seed)\n        x = np.round(np.random.rand(n), 1)\n        I = clusterAnalysis(x)\n        self.title = f"clusterAnalysis({list(x)}) = {list(I)} ?"\n        self.assertEqualC(list(I))\n\n    def test_cluster1(self):\n        """ Hints:\n        * Make sure to frobulate the frobulator.\n        * Just try harder\n        """\n        self.stest(3, 10)\n\n    def test_cluster2(self):\n        self.stest(4, 146)\n\n    def test_cluster3(self):\n        self.stest(5, 12)\n\n    def test_cluster4(self):\n        """\n        Cluster analysis for tied lists\n        Hints:\n        * It may be that an observations has the same distance to the two clusters. Where do you assign it in this case?\n        """\n        x = np.array([10.0, 12.0, 10.0, 12.0, 9.0, 11.0, 11.0, 13.0])\n        self.assertEqualC(list(clusterAnalysis(x) ) )\n\n\nclass RemoveIncomplete(UTestCase):\n    """ Remove incomplete IDs """\n\n    def stest(self, x):\n        I = list( removeIncomplete(x) )\n        self.title = f"removeId({trlist(x)}) = {trlist(I)} ?"\n        self.assertEqualC(I)\n\n    @cache\n    def rseq(self, max, n):\n        np.random.seed(42)\n        return np.random.randint(max, size=(n,) ) + (np.random.randint(2, size=(n,) )+1)/10\n\n    def test_incomplete1(self):\n        self.stest( np.array([1.3, 2.2, 2.3, 4.2, 5.1, 3.2, 5.3, 3.3, 2.1, 1.1, 5.2, 3.1]) )\n\n    def test_incomplete2(self):\n        self.stest( np.array([1.1, 1.2, 1.3, 2.1, 2.2, 2.3]) )\n\n    def test_incomplete3(self):\n        self.stest(np.array([5.1, 5.2, 4.1, 4.3, 4.2, 8.1, 8.2, 8.3]) )\n\n    def test_incomplete4(self):\n        self.stest(np.array([1.1, 1.3, 2.1, 2.2, 3.1, 3.3, 4.1, 4.2, 4.3]) )\n\n    def test_incomplete5(self):\n        self.stest(self.rseq(10, 40))\n\n\nclass FermentationRate(UTestCase):\n    """ Test the fermentation rate question """\n\n    def stest(self, x, lower, upper):\n        I =  fermentationRate(x, lower, upper)\n        s = trlist(x)\n        self.title = f"fermentationRate({s}, {lower}, {upper}) = {I:.3f} ?"\n        self.assertEqualC(I)\n\n    @cache\n    def rseq(self, max, n):\n        np.random.seed(42)\n        return np.random.randint(max, size=(n,) ) + (np.random.randint(3, size=(n,) )+1)/n\n\n    def test_rate1(self):\n        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 15, 25)\n\n    def test_rate2(self):\n        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 1, 200)\n\n    def test_rate3(self):\n        self.stest(np.array([1.75]), 1, 2)\n\n    def test_rate4(self):\n        self.stest(np.array([20.1, 19.3, 1.1, 18.2, 19.7, 121.1, 20.3, 20.0]), 18.2, 20)\n\n\nclass Report1Flat(Report):\n    title = "Week 4: Looping"\n    questions = [(ClusterAnalysis, 10), (RemoveIncomplete, 10), (Bacteria, 10),  (FermentationRate, 10),]\n    pack_imports = [looping]'
+report1_payload = '80049592150000000000007d94288c0f436c7573746572416e616c79736973947d94288c0f436c7573746572416e616c79736973948c0d746573745f636c7573746572319486948c057469746c659486948c2e636c7573746572416e616c79736973285b302e382c20302e302c20302e365d29203d205b312c20322c20315d203f946803680486948c066173736572749486947d944b005d94288c156e756d70792e636f72652e6d756c74696172726179948c067363616c61729493948c056e756d7079948c0564747970659493948c02693494898887945294284b038c013c944e4e4e4affffffff4affffffff4b007494624304010000009486945294681068164304020000009486945294681068164304010000009486945294657368038c0d746573745f636c757374657232948694680686948c36636c7573746572416e616c79736973285b302e352c20302e362c20302e332c20302e335d29203d205b322c20322c20312c20315d203f94680368228694680a86947d944b005d9428681068164304020000009486945294681068164304020000009486945294681068164304010000009486945294681068164304010000009486945294657368038c0d746573745f636c757374657233948694680686948c3e636c7573746572416e616c79736973285b302e322c20302e372c20302e332c20302e352c20302e305d29203d205b312c20322c20312c20322c20315d203f94680368368694680a86947d944b005d9428681068164304010000009486945294681068164304020000009486945294681068164304010000009486945294681068164304020000009486945294681068164304010000009486945294657368038c0d746573745f636c757374657234948694680a86947d944b005d942868106816430401000000948694529468106816430402000000948694529468106816430401000000948694529468106816430402000000948694529468106816430401000000948694529468106816430401000000948694529468106816430401000000948694529468106816430402000000948694529465738c0474696d6594473fdf6c8500000000758c1052656d6f7665496e636f6d706c657465947d94288c1052656d6f7665496e636f6d706c657465948c10746573745f696e636f6d706c657465319486948c057469746c659486948c5372656d6f76654964285b312e332c20322e322c20322e332c20342e322c20352e312c20332e322c2e2e2e5d29203d205b322e322c20322e332c20352e312c20332e322c20352e332c20332e332c2e2e2e5d203f94686d686e86948c066173736572749486947d944b005d9428681068138c02663894898887945294284b0368174e4e4e4affffffff4affffffff4b0074946243089a9999999999014094869452946810687a4308666666666666024094869452946810687a4308666666666666144094869452946810687a43089a9999999999094094869452946810687a4308333333333333154094869452946810687a43086666666666660a4094869452946810687a4308cdcccccccccc004094869452946810687a4308cdcccccccccc144094869452946810687a4308cdcccccccccc084094869452946573686d8c10746573745f696e636f6d706c65746532948694687086948c4b72656d6f76654964285b312e312c20312e322c20312e332c20322e312c20322e322c20322e335d29203d205b312e312c20312e322c20312e332c20322e312c20322e322c20322e335d203f94686d68978694687486947d944b005d94286810687a43089a9999999999f13f94869452946810687a4308333333333333f33f94869452946810687a4308cdccccccccccf43f94869452946810687a4308cdcccccccccc004094869452946810687a43089a9999999999014094869452946810687a4308666666666666024094869452946573686d8c10746573745f696e636f6d706c65746533948694687086948c4f72656d6f76654964285b352e312c20352e322c20342e312c20342e332c20342e322c20382e312c2e2e2e5d29203d205b342e312c20342e332c20342e322c20382e312c20382e322c20382e335d203f94686d68b18694687486947d944b005d94286810687a4308666666666666104094869452946810687a4308333333333333114094869452946810687a4308cdcccccccccc104094869452946810687a4308333333333333204094869452946810687a4308666666666666204094869452946810687a43089a9999999999204094869452946573686d8c10746573745f696e636f6d706c65746534948694687086948c4072656d6f76654964285b312e312c20312e332c20322e312c20322e322c20332e312c20332e332c2e2e2e5d29203d205b342e312c20342e322c20342e335d203f94686d68cb8694687486947d944b005d94286810687a4308666666666666104094869452946810687a4308cdcccccccccc104094869452946810687a4308333333333333114094869452946573686d8c10746573745f696e636f6d706c657465359486948c06406361636865948c0472736571948c0966756e63746f6f6c73948c0a5f486173686564536571949394298194284b0a4b28654e7d948c096861736876616c7565948a0884d8ef03874d7f467386946287948694680e8c0c5f7265636f6e73747275637494939468118c076e6461727261799493944b0085944301629487945294284b014b28859468138c02663894898887945294284b0368174e4e4e4affffffff4affffffff4b0074946289424001000066666666666618409a99999999990940cdcccccccccc1c40cdcccccccccc1040cdcccccccccc184033333333333322409a999999999901406666666666661840cdcccccccccc1c40cdcccccccccc10409a999999999909406666666666661c40cdcccccccccc1c40cdcccccccccc0040cdcccccccccc14406666666666661040333333333333f33f6666666666661c406666666666661440333333333333f33f66666666666610409a9999999999c93f6666666666662240cdcccccccccc144066666666666620409a9999999999c93f66666666666622409a99999999990140cdcccccccccc18409a9999999999094066666666666620409a999999999901406666666666661040cdcccccccccc0040cdcccccccccc1840cdcccccccccc10406666666666662040cdcccccccccc1840333333333333f33f9a9999999999094094749462686d68dc8694687086948c5372656d6f76654964285b362e312c20332e322c20372e322c20342e322c20362e322c20392e312c2e2e2e5d29203d205b392e312c20352e322c20312e322c20352e312c20312e322c20392e322c2e2e2e5d203f94686d68dc8694687486947d944b005d94286810687a4308333333333333224094869452946810687a4308cdcccccccccc144094869452946810687a4308333333333333f33f94869452946810687a4308666666666666144094869452946810687a4308333333333333f33f94869452946810687a4308666666666666224094869452946810687a4308cdcccccccccc144094869452946810687a4308666666666666204094869452946810687a4308666666666666224094869452946810687a4308666666666666204094869452946810687a4308666666666666204094869452946810687a4308333333333333f33f94869452946573686a473fcf9dc400000000758c084261637465726961947d94288c084261637465726961948c0c746573745f67726f777468319486948c057469746c659486948c29626163746572696147726f777468283130302c20302e342c20313030302c2035303029203d2037203f946a250100006a2601000086948c066173736572749486947d944b004b07736a250100006a2601000086948c08636f7665726167659486947d94286a250100006a2601000086947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b158ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a2020202022222294869473736a250100008c0c746573745f67726f777468329486947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b158ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a2020202022222294869473736a250100008c0c746573745f67726f777468339486947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b158ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a2020202022222294869473736a250100008c0c746573745f67726f777468349486947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b158ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a2020202022222294869473736a250100008c0c746573745f67726f777468359486947d948c0a6c6f6f70696e672e7079947d948c2564656620626163746572696147726f777468286e302c20616c7068612c204b2c204e293a20944b118ce72222220a2020202043616c63756c6174652074696d6520756e74696c2062616374657269612067726f77746820657863656564204e207374617274696e672066726f6d206120706f70756c6174696f6e206f66206e302062616374657269612e0a2020202068696e74733a0a20202020202020202a20636f6e7369646572206e300a20202020202020202a20616c706861203e20300a202020203a706172616d206e303a0a202020203a706172616d20616c7068613a0a202020203a706172616d204b3a0a202020203a706172616d204e3a0a202020203a72657475726e3a0a202020202222229486947373756a250100006a3a01000086946a2801000086948c29626163746572696147726f7774682831302c20302e342c20313030302c2035303029203d203134203f946a250100006a3a01000086946a2c01000086947d944b004b0e736a250100006a3a01000086946a3001000086946a320100006a250100006a4201000086946a2801000086948c29626163746572696147726f777468283130302c20312e342c20313030302c2035303029203d2033203f946a250100006a4201000086946a2c01000086947d944b004b03736a250100006a4201000086946a3001000086946a320100006a250100006a4a01000086946a2801000086948c2f626163746572696147726f777468283130302c20302e303030342c20313030302c2035303029203d2035343934203f946a250100006a4a01000086946a2c01000086947d944b004d7615736a250100006a4a01000086946a3001000086946a320100006a250100006a5201000086946a2801000086948c28626163746572696147726f777468283130302c20302e342c20313030302c20393929203d2030203f946a250100006a5201000086946a2c01000086947d944b004b00736a250100006a5201000086946a3001000086946a32010000686a473fcf9d9a00000000758c104665726d656e746174696f6e52617465947d94288c104665726d656e746174696f6e52617465948c0a746573745f72617465319486948c057469746c659486948c476665726d656e746174696f6e52617465285b32302e312c2031392e332c20312e312c2031382e322c2031392e372c202e2e2e5d2c2031352c20323529203d2031392e363030203f946a7c0100006a7d01000086948c066173736572749486947d944b006810687a43089a999999999933409486945294736a7c0100008c0a746573745f72617465329486946a7f01000086948c476665726d656e746174696f6e52617465285b32302e312c2031392e332c20312e312c2031382e322c2031392e372c202e2e2e5d2c20312c2032303029203d2032392e393735203f946a7c0100006a8901000086946a8301000086947d944b006810687a43089899999999f93d409486945294736a7c0100008c0a746573745f72617465339486946a7f01000086948c286665726d656e746174696f6e52617465285b312e37355d2c20312c203229203d20312e373530203f946a7c0100006a9301000086946a8301000086947d944b006810687a4308000000000000fc3f9486945294736a7c0100008c0a746573745f72617465349486946a7f01000086948c496665726d656e746174696f6e52617465285b32302e312c2031392e332c20312e312c2031382e322c2031392e372c202e2e2e5d2c2031382e322c20323029203d2031392e353030203f946a7c0100006a9d01000086946a8301000086947d944b006810687a43080000000000803340948694529473686a473fc74c0a0000000075752e'
+name="Report1Flat"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
diff --git a/examples/02631/students/programs/unitgrade/Bacteria.pkl b/examples/02631/students/programs/unitgrade/Bacteria.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..b246df45c63387d95bc69cc26deba7770d8249c5
GIT binary patch
literal 2050
zcmZo*nfjfb0Ss!VX!LM6B_@}o7G)+*>ES6!EiQ>qFUl`3$uOMKHl>HPB(o$Z6~xj^
zf~s-{%W4=J80aV%=$Ys!7#e_>rUnL@3bqR73ieYn7&DmKru48S78j=$l}u@yQai<)
z!JEApD$bFdUzS>wm<}?wc8Uf>w024lS5AI@L1tdMUP0xQ+9^G%DXD1+XqM&~=qM!S
z6l5goD0u5A_-R@xOz{@&d9I|S#HFC1px~UClU$mUSdywxl9`*TP?}egnFBXM0pcx%
z)QaTP)D#6jh2oOLqLR$KbcM8{{9J`Zg@XJ7kmk(%Jcax;g**eePCc;U8JT${#a3V@
z$Sy5~<ovwi%#_q3g**c!QLytA>=YnkRt1SgiMa}S1`v%<E?5nUh&Kw)56UY_Eh#O^
zgK(6Tl%}*zDK5@nM2RIMaPW?Xoq_^1Y)J?^<I%7qJKdR#h8@{qXG&4n368Att~7%&
zL#%B|220zN9?UujTNPwz0;z*Qx;UVf4<D%V0SWN5P08TPV9b!iX{3RUf+0q=W(+YB
zqzh&wGssAg0L(}=sFC_;l@_$7G%zqguPjYXETL`%>4h5XTP6xJ86*NTSr2Nm26mI-
c##&l}s$c_%TS1zjMtU=VOauvlO)S*|044x_qW}N^

literal 0
HcmV?d00001

diff --git a/examples/02631/students/programs/unitgrade/ClusterAnalysis.pkl b/examples/02631/students/programs/unitgrade/ClusterAnalysis.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..36635371f6e86d5f841a3827696a5909e766532b
GIT binary patch
literal 763
zcmZo*nfif=0Ss!VX!P(q=ad$gq!u~mCFWEXXBJQC;VnrmE{RWu2pdjmo6^Htl39|I
z3S#L&g<+~Sq7C#cbQBEq3_yfgtfqpkLbRcdf{~7bVXT7vlnllUrnV_PY>CCisYNAI
z+NRV_@n(pfqR}IoSDIT;sh6Bzl&Y6onp2XQSX7i)Ii-iKI5{yVv1rQVDLt%UB~yA>
zQ%WieQb8h2nI=;@JKCoNP0{dX?qRf<;^*h*_5c6>|6szKp=3&uGYcaF1H+WIDM3>*
z_%cMCSwLPz;=*N9i!&Hey=pY2ZAu19+ms$NES@w4`wv7Ig9(UFjUYZncvhipN(Kkq
zmsnkZ%Rvyuc-&_UbDtd+_Zfj)Wey_1?gKm50OCk!bU>U6jT93s?u1(naS48R;*!M-
aRuho3(Zhr)c0t^UW)vD1?#|TWQau35`|pDQ

literal 0
HcmV?d00001

diff --git a/examples/02631/students/programs/unitgrade/FermentationRate.pkl b/examples/02631/students/programs/unitgrade/FermentationRate.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..9f5cea13c96d67ff2704de398cd66b78a2db463b
GIT binary patch
literal 618
zcmZo*nHtZ;00y;FG<pQwQj2m^^GXs+GV}9-5=&C2^l+7=7MH{qC6=TbPHCIc!&;JA
zl9LKzxu>D2)rdAS&@<FgFtpS&)=@A7GcELtzyjtv3VM2au{sKdraB5nrkV=2AZ2C-
z1`765G8i+M+NSidB^DQ_7L`nCn^HT)o1sTEuQa!yQZG5bC{-`FG^Zppv8X7qa!L<d
zadKi#V$qbzQ+imzN~ZL%rj%3`q=H14(k!NQcC=3knxf&&+{0)y#m~>r>;M1%|G|Ve
zL&=mRXO3AjLBQByO52p6Da9F#NM1CW(l#Z7rEN+NnV!>8FfuRzdCtgE&(ho!;yKB-
zDH$9PUuE!S2s?Ak0NMZ37MlZ%VGhv13|&J#b5l?V>L?h2tN?ML!KaLF12{q%{@7#j
jq6y3fPfQz#i9c|R8i74&XsKrki$PtiPH2FIa;Y8w7Y@sc

literal 0
HcmV?d00001

diff --git a/examples/02631/students/programs/unitgrade/RemoveIncomplete.pkl b/examples/02631/students/programs/unitgrade/RemoveIncomplete.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..30edf2db7bc0e41f0ada9c1c7443ac1d487a6d9a
GIT binary patch
literal 1444
zcmZo*nL3k|0Ss!VX!HmKrRL_BrF!Ni=jRsWq?V*k=@BSNEiQ@Ago_wXX`9l+T9R3k
zlL}%57eRESXha+88S5w*=^23tV;uz(5X)50P)EU7&qzm4PcK$e!B!y}p#UzYU<%S{
ztY-{XrC>iLgE51tZAuSYVsUY5QOT6HDYa9)8Dghs^oZt_<`z`yCFd8V>gAT^lw>9r
z6(v?q>0v8QPRvOxnlgDx4=Y&7lpfZUlFEWqkO)(n#gxvD_9;PAG`yL67;UEb`T2SM
z|Ns9#nDAyOnUdtpF>59WFgi?Wn-Vl7gD*qGnIjDhm@tJzkcA)`Igy2o!9WyQ2y9du
z7qZaVGa$f#DTHD?L=^`_RcdhtBSwT6O=+8w!O}LR#~V2+40RL?K@k9r6hly?Kw<_G
z4ThkI!KDHc1x9UCGC1I24+#^9Z$H{21ryk_#-EXeAddcmDTLx%h*`LU9IJ1QVZQZ8
z_!gXyOhLXi0r|=Vl$yY)&qB`-oTR`B4~v|F1xS;Ho^dS1$39qm42d}bNCZFv0pepp
zWFd%;v8Yl&Rs}H&MF<iIP$8^7Hi7xr0pVk4?1A$eENYEGeurfuWFH%W@*>QOX~cOE
zr+=Wn#_Cd2m`jlg1v7}NjC2&tL17J!7Bdjb5;<-_90hO;f|DdTLcuIcXwd<QpK>gY
zheU=Faxg<2kCKfbs!$RsBr=FoMaX!FS<qO7Boc@aibjYK7F8%hC{9f+F4Y47-%{y-

literal 0
HcmV?d00001

diff --git a/examples/autolab_example/autolab_example.py b/examples/autolab_example/autolab_example.py
index 6cdf58a..a4bdf62 100644
--- a/examples/autolab_example/autolab_example.py
+++ b/examples/autolab_example/autolab_example.py
@@ -1,9 +1,9 @@
 import os
-from autolab.autolab import deploy_assignment
+from unitgrade_private2.autolab.autolab import deploy_assignment
 
 if __name__ == "__main__":
     wdir = os.getcwd()
-    args = [('example_simplest', 'cs101', 'report1_grade.py', 'report1_grade.py'),
+    args = [('example_simplest', 'programs', 'report1_grade.py', 'report1_grade.py'),
             ('example_framework', 'cs102', 'report2_grade.py', 'report2_grade.py'),
             ('example_docker', 'cs103', 'report3_complete_grade.py', 'report3_grade.py'),
             ]
diff --git a/examples/autolab_example/tmp/cs101/cs101.yml b/examples/autolab_example/tmp/cs101/cs101.yml
index 7631a7f..6dc13d8 100644
--- a/examples/autolab_example/tmp/cs101/cs101.yml
+++ b/examples/autolab_example/tmp/cs101/cs101.yml
@@ -1,14 +1,14 @@
 ---
 
 general:
-  name: cs101
+  name: programs
   description: ''
   display_name: CS 101 Report 1
   handin_filename: Report1_handin.token
   handin_directory: handin
   max_grace_days: 0
-  handout: cs101-handout.tar
-  writeup: writeup/cs101.html
+  handout: programs-handout.tar
+  writeup: writeup/programs.html
   max_submissions: -1
   disable_handins: false
   max_size: 2
diff --git a/examples/autolab_example/tmp/cs101/src/driver_python.py b/examples/autolab_example/tmp/cs101/src/driver_python.py
index 9b3e081..074cc75 100644
--- a/examples/autolab_example/tmp/cs101/src/driver_python.py
+++ b/examples/autolab_example/tmp/cs101/src/driver_python.py
@@ -25,7 +25,7 @@ def pfiles():
 
 student_token_file = 'Report1_handin.token'
 instructor_grade_script = 'report1_grade.py'
-grade_file_relative_destination = "cs101\report1_grade.py"
+grade_file_relative_destination = "programs\report1_grade.py"
 with open(student_token_file, 'rb') as f:
     results = pickle.load(f)
 sources = results['sources'][0]
@@ -55,8 +55,8 @@ def rcom(cm):
 start = time.time()
 rcom(command)
 # pfiles()
-# for f in glob.glob(host_tmp_dir + "/cs101/*"):
-#     print("cs101/", f)
+# for f in glob.glob(host_tmp_dir + "/programs/*"):
+#     print("programs/", f)
 # print("---")
 ls = glob.glob(token)
 # print(ls)
diff --git a/examples/autolab_example/tmp/cs101/src/report1_grade.py b/examples/autolab_example/tmp/cs101/src/report1_grade.py
index 8972ab5..fbbeabf 100644
--- a/examples/autolab_example/tmp/cs101/src/report1_grade.py
+++ b/examples/autolab_example/tmp/cs101/src/report1_grade.py
@@ -453,7 +453,7 @@ def source_instantiate(name, report1_source, payload):
 
 
 
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, unmute=False, **kwargs):\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n            # for item in q.items:\n            #     if q.name not in payloads or item.name not in payloads[q.name]:\n            #         s = f"> Broken resource dictionary submitted to unitgrade for question {q.name} and subquestion {item.name}. Framework will not work."\n            #         if strict:\n            #             raise Exception(s)\n            #         else:\n            #             print(s)\n            #     else:\n            #         item._correct_answer_payload = payloads[q.name][item.name][\'payload\']\n            #         item.estimated_time = payloads[q.name][item.name].get("time", 1)\n            #         q.estimated_time = payloads[q.name].get("time", 1)\n            #         if "precomputed" in payloads[q.name][item.name]: # Consider removing later.\n            #             item._precomputed_payload = payloads[q.name][item.name][\'precomputed\']\n            #         try:\n            #             if "title" in payloads[q.name][item.name]: # can perhaps be removed later.\n            #                 item.title = payloads[q.name][item.name][\'title\']\n            #         except Exception as e: # Cannot set attribute error. The title is a function (and probably should not be).\n            #             pass\n            #             # print("bad", e)\n        # self.payloads = payloads\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\nclass MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n    pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        item_title = item_title.split("\\n")[0]\n\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 2\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    @classmethod\n    def question_title(cls):\n        return cls.__doc__.splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    # def _callSetUp(self):\n    #     # Always run before method is called.\n    #     print("asdf")\n    #     pass\n    # @classmethod\n    # def setUpClass(cls):\n    #     # self._cache_put((self.cache_id(), \'title\'), value)\n    #     cls.reset()\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    # def unique_cache_id(self):\n    #     k0 = self.cache_id()\n    #     # key = ()\n    #     i = 0\n    #     for i in itertools.count():\n    #         # key = k0 + (i,)\n    #         if i not in self._cache_get( (k0, \'assert\') ):\n    #             break\n    #     return i\n    #     return key\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n    #\n    # def _cache2_contains(self, key):\n    #     print("Is this needed?")\n    #     self._ensure_cache_exists()\n    #     return key in self.__class__._cache2\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    # try:  # For registering stats.\n    #     import unitgrade_private\n    #     import irlc.lectures\n    #     import xlwings\n    #     from openpyxl import Workbook\n    #     import pandas as pd\n    #     from collections import defaultdict\n    #     dd = defaultdict(lambda: [])\n    #     error_computed = []\n    #     for k1, (q, _) in enumerate(report.questions):\n    #         for k2, item in enumerate(q.items):\n    #             dd[\'question_index\'].append(k1)\n    #             dd[\'item_index\'].append(k2)\n    #             dd[\'question\'].append(q.name)\n    #             dd[\'item\'].append(item.name)\n    #             dd[\'tol\'].append(0 if not hasattr(item, \'tol\') else item.tol)\n    #             error_computed.append(0 if not hasattr(item, \'error_computed\') else item.error_computed)\n    #\n    #     qstats = report.wdir + "/" + report.name + ".xlsx"\n    #\n    #     if os.path.isfile(qstats):\n    #         d_read = pd.read_excel(qstats).to_dict()\n    #     else:\n    #         d_read = dict()\n    #\n    #     for k in range(1000):\n    #         key = \'run_\'+str(k)\n    #         if key in d_read:\n    #             dd[key] = list(d_read[\'run_0\'].values())\n    #         else:\n    #             dd[key] = error_computed\n    #             break\n    #\n    #     workbook = Workbook()\n    #     worksheet = workbook.active\n    #     for col, key in enumerate(dd.keys()):\n    #         worksheet.cell(row=1, column=col+1).value = key\n    #         for row, item in enumerate(dd[key]):\n    #             worksheet.cell(row=row+2, column=col+1).value = item\n    #\n    #     workbook.save(qstats)\n    #     workbook.close()\n    #\n    # except ModuleNotFoundError as e:\n    #     s = 234\n    #     pass\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)\n        z = 234\n        # for j, item in enumerate(q.items):\n        #     if qitem is not None and question is not None and j+1 != qitem:\n        #         continue\n        #\n        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.\n        #         # if not item.question.has_called_init_:\n        #         start = time.time()\n        #\n        #         cc = None\n        #         if show_progress_bar:\n        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )\n        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)\n        #         from unitgrade import Capturing # DON\'T REMOVE THIS LINE\n        #         with eval(\'Capturing\')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.\n        #             try:\n        #                 for q2 in q_with_outstanding_init:\n        #                     q2.init()\n        #                     q2.has_called_init_ = True\n        #\n        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.\n        #             except Exception as e:\n        #                 if not passall:\n        #                     if not silent:\n        #                         print(" ")\n        #                         print("="*30)\n        #                         print(f"When initializing question {q.title} the initialization code threw an error")\n        #                         print(e)\n        #                         print("The remaining parts of this question will likely fail.")\n        #                         print("="*30)\n        #\n        #         if show_progress_bar:\n        #             cc.terminate()\n        #             sys.stdout.flush()\n        #             print(q_title_print, end="")\n        #\n        #         q_time =np.round(  time.time()-start, 2)\n        #\n        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")\n        #         print("=" * nL)\n        #         q_with_outstanding_init = None\n        #\n        #     # item.question = q # Set the parent question instance for later reference.\n        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)\n        #\n        #     if show_progress_bar:\n        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)\n        #     else:\n        #         print(item_title_print + ( \'.\'*max(0, nL-4-len(ss)) ), end="")\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        #     if show_progress_bar:\n        #         cc.terminate()\n        #         sys.stdout.flush()\n        #         print(item_title_print + (\'.\' * max(0, nL - 4 - len(ss))), end="")\n        #\n        #     if not hidden:\n        #         ss = "PASS" if current == possible else "*** FAILED"\n        #         if tsecs >= 0.1:\n        #             ss += " ("+ str(tsecs) + " seconds)"\n        #         print(ss)\n\n        # ws, possible, obtained = upack(q_)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nfrom cs101.homework1 import reverse_list, add\nimport unittest\n\nclass Week1(unittest.TestCase):\n    def test_add(self):\n        self.assertEqual(add(2,2), 4)\n        self.assertEqual(add(-100, 5), -95)\n\n    def test_reverse(self):\n        self.assertEqual(reverse_list([1,2,3]), [3,2,1])\n        # print("Bad output\\n\\n")\n\n\nimport cs101\nclass Report1(Report):\n    title = "CS 101 Report 1"\n    questions = [(Week1, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs101]'
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, unmute=False, **kwargs):\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n            # for item in q.items:\n            #     if q.name not in payloads or item.name not in payloads[q.name]:\n            #         s = f"> Broken resource dictionary submitted to unitgrade for question {q.name} and subquestion {item.name}. Framework will not work."\n            #         if strict:\n            #             raise Exception(s)\n            #         else:\n            #             print(s)\n            #     else:\n            #         item._correct_answer_payload = payloads[q.name][item.name][\'payload\']\n            #         item.estimated_time = payloads[q.name][item.name].get("time", 1)\n            #         q.estimated_time = payloads[q.name].get("time", 1)\n            #         if "precomputed" in payloads[q.name][item.name]: # Consider removing later.\n            #             item._precomputed_payload = payloads[q.name][item.name][\'precomputed\']\n            #         try:\n            #             if "title" in payloads[q.name][item.name]: # can perhaps be removed later.\n            #                 item.title = payloads[q.name][item.name][\'title\']\n            #         except Exception as e: # Cannot set attribute error. The title is a function (and probably should not be).\n            #             pass\n            #             # print("bad", e)\n        # self.payloads = payloads\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\nclass MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n    pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        item_title = item_title.split("\\n")[0]\n\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 2\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    @classmethod\n    def question_title(cls):\n        return cls.__doc__.splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    # def _callSetUp(self):\n    #     # Always run before method is called.\n    #     print("asdf")\n    #     pass\n    # @classmethod\n    # def setUpClass(cls):\n    #     # self._cache_put((self.cache_id(), \'title\'), value)\n    #     cls.reset()\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    # def unique_cache_id(self):\n    #     k0 = self.cache_id()\n    #     # key = ()\n    #     i = 0\n    #     for i in itertools.count():\n    #         # key = k0 + (i,)\n    #         if i not in self._cache_get( (k0, \'assert\') ):\n    #             break\n    #     return i\n    #     return key\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n    #\n    # def _cache2_contains(self, key):\n    #     print("Is this needed?")\n    #     self._ensure_cache_exists()\n    #     return key in self.__class__._cache2\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    # try:  # For registering stats.\n    #     import unitgrade_private\n    #     import irlc.lectures\n    #     import xlwings\n    #     from openpyxl import Workbook\n    #     import pandas as pd\n    #     from collections import defaultdict\n    #     dd = defaultdict(lambda: [])\n    #     error_computed = []\n    #     for k1, (q, _) in enumerate(report.questions):\n    #         for k2, item in enumerate(q.items):\n    #             dd[\'question_index\'].append(k1)\n    #             dd[\'item_index\'].append(k2)\n    #             dd[\'question\'].append(q.name)\n    #             dd[\'item\'].append(item.name)\n    #             dd[\'tol\'].append(0 if not hasattr(item, \'tol\') else item.tol)\n    #             error_computed.append(0 if not hasattr(item, \'error_computed\') else item.error_computed)\n    #\n    #     qstats = report.wdir + "/" + report.name + ".xlsx"\n    #\n    #     if os.path.isfile(qstats):\n    #         d_read = pd.read_excel(qstats).to_dict()\n    #     else:\n    #         d_read = dict()\n    #\n    #     for k in range(1000):\n    #         key = \'run_\'+str(k)\n    #         if key in d_read:\n    #             dd[key] = list(d_read[\'run_0\'].values())\n    #         else:\n    #             dd[key] = error_computed\n    #             break\n    #\n    #     workbook = Workbook()\n    #     worksheet = workbook.active\n    #     for col, key in enumerate(dd.keys()):\n    #         worksheet.cell(row=1, column=col+1).value = key\n    #         for row, item in enumerate(dd[key]):\n    #             worksheet.cell(row=row+2, column=col+1).value = item\n    #\n    #     workbook.save(qstats)\n    #     workbook.close()\n    #\n    # except ModuleNotFoundError as e:\n    #     s = 234\n    #     pass\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)\n        z = 234\n        # for j, item in enumerate(q.items):\n        #     if qitem is not None and question is not None and j+1 != qitem:\n        #         continue\n        #\n        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.\n        #         # if not item.question.has_called_init_:\n        #         start = time.time()\n        #\n        #         cc = None\n        #         if show_progress_bar:\n        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )\n        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)\n        #         from unitgrade import Capturing # DON\'T REMOVE THIS LINE\n        #         with eval(\'Capturing\')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.\n        #             try:\n        #                 for q2 in q_with_outstanding_init:\n        #                     q2.init()\n        #                     q2.has_called_init_ = True\n        #\n        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.\n        #             except Exception as e:\n        #                 if not passall:\n        #                     if not silent:\n        #                         print(" ")\n        #                         print("="*30)\n        #                         print(f"When initializing question {q.title} the initialization code threw an error")\n        #                         print(e)\n        #                         print("The remaining parts of this question will likely fail.")\n        #                         print("="*30)\n        #\n        #         if show_progress_bar:\n        #             cc.terminate()\n        #             sys.stdout.flush()\n        #             print(q_title_print, end="")\n        #\n        #         q_time =np.round(  time.time()-start, 2)\n        #\n        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")\n        #         print("=" * nL)\n        #         q_with_outstanding_init = None\n        #\n        #     # item.question = q # Set the parent question instance for later reference.\n        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)\n        #\n        #     if show_progress_bar:\n        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)\n        #     else:\n        #         print(item_title_print + ( \'.\'*max(0, nL-4-len(ss)) ), end="")\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        #     if show_progress_bar:\n        #         cc.terminate()\n        #         sys.stdout.flush()\n        #         print(item_title_print + (\'.\' * max(0, nL - 4 - len(ss))), end="")\n        #\n        #     if not hidden:\n        #         ss = "PASS" if current == possible else "*** FAILED"\n        #         if tsecs >= 0.1:\n        #             ss += " ("+ str(tsecs) + " seconds)"\n        #         print(ss)\n\n        # ws, possible, obtained = upack(q_)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nfrom programs.homework1 import reverse_list, add\nimport unittest\n\nclass Week1(unittest.TestCase):\n    def test_add(self):\n        self.assertEqual(add(2,2), 4)\n        self.assertEqual(add(-100, 5), -95)\n\n    def test_reverse(self):\n        self.assertEqual(reverse_list([1,2,3]), [3,2,1])\n        # print("Bad output\\n\\n")\n\n\nimport programs\nclass Report1(Report):\n    title = "CS 101 Report 1"\n    questions = [(Week1, 10)]  # Include a single question for 10 credits.\n    pack_imports = [programs]'
 report1_payload = '8004953f000000000000007d948c055765656b31947d948c2c6e6f20636163686520736565205f73657475705f616e737765727320696e20756e69746772616465322e7079948873732e'
 name="Report1"
 
diff --git a/examples/autolab_example/tmp/cs102/src/driver_python.py b/examples/autolab_example/tmp/cs102/src/driver_python.py
index 092842a..80da44e 100644
--- a/examples/autolab_example/tmp/cs102/src/driver_python.py
+++ b/examples/autolab_example/tmp/cs102/src/driver_python.py
@@ -55,8 +55,8 @@ def rcom(cm):
 start = time.time()
 rcom(command)
 # pfiles()
-# for f in glob.glob(host_tmp_dir + "/cs101/*"):
-#     print("cs101/", f)
+# for f in glob.glob(host_tmp_dir + "/programs/*"):
+#     print("programs/", f)
 # print("---")
 ls = glob.glob(token)
 # print(ls)
diff --git a/examples/autolab_example/tmp/cs103/src/driver_python.py b/examples/autolab_example/tmp/cs103/src/driver_python.py
index ed9bd8b..34e6b0b 100644
--- a/examples/autolab_example/tmp/cs103/src/driver_python.py
+++ b/examples/autolab_example/tmp/cs103/src/driver_python.py
@@ -55,8 +55,8 @@ def rcom(cm):
 start = time.time()
 rcom(command)
 # pfiles()
-# for f in glob.glob(host_tmp_dir + "/cs101/*"):
-#     print("cs101/", f)
+# for f in glob.glob(host_tmp_dir + "/programs/*"):
+#     print("programs/", f)
 # print("---")
 ls = glob.glob(token)
 # print(ls)
diff --git a/examples/example_docker/instructor/cs103/.coverage b/examples/example_docker/instructor/cs103/.coverage
new file mode 100644
index 0000000000000000000000000000000000000000..f386b2198168450113494de5b3b3bd99d653d108
GIT binary patch
literal 53248
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
Z7!85Z5Eu=C(GVC7fzc2c4FSR-0004q+NS^j

literal 0
HcmV?d00001

diff --git a/examples/example_docker/instructor/cs103/Report3_handin_25_of_30.token b/examples/example_docker/instructor/cs103/Report3_handin_25_of_30.token
new file mode 100644
index 0000000000000000000000000000000000000000..af7c703d2692f8bf15644581b9cdf6688b4b9c3b
GIT binary patch
literal 117485
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
UH)Kj`4+|($O@S#aEiTmq064_Sm;e9(

literal 0
HcmV?d00001

diff --git a/examples/example_docker/instructor/cs103/Report3_handin_30_of_30.token b/examples/example_docker/instructor/cs103/Report3_handin_30_of_30.token
new file mode 100644
index 0000000000000000000000000000000000000000..0ddcac53870efc12081817272c4b694c4c34fe9e
GIT binary patch
literal 117467
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
Sl++#;P!^g3lP@hU)dK(kdBY6=

literal 0
HcmV?d00001

diff --git a/examples/example_docker/instructor/cs103/__pycache__/homework1.cpython-38.pyc b/examples/example_docker/instructor/cs103/__pycache__/homework1.cpython-38.pyc
index 4beaff64aef655b294b4513aa4842f7eada9c024..c2ad43883cce209ac9cd30ec4db9f197297be5f1 100644
GIT binary patch
delta 20
bcmX@ec94xbl$V!_fq{WRdWykDZZl>8EsX=`

delta 20
bcmX@ec94xbl$V!_fq{YH<6)hR+-A%GG;IXv

diff --git a/examples/example_docker/instructor/cs103/__pycache__/report3.cpython-38.pyc b/examples/example_docker/instructor/cs103/__pycache__/report3.cpython-38.pyc
index da19a02cc1c508d3eaafcf35b0b34e9d58501d7e..78157d3ccd77777a3e6bdc5d8ef57fa286b7b497 100644
GIT binary patch
delta 25
gcmaFC^@58pl$V!_fq{WRf388I7xPBGNLEH>08T#zHvj+t

delta 25
gcmaFC^@58pl$V!_fq{WR>7P#Gai)!Yk*ti209Azs0RR91

diff --git a/examples/example_docker/instructor/cs103/__pycache__/report3_complete.cpython-38.pyc b/examples/example_docker/instructor/cs103/__pycache__/report3_complete.cpython-38.pyc
index 921af5c7208e7aa4d953fa1e4551029aeb05c182..ca3fa7b43ad2a579965093501504022367ac79d6 100644
GIT binary patch
delta 53
zcmcb@dy<zol$V!_fq{X+Zm~h)+Ks#hY^;*SMag=T?buZL_&}`Eyv&mHqQsQc$qj75
GjLZOZLk^|@

delta 64
zcmX@fdxe)bl$V!_fq{X6_n%Ip=|)}yHb&9OPHd{OvZZ;MCFw<pDXB(!aAtf)YED6F
MQSszbwqQm^04-D!>Hq)$

diff --git a/examples/example_docker/instructor/cs103/deploy.py b/examples/example_docker/instructor/cs103/deploy.py
index 9379f59..e1350f9 100644
--- a/examples/example_docker/instructor/cs103/deploy.py
+++ b/examples/example_docker/instructor/cs103/deploy.py
@@ -4,25 +4,24 @@ from unitgrade_private2.hidden_create_files import setup_grade_file_report
 from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
 from unitgrade_private2.deployment import remove_hidden_methods
 from unitgrade_private2.docker_helpers import docker_run_token_file
-import shutil
 import os
 import glob
 import pickle
 from snipper.snip_dir import snip_dir
+wd = os.path.dirname(__file__)
 
 def deploy_student_files():
     setup_grade_file_report(Report3, minify=False, obfuscate=False, execute=False)
-    # Report3.reset()
 
     fout, ReportWithoutHidden = remove_hidden_methods(Report3, outfile="report3.py")
     setup_grade_file_report(ReportWithoutHidden, minify=False, obfuscate=False, execute=False)
-    sdir = "../../students/cs103"
-    snip_dir(source_dir="../cs103", dest_dir=sdir, clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py', 'report3_complete*.py'])
+    sdir = wd+"/../../students/cs103"
+    snip_dir(source_dir=wd+"/../cs103", dest_dir=sdir, clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py', 'report3_complete*.py'])
     return sdir
 
 def run_student_code_on_docker(Dockerfile, student_token_file):
     token = docker_run_token_file(Dockerfile_location=Dockerfile,
-                          host_tmp_dir=os.path.dirname(Dockerfile) + "/tmp",
+                          host_tmp_dir=os.path.dirname(Dockerfile) + "/home",
                           student_token_file=student_token_file,
                           instructor_grade_script="report3_complete_grade.py")
     with open(token, 'rb') as f:
@@ -32,17 +31,14 @@ def run_student_code_on_docker(Dockerfile, student_token_file):
 if __name__ == "__main__":
     # Step 1: Deploy the students files and return the directory they were written to
     student_directory = deploy_student_files()
-    # import sys
-    # sys.exit()
-    # student_directory = "../../students/cs103"
+
     # Step 2: Simulate that the student run their report script and generate a .token file.
     os.system("cd ../../students && python -m cs103.report3_grade")
     student_token_file = glob.glob(student_directory + "/*.token")[0]
 
-
     # Step 3: Compile the Docker image (obviously you will only do this once; add your packages to requirements.txt).
-    Dockerfile = os.path.dirname(__file__) + "/../unitgrade-docker/Dockerfile"
-    os.system("cd ../unitgrade-docker && docker build --tag unitgrade-docker .")
+    Dockerfile = os.path.dirname(__file__) + "/../../../../docker_images/unitgrade-docker/Dockerfile"
+    os.system(f"cd {os.path.dirname(Dockerfile)} && docker build --tag unitgrade-docker .")
 
     # Step 4: Test the students .token file and get the results-token-file. Compare the contents with the students_token_file:
     checked_token = run_student_code_on_docker(Dockerfile, student_token_file)
diff --git a/examples/example_docker/instructor/cs103/report3.py b/examples/example_docker/instructor/cs103/report3.py
index 6dfbe04..3bdc6e6 100644
--- a/examples/example_docker/instructor/cs103/report3.py
+++ b/examples/example_docker/instructor/cs103/report3.py
@@ -1,5 +1,5 @@
-from unitgrade2.unitgrade2 import UTestCase, Report, hide
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
+from src.unitgrade2.unitgrade2 import UTestCase, Report
+from src.unitgrade2 import evaluate_report_student
 
 class Week1(UTestCase):
     """ The first question for week 1. """
@@ -21,4 +21,6 @@ class Report3(Report):
     pack_imports = [cs103]
 
 if __name__ == "__main__":
+    # from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
+    # gather_upload_to_campusnet(Report3())
     evaluate_report_student(Report3())
\ No newline at end of file
diff --git a/examples/example_docker/instructor/cs103/report3_complete.py b/examples/example_docker/instructor/cs103/report3_complete.py
index 4e72f82..dd85bd8 100644
--- a/examples/example_docker/instructor/cs103/report3_complete.py
+++ b/examples/example_docker/instructor/cs103/report3_complete.py
@@ -1,5 +1,5 @@
 from unitgrade2.unitgrade2 import UTestCase, Report, hide
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
+from unitgrade2 import evaluate_report_student
 
 class Week1(UTestCase):
     """ The first question for week 1. """
@@ -30,4 +30,6 @@ class Report3(Report):
     pack_imports = [cs103]
 
 if __name__ == "__main__":
+    # from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
+    # gather_upload_to_campusnet(Report3())
     evaluate_report_student(Report3())
diff --git a/examples/example_docker/instructor/cs103/report3_complete_grade.py b/examples/example_docker/instructor/cs103/report3_complete_grade.py
index b053e48..8ea5f2e 100644
--- a/examples/example_docker/instructor/cs103/report3_complete_grade.py
+++ b/examples/example_docker/instructor/cs103/report3_complete_grade.py
@@ -4,15 +4,10 @@ from tabulate import tabulate
 from datetime import datetime
 import pyfiglet
 import unittest
-# from unitgrade2.unitgrade2 import MySuite
-
 import inspect
 import os
 import argparse
-import sys
 import time
-import threading # don't import Thread bc. of minify issue.
-import tqdm # don't do from tqdm import tqdm because of minify-issue
 
 parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
 To run all tests in a report: 
@@ -113,24 +108,20 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
     else:
         b = "Unitgrade"
-    print(b + " v" + __version__)
     dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
-    print("Started: " + dt_string)
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
     s = report.title
     if hasattr(report, "version") and report.version is not None:
         s += " version " + report.version
-    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
+    print(s, "(use --help for options)" if show_help_flag else "")
     # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
     table_data = []
-    nL = 80
     t_start = time.time()
     score = {}
     loader = SequentialTestLoader()
 
     for n, (q, w) in enumerate(report.questions):
-        # q = q()
-        # q_hidden = False
-        # q_hidden = issubclass(q.__class__, Hidden)
         if question is not None and n+1 != question:
             continue
         suite = loader.loadTestsFromTestCase(q)
@@ -140,11 +131,10 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         q.possible = 0
         q.obtained = 0
         q_ = {} # Gather score in this class.
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
         UTextResult.q_title_print = q_title_print # Hacky
         UTextResult.show_progress_bar = show_progress_bar # Hacky.
         UTextResult.number = n
+        UTextResult.nL = report.nL
 
         res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
 
@@ -153,20 +143,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
 
         assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
 
-        # possible = int(ws @ possible)
-        # obtained = int(ws @ obtained)
-        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
-
         obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
         score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
         q.obtained = obtained
         q.possible = possible
 
-        s1 = f"*** Question q{n+1}"
+        s1 = f" * q{n+1})   Total"
         s2 = f" {q.obtained}/{w}"
-        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
         print(" ")
-        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
 
     ws, possible, obtained = upack(score)
     possible = int( msum(possible) )
@@ -181,15 +167,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
     seconds = dt - minutes*60
     plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
 
-    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
 
     table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
     results = {'total': (obtained, possible), 'details': score}
     return results, table_data
 
 
-
-
 from tabulate import tabulate
 from datetime import datetime
 import inspect
@@ -212,7 +199,8 @@ def gather_imports(imp):
     # dn = os.path.dirname(f)
     # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
     # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
         top_package = os.path.dirname(m.__file__)
         module_import = True
     else:
@@ -233,7 +221,7 @@ def gather_imports(imp):
             for file in files:
                 if file.endswith(".py"):
                     fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
                     zip.write(fpath, v)
 
     resources['zipfile'] = zip_buffer.getvalue()
@@ -277,14 +265,14 @@ def gather_upload_to_campusnet(report, output_dir=None):
     results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
                                           show_progress_bar=not args.noprogress,
                                           big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
     # also load the source code of missing files...
 
     sources = {}
-
+    print("")
     if not args.autolab:
         if len(report.individual_imports) > 0:
             print("By uploading the .token file, you verify the files:")
@@ -297,12 +285,15 @@ def gather_upload_to_campusnet(report, output_dir=None):
             print("Including files in upload...")
             for k, m in enumerate(report.pack_imports):
                 nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
                 nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
                 nimp['name'] = m.__name__
                 sources[k] = nimp
                 # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
+                print(f" * {m.__name__}")
                 # sources = {**sources, **nimp}
     results['sources'] = sources
 
@@ -315,15 +306,17 @@ def gather_upload_to_campusnet(report, output_dir=None):
     vstring = "_v"+report.version if report.version is not None else ""
 
     token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
-    token = os.path.join(output_dir, token)
+    token = os.path.normpath(os.path.join(output_dir, token))
+
+
     with open(token, 'wb') as f:
         pickle.dump(results, f)
 
     if not args.autolab:
         print(" ")
-        print("To get credit for your results, please upload the single file: ")
+        print("To get credit for your results, please upload the single unmodified file: ")
         print(">", token)
-        print("To campusnet without any modifications.")
+        # print("To campusnet without any modifications.")
 
         # print("Now time for some autolab fun")
 
@@ -336,8 +329,8 @@ def source_instantiate(name, report1_source, payload):
 
 
 
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\n# class MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n#     raise Exception("no suite")\n#     pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        # item_title = item_title.split("\\n")[0]\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    def capture(self):\n        return Capturing2(stdout=self._stdout)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        self._stdout = sys.stdout\n        import io\n        sys.stdout = io.StringIO()\n        super().setUp()\n        # print("Setting up...")\n\n    def _callTearDown(self):\n        sys.stdout = self._stdout\n        super().tearDown()\n        # print("asdfsfd")\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n# from unitgrade2.unitgrade2 import MySuite\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n    @hide\n    def test_add_hidden(self):\n        # This is a hidden test. The @hide-decorator will allow unitgrade to remove the test.\n        # See the output in the student directory for more information.\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n    @hide\n    def test_hidden_fail(self):\n        self.assertEqual(2,3)\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
-report1_payload = '80049586000000000000007d94288c055765656b31947d94288c055765656b31948c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b04756803680486948c0474696d659486944700000000000000008c0474696d6594473f60628000000000758c0d4175746f6d6174696350617373947d94680c473f689d000000000073752e'
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            # print(self.questions)\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                print("q is", q())\n                q()._cache_put(\'time\', q.time) # = q.time\n                report_cache[q.__qualname__] = q._cache2\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            # self._stdout = sys.stdout\n            # sys._stdout = io.StringIO()\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f" * q{n+1})   Total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.normpath(os.path.join(output_dir, token))\n\n\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n    @hide\n    def test_add_hidden(self):\n        # This is a hidden test. The @hide-decorator will allow unitgrade to remove the test.\n        # See the output in the student directory for more information.\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n    @hide\n    def test_hidden_fail(self):\n        self.assertEqual(2,3)\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
+report1_payload = '80049589000000000000007d94288c055765656b31947d942868018c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b047568018c0f746573745f6164645f68696464656e948694680586947d944b004b04738c0474696d6594473fe3b8a400000000758c0d4175746f6d6174696350617373947d94680c473fc45a520000000073752e'
 name="Report3"
 
 report = source_instantiate(name, report1_source, report1_payload)
diff --git a/examples/example_docker/instructor/cs103/report3_grade.py b/examples/example_docker/instructor/cs103/report3_grade.py
index 06bc99f..3b6b512 100644
--- a/examples/example_docker/instructor/cs103/report3_grade.py
+++ b/examples/example_docker/instructor/cs103/report3_grade.py
@@ -4,15 +4,10 @@ from tabulate import tabulate
 from datetime import datetime
 import pyfiglet
 import unittest
-# from unitgrade2.unitgrade2 import MySuite
-
 import inspect
 import os
 import argparse
-import sys
 import time
-import threading # don't import Thread bc. of minify issue.
-import tqdm # don't do from tqdm import tqdm because of minify-issue
 
 parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
 To run all tests in a report: 
@@ -113,24 +108,20 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
     else:
         b = "Unitgrade"
-    print(b + " v" + __version__)
     dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
-    print("Started: " + dt_string)
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
     s = report.title
     if hasattr(report, "version") and report.version is not None:
         s += " version " + report.version
-    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
+    print(s, "(use --help for options)" if show_help_flag else "")
     # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
     table_data = []
-    nL = 80
     t_start = time.time()
     score = {}
     loader = SequentialTestLoader()
 
     for n, (q, w) in enumerate(report.questions):
-        # q = q()
-        # q_hidden = False
-        # q_hidden = issubclass(q.__class__, Hidden)
         if question is not None and n+1 != question:
             continue
         suite = loader.loadTestsFromTestCase(q)
@@ -140,11 +131,10 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         q.possible = 0
         q.obtained = 0
         q_ = {} # Gather score in this class.
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
         UTextResult.q_title_print = q_title_print # Hacky
         UTextResult.show_progress_bar = show_progress_bar # Hacky.
         UTextResult.number = n
+        UTextResult.nL = report.nL
 
         res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
 
@@ -153,20 +143,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
 
         assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
 
-        # possible = int(ws @ possible)
-        # obtained = int(ws @ obtained)
-        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
-
         obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
         score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
         q.obtained = obtained
         q.possible = possible
 
-        s1 = f"*** Question q{n+1}"
+        s1 = f" * q{n+1})   Total"
         s2 = f" {q.obtained}/{w}"
-        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
         print(" ")
-        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
 
     ws, possible, obtained = upack(score)
     possible = int( msum(possible) )
@@ -181,15 +167,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
     seconds = dt - minutes*60
     plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
 
-    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
 
     table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
     results = {'total': (obtained, possible), 'details': score}
     return results, table_data
 
 
-
-
 from tabulate import tabulate
 from datetime import datetime
 import inspect
@@ -212,7 +199,8 @@ def gather_imports(imp):
     # dn = os.path.dirname(f)
     # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
     # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
         top_package = os.path.dirname(m.__file__)
         module_import = True
     else:
@@ -233,7 +221,7 @@ def gather_imports(imp):
             for file in files:
                 if file.endswith(".py"):
                     fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
                     zip.write(fpath, v)
 
     resources['zipfile'] = zip_buffer.getvalue()
@@ -277,14 +265,14 @@ def gather_upload_to_campusnet(report, output_dir=None):
     results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
                                           show_progress_bar=not args.noprogress,
                                           big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
     # also load the source code of missing files...
 
     sources = {}
-
+    print("")
     if not args.autolab:
         if len(report.individual_imports) > 0:
             print("By uploading the .token file, you verify the files:")
@@ -297,12 +285,15 @@ def gather_upload_to_campusnet(report, output_dir=None):
             print("Including files in upload...")
             for k, m in enumerate(report.pack_imports):
                 nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
                 nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
                 nimp['name'] = m.__name__
                 sources[k] = nimp
                 # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
+                print(f" * {m.__name__}")
                 # sources = {**sources, **nimp}
     results['sources'] = sources
 
@@ -315,15 +306,17 @@ def gather_upload_to_campusnet(report, output_dir=None):
     vstring = "_v"+report.version if report.version is not None else ""
 
     token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
-    token = os.path.join(output_dir, token)
+    token = os.path.normpath(os.path.join(output_dir, token))
+
+
     with open(token, 'wb') as f:
         pickle.dump(results, f)
 
     if not args.autolab:
         print(" ")
-        print("To get credit for your results, please upload the single file: ")
+        print("To get credit for your results, please upload the single unmodified file: ")
         print(">", token)
-        print("To campusnet without any modifications.")
+        # print("To campusnet without any modifications.")
 
         # print("Now time for some autolab fun")
 
@@ -336,8 +329,8 @@ def source_instantiate(name, report1_source, payload):
 
 
 
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\n# class MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n#     raise Exception("no suite")\n#     pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        # item_title = item_title.split("\\n")[0]\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    def capture(self):\n        return Capturing2(stdout=self._stdout)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        self._stdout = sys.stdout\n        import io\n        sys.stdout = io.StringIO()\n        super().setUp()\n        # print("Setting up...")\n\n    def _callTearDown(self):\n        sys.stdout = self._stdout\n        super().tearDown()\n        # print("asdfsfd")\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n# from unitgrade2.unitgrade2 import MySuite\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
-report1_payload = '80049525010000000000007d94288c055765656b31947d94288c055765656b31948c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b04756803680486948c0474696d65948694473f506a000000000068038c0f746573745f6164645f68696464656e948694680686947d944b004b04736803680c8694680a86944700000000000000008c0474696d6594473f926de000000000758c0d4175746f6d6174696350617373947d94288c0d4175746f6d6174696350617373948c10746573745f68696464656e5f6661696c9486948c066173736572749486947d9468158c13746573745f73747564656e745f706173736564948694681886947d946815681b86948c0474696d659486944700000000000000006812473f9894100000000075752e'
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            # print(self.questions)\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                print("q is", q())\n                q()._cache_put(\'time\', q.time) # = q.time\n                report_cache[q.__qualname__] = q._cache2\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            # self._stdout = sys.stdout\n            # sys._stdout = io.StringIO()\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f" * q{n+1})   Total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.normpath(os.path.join(output_dir, token))\n\n\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
+report1_payload = '80049568000000000000007d94288c055765656b31947d942868018c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b04758c0474696d6594473fb71ac800000000758c0d4175746f6d6174696350617373947d946808473fb127100000000073752e'
 name="Report3"
 
 report = source_instantiate(name, report1_source, report1_payload)
diff --git a/examples/example_docker/instructor/cs103/unitgrade/AutomaticPass.pkl b/examples/example_docker/instructor/cs103/unitgrade/AutomaticPass.pkl
index 2a722e2b9c8264b76eca73fec2c7dd84eb0e02d3..9b6ff7ac689837f86e1b0e393993ec7acbb784e8 100644
GIT binary patch
literal 4
LcmZo*@zVnU0@?uq

literal 93
zcmZo*nHt0Z0ku;!dUzd6OY(CQOEQxK5{rwc^az)v7MH{qmz1WY=9R=3Bo-H^rc7y@
m(!&N~6_reBn^HR^gE51tZAuSINoH>9l(s4E5YreKO7#HeD<BB~

diff --git a/examples/example_docker/instructor/cs103/unitgrade/Week1.pkl b/examples/example_docker/instructor/cs103/unitgrade/Week1.pkl
index fe27b785553c86fe6975853b9990eed439d2d5bc..20eb565b4b7903e4aef2d3d44e08726a2b0e14ed 100644
GIT binary patch
delta 22
ZcmWHy<85G>YRmuuwNobY=`$7U0RS=m1aSZW

delta 47
ucmcBu=WAe@>cap5wNo@E^6E=vFlI2dP3d7N$;?fi(l*5%BFVr|ss{iFA`0yQ

diff --git a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/Report3_handin_5_of_30.token b/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/Report3_handin_5_of_30.token
deleted file mode 100644
index 675c59014e1063147604cc9ab25520eb3d1bbb5e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 128198
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

diff --git a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3_complete_grade.py b/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3_complete_grade.py
deleted file mode 100644
index b053e48..0000000
--- a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3_complete_grade.py
+++ /dev/null
@@ -1,345 +0,0 @@
-
-import numpy as np
-from tabulate import tabulate
-from datetime import datetime
-import pyfiglet
-import unittest
-# from unitgrade2.unitgrade2 import MySuite
-
-import inspect
-import os
-import argparse
-import sys
-import time
-import threading # don't import Thread bc. of minify issue.
-import tqdm # don't do from tqdm import tqdm because of minify-issue
-
-parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
-To run all tests in a report: 
-
-> python assignment1_dp.py
-
-To run only question 2 or question 2.1
-
-> python assignment1_dp.py -q 2
-> python assignment1_dp.py -q 2.1
-
-Note this scripts does not grade your report. To grade your report, use:
-
-> python report1_grade.py
-
-Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
-For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
-
-> python -m course_package.report1
-
-see https://docs.python.org/3.9/using/cmdline.html
-""", formatter_class=argparse.RawTextHelpFormatter)
-parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
-parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
-parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
-parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
-parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
-
-def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
-    args = parser.parse_args()
-    if question is None and args.q is not None:
-        question = args.q
-        if "." in question:
-            question, qitem = [int(v) for v in question.split(".")]
-        else:
-            question = int(question)
-
-    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
-        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
-
-    if unmute is None:
-        unmute = args.unmute
-    if passall is None:
-        passall = args.passall
-
-    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
-                                          show_tol_err=show_tol_err)
-
-
-    if question is None:
-        print("Provisional evaluation")
-        tabulate(table_data)
-        table = table_data
-        print(tabulate(table))
-        print(" ")
-
-    fr = inspect.getouterframes(inspect.currentframe())[1].filename
-    gfile = os.path.basename(fr)[:-3] + "_grade.py"
-    if os.path.exists(gfile):
-        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
-        print(">>>", gfile)
-        print("In the same manner as you ran this file.")
-
-
-    return results
-
-
-def upack(q):
-    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
-    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
-    h = np.asarray(h)
-    return h[:,0], h[:,1], h[:,2],
-
-class UnitgradeTextRunner(unittest.TextTestRunner):
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-
-class SequentialTestLoader(unittest.TestLoader):
-    def getTestCaseNames(self, testCaseClass):
-        test_names = super().getTestCaseNames(testCaseClass)
-        # testcase_methods = list(testCaseClass.__dict__.keys())
-        ls = []
-        for C in testCaseClass.mro():
-            if issubclass(C, unittest.TestCase):
-                ls = list(C.__dict__.keys()) + ls
-        testcase_methods = ls
-        test_names.sort(key=testcase_methods.index)
-        return test_names
-
-def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
-                    show_progress_bar=True,
-                    show_tol_err=False,
-                    big_header=True):
-
-    now = datetime.now()
-    if big_header:
-        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
-        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
-    else:
-        b = "Unitgrade"
-    print(b + " v" + __version__)
-    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
-    print("Started: " + dt_string)
-    s = report.title
-    if hasattr(report, "version") and report.version is not None:
-        s += " version " + report.version
-    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
-    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
-    table_data = []
-    nL = 80
-    t_start = time.time()
-    score = {}
-    loader = SequentialTestLoader()
-
-    for n, (q, w) in enumerate(report.questions):
-        # q = q()
-        # q_hidden = False
-        # q_hidden = issubclass(q.__class__, Hidden)
-        if question is not None and n+1 != question:
-            continue
-        suite = loader.loadTestsFromTestCase(q)
-        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
-        q_title_print = "Question %i: %s"%(n+1, qtitle)
-        print(q_title_print, end="")
-        q.possible = 0
-        q.obtained = 0
-        q_ = {} # Gather score in this class.
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
-        UTextResult.q_title_print = q_title_print # Hacky
-        UTextResult.show_progress_bar = show_progress_bar # Hacky.
-        UTextResult.number = n
-
-        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
-
-        possible = res.testsRun
-        obtained = len(res.successes)
-
-        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
-
-        # possible = int(ws @ possible)
-        # obtained = int(ws @ obtained)
-        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
-
-        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
-        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
-        q.obtained = obtained
-        q.possible = possible
-
-        s1 = f"*** Question q{n+1}"
-        s2 = f" {q.obtained}/{w}"
-        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
-        print(" ")
-        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
-
-    ws, possible, obtained = upack(score)
-    possible = int( msum(possible) )
-    obtained = int( msum(obtained) ) # Cast to python int
-    report.possible = possible
-    report.obtained = obtained
-    now = datetime.now()
-    dt_string = now.strftime("%H:%M:%S")
-
-    dt = int(time.time()-t_start)
-    minutes = dt//60
-    seconds = dt - minutes*60
-    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
-
-    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
-
-    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
-    results = {'total': (obtained, possible), 'details': score}
-    return results, table_data
-
-
-
-
-from tabulate import tabulate
-from datetime import datetime
-import inspect
-import json
-import os
-import bz2
-import pickle
-import os
-
-def bzwrite(json_str, token): # to get around obfuscation issues
-    with getattr(bz2, 'open')(token, "wt") as f:
-        f.write(json_str)
-
-def gather_imports(imp):
-    resources = {}
-    m = imp
-    # for m in pack_imports:
-    # print(f"*** {m.__name__}")
-    f = m.__file__
-    # dn = os.path.dirname(f)
-    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
-    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
-        top_package = os.path.dirname(m.__file__)
-        module_import = True
-    else:
-        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
-        module_import = False
-
-    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
-    # top_package = os.path.dirname(top_package)
-    import zipfile
-    # import strea
-    # zipfile.ZipFile
-    import io
-    # file_like_object = io.BytesIO(my_zip_data)
-    zip_buffer = io.BytesIO()
-    with zipfile.ZipFile(zip_buffer, 'w') as zip:
-        # zip.write()
-        for root, dirs, files in os.walk(top_package):
-            for file in files:
-                if file.endswith(".py"):
-                    fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
-                    zip.write(fpath, v)
-
-    resources['zipfile'] = zip_buffer.getvalue()
-    resources['top_package'] = top_package
-    resources['module_import'] = module_import
-    return resources, top_package
-
-    if f.endswith("__init__.py"):
-        for root, dirs, files in os.walk(os.path.dirname(f)):
-            for file in files:
-                if file.endswith(".py"):
-                    # print(file)
-                    # print()
-                    v = os.path.relpath(os.path.join(root, file), top_package)
-                    with open(os.path.join(root, file), 'r') as ff:
-                        resources[v] = ff.read()
-    else:
-        v = os.path.relpath(f, top_package)
-        with open(f, 'r') as ff:
-            resources[v] = ff.read()
-    return resources
-
-import argparse
-parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
-
-> python report1_grade.py
-
-Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
-For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
-
-> python -m course_package.report1
-
-see https://docs.python.org/3.9/using/cmdline.html
-""", formatter_class=argparse.RawTextHelpFormatter)
-parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
-parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
-
-def gather_upload_to_campusnet(report, output_dir=None):
-    n = report.nL
-    args = parser.parse_args()
-    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
-                                          show_progress_bar=not args.noprogress,
-                                          big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
-    # also load the source code of missing files...
-
-    sources = {}
-
-    if not args.autolab:
-        if len(report.individual_imports) > 0:
-            print("By uploading the .token file, you verify the files:")
-            for m in report.individual_imports:
-                print(">", m.__file__)
-            print("Are created/modified individually by you in agreement with DTUs exam rules")
-            report.pack_imports += report.individual_imports
-
-        if len(report.pack_imports) > 0:
-            print("Including files in upload...")
-            for k, m in enumerate(report.pack_imports):
-                nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
-                nimp['report_relative_location'] = report_relative_location
-                nimp['name'] = m.__name__
-                sources[k] = nimp
-                # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
-                # sources = {**sources, **nimp}
-    results['sources'] = sources
-
-    if output_dir is None:
-        output_dir = os.getcwd()
-
-    payload_out_base = report.__class__.__name__ + "_handin"
-
-    obtain, possible = results['total']
-    vstring = "_v"+report.version if report.version is not None else ""
-
-    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
-    token = os.path.join(output_dir, token)
-    with open(token, 'wb') as f:
-        pickle.dump(results, f)
-
-    if not args.autolab:
-        print(" ")
-        print("To get credit for your results, please upload the single file: ")
-        print(">", token)
-        print("To campusnet without any modifications.")
-
-        # print("Now time for some autolab fun")
-
-def source_instantiate(name, report1_source, payload):
-    eval("exec")(report1_source, globals())
-    pl = pickle.loads(bytes.fromhex(payload))
-    report = eval(name)(payload=pl, strict=True)
-    # report.set_payload(pl)
-    return report
-
-
-
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\n# class MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n#     raise Exception("no suite")\n#     pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        # item_title = item_title.split("\\n")[0]\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    def capture(self):\n        return Capturing2(stdout=self._stdout)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        self._stdout = sys.stdout\n        import io\n        sys.stdout = io.StringIO()\n        super().setUp()\n        # print("Setting up...")\n\n    def _callTearDown(self):\n        sys.stdout = self._stdout\n        super().tearDown()\n        # print("asdfsfd")\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n# from unitgrade2.unitgrade2 import MySuite\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n    @hide\n    def test_add_hidden(self):\n        # This is a hidden test. The @hide-decorator will allow unitgrade to remove the test.\n        # See the output in the student directory for more information.\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n    @hide\n    def test_hidden_fail(self):\n        self.assertEqual(2,3)\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
-report1_payload = '80049586000000000000007d94288c055765656b31947d94288c055765656b31948c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b04756803680486948c0474696d659486944700000000000000008c0474696d6594473f60628000000000758c0d4175746f6d6174696350617373947d94680c473f689d000000000073752e'
-name="Report3"
-
-report = source_instantiate(name, report1_source, report1_payload)
-output_dir = os.path.dirname(__file__)
-gather_upload_to_campusnet(report, output_dir)
\ No newline at end of file
diff --git a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3_grade.py b/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3_grade.py
deleted file mode 100644
index ecff9f7..0000000
--- a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/report3_grade.py
+++ /dev/null
@@ -1,347 +0,0 @@
-"""
-Example student code. This file is automatically generated from the files in the instructor-directory
-"""
-import numpy as np
-from tabulate import tabulate
-from datetime import datetime
-import pyfiglet
-import unittest
-# from unitgrade2.unitgrade2 import MySuite
-
-import inspect
-import os
-import argparse
-import sys
-import time
-import threading # don't import Thread bc. of minify issue.
-import tqdm # don't do from tqdm import tqdm because of minify-issue
-
-parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
-To run all tests in a report: 
-
-> python assignment1_dp.py
-
-To run only question 2 or question 2.1
-
-> python assignment1_dp.py -q 2
-> python assignment1_dp.py -q 2.1
-
-Note this scripts does not grade your report. To grade your report, use:
-
-> python report1_grade.py
-
-Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
-For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
-
-> python -m course_package.report1
-
-see https://docs.python.org/3.9/using/cmdline.html
-""", formatter_class=argparse.RawTextHelpFormatter)
-parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
-parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
-parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
-parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
-parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
-
-def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
-    args = parser.parse_args()
-    if question is None and args.q is not None:
-        question = args.q
-        if "." in question:
-            question, qitem = [int(v) for v in question.split(".")]
-        else:
-            question = int(question)
-
-    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
-        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
-
-    if unmute is None:
-        unmute = args.unmute
-    if passall is None:
-        passall = args.passall
-
-    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
-                                          show_tol_err=show_tol_err)
-
-
-    if question is None:
-        print("Provisional evaluation")
-        tabulate(table_data)
-        table = table_data
-        print(tabulate(table))
-        print(" ")
-
-    fr = inspect.getouterframes(inspect.currentframe())[1].filename
-    gfile = os.path.basename(fr)[:-3] + "_grade.py"
-    if os.path.exists(gfile):
-        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
-        print(">>>", gfile)
-        print("In the same manner as you ran this file.")
-
-
-    return results
-
-
-def upack(q):
-    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
-    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
-    h = np.asarray(h)
-    return h[:,0], h[:,1], h[:,2],
-
-class UnitgradeTextRunner(unittest.TextTestRunner):
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-
-class SequentialTestLoader(unittest.TestLoader):
-    def getTestCaseNames(self, testCaseClass):
-        test_names = super().getTestCaseNames(testCaseClass)
-        # testcase_methods = list(testCaseClass.__dict__.keys())
-        ls = []
-        for C in testCaseClass.mro():
-            if issubclass(C, unittest.TestCase):
-                ls = list(C.__dict__.keys()) + ls
-        testcase_methods = ls
-        test_names.sort(key=testcase_methods.index)
-        return test_names
-
-def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
-                    show_progress_bar=True,
-                    show_tol_err=False,
-                    big_header=True):
-
-    now = datetime.now()
-    if big_header:
-        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
-        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
-    else:
-        b = "Unitgrade"
-    print(b + " v" + __version__)
-    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
-    print("Started: " + dt_string)
-    s = report.title
-    if hasattr(report, "version") and report.version is not None:
-        s += " version " + report.version
-    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
-    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
-    table_data = []
-    nL = 80
-    t_start = time.time()
-    score = {}
-    loader = SequentialTestLoader()
-
-    for n, (q, w) in enumerate(report.questions):
-        # q = q()
-        # q_hidden = False
-        # q_hidden = issubclass(q.__class__, Hidden)
-        if question is not None and n+1 != question:
-            continue
-        suite = loader.loadTestsFromTestCase(q)
-        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
-        q_title_print = "Question %i: %s"%(n+1, qtitle)
-        print(q_title_print, end="")
-        q.possible = 0
-        q.obtained = 0
-        q_ = {} # Gather score in this class.
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
-        UTextResult.q_title_print = q_title_print # Hacky
-        UTextResult.show_progress_bar = show_progress_bar # Hacky.
-        UTextResult.number = n
-
-        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
-
-        possible = res.testsRun
-        obtained = len(res.successes)
-
-        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
-
-        # possible = int(ws @ possible)
-        # obtained = int(ws @ obtained)
-        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
-
-        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
-        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
-        q.obtained = obtained
-        q.possible = possible
-
-        s1 = f"*** Question q{n+1}"
-        s2 = f" {q.obtained}/{w}"
-        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
-        print(" ")
-        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
-
-    ws, possible, obtained = upack(score)
-    possible = int( msum(possible) )
-    obtained = int( msum(obtained) ) # Cast to python int
-    report.possible = possible
-    report.obtained = obtained
-    now = datetime.now()
-    dt_string = now.strftime("%H:%M:%S")
-
-    dt = int(time.time()-t_start)
-    minutes = dt//60
-    seconds = dt - minutes*60
-    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
-
-    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
-
-    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
-    results = {'total': (obtained, possible), 'details': score}
-    return results, table_data
-
-
-
-
-from tabulate import tabulate
-from datetime import datetime
-import inspect
-import json
-import os
-import bz2
-import pickle
-import os
-
-def bzwrite(json_str, token): # to get around obfuscation issues
-    with getattr(bz2, 'open')(token, "wt") as f:
-        f.write(json_str)
-
-def gather_imports(imp):
-    resources = {}
-    m = imp
-    # for m in pack_imports:
-    # print(f"*** {m.__name__}")
-    f = m.__file__
-    # dn = os.path.dirname(f)
-    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
-    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
-        top_package = os.path.dirname(m.__file__)
-        module_import = True
-    else:
-        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
-        module_import = False
-
-    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
-    # top_package = os.path.dirname(top_package)
-    import zipfile
-    # import strea
-    # zipfile.ZipFile
-    import io
-    # file_like_object = io.BytesIO(my_zip_data)
-    zip_buffer = io.BytesIO()
-    with zipfile.ZipFile(zip_buffer, 'w') as zip:
-        # zip.write()
-        for root, dirs, files in os.walk(top_package):
-            for file in files:
-                if file.endswith(".py"):
-                    fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
-                    zip.write(fpath, v)
-
-    resources['zipfile'] = zip_buffer.getvalue()
-    resources['top_package'] = top_package
-    resources['module_import'] = module_import
-    return resources, top_package
-
-    if f.endswith("__init__.py"):
-        for root, dirs, files in os.walk(os.path.dirname(f)):
-            for file in files:
-                if file.endswith(".py"):
-                    # print(file)
-                    # print()
-                    v = os.path.relpath(os.path.join(root, file), top_package)
-                    with open(os.path.join(root, file), 'r') as ff:
-                        resources[v] = ff.read()
-    else:
-        v = os.path.relpath(f, top_package)
-        with open(f, 'r') as ff:
-            resources[v] = ff.read()
-    return resources
-
-import argparse
-parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
-
-> python report1_grade.py
-
-Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
-For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
-
-> python -m course_package.report1
-
-see https://docs.python.org/3.9/using/cmdline.html
-""", formatter_class=argparse.RawTextHelpFormatter)
-parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
-parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
-
-def gather_upload_to_campusnet(report, output_dir=None):
-    n = report.nL
-    args = parser.parse_args()
-    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
-                                          show_progress_bar=not args.noprogress,
-                                          big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
-    # also load the source code of missing files...
-
-    sources = {}
-
-    if not args.autolab:
-        if len(report.individual_imports) > 0:
-            print("By uploading the .token file, you verify the files:")
-            for m in report.individual_imports:
-                print(">", m.__file__)
-            print("Are created/modified individually by you in agreement with DTUs exam rules")
-            report.pack_imports += report.individual_imports
-
-        if len(report.pack_imports) > 0:
-            print("Including files in upload...")
-            for k, m in enumerate(report.pack_imports):
-                nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
-                nimp['report_relative_location'] = report_relative_location
-                nimp['name'] = m.__name__
-                sources[k] = nimp
-                # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
-                # sources = {**sources, **nimp}
-    results['sources'] = sources
-
-    if output_dir is None:
-        output_dir = os.getcwd()
-
-    payload_out_base = report.__class__.__name__ + "_handin"
-
-    obtain, possible = results['total']
-    vstring = "_v"+report.version if report.version is not None else ""
-
-    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
-    token = os.path.join(output_dir, token)
-    with open(token, 'wb') as f:
-        pickle.dump(results, f)
-
-    if not args.autolab:
-        print(" ")
-        print("To get credit for your results, please upload the single file: ")
-        print(">", token)
-        print("To campusnet without any modifications.")
-
-        # print("Now time for some autolab fun")
-
-def source_instantiate(name, report1_source, payload):
-    eval("exec")(report1_source, globals())
-    pl = pickle.loads(bytes.fromhex(payload))
-    report = eval(name)(payload=pl, strict=True)
-    # report.set_payload(pl)
-    return report
-
-
-
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\n# class MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n#     raise Exception("no suite")\n#     pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        # item_title = item_title.split("\\n")[0]\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    def capture(self):\n        return Capturing2(stdout=self._stdout)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        self._stdout = sys.stdout\n        import io\n        sys.stdout = io.StringIO()\n        super().setUp()\n        # print("Setting up...")\n\n    def _callTearDown(self):\n        sys.stdout = self._stdout\n        super().tearDown()\n        # print("asdfsfd")\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n# from unitgrade2.unitgrade2 import MySuite\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
-report1_payload = '80049525010000000000007d94288c055765656b31947d94288c055765656b31948c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b04756803680486948c0474696d65948694473f506a000000000068038c0f746573745f6164645f68696464656e948694680686947d944b004b04736803680c8694680a86944700000000000000008c0474696d6594473f926de000000000758c0d4175746f6d6174696350617373947d94288c0d4175746f6d6174696350617373948c10746573745f68696464656e5f6661696c9486948c066173736572749486947d9468158c13746573745f73747564656e745f706173736564948694681886947d946815681b86948c0474696d659486944700000000000000006812473f9894100000000075752e'
-name="Report3"
-
-report = source_instantiate(name, report1_source, report1_payload)
-output_dir = os.path.dirname(__file__)
-gather_upload_to_campusnet(report, output_dir)
diff --git a/examples/example_docker/run_all_docker.py b/examples/example_docker/run_all_docker.py
new file mode 100644
index 0000000..15e9ea7
--- /dev/null
+++ b/examples/example_docker/run_all_docker.py
@@ -0,0 +1,57 @@
+from unitgrade_private2.docker_helpers import docker_run_token_file
+import os
+import glob
+import pickle
+import time
+
+""" Run all examples on docker. """
+
+if __name__ == "__main__":
+    # Step 0: Compile our two docker images.
+    from unitgrade_private2.docker_helpers import compile_docker_image
+
+    docker_files = [f"{os.getcwd()}/../../docker_images/unitgrade-docker/Dockerfile"]
+    docker_tags = []
+    for f in docker_files:
+        tag = compile_docker_image(f)
+        docker_tags.append( (f, tag) )
+
+    EX_BASE =  f"{os.getcwd()}/../" # Base of examples.
+
+    runs = [
+        ("example_flat", "programs", "programs/report1flat_grade.py", "programs", "programs/report1flat_grade.py",),
+        ("example_simplest", "", "cs101/report1_grade.py", "", "cs101/report1_grade.py", ),
+        ("example_framework", "", "cs102/report2_grade.py", "", "cs102/report2_grade.py", ),
+        ("example_docker", "", "cs103/report3_complete_grade.py", "", "cs103/report3_grade.py",),
+             ]
+    rs = []
+
+    def p2mod(file, base):
+        return ".".join(os.path.normpath(os.path.relpath(file, base)).split(os.sep))[:-3]
+    start = time.time()
+    for ex, ibase, ig, sbase, sg in runs:
+        ibase = f"{EX_BASE}/{ex}/instructor/{ibase}"
+        ig = f"{EX_BASE}/{ex}/instructor/{ig}"
+        sbase = f"{EX_BASE}/{ex}/students/{sbase}"
+        sg = f"{EX_BASE}/{ex}/students/{sg}"
+
+        # Uncomment to run example deployment scripts:
+        # os.system(f"cd {ibase} && python -m {p2mod(os.path.dirname(ig) + '/deploy.py', ibase)}")
+
+        os.system(f"cd {sbase} && python -m { p2mod(sg, sbase) }")
+        stoken = glob.glob(f"{os.path.dirname(sg)}/*.token")[0]
+
+        Dockerfile, tag = docker_tags[0] # Get first docker file.
+        token = docker_run_token_file(Dockerfile_location=Dockerfile,
+                                      host_tmp_dir=os.path.dirname(Dockerfile) + "/tmp",
+                                      student_token_file=stoken,
+                                      instructor_grade_script=ig)
+        with open(token, 'rb') as f:
+            iresults = pickle.load(f)
+        with open(stoken, 'rb') as f:
+            sresults = pickle.load(f)
+        rs.append( (ex, sresults, iresults) )
+
+    for ex, sresults, iresults in rs:
+        print( f"[{ex}]", "Student's score was:", sresults['total'], "score using my eval script", iresults['total'])
+    print("Total elapsed time", time.time()-start, "seconds")
\ No newline at end of file
diff --git a/examples/example_docker/students/cs103/.coverage b/examples/example_docker/students/cs103/.coverage
new file mode 100644
index 0000000000000000000000000000000000000000..f386b2198168450113494de5b3b3bd99d653d108
GIT binary patch
literal 53248
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
Z7!85Z5Eu=C(GVC7fzc2c4FSR-0004q+NS^j

literal 0
HcmV?d00001

diff --git a/examples/example_docker/students/cs103/Report3_handin_10_of_30.token b/examples/example_docker/students/cs103/Report3_handin_10_of_30.token
index 7231343c1882f4366cfe40348680c8d947889798..3880b47087c30a84d5471426ba613e6421ea54fe 100644
GIT binary patch
delta 8228
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
E0BT<w$p8QV

delta 15750
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
V171BbrH3`S*wDauN@;Pa9stCDjCTM4

diff --git a/examples/example_docker/students/cs103/__pycache__/homework1.cpython-38.pyc b/examples/example_docker/students/cs103/__pycache__/homework1.cpython-38.pyc
index 5c552a81fc42feaf0654da24d93270b73dc806af..d82e790ad8cee1871f1919af140451af558d6b85 100644
GIT binary patch
delta 20
bcmaFB{(zl3l$V!_fq{X+V6MSN?yJlIG*SfQ

delta 20
bcmaFB{(zl3l$V!_fq{WR`Jc{4?yJlIHYo)(

diff --git a/examples/example_docker/students/cs103/__pycache__/homework1.cpython-39.pyc b/examples/example_docker/students/cs103/__pycache__/homework1.cpython-39.pyc
index 6dfacc25f48700797f5286eae416edaeaf0e2b5b..0e7a0c627f56abdd78d2ba3ec05f9d13ea233030 100644
GIT binary patch
delta 20
bcmX@ec94xbk(ZZ?fq{YHakBPCZZl>8GI|7s

delta 20
bcmX@ec94xbk(ZZ?fq{V`+D&sKw;3}4E(!zQ

diff --git a/examples/example_docker/students/cs103/__pycache__/report3.cpython-38.pyc b/examples/example_docker/students/cs103/__pycache__/report3.cpython-38.pyc
index da19a02cc1c508d3eaafcf35b0b34e9d58501d7e..78157d3ccd77777a3e6bdc5d8ef57fa286b7b497 100644
GIT binary patch
delta 25
gcmaFC^@58pl$V!_fq{WRf388I7xPBGNLEH>08T#zHvj+t

delta 25
gcmaFC^@58pl$V!_fq{WR>7P#Gai)!Yk*ti209Azs0RR91

diff --git a/examples/example_docker/students/cs103/__pycache__/report3_complete.cpython-38.pyc b/examples/example_docker/students/cs103/__pycache__/report3_complete.cpython-38.pyc
index 921af5c7208e7aa4d953fa1e4551029aeb05c182..41e62d06e5af5bb771d3c92d6afde5e8a0d36380 100644
GIT binary patch
delta 24
fcmcb@dxe)bl$V!_fq{YHP>^ooj*Yy>*ch1sPU{9S

delta 24
fcmcb@dxe)bl$V!_fq{X6_n%Ip=|<jTY>bQmN<0Ok

diff --git a/examples/example_docker/students/cs103/__pycache__/report3_complete.cpython-39.pyc b/examples/example_docker/students/cs103/__pycache__/report3_complete.cpython-39.pyc
index 2f18f8be0976727ab41dd1114924b8483c6d3aac..3e87b71662ab4e431da5c9b952594f5411205f72 100644
GIT binary patch
delta 948
zcmcb|`Gl7*k(ZZ?fq{Xc>7P!b2+Kr18OFSc+Qts<3@NNBY%L5aY^jXR%u(zq3@Pk6
z98nzZ3@IEboGlC~oT*IB%u$@FTq#`HOhs9#tf`#M49$#;3@Plv44T{<`*au?Z%y9K
zD9gsrz`*dUZ1O!u1EIvylKh;+r1;c|#N2|MRDC_Y$-GRP1$Y@47>Yp3AcVl=3rv~v
zf*?T_5FrF25Yk|lz~l&Kx%y;~%aJiN0|SEt0|P^`0s{j>Dnk@w3PTiA3S$aW3qurh
zDoYA;3QG$^Gh-BM3TrTfCfhAu$I_Dg+{BX1<bcHD;$%i7vp{T+_0AyU1Q-|?Y8VzU
zq%fv1E@Wb4NMQ(O&}6FjE8=8eU|7j`i#xHnIJKz6wXifXXC-41AF7K%x^D@Wq!yRN
z7nhW#q~?{x7l1UR2!qUK0$IvfrHJAbJuIp*oL7&{eN1roF+-g95)>#!5+El@fe3K;
zfeEm?1i&_BWTvE~=EbKaX6A^&9mP~7hs99{rS&;}nruZNPZWuOOcn(Z(jWrlup(Iy
z3v3aB09jci&cMI`iqv8@1_lNWMh<2sMzEM4?)X$giBE7`GNp+#rLv|lr!l27MX{x_
zr!z)zq_6}tXtGY;&MaU55|pg{G&#}ScZ;<ovm__A2xK+b(p#K`rK!awnfZCew^);l
z4GoNM@f0K`XUAve7UUO|6hqP^nh)d{7#Khvh5CSnQGl@sBzB7<K0Y@wGcP`#S(E$L
zWIq;F##@t1STsFAUM^Aw1qetP#7zh@!7NbF+~Tmw%}*)KNwotdzhY225@F<F65tcy
L;9wMB<zNH=sMEQn

delta 416
zcmaFDdykVZk(ZZ?fq{V`+D$Vtgn1&L3}f6xZDWHJh7{Hu_9%9Dh7`6G_7;W|_Ee^3
z<|vL-&J>PprlP1+)>MvWhGs@ah7{Id22IY5^K=*)qb8qblx5>%U|{%_Joz1?!DK_G
zO#(a&3=BmeF$lpw`7=|dyZ}g$1w;sf2!u44#Xq^4Sx&|;8RRZx%*4RJ;K0DZP^>Vy
zkyTV6oiU0vl`Wkyiamunm_d_e@)}n8dOuB$A|a5O!XQF~fq~%`Ye{BFPHGVw0|P@8
zXJKh-aY<%=Uhyr~<YGeu<0zhj#N_Pw%-n+fqLN~W8^MkM6Z{}U#26SDK&BOgOyFQ-
zVdP>g0*T$?h>y=r%*>0A*W`*4EzQd;NiUil!Y0QUHMy8g(@_$p7vdhUc?bez@+}UV
d-29Z%oK!nTkgq@?CBn$VB*4ePD8S0W2ms_4PRalP

diff --git a/examples/example_docker/instructor/unitgrade-docker/tmp/cs103/__pycache__/report3_complete_grade.cpython-38.pyc b/examples/example_docker/students/cs103/__pycache__/report3_complete_grade.cpython-39.pyc
similarity index 90%
rename from examples/example_docker/instructor/unitgrade-docker/tmp/cs103/__pycache__/report3_complete_grade.cpython-38.pyc
rename to examples/example_docker/students/cs103/__pycache__/report3_complete_grade.cpython-39.pyc
index 8bcaebe92988bf2a57647836e6aabc65f30fdadc..5efad03805d904ffdc7a11abb12cf5d179ea47c5 100644
GIT binary patch
delta 2103
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

delta 1936
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

diff --git a/examples/example_docker/students/cs103/__pycache__/report3_grade.cpython-38.pyc b/examples/example_docker/students/cs103/__pycache__/report3_grade.cpython-38.pyc
index 7433fca776754f5b6910141e9adc509cbf13a6f5..fe08941631eb3353b6394ba8fca90bb65c4db357 100644
GIT binary patch
delta 10563
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
LETDxAOdyp2L8pMq

delta 17866
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
JpM?pe5&-@WOrZb(

diff --git a/examples/example_docker/students/cs103/report3.py b/examples/example_docker/students/cs103/report3.py
index c97b5a4..f83bb53 100644
--- a/examples/example_docker/students/cs103/report3.py
+++ b/examples/example_docker/students/cs103/report3.py
@@ -1,8 +1,8 @@
 """
 Example student code. This file is automatically generated from the files in the instructor-directory
 """
-from unitgrade2.unitgrade2 import UTestCase, Report, hide
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
+from src.unitgrade2.unitgrade2 import UTestCase, Report
+from src.unitgrade2 import evaluate_report_student
 
 class Week1(UTestCase):
     """ The first question for week 1. """
@@ -24,4 +24,6 @@ class Report3(Report):
     pack_imports = [cs103]
 
 if __name__ == "__main__":
+    # from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
+    # gather_upload_to_campusnet(Report3())
     evaluate_report_student(Report3())
diff --git a/examples/example_docker/students/cs103/report3_grade.py b/examples/example_docker/students/cs103/report3_grade.py
index ecff9f7..3c64c04 100644
--- a/examples/example_docker/students/cs103/report3_grade.py
+++ b/examples/example_docker/students/cs103/report3_grade.py
@@ -6,15 +6,10 @@ from tabulate import tabulate
 from datetime import datetime
 import pyfiglet
 import unittest
-# from unitgrade2.unitgrade2 import MySuite
-
 import inspect
 import os
 import argparse
-import sys
 import time
-import threading # don't import Thread bc. of minify issue.
-import tqdm # don't do from tqdm import tqdm because of minify-issue
 
 parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
 To run all tests in a report: 
@@ -115,24 +110,20 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
     else:
         b = "Unitgrade"
-    print(b + " v" + __version__)
     dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
-    print("Started: " + dt_string)
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
     s = report.title
     if hasattr(report, "version") and report.version is not None:
         s += " version " + report.version
-    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
+    print(s, "(use --help for options)" if show_help_flag else "")
     # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
     table_data = []
-    nL = 80
     t_start = time.time()
     score = {}
     loader = SequentialTestLoader()
 
     for n, (q, w) in enumerate(report.questions):
-        # q = q()
-        # q_hidden = False
-        # q_hidden = issubclass(q.__class__, Hidden)
         if question is not None and n+1 != question:
             continue
         suite = loader.loadTestsFromTestCase(q)
@@ -142,11 +133,10 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         q.possible = 0
         q.obtained = 0
         q_ = {} # Gather score in this class.
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
         UTextResult.q_title_print = q_title_print # Hacky
         UTextResult.show_progress_bar = show_progress_bar # Hacky.
         UTextResult.number = n
+        UTextResult.nL = report.nL
 
         res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
 
@@ -155,20 +145,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
 
         assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
 
-        # possible = int(ws @ possible)
-        # obtained = int(ws @ obtained)
-        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
-
         obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
         score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
         q.obtained = obtained
         q.possible = possible
 
-        s1 = f"*** Question q{n+1}"
+        s1 = f" * q{n+1})   Total"
         s2 = f" {q.obtained}/{w}"
-        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
         print(" ")
-        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
 
     ws, possible, obtained = upack(score)
     possible = int( msum(possible) )
@@ -183,15 +169,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
     seconds = dt - minutes*60
     plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
 
-    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
 
     table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
     results = {'total': (obtained, possible), 'details': score}
     return results, table_data
 
 
-
-
 from tabulate import tabulate
 from datetime import datetime
 import inspect
@@ -214,7 +201,8 @@ def gather_imports(imp):
     # dn = os.path.dirname(f)
     # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
     # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
         top_package = os.path.dirname(m.__file__)
         module_import = True
     else:
@@ -235,7 +223,7 @@ def gather_imports(imp):
             for file in files:
                 if file.endswith(".py"):
                     fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
                     zip.write(fpath, v)
 
     resources['zipfile'] = zip_buffer.getvalue()
@@ -279,14 +267,14 @@ def gather_upload_to_campusnet(report, output_dir=None):
     results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
                                           show_progress_bar=not args.noprogress,
                                           big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
     # also load the source code of missing files...
 
     sources = {}
-
+    print("")
     if not args.autolab:
         if len(report.individual_imports) > 0:
             print("By uploading the .token file, you verify the files:")
@@ -299,12 +287,15 @@ def gather_upload_to_campusnet(report, output_dir=None):
             print("Including files in upload...")
             for k, m in enumerate(report.pack_imports):
                 nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
                 nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
                 nimp['name'] = m.__name__
                 sources[k] = nimp
                 # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
+                print(f" * {m.__name__}")
                 # sources = {**sources, **nimp}
     results['sources'] = sources
 
@@ -317,15 +308,17 @@ def gather_upload_to_campusnet(report, output_dir=None):
     vstring = "_v"+report.version if report.version is not None else ""
 
     token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
-    token = os.path.join(output_dir, token)
+    token = os.path.normpath(os.path.join(output_dir, token))
+
+
     with open(token, 'wb') as f:
         pickle.dump(results, f)
 
     if not args.autolab:
         print(" ")
-        print("To get credit for your results, please upload the single file: ")
+        print("To get credit for your results, please upload the single unmodified file: ")
         print(">", token)
-        print("To campusnet without any modifications.")
+        # print("To campusnet without any modifications.")
 
         # print("Now time for some autolab fun")
 
@@ -338,8 +331,8 @@ def source_instantiate(name, report1_source, payload):
 
 
 
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\n# class MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n#     raise Exception("no suite")\n#     pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        # item_title = item_title.split("\\n")[0]\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    def capture(self):\n        return Capturing2(stdout=self._stdout)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        self._stdout = sys.stdout\n        import io\n        sys.stdout = io.StringIO()\n        super().setUp()\n        # print("Setting up...")\n\n    def _callTearDown(self):\n        sys.stdout = self._stdout\n        super().tearDown()\n        # print("asdfsfd")\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n# from unitgrade2.unitgrade2 import MySuite\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
-report1_payload = '80049525010000000000007d94288c055765656b31947d94288c055765656b31948c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b04756803680486948c0474696d65948694473f506a000000000068038c0f746573745f6164645f68696464656e948694680686947d944b004b04736803680c8694680a86944700000000000000008c0474696d6594473f926de000000000758c0d4175746f6d6174696350617373947d94288c0d4175746f6d6174696350617373948c10746573745f68696464656e5f6661696c9486948c066173736572749486947d9468158c13746573745f73747564656e745f706173736564948694681886947d946815681b86948c0474696d659486944700000000000000006812473f9894100000000075752e'
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            # print(self.questions)\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                print("q is", q())\n                q()._cache_put(\'time\', q.time) # = q.time\n                report_cache[q.__qualname__] = q._cache2\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            # self._stdout = sys.stdout\n            # sys._stdout = io.StringIO()\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f" * q{n+1})   Total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.normpath(os.path.join(output_dir, token))\n\n\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        from cs103.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n\nclass AutomaticPass(UTestCase):\n    def test_student_passed(self):\n        self.assertEqual(2,2)\n\n\nimport cs103\nclass Report3(Report):\n    title = "CS 101 Report 3"\n    questions = [(Week1, 20), (AutomaticPass, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs103]'
+report1_payload = '80049568000000000000007d94288c055765656b31947d942868018c08746573745f6164649486948c066173736572749486947d94284b014aa1ffffff4b004b04758c0474696d6594473fb71ac800000000758c0d4175746f6d6174696350617373947d946808473fb127100000000073752e'
 name="Report3"
 
 report = source_instantiate(name, report1_source, report1_payload)
diff --git a/examples/example_docker/students/cs103/unitgrade/AutomaticPass.pkl b/examples/example_docker/students/cs103/unitgrade/AutomaticPass.pkl
index 2a722e2b9c8264b76eca73fec2c7dd84eb0e02d3..9b6ff7ac689837f86e1b0e393993ec7acbb784e8 100644
GIT binary patch
literal 4
LcmZo*@zVnU0@?uq

literal 93
zcmZo*nHt0Z0ku;!dUzd6OY(CQOEQxK5{rwc^az)v7MH{qmz1WY=9R=3Bo-H^rc7y@
m(!&N~6_reBn^HR^gE51tZAuSINoH>9l(s4E5YreKO7#HeD<BB~

diff --git a/examples/example_docker/students/cs103/unitgrade/Week1.pkl b/examples/example_docker/students/cs103/unitgrade/Week1.pkl
index fe27b785553c86fe6975853b9990eed439d2d5bc..20eb565b4b7903e4aef2d3d44e08726a2b0e14ed 100644
GIT binary patch
delta 22
ZcmWHy<85G>YRmuuwNobY=`$7U0RS=m1aSZW

delta 47
ucmcBu=WAe@>cap5wNo@E^6E=vFlI2dP3d7N$;?fi(l*5%BFVr|ss{iFA`0yQ

diff --git a/examples/example_flat/instructor/cs101flat/Report1Flat_handin_10_of_10.token b/examples/example_flat/instructor/cs101flat/Report1Flat_handin_10_of_10.token
new file mode 100644
index 0000000000000000000000000000000000000000..6207232bba6714f3ffac3686c93f17dac4be1cb1
GIT binary patch
literal 65761
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
V5_?!csd!2cCp?a(loprj0RUJp^)mnf

literal 0
HcmV?d00001

diff --git a/examples/example_flat/instructor/cs101flat/__pycache__/deploy.cpython-38.pyc b/examples/example_flat/instructor/cs101flat/__pycache__/deploy.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9c91ca3192aaec26f60abe00c1109cb32983e52a
GIT binary patch
literal 581
zcmWIL<>g{vU|=}nr<>Ts#K7<v#6iaF3=9ko3=9m#5ey6rDGVu$ISjdsQH+crHd78$
zE^`z!n9ZESlFJ&!%E*w)mco+FR1}iRoXVKO3WjXGEQ}1PtXZrn>?s^6oGDx>+$lWi
z%qhGe@f5yb22K8#AUib~Z*d2u7UUO|7`o*omS{5G5-(0IDJ_UkFG@^FjZe$WNsTW8
z%WE>;;wa9`EQn9ZEV{)JAD^3;nHL}LrpX+|mYbQEnN}IanV*zaTAZ9%k{ZRHT9KMu
zT9SH;p-MtePhU?@zqq6{B{i?4SU<Vg(7-S)C$S{t7I%DnL1l7caz<)=d=<NvUP*p-
zYF-s*N@_t)ex+VPr6x-hS8;x6QF1EC(kPCU)Z!8_OEftrH8C$9#Lvu2EXmBz0}HdK
zRwU<?rlk65vPW@4Tn)CVh>3xLAxf<@FS7*Vt%9P=vc!^9BfX5wl$6xG_~fG0#1e>a
zi;I{+irGP4El4dYVqsul0C_hrF*h|nekDT@Cj$e7_!Z}D6%$&VT2vfUQksz(<C33T
znhWw`42DH9sTGO21v#n3Fh)Em0Ae!pic5-0lS}f8V&I_?1NZ$c4x8Nkl+v73J4R4q
R0HqloMjl2UCJsgcHURWnuU!BD

literal 0
HcmV?d00001

diff --git a/examples/example_flat/instructor/cs101flat/__pycache__/homework1.cpython-38.pyc b/examples/example_flat/instructor/cs101flat/__pycache__/homework1.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4ad952b7db7aa4adbd8a113e6d74f318bd77ce47
GIT binary patch
literal 835
zcmWIL<>g{vU|`VW&`b1VVqka-;vi#o1_lNP1_p*=HwFfV6owSW7KSK>6s8pB7KSLs
zRHhV`Y^EZoROS@cRK^sx6t-rj*$i`;ni&}xQkhfOQyEg&QaDmLQ@GMuni-p!7#UKy
zgBdh=k{OY#0I``F7#N&Ew(u}8FqANqFxD_MGd42@GiWkaE#gv8P*8BsEKAK(NL0wl
zEG|({&#eT}>Iy}vC8b4q#W3;Y{Ji4K;*!j~bcOshg_4X^h2q5ARE5->)ZEm(l46C-
zJcXjvvecsDRE7Mal++?U1y{XvJ+S#u@pzEA8qtP2Mmol^nhM1k`K382P-_&TjdhH4
z3}Y2E5@9xKLNseK-C_Z0yu|@ECPkAmiVfn(l?+87-~CE-wu%WYPAw{qDJjiJjd96O
zE(JR(rZg|JB)upxB{jaFD6=fFBsC_rA~ClhC$$*Hh)>H&EQ!g?D=sN2O)kkVib*au
zG%y4UX5{Clmgg5`8|oEQ-r|AU4)z2nSc{oJ;mlgZ%D}*o3}%D)3=9k)HVA{moP&XZ
zp@yM`QJeuB-bv7~E-BAf$SciFN-Zi@NJvajNX$!7NJvUhD9OkyR!A$&OD@UG&x3_f
zab|8oP9-d$N-|P2ixi4WbFIK(Yp0NylA@8QlccF&tB|OjqyP>PO{QCniMJS&z#Is{
z!oa|Ai#ahR1>_`%<C%*<>{}f1@wthadGYa8;*t5KMG8f!#icnVpjb9i&{i-~uvK^o
z@=ujm5IBB8DIigyI5#mT2b^MFf}-FhC>UOX611Nt3ph;RX6Gg5rpCwLVl61j%qxMo
h1*8MQ0=tUCCO1E&G$+*#9IhZYaj<i+axjT70sv2E*y8{I

literal 0
HcmV?d00001

diff --git a/examples/example_flat/instructor/cs101flat/__pycache__/report1flat.cpython-38.pyc b/examples/example_flat/instructor/cs101flat/__pycache__/report1flat.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2b843499aeb6a5314ec477e4a8ff9439e6927c59
GIT binary patch
literal 1204
zcmWIL<>g{vU|`^O*G>Gy#K7<v#6iX^3=9ko3=9m#1q=)fDGVu$ISjdsQH+crHd78$
zE^`z!n9ZESlFJ&!n#&f&2IjNmut%}GGo-Mlu(dFxu%)tRaWpeWai%b&u;j2rvA8p&
zu%~deFr;v#GBz_uaiwynaAq?V<)kvFay2tFgUn|MX3*q%337`j<1MzJ)Pnq?5>3Wi
z;;ChcIi-musqsZ%q4?sG(v;M^5>2LCJVmKxsYS)9@j02rCAXLpQ&RkrLHdy~6U;v{
z3=9mZ3{i|J3{gxej44bl3{lJ}%qc7_3{fm8ticSLY`0j$Q&Y1IlNpipgV?ML3=Gbo
zAkko8V5nhOz)-@N!kEI?%#^~kkckl{!kog=%#^|k5=mhI8Rz#BWcN!@fM(A5|Ns9>
zkU5zP|NsB5$#jc5vA8(3sKm9fG%=?LB(ak57E5tzPTER_B3=dthF{6fRxzQ)sYS&x
zC8ZguF)sPZrManjCB-qNd6^~YMTse?@dZVhWr-!JF{u@axdl0?#V|&ET25j~OlDqj
zNl|HXNq$jGa<QR-Ay^O+gkZK_LFFxulGNgo_{5YHc98c#E@fa8Vyxl=hl3tW5+gv^
zU;(0l93V_7%<0U{j48}1Oeu`%%<zC<@p}mh#UhX$FPRw_7&MuRKxwcDWM2_C0|Ugz
zU~d=kF)%RP;sM(Xja-m|Vo*pjFjfg6ISeZ8r^$MYBR)PaF*h|n{uWn!d~SY9X%2|Z
z6CV!>U5HE(Kgb>-5CIBah-F|F$i^a&k3hH><R%VA4i>No?!*N0I3h7cF{iSmFr_i2
zGe)tdvZXUdv8ONxGib8h;)bMRL${p7k}7`ZU<E@1Lj{PKg5gV0Aoyu=6bXY|B?2Nu
zLB3}#$t=l91v?;$v#>O^xFj<_ulN>cMt*K;d45s0VH8h6VsdtTW-cg)6eD>B;U6&u
z1_l98oPs>X!N|hM#aILq0|ixXVrE`^ye3bSC_E_{=^>a!ps<dTMF=3|;xkfn3Q~)T
zjfz0gSR@H@GAO{n2{?)aqy-dnQ5+$u#U;*(#Sl+`Erxg!>_7wo3i?|dHjo&z10|AT
WkfV7Rc^Cy4IhcevIT!_4IhX;a(-RH=

literal 0
HcmV?d00001

diff --git a/examples/example_flat/instructor/cs101flat/deploy.py b/examples/example_flat/instructor/cs101flat/deploy.py
new file mode 100644
index 0000000..be04b5a
--- /dev/null
+++ b/examples/example_flat/instructor/cs101flat/deploy.py
@@ -0,0 +1,15 @@
+from report1flat import Report1Flat
+from unitgrade_private2.hidden_create_files import setup_grade_file_report
+from snipper import snip_dir
+
+if __name__ == "__main__":
+    setup_grade_file_report(Report1Flat, minify=False, obfuscate=False, execute=False)
+
+    # from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
+    # gather_upload_to_campusnet((Report1Flat()))
+
+    # Deploy the files using snipper: https://gitlab.compute.dtu.dk/tuhe/snipper
+    snip_dir.snip_dir(source_dir="", dest_dir="../../students/cs101flat", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
+
+
+
diff --git a/examples/example_flat/instructor/cs101flat/homework1.py b/examples/example_flat/instructor/cs101flat/homework1.py
new file mode 100644
index 0000000..286b79f
--- /dev/null
+++ b/examples/example_flat/instructor/cs101flat/homework1.py
@@ -0,0 +1,16 @@
+def reverse_list(mylist): #!f
+    """
+    Given a list 'mylist' returns a list consisting of the same elements in reverse order. E.g.
+    reverse_list([1,2,3]) should return [3,2,1] (as a list).
+    """
+    return list(reversed(mylist))
+
+def add(a,b): #!f
+    """ Given two numbers `a` and `b` this function should simply return their sum:
+    > add(a,b) = a+b """
+    return a+b
+
+if __name__ == "__main__":
+    # Problem 1: Write a function which add two numbers
+    print(f"Your result of 2 + 2 = {add(2,2)}")
+    print(f"Reversing a small list", reverse_list([2,3,5,7]))
diff --git a/examples/example_flat/instructor/cs101flat/report1flat.py b/examples/example_flat/instructor/cs101flat/report1flat.py
new file mode 100644
index 0000000..9ede035
--- /dev/null
+++ b/examples/example_flat/instructor/cs101flat/report1flat.py
@@ -0,0 +1,24 @@
+from src.unitgrade2.unitgrade2 import Report
+from src.unitgrade2 import evaluate_report_student
+from homework1 import reverse_list, add
+import unittest
+
+class Week1(unittest.TestCase):
+    def test_add(self):
+        self.assertEqual(add(2,2), 4)
+        self.assertEqual(add(-100, 5), -95)
+
+    def test_reverse(self):
+        self.assertEqual(reverse_list([1,2,3]), [3,2,1])
+
+
+import homework1
+class Report1Flat(Report):
+    title = "CS 101 Report 1"
+    questions = [(Week1, 10)]  # Include a single question for 10 credits.
+    pack_imports = [homework1]
+
+if __name__ == "__main__":
+    # Uncomment to simply run everything as a unittest:
+    # unittest.main(verbosity=2)
+    evaluate_report_student(Report1Flat())
diff --git a/examples/example_flat/instructor/cs101flat/report1flat_grade.py b/examples/example_flat/instructor/cs101flat/report1flat_grade.py
new file mode 100644
index 0000000..48b0980
--- /dev/null
+++ b/examples/example_flat/instructor/cs101flat/report1flat_grade.py
@@ -0,0 +1,349 @@
+
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+# from unitgrade2.unitgrade2 import MySuite
+
+import inspect
+import os
+import argparse
+import sys
+import time
+import threading # don't import Thread bc. of minify issue.
+import tqdm # don't do from tqdm import tqdm because of minify-issue
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    print(b + " v" + __version__)
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    nL = 80
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        # q = q()
+        # q_hidden = False
+        # q_hidden = issubclass(q.__class__, Hidden)
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        # unittest.Te
+        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        # possible = int(ws @ possible)
+        # obtained = int(ws @ obtained)
+        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f"*** Question q{n+1}"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    print(" ")
+    print("="*n)
+    print("Final evaluation")
+    print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f"*** {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.join(output_dir, token)
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single file: ")
+        print(">", token)
+        print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport os\nfrom io import StringIO\nfrom unittest.runner import _WritelnDecorator\nimport inspect\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n# class MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n#     raise Exception("no suite")\n#     pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="")\n            else:\n                print( dot_parts, end="")\n\n            if tsecs >= 0.1:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        # item_title = item_title.split("\\n")[0]\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n# def wrapper(foo):\n#     def magic(self):\n#         # s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n#         foo(self)\n#     magic.__doc__ = foo.__doc__\n#     return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    def capture(self):\n        return Capturing2(stdout=self._stdout)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        self._stdout = sys.stdout\n        import io\n        sys.stdout = io.StringIO()\n        super().setUp()\n        # print("Setting up...")\n\n    def _callTearDown(self):\n        sys.stdout = self._stdout\n        super().tearDown()\n        # print("asdfsfd")\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n# from unitgrade2.unitgrade2 import MySuite\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nfrom homework1 import reverse_list, add\nimport unittest\n\nclass Week1(unittest.TestCase):\n    def test_add(self):\n        self.assertEqual(add(2,2), 4)\n        self.assertEqual(add(-100, 5), -95)\n\n    def test_reverse(self):\n        self.assertEqual(reverse_list([1,2,3]), [3,2,1])\n\n\nimport homework1\nclass Report1Flat(Report):\n    title = "CS 101 Report 1"\n    questions = [(Week1, 10)]  # Include a single question for 10 credits.\n    pack_imports = [homework1]'
+report1_payload = '8004953f000000000000007d948c055765656b31947d948c2c6e6f20636163686520736565205f73657475705f616e737765727320696e20756e69746772616465322e7079948873732e'
+name="Report1Flat"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
\ No newline at end of file
diff --git a/examples/example_flat/students/cs101flat/Report1Flat_handin_0_of_10.token b/examples/example_flat/students/cs101flat/Report1Flat_handin_0_of_10.token
new file mode 100644
index 0000000000000000000000000000000000000000..c9122d00c8fff99b66be2f551819687826d1b9c0
GIT binary patch
literal 65468
zcmZo*nY!^m0~pj!(dc0<$uCLFnc~gh&DA!ghdm{=Br!9mcuMUQZw8PwWBC+st{#qp
z{Nm!wq?}YRCqJnqF*7eUWr{aL4{K&gYA#554{J$gNlxmN9@g;G)NI2krNuq$#rdU0
z$*CY&h+*tinFVQ?IjK{e9R4vd1b8#Eh=AR3CQCk;>j-;*88ZU|2=g#7Fl6NCrk3Xy
zWgF@hR4OSc@p8FVB<2?6q$(7bl%}NSl_(_Vr=;pBgk)qED}c;Y$ShV!EG@~;O)SYw
zPRz-vR7g+FOD#$)Nlj5mE6UGRD9K0#D=b#X%mZ^W^NLG~N|Q_Si*!>mi&8<1N?tCo
zT`8$)3Pq`9sYS)9@j02rB^tSvAWG9pftO1`K|ukm2*hyDEKAK(NK^pHDyTzLsVfwv
zmXsFd6~n}n^Ye-`i%T-|(iQU4z*ZM0=B6s7=A`DP=9Pfm1GP*czbGZONKe64FI^8}
z6I24?ifBU}BOT*dO@-o&{L-8hs67hN#yUnihOr77i7+cQp}OJjR8|P_ck#DUFjUCN
z%u6j+$jvM+&dh^bl9*YXs^FJj;t2|2kfTylT#JhGi!_wrA_{4xdC4W2`FRRS`6-o3
zn!H@RT%ce|Oi9s5)JZ}P8U;wGl$7Ty<dx<or4|({BqSy%B<7_kBqSv$lz^iQW*XEh
z#hJMUIh8OUm1Lx57AX{$=2}5Q!A=2Yje@O0qIMD@0%+s0%ru4g_`Jm2)cAM>TU!OC
z`1st!%)Iz`C8&Fp6#|O#lX6mX6%4Hu!izFXQWX*r0aTumnVbP~u>w*MKs-`Vl$lqe
zk){-xUs|M4lv-SxQvym8Mhe;rMhdnH)gW&g=@@C&f&v(nz+f7Jz^M_Ggc22sa}#rN
zz)4O?2Q`^S8|fJ9nCh6vYHIRwq2{m2yH`z3W@cajVLk>1hN9Gh{Gt-Ww4B6}fyiOt
zELobDS(09qn38IwhhQpX=7L<N5CnE0FBeXg@foQ(1*t{FMlc<zWr;bZi6yD=5WmGk
zOA4qF@B#&<964+0fTD|+3u-mUF(s+RC7?8(oRe5wtN<?4G+^R-A*sbB&WXjTn$YwB
z$_OA0@u2uCPR&V!Nr0jd#MetKE>0~faV;!O%+UZT0!6Zpf{7+1S>RNrYiMAgqhPA3
zqo8YP3eIyNrEu$@UeEwpf!9i?LeyeJ2Uc=`4Tk$39#Fho5YIzm!q6=zu|xyHhS>!!
z@)c|ql$?VV3=IsSai(CX1o2j3X=*X3$S78@RfyIAhoO#wp@C+sf`YPwXI^qnX$mOg
zfJ&mAR0Wu7g|z%41w#Xc<f7D+%#vbgQC5(coE;B|AFy$7SH^;3iExGu%}dVD1r==y
zCHV@l(xx;|0hF&QOESPY3sii<;uspU$_g+6Jx~##QI=YilwX`#QfX@hjXNBv4jNLB
zP(#g*XS3vk7nw253H-*u0K%Y35RzoU*)blRB?cl>LV_1mXctr}Bo-^=6+rV&Nn%oI
zPGU(aEbGAdQ0bJ!lGKvST(~rh4^L7Bm1&vjIjJRZ0a&2&aw$V<XOIBc-`I)*-^$?9
z%#u`aL_-RP%)H`))MSKt`NeRf6N}Od5{rsc;R3~#2uYAD;SwboMX8A?pqN)yNXgGr
zFM)Y41T3MDl&l9ToO3htGSey*GK-5#Q}qy<3sZ6xVER(>A-*U92|_~=%uY&8PAn}>
zMHr(CHU{Jqup^5=^%>N`dX7curJxiV0CIkjMoMaNa#3ahC<EE5yF$x0g-S@x0V*Q(
z)O8e63o>)^(`}WMl%VY+P!lC2U!kZpPXSa*fJ!BB3nNhhlEgsryj*q)1(hWk`FRS7
z#l@NFc_3R2<5LRs3MxTPgX+)E%c(@<N+X5*A|#%kAxI@|a};z76^!s%1Xchs#V@}k
z71At#__$ahB|o)TAuqo~0h}gKJgpFtk1497P+FX7h2kQJcMajW2_)&3nFneb>VS*}
z*_c?OkeP;TI;a&{kXQt+loJ(l^HWN5QWZ2nWlv&ys-_OO4FhUOLJU`cI9H)4wXig^
zD79DtrnMv^u|xr?O9$NI)6G@L2S+8ibb|(dZepcEQYy&lX{9-Oyj*ViMGBx+X<}Y-
zst(9yNLInxxS4qhF8RsebW*IJoL>rRqC#!bhq%f(J~<!Mjw?ykE2xAxIRRB+0?3<*
zup|K04R&XqLUKl8UV5qmyhRKuF4Yk>LYi?!rFp1<t(&WWYK0!eE#O2_oSLeTQBqP+
zY^ATClAm0x2l2jMeo?x<v7V)VDX0R_PtHvNwN3RhN^*0+&2Sx1P~|3;l%y8LgDWCi
zSk~4HN-PgattjzG%_(rpFM_Di<mG~7DZRv$l=wtwUeZw4EmYT0$V)6rFSb>;SJzP}
zsVqpfEiNh2QAkNmODxSPvGvQ(OVv>TwI*!U{XuCSR-{AHB)neINYzW%vjV4EO?8~s
z=@w_?m#0>Mil@{RbsYtTL~yg&R;joozbG}nq^LAiNk;){U2sNzIXHd5H0Y<K7H1Zv
zg4*_=#vuV~KoMP9LV`7kdBx?aMUWH^>Od(#O(@1=QE6UoX-O(kK0&l-A?;Q@Jv~j3
z6}gFdDd18FWG5c03KENp6LWG1+2x4R&jV>fly!Ovp~b0br8x@a8L4>+DXB@N>FJ=J
z4#-wWj|CRHXw5{8B5;FK2VTZO(?ubuhYMvxf&$6`*_)V?1Lb9==YgUZ+OdiUWmj9b
z#GK+(9Z+wrJia79CqA{P2qFe+KY>!Ef-R`nC{8WX11Dcl$}QG_wk<N#;I08>Sx`a+
z7eOF>dW9e%P#FmlhBj9~twVTvwN-$qgEYoKQkiKAN_tA54lqm+l0J|En6Qol*xR6X
z8>qulrU}Z63T4PT^@<B}GD|d+^prGX5jLdefXiW!SuhMUQ^8gNWEPAIZghgwWTq)(
zBo-%@loY|EKna>GQ{o{B795;Pnqa?!e4JmbSCCkep_f?<3TLP`Jv2?lU|k4JSYimt
z_eJ17uxmwfD!7=|P_k11cY&=GLNZbn3W`#7Va6*!+yov>P|{I=xg{~F8004Wj?qz2
zf>&*+6`92)dJ4`Nsma-p90@InA$34bP9mu42XzD?!JC<;07-wKct?wKs01{|Aw0M)
zXhOxJ4JHHC2jzllN>Ic=a&xhcLP=s$PHKEgVo9QctpZy1f%+FI+rT0in(zyX^3#h_
zi;Lrv5{qm>kq2=dG=<rM)0vI}q+Oi~$sRfiP?y+3X{b@KLK0LF6zd_Evrq-FC_*TJ
ziReIVwS`bRkgx%Hk}w9@1JAz59B>MTn1m&xBBd=zVW<>PlwX!voSC1Om;(#N%=|o1
z1j8HwYgcO^LL6EWfK-456>O2B17bNy4q^qWeo(IiBnQF}c_jsqZ4g~)ptdKp9j%w1
zT9RK{l3J8jl$e`ZtN{~FE-flb%_{+mYG`Uk8^-E^G8|}R1Y$@!h^t@=&jd+{#i<}!
zjkF@oXe(XgSOskbC3q7I+AYjXgR2MUfnp7?F|a}r$+_T$A+*H{st$`4G7`&DL9I81
z%G45tq}0?rg`(8-%;J*NqSO>Ug_t~0(-kTJ$y4w|T#%ERSey!O7=xNsActFlLIY$S
z2tz~2&dyFrM*-p>h#!$8Js~59;NiR6#Js%JB2YJ}GQU)zC=nzD9gEZhnTyCppus@s
zU{5hf6jBY9f^xe?A<Wmx3K<Hv3RRf}8qpe=(dy;uu{sKw(dw{)S11=Y^r{{UDUmb5
zC9)o<bC6oBp&1KJEg1^7l$ZkXH^@DC1$v3aiA6<;l^PjPvmt|<3K`K>ItH;iVA>E$
z8^!8?{0DBVDTKlXcR($*pi)p^ArGKblz;|NAmXqv0F7(J$7kkcmc++{$24>lv_Msu
zj)Im}b~%UzQwfTb;?jcDA`MMFxDIr+2)6{M7M7;wm1HL7fGqXNPfSTILUv4X2}BHL
zJjfyGsbCj^hI#zJnF2J(qN4!nP=UmpLE}O&^&sbfB*0^apy3Ia+b|3PsX}On1T;vu
zGT7kc#NyQW+|-hc{1lKWpiyNF6dii;@hO?fCGqik*{PMq8pt_32c#n!sVW8yqd0@o
z2dW9VMfn=Y?grVOnFj9OCV^v4!&wJ0=m82ZkbBW}fOLUv1iR50!(9s63OU6H?}40v
z?m0ARNZ9EW=NFY|WT#fzqHEF1%u7kFfF?qa_0WU}QU}osif>TN5v-v=l_#wJfv}<V
z46OP=tBoKnIC$-Y+^mDuFHoJ3>IKSyXan^t;?r^x(``eFN<po`%$(G`5~vbH2!VVA
z!{AB=rQQT<#iJOdb%~>POUg`-&qxI&eXvVFF$ys;FTY&DRsl9>qnDRoj@14{=t8Q{
z5{r{FGvkvWC7`VWY<NcxGRhO52JVw-D1nLqchLB*5~weiS7NJ_lAoUoDjZ=xO#%%b
z#^fpKW#wn)X(&YJfZLflpj3-&2c)eD>K+zrXo5P%IjMOXIeNt<MVSQ}nwkoB3I?$X
z(4>LZ0tMRuatL@N0a^n=%K9Ww<)l!iq@b-39}k-B$;{7-kB1tQQW6g`J}+ItRv|CH
z9AsA-X!J-!Ni{`ZHCJCXQbE<jO4Zj&H5le0h^b1!C5c5PsVP<pAcNt?K#c`uQb<Qb
z4?K7Zi2-a)V5ozjtzM`es352*2Wm=z5-(D;6f0=kDky>4QlM4_*nU)f5Zj>cgbpcz
z#=k%=E!I&`(g2NB>FR=#EI1+{Ll(uFN}w<Yr%I3%I5jJP!dXEH=67WUh^c8x;F2^2
z+DI-2kBeC;fF~-zV^**X18vzu8tFO;N-^+;5V)BGYi+^`v^*aLTLlXPhzCGX0~(~U
zRRG0^9*BUY*y7~;qEygKN-acb4!EpWuvNfX1%O*{ptJ}oEAw;|GzxVT$~8f$FEy_;
z7d(3iZQts_TD8TXd;`(~!paJT3bqP`Fw3Dr@fn#ZDXDo1whG{q0^$%1InY2Lw7@OY
zi-(MG#K-F>cz`uSlM6@}TH6v9?~u-rwxNQeExeP6lomiblk@XRGV@AP5iTeOjiV~q
zDnNoo4@7}V_+q!B{9F(NRMcw}B3WJtPNg7E!b2b)ECk7iu#Q`yj)FQYgdp<jnvfI%
z@*8N@1Jo*vk4Lzq5TYy|oNPd)Kp=FoKtVOrN<p<)NmV0H+fYXV;s7KUfi-BLXxC9l
z%}cR`r$vz03-w?vCk0ytXtIHb!<tZN;_=`_qoAzdo>-ERTBHC;NZ_gB%wh#_#R#2=
z02zZcEf9hfyvhoN@#UE%8S(k0CB-F)d7!~%aC-*akuFKig$E)ydx1t4K#8qT55y`4
zWin9gf;e!6dKrnu@t_Iq)D*Bu@klj%D7a|_o<-C{2@p_xp@grpf=6O<b|oVCk+p&|
zHga{NU<;|bP{g1{AO!-l8IXxyP+1A8g+W0C!k{rxTLrK>Q0juT_K@dLK=YTNhCMiZ
zZNUnI!2Z$HD=N*?04G;?CIy*@6stw4#d@I1zc{Eg58*MS=mk|0AVtNc$;qk3#i_+8
zCP8N86fhMjXe+=)Q$e%f#hRejOlqD6$gs4;%$(Aq)M8E0#4tzz;RJ*ulogQN2^#b$
zFII4Xiy<XuWd$Vn!WF{A@F~o#EXps<OVI#n(kNHZf*Yi%pbxi6K~oc4UBX>sr(gid
zmIlbt1hWr1LW69Yf|i1zo&k!Hpk#{GKv4XEFgWW(=f#3@lzO?kl|s3W0-_@W;liv`
zw}LxdM?oEw@{8526bj>Y6x6}R42T0}K+AKG`GtBg-JqT)bTJAd@KLfp%%RBMEjCoJ
zRY+6P($Z3Z7dnO2dD@1x(B=Wil48(&e43I%HNv)9{pxaLC6JP+*ib=R0W=JzrJ#}L
zqYFw;#fF*?+DKDD6O?$0jbN=4kkJr*kiIyG55kB_PcN~cAT=*VBRWk9-E}$&X-XLG
z0rmMHo-Z%ffycZKJXjTM6(C(raI`>^6f9VvF|LqXT$-x^6V!w`7AcrP$qb?jCa9^P
zsi3UjoLF1}nj(M<>4OINAZ~%SJ77kF205Wih*0EVhG9e`?lvjBMFlEsP#b1Q?J<Zg
zDJ4)3f|>}>c7iUn^#Bct+|0bvl2lN$ETu$W-waw+6sIQVgNCea6;etRbQPeAv|!Q&
zIYl|3S~M{?DJ4-MQ%9lLN};%<NFx&z*-GGsS1~wM6oXq%nV>q_5R&o0wG_m4kaUoy
z<P4pz0W}%56%hW@R!~yV05#1()@eZ9prfD!VJU&_(os;-RshRGovfpv1Yv>Xl{7)^
zGl*?iQkYT*XziDhj)IbsHpuzVNP|U+rnZtkiUce+H5EXK4wP)6qbuN?UIH>q-AX|N
zrXP_SHFXr!p)1SOtsqq^G(ST-aZq!RhZ=dgU=X|l1U9q<o1=yCiJgLm4r#&XZ?lT?
z^WYq$>Eom-Be-xuW^#58Vj>x&3Nm(+R8<aI^rHbX1k_E?Q7FmJPR-M_QcwnEhV;}D
zg+y@itdO6SR$8149?1oFu~VVFUQjDRAw9JOJnWrRWu&8^o?nofr>?01Hc3Z8sk{W#
z^e<LOLu%Be>7m*SuFybT-gI!I1-3pyBQv)E)=Vu*g|5N_#St{nb3wTxw*ZnZl)+7r
zTu?g%G$I8v18OUxT@NZQt8?{W>!RQ*l+qMz6+ptE0X0|yPgx-a)cl1Fji+Q5ftr6B
zY0x|e3Z#N~kZp<SpvF47x_GD~;^Q?yCWG|G$3yyn8tQuLn$ZTapkW_~jX2B%rDr0|
z0S()O`+blALF$a<>L{qkgQpSV<JA!}39wc#L>i)9UDFD@ss+400o12Tgsd`wEIPCT
z2NAfH6CV!`Lr@b!Jr_L5tPXC@gZm56kOyV2l6-u@1PU9JFaT+R7zYhN1zUxXB3Sz$
z)M3MEHc3IH7Z37tv;k666x~{|Pe2(M<R*H=H+mXE3OZ;Cfv(Gdu0e&wwKA+YDK05W
zO@xU-mFPuf7Pw`C3ILENpxQI@VXDAEpOcxL8lRt(m6{B$YV!4*Doav}J^eLuE90v&
z3&7o2sQn;rQfXRRDtO=>p%N+$E)mdd)<EddQBW@jCBb6Q7%@^bDuejYVgYIr$hDvj
zZBc%Hi4JHczgP!6Sp}Yf%`es~Pt3{IKn@=y<6wG0o&yyLAi5Y$9;7BS4Q!-dYF<h)
z$mJSJpan~?LI<P*8K;5L3#g8V&f9@UdmzpOS%BnjWL;%QI*L+rKxSybq8Z%;#5^3V
zutD}9sL2ZIS)ry<P=-)IRtAY#WG8^wRhb3Q@CAEAN1+T{?1H4=g=@4rH0IPntzJZ|
zfhJbKgY&Q<0wf(sHiLB`@gWXDQj6knuxb<$n0nYu17zJbs8)iPAF#X#ia4ZLgAJae
z#~#7-1B(b)aHnaaM?T01Q0!7K8Nn-~%$!slX$GbQhcszP3Moc#m<LMw3ZRM`Pr_6$
zg5=vY<eD6mdXO<9uFF6vC@oD7v^EWvYCtI!DHCGzMH)(MBRLo0#55fRoNmEyKcbZe
zNm-!81T7C?YjR+#Z>YDREwmW4L@Toxw#up`AJkw1ua*IKWk8GSpmT%ZkwpdA3OJDK
z;0x0rZQ9XgVBppFsB5%F)-o{NynNVr7NPY;E}6xk6%Pt9^$JOeMfg@of%cu`Bqk9u
z7QEOCw00>cF$p#wtPZYAkecwN1)xFM_>%ni<iy;9(&D_-66g@LjzWHENkM5zd`e~!
zc+nB8zy&q6A<0}X&j(T!faXd;eQxkdQY;ILu=Ka^EbRaf5W+|Pp;K3oAwps%#T1Gm
zQ(mB^D2}-)<f0J42HOjZ1o-+9kl*wWkx7z?h}kUgQWUUJ(Aa|(nUGF7VsHk^w^h>0
zLsbD@ONwP32Sfv`dy2f01FBzHAu*>oA3OvPDa^oSDtJE=s7QmZAOknAiuLsLK&2Td
zNKm_RkZ8_K1FwZZ_6AZlk(mY^#{?ITnRzLhWtl0Zi8;{DK{0sV3`sr67KrPWoGKL{
z2@%wj0WFu%19wZoj?w`wtN=|ifmTI><Uo~tG0IvBkV&BGAKa^iCQVHH(X0k(f?5w+
zf`PSngQUi>C>69t0JOnNKQ})mGc7YUMFC++PNhOpCD^5zc?yZ?MXBJ;Rtn(S&?O|a
zSRu6{F;}6eG$*wfG)4k47>1z^2K7&2K?Ryvg9;<8fJwq)2&5l1%#n@26WWli5TKw2
z2PLS%1POgTJ@8Tzkijqv3f62L1#rk>Oj4oPhb4IPGII-1+6fA_3TQ(IxzJP!vkyea
zgNErri737(6|^d?EHyqSA2O(+16?Ey4GRTZ=rVIXs6aeuMG#yYs67KoxgcX<SQ)AZ
zt_*HEmJR@P90$~}1_c(hY(z|;X`=WKi)TP#5Umc0OiUZWZEIYTm`+DA4B8|I?M%o_
z%Y=jv*gU8Nq{W2G5YQ+GL^XVT08=Tn5QxqOH4;IVV=7Swb#_3b(9zl8k)3Q%asnv@
ziD!e$i_AO)s6nyVQY9!}AQ=%dNRDmP2c!mum0_lVhM2Upphklh?SQO>jyXYVoM?5Z
zG}x<9HY@{y7KXvAIM5t7+Wa=6{(~fp^wg5%@)Sg(DoCsZSDyK$CE#?2lp104tMIS|
z&Hcw`fT!q`VD>`>E)m0)VEv%!sp4pL$mk|?#G?$pG(ai7Oi3G(Ui9FT^PtV6pzMMW
zfox^~c?UKM46_qbuG%UnsTRkpX2$2I#j9qj7DI|#B~=Y{FTuw35suV>ItH55Vdla5
zXW))9BH%!|12j?zNjKoq5ZrwMYXgljBtbhXNTmm47*sE%G`9dW1y-6<0vb>NH(WqT
z0DmO}Nl1wL6r=+x2HMDxS^_G>Q!-1yX%*U>2M4*10(8Y5q$q?`m6>_zIj|8m<YF6Y
zBB<T~`ve*osFuMSRNz`5zqCXlF|QI-e!+8VF}S#egbhe9tT(CT2U?~N+TjE$ev9*S
zQ^9+ULG8G-Qt-kB$ha^hJ;y`#aFk>wmZWNcvNf#uG>nHR0IhEYr&L%A4zyxPLn*Z)
zHCag$TB0G;rsw1*CFUR&dli7D9-wgoO76uPNuV(&J<u?DMrs8t$-vfzK@umlbq98i
zCQONKL5>b+-Xb%(1hOOu;&WJetXG^`5)Vy)8U;DfFopL8K`9)Ria{7+3Czt3whHQy
z!cHN-I3_P9Pg%jm-!CKvvBRpkq%<u}AtSXYRiQXDFF6&q<Qdl2gYT$8T9^Ye2-Hwc
zPE5{7jfV_`Lq^^p!&~4*V2G8(pw_0QRZJcz9-)o_tvvxRMTUePL=O8%b!JW~*gQ>$
zB4`?iWvW!r((Pi6lsuRPAWQO#^>VXQGK)aMa9z-qWLD7SF-oA#!k~&C><Liyj^uWz
zU5HExs^Gw`&{2p{FHee5*HO>}EjUesdJAMLnx7!K6do)(pxqY*AU|j3=h-UdROKcr
zL9NM51GV9j@{3d9j&sS+OH~BPqXsq9w{X|MJgp3F4uT!1V5^Xv7q5X(0;+7levB_D
zN=?hGfE0Uhc}Vy`lM-5}!WC(PoDq|Uh;#6e2tpbf3fLnTw8IoU77s~fu#I?-?Ow1^
zU(oW7`~q;%f|Sq{N)po*$}@9v6hM>xdJwl#>{(Fd1|9yy6`-K_EGepl`U}JZVI1k9
zC@BV3R6|?{QVYY-kVQ`%pyEO!4Nsx~=}!gkflz>Ng#e|vR5Uk1%iEA5P@}s9+L=jI
zNJ>mmfaEQ3(oje&0j>N)%S#|TKp1L<C*(*3P_!z5roI!4ia~Q|NsuBI%W)2n{zo!s
z!F5q3NNGxHPAX_`YKe|QK4|SuIp{Qll>G8Mkaral74lNcK}j97CJvOiL3YD1#0{y?
zECCY*6@cKORES@|%cL~Ypo+j_aflFyhBT;Zha}gSJS8Qin7s7N640J<1w92dH3bj{
zwEZ}<L_s%KLCGJy#iUpXCRI>coB?7h6l4~_OTzTb67AyR3@d&8^vn{6^vsf+#3a}j
z7rm5{QoWRH{gTp*RDJl?Sv`<7y1JzW;H8cr*MMCD-C?T-OZ1Rz3Cc?`p!QjQQ3-sx
zFI*t6G#9o77%o;^Sqx_<=jY_4g7>u{#EMek((s+N2$8~+Tm&aG7oips#&9`Mg#oI`
z6f*N+4h}9U%FIjm^pD8{OMv_fT66<iAp}~156%DaprSQ3C(k7{Ilm~eB)<r5B(%!_
z3J~b38N}Rug_S~HfgX6SR--}_G=m4NdQ$Xa@<6L1P?Q#z=4w=E#^mLu<>cpsrg3s0
zD*zy-fCa(wkV30CwWPEFG+Gm%R0(N+YB=kF`$H+2MX*8?)ILzKRRFD^MxP#pBr;_M
zm=;K*7c>n5SuP6`2W@Z6g{5I|^B*+V0V`EAi$Qe~OfAe>WpG*tRauGIsVSL7#TsxG
z5No078YT*{0~CZ{S3*}QLQ4fu37wIdk_uk453>Pe0n`vsRgBQ;lb@cRTBHG~qhP8*
zM!@DGz{cn(K<3I|3P8qzR^aQEq!#6Zw()`%sZ|#16_=#smzF@>3|Etr4_dYhF#u#S
zNCIR7q|pE}Mn@qxwYV6xsTb-8kP?st+<fSq4@?=R4Hya_N<j9c<&+j@fW3k2d}YXf
zQm~`~WR*XtlarU4ngTkcCcg-_Bi9&QYbTauCS~SimQ+G(Adm||>(oIWf<%IIVnInM
zC~s(hR^h{}0yzLJD4{zeAYla_I|ME92W{(w4dx*>SU`LMvJ4y?@eoa*(8d<hkOl9c
zHAdiFqDYzv?alys17r)txv6=eZN9KwAIV^krGhq0<`)%1+NPkj6)E|7phjc?sOb*f
z;9Cr?-;sg{-PQ0k0&0?=O4=%bifu^K1X%{j7pXaEdY}~^nR)4%`JiRQ(6UGaS{s0T
zkeQ|c)(r^@r1S)mEJoOGs{l><VAXI_kxW9XTQKyaYJ`O#NLgl@0&1Y4I|J&G)FM!^
z1$9(vQ4zwcAX6aX5H+w;R|B-nD>pSazo=3nBR?lqArn2fp;`=T3Zg_G!U||{0P+RQ
z?a<h-K;QBMOUz(bf!v;2Q36^O2hxj(5YQ+Pbb1xCJOsK$04YdQQga}&0}pSIk)S#;
zHC3UsKmpvDgLn_&P)Im{3Kmeh2U!oz1_&jvNJsTNdZ>dV9}=E0mxBX6CJ!wK8)?8Z
zGtBG61P$1~NNxlb2ATP|f(7CFk_ymr1*I7H)(fyfNWlhK&kI@>ms(L$l$cx+4;9fU
zsVG5G2lf>-ZqUsbtU(V-03Zx@J7j1Cw5zfLJzYb63|eOhImQZ<XkjrI=vk7Qi@Jvl
zw0IsCdEhmx3XlQ@66~NROIj&tt_D=-K*jPweR%^22Xt0WE@(JA9<*8!v^-tU#0Vk<
z>O_Is@}Rx`upT*z;ou`5z_QTI$q<`Cogh%b3fgfBn!iac0=1VxC%F`X=Tf1Aa?sMV
zJT)^t1C%ZdLCe@OQWc;A&_l}#p$qi&K*0bCKS%;a*{%mu1Fd7A^$xbm1(ttG@^e7j
zcfiY^z!3rqr_5q->5QJEK$#Jy#1@jXAuG9kjDnzp(~vL&xiB>cZcS=&2`KbQH5Ghf
z6U@UPBf)NjHrl{!_|^^h&?3TqWrzdglk<x}2h2hDydcFOb_s+5U>jh83R=|<jRO=H
z5w2-L4hLa)Xn>CD1GPOsNfB!ZgB3u-7vx)*h2S_ZPE1RUPfsm@Y%#!S=fG@1Nwts+
zk%<@xMY9&EZqUQjhzJp6bzn1*T?R=Be)&bYU`IhZx}a>KqX3(z1Py>f&TN2XRcOF~
z5~3|6+n_lOECY$jlKdQmQ&KY1K#Lzidt{S}H54>J4CrQASZ3AK10ArY3+iLQ_R+!|
zq6v{xKq^f0ia;wf^9uBe3yVrX#)0}93Seurv=odq!2=>7=YlXeX@K`9z%xInq$<jV
z1qetHXxyqOSHVu9BtHkuSCFo6nv!3Bi9#x9hYomD6g(o5lUf8if<~dbBtNItS|KmL
zC>Jy{335nkQ7UM-t~{|=p*pW9w-$ScI!(zHa=4)`q%WQcTJ;9fSgcSDGDWW>AJk&i
z0G)G(2v3lM!M=h-BRK16z(Nu^26KzkZ3#OZ<TQxkphOEX)5mDABn$-{i2^x2fCB?F
ziVO5|6Du@8;fRtTKyi&EMM<RF)><p1q?Tnu)-6LK8_8(fK^*P2wK@vbc^HnxObD>r
zVkjjDP@IFd>VgU$eFY7}R9y=NZE)d&vjBq1L(3&Z;iI5QbV>u2Ye~hB1cy{wLDCzj
zhyptcT*g4A6Cr^O%FZB6Y(WFcuORg>4AVF0ijsn&R9LA5tIENN2)RN*uBK3`Gw6H@
ztdIs3O$hUF8V5RX6n+8?XzdVq%?Nm)G!uG`BB<m}EiNfm0Bzz09e@Oys!C5S0iQby
z-HlL`m#ztI?14fVHktrpgB$|&6||WG_7mzj0g4a72j*ZsG#1o8gREx(&G3NY6_O%A
zc7WudCPS@DK@{!C=7S4Akm|J3JS?>UyyycN3TlfK<Y(rU6hn=MPP@QHH^2*tU}+yk
z5atG`AfyWq<-kv&0WW6Pfh}W#@~|~(3!r<P6l@g?AzlUrEzAy-7CT4+<aDspU@GF_
z9z_lbkWxryP_nbLQvjbG3+c94fx;Ff4Z{#+Fyr811d@hZ1`CIH4HyfLWv<YJ%%E$}
z6g2YkOH!>AKquFMk75BI!BS9^58hyzVyyrgR#qrUttf%c<Z0q?BHU_NMgTbx+8T!U
zXQ6y(dW2;TM8IOsmB7zP0*w|0L5}510rh!6Bci#P6$&N!>8YSO0?2$E=rHNDG^88>
zas>!O!chr5cwqqxb0L%ub)W_`^*|`3l9HGi6;NrK4>~jud;%I;TMgtSr~=4ZIxO-a
zHBe{A#N^ph8=waT$T|>)Sed324mxhFq^J@!xmf}^e-e~=Av>oPV$`d_`5DxesEttv
zt;;Hcln|h)f^vn#JOyw&$4W^@0XC8iG94L%a|$fofN~1BPlXiB$cmwp0-&Lb)TG4Z
zY(%0#Rt0f9T#+8+;EMRviewE?V;fm1j1AGEMD5_U#TLHMN<_l|vDyPAOT#-_&~ykp
zE)8GL4&GUSCR)&NU4Cu>sFQ@86+uR4<d?_8!W(q>CpZFNR-vUpXt00=l#pTs-4rxU
zU;|+`V2e?hejJv9^~2;q`XT;6asbv60#p`&s=mY=^ga<NlELW|lyu=`u`SFBL`7u_
zEt-(5A|aFG%)^LKq)YmOSeK>*+M5q6;K5UDAn)VIxhb%dS#uLhk~84lYEYY`G^a#Q
z0c;jDFC&ExC}cqxVkNdLPB=0_`au}15?`_bDZ-w2Kr$c<lQqPWv%nQ4=ok@jTLQUm
z#7s?y#De5kVp0Os0nnj8Bqteyav@}JI4}ToT0D515j@%ma|+0T&?E`X#E?@oFx(5C
z{soy0!tT)P5MU7vIi)@m+=fg_1s^{JIzr8<5_T@CjzUs?Nd}}c2Th!nq~?KYQqYQD
z_#7Pg=vGKwssTRiGqG5qJT)f=v}OS6Mez81F{1oU1g-f=%>&oU(1ru(xD3#ojt1zY
zSX7@WB&Fu$muu=Nc;-PS_Z7<Xi&8*m5@vwhTv38_%|m9f6)5mPo&{mZ;S(_99Kk1_
zLIVmZvLGYj8laV6a9=?hS4bu&CgqnQr&+|vFjymun+7_O0kqr_W|A({B*>UKA`B48
z1~mjg%j<L$N-9cpK!<RHZcfnDQLup}b!Z;5L#YF-Ai-><09jO!n4<s*aPWFMkmnPN
zGK=%`5O$*^3XD@P(NhVi0S~%mBNdixGC`*t7Z<03;}7f)R4;()F^FZLWQr;WPN1O0
zaG>}@_9Rlh0PzmUtFX8PnFI1jX-O(HxkJr?w6h?Mby(g2MLc-H4178TtyKm}nUGjP
zvJ|8Xl3c((LbVMu&48vwkmgPx#v!FCkbF^YJo3&3jbhL=T2N|kei`UA(R}ccn4o<n
zNR3ZeGO|@bpK~cjHXJkpj-?idq@7|!%7MfJ#B1QyEMUK(#Yj<Vv5o?YCfEdrKj<ow
z)D-YJcfP6MYdkbSXD7o#+5uchL8h@GR)Hca9@N<_NGwW)pWp{-^67xrFcibIBDo1^
zA&DN;MwiUw64>-A#K^qVa%{%wK&mLvfq2L!XM=(tJiG{YAxIi_S{}rmAnQS$<0Md4
z1ubv@l^Y;I7|sSCq?M!>9}m8dB{d~J9-$L%XmpG^vI6je=IHFyN^s5t(V2M)+2BKc
zKpaq`BQsAy1EeVzyyZJS9<-nj#0QPOf`SPoq8W>@3Yr%{p$?i{ARG#yECY5Q{9qIJ
zqWsbVjoj3dM6kFmG>nmB6&7~j(R9#BOrd#TW(xdRDJ6)LK&P8$g3eEm2k*a2fgNxK
zku3oqPXwB_0<EG60WFp-1|4Lgke{ajnj^|g%*m{R3@B<8<Rm7iX5{Cjq!w8#6sMLz
z7Dj-k5sSbFw8I7|@JxxJAB%+Q7}%mj(EJ9(dGX-0W#C<Kh@eA3QGP*cQAs6)3rcNZ
zW#9q^7A~Mv0cwbX^Bq_kv~M3|GFk}&&R=kQqLCsJWJE3`4}ngCN{6g=PA>r^z-ZVh
z5FqV33h5<~lRY7lATi`*2wKCCUIJUhAFTwPd`eEu$%&5#9pnL9_@NXV3sMVR`lOdx
z432&ckm;bEfJldrrI+X^K$;h54hCfrPml|tE=Th%$WIXGfx`rLY>k4a25i2{79@?_
zkAkLWkgy&koInW{WRL^IjN(+#Y46w~LkCi=A;$@lF$%U2X}EEi@e0acxT6&$i#Jvw
z3Luj}&_G8z$N}PFkVjCw2-c(wcNB;VT2oz;3SD*qN^c-Ru)DxM#PlCX9^yTiIUrr2
z3<cJOtO0ZyPagC_0ciDH0;))%V}(VjIjLodd62XRzJv)DQIIu<dC93rl@X|egl=Pe
zVonY?-r`|8A>(bxjsT?^P-KD<4mgHD9P|PfI+g*F(t{a=anKo-^oFVd90*7?BPjeq
z7*!RPf&#W44OZ1bF13N$2QK?S#UNx&y8@UGEdgOWJRsAAkXVPgA5`nW@;vfBEKr7r
z<}A#uV@Q(F6Al%W6?_vbGIL9F!B=%DlxL=tWWXW<d!1X9TAW&<k(`54zk=dHqfjRv
ze41f$PBA>3vBU-JJd;AuI&-jTG3v;13JO#ZF4O}{f+}Z--?6(V7qpgFBRMA-*$imL
zfE7sTsU>h#FyDa^Hu$g=jFgQ-GpJ&OsD(F)!Dc`Pf52OS;5)n^>Y#B9@(j{3FW_{F
z9B0v>lZ`<&Gib3TxK>8e2+|BXy8^Vb6E+Ztrdcl@d_oGSgaDZkZ2(OGAgx%|co8-Y
z6jq={2qf4+#vti|t@MN)#Q>8+${O%}dm!f^ts{jUs{sxHNZ4!YC}1%F(qsXpahPqO
zSz(ZA8YpIi5B=7JEXD$ziBOzcfZ_~rLlkB{s4D>7PY5yzwwDmRWd!6$aAbm;74YUC
zXya8f?DSj(=wu3bwFz=!16>@LnU@ZVA;`UcNM44W(+~3pEYy&L090uqf*LGSo|0Ll
z11bNZMKYG<y&#o3pdM;AitR`t09_FR?P0(M>>#J0A~_PgYYSwW9=g4t^VH#oHN>an
z$LHmjfcLS*XXfdpB$j~sU!br9VU#ieY#O|<LQBtudf?&*tR~M#L0KU<wL~Eoxg5$#
z%}X!IfUo@l8K0R3ivZAoBdCFkt5JlqkqEL$55DmT5~C<VgqB4hYn74qPe8AI0J|1z
zNFt{Nh;ER3!RnEnf>;R;E*)U2>rrDx6Q4^##$t6XNCK2w(v<8J!V`<~GV{{$-z1@<
zPz_6wuoMb*FLwXcf<hd+QykJg2cOXoO81bRD}MeV;B*M;?q=qJmQI2OcY;zAi}Uk}
z!P7UO4HgPXMWA!b6hOOqL5D6Emn1^3ozR2Ucp!fuLJ-spE-A`PE<s8@2w9L?^Z^Cr
zo-0Bn&L9IB0U06$X@q1!P$>YudkqvGu>D=28`um{qd5rW$}7mo6!;L<#G(}V4hQfA
z7WlTew8XsRN?1n&WG|%FfUAU94w3+EBLN@U1mAf88sr3@b6f<f3qfi?7?j-#b>iVI
zA6%IYY7uCaAHoul0mYz`qd`j%Gjmg+rxhwFD>y2o=jW$@4x^}m^ew>!5BTU~P%0?N
zM>B-DBYsgeA^8mXV1A^dS|Ky4nI)CTC$pj&0^TBv=6sO1;8<4y>_b#tg<zk8w1LhK
zL}?3vJqjK3!E9-Qk^|&YKJdN`)acL5gA5KRWR*e=s05wK2fmgIwC@wTqOm-&Qcn-5
z%?oMq#e<6l&|c<Rgi9fDt3X8LB5tz*H>cu@6U$N|M&f8xfvzw>C_+w9uz)MngBTDU
zqYh3q;GqUcxFK8!Q;h71Xw=h}L7T>5W}#|C%aBBxRUM<Am#+W`F3`|zJW7Ot@&PDa
zrGrj@H_|Jpj8V4&wY-r+722*tb~17TKrX96u?^oh3mUTmmqVC?e?&(VEFi$gq=0wh
z7NZ9j$St7K2YoCLG@J`90hJYeK?jZ(<tKsC8MJ?(r{Gus8UxEK$*BY#!I55)0a`zo
zlvtzy+P0RG3L6(GODxLFFD+I`OH3}wF9P{0Um+QM9}vhJ;K3)5#^TD{r2L#>XiCik
zud_z#Ie^rHN^j7>F{I@MR-u7hJQje@r_0ex%gjsBP*O#1B@}|zAcGe*AkqY=YELc!
zEzE`b6P6+}LHnVgrqn3uC=?`@Xd5C`-XL|L+ay3*!E1V9R)Q2~Y8zr(AOz9_b_6JO
zptu3lrYJ<8q=Wb$Hr|i}wH%t1kcMR;>cBk%P$Z&{siH(8WEKEhJVV?AJ`FxIIUaPC
zGiXmVXqW=DlsiT}T30*PUO~g&3XEf7QnVCeV)PVZVp6mfG!<%KqS_!)d(fgQkkV+^
z)L4aRZQWRVm_qv)b%;$x72s0`z-^JtoKy|0HiH_@dSR|XPX58JQ2&E2d$d(3ssP7L
zVonayI(>*#bXrb+Vu?l~_&{il7<IiEbx;mX1kLO!rGhU7ON5@;4m#{N5i$&w2v(Dm
z1MR?MLXMP4%*g>oq^W@cQu2V*+n`{D_yiQK=*<Boc!7Yp@mH^)(hAl_0<F%?SI7m;
z#z05I6_s>ASx5t9CDg0Xs7}nu0cB9|z?Onza!F=cY5?@EDR|NcMLcXs4BW=kQ78em
z=Msw`JKl95-FsW5+)7Xd3m=tN(g9C0B9GuhcOfDC1}c&CK+EOP_YK4smF9sOe5gZ`
zpx}ULfv&9v4=kV=2R^XaKo4p05LgQ+sevK|zEu${TB4v2>5!z9fI2K73qTkwhv9rs
zPZczwkL)E-@PTxIFtlS*04k(x6+oAl>VXIiaHS3&$<xb&hCfI-xFwiagxnAW2}A4#
zHDf^a7{qg+H~`oC;0Qo2l)$QyLJK4RgB4(S1u4zJ?F20&Nd%2ZLl~eN{~))xYLp}v
zrKgrad{9)1><2W>dJsn<c@k_rsK$*4OQnL%N3_jg!3XjnbjGg)a}OkRtP5-w%&%xZ
zz{n-RCHVyfpp`U<3dJC1D!BOvPn~)S$mKVR$(U&l6jPv~YZ8JHvb_{3AkfB2K*L0!
zgaY1xo|ghigdhP>dlXb=<LU>3)aaEKfUcU+K(95x-T*5|&dD!M1*IQQ1i>&|8r<23
z1wBX>u~|zGytNWpC$y*l#UZ$vsiCQ$3vn(;2o|j{(?Ahf1iE$re1kV6^@42xg&)Xi
zpjK*ON-k#3fSlrBi*O2fT|p-30zX>=Pyv=$2EW@5bgwTYIf6?79fiE){G4K2&`sY6
zD?!#`;-thP=;b=LG3wPhpd-<0tCJFoYHJjtt5b6l3yM=yYHg~EQbGNt%)Ip4SWpxx
zC@X-Lab}jp7bhp?q}ryGK)ALs>X4(tiy<vjgzcaf1-PkO1iB0soNx8=bPd7hTf0E^
zV8RnTc&{pG1Ab1WwL(rR=zca(8Io9{U}>oex>q?>p){`~Ge-fg1KN&(d5?$;0#XW3
z0D4%{2Z|E-G!IA=87CE`CT7E;8zuot3VOvksi_4JpQa#ha04kqSdEl+L8d4}I~mXm
zsuA14z!z75uZaiWTn!F5&_;{m(xOy_@>B)To?pnMSAJe9=op&Z{36ikJEV(@Q6A*w
zD}YS|WqXJc*zi0k$wH2sNe1;Ya&kavIyoD3gI@_~4+pHc1&u{0=|b;W%1tcLK<r$v
z0L?8X=B9!!pMe>LI8RFtd|w!>eu3sE@CY5qYS6-4a0MI>>RZL9q^4!&rKUiyFau3H
zX22W(N>a%=;3J5U#(+VFgQk%6GIJq2<YCG|!Je50-X#rp9;hh-8p(#;freg+rh*3-
zlXIYpO`vWCl|`Vq0y!6ak4h1Ea!{i<JF~#n2xgy>l9D^<)OH2%;9h>3LZSjhG00NT
zk{8I*K+tJHr8%j3U_a}DT%Ml-G92Vw1qFo!kf8|*&=bH?ixo2R%OS0qoYb<^oMLce
zz9ca@8?=xHq*kFkBQqxzv=<M&OdDb)JRgGGqNe~-XKSdCo0^zcte{k$0qSw(<P<C9
zg6<IpOB$gFS3+H`q>x&Yj67iHn5U4MTToI7KJq6o9aLCD!U%M5UK-e*g47fRs8d0!
zm{L<fJ@({mg$(f4K#0TO3rLE=J^|h83i5CXsQygOhLyhH8WTJltPM69q8HkJ1nbmP
zumPD~RHC4*U<i*(h>H|r)L{)`NJk1hyaj5*fb5J08y*WDR)?4i3Mr%>5oEL)bjm&C
zo_NrPScsSgl5x-qPFW!#H$MerLISvZmXr$KcnG;b7-DZG=(xbtWY8i>(0SUa$)JuM
zXow*{uQ)#^72*bEg%E!ie~psV<cyO1yv%G(D+N$@Au}blNC7e$6(0{OmqFwBp!5Pt
z-r$7*aK9^nQy;8n1931s^}}78l3D^fZ5*5gL9T|_o|&cqD$aA#AkBItZ|bFi&(q66
zp7>E#@B|gjpw0BzpsO}O4es(p=xHht<3YU!$YQ{ZR0YUk4dCnuO7I}(gRrtfL_~xY
z==>b;qOR0j*lM!8d<9hFic1npGLxYOfD@>Ku0m!Bc(4-U0f>1Z5;TPg9=1tTNGr_)
zpE3g0flvqXHY}L1`7|096tPGJ8SLf)Xh4Flq6V1*?*GGYIn_&x2TAB9=YvZLh?Stt
z_4z5_i%mf{dBmvOK;p(OMjd?Ue@T7;B-bdE7MFq+NI<lK`~tE8=2Gy2XOIB+<`lTs
z@{1G_p#cLcN|coq9Lw@EQxuXji;_!o5{ndyQqzjT{b@*o%t=kmh8A<m3OFxUH_|iL
z&&f<GN-V0>hZVY@>(!M@GE#Lxqryc6MX4pJMY`bp2yrxM(>79&f;&r~<<k&ZXzo<f
zgVrP<-@tp=h{^zzZsNf%1ziM-v?>pDQmKwYJQ#u3se!MvM9rv)Md@IvVvt^lwV)Lx
z<*Cr25pZdoSyT*KEDyS_wj{L(yyONf4iZ45noMXIf%Jo%ngY)wFms^=63AVU`yD{6
zXoFbLVgOhoLdu_@C{>1335g{Npc^egZDCORAVwXWmO*K^C^ZeTO%ik-DP&;+*qbmr
zL53*6=iDKa`=zO1C7^;z17@!dxEz8eSBNGB=%NmA-Hzrihzj`GMVTegYs*lrg{jIc
zhSl}(wt|iVXk0rpFCDa04YV*cBNcRceQ9D2w3!3bp$AK+5W`?3G;zSzv%pk?LI}QO
z0<`1_R3pQE1$Qq<6tct<v}Y9NXsDSWNsy(Wgr!hY3GN#~htVDLD$!5+(NRcG2B`*B
z`RSQusig%a8L6QB1|Jsyr%j|}hkDU5#BxwMpa8ll3Y4ax<pM+obRr+9K?OENFD)L#
zPlPo)K=yzpra^s$%7RpAL(59R0P1CsJV-NatpKQD1QG+Ks`O+~0*D7EprX{GVhxZR
zU`-TIFlVNLe4nZT(x3^dz(EX<ZD?sBGY!<H0ADTxQlX;&S}ByDk_uiV1PV;BW{~M<
z8ljfJ;t;MG>P1xjAVK6>1*92<K{|_JB_D_b^*&4<Mnf|oNCo&nVnj;-rUF5uBnFT$
zQ~<0Qlxabi8<gfH7ekJ80r?Y@44~&mAuTn8oh+4-nwD6aQvzBd2vP{HQX$vXL2jW#
zH0VJ$?SXO!L>v|+;7L;p=pt^&fR%!+f-dO%1P{mL>`GWA2wLI>n+<}l?1grMFnZ<C
zD_bB54U~Y<hOfXEmE`IufO?TdnUI6TkS4`oE(3*5G5Wy(g!Doz1#1QMc;WZvL0eW3
zX^@-1Lw&B`yYawXCQSuhJ8)rzl$yW?QGrTEy_EctV$difm;>^#Bg)1LNQVX@3A%+P
z7jm#tP9Cf&333qFG}t;7kXlfwlAH|bxPlabFp^2h$*_Z*N>GLppu=3r$?@>+s0P%Z
z(76PNFG0qEtkFYw)hDyKL?cGsH7LkG2vm%LrNKKLKy#HK4Im5_#n9yD=;;I313Fa@
ze1#w=&4KiQf;2HD1stH@@Pu45tpnN<g&CosAym)?4L#H}30a(=sh60N;s&{+5PWqs
z#1J%3;q^X5E!0ggqd?voP*;J%353B30puDzQc{u<C;~veXOIyftgL`I8w8X-Q4%gl
z0mKTV^r#V|?iQntREi;`Hb}-o3_qa+VKC(SNu-Fif=@E*ftnEDaRTt+F<7$^EE^}L
zq`-^<ML&{DAZ~?NlL{|%(G)2w5H<+nCHVEVNUKD_YwF;&IQ*7ch(|%;1<?wQ9nc6M
z#0-p3g{T5&4~^nt_`R)|#vn%05TOdP281Dofct=;N)~xQ79<VA%IGF)Kx=sLxLk2&
zQckKSsQL$8$qH(=!Zr_sM#y2?Eo?yv488$Q2Xfy5Y&ix*62{YkZbg7lplM3*E>2s}
zC{1Dx=#bq^@TK37jbBJH2k}Z_d~{YUXu>&0y&Tk~00%bY@EuSw2isK)l7g{8;*jI2
zQ&T|VaPP&aLxLV82w{Pg!W;?`1>KAWwgG(;fhI^LcuW$c46FpqLz=LKxVNM@H5t@|
zflo((N6<ioh9;;lQB<O%V1(pLaQZ|kbHIHD<l+xS7NlNB0ah%7W(AN-L7W5HpgIPm
z7%A0((gKESLB{K$RuHJ}1?j?<0KxL0005f=3Mj})IFOwpFmHiWfiS4+3%cb_DZnu}
z7<?Zj)Mt=Z3b<%;bx}gsmXZ&eXe=rL*#n)f(*iBY0__F`+neX3pbMTF16u$Z*an^Y
zUR<mR8>|Ca4#K1c7)TE^i-MW~=>AjCR)D(=OAZF<#<83LVklPKi2MrD4{GLu)0myD
zf`J~kCL!3*pj#QBS7d?`H8`Tdw_++l$F(()RxyFhg*X7L7n%Y=qM)h{T$+Fycu2)G
za-u_&o(Pp_1#FfAbW|U73PVsS(v~Z5bb(ZZt||sO8fktHe#AKV+IY~M52zmtQVcpB
z8YvSgLkb||`8$-hBFHD8c|xR1l=UD@Qsk6{h)mF68Yp_xQ%hV@i<6;kNpPD1#a0v@
z2o7YSfd+WK9dschA_5U=K&5kPafx1WMt%{BC7=$b6L_sZxaSUz7LeC9K&y1XeLV1@
z5|q_hX$r^&Lsnp;<#c5QxBMb_-KqfYo<Wwxfwr-MdPGP*1uuewb|64K1!#jD6pSE@
zY#C(6h)_U*<19J9G_M4djzIN!F>(tQoCpx6LdpuzI&;v)nuV&Fda9Y4pnK01R24Mx
zKtrNB3Rw^ep$REsFt)}RLc1X#$D{O1KmthhA*rPS*xkv=3byET>?O9SZh+0DgEb)B
z4Dl$m`b18>klX^UWRZoD{g_jX{orY=R)8+tg)D1;my_Tk(gapaf>JxWyEHX5k;*Vc
zA_m(K4~kM~B8FumP+<XC=M)S+4;5TqAeR)d@C9vzD+8_W0jGwX#NuMmm=Y+Zp`}{z
z40}9kSfU;v0*XPjDOkj~CaBUzx%?fqPXy8n!YE2$c^}@OL%lv85ey)mI0|!g1C?w_
z^B`kvpit9O2nL<6nU`4tUjC(5P-%xz!zn9Zm;pYG6I>jCHkg7IN`Oj1RQF&{i`YUD
zmLgHCAuA<<!U3Elz?LV2N0&fi;M7o*T3nJ}l!}rb6qFT0L7QaDLC0c%wl#r@w^GPa
z^WgA7_=)5M1M*HTs6_#F5%!)g$a!#;@Rk}xg!JYP%#j$`6)iD?Yz4<3IA4HUS)f=%
z%3~lEFsuxn0J2p;F1<jqkhB5zCEV?x1}4%hK4_H*rbjS}K9Fe;7lAJ3MlBk^4JJ^r
z0BQ|_+zGy|T>}v}Ak83*)XIQ_AX+m6G%O2|P=GX9plv%PP4L>(%ru2UJy7NV4e~)&
zJL*CAE<nesFpipmw+n2Q6toobe4y<W*p?-5Ee|SLf=cu9Qj4$*RDs1|1rs=(qVA-?
zb2cZq2F7;&Iw&YW7}DRxaU3$Nn+YGdg4zVpWDB7{w*zIDg9h8d9s?N)c4Ka0b}D3y
z4V-{r?gz<(5=&8PBIt-jaKeWeq@WDm4Oy9As)&d-sFbY&q7{!t663^p4TwIZ8VK4x
z0NV#SEEPOP2vrCfa?wK_iUX@ftd<7V8_J*~6%@*gK-U`-X{6=ngS-XlN`X9`o0y)N
z4EHWX9O_|E`+)GQJ=jV_Sq_?12X_JxMy2KFLo5K@#R4)LY^Pp)d`f<Dd^~87J3k-B
zgDHXf9jp@M3vj9c4Yii!=YuBlA-8KlRz$=@J*T4(4~oI~?9@sfg&?1N(9987AC|#a
zP<}`$DJ=lapT;|bE_LzDO9P#;jgZh#f{QEZC`2n|WR?_zcDaIfKBPiei510}RiK%0
zB~TX_%#H;oDNx9QTalmu*8vZkr$C4Jpk<bll9GZiDD0t2n4x}vq?C-3l7eE$<qH|5
z;ENaZ3o1)8^7HhQp>$GCev&?DLRa4>Gf5vFFrbCb;7e!V^W?b@H=-;`0l5xpA2?!k
z6ri~T+p%Jx{o}R@V0C(6FU4o3XlUvvXec>=xu8on!0`tPInXi=cqC|ma+r<+B&R_G
zK@;WVKa|xsVADX0TuTx&^NKaHQ!7C!6_j3J7(6ovNiSgcV7eO;d@%KpqzN&%ptJ;J
zBzU81De`d|SXvk`dyw^~r-JokW>2tUh`rE63k_OOvPCK}i%USQa^$iSA_DUy=p2${
z(B)2$-UWE?1!!&{Ge0k}s1meRBRK=KAP;m@1gMu*TAW&>3maMi9gqRi3|`~`nmh-o
z09EzHpba{i#o%*XQ;Uif!1)0r2@Vx#w*#`kADTo!)0IJ~i7C4Ic{!lf9LX7}dJ3+2
zpv6O=WgjIO`6&vCIpv9!#h^v2DW%D&3dM=Jsi3{Spfh+NAptSb2+7D$kaNq6GD|=w
zxxg%kC<Y}*=t<__XoZCcC>o0(>uTT!Y8Yuit^|Oz-=PPigR>k+HTEr`u*na|I0^b*
zRZvC@g4hBI7nowm+FS*AJ^~pJbqsVF5UB9d18pEH(17kagsyy#Hi(6ZgQ{jE<)8_C
zP$L{tK|>^v&R>A`+OhirvilWnqb;;;0o~-Kqu{BKm<z6wK+y%7OoF5_*w$Ilq#bDW
zS857u*%x?PKeI%kI2E*hqAV43&VFKYcBLNjcs1Ce`K2YG6b6k_NX&r(1uO}UP&`tw
zlmN;TAWfhsj|VL{3QjEvg{*u-j&(@JgTyqby8u4P9&{o;!dmDAY$nnMBt(4+8ePrT
zLtG+&&<1NC6oc(W%FXa5PcZb<%F+T*>mQ!9;4ThHO)PTBFVDkBswmbY`vBAS5||m-
z9FSO?l2)9S0*U~LPLS2;qZq*@iFqlBMJbrB0Id^-`x0a917ad53P6qO6db+6Vz42g
zwkfz5>YED6^?r$<i*rC)K^U4Bis38Ju(=Y$b<i0wBvW1TlVO<!GOB}_i4bl^xC>`^
zAcZJ+{1}vcz#ai7QP9ER8VXoyGtlOylAP2Sb<mE>6y(!sp&o@81{xa#HPulwG9nPL
zoaq79h!GG_Q^Cmu-7lbl8;GABz?w0RZ2*gcjf7Qa&_)F)V!%d1%HMcUr3Y4rQgb8w
z6<m9vCUVe}1T?dQ^&)3XXoU?HM;!%#RbQYrzxhRwK`TV75GIQ&y@6v0vIrBjZyjnq
zXjTGg{2w{YFpb72T0k8XNXi8}7czke5kU45coPM-X&gvErh;oeXn3YVuHFNUAo?a|
zrz(I;S#ZJvm8_tnJwfYeL9qbBpd1GF7^otKSnQIY3`;slQ3g`146S29>)D`9LeRp$
zvedj1@Tx8aNLx1rd{8=AQ4#pUgp~YbP#u()4z0^UW`Quo^<cLVkqp49(bFNkj6rF$
zDJ!^vjxtTnEr2=`JiMs^T1f&~Xb7rBAx%St6xelGNVyVh6(l^3qOs;g$Z6@IgcJ)+
z0g&7P@)oG|V+%en4iccCyaEyjVdxrk(3lw_J{5EokhaLc${$3yV08gFgF(syPz0g}
zj0QMB5RQU)2|3?rMuWv5)_~f}AfFVa!dHYTKr;wL0VtbdafcFU%s~k>L<m`256`B`
z3LzPp#h@gYTM0hg3LGGiby9i?!TAd18HptzY0%|!iAkVMr<o=85ch(LX^5?vn3V@;
zpcU+Jr0f-s+&}>ZGYG@`!AK=J*7`vsStl3nZjjyZjycF4%mzGCu7Fiya2;BZ{sg>}
z0`U;YIUuw2;z3)bAqfjPRY2q*X$m46pP84E3fk$0G-wS?7|@Ub$)|$mzL3`Fpsb~W
zSPk|MwgLiVCvq7BEjE#tkf4>GV2eRX9!uE?mLsy{gsN2l^&F5xfk+n^;d6o!DQ*C@
z_+XAe3N5hvz_l<ajC2&heRXIkgE!Y82OCI<UOct{Mk-Hm)CypWKnvO+y*{WFs7Vp5
z23$IVY=SxlQX?X#Lr@Vw$Q2+15K#)<GHnDpkqwmd!DgaWP@sEclk@W+on4T2u>ItE
zAJj_+-K-6EE21I=`w-b;P~S8jk{O`2B7_s4R+<OeM^sc?f;Urw?7=n~5Tgz;2W628
zG|_=P2MrOt-Fx)T3}OlmG~|+*m#zc}B1m!q<$JLAu(a^Nsj9jbDV1a*TC@;{A{PY+
z1EDU?1TUTin~szaKsFL|BeYTk7cmg`>L@6IY**4z$V@?U5qxn6=n!Pk02DZ}W~M-6
z0ZAp)!Jwn)(?Cm)brj%wG2;s17qIiAGgCkb5UdX&g&ZTG$_E@?VD(7WLKHzQ2TMW=
zPHpf3^AOWOMIb~8_{J1xXrcn!XQkknSE-|rTbvGNDcCB2Pie(mtp~OVJ!R@484C>)
zuvyr$FzAFLu+7NX2U;+|4mN=uwF6s=4m$)2Y&pEX(^LQtt|RU>)mKu`hE~>yYz1DP
zA0H38#$B%<I|n|w1PTqLGZ!$Nqzsw{1~=ZoBe~!m7YZ7gdZ~JlD!U|K0dyFHLP<XI
z>~k{6duXW~B!s1Whj|uq?<R}~^E%idP2?~FC28b)IC1EJl^`JHc;^Bkxe8Q^pyeCz
zv8ee4sd*Y;M}X!HL3c`H+$asQ0fZqJvqCPEMvWn8Nn)g<0J;<xk_wd-oJvbT=emRU
z&?M#*=YtP+1SeY1DbYEZ$(bcNu)8e5v4qrE0GW>*DDZYWM86_rKn`@MKX^b`Au$JZ
z(LkjF$OzEEHsPs|)%T#KXCN`q){>I)Oq3JtKz@QGNQjF;d=OSvz}RmGKHDV)T8=;t
zN-j?<hTB@4TB4^A4sGD2=Yyv9^7HJ$H)n$k1YvLx6G$-d@eYu6AVVOY1&t3X=_r6r
zKq?E6&Od_ofgmaf$1>iVqEiw}5<y#FGLy4&Qc-U@2KfVqK@o&exq_~uNi0c31Sgh(
zT-4H9Q2}fpDC>a7$iOEiBY75baW42SS<rwwEJ;A34ZN=dln+3u2Q<wPl$xGdT#^d9
z^bmgQFQ^xknwgHc1{h`r$}l2iw6Pep%P+s660|KZEx!mwn+|li7u3j4NzE(COil!!
zv5^WIphNh$Jh4(k3)DY=T$&9|_n>K>ycCe(dhp&CXrLB+(kN)>AE<i<8hJ}hLcdP4
z0JLi(zqAC}lZ3k&<m0^5awK1t=Aj&~2Ri#PCkJFWiZaL!MWj@utl(Oa2;RPylbM~W
zke`!+=pllx+${kOV}s7(&Q47&C{_SnjgSor9&mRC>Ko8@L8J~{5O_KOHT0kx6cm&}
zS9<4wk1awAU9k0_KmfTJJ@COhNApuO70UBVb5az*H;ts^=Rr5xfzo6UQqbChZuo`=
z4QTKj<amVJq0R=~2o2H-!paIkdih0}>ClUWL1_&n493a|x!`U+>?m_o!@%)h0y;qo
zX}%GfK7&As6J!Q*9Kbj5VF@O<93(-ZX+zA-p$0Buq7G!2vVw+|W_T*N*iA|W-)9Pr
zETxRf^vu+}%w#1<ydoQ}P+S7K-afM!e4TD_W_n&?Noi54ZUJb7yQnNPFI`6gTqRcK
zmm&&Q(1~H76kC!Hu0s<Qia;B?b5j*Shb@B=NkJlLt4v91QL!F)B^GE;Fyyv&(1^D}
zMq+YyW^slBWJ_9RYO$W4UQ#Le5M1zaq{)fJsXE}Q89eWi2)*GK)Qbj1kd8ueKIrmU
zb;uopi3&-XpgpX`rO;#njRa(Wg5m>Im?+pP;4Cjd^56yyD33w%OL2H+Nd`PYfo3Z}
z`z@f?isLU&a&n+s`M^7!oqd8KgGDZ`&i+A;A^t(2^Vmu<pe_bQUw$cQBSL<02_he&
zY_CG-%mtk=1d0O%r6NSZhtQ^Et$>n6Kt~OMd<~jsK&V2|tfWwunFtDTNcsc02c!dA
zxe6|POEUBGP+SL_0)T9@MVOKU>bZlG1vDq4g(&ot`TU|l=zW%u@I_v@3L4Bx11*<8
z*|!REA*4n@YC{%-54eR4TBm_pkID)j`Q@N;1+<(HG!+L~2n|2a8g`Nrym$p!mYZ0a
zlnRY>PzeV*K&%*))iRSy;^Xze{l{YX1~QOCkeXqrnn6t~M4^LmlqzWBFN$TzWtlA^
zs?ch7kd+X>quPd4x`UK}aAjs{P6}v&Ba)9mc>#o>QI=PlTTlr~jd=yo{ZS=}Nu{8x
zVPTu2V0@@F=+F+(Xc$Zy#)ogdE2vD%OwUOzfeXMks(=<0fEqR6m6_n>U`B}3e~e(}
zLC;V?aw0T};pXKR!<mUi=>>^J#i?+C;!1=h$dzyj_<1l2%CH^J&=7!}52KKjtOqK)
zax?QX(<&7}TOL3I$WS$)BXAHJQ}Uscw}mOWFlU2RB&8-NmKLWX%+Up#1M&;lnV>tj
zVNTX_gqCXoAP*F2Agvy;jZt?6rL)A6R8UJAwClGZzo<kHv~wu6ATuXF-Bw9S$+aRe
zw;(6gN+BjM1ai?5D2amxxWQ#kq5@=r5lB8J&klB{d}1-En9ohkD=~~uDF820fa?br
zxA0k4BhWf}1P^o=5k7MibPE-X2r7V>;+J2N3OV)yvf#K_0e+nfI9;IlS|KD~0Yg+r
zp%lC(6v;w}cMapgYM~x;16Axfl{%nCCdfw6SZo@y>7Yslbe=sZ$`YZcIw)v>j`2-Q
zPu0``&&h(CX%NGqmzgOPL2eWSU4c<l0@4bq;S`{{AXS%cu0lR|R~}?#GkD1eC?|q8
z2A3A6rj_RC#pHpODI>PWf@ZWbQlZhN0B#$DTAg_cF8Rr&pcpIGPtGqbDo%}u+N2M0
zl`(h&2k7V(y@E=JlM_%CCV;$|2ulJ`-C%d-DI{lr&US$wX8^j~y(C{DMjc^g0yqqc
zO7p<mx8dnXH&+4G4n2rt!1vaG4grKMoB_>>=s}js=;ars>l^D?>Vsz|^pkT_K!vp)
zXe)Y5o{|!H`ASi4BIr;xNC)2*o>_tt%R$@RJW_KC-14DnG-L80xeBz`EgsfP(1=mj
zEd=G1JkS`mZH&4-hy&Ui3tDmps$jr-J;5WKItrlMux(@1{Xq*XQek-x+zNrGe2rAS
zbUiC@^40{8so}6x7qli4wrL1tCuq}jW`3Tn5_nl?d`VF$XnhjQ%3#o$AfTiL)1se}
zTAW#wngU(ELC`ALf)f&~f?f(<nO_RMbq#6;=-?lmfvF4G%|xU%kkxUZJOQbrz~fBG
z`MJ4?pso=3tc(=U+%9hGpqr%#+viwXlAjAYP6Bk)0{D_f1$YUl2U>Ouy8RNo@HQni
zsWd$ubQl;oR3W`fSaio1rGiS=_~MdMPzO%~!qtJd5}+xi5VT|*%7%mplmm4yl$V*F
zmtT|`4;>~2AEgahZ3bO$T#}y?pITG|5refMK`9l~`3Bbndf@a0O3(0p1E6)I&=wLX
zCxh3mfUa)<>C-C&34sPYK*C6E1$Y9sRe-2NG|Mv66qNM9NBzMRA?X7(9ALsa3Se)8
zHvWRnohySJ23Q7akHM5cmI`Pn=_w&!S%PH*0Hy)7A|$T_emexX%?+{>sTl=}0wrkr
zgq_3;4o)S=0SzD@!^X&<2SG!$fsafC9nk_iF&3-~p$SV2A^9F-49HFaydM|;sm)3{
z3NW|8PHo2P7##&Ac#Q`h#nDr62A}r{&YI8y8geuQ^dM%$8Wi~5mY{e?i*rcARDi}f
zga?Us&`F+&;N6H=v_X?FOdpgBYPNtP29l*gcQt_qD&oN-H?|6B*#|S*z~UR4@R9d+
z*n%Pt;yP#wvjwL!*amj^8EH_LAZ?&T*_jDW*T}^#)Gk=E0o5PHdLRWb5wsnekgx%H
zk}w7t6A#P2$Q*DAhM0sUqavj(NQtNvP?TSmSqxfCm;(#N%=|o11j8HwYjSIpz(X9V
zbq^K<O|8QvA(n%5L##m6kKCPt$SZ*l4ut4R12syaO>EG-2e=~&p6@9Jod{Bpnp~m>
zT2h;uR{|E*(A11JjMW1*Pe98|A%>)bxJc*LgKkp-$%2k<0bd0G8lQ)^%%HpRFh?@M
z#=r_igm*x9)5BZB#icnV#gL&OP%5fSEl~hpJ`3v$gNA`)AWd3m?-<tJ1MAdLD9A}o
zEKUUtT7Y`I;C2?u<+RWsva_>O(oul82;xa32YKd!^@3Mh<|cwx-h;YOpiz>dM37Ww
zG1y%2(mg~r0-s9;%}pRtNIg^v%I+G4FmEd>WGL7wRAm-uL~CS5gLeYQ>L`F%usy#q
z>QDj1#@|>-!JG*$nBjd?&;n?Xqcaq2DK`re1|YYA?g5A1Bc1_GmPL?Nn;FqoI-n~v
zK(t}3jsl1_iq!%66*9{b3fl+-YRu7M%K{NA6<`a2gHsDjK?AypIiTf9ps{z<{S(C{
z5HVQ9fX0Q=Q{kKXKx-@@hmk{;Gl7;AJA<}&!PJ979@HBH&rpHJL11pfFa)Fup&b&?
zAl=H~#U!BNFz88oAXC7jDJVJ+gA>`QmBlDG)`G`hU?<Fgj0BBvID=9NstMq&0!Sql
zNGa&}=HlYgByh}WI77~g1ZhK@Q-G!eqzh~#*p1E@?o!ZJ$U$0n12PNUb7<0#u+uBf
zF9I+5wnf*X2cF!8CPI+)(1Zw52hj^kd!U#jSY3f?QdngKVZ$mP@R`^cRTE?zF0Anm
zY0sfoKM<XeiVj5usM`^rmXnwcK1~?yN^wL20Qm@p!8Hy_B?{W(u7gK0tgeE%0=vSb
z%=Gw-)Wnq3BCtz9X&0gpbQ+v3XqF}wG>oE`mtPK><IGG0jkrQ}A*F!C;^fTC_#{Ya
zXsZAl2GWC!20_m&)ldQz0q&rq;KAL!yb@cbl>Gc$<k~L@wA%%AgD~X$S%v5va32~x
z?SgCxq~!_fLKbU)PqPMX<H~_8VFevbZ4e7vK8n^J1zQ1f33#voS|33Q{v=RUrBDW%
zYmSeH9^@V$4^3hzCGn6YehRh<dHLlayV5}6qoJglqOY2(uNtYK>S3koYo!_t^AW^U
zCGfWH)D$ZPkil?cpvHpoHMG500$S4wi2`g5VyJ_lZD6P#s353e2dWZ5sTV0;z?T>*
zDZmtg>_^oHu?^}@=)e<b8WN<kSVuug12m+is|!lA;D~^XYZPlj&M*Kq$Usuy<P2F&
z58uQFo7qfL0vDyArS8S$u)Pmf3QC~!%RzlF>`itZ1<0;)i2J~;9$4cOR-~cq@&m<9
zViDFwq~MDRp(_|c845Hv48F<(Yb5|~(1DbJO3OSQ1&u--g>vu(TB+b;*b_@qq0L=A
zSR)tZ&MjqyLIqoeLRf|YnFQL$2pxU4RRCv5h_5i@Km&%*A{TUN1Gw-7ZRPREOi4*a
zKD8RHsR@gC@Muk*wjpS3E6j07i2-CEXsJ_X9&EY<BvMT3T_J_wWD4>mJOrRyI=~qb
zwz>{{^99Tm5Cx!BZJ^Ak0P-ES^^BnHlO;K+knQ52k^nY0prD#*1=<*|s*$H{sG|UJ
z0yG1GJON3-DB7`XH!akIHKRa>k|H9ZP!HCcLK6q=imR?wP*!kH1g$DofFz|%Xe$pK
zKhRlPkRz1AgWI6$M=u0vb_W#wpmi6Z#n<4wXh8Quf$psX_pCvu&%i<noWnpv4WLT8
zP!Gfc-yI5yUl0c#-Wd1fL67DKxdOZ^6taC1bw@WS#vt(k4PRvi56~VHL^vR8#i(*X
z3mHK99l07(fEs}m2*_qYj-CJ&m!O&$<Twz9tQ`ic12w*&EkXEhNn0aO$pC7vgTvPr
ztPtWK)N5xD?na8$qSRtNPz)5K9KL}Ry`XvmqzHQcN-F5wE`&*t#ZKT8RZtZvXe+=)
zq33;pS~RJ7peuLv;HP<kmS%!9BAkFQTUi0gouCnw@?r%CxENAmR#rfAFI*u^44=Z>
z$|BJ9(;6U68s!RFaDy}z^x-xsXljBpD%>@83I>p}+W<M5VD>?WY>-V;&{8neGe9vC
zw8ILkfuI-%VQ|)o&Wi;V#NdvNl|ngajtr&=blebF0A?>p0LBI>1Z99?kYHgvhzl-+
zz+5m3X@3GrZibnFhz68G0B$>U&llLGhM-w`CD4%^@ZzViI#1iM7TQ(-D*`R7O;b{+
zM%Y%XUtNx@1X3my8-mWHP|{P<Qqair(FG;HVna;`ZKSCH-fUiMq<|Ew5PgttI>;&z
zMpS^X;}oOQl+azLqmZVA;T}*w5aRjrV#L8$I`EXCV5<P>gn}ao>I_)0K;vE^x41M{
z111Pwbq{hBENoF!!2}_5u+E8)o0lMS01BCT&^05_MhMJE(D-M5G5AO>h+CoZFvCEj
z3rV0Qx~VA;dE6~jc=HNW?4Y*NkQ!$YQ@}TEfbt5c83#R8Ko{DQfQCeFW?pFtWDR<W
zzP=fBsXFv%A<){V5(Qlas3I+xbU{v04(N`Y#N4EmM1@Qpg<>nvdD|M9;6;t#R$wtW
zRTP7pQJJ9n+7OZj!ObU#>mcbMP02YQG}TuEZa-=(ApEDT06mcaWSs`o4LS-+5S9|y
zE*%9WZ3VDA)X6#uN)Q%EUP%+wP=(lrC50)4fNtXg?X_0Y2A!>h7AczAO8O`gu-Md8
z03|w53W1JyK=M5JbPiCC)qq7SB0YkS9ZN|qNzBXv=W%digyv~zw+?ESjsn7^pyCRG
z!BfkykuUhPEOauP*vV_?Kp1@5IIB2656(fFcuuM^f(t_yNW!@wRgjULq^k0w%#u_M
zkRhOc1L#(p?9@E)Eda2^GvLBnAwMatv^W`ZD>kSF2-}_lYBPWq*?>=QO{y{im3pA1
zn=$H|8YQ4B`*akP%1c1KfntR;q-I_k<m^ni&6=Pf0(FDa!Ht-B$h3B`MrLjSsLKb9
zC-C|SP+z1P8tkCGC7HPekkp|JZkptR+9jY7E0`HjTM<otP@!3!3t!Sy3rb%g3(^#9
z6+ptEp+eZ%=gJBxptGuAW9P8dv7qIoAT7!YCHV!g*-lUaP^<^KAXE>gE*|QL_;?MF
z$)FL(_;^US5OP!+=tL?_y?F2p0K5~2ZYn5U6KxX6ey~Z9KtbxG<$@vyW)-NJ3!0$;
zHQQjVVW<L#382$?Kugp-!N(_nx?70~#hIX74jwtQ0tXei^#j_42Oi4+9nfH_5Tl+8
zJ}o{*9o*Ch_a&fl017hv0R{>sNccm`HjoyGdC;IlIZF)GP{(ODi9x0Zz6uw7RzJv6
z5JtBc>=#f<1xcdE5_%dT+IkfK5;7Gj_@E&K$ts`$S&%`HSXYJ>FW`ehU}9C71t2AQ
zQJDp9nV{1wK;D3Ahi#5l2FGrEPG)v$JoGSqTZPPgJ*Uc&)M8J6joixks>}j#Hy3I@
zh?`WJmIm&wBB_K*gG&fBn>7%6KxwiZoEVEiUO<XWWe^`)OhC;7xfj&s1>MW516mPK
z3|j4<lL}r>l3%P>o|u!ZfgD0e#=-Q0LI6}mfM{%ILT9FdLqIPzFQpjdb`2%Hf=VS=
zAp|l78K;3V3sS}h--iov9>@YDcO&a6L(&1e*%+35&`m&0+`$SJWDkOxw4f}Eno>d8
z0=Z<u;f$)x0%-Vxy`iH}1}=s{E`{IR8y%w#jl3A}ZH|bT1I@*N79_xrEk@RZ<VJ`-
zWC8H0Bgm>zTn|x?Dg@O5o1cKx1EAUpUiiXtB`Erk;tsYU5IqhFrXpB$zyduDV=n~A
z2v8hTFEPQZsLUMXQ%6AY0mCpQIAWBvgoP9*ILrfO00mHe4!R;6l++<3o=6EClz)q$
z`8N%@hKIQrMkC_84Aj3$OVb1GjDQV6fl@3|X2s@@G?e&8axlV?X?R_O-vx*k93*vt
z5)`y-ge~%cEeU~4LxWdAP`pSkv>3GPE3+83atqq*0<F6Nw=Y2pRlsxZ(1tB&Sv;r`
zMqTU#ksMuG25Qla@TFzCdHJx>FTyL7Tr!J6bM&B1AMi{2@UOK>EG@~;NlYSaG<f+K
zXa!VGViI)47{p{q*8|$lFD(F#bjO$E$0sM|7L*p}rItWPu63XrJmOO_i@-~lU{x@v
zJq}6ldU-yOrVVJB1*m(DYk3luZkYn^1tQ>4Mfi*X%Cs0UvuO&D!?VHDRXAq9U}YjI
z4Yn5+cc3ftz^hO|e$zw5DM=<KWx^-VK#c^jQP2p4mY<ORJ7OFM%C}Y0f(_+EMZgPH
zv8)DxNW*%y$m>C%HYh8A_Zoqs8L}h+T)cv>7y^}T&~<3wHWz501*q5s1q)=YJglz=
ziDu}ITV!t_)fvzWI-p4-GcP5xEHkAvF$daj0AJc+fTSK|3&izGPL&Ffgb3>9fQnu{
zaNiZ|D9FB$veY8bs%wxOsLn4&S&#uT3Dg<@cRg|1k7hMU6V!UpIu5KIA0#!7MX3tO
zMX8A;sVVxo`6-!cnc%hmFi+-GDkN2c){%f(BZ=unsi~m#xX?WvA)%ma!4h*7ib``*
zi(%bekl`Q<bue<58FchBR2VZHVKD^KiyG$0Mu2BG(Yy@xu4i6yPH74#sKG%Aaxo<I
zp@%4e42EG)ux9HhfI}8zZVSaeG`m0s<Ynd-pfnm3Y!#s84y0x;)&Lzi0aA*L<3VHl
zpjp58qSTy3&~?4wd&xk1N_3zru%T%Rd;>B_r5;ou9<;6qt_{?<fuvky<3Se*f%L$Y
z!A-}~D}WC7fZE!iz=D>Ihz*XKDE@<HIb_>FVGtdo4v9@nD<O?-oU-6{H*Vvgjdakh
zdYNgNkl`VSiBK6xFk^-R)K#GI5U6_ia15qmXi*TI4Qe-nbYdz2U*`ZCwvNsQ4+3R_
z5*0`(sDG3VT3injfEpBwEp3842}z%6;8AsK14JM-Fs!TqH4QXwsHFwvfKCeqSqmMW
zg4R2rTi(E>UNOY8P{pu}1X^ZRT2fG20;=jjbL43A<M{|lThJ=b^wg5%@)Shkf*#Nc
znz{q0KcrL%S*4CVK%=do6rYipmy($W--!+x=|qfkg7t&uwu+-;)S&~S(7C%Z_~HVk
z_%bDJNV?I3&D>|ELH7nAL?Bz>Kpuh(9m9MLDPe6DlvIo3RWsxB)8bV#Rf{17uac?;
zx~E{10SIU6Kpg{3^f2>a9XD`48WD7$d;%KUgrprrmjSE|)NR1J#T+tn3fWo?jZ7V+
zz2x{SBuH{X)UBYT0~G`97)dPw73e9MCEyebZR3N39lit*QY=EM&CI;?oK$d)WCdOv
z2{H|Yp(cXr5U^jM!GR<d0=kG3+PDJO2%tlLKo==O>Jdn`E!G3o3y{zO>4kMPmHa?E
z)G~8Z!L9@!dkt+tfHvAe^nk`~A!#}uvRR}g6SM*Wl)GU?sbM@s0qDw+N>Ez>)|vw?
zd(u!!tw>E)(u9_72(_SlyApE{E5-^yGZxS|0U1)Pkpvo+(gTgGXQWoZ5)EuUDI|G9
zTY4HG=V-!|*cN~;J1Hs3OorUA4h=O}*$g^HEgqT#H41W|vhXe<sQ3n@<Cr|86*!=!
z00w%NdIsQ(1#*%?Mt*K8=v;q8*l=7CXjg7=YCLHDnT|qYN(y{X9<c`vw)`(VH8tB1
z_Zgs|KnKm>#wVs=9?k^b1rM1g2A{Q|0a9e7W2C90U;_0FD3Y-%(*<4dtYE6Cqo8YP
z3Lg-HTL<+5#(5POW<eE#{i+ddsAHsK9IL6L5N)huq+<x0d;x_Zq=G;M6wLEM;4Ke^
zZaIl18W1)t!GLE{L1FD2tYBzhr~r{wFoe!~!j>t3T8_~g;4sutFf`DN1&?KeTOO$j
zppk5Fc7mw}CvHOnXof6?E)_s-Ux3y@z@sx(otF!exC~*bM8Q@;-NL}Y#M0C_%>V_M
zr&yX;BpaBTnwy!LnVKaT8(Nw`#Eg>7Qq9tg49twp49$$qEX+)e49tx|s*DUw(?Be9
z6LV8@1Jg7!L$g$KV{>yeQ*$G8V<Q7IOS4oX19MZeR5MF+6EkyjBQrxY6Ejm|BcoJv
z19MAD6AKG-V{>DpRCQi1P{OxWf`k(|M3s2CVD1Mkm;hHzMC4pFA8Yb*A&OU|rVDJu
z3^voC$;$<8bU}(ULY+NLUakOdMkWyk5e5)AlO-R_b%Z^@jG2J}gn2-MP`s@X#DGVO
zUO^?g&dIx1O-*KIU;tr0kYXs_)|kM|zyS48T25jKn%=Wn^1+MDnC1k2V_*Pbh+80<
zw>7?JL(vOgHy+^4$_7%y%)rdBgMope=r4#jrH317q-{!1kh4_`=!o0mn3B?r)EM|q
zwir+u0ABA0TKiI#Sdto(3fV$g3}b-Su$9C>Hv$#MBo`YR7=m0srH2=##Wkg)M*`xx
zc#JmelpYa?6j&$R?NfTBA;R%clTcc9Q(~v|2twqMv`tCuVF9JCDLtI<NSIPuT&f2E
DVzir6

literal 0
HcmV?d00001

diff --git a/examples/example_flat/students/cs101flat/__pycache__/deploy.cpython-38.pyc b/examples/example_flat/students/cs101flat/__pycache__/deploy.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9c91ca3192aaec26f60abe00c1109cb32983e52a
GIT binary patch
literal 581
zcmWIL<>g{vU|=}nr<>Ts#K7<v#6iaF3=9ko3=9m#5ey6rDGVu$ISjdsQH+crHd78$
zE^`z!n9ZESlFJ&!%E*w)mco+FR1}iRoXVKO3WjXGEQ}1PtXZrn>?s^6oGDx>+$lWi
z%qhGe@f5yb22K8#AUib~Z*d2u7UUO|7`o*omS{5G5-(0IDJ_UkFG@^FjZe$WNsTW8
z%WE>;;wa9`EQn9ZEV{)JAD^3;nHL}LrpX+|mYbQEnN}IanV*zaTAZ9%k{ZRHT9KMu
zT9SH;p-MtePhU?@zqq6{B{i?4SU<Vg(7-S)C$S{t7I%DnL1l7caz<)=d=<NvUP*p-
zYF-s*N@_t)ex+VPr6x-hS8;x6QF1EC(kPCU)Z!8_OEftrH8C$9#Lvu2EXmBz0}HdK
zRwU<?rlk65vPW@4Tn)CVh>3xLAxf<@FS7*Vt%9P=vc!^9BfX5wl$6xG_~fG0#1e>a
zi;I{+irGP4El4dYVqsul0C_hrF*h|nekDT@Cj$e7_!Z}D6%$&VT2vfUQksz(<C33T
znhWw`42DH9sTGO21v#n3Fh)Em0Ae!pic5-0lS}f8V&I_?1NZ$c4x8Nkl+v73J4R4q
R0HqloMjl2UCJsgcHURWnuU!BD

literal 0
HcmV?d00001

diff --git a/examples/example_flat/students/cs101flat/__pycache__/homework1.cpython-38.pyc b/examples/example_flat/students/cs101flat/__pycache__/homework1.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f019923d47a404593f992813d90c89b3e2da2546
GIT binary patch
literal 994
zcmWIL<>g{vU|{$tpqFUI%)sy%#6iaF3=9ko3=9m#UJMKjDGX5zDU2yhEeuhNDa<J>
zEeugismv*?*-S-lsVpgMsZ1&CDeTQmvl-?xH8V0Yq_U)Nq%x+kr*NilrEsUSG&43c
zF*2m^1T$#zR;6>fRwU*Y<fJMTmz1WY=9MTU=clCVDTHKX7AvG>=A<fQ7Aqu{mgMIq
zmSiR;=Hyf=q^IVk7A2OXrYNKp<>xAtWTb)>7As`tfjOCZ#U(|h$tC$kx+$4OsUSur
zS281#e?V*|1_lOake7HE7#K<zQW%>Vn;27=f*CZKs}^x7C@3hnXO^YrDI_Z7WEPhw
zsOMIKXmy36)RNMoykeMma(-TMW^qYoUb;el8rb^c#N1Sc)ST4Z)Vva~n~GA)Qj3aH
z74nNxQj7EyT=mlRz~)26<3Z+XL>uZD=@`dqDimkrm*%8Etx<?J)-lpCj8)J`gxRPG
z(fmu?6BKG7OBB*d^O8$4^Yavv@>44PRx;ia_RBAUOQ)u|78T_eX);E!LHw|ip@@Zn
zf#FxYvsFxJacWU<Oi5`*YK%*Maw*8T;+WFB%#!q?#FW(df}+f_#FEsQR7e~Z!x-^t
zIf*4P&=@O@NiH@tFa!%_<maZA=NDxg>J?Pp;z9Ny$jV|+pfj))u`w_(B!k(|NCB}y
z7*~WOK_jE2JYONNG&d==s8}H(F+m|QFGV3CDM6tGoLXSP01d+8%-n*UN?1siWTa*m
zDHNCHT7d)KP9ZTRMI%usNmIdAAyGR?p$L>H{E9%X&}6#Bn0SjZ2^>rif|Y@R;TCgZ
zN(v~oK)k_H#0e7Qh>y=r%*>0AuM&^UFD+6iN-ZwUDFG!0BL!^*BL!Q9mmo8%#Dc)d
z0F+P?6^e5cb8^55>m@S-1H(&@@h?G{%ukc`7JGbrN`7*DJUE!(mgFVorpCwLVl61j
p%qxL73KXOe7D)ds4x8Nkl+v73JCIL`K^dBbnS+Caje|*q5diVO60iUO

literal 0
HcmV?d00001

diff --git a/examples/example_flat/students/cs101flat/__pycache__/report1flat.cpython-38.pyc b/examples/example_flat/students/cs101flat/__pycache__/report1flat.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2b843499aeb6a5314ec477e4a8ff9439e6927c59
GIT binary patch
literal 1204
zcmWIL<>g{vU|`^O*G>Gy#K7<v#6iX^3=9ko3=9m#1q=)fDGVu$ISjdsQH+crHd78$
zE^`z!n9ZESlFJ&!n#&f&2IjNmut%}GGo-Mlu(dFxu%)tRaWpeWai%b&u;j2rvA8p&
zu%~deFr;v#GBz_uaiwynaAq?V<)kvFay2tFgUn|MX3*q%337`j<1MzJ)Pnq?5>3Wi
z;;ChcIi-musqsZ%q4?sG(v;M^5>2LCJVmKxsYS)9@j02rCAXLpQ&RkrLHdy~6U;v{
z3=9mZ3{i|J3{gxej44bl3{lJ}%qc7_3{fm8ticSLY`0j$Q&Y1IlNpipgV?ML3=Gbo
zAkko8V5nhOz)-@N!kEI?%#^~kkckl{!kog=%#^|k5=mhI8Rz#BWcN!@fM(A5|Ns9>
zkU5zP|NsB5$#jc5vA8(3sKm9fG%=?LB(ak57E5tzPTER_B3=dthF{6fRxzQ)sYS&x
zC8ZguF)sPZrManjCB-qNd6^~YMTse?@dZVhWr-!JF{u@axdl0?#V|&ET25j~OlDqj
zNl|HXNq$jGa<QR-Ay^O+gkZK_LFFxulGNgo_{5YHc98c#E@fa8Vyxl=hl3tW5+gv^
zU;(0l93V_7%<0U{j48}1Oeu`%%<zC<@p}mh#UhX$FPRw_7&MuRKxwcDWM2_C0|Ugz
zU~d=kF)%RP;sM(Xja-m|Vo*pjFjfg6ISeZ8r^$MYBR)PaF*h|n{uWn!d~SY9X%2|Z
z6CV!>U5HE(Kgb>-5CIBah-F|F$i^a&k3hH><R%VA4i>No?!*N0I3h7cF{iSmFr_i2
zGe)tdvZXUdv8ONxGib8h;)bMRL${p7k}7`ZU<E@1Lj{PKg5gV0Aoyu=6bXY|B?2Nu
zLB3}#$t=l91v?;$v#>O^xFj<_ulN>cMt*K;d45s0VH8h6VsdtTW-cg)6eD>B;U6&u
z1_l98oPs>X!N|hM#aILq0|ixXVrE`^ye3bSC_E_{=^>a!ps<dTMF=3|;xkfn3Q~)T
zjfz0gSR@H@GAO{n2{?)aqy-dnQ5+$u#U;*(#Sl+`Erxg!>_7wo3i?|dHjo&z10|AT
WkfV7Rc^Cy4IhcevIT!_4IhX;a(-RH=

literal 0
HcmV?d00001

diff --git a/examples/example_flat/students/cs101flat/__pycache__/report1flat_grade.cpython-38.pyc b/examples/example_flat/students/cs101flat/__pycache__/report1flat_grade.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..01435181f7f83079961ed2105a4d343c2511a9d0
GIT binary patch
literal 57893
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
A*Z=?k

literal 0
HcmV?d00001

diff --git a/examples/example_flat/students/cs101flat/homework1.py b/examples/example_flat/students/cs101flat/homework1.py
new file mode 100644
index 0000000..3543f1b
--- /dev/null
+++ b/examples/example_flat/students/cs101flat/homework1.py
@@ -0,0 +1,21 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+def reverse_list(mylist): 
+    """
+    Given a list 'mylist' returns a list consisting of the same elements in reverse order. E.g.
+    reverse_list([1,2,3]) should return [3,2,1] (as a list).
+    """
+    # TODO: 1 lines missing.
+    raise NotImplementedError("Implement function body")
+
+def add(a,b): 
+    """ Given two numbers `a` and `b` this function should simply return their sum:
+    > add(a,b) = a+b """
+    # TODO: 1 lines missing.
+    raise NotImplementedError("Implement function body")
+
+if __name__ == "__main__":
+    # Problem 1: Write a function which add two numbers
+    print(f"Your result of 2 + 2 = {add(2,2)}")
+    print(f"Reversing a small list", reverse_list([2,3,5,7]))
diff --git a/examples/example_flat/students/cs101flat/report1flat.py b/examples/example_flat/students/cs101flat/report1flat.py
new file mode 100644
index 0000000..4a268f7
--- /dev/null
+++ b/examples/example_flat/students/cs101flat/report1flat.py
@@ -0,0 +1,27 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+from src.unitgrade2.unitgrade2 import Report
+from src.unitgrade2 import evaluate_report_student
+from homework1 import reverse_list, add
+import unittest
+
+class Week1(unittest.TestCase):
+    def test_add(self):
+        self.assertEqual(add(2,2), 4)
+        self.assertEqual(add(-100, 5), -95)
+
+    def test_reverse(self):
+        self.assertEqual(reverse_list([1,2,3]), [3,2,1])
+
+
+import homework1
+class Report1Flat(Report):
+    title = "CS 101 Report 1"
+    questions = [(Week1, 10)]  # Include a single question for 10 credits.
+    pack_imports = [homework1]
+
+if __name__ == "__main__":
+    # Uncomment to simply run everything as a unittest:
+    # unittest.main(verbosity=2)
+    evaluate_report_student(Report1Flat())
diff --git a/examples/example_flat/students/cs101flat/report1flat_grade.py b/examples/example_flat/students/cs101flat/report1flat_grade.py
new file mode 100644
index 0000000..65db51b
--- /dev/null
+++ b/examples/example_flat/students/cs101flat/report1flat_grade.py
@@ -0,0 +1,351 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+# from unitgrade2.unitgrade2 import MySuite
+
+import inspect
+import os
+import argparse
+import sys
+import time
+import threading # don't import Thread bc. of minify issue.
+import tqdm # don't do from tqdm import tqdm because of minify-issue
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    print(b + " v" + __version__)
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    nL = 80
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        # q = q()
+        # q_hidden = False
+        # q_hidden = issubclass(q.__class__, Hidden)
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        # unittest.Te
+        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        # possible = int(ws @ possible)
+        # obtained = int(ws @ obtained)
+        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f"*** Question q{n+1}"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    print(" ")
+    print("="*n)
+    print("Final evaluation")
+    print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f"*** {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.join(output_dir, token)
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single file: ")
+        print(">", token)
+        print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport os\nfrom io import StringIO\nfrom unittest.runner import _WritelnDecorator\nimport inspect\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n# class MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n#     raise Exception("no suite")\n#     pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="")\n            else:\n                print( dot_parts, end="")\n\n            if tsecs >= 0.1:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        # item_title = item_title.split("\\n")[0]\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n# def wrapper(foo):\n#     def magic(self):\n#         # s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n#         foo(self)\n#     magic.__doc__ = foo.__doc__\n#     return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    def capture(self):\n        return Capturing2(stdout=self._stdout)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        self._stdout = sys.stdout\n        import io\n        sys.stdout = io.StringIO()\n        super().setUp()\n        # print("Setting up...")\n\n    def _callTearDown(self):\n        sys.stdout = self._stdout\n        super().tearDown()\n        # print("asdfsfd")\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n# from unitgrade2.unitgrade2 import MySuite\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nfrom homework1 import reverse_list, add\nimport unittest\n\nclass Week1(unittest.TestCase):\n    def test_add(self):\n        self.assertEqual(add(2,2), 4)\n        self.assertEqual(add(-100, 5), -95)\n\n    def test_reverse(self):\n        self.assertEqual(reverse_list([1,2,3]), [3,2,1])\n\n\nimport homework1\nclass Report1Flat(Report):\n    title = "CS 101 Report 1"\n    questions = [(Week1, 10)]  # Include a single question for 10 credits.\n    pack_imports = [homework1]'
+report1_payload = '8004953f000000000000007d948c055765656b31947d948c2c6e6f20636163686520736565205f73657475705f616e737765727320696e20756e69746772616465322e7079948873732e'
+name="Report1Flat"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
diff --git a/examples/example_framework/instructor/cs102/.coverage b/examples/example_framework/instructor/cs102/.coverage
new file mode 100644
index 0000000000000000000000000000000000000000..a93b4d7e94a84f8ad080beeafaa98b3784e23e91
GIT binary patch
literal 53248
zcmWFz^vNtqRY=P(%1ta$FlG>7U}R))P*7lCVBlh4VBlpy0Colj1{MUDff0#~i^;{H
z=X{u#Ka7EgZ5jiA9B%}_F3(b4eePR4Wt@|_m$PSa=CDn}rFm3*Gz3ONU^E0qLtvzZ
zKw}^eySStzV^eKOVp2|ONl{{QY7vCwbq;cM3~^Nmadh%=Re*>oXmBYgC@ARaDmW?>
z<(DfIq!uZpW#*(RWag!0CMT9;=A|o?WTe7Wmlmg{fNDI2l8nR>utGhsevp><%oK&p
zypq)P)FOp~qRiaHqDqDA)Jh$&0;p{zsTCy<fwcUh)XelekO~D2sCG?-qSUn1qSU<P
z)MBvV3L2Rynp~RA^<3=Y!orO0sbD`P79}SZC3B<rCb1|P;T6v`g`(8t{Gt?)>ywHS
z^O7@Ci**zd;XX{x&jYyx;@hJ9T>X-Kg`CVhus8FHGfOh_^Au7mQj<$dQd6*cPzMxf
zFs!Q!3KF<)O7ayFKpskf=!DvZ6gmjaSad>_Lp7%r<>%(*!-5r|5oEQlF2v1wrMXF|
zMG9G^xdoueDay}<SX`2iOD8zK!Tv?nTapjaNqpR3iA$&l;xkiFq7y0%j!}rN(!9*V
z(o_Xl<m)IvmBeSJ=qNxuuA>0*geI4!DmR<Br7$ByW?o8aMR8$HW=U#%VrfY}m>-{5
zlpJrESd`4uBFMomE-%m6UI<PoATP!zWtJ4f8JsAI1}=;v>44;MryEc%K}{r}T$Gce
zke>$5G9cXwkN_?QB@jfO(TDm}A+ZRQ(G>FYQo#x{ONyZpkeQQ;HNil#Dsuc#Gqr&n
zn^{t<kd%|3gqqgCDW*6z73?vXvb55?WKdQqR>;g#NX{=yElNyJ)q~1{b3L*{VeyQT
zDnR)JDM_HHhXxWw2}zSn(~y%*+*KY|(g8&hIElm?!kJu+l5Fha($b7goZw^xbqJJV
zM@d3ZK|}&V6r(Vy+|<P4(jr(vg0GN-=>U~YsCfh`qsgVI%g!e5D2>ZIP<8Q!PzFaM
zI}5wGs3>D2Bu9Y48-!U=JOL8H<^!-e@y;(uEXh#7bUR2`lS@;bl}+4Q6qmz6R>d2F
zNVeu6Ca{y+*}<Won_7|x!pta628ke??44SvTb7tpnyOHcm|0W|DmI`sfC5NiN@7W(
zLSj;WX$d&}g1F%1nVnjR<X(sYnC{O`t<(f7*VR?<POU7qf^ihoGZKqIg-@}%LQ;Ny
zPHJKvs9Xl;70+UYl8nq^1(01(ryy5G_6ReID?w(Ym#KrD0x<xR%|kL$;n_+dIX^cy
zF)syD<b!KpNEMfw0{0W7?9kO!P*5*REh^5;&qFg4RLz47h01~oDtNXnsDzYHxrr%|
zTn>s0BooUsQZbB!IMXGuB()?nH&p?o1nd})R)zA!Vuj?Q)I@L<s;SP5FZMx^6mJM3
zLA_)SP@An$o{?Q#Tbr@56r2iR?u;)^&PdHoMB_4{qzyDlL^AQuO9eFnkdp_fZG#jX
zATGoPP?-ja!6Zm1z*Iq-I9!^b4n8CQZwCI~Aoq^q(GVC7fzc2c4S~@R7!85Z5Eu=C
z(GVC7fzc2c4S~@R7!84876QzSOpNTH{yz(U7z2Mle*=FCf7med<EVE=Ltr!nMnhmU
z1V%$(Gz3ONU^E0qLtr!nMnhmU1V%%Eh9SVi!Ys=VTUTKq#mp>f3|d!UWME{dYhbBs
zV5DGZXk}nvWoXLF#4Ifgos~D$GtFmYk!=iyt)_@pcec_GElw>e)-Nf|NY!`APcF?(
z%_}L^FU`v=NiRxFNsTWk$}CGPN!3rSNX#wBNiBvk;?s%}b5qOni?a1I^NLG~N|Q_S
zi}aI=4GoO+Q&J0Z@+<WUD%E2_i~L#mFEQ|6;{U?`g8x1Z17+0c(GVC7fzc2c4S~@R
z7!85Z5Eu=C(GVC7fzc2c4S~@R7!3icg#Zt;EF)~_frW!vlo2%Yz|74o%?KT4VB%($
z<%A6}fad?1`93l5AK;JT`$RQIj2bi=0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8Umvs
zFd6~_90F;~EDVi-&Q>wtiS-!J#Ci;TVm$_9Vm$^nu?}M(Ce~vR6YDYHiS?L_e8`l$
zp<Y2{3KI)Mqc3gjDM~HKFDfz8E2y+%WMODzBxno5Uq(nwy@E>6{690_X9oU*e4qKF
z2RLd*tsf16(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4FT$fKsrlfAmJV}Y+*gD
z+g}W05ZnJ}PGxEIrI9^|{y&o)OCuvE`Tc*;{Qv0rf7DA{qb7}pz-S1JhQMeDjE2By
z2#kinXb6mkz-S1JhQMeDjE2A<3jt<EW(Ho+{68cA9|rzEgUofK&KV7X(GVC7fzc2c
z4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@Rph^fZGxKtS=Kq=bCo}Lb=bz0#nJUJP8ZsIJ
zqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsKsW^0m{}M(`IsHJm{=G&#h4fv
z7!K5gGqQ4WHX0DtjH=>*FofU052hO!7%UddkbL}!1<Yk&U~mA<|1<NyW#IqK|Aqf8
zOn8(Y4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVE2A;8AM$jQje45pZv
zSXekY!SnwN0z=kEqYfVpfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5FjE1
zK=c2j{eL0?YE;Q+2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-R~z;Sd1r{~zuD
t58((Lb^2%sjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb2Dy0szneI(`5E

literal 0
HcmV?d00001

diff --git a/examples/example_framework/instructor/cs102/Report2_handin_10_of_18.token b/examples/example_framework/instructor/cs102/Report2_handin_10_of_18.token
deleted file mode 100644
index 3dc602acc93517ba2a3211a3f926b2dfe0cf8c90..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 80985
zcmZo*nYxDo0&1sd^stuXmn7y)@#gXtYMau-o|0OUn3+>NrFM#jHv>qXv3!a*R}V))
zesOVTQcfzElb=+Qn3<QF0^+b{mZau_)c3HKWR~QlPU(>g$w*a5%PcA`Q79};EiTE-
z&r?XtFH$H^P0dy?)SFW3%~(4{BZJMGBZJ+WBZI@6A%nAaN(OfiUvO%2eqM?~K~a8E
zPHOIy($XIG;{4L0<W!LP5a+O0Wfr7m=A=$>x@g775a7+sA_Dfy(-^7XznAU_h%qrR
zfG|G;14DALp@ETpN@_t)ex+VPWm-{wt^!z0uPC)3zo^7WAu|_5D+EEfyj)-<rFoep
z=|zbtsqqCxnPrJ3sYZGknJFo$dGX0bsfi`2@gVz)VS0;GOG*pkA?iUA@es2Knw6ed
zl95^zUs{lppO^wO3`H=$BtJemF}I+!I4`vXYF=?(W<fz}ksgSSPsuETX@v24xiZrf
z;^XrYb5rBv6>M!4l;Y!a6EpMT<CUy<xp=u06ciM2TcQCC2n|h5h*BJ$gQ?R|$j!{l
zOslkYOUx-w)ltY#N-Hf+PAo}<38Yq}CYQpvFf;Qq3qVfSfJ7~bX{)5Crw@)9B^`y7
z)Z!Ajpq`$7aY<=PYF<e(TtRY9YGPhINLglHA}Do%RfiOnrs^o9RwU<?rli_NtH;L|
zR3;}TXQal*tLrGJYw4BbXQ$?YnD7Ll9;?aAg-AkD;ZnhuKW*Lb$Hc$@!b0#Ql#!pC
zTAp8&ZKzjJnUb2OP?TDhT2!1GpOaZ!qLEt(qBN}(loit;p{Asy1Yx*mmZjz?Br1Ru
zD5ygesw)(wmXsFd6~n}n^Ye-`i%T-|(iQU46iPBu6^avcQx#HkQgcDxR>;hQ*{6_S
zl#*Jcr{JoWt_QII#Uas#Iz~Fiv6>3S8Tq9-DNuV9qK$QobPQt^G!kJ}YC?6x-3f6K
z*qItoBU51h(gY<Nkf#$<QZy2ElF&S=0P$l<dA>qkX>L+#QL#coVuC_qUW!6OQi4KB
zMrN@>T4`P~D4t*rE6&U<$f<<6uOuTivq+)1G}j8^Cp!h0O$xROiP}jD=*~>kP6D|J
zUqS~Zb7h49NI9ZlXr&Ndlv$Fhkce<fc}8Y(2FNA_B&S0hP*9YaSE7-o6q#RIq)?Pv
zT$)n?iWwsXZ3QC*TZL+n^Ne(iG;5WhDH^6B2%IcH5t*n^oST@F0}fFo9a#K9(o3|F
zj<JrZj(IF7lOa-HTZUZl@t*ui=Ijg%AS?h+eUJjh2v&l@izg#J1QS*cKr%42us}#7
zRK{nd<`kqB6~oKE)Uw2!Qc$S|u_hjx-S8Lz*BTm<T3q6s2+H~3oTj6Yk(rXp%LOe}
zixTrv@^e8^m7J4UT&xhDnwo8>0oSAnjc+9-B?bI71|$VQA_tTbOF$(AC>DxSbJAeO
zfTA2^luLecaY+#<5<qnhIQ`|OmSp6oKuiHC17UDU4=!@_;JF(Xh>0mF5X(RcL3ZdR
z78j=$mADp`CgwP6fNTcEKQ#7nE7CPIFwjvj1;sPOJh<bbnM?y@IJyTQsR)!<!Nms1
zPYTKkjwvY$i3;EvR-q&xTugw10h*IRZouawsD0oB2yqHX2gr6*uOX|`fR!iU5`dQr
z5{ZG(8r=wcM55N<h#+?WClH9$pis!IjEC5jm;(+39fh1?<bY5HCkb_kHg$!R)a3l4
z#FG3Xh19&_(xTL2Z~(x|mCRy=y!;Y{qS8Et{5-If7Bm?bYbhk>=N6Qfq!vLe2l-oB
z!85P8BsDPwtTZ`4B~>A_7+H5oDyZTpDu(L?muH}&8Co1<7Aq8h(nJc#zVghH43J64
z7UY8}cZGtYR9&d`pyC)*k`ycG>MCUFrRt#-jpdm+IbbIgrKTqqrR1a*7lR6&jQnzt
z(F#!SC}boS6r|=AgOWf-Vp%G(m7qcuTxFz!>_Svf6eSU8%>aojXoZ(k3{DZCkOV~~
zC>cT{Gc~@XC^I>`5*($-(V0`MV5<;qq+_CE5sPp$IQ>DAw5>v#5+vb+axQZ5sgRtX
z2WoAC#H(|PZEK-*E6DnsVo-q$HU>FCDU_5J<fLlk6l*GIDu7Z_X0ZY|d=qoZ6Dx~B
z?aP$X<Wz9L7G<Vqlt4>)q>#!fHde4zz-2NlXDDbYfU;&zalQhmc~EQ(HWHlFK}Hs&
zCYKZ|Wabr=mMA0^rI&*1b0kZ^#)Fa(yl4T7VD*ZTrh+D#XOc@w6LWGZ6+jUHwiud7
zK*=^GRS#6~!pmZCNe9crkV?V`+KPk46D%T>oP!k%4Gf`;Vg(~;c*C0V;F#0^m*qMN
zh6b8C3L5Y-K}W$tQy~@<CZ2iVc9=q<LUCqZdQK{8Pr%SXA-O0uC9|X$8X5(O$=UIc
zY6EOO*txMF9}ueLaa3PWzZq$O3SUGe%bYG3{QUm<x+Gmj1`rlQuVf(&dA)*4c*y0I
z<`z^cBo-^=6+r96lEkFaoWzn;Sakv8L#0y^OHxZRbK%l3KHS8D%CyY%98i-U;$sC+
zJq?OPuzw*vlFYnfQ0jr}$uEX86N}Od5{rrv^=xq^LK0*#TxCf{QEFleDB~zAq~zzR
zm%v;c0+vunO4b9FF_1RALS}JsDJa!I9aU18lB)pImy)jlu3o@`$O@8DlM_peQxV4K
zf{g+B1nkHnP#X^FU_D1@9tZ$Azepn`wK%ybvjEgGv{iS7HbWFDA+0V@zf4bEM<KN!
zGbcaYR!K?8wIVUMAScyIftM>JA6!&|T3DcP1LZM=L<L9#1|-kRWv5V3S(1^Tr;u1&
zoSB{n%6W$IDFxt&h3n7H%c(>pOe2N-A|#%kA;=TB%~8-TR4~G45m*7l6u<luP-&A{
ztN`(Gu|i6IDx}T=cN|eXtq_v0fFY`*P+FV{?!m!b1o5sRQi|o}a?8vE6$v_^>JVgO
zVu?a#8nWr2imo8B2;87eRLIRwDa}b$&;Vt>#Pn269i(~=6ai4@Dioy_mS%!#U6|IA
zjKmTJs4g9F*`u4QkPnVZa91B1__>Ld3Q4ITr>B+X=<#y7<rgVr<`tJD<|U`<fLsQt
zQo&Y%`pzKNW#%ck<R?SQO8w;gQcyn&YLh<1%f|7bIyEP?Bvr4V65`|pRD}s3gA!p$
z0ID18&OC+WjKsY3RE3nxqSWM){Gv)wRjQ7#5z=)jD$PR;Y~5T1R4brE2;f9goSLeT
zQBqP+Y^ATClAm0x2l2jMeo?x<v7V)VDX0w8PtHxr$;?aD%P7gs;pI|NQqlnhRc>NQ
zNor9%xN&6*%i4NDiRB@w6(t_2IR$R{MG!Tbyj+khrI(nJ5)Z3SG}Ltq)pZo|5{uG{
zZPo47breb}3sP;1ONu}}>9oYsoDy5V{Jc~h1yIA^R^1<z=3#{<qzwWq*%dTW_0sjM
z!0A>~9jA4=#TohKsTH8&DK$l1M?oPG+_|$=DlW+{0<{22Q<ZcSpw<P$8Za;o`YEZ!
znML3x3aB|mz#33QmzI!VO=4bgd1?_P#e*AmP!o#rSX7#qTUwGzluw||zx*@>NS{wn
zPfrunNX$*lO97WcAUp9`1!^=V=Hw8v%dxa1KR2-?GZ~bb!7WV%cv+{X5L%p?R+^(w
zo{^fTkdm5Inx3ASm#zo0m6r?DAcMs&bR-Jaqtk%o9vyfY2Td1+paDE68xj;y4%D$w
zUS@h8D0*`<i$SRwJO&0E<pCv#_>%mb_|&2zh#0I*0ZNq$whGX63#LFRw^#$(cgjqI
zy9ShHK?xOH1cCJF6@r97?Rt<fw6h3m^}*AtEvQvhtXGI=QD&woDCsGIhD>0Jkn|zz
z)lmR@8`LTVb@t0NL3vT33|XgMaY0UIiH4G%k|t7{H8lrZ4ui~sVVG44whAD#U|e`3
zIWtWmBe6KKq@)NQ1xnClnGz34u;AcS(ggb*<m3Eey@JG&486=^P_YQrriZ4f7_1AS
z2}=wi`MxMIvp7}3wIVqcTuf^y*(tad73CLMDS$fPC_NR3n-oA+E9oe}+>)474002G
z$LJ_1!K=2^ip=5?Jq72C)Z}bPj)a!PkUAhI2RwKO8bpCaU}l;EB>jQn9WBnG63`fj
z@Zh?j2^EVrm<&`OlnbiZL6HZ^&BZzjC5cHnsqra^C5Z~Q3TW8}>R+U61B+lC(0EpP
zd_hrudQoa|aePu@ku50lAg+U^Fk5gs(@`i(ElSESh7XKFU1AHRp+><9Nl-;ltOv?g
zFcGK%SPDQWfQjfpY_)|@I*_mdd6F;&*#pnM$Q*DAhM1(RP*PNB1!~!Y>hPk}^vvRt
zRPZQEaY-V)8Ltes4B9>fwQ9lb7}zj6%p{N^sG7{8oMgS6)Z`LSpB{^RMNWBUUV1UI
z47eSdUyzztP+5@!YtV-07iA~q=Vv1;gj!LMn3n<?`7Bl_fR5@wTnRQOIX?$vduDzf
zd^|rT6<leiWG0s&o0gKIV5@*6r;(GGo0O7hr4S7oL<V^YVr(iXPk|dKpn3~bzCa5P
zh%{(SD%(&;L8DMdAzl+y+@$7}=B5@UmZU-xnjS29!N)@&Izd)|bsOm@fJ$ssy@h%p
zF)Ug@+EP-Y)nTT_XXd4(R;b77fd>*&G_nn$MKQt_m==(U7|M-sDu>yCFuPC>G!KDO
z1IT=YVh|6%`jY${gmME=^AVKWU_~oPzm9@BNRg%jsFVhWl3q!E4ps-C#uF?waG8p#
zS{>N}R4JHU$VsOVoJACDp&b;xa?reuwt|wrl7co&3=~ib+6qc~6*<Kf&>pukvLTsi
z@PZgxDL{;c)wGD{ONj^d`ardAiXMm+pIVWenxg?#u2+&D4@%px8W^Gv6kgD}0wMrT
z12BV7)FV3zoE||5u?W<r)-W_MFu-(Ac50=9t%7<{X<od#c5z9OMm8*vK$d`UW|{&>
zRc4+7#PJwT0jWw!iOx=~j8(7&kE&}xR7Qi%HBgV$1N9$Mi^2VUkZOcCu=)+81Ysa*
z93uM=qz;6Wic%9{r3<n=XxIl-@F>_Sz{()hkOe6y&PYuyQLqJ%5rGuzfm+P4!8?dU
zK_Qu(pQ8f{2SllmlA@QLS_$$PMySBe)=N&!$<ZjvFSj++QAp0uDb3BZP0r8JHq?X!
zi-Il4Tx55H`~<SID8C$AaRLn*%*X`k!(wewez~?0E~`N~6KXe<0-1scjpD?zR9N!F
zsvtQhzc>{htS}{@WL;3A;0x}<`sJ6n<(KBAfSWX+(Hc-^8DtG4ctL|oM#d&Etsn_d
z%?oP?U}=Uz0~@RoJRhVKP?TSmS)7@lmzV=<BV^|1ftoKMMIa0t2+}~bC!k3kDw~t4
zV2jk)fH(&v2kA|q>IaQnf#g6KBCn(XvJIju4K%U>9VOCBPc6v@4RNOxCFZ6UYruq)
zON)w9^Gd*?8k(BXhOv5}HXW#}ff$kw;wsp}OO~X>;#82VMp}_(w3V)LET~9=4=^Y}
zG$EBl;1*u72G|%_T0wFyc-R9vo&)Oa6)S+otU+TF3YDoP3Q4J{c?z(mL~4qjLQEcL
zU<cZ^fV3FlO|*iX)WqUc@URbP&;aCcD^O^FtOH?a2-(@$Dd{Lc90YMLlB6eOZU8*J
znwyxHms$i$DV6!93Pp(^DbQ49W=^Ue$Xr;`fDeF!JpdAgbh1i8ZCQ;%n6H%;G8AkT
zsxk{SqBSz3)yvgmbrdqA)nTh9pj_Cx3H4Y=e<KrAb{0bNXt9PStR<15U`vT95PyT*
zlUJaZSe#f?lvt^e0ZoZe|71j4=@`W7D1c}~C~Xw01M(kuC_*7L54s2fG!79|3JNR@
zP>T*U-lhi<1I_(G#9?6o>U+k=XXa&=#K(hY0CW_zKpi<91ud=Yau5rq5)>!Jr3I-)
z8k%}=9q4KiZV65;EKSWT$xO@vS?ZIYn37tA?3m&bh#1UxkVDc_OF)W2vy*<{OaU5N
z*8z`}gT$OcGm<d%Am@Pm1zt7*Dk@-Z!!QJ-3ZWem&>-E)V1ttri&NtvlZ_x#K+|^`
zC_41w!F6wZJgi7Zm;jj}fwmPvMuJLbXHfb;H6gbsUjy0QAf=gU;KAD@aLj2q>%a$;
z^<Y7Ot^=eCY$Mo>&KT}e&{oKSwz@$|K~6yT9GWyF?DUHBi%K-IQ!8!JwdjG{ozO%G
zG838*LFyoSLGcZWIfDH!P}dOFyMnMmWqD#w4rJ^Bqpt<&ronnrFh$^w4y^YC6@+x2
zpd5%c(5P8_T25lREo6a7ab`|xUI|nQBKkl+f?=@9D7`|kRy>MP#!hhb-I6lX<1<o0
zNgwPIP>e!M%*!tabxokN4tja{<*=$UGfg20t_!I`ODs;#%#2Thlz_Ghu=xl*$h1U!
z8hFG}LkUy_xP#U~fk!IyN^F%<^7C^+g(J+TNeZ?KN-=p#dRh6Ic^V4QIp9&098ju7
zwgWPf0vh}**3bmC+jCO$G;;Jn)AR)znwkoB3I?$X(4>LXS_9bvwgKdjbg)ApK8BR_
zNubI}p$ycBj*kaTcV_12#m7U9Nhyg38K0M~V5^XqUk<V>4Kz2Rp`@CkubQi`8mXY_
zVWsM8r5X(L5X4la;F83mlGGF{1(3mTW1z-@vNdEFO%FU>25}Fz0UoG>pkq2vJy1c=
zKn1Al0!q9{(Ne6SZL6RJ8Yuv^GQjqu>Vwz@btiPf1T?z?a%r)Sf|3SkCPr5mlw`pX
z0U3}l)>Hz8IXG2<q`;{e(nC^$`CS=0o|&cuE=f}qAVWaK;8`Cl1@ICU&?r6jAt)Vi
zB7g=FqV0p!`OWiDuvM@yfOr5DHJ~X7TLn;z=z$1WiY-pgF9NlZs%s%iL2KhuK`kAu
zRRDN=0+dQXWn~_uQ(aDEry8V9S)owDR-q7PIaDYfve-|-Rsp=K4dM_CInXp0w7@OY
zi-(Ng$H(g^cz{<5Lc;>23$1Mli+9LSpSGcbqAh#~6e%r$bb=<nGxJK3Ci#m?L93W-
z6(GT)2ckeFe6d?melCass+u$kkt{C+r&5q7;lm2?U?E68g!P>ZbrcW-1Ymhs7Z>C=
z(5e?ut1vzu5f+6IV?aYYd7!S15^N4wK{eA#LA6*(RU=Q^P)7mc03;VdQZI^j9fj1q
z6kB*&1bMws57u&0uvLI28;Cfp356ye4_cU2tDvml4qjHN07*!h&{iF|VuVgLgN#u|
zt|1YgQdTI82QB7^&o3<jO;UlTPQmRNP)Y{%V&H)Y&R!r9P*DdRdjVxKQ0#();R^LK
z5{u(O!}zHwV3XpJYWPr4Gb#wYzDy4#KtS<@628g`9*N1>l?az2YXxU)<mv{ra3Lcf
zbzo8fY6MasAe#YMx(6yNLA5X_h(H)L<7cY?RtHL5kk+0CWF#}Qq|(+1w6YD<E(V9M
zEm$GMKbm?)rFk0Q<cbvc%AiFN3M80_+290+7IxFC6l@jXeLRr!mBF!;g{^-JjWSRr
z3Q`Hekd7iKw}K)Nxrhd5RoLhjhC~)L4})|eWnhSLAcHZpF?3)DBneRlvK2?l%Y;l5
zgR2S!Wrbw$U^=M01BrlV@F7dwN{c}qDg{VV1I=j`r<OpLi^0}dAgqJ1GSk34F_61)
zCs(XKDh5@Npq^}IZYoOg4K^5&N+F&D2_`2i*eZZrj7>5#4bs#?PQzI31({R=TCE-r
zT2-E#Sdy9&52`&t`9%*+NEtLu2A<#415a>()nyhdz?Fd$2dFDqsE}C#>Ky2SMz@Pg
zb2SvA3ysi?1BG~@5jeMFk0^Kp2INSD$3Z->=N*$vGRsl}pmPNpCAQc+q63LBTa?lO
zB?E!X17Yy!H7I+4+eNTpaOcE=l2Y)fyt0Cezn^-DLXfMkf0(O6h=*sef{&-4E4J_l
z6?xzh4Gnd;0qU9>(8e%?(gctFJLi<<Wmm#%E3V8dNvr^62<ZBN6mWXXPlK)s2X{(R
zkxCrYU;#}iU~>-0dmv0O$Z@6-kZuqzG|~h0Mp5f`kOVp|G{PvS6>JqkijeDGj7*Dc
zh_V7|HiB3SN>HA8nV^nqW))~T24Wc$d=?kv%i@egaHJKbLYBm1&#@r;pkrR}Sv=7A
z1#F}XB##=xAQ5OThxU*N1{qX2q?bcbHOK-;g$@~-0`Wl@(-|O95QeI@Rnjsxz?!f@
zijXlxLz+@JXto;^teJ^9nN^@xFT6yqE`&73YrzXq;A+6Liwd9#c?HlysB(qGJO%JT
zFRalEvWAdLQ%P{7Qb<OsLQyJcy9LO7ptUmKHJsoA8tz)~Ld2ZR?9`k}g|x)X9Pnrp
z$SEL9$T><F0f#LIkyM~2C+n4@7UgE<fu^8v`nI^TSg*JwCBL*pFD<9EI0JW{f<zcf
z35KPChc!2WH07o$*ya`J6@dnGH58D02)f{EM@IoR0|gE*Y~F{sKuJMKOCdM0Lc>5O
z&qqO50o3ONSx}M#-q({?0$LoZt)QU<LfQ(Ti3yN&ZmK4@Us(*^iUjRDK_nFHY!wXj
z4B=fT@ZwTX)eWAu0@V%B?pi@&C8%j$3|EQAm9|O>S_*kSSOXq+YZR?2MK>R<I0Ds=
z3d#z>pcX+!DrhxEY97+wEZB-HaE%CB*a+J7kd|7MnwN}OdV|V2l(wm@LNTaUtfZx-
zrBJAvsi&H$iPZkj0(AmFdLUU8*_-H&COXw(uTR02z-xDKy8u?5f~1h$jO+?fDgwt7
z*1`^wl+g7nXe($asOza~L6Vn3o{z4HE+~B!7i(%NXktt5U~AwVOQg;t$ZWj*M@W&N
z4C`G$%)oFgL>0uj#l<*XpsYYRBZIRU(XBfT=p=)V0<6cT30enJl9~&em549M&&(?+
z)&TcW;3IG-JoJ?fU`g1x9NMY|@KPwyKp(U^(@}s_RJITbBVG&Rqq9I0hSloj>Q;~{
zx;z!M;9ExlF*I)lce##&I;?xCZlwVCm^viP)vZ9=TT)W<bQIKK?o+n{7aWjCgb6~|
z^k{-+qd_|&VOE1X*3f|sP<nvGSxIqfGAIMV3q4Rv722xCTI7MWf>HxGpa`~^2^a5#
zQv}FHNYVm%6gek>a)P>^x&o}ERR9;YCeY#*lpV0<1}s@0)N_V}Ge+75Sq~{=0vv;b
z!Gl@QxB+c&ge5z0CRP9!LvD_qKCUj%=_-(JNJxWNnQ01;0Ed+2SnUF-D~1lnX(&Oe
z2CycyngQJxAbpTvDn{&(00}B9louoN2WXolXhTCPXhjKh8VNLPi7*cCCD4+AVm;6h
zd2vu_9zp>um4fENQ}Z;6Qj7J9OOumRi;GiHZH8<v0M~t}iWIaJ;G*D0Q8CDKpfU`k
z4%99It;o>?1u#ee;RJ*ul;QaXl;QJAG|Gz=9N=Ooc@fFIpcQgpg)lLE3UezV?EsJ_
zjdBGo1-K>!eYi~unwsE2Wq7FBDHuQ!g8}kj223l=u}G#VXek)#8K4*m%3xRx1jQ!^
zg9n(R^AM#=Ick{#;=-&{w}LxdM?oEwhl<s$6bj>!3JAzJ8B*a;s0Y&xnxBR4w?+g$
z$^aS6p~&7XHdFxZsR7l>@S(ZF>O5^j<oz???K5dg3e^bPYW1tjk(EFbv>_;`E9og|
zDQM*RK<YX}O$ZIynWC*wYy=y_2ZawrA8NM%F*FQYZxfw{7&wHwPDde43Bx_0nNf)6
z3FIVjv_O*-ELfm1u8<4r+`|MlVU9%#W>7MNsDcTC+K9>u&WXh(pdl5=vTo2KPl#J!
z&Aoic)_Bm88z>V+9%dLuMB<*gfzLaDhU8GEFOX&}Ahx7{#$Q2BN3J-aW9-n7$j!_v
zElCB{GASkc`ex7pRcI3zG<j5_pbP4>gA{4OqziJ2azF(Pc%7R<rj9}}w6X)06iVRf
ziDGc7C<YhFnV^wuMB^Bi79r^%P02YQw0Q$Ev7)Vj@SnB<v;hvXP6O&t9R(!_O9^b3
zj)Ic50$3jEWE}-12n!^yqzUTKLBaw{3R4OJjTkBEC@3j`S06zm4HhYy+DiH;5{Lu>
zN_3#43|)f&8evukkJ_kPDQLj-Bg%D9eGff70n{u2&169Ha}jvMH)!y)G^Ye*xhW`=
zAQ(KL16u$B8)1R*iQQQQUHAdt0F+gnp9kk4Z6QjkGJ*>iWF}|lAT|?$R6$laBvqAz
zHce}Q3;|81=_r7A(1Z4WgEB*UDri$1sGA1g_76Jf0o1fjh0YCw2bR)POTbH?ld6nB
z?W=;+JatVCut_=!O64V>39@2^G^C0+O%K&x@GK8#Vi<aE0c2fgu|{TY0c`vhK5znx
zBWR%Kg0g*X0VG{OhJtfJeKgRz4cJyQsI7?EFHmt=ovRlQo{^4^hwt!CQ?OM434@lM
zz@|Zz6;kp*SsJ=jJ0-ISG)bb72F-KI3MKgk@gUn0(?L^Ouw~RRb@5O~#K&uZOa|$V
zkB7{ZYN+d}YepNyf)+<WY{X$EsMAWMIiRK6@Y&JKG_Y^L!}js<aPNX@d-YuKdMb7B
zpf`8|3>rwFoPgg)Aa9^J7o-JZ9MrEUgKB6qy{KlB<SV^+knf@mkmgp<tp)o8l+!?N
zqDR!AM>mr9ppgkl$DlPspg@DAQ>bWhNl|JdObmMDiC$D@fm<dhuYx=QRhXF%Qw1_5
z9yG8NpP!VKnhdTL^7Wi5OHzwH{WWqc<EudDZX}i@LhT1}lS<Rl!1Jq_2$fK2aOOp`
zSp%U*M?t+@T@y6^Se03Tlth$49)jjzs7WB#f`&PZ^7Bh{KpU@$b-;TIz#C@ri}lJA
zbFwv%!w1PYm|l?QK)Dx07o*98)MTcCjnqrcODP7qTti8(pi&7|K7dpp<1|ouLCU+}
z<qHt!fh<6BH?poWBppSmIUqAMV9|_j0%F?)EWaar5Qha-nFY|013OShp$uI1f!qKu
z;iA={aiR`tdLrTj)Y}FxfrX9CA?ZM}8mtS64@o>oYEd!{ST%|WOg-oX6HtW)Ih_Yo
zHNeX{SS|xa2~vE()_I}F3&E5D3u0J6rfH%_E64~?yiqTKz-xre9OMyTP)xuuObL#-
zBrUNZ#Rv}bK#5ubwCw>;l2b2&<j6GS>J;W)7>$VQGEfRiO9L+whou^{LK&Mc(okX>
z$+-w8rs*i)bPIm_5ltmX$^s=OXh{d#90}V7NxhxLp~axd8Tjs8SnCEfISB4gfOa=S
zm$8Bu!6?ACB7<Bvx*vCRKQ8KiT;05U*svU-jh-%<#h|Tcpc5&;d&m@$5{vL{RZT1{
z$<IklB4jLh*DYuhX-;AisFVhEI}rOrq3vkM$zv#oj6t^`=_urvmK2miPT>MgHNXm7
zP<t2Jf6DWLR0W`Ay`YXScuT(?<_=G2=ZVNYcHl8h_#!pvDoe=f0Ql%JxG9G|Y77&E
ztj+|@+~Qb92`dIsX|TPpNP}<W1Nlu45t$^Jh*)?D-V+Em3L1ORA`{XxMvRa^`L;@0
zd8jJDoBF{M^rhfAO;C3i<a~$*SRWC2(*ab!vO*&0XcEv|6nJVBGP?|!5(UrFgSYa6
z8&1V~df)>?K;}Y}fkq2J%kUu444oH7_6AZbEHe!{m<TQ&GxJh1%Q90+6LX-={$lVF
zPbBpqTOh7ia;j8-Bt+1ZDX7GSoYMw&ln!VQ0BAjAW?CiK1E5O27-iW%$Rtqp5ANDQ
zlP0G9XjX$XL9GYv7QotXK~m#blnOeo1hm{lKQ})mGc7YUMFC++PNhOpCD^5zc?yZ?
zMXBIJcoe|3p-V_;u|jG^Vy;3_X-;Y}EapIlgD}*=piUwzs6cB#p~46&V3MHv2BZ&!
zQNtYB2t1(;IhF+!)Zm~5HJBiwucwDH4-K*a6s*}g3gD1MY)68+4aGhz!JC(vTY%C|
zP_TuaI|!-Hi#2kgsT5=v3`0zhFG>aN4K7QK&&f{)CwVL_Z|GPDsND<l3$*A$Or>d}
zSdYankQ1ZTaoGrN`r?v=<O!IgK{UiLP$wR&5tO7r9N1U^NC^x>vsZLBsQCrbhiMvk
zwhuHIADs=Jl+6Z36i6v(SUMZBY%5OzYEUe;_y$=9N#beXDG_Xg8Xz?=tPC>^G=id~
z1vMJ9a|2{8bVvnSmPe~YrNLf>vSCRRv^xl1d4Sdif$9&W1cInpAaR<WT9RCz0&0Fj
zf&n^r4qAd45894|*ft4YWQ!QD&{j~2&q&Nm$;?xN*$)|)LyXFS^@G+Z7Dqz|@1Uau
zW$^XkO7Ue%+K{N$gRjsA9r6e+&EO)4g?NzJ1tqwh;L$A5Qh3$kc-74K{Iq!0Ox0pY
zL8hdtf$k;P1Q5cJI#9<zQz^_mSkDLCxkLmUC}C%(!YT=HIRow(fVF}8<w?+P08+3+
zM)~woN^=W9(?y^LfsO)bs0tG5_=|T)LPFG3phN=|1D#cqS^_E_Q!-1yX%*T~1_!y0
z0(9FJq>urZ;h@taazN+9f{yY*E)bz6f=XntPoRN;Y8m`IRB-v44?0*YuM%{QO=emq
zq^Kwc7i17`f%L-qX-a;eqtrm>GJy)V;{4oH1!#Q?IusJ*5Xi76Bt6GN7Dbd~f>y<V
zax!SCD=0k}#zPe7C_tkX);0odThUMg9eApw2`!8eYSVM_lM-`4n>Zm3D*%nGL*oQg
zJr`>vfyQa{K%>AJsTHs!1KR=!Nu1EL2{b^?(S#|nEy&RU%|T}-mq7M~Kr8?)wFNm>
zuQ;_N9_mt!0@zk)crOd21e9|?7-9*`&7dv2kdj&<zc?l@CJ(%#FeC<Xh*WV&X<C{>
zMru(i=!~!ARM@Ew7>5QS?alxh1RBZ(ACVRh8RvzJRzZe@z~ion4LqQBoTgPw9w;86
zjsZ=wgHKz4gdRi=`#@}FPAb?uO^70B8i!@7RM6=Z#TqGjFbhDI<QMDZW~XEpfrR0@
zAPb&Tt)P1(lt5>Rf~rukCqNY^lG~wnAu=VXZUVbPM<GVNJSj$9M*%!)mIn0}$W}Bz
zL2@ZPSU}rqa|=Lz&dkrVRm!Q#O;mzflbHr;9f8i3fIH45KQC1gB##=@P~XB`1M{>p
zxS<7hpn|PJa$dX!LJ6p{0sAq&peQvhvjS4=!Q~<015HY3p$b=|335hE9wN>`JJONt
zfQAD0$W>5Q@Pr(P22N$Lv&JANTEXT>Kx_Q-3&2GSQbJQGNlb^F`3IWI)`Pf}V$Xsq
zH|TIbt^ftaCun6W#6}PggmI*YqNEsDQH`n|qz4+Z=!pYVTxg`>NfaQx*w=}o+5s(Z
zLyADn*^+$lrV@ojg`~t31xVfkCk=(f643T9w7dke1B9VwctXxC2F1Dp=v;}!BJc^7
zNsuBIagtGbY99Egixf!9J{h#@7IFetN-F3)FNMq!9R={wndP9vYEtsc^FZEJNL0v6
zEe9oa(8efG;s)6b!w@&5LbC)+6jT6$2Pq+b0q>R3NP{W@k8&YG0~*qxmI@@f#^fm}
zDaGWaXO@6Z2-Z_jQ&RwOlJj$OGfNb7a}|{Q!KdgHE5W1+N{cf<Y=wf%0(eQ7o>`(@
zT%2L0ub-Y-;*g$Ml9QMO+d`$6Qc|jylC57-nvtpxU&*ZpvPM_8v;e%W8{`_WOOzEr
zHG_g4EYU-<B`7b&fZAvIMJ4bZEpP#(gA3te#g)Y|d0?Y5^I>KMmw*-@d-}r_AsvbW
z7b{AIGeL`K!KVr$L<&=K5uD6igjz`8!{stdQj1FR^K**fB9OWTy3PYJ+gxF#0ACMP
z0X}3Cw!~a7CJ!`^kD|1=G*_cSGbS%LEhj%8v|9{vHj4tp6tEyz9#Re!gAZ&^$t;Rb
zs)X#@(s0%RH8nxUh{MW7P#vpas{q;=i#|&RNjJ(0FfEXFENC_WvJDa@4my-A7nUr+
zEqc%zCs;w5Sq!RXU}|C3LKZ54YN5pJ)RfGkVhy+oh_%q93KNCc0ZJxdS3-B6K?_w-
zp$j^Y8N3%8W&<dHKn(%at_ZC@`RVDYMH-N52c{Zi1Z?0QY>bWqWXcGp0Aw6^^8|Da
zF{oXGSWpIWGh9thK4?28!~l@RAPJBSkahsb7#)S&)Z${$QG`%GfRunFU~80fpc5o8
zWtcW#D1ayd*#lX*3^ESc`O4s3A_`zh1<3AgP`@QFH8mwQ1>B^CuKO?so%B|aSdy8P
znUh&k39VE>E(9${1bGM&3Ghu68lc_PFsncgKnqIfj(5lo3)o;6Vy`^J;UM!tPS%4c
zQ?P{|l7%EoXeT|$X&_@DPDsrI9XJTvp`Q%iGLi~9x-Gw`7}A8af}HyaYU`mKT?=mP
zA$c3@ta!+>aL}eR_!@B}x25K!>48=cWag!3<}27Lz)BkpXi*Gu7ii@#NFBt7NHGtR
zM5HDKTLow$g;@+LxH9vROhPNzG4!KqgoO)8S!S97YEYm%1LVMX(4kkL0tV`+)S@DU
zS3#yg#8ZnvY7jnEP*%uI%>|t`nUSB9s*qWN&;)i6s>Pso7)qodR6{c^NE6KM&^WC?
zKXd_>?7*%9xjnU_BsDJuoQV+;0vbJm&Kg3N9zZu~BL!(nY7XQaWJD|~fHt<I6{V&s
zlolv}dr}bZAsh+`2her_P`UtF4^1WrC9p_G^*nm0gOd~_JVCw&xf~qmAn!wRTcBr2
zYA)(&5TI?aF#m%W-9k5?K`aNYWlSpt4P`?rd{79L<bw(>1Be3DMdYB3rg|nu5Ghbg
z7}OvGo$UqdR-qUUKlux~2pB2}YRQ7K9q8;B(C~I@5onSLveq87kOn%k0?k{HHOdOM
z3Wf@x!YNe&DgeD6q7ZrnyB;VIK(2?R0no-5_`w@6HPFKwp(PErvIQ0opdbLPoCMw6
z01j$cIAs=tckZFb3@B1zN}wlYLspym7zIIx?;v3Ya$#x?+?v$l5>V)qYAX2beVB(q
zMuOc4t){_j%<&<F{mRfJoSa_-I`$PBIY=>xT>@bM*aldjg7#BD;{e4)gv()&!$BAx
z8ld&zpxOqM6tRXdSOGMALB54q2#)jO#I)4-^wbi_l5B9^hNXLCTToIhBtsx?D@FJc
zqzS2v(Zke;P>ZY%Y$meHASuBwzbF^%C`fMwlxaXWv_MXd1&w0mfRiVhlR*j57P4Cu
zEkwXFkeDpV&p|jPB{L1QKnrx*O;WLjf(D2IJ@y8cSvB?2auQ2)L9I&Ii8!zcB~6H&
z0#ccmR|Hx;mRF!xTv${BG7i+jQ~+C}rKMn`3GUT`0t<w}Ndvrw8lL$<t2T>rVF3bC
z1R8uO%2lvaD9O)3^A)83lBVRBU!sr-+G`IU+5&fLb5e^yM<pv%m*nTvS}Ww`7v+NH
zqCpOUY|l|BPb^lb&MV5T#ojAQQ*wn|BcluHP-TLa`+)ZK6f0DNOaUE_mswn*0lLcs
z5uP9igM9^wMsU{CfQ2M-4CWT6+Y)v-$Y~J6L5UV(rjOBJNf-(^5(RR400#zU6c^}$
zHUNRb5hX!@;u=Ycl1R6$wN^+;Ez5*Vf<Pi0$!Oa_9PPHXIttZ!7>>nE2(a2>C?yC`
zoP*X)g9;vf1r5VgT?++maN&Zp0D{Ux%OynNqo7H2N&}T^NyQo<%RxmDD4T*XB)x%(
zD3A;!xk2WHAb|~11H!}>G@$$nQV+v0eS@wjDJV*Xl}fOx9Gr-dD-`5v3Z*)O4vNDH
zX;9IGFb}73pi8CTce;R<RzQ|1fm(B!&?_%MC3k9ZNwEUxI3CbJ-Jtn~^wbjY4PS}i
z4J`^qdFh(a#vUk?Vf{xC8{`nEub|Bou%AGOdV!89hjbHBd<Z_+*)PAu6STq}bkjj9
z<QPN^B~beeGTjdvKn2AsBt?Mi0Lej3hFX_`DB6+D2N!-I)oG=9SZV=y(FZaV)D|g#
zZuv{iNkfd}!`5ej&Lx4ReTY}EujGJq1z{>c;RD+C2QwuT=?pHU!{s2J0|jCMbRPz&
z4UG_m`4ieGM@WF24qgHRQxOmMC~`=EO@<r>X=i7r0KOj#GA(BX3R{pg3`6n^%s6-$
zfu!M<!NMV41IEH*nJe_bedy901&zG?l2j`N&<zXVLlwb?DHasvgExVtSSx_W1{F$D
zD@vf#F`77>2)7!R5kO9awua$-Hz*&P9$}dS5q_8h-te=$L1PI)kn1B-K)D1o29}#y
zp-_^ao(jDqDKoDGbiYwr8d8n`xdMbC;i!Zjys&_Uxe&^SIuPyX3WPg}85ReXrum@D
zEsBd1bI{vrASXc;K(?HswdFwaAPjYOOiZ3FwE=oifUE;yh?UTT5=x3HK{He(kb6=<
znO6bQTaHn$2Ipr`SE4pX9kgtv2vS0ThIJ8VBv>iwD8R-pL8c>Pa87}x8&FOG_o<MY
z&&Z0QGdm?kiOH!+iOJcB$Us&FaXeg+9^?o*(8<Lb$Tc0N7A0y2uPwIlg;pXO28bzp
zlq?PF&cQnX(1eJuXNRHI7CgKN>Lej&MUc_Rg(m2d8gK+alY9zV3WS8DQcO%9vPaNO
zLDK{_5MPYK^y9D;tRE%^N)g~2*HVy@1lAG)R2D#sb~FcpA{v}dK}i>07TdzCKvYz=
z(4q;+DiSg|&OD3=MY^Ofh;?a7pi{PB1w43`2IPGlIX4A%gHUc_Npgk)EcQTclG2<K
zJq55?;64jR$qx!$h?Ur~IN`_y=?7u3N|?o<XvbC%V9z@s?H~-3HN=v$z!fEE8y&cr
zf?PLZrY1yUAu%OD9RMBrLvoTKC>KHs&A<Rqr4Jrw1dletoC0znG)Y1;Jmfq)4EKWP
z@IYpRusd`T6c*8tn@BTZGp3*@2OWm&R0+FoKt~}dA9TYYs4@plm6W9Bfof9FVoCU{
z3;2p5=mG`sr8J4f3gxLeIiL+XP%nbVd5aO{Zz5>nMrt0oR)#hlK&!4mBmNqo8;wwX
zrjV4HlV7f>r{I|fnV|)p-<<;5%$Si1X=lJEcNH>=tw4bX@+=5Lj*){I=Lo)`2O3aF
zkyTOw+OedOm<PJh4tyR>4lINaCMPE4mm#NF$hmc(rK(_!Fm4)nTOzn24lzj=(o9n*
zsVG4yxDm+)H3UFwq;x>4bzryJYU(K1z>+#NkJ+IZWd#XlD+S2RaAJ-EB*4KlNFdKA
z7G)Oa=OMx$B~f79&VrswKn-}vNoG*5Ag-V+$%l-Ip?U#S{6j1QB~w&6Z~_IbXadDw
zMG3-_NX0P3J0P#Z;u2&I$RnjCsnFyOH3zw|4$B*$hzGBFK+J|gl|d-*A{dBQkSqo1
zf+QDk%%IwanPxx{53cGUGp`WikkS-Lz9<*vh8B%t&@GBVsk!-OsVK|tks6<{WMr$5
zS^;X4l*B_tG>VZ82aSMZsl_2_rx+2akXV3t4ZI`)>^HO+DM~HYQ9#iYlLsk%{6UvK
zr>1~UtoBU>U$LwKy5kEL(hgu{kcmr(RiKE92X%G}5{pvdQv#qSpALA|x)`Pv$xTR;
z{(4XwT{4qPVAFIEBlA+ru^FcWsiHvFL?D}-4GMnH6sQK+g&=9zxz`YPf~*I1j*~#k
zTR~IWpmGBw2*cUnQ#g|J;^V<LU#F(T$0KyY4ULXbM^*q{l?u8l0-W=p_ex|JgH|(v
zIG{#HW}bouNK-C&uWNifXjK-74;p<11rta_GZtYLG%tWc9klqAa43MX4A^}Nu)`PJ
zi}FhgG;&i*62aoO&@e`hRan@8N7F&eNkj9%%oO+mu}Tmpfle071YHdl58j>xI!6TD
zGls~PfDal4O<RGc=|Vs&9*YY=<$Qjg0%(p1e1IBcKvAP0CowrSBR?l4wa8ild}1W%
zzHZP|VG;NuLD(P#o+&Z(15RP*=0Y3;TUiF0-++pM&%c0o!6AYU1x5J<sYNA~5H2XS
zft7&^7+AP~QU$0X3eI<6Y0!pckjZEz2snSmLsck5BSj?0h+Ie>0-foa4q39AUII#h
z(XgHBAniH|=_Qae`XQ1aG2~<jN=@k{u$9=+O3=wC&^;XS@u0&7U{n1{v9Tbvu+{3B
z#o*}I0GSS&X#;JShaMxGUZSG_X<nc?7?edkK`w;49L={NKS7)a_A%^e4FyjP*nE{O
zNE*2x1x?Q&VLeDVff6jpAP0yU#i^iM39&_n4y0N`juRwf6l@{VaN{uJ6_melM=MAc
zZ>&NTKq@?Fpd;;IhqxHz5fm?iH7Ua#1>%Ah#+IZ)r|&`O4I~J57ubiG{sYNFyazJ}
zqzjaxz`Bq%fKCj_gI;_IZeD?M7JT2MLQ!f?YFT0)B<-Od4hUIwoSceO8G$-T=r+bD
z=H!6mEglxd#TbqNr5aFVf)WlmhCm$j0v0-!0g}>#8KsAwqp_qnR1M%jK&lx*;Sa*7
zs?d#v9tHsN8?35>TuiJ13rle62Pz05OOqjoqe9C-*s^@cL?I;JVLkxWJFr}jyio;|
z<)L{Cb8iijB=od$1!V=_#EQ(^(p&}5vIvFp%#@N0kaIzP!(Qtar52}_Xe5K~GKV+`
zq!bhr8ihKL>%Nk6is2!RB{q;w<c?7Xn--%E3l5N3FkGkymIPJL5R0(8Cl|CNQzJPi
z8QBbI)_@gB>8T}fRWRRyk~a8uL5yUDLo=vqgs6o#ios?;hJV02IpDi`AnK4(6=>%@
zXz?9vG!Hq>q77p8;=$)TfU-Ggm0h#}G!8*wfut3-vJSRS943X7FyZ@(K;|H=+k@@q
z2j>%rzcqCfuowVoFo4n*%r?-REXXts6tlsX=V(Hf)POc@7pE4WI0M`agqaU&h(q@~
zflSf?ZD#=O76U~FByzz)39i=R%`edIm1NjG6bjJE42<b?&{a*DdFi0Qh2D0Hxa<dZ
zpCimCuy8{T1W=^`aRMl?!7`xR%XA>+FSJO+vY-;AQU}yS%to;tDGZ=1GN3Jd*gcq#
zD=m>?2E6qJWSSnjy`a56@G><%B|kndzXZG)C_Xb!FD0=A(f<KCJu?j!MxZe{P#X|e
zy8&gx1mqx3_y!9|priN#ZN(X60VmQrap+}jU@u_xEOO3-=mxnLtRC4Zh!wx!>;qdx
zj2dv7_*@Dy7OQJP5}+iVrevoOo>-KZnU{|LQcxX*YFMIyB_gnUvHPzU6ynfpV<A0Q
z@P$;MqzPG}@8=%^PAZ_Wip)IFDmBpfM^I{FG3Z)G&<qD?A-O_QQGRx6o&sn~An1mX
z;*vz@4WfF`DgopVL<oXfiX}yv$t6ey4MG;A7QN4n+_^)j#2I8DBOs$_AdQe*0?MeM
z^MAo{1e^T=9hGm08qGnad59Z*6(EB*;2Q@Li&Ee#xxsTh8K80ew8XsRN?2PQWG|#x
zg{y>E4w3*Zmj@r{0$NcH8cG6R0R+C(qX<-4fYg96s7@->iHA21;8iD5Xo1v0Edm`a
zhOh)Af#sA?1!V<Ch4lRV6i~mqq7vNw0+$WoQ+z?Gpd=s75aRB$K-Glgvx*YXC@03f
z1dt6onI)CT7X_di0zStJ^^jALuMk*Q0qjFmU7&-eK?f8ofVG3lXOIR^q{o9j3LO@~
zY>a`k2RLDX7qg>Ae`X$}|E!P&I>f&uUjeit5PZWrXnz}Y(O-FDrJf#Avk=lGiU$`9
zpgo(l2$w?QR)L7fMO;i=2-=<$Uz}K$3NaE#s{?dj7eWzof&v8u2p8%>42X_V2PYbE
zZyXYC2p57Bf-tftqEW9J0d0<jnT4tmEklCL0bv4WRmZ63<tspf3pBck8eyP(07_Tj
zT^B}r1(h-CR-onaNTCXC_#j(@oB)u^YEW#$_XmQ8b-?8iWHKAM93VQPU;zO>XaRDz
zG<tBs+yV*;5LO0fKTr!C<TvPj7igIqQph1rum)9&nR&2^vKTbg1Tp|}yfvC+G~{yE
zSgb~Z9003PoFK(Etg2Q34FiELQ7o!dC@xLP%`7QN1^1EQ!4GygtULl8O$lmd)Pm0=
zD=tk!NWh&|tEb=wy7&-Lqk!BB;vv@zAU8og3}Ruc9YEp;6(AnI8UiGbP>m%~A|ydd
z5j6#f2g49Gcr}B)84sQ2f)+5a8F<w601BtrXs~(+Ge#ZSE{st}YBGcDhS&>Yft6zn
z??Ckx!(ti9RM3)f4JA<CR?<;0L~09xOhcGkh<<~HEj(Sp3?<Se(4Fpxl{qQk+uiZF
z547OGIX|yBGbI&tj(Ki=8K?#YFSSN0K2aSD;(-GKG-wKM#Xv0~9LR`eNO%GobIuA8
zSYZ3p6qLXnUSd25+BsK{T9lDkPz)MpC;|^>rzjBiCD<m=;oM-W2zm{y3Xi9-&$TLm
z2S7lX5H#=sI{h&-sk9^&a{B_L2?#bA)Fem*?Y>Sf0UaHw0U8i1D9TStOv<SQ9r{w5
zlL8)LOG-s<`+&TF8g!5$5|B6yqsqg#fF~uUpsj0wc0-_14Jxx>Oi+Oe*)WDag8-UD
zf);zq3cjEV%Zl=oKvg$%OhQk=u>dsko>!7n2|5=gy(9y)YBwpdNC6aYDXFm0*s{c;
z%>2?~g|x)vlKdi2MUjtm!4G)I8>F$gGB+tdrx==g^FU(}Acw+6I6$=ss6h;xu7dP9
z!7AXRD4;MY03QdKqnDPMm!hGh3hEnygh99vwDSRJ_!uMx>MbRgfbQjk`V%Aw!kM6b
zcTiJmlynpdl1sGF%K*@Alpw9(5*ubENO7jNA+}|SAalWv09Ck%svbHtRfxU>2jYL&
zC}$3|0D{)eNRvSjb>PtmPy-EpCI=-FA#;z|;u+!|@D=Tu$??hgdBvdZ^q|2}&<2ti
z^=Mt~SbGHxdn+)GiAm8?h>6ith>1zjR?t+afr)B^MD0OKJwZyNT~lKfqP2Bn?O_V-
zW7Huw6;*%_tN?fKGILTju-Xh7FwhHg4RZ1ic7^&sF$WZlMHS$<NzBR70QnDMBt$AY
zEhj&*L?aP=RJKNpx?YSrs9}%@s^pbY!DUV&>{|0YusTq>N(8IP$$?fMnUHgS5_57u
z5ou~*fRsES6&%7^P_&}gpGxpbUJt=4sI-E0J9QLtLG!=R*)~Nb9Z>es09gn1CN!E8
zb8;Zr6Fiu%fOfYMtceARcGxgHv_n<`>L4c;L5@m*T@Rs@TM6p1zz^V3(g81QKsgQy
zlr~}Jf_w&Q;^~1VtkL&!#TS+4fqKxW(;x^f(ES|X@(&U}a5?Zn&IWphXu_a`20Gpu
zz9ANBw?1SLCZz;4NCPqigu!wc&Ib*wfff-VdkGYPARQnKD+NJCl&wNZVM?wZh|mCc
zbHK9)dU?<o04WDIo)U|Yd)6Rfh~1#O!9X1Yh%Z2K0PaYEBLE`=kwOa;!Vo<mvp`mW
z=6Nu@f|TMw>cDn_maZj&X2Bqg%)E5HkPOfQNR5)jqV&`fh!2WNk^O+CSr6h!Bu_$2
z&dg1X2TP@b%|~2#1`9rr2cfGlN>VXA2`$9HX2JZ5<^zm85?qpBPylMPBq|hxn5ii!
zsZ&n@x%5Uc88gk15sZ+jbfkbly4@6H8>pjLkd#;iKDi(-1(FCs0-)L)ROjOwSOcli
zD=kO?ov4CdXMhaW11o^u^^Qmh@Q4CQg9kWaK@XMzZx94+G=$wtgwP2sEI>_F=zSUr
zx)A4rgkaGMGYu4xMW9OyQ*+WV(kaMp&}aeHoB=uh!xpjU5xkZu6V#@$H2@W1iDjvf
z&YzA#N@{U3Bsqdh03C(A<oujsTSEf_9fZR{9>c^*iAB(>d2M6Vt8+l7)YVoeB^K4z
zC`4DM<|Gyrr>4}}RKqWzs*MFjk%F=UXz6%nNqli~Vos`UN(qE(8>0?6LcJK$)koM4
zD)+%-2Stf_>5wF?m#1q8KKI)tKM%Ak7@pw4OBO*VH{?`WE99gmmZgGDFjPn^QLwaB
zRY=LtOI0Y%E6L1Jfa`#^Vqo4QB7=aG5=b8?O5jt=AW>wTRFs;S4U2A=1Sl!!73ZX;
z7JxIaUJ7V|5KIz8BdkVByC74b2PuFmGVnkf__j;fp$hSt#d-N9U?GrNNIm6S84Mcm
zLTpwA%Y#Sgz!Kmf25kc?E-gw`C{I-Y?Lmj^P6vf#VqRr#ei3YL5Yp&{v`}HwhTxk<
zK?yrKTLUHrOUs}pqmnN4s^;9p0u96=2^FA44T-s_p!;iK+7Jh+>4C2thgCArOa(p?
z2$W?&EB?X0iwBKZ#iyjEW#*-(KyN_@t#`<PIRKQdl5@a^J|j&%feZ(&UD3<Tg&f8J
zQw|Dy&^hI)B^hw%fm$P=2{hO>>gYu&<edFv(D@P|?NGOZ3M5b@fSe1yAF~L&DnX+-
zJF~#n2xgy>l9D^<NP7iP-x<{GPJ~>hSp>2awAK!?CK)<8qX+i09?0eSDImi^_9-YR
zB!CP}P$(`)O$MD4SgeqdUk+*1<fN9R=78^mD=tY)&IYaE1F2Og&&bS41r7Ou_lH2-
z2hWTkx9BN=)Y%#;<fbO(6)Px}XMo1Ba&n3la#NLbAd*HX!j({$D=DOwB<mr$&M{9R
zHMgLo5`17(UOK46hJ+F5K*Kb!Q3a_f3Q(tlI(MllpmEUTY=sQ)y-5&<!B?(9d}0ea
z?*z1|6I6*NXM-w#P-uXwP4F@lZLrA@z0f8kSf{3f4aoGO5(RAqLwH<5T%-`A4r>!b
z`cmLY15iT-6nfEM!(+iyfe>>+A%!%B3z?_`T>+2>ii;A^SOY{%1IajOEvKxIkei<Z
zG9dxnLrY2p?|4=y2i-Xcu@`i6Xhmu=XmvK|1oPBnP~Q$TaGRf3oS%~laf7l#h`)=!
zMoDUNMoE5NX11o40;tCT9*KaA@yEx527zI#m_W%JyaEaCcLi|jgLQ5o4u+?GxNB2V
zOF-wlgOec0)eze=(-c5udQKXoWsl@dy)^JaiaE&h&B_X%pz;}1nrDOVApy0!%M&X>
z$r5HfsN(=xg`AP9067-~dOilkLQo_tD?~&@Sb<Jo0<R`b&4n#v&C6FnHLkcMu_QAY
zY5+KaD(EU?mVl>#kj(>`3L4V@4~8cqMh8GS1ECJ&ZCEg2^Jz3JC_uBv;D7>6AA|FK
zd^|KDL03b9%mI&r6s6{sfTLP3EgmGHmz)n)4Y3k*Iz)a-Dp<9mtwM~t4J2;tV${JG
zqn6|sKyr;jX>loNWfnvm$S)v0FqeXNT7U$=R|lq*=0OHN@{1G_p#cNStjfv?j%E3o
zDGJG%MaiW(iJ+mZv|@0V8th6?Wt$CM%&V-RkWo@nP;8~IpOT+ktOq%+L@&Q6UEfI0
zTt6o>sVK3iQXf|6W|ZXSD3@fU>VoFliVBKSOHzwK7mdO8W`GWSKnhZDj|n6P@e(w5
zD(OLM5|D4;ooqy907^IUV3%s76~T&F1z7C}bqd5p1qINlvN{U!U<6(?8xI;JM$Np5
zMd@IvVvu<-jmn@(5^^OnxP;CuDhBP`0SyM1q!xh(lELC20Ypm5goYbvc^t_3De!y)
zGZ$J&f!w7D4s#GI+8`FRG6|Njkn$`jnw25dL}H0Ta$<2RsF4h6IK-%f(>EwR7o|e4
zR0N$J3t1%v_9o0ukRb}7lC%W8<r}(?3akWFcxk}w)d81H&?F4eqySxE2G)t@E{F>F
zX;_&h#gNG+RBK_XGK*pLKfL{*qX3#?%gjp$t(yg{QqM?LNK7s%P0WE91b4C?EbT%J
zgOSh#16y1NGanQ}@bz1u^_QSp8tyB&dqJX*_2!@r>@Y_|%>+q;ECnStg_25erwKY?
z>6ljuKVu4-+H@4slR>IM&4BdGveeRol8jVP9)ypSfzvBevV-0-2Ns6aYM`<~0d%z%
zC{01j3W&2nXFP%$SzzUQY4IR_BCII_vIn$A2GohDEJ%emzN{1spk4;agES)#>Vd>S
zsVY4glmOzv38*Nws8|E!21K3$$3Dnx4Uh&+P^AuHfJD&JLS`DModFt;1uNB204-b0
zPe}!@SOf(oSTo3UG>xFR#HJbQMO6JDLFAeSq#1@m4l9P0h9C~q`!IPJ4b6Zc72w08
z5v>E53IvUk7(l{M0kCFJrUhL@QJR+wy^a;+Pf#*|Hs6ufJ;O?;l+?7u(wq`d83a-Y
zu00fxF1JUt-$PQNGtiK0>7k(pT|Nd$6_Bwk1zQDO&|xkfj>*}Tu!<2hI1ZoAf~bS`
zjxa_&;A`bT{sSdov~ex)buqb+?qyLX<Y+pi<p;=#r5OE`5<+?*{s37FD$(@d7Y#yN
zTM%iGo4_N0u0=)pMbHUw1zkIEVFe8rkP+Z>(7@)T<d=YF7{MHnhaFLNTS7+gA(EiG
zaB?B%dgbK7G9uhG*pfMrT2QHyoDAvFf)s!-l1ZqSVM1IEQ3BGemz*3A@26@&{R!!~
zBPCO?N`zN^K*wjqsJjLQ`3HfDF|agv+ZAY42*_{{28&{70^L&y*8@7I5`5<(D9wTN
zfPyqJ1-g|RWPpwWsGq3=nnuBlP<S^KHBCZRYH8{vrlhzfX6BR@rD`AyK?DHEc>Lan
zsD-)-W)w)<fVv74P9Tg(R-~jPB~Sz)kESUrAPy=5rB9TE3$h2~VLeEOfuu)`7<IQ8
zb)@8hl-i)`zz55LQY}gl21D-a1P?kug3t=SoJSATga8i<fKRf*nvG!DI58y!W)vu5
zkz4|CE5w>qc%h4?NLhifK@cxNE@uVRj>W~L&?W1TIa5f#9W;30k(rW`iag2+(F%?o
z(9j^n42)2Pr~+pX4W!G9A>joIc8CIOmlva}0rv|*l`Qf|EyxHERz_E?0j=S|19ruk
zNja$lczH3p<KUMU$EcTsx*6cWhMWWjD&}BE9Dt-?Y>+tQ0QA%pkT~3XG0;1VL4uG-
z04asdbb~}eSIL2GK;O}%2~r6jtOO|oD*^M6mc~G$2Yf{?=;R~V?d{;9H4vep3F==I
zm4NPUNB9z)K2eHXa6baM_(PEesn=0}70aOM0_0K<=SVkbf(xV=Db<0}0)}fr#_OS0
z5UB12=|YV0Vh%Th<w0#Yut}hRf*i{Q*|vu8H%J{ct%GJb&=rEN)PzjW!7o(?8;Iv-
zWmL13VK-N!9)1C`7Ujxbq<JQY95l6nIytZeg=#X|CCt#MfE)`AE=yfqkd|VC3`M_g
z8Pz<H3dBXr3b=1tM%4xlJW&0LoLInFAJkVtDpQeD2%@M%s6;CbvlO6X^Puxvf=ZD#
zYl5Qyq#AS)Gw6;Eq|k#eF9-(BeSv0fK%GvIV$k8>NF}l|Xi-Bs%63GQh8-w8K(l>F
zZB0E$yAbA2kP1YC0gZ-%l2CeTiA!p6GPL0buHcbuMNyC7K$Z$<fM?7>mrdfd0_>6E
zjQk=LOF+FrC-5#Ia5ozqCm^qDfEF);J7nOscE}4il)>#6z2yATJn*_rP~}z(su)4O
z0%33<BU}i{IH3I>pldk`RWtQeGc^@di<J~q6*TfdV}?2kSr7`L3CZIatC|dvc6p;T
z(m|FZRSu+<C17_aCo9;Z&qSBlqPhV#;|$h-a5KcC(1UQ0=V&3R5!9qXNi@iQ%qdPq
zE7`zN0nP(@=vH7UTTqJ?P-;Tgq^XIx!yP%1fISfpN*$p3Hnq3}CJAaJLY7wsmw;yG
zz-~d#iLmemt+pxyt$+dLTIZZZQ27Gc&x7VA@H})pYFH}RDnJkA1jQZ*qfJyIW-vfC
zSRqPbjD1fHvJzO{f{#(?p_%}`lK^BZ2xD2m2NFin0ZPX<rFoD6Cs3&ADFlN~P|eFM
z0k1mME2y+nf(0Q+HwY^$V3+|uZxtNJpmmd=<piKo2DOC5o))o%A}mFsSVLAy1UVO+
zB*2y@gNIr`V&K$Jlv-SpUzCcH9u$-nLW@&VAfxP{4TqrOqZD$IKRA34ej+)+fV=}<
zs10=y?D*)CROIpo<UF`a`0@&f2<de{I8MN69o&on#f*+ZYF>&h#_2`M&{+>#1>_P5
z<QhnPgIx}H52yu&G=B}MV=x_uQJjHHgSZHERX4mT0nYBAn}y&319GP(=$dT}M0kTV
zgD~`JZcy705-K2dN(#`4V@>eA-w+7}J6i<<J;e3j;AQTJmBpEP3Xp}<da&hn&{hL-
z?+aujye_p>QqWS!^8q&r!PN=8g9}<<lUf8DtceHR#*vzn=aQP7UzAvqUj!Z3!FIkq
zY?~pteg%~|(47Ntqv3t$(!9J>_^>rN1*7i1!gHQ3*s<7b2YC;KA>Be8M`6QyWAO1E
zs7(+}wh#(*EmL+mXiOR$JRn2CZp=;0P7MMNMS+tca*+#4az&|$pkqzJF%L0FK^eTh
zvNFF^5fS-NDO&|ZV;74gM!0K0^dZ$v&~Z4heUJl=!9!_Kg^-a6J<x&(Xu}1x01{LI
zA+~RTibIgk%8Nj^N)&0N<>$jZ1rp9pOwUZl@G7VYPQ*kv*jb3u9W)QE37g~wg(xf~
zf|{8iJ_x7f=R>T61PIuEz4-W){N(s}(3o(3K8y!Z01W}KI*?z$X#+Ga3BCjYmV_be
z3gV%j)KQ2B#bbPSYNd`skWW5n>IJM1%Sa`-GASu708K!~J0~V*q<ZG1flgURNN6a*
z#g%jvqLnf-ONv4J(?J`uQX#CwisH;F&{VP#s0RRM$AS|UD2&0aI8earfJWF;Q=sEv
z&<a{fNlC#M6bsOu6;MAwd=HzHO3y6GC<Whpp%0mw(ocrcNjdpR`k)z6eV@!EeR#lt
z_FsVOSNKG8F2s!}OFKZWgW3m<6deU<Ucq+CHR$9ATLrK>J+PPJGgCA)brdv|9Kc-A
z9Vg(}1BD!DC<7h|8lZfpqX5Zo&_K{cIkQt)0hj49>JZb>Mu_0m8Q5yjs?w6g%)DaI
znH901WCBWRAdIp&234&_c4{RoD}a=OFnE3pk_^Ef#S9Qgynxh#FeC>+%q=J_0T~J2
z`(BEC!VZ?E4a^>7{pqP-{g}BQtQcZ1G&exw4CGOy0=c*Z)Ez(`T8D_hJPA6QC>eBV
z7o>p*-fIRLp@(iIfgGX)Ze$dLW}_8Ki&KkqVFMhXgM>hu!OJf|)7r2OS}|xfdS)^B
zXy??TVg+zU14)8I1v(lJ+0X<{d!R|fpwz?^-Tb^9&^n9cj8r`Z*F4aQ9ngY|l8pQm
zg~Xil#L8mOs=bub<Wz;?#N1TSIXa+Yxga3{G0_Og$WV}T%Zos}Ve%k(2|k^MeP=gp
z;sDZSMc;B>1YZdQE07@FJ?P4C(57n8Ue*E)@N!`2k{WO+rU(sRP`oQZB#=%;f%b^8
zI|;HQ9c}YFv<(8?SE{4nsgRfpu5>^l2AWlYL^EtVJ81R_wCX7}MFF<l31z(_*hTrJ
zC7{@Z1|K9yK?xcx3642DQm{}5r9Y4+P%(nuyA3W$%u7iug4~t>OMxK8#h_K7usRxD
z7jn}Ql*Lm(BPpQiCTL*^G5~}jhJb21aPP@C6_jZF5<%DIfTTef8h^#`rA63W3C`rm
zu7fV)MKaYTKN&P!omrp(-HeWz01&~4a2LAI;NgLkzrllm@Lm!))ImqlYbanTWkGuZ
zOL9_U)Il4RQ;^R)hI$lY7-+Nz)ErenNrZ?%z;a3qSR+P2KurY~Q0RUE#S+BN4q(j~
z2Z4Y^!A8PLL!|fv8wtt2@t`sjtPZ6{LG~-S@B>$+ph#5)9q6V2UZWSBS`rFba0rV(
z$QY`!f+M8tC@KXVAd&{!Tmo5R2Fe(qB`~Qe&{7Ga0h+xMi&N5IO=+k^Vli}?gR%l<
zc7-^l7~~3YzZ<#yfar&%B}l{)?^TFLK_n<QLW%@<2!K*CD3QPlb8zUvLI9)(TH}Gm
zQTy*OEub~6`9+XryolBtOcqy;17|kaJcS-YwL&%0Fg9|k!897Vya2}`r~?7XyI|)+
zCUGDF$X)_(62LYa0V*QE?gDjoA^KeMlVNEeDb0ZbMj2Yifa^AJoPZKUYFTO?XeCAt
z=n`en!s-<8-2q@lMVaXtB?_PgK_#GTa-gXOWEKdMmX5)y(K8aFP(aSm$_j3v(|uEO
z3n0}P_|6~&4bb9G$PzeE?FwlXDWt&qY)Hil*eXZ{Gm6Gqlt3;J0Hp)a9$`=fLb5Z+
zTadHk5CICx>>zOvhAxo?4OStdLqS&oX$J>pqQ~k2a0vk^%s>%{9xxi<)*-@C5HEq&
zMnNks4b5n<7&som4N;I!ic+B&7UWp4JR}&v<qQ^gK=xpQ#^xYvzrnc-Vym)32<RNI
z%wmPyO7Mwq;E`9zdL2E5;CzMhjKmU90s>vDmzV_FW}aDM577(Cqi~0ToPnH}L1UaC
zF+|?fi;qWcAAsBr!tjnJQe}j-iqlBe$pyO{qzh6kmF8s@mO}TTgF**nA<Pkw!YSJT
zR`I}H3Qa-~d3cK)MHIAo4LSl0Q3gtsnV=Om@O$YXgVXQ@K@epSmqFV2*#@97)Jz=|
zgFy<wyWT)^oSAvh!U^IuP{UY3BijHp28l?ysNMnT2Vv*}br2I`Gqgm?gv1PrSaxb9
zN{K}D_ynx=f<D3k?=?Xz133Z|@Otr}BPAdy5ji(O<RCtR$i`>prKEzkuR+5YWCAop
zL4pD-p9<=pBdxGOSqTNP8k7R#Q^8GYsL832yIMhZ!a@#YI<&SxUI2nfn4kcMXa^M)
zSgH)Lqlm09plZRJ*O5bkNEaC4bAk~mZUD7jLERpZBalK1>^@M<3ayI3g9p%12Je|c
z4mMCQ>R}CFXsQN<Ei~yt)FNt5utlKdXpr6_)Czb821gxO4Y<?->DB@Dj&Zi6uthVH
zD?kPyq7-_xgb}!-3^|LfG!-QmK&(#A&jWX;5rILj_d%H+o}tk~0n=h5cvl{~&Ctf0
zC#Z)Cx_}9M!=OE^-3AJEh<^zL3N&i)xy=aKai9)&JS3+=-38&qr<LY`_AV6_mtYPR
zAhkb07GWDZiBX4`gEG1S%@GifphX9kF$-vrz`KXw#gm|;8x%kTRGE3{O5pT^lqA4r
z!is-L1_vj6aFVaCMN*jw?yP}oXsGX@s=?(DB=dm69O~js@VZ>E=}3MDDIn-ZXiEod
zF2ub$3Q8c`m2?y`kxxO7ho2y93(*74Ntr3oSU_?+BxFG`q>%<%)vTic*NYif2)}@x
zADx*3YEOXmA*7IF1k{`dhZk5qlC=;;P|LxR&{AF7Rsnn<HYhwmnH-`7d^40YG*N-=
zvr=%(tJG1*Elvls6l@j1r%_`r1O(fJo-*~2jD>~?*eq=23;4`BkSWM{8=5s>r&Ga>
zG=r`H28A|U8=_dzQ~*zFATHt6R|2g?04E$oo(Jy+h>us$R#4I_$j*UJ)qz3->EIl2
zU?4k58MNjW+#&~$euFo7C}?ErrRqUiVW88SLHp)P@{#AtlR@r8OXVOTP`M9^0}zHL
zT$pDeH_F0zFt39R(nNL;NGtLUvp96XN)V88yfdqiTm`D)(DDuV_~-nB)I1HaBR~~0
z=mK=`$<N5wpMz`wVaR2{klW8e5sQc+Si!HO0J^~$lBSgvoJvbT_g8?o>?GzCgHFK)
zt-eprNClmSpOcxKS&{?0r4<}YNG%zV`N)9+?~H*HJ-ibJKFI=PU}6qvKXE1al5EiF
zWZ|ihh5euwAIMnHPL`7LOq7#5L4JZHNQjF;d=OSvz}WK(KA<ZFQYL_Qge7NyZ+3&(
zTAW&<rw|Tpv!~~SCQ9@3?7`Q(gA4>=a1awnFt8~NC6IL>Lm-|74SFi+D1c2sDhrSf
zv4gh1ASwvQGTv*=QxZ!OK|5|Tle2SDQLp6&`2&VQ5rmNdKv!-hmLwvA6EsSR<{s42
zT2TRPA1Ld9M;*Z@!y|bXvVRhMOEPHs0hS~n(FWc!0?G%V)B~E72}(`R1YH4}nU@Zq
zZv=I1Q!~>M6Ob@7;FA|1F9m@IWQ!FN6_WD{DnZ)|L1R0}+H|1to>{DrnUb1Ul9`+c
zKGh?&EVT%FEHcQT^2ACFEl{VgB0067L;;-cL6c*7DIml3;9Y9a=rj04Wzdc;P@fw#
zc$Aoge*J6#XhTSTX$f?A0PbdxkMmN?k$hR2hjNH0=!ln`9FXBC${>SPNU2C!!L=e0
zyjw0OGdoowKPLsz?FU^ZT>=`L2i-Z4otj!utN=Q0JsT7};2tW}H=x~#NWJtR@Ek`G
zN}z)`G=L|a6AKD*z-P~)$m=M8tp^1H$j#`158kMnpQ5Qyo)0>727IFuX!kNAr3E1c
ztu5#}dU())W&}WvN4Op8Y|vaZD9S)sSs_R-zbG?36LbTtEjVF;guz%@As0MW1G};T
z)i7}Umw=7|M4F?8rq3Wy;slw290&0If>?qHE(h@#nl{8dCTifq<`5v7lod3zG{aND
z#con6`2JsTWGQ7-re~(+WhN^@;uYC&h2oOToE(MBV(|9y;>`5C#FEmYRNVs50AUg6
zgeDyYaFtk@Uy3MLLB~FVQY`dHyhMc}&}Q=7R0YtX@}NXgkO<m^Q<7R#tf%0XU!(xq
zf~*6s6F_qa3K@yX*_p)|3XmOenW@EkdU{Ev;KRPb$1W#>cWQw$2Y50ku_(P1bbT6V
zU<6bc=qMEDgDz`UF9sJKi3&-Xpe?h-pgspE(4mol>`zd9fC>`@TLqlu1xOy;paJDE
zNPZ~}&n(G+Cn(ThENCkSbU_3D@+2n*x^ob`vD(=u7%~Fr;_B=l<QU=~1Ugi+Bm=rZ
z73AvtQqUfU{NfTsK7>y-f#eZ7b3tbsf#N_xsR&W<A+#x3E9B=PnG8DI2;^(f%nd>n
zie@E+vdlzKV+fLzK=y%jU@KR_d88yWKM%!q(CuB&1|7nb9MG@=C|N*rGFpg2Z_~&x
zf*r>X318&-e$Zf08fY*GWt%L>g^(HrY9*)*Sq#4P4>FaK25LPjD|qCWgUS`q;z!W@
zB4mv<{M>%n*-h}`6=Yd%Vr5b)G}1vO9Ox9tVo+AgOfHF!*8|TT6vKz2Kn_7_hM{T(
zHLVbZ4#wg(&^}`n%aF@5TSQc$)ubRRA$~`-4XJboDFNZi%+#C|&}DQ;J_6+h5Qaus
zUTJPYB`7uK6+oBhlq4pVf=(=ht%HE^q0*r7Y|z>#m^6$J-`7`AnU<NJlUf27fUV;}
zvK1O@a3%T0aAsmrdO>1QaVlJ(xDp`=vKTG_KUPLT8MbE{>M6)EGYUz`dZ6McH#09Y
ztx^GWra$PE2B;d)NjeCPDf!Sz=E9U*n9sl}l2VfsON&zx=IDaW0r>^&Owg6`FemFd
zLW`;ZkOzu1kQUL{#;Ci3l1^etDySd??Hex0FDlUk?K4U($jr%4w^dS7a;-=NT^4Dj
z5R(@Ixg!pgYC+@X;9?{Zx>^e)ACqUN09me~kXQ^Vxj{vwVSGvfc$EfRKez;iO-d^m
zfmYokc%U<l@R_5aTL@ariQ6Ku0*EPo`6a24Gch15o{JUWH(`O-QKI--AtYY`LsSQ}
zH~@S@5!^z^;xxl}uv)0c+(318PNfd0@CVrl8Zl2pHXT$?fUe>IMOh;BTnGgX(Bb8Y
z>8YAJ;Elte$^~LL^d3fqBFJTk#R@R3ph`;ts!In{HY(`mD&&Lr@IjVVSC(Yt=YcX8
zXd7{9acWv=j$TY2sJ=sNrUgx%W~4%+O#$581vMn|6kPI?!IfIEesX?kQE_TK)Fyq1
ztBk?hJwPY8=oM5#oScBFFahMvL|77l>IS<rPa!!2bVLmFK!p4v@aX|D>If?nz+q5S
znui+Ny15FdcIZJI10G=j9nK0{IRu)$Lf+19tY@hYo<-76&P@T8zj~m}>@j&tO5pW7
zMY)Nfli47Bc3XI62}&#nE$s71%_(rphpN$x$%Eu7(9XDcSk12yqpn*B$|-rEML)JN
z>h>TGXeTXb<sGQb0PhS1kErS>WTfU4*v6>)gBF6M!txxrVF6G18mW5edRE}ns|g+^
z!(pi|XpJ{)a0p~4Xp41bex9uocu7lqNl__iffmflV9==|pri%UqMwploLQ8b0$pZ8
z&??x%7!s^X1mD{QN&lcN!r-HSN=s5f=Lg{oOkK!jPefV+StJO`PLOH`Jam+tpPQQq
z>fL}(+eiT|BEW4O=ujNc;c)6Y3iw0Nv9u&V7jz&6=&%L_kT%45+<KsO$)JmS%R%RV
zq@*U5rl*6>6a$AUq{9e{?)aiqQ0W?9Tv7_^vuQxMI`E1gno<fuYwDqFNQgi=Ad5j4
z+k#e!=qO~S=j9ir#zRLw!S@hAmfJxWWS8XU#HSV&LBwFqLQqNt^{2r#fgU)0fzmU4
zV+CjtZYgN#Jm~tLV(@-kaIOUD(<=mJZqOJ8$N@;zKRf~3f)8iVD@3%kK*zD_fzJzs
zDMHc*Y74-Gbritf25l1t9bZ=lxlX4H)Wm`*fh<bWP|{OEzHJFhryiyOwEZxz1b(p%
zxET$y6RBkcivlHB8i$>k3n~<qAjdg?d<+}*f*#Nh(FQ(u5p>84R1@Sr0)!?kF@)rM
zjA0!+1@Lxg{HN(F=_tV50y|9~uVZu+l;AZUcwk0P!8s!}IUABSp#?PLR0ik)`JfpF
zNCd*K<psq%TAV`?rUEp^Aw0M)XhOxJ4JHHC2jzmAEue^jWNFYfbD*(@c<^A1tpZy1
z!OS+W_=YBYlsz$^$b+~Jn!;?s=?u2r9e&gr)Frl18fp}*!~|6j#d^raE>r<5*&r0a
zM06mw+CnIT=e2>n55pjP;$hhrnFCJ2kWf}u038tw8chII?Z`bY(9t=tE(Bx}7}~T1
zHF&{I7SIl&vcwW-XADJ6W>HSEUQTK<sJ{(eV1OcDkyD<TmyRL>8W2<f4crz~R^-4M
zsp0uW*-82N&<lJ~j3@xDmMaFe?F&+1egXL$Yz~%X%g|Xv&^#ux@)Xc~4U!yuYB(CS
z92sOF#8&X`dT_f1lv6?F3-owWh%~5gm2Ie_pi!u!0J(D~6?}>+=-feQ#)2g;_(gaS
zoggc~x{Y)cKqWS)s6yz4o}msacM)1Z+EP-YW7J{BLgq|j)MH^MU1Y<~JH(<1WD%wY
zBWNcJiw2l2NajP%V#looWCxOR5Ep!?J8m5%`8h}$3_u6Wfbtz|svTqksM85n20Jzu
ze5`bS4pu`^;|vxqIL$>>4w^j&RSMup(L<Gk*@m2u3c(o$e2^}vb_QP^1Ddx1&+9;w
z0BD^zNKCIHr?>*TYgHN95TxO6XcYl57Bl`+;z4r*pgK5355xjpTb-Jt0adP7k`F$_
z2R3s9iBXVupfv|X0Gx<m27z)0Ts^X*z^N0IEFotz8X6cFV7dn~UmK%dRGJqbqpl6w
zy^{?KCXh8?oS6oimj@XIaXyA)K&nzwU{mejp%sYAXo$%Mp!5N1^`;iX@90K&1*`v1
zjYN${WM6{RfiUuV7-V_S{4l5}Qm|Ekl}hl?0_g+aCR3b|nhIKb2UDz<m|T)shEhU;
zLNhr(2Ry?J3JFABPf3B@REZHTAoIXx>wzx&(<sU>w>8vJNY2kG&CRn-&d<>{)P#)P
zDA<BR7}?z*w}I>|$}h)Oz(7MAGeSZ7uvlA^U#@M0%W6;#h1w0JK&F601{8F9pj$j(
zNffIBl!I8|IRkViU_pt3FZkFxzx)z6&`rDGMh>X>hiyfLqyx~9oRP5!vgx3@7}hkv
z(lCVvHpr!r9)MCnQGQuwF=&y04y@IXnU8X{Ic(HOqXgc<fF^d3F<?Q^l0Ud4#5o{2
zh!v>%kw*j}@=6Mb=2IGI5C%G=1R4kgkEMc_EEI#z%L1Q)2--sfJ4;SOQ#0ByRu9zj
z1eG@stJ6VTq${pK7oUP;K?j?G?+pVLOYo5hXwigJ8iCt<#TsB^U}**69VPJiNM(L0
zXym83G^eCk0X&-lD!nUHOB9k)Q$c(2AoEzDnami-5Ds*J7t)A?x7rGFQWJ|)LF4Y=
zfeDbyQEn5529ceeosy0M#6=KKB00!253Cow3nDiWw6PA9R6qm$MTsD(%wq6(g&riB
zA=-<;(`C@!EcmQZNWZHT)V$Rwgn3(8Aw$7dp(?XLBU&Rf8hlPhtd0VR1wX(*9V&o0
z79$qY5dkm!D}-d#Vhv4L6C*>xmU6Qoo&dQmuRt%cII*ZGu~H)gnk=Dy%ZRqpF^JVs
z0MUj}+9*~Blsg~`1wvsvgF%BAwAiUg#7aQe2A$y4!cx$jWMU3z)iY@NIJF3MuMR{E
z7BQfyjr3IbE`QL<Pso{2kX6#4tv=v&=P>o4<N_Lf1TV4xl^Za(VHg5Zh0qQOXpnBm
z;R2u;9q8G!AXC7#7K#qU_<D9~C8FX2nE;+bfStbv5&#v|&Y*e$)dcWPL8Oujq!hIJ
z6LBn#GvtV6kT%3AK4>~Xy1+Jq-RO+rE(L9c9B88)q!eTpy64cOAz`OioL>aqie-zg
zMGw3_37QB&W<nDpNF78kDD8n_j$ro;)N_P&z94K+!44Y80AD15(G`Q7djaoyK^1}f
zL9oshWKaXv#X?pA8fJ@6%SlYP1s&s}qfnfglbQ#+`4Eu+Kt6(Du*oQ$MzB^qieY^-
zh{f0yCS|6_XQU>kq!xi)0!q6Og`o3OZ9xkSQbE%OdU^Tfu;xf+8felGstYLvBo-%U
zX2vH$N<&)(*i42VWI_Xa%(sRTs0eT`N=yNb{iWsSmDnn!<mcyt3QCwylR(D`#Kh!5
zPvcaG&H;}ZgI5k9TLKwr0S%cJL-u@u_JHTW_6C7&b1;a7E#pUOyMe3$TLE$jxTguN
zk01qq5~!+DC<85*ijRlhegZ#UHKimTw8tzj9dss8emTglG*I|xD5<9CtLEyfMk=U!
zSgHD2sRqM*1Tj?!e2z+Lij@M$V7M{Rlnct&&^CMtXtNL`3a||TK^+7g^MUGt3W5eQ
zKvg0r^&-U!_`Y!^1(+g`{iymNwn5zqooE5Aqyecc)=^N>08QcO>VncNI3gh9_{ET|
z^5A3%k^(1Zv>ouU#W`u<)j8n(Z^h-XJ&9HdN}x+Wz`Yq*jzJls(oujM<N|RYxYYw2
zY=ISNC`SZ<;wG^O)IJ793G{dYh-UDe;z(D@ftELcuN1^u34jMMK*<DDTINA|-Q}8~
zQWMddh6W+5;|lL}gS06t6e`#%6v8qLR45)gfoiJ&&X5p?VaS0d$e<^Yfi8~&SDT={
zyBNoip*1yO5f2^*&C@mnE%$;s4k<B!>;o+&&dh_&_=7}>K}WcQuEEI%l?31gOrSck
z*sUl(7sLQnP8x;K#0t_-2u`LTPwK%efo|FaZ@z?eslhk!p(=p)dqKX#w#x!^_CiTc
zDrod44-}V5u<30D)l4hUNja(-dD@0L3J@nCxe1bhQM6+@tD;a3){Fuj<Bf=fLOob(
z3QZie3BI~kL0Q2)u_Pn4NCA?RGNG+JaQr|Q8i4{v8FAoU2((`Y5iX1eEgb~y(gNR!
z3A#cSbj37iqzBZkfd?Zvhk-;u$qhO@0~@IT3Bwg)Txks*FalWzJ`4hKY69vJFQ6EM
zL=-f9l@&Y^le3Z5Vj*h<=WXOF2ecLs{mvBys1ZnkfNTcjtS3-$395-fjss!Ho+hw5
zQ2K(l1mTAy*cyRK22e{M9KN<-g%JN>zy1<*wl1g;1uG=RM9?TBsF9!tYKVe0fX|q~
zZh95yTpnX+rw`<OWpFHIVe9ZhqYPA$f>eSqq~{3Aub>D-E~UYl6_!6RB(k8n7^Dj+
z3qy<p8H|~cp?zAABt#j=Rval0v|2yE1Uz{Hx?c`*<TR+n1Jxhk>3{INA8f@8Xqg%4
zbRNi(RB-->jo%`ygRr2BctP&Qom{c{2z-hesB4SZ&4$RL7@h;!20obw<YFXsAaO7T
zt$;;OuUPE`sm6Ac5GcQ(U-}0=;s-oiucr`_kqW;E7BnA~n+Ur35fq4^nao0k%o6aL
zPtX8(acQoGLUf@Kx^W=Ig+}1qjy<B_Z5WUvA+ZW#fiT$fXg5Wb*kbbt)-#ci3QvT&
z-~nz>_5e4HU?b(ui3KI4pgorg$_g(2elhAH3PG;E{$Z{PAs(K=3O=5GuGk^~ROW%l
zI5c9^;YP%$YidB|8=%t;n&9*1opVa_vMXU07FXt#Bvyd(1axsh3OGsTrzxPVNCAZd
z2qSy|;(?|eusH}M2f_qH9cMBD=?39KBRx<7j#|lsB+zl8kzPh(F?f4zY6@ga8^#HF
zSd%u)AY}#AoCL8Jl%_oMGD|WOb26(yYdKQkGqmu@UXU+~GZMk^2D_{jd!_~11sw--
z1+T&dU0#@2tN<JR0?DI>Fh~TN(V-nBf<XpV4(aR=R1LBKQl~?Pt3Z4Z#&iZq6ojFw
zZI!f)VP}wogb8U#Qwj%7ii3g`9GIZCFT7B$2Ho>pl9O5s9`J#yNd&Fp17Cfh09r{^
zu8^1qI>R`>2-fT;#$x0%NeDSoDFnO}26V6t$bF!NHsF&#z-2VtwdJ4{sX3Y1si5V;
ziJ3Xz0Vt4DK$xHv7y*YZ2a!~!qMkj9%{Y+55Qj2ho<NG~Xh;kbYU5$eO(0F6L&)G~
zkSTymZfG|F+hML)je)p8NkIvA{22W7F^~oDhAU_VrM7|w`G<{xZ_@zP-rz|sQ1t-q
zao{;@3=vjPS0WA^0|he(Bb4B7kfPP5=&^=Y9D%Ax1!aZc)DmzGf!wkIFNz>@_Ib&v
z;1&~TWh7_}7kX<1Qj-zlE>Jm#(mb_Q0G*$xpoDf<CbSEX1?mTY^yq<`BgoYmx}%9s
zwb-jvuqE&cJ|5J+gw?1ZDP%Vzy8;yA;4U%N!VVHi==wo>u@%6F<!a?7R%jULDCGI*
zn&^VYHj0Zuhcsd7)IdTH-oHfZLxN04Y&p?U!01Low2q!;U0RX~y579F7&PJst<d1(
za*!GeBW8#DY1WXmK|<ESek3Kt7*JjyuAs-AFTmMC0ao%VfQw!e1zqrss-VmP+CzkX
zI3-3Y4sC@%atqds2`O^|9D{?wr$Itzzd&2s;bRA&@kB_m1UhdY<&0>AcR>qSi&K+}
zp$AD~wF?|9&>=bvC1Q??Mwkx?sAAA*e#qrrc`@SbcO3<!VGZa^6X>oegnGD_Y(Y~~
zdZ12mG0HK~NCtokp`z4c#C;j?kus1sARAr5k%6j6L0bVX3Z5Y^25nA-83w;30u;a?
zjR+?oT#0hZH)!cyd9i|n0?h3wITOjfaD^~2d<t_bi$D{<8X!#?<qBHxkkeGqhufr}
zsR<t8g4qnd6dIfu43Nh+VD>@R_92_5prv4_XMkcPXnY5&fuK+YVept!bY3iI1QR?X
zXr)jNTB-um1UkhYEC90?BmiTB6oRUOVvt~AJctXfF2P(d3+cQdlwmNK35aMw89jsB
z4n08)>{3I}4lQtf4Ij5Ftj^Omtc4D;gB5{Jd`MGLs7BaUt6yD?tOT004MDY`lAe;5
zf<~SXqz*LHgwRHs3g9DNi;WbJVilqfwZniIIfkv#iB3a|DnebSqmZVA;U3TgD#Y^y
z@)S6Npw55=3pDN(azQ<Rm>~EV9Z(p+!WKmpOc2z11Z_qvE&*-8f$mhu%!BS1gf#^7
zi^11BfEMXMnGm-^<za?_rsb1BXGf$$7qa1=+JVnYfX3@kr#FyhH6XTtZ*~Ud6;NXc
z){2G>!9znLH!}~km>RUhwM1Xv40?tN^rT&|sDdu2I}cK%1(PnwDFR*l4ZX=TQ%9lL
z3UsxjMkc7t0G<1*txyb36~*AfITJL{jX0whmI)#0AWg|RAG9Z=1U&Jgt$^^KwgR+i
z4zf-I>QEg8B?wCiY?qFLlC}a^9_nNr1tkazB(J0i>gqwl0!s>03dt`?%mJNBssvuG
zgcd29+DiH;5{Lu>N_3zU0$s2G$@Abb9Z-(dfJG~!j0fLlk&;@Hn3)64<KV;y&C}5N
zP^eit3J8~iLJESxBR;StBe3xo7@ydUOVAZ0@cl(u#rb(~4$=;#q$(r0Fl2K)oC{I~
zSrU;{RbG@?lBxkR1T^8MqfnBcotg)}OBS|q5?oj-<R_(-7AHe`<Dh0Q?7S)Pz!U6#
zwxlW}P^kx6{RtX-0-L3ypj2K0nno*DK;E~X2E76YX0s+Jh(Pnl>EO}-c*r8vVvWq)
z0@x5Qd|(9>Q_x@s9Tk<CTL4KNkkR5?P#+Go)B|P)v^jv7BLj7Es&nDnS!+S*3zQJj
z6l@hh!l0EZuxmDz6;eRAD!>+5!%jv39VGzLqO4GoUjW+{11bQD^$HS8GW1~T;-QX+
zkJkX13|gua9}k&N)c`lLK({Ao>cxZC>%(V1(M<)d!Xw%wko|CzK)d%4-4eK$K`nq7
z^<3~mtQd9h=s0+;3>s7*pW*ix$TN^&f)+s_EfDjdK1LaO16ABO%_h-jdhsA1f^TmH
zSqj4F7K8l)N>Ct4^uR=qN}{bt@h>4$k%A8zLXZ><T5tq12$o`@qTutdVPaL81t2AQ
zQJDp9nV{pDLEeBW%*=<W0x5|H4MD|2uUEBI$jsMssw_z@_Vm}tt&FeAEC5gALhT1}
zlS<Rlz|*lvDxuQgjErWp20{-gUzdaC6cdX<UO<XWWe^{lo1tcb+zT2KEy~X?(E;u7
zDh3_Ml9LMFADCaPSDu)Yt$`duNXEhRg1iUH$siirjewbHkd<Glc`3ypw`(Zr6;vw0
z$_kJv$T$s@W{~n{R(@ul2E=(F3y|E6tg8%3M^S1H$P5iw@<BHNu@M87_mMq_!-A^J
z0%*vA9jK#F1}+CdZh)6|(J|`KXo*n=HB1q40$N1~UPKEU8%NfIWIIG3vH<viY-H6a
zIS8U2RS2r1q_haM0uZu^8MHG4QToC18z^G*5U~O~Dh@q%2&NBMK*NGF4dWmhkP)ER
zqh2zB*AbaH$YaK!_<&)U5*#r~T9QGE6CCD&k~Vld1)hW#qh18fnQ6#XEX>6)8WG=R
zpmda$23~LuOFL*qG&X;vftm;K+78LV2uG%Y$_bpV!S4b@6AHXV9=viBTI#{JW5PD?
zK{gtJ_p4F7ojJ4^G^vwW4BKN1ZTEoY6~PTW(3V2zl34H(8qk>}ptdgRwp2*7b957M
zVqS{E2;T&(o0kt;%RzYWs!L`uXmvU0#GUk_)Z$`=q{JfpyJ8bdOY(CPlL#9P-slV3
ztD2LT1R8Pzt>;GCh6-(HmllB5XvLT0$0sM|7L*p}rIx_A)a93!6qJ_4r(_m^x17Q%
zS5Si(lHT?5d?3vc(1uV@{}|UsQY`%<1>9Tt!0Tb)Yu%u$JBeQh3R~qFQdF8s`c6Ao
z+{Gs)7TJPUdx89>hlo>>OiapzFZ+ZW1&u&x`3dPjBL-5Sd|M?g*j<=V5%7@$;5q(M
za5oIrYk^3^x{=5`8K5>OLk@ZZMKgHj2vT`N=2XGc{KdtfnNCnm3OeKlR*yrJffoB9
zj!A|N>4HN9>J6l(8}#C3Xwt~cOUW$DOesywf%XW%moXb4sRva|5Z5a?fexVtxe(+M
zP|>Rg?mU8<c#uPR%2JC!=VO56z%E7EN&qqm)EWTy{czfkW;I9?)Oyek1gu>eBsGpj
zsS3$Osi1`?`nmZjnQ58egI8dl%&AmJss!zT0JTOE(~DA5L1$e+57Y?>EmlaaNX%6z
zD$PkPhQ%Dna1e$%7`e|1x+M@Qj2Vuw7y{`<4Rd58!0U3+ybSfOXI^qnX$mN)!9fXf
zF{BvK(?gla23Y_K)@&UGaL8h;%0#gb%`TAUyv*DJltzPstpc>%fz<598lVH5K}wM^
z#OLuvsX2+DZCCL*`OuLETlj8gSaTdY90F<zgZu(5x)5DnO%&^)IRe=(kP|_>(ja^B
zF|35Ng>g9uQutvp4%E?yXayxJ5Dzw>fUFpr#iFx8?J<x;FwFx`7=lLdqqD&?yV;<~
z0x1QJWoLtq7Xb-C4T{AU=O7Cq@ty`AF2*+U0a63Q$_h}^K*KCrT2Kz?+9;5<&~X=N
zc^)034wZ*^7RG@NRD(7i!K)C^5+l%zH&QY|)Gv^ZR(fhla(N1<MG6TB=oCC?F=sqz
zrxRjVCeji6;Oz&Hvo+&067y0r^Wev8LWb}V19)Klpw*7W(J|`Kkv`~Z&NBFNbEWt)
zC2dHA>%rD?XQn|<M?r`{&h-L$2t4tupai!SQgYcUD5)05t7gXMr^Tygsun{EG$mCH
zbWg!%ju6h&fjS17T4CnFIz-@}CnD%T2^=(L2MIDnQyi=f)EvipZYE?%5OQ87G%|IN
z4#>n`&_j|FqRs*(9jF-S%$(E`P(hiJSprV6(6%!;*mV@3o5CQ)4Wv5C%uCNn1()<z
z;O%lC(?A$%BB*Qz`vn>tNKzsB3h+h?xTFOgMxU5h2|7<FGc6NRXcX&#%3Db2fb_yT
za7uolW4AJMAuA@pHzPu;G|=f`5Ivv)Nl2QGha8tvk_p-g4$9A<g|ndkfMGmD0ccXY
z5>$i1T1lXdFd9m!6{*Qen$Thip*B4yKPfQ>v4^MtG!zew6ObXr8cCpm96ivGaYkwd
zEYZMr7($XKv<0OBa*ifUiETlS4rm-dGr0t^(*)vk(867ib3r$j#6y#yMgeTUHN5Ku
zQUa=8V)BsoWPrAb80cB*8Gw^Gq~KO4O3X{i&jqOkFCA70Pfg7>)CdJF@dd47hlK*@
zk}uGTD)0fnh}9~fTBSTSHCw?@PXT_g87Q<tbCU6iDVVqCfDCfUPljewkbdxrEXWyn
z2s1!23<@-b<YGeuBfX6L+*Hu+S3}rvdtwT7at5Rjyk-<Kn+iRR7-X}Nju9-JaVyd_
zG%(OnFa;@u1Tft3MW90$i&HVq^2O&WsGfMxelCb{Ae%v64uY7bkO(=q5G16m;Fyx4
zkf;EjQUuLgf!ai%a6?+=gXuG5D>R}Fb&Pb3V<E1G?bCzJBN}0k#o*NB{Ja!UM<ppI
zH5U=$ko!0wt_B4{Ze={guEZR080aYEpl#X!r3b|AW{4x?6d-4pgHAY41?9nH@Y+A<
z@@deeHu<2<0I3RE&=YftwP5E66+x^A1)8#gXI^nhYGMkwZ~-4SlvxbkgbLMNk_x)(
zuBaHU7d-q83PVUa2&$(*>rzrv6!P=Hr3%O-WDD}a`x6R^QW1BAL9`Yt=;}g_q6DW+
z&^eG`FMwAIf;>=^nx0sck^}1J<)<lRfC`|DR0XJa6f(ePu@-}(6twLY*~(1Nhy$oW
z2|lI?R4t`~6AMz5lb*idxgKGjMh;?;11K^<$qE{ssqrO6naSCe;7EmKZ%~MX(;6f(
z+A1hP5-g}~nW#{l3pyDNl&Fy=rNJ8)HI$M{LC0;S<y0!^D46Idzz(?p8JJTHnzsfU
zi=3DgN<fztf?Nn*vj@JV1RSzxSEhlZ5_~8sBvz2ZD5uyMw6y|sIyV-RVYxy9d={)D
z=u~J>*->l_N&wLFm5Wk~K|8fUBiW#XXJLnb6(d;!b~s9@0v5qyVNNk*avgf*3dA$X
z&`WthK@YYVnmj-WHU)GvAbNf^)_~_+ShT>S4pgnh=jIn-7Dr$=A-PfmRP2F@b7=Vv
zE<a&b1%X?~Mj8+rW(z#dor4t&4Ga|^vI<7f$c8PJ1$7~#HNf?Qj)I{9=;B1UgLM=v
zkom@71+kDN*PuR1szRaysCSx!Sac0;R2UjSn;5WwNA8J$_WFRGAFIyG1*s|xVRfE@
zt%ACRfq{vosd<`#u>le=Pq8#Hvam=tFf}zdGc_|cOENaJG{G)vk!)aLZenI?ZftI1
znr3EbW@2VyX<}h!X#&!3ZenI>Zeo^fW(pHCv@|g>OEWVDsW&$=vouRJGdD6YGc!vw
zH!?CXH!-s?votq0GB8UqGX?X~K<1fQ7#N#b7{JUmGcz<dHa9jiH8(Pc+6Hl*Ns@tq
zNs@tyNs@t~Nn)a58W@<HqUkpQxeH_i#8oEdNS+5XLFz4%4U!Q)GdD6bH8%s>Xbkg>
znT0_j$fqE?K{lI$!_6egz}O_ozzF09P`H51GP5u=0I4*yFh~W_m^NA@8z8v~Q{LRv
zBH6&w)X>}%WG2}CX=bU$Mo963Rn{We&={95Ow-Iwz;R$~mSk=T2@8v41011?@FB=0
zW=7_w<{%fFnj4v!nI(ht!$Kb9LNg1)L^BJ+B#>`$qy#fl<S>P$1VbYOb7Qj<Gefgv
zvt%O!vt&?u0L3zziDo7SX2xcQX2xa~;P^;3NHR+?w=_*di77*~WN=EfG&3_dHA^)E
zg+-cKnpv{BF<3m&G|j{Ul$t=Mn3<S@(v+d4iKVfniIJs+Ay|ziKEGO+Tbh^|nxul#
z061KrrkR_8d;p3qOB0Jk0}E4A%OnFML(5bX6T>7^;}mmaP{^1Wf%Jn|@U&wH3Pm#u
zqZBh!WFMPZ7@3<{7+IKE7$rem21;MhbY=`P1?CDf3u6P2jj4%7$z~>oCgz4|2FYd?
z#yD+6O07iMXaaH_HX9AhQjOA5Ez>NLlMRv$Q<AXT2+|GmBgp-zenia!pisfg2cR%E
zMb8DsmL{;YW@cfS0@4YJ4@8PJvoHdOE5uH7V>1gA3xp0MNL*MLnWBlKg}9l8Q7U>U
zlNYZjwxihsawGNQl?WTD9IwbWf{S$%%-95lw?(o+DpCn$Y?cNpnN2|?I4?uWCFFPo
z=`yo0vjD}jnFVgM4b3ra#8HkyQjn#&sZpvrFBhmAX{!XO#Eq1AxnOlCsKo@Hkt3oH
zj8@xf@^T>tDj;J#ph<M3<uRZ^yZCrbUM}dcAY@>G&~$`mfHxzP2!jX%2t19E3jTZP
zo`4t=0|N;2g9M>?TO)`8ZVc$Bq!#4lSLzj1B5RfkmkPf8Y3qJJCI$u&76Pe<;%$x2
zObiSV%^9$cB%1!V47uRrJ^7Q&*%=r>SOBUQL~Uz4$O6+32^b?Z-OTB7!O!onuS?Qp
zWB_3?kTxjZ)~LpVrW<~+Pk=Wo8%P-o0}I1{1_p*bmW&Jx3{y9Q#26SDru1+l%`8vp
z33axL0bLSY98*%7ks1R(V>brA{SdTE8GHsHXq37jC$%^R%7_P_Py}iQ$ACsaib|79
x@{3}?VKSwM7iEpWl+GRrh&SUghEb>VKpSG95SY@#0!nLBdRQUmloprj0RXY!1p)v7

diff --git a/examples/example_framework/instructor/cs102/Report2_handin_13_of_18.token b/examples/example_framework/instructor/cs102/Report2_handin_13_of_18.token
new file mode 100644
index 0000000000000000000000000000000000000000..303223eab586229ad1fd65b48a7b96322ded0274
GIT binary patch
literal 60507
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

literal 0
HcmV?d00001

diff --git a/examples/example_framework/instructor/cs102/Report2_handin_18_of_18.token b/examples/example_framework/instructor/cs102/Report2_handin_18_of_18.token
index 01a473c0bc4e8c0b536bb6c2b01d901ca33c5689..fe0c87cc2b34d3770b07ece28291836a66a6d7ed 100644
GIT binary patch
delta 9214
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
GrFsAsXa{Zp

delta 27029
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
DHviow

diff --git a/examples/example_framework/instructor/cs102/Report2_handin_28_of_28.token b/examples/example_framework/instructor/cs102/Report2_handin_28_of_28.token
deleted file mode 100644
index 4fe9c89fea3b77998c9201c910a729cc1eb16d89..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 81409
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
Pu|K7U6=F_laj6~vkj0d4

diff --git a/examples/example_framework/instructor/cs102/Report2_handin_5_of_18.token b/examples/example_framework/instructor/cs102/Report2_handin_5_of_18.token
deleted file mode 100644
index e22d430bac7ac0c21c0931fd87cd6871fa95b8c9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 78385
zcmZo*nYxDo0&1sd^stuXmn7y)@n-cFYMau-o|0OUn3+>NrFM#jHv>qXv3!a*R}V))
zesOVTQcfzElb=+Qn3<QFGR2#<hc&Y#H5a75hqWZLBqw!Bk6cJbszO?3QE`bvVQFe{
zNoIbYLRx;2LV0Rxwt}JFlu~cT+9?_tY~CCh?A{z19Nr8WoV8OjxO@15Q<L-aQWOe`
z@{@8>bElM+_OKV{mlh?bg3O0FhrKGZAT2W|b&AtU14f1bZ)O$|uwS0WNCp4BbWcEx
ziGcxx`571(l8X%ujPz4d3v%)+^$IG}it=+6z+!qusRj8(B}NLFxgc602*Ty%0xK!a
z%PdJRN=!+OFDS|^ODst>(#yz9NlDF%PcBMLEJ=+A*<TFPTbx=_S`ZIW50Z$7m`%{E
z^u&^k)S~#(f}H%s6qsQsg7GE!@yUs~1*OG#sU=YJit{oH3Q~*oKy-XcW)VyyjL*xJ
znWhjQpO=`M8XvD<Ypb9XAD^3;nHL|gWW~$H%cY>8pn%&F4QN1UXlg=~;_w_yosL3o
zW?p7mrL9|HPI0P^LVi+OX>oF5Nh(YrwIVgS6vl;_nU`4ra=Hd2YC%j}B|SZTaLg#_
zD5Rtom%s(}^z@5MN>ftvN{ZnMl5<iM^Ws6uGV>BasSB(+q^LAiM<KN$Ij1xw)izo^
zKE9wbIWajSH9lTlM?qanuOvS^H4nsuCkXXeO<pcU5|Rp+3cmbl>wZ5b1_lrof+wMj
z{M^*?{Gx0_y@JY=)HH>n)Uwo~;?($@%;FM_+)5CoX{Dg7m<9<oB_$;Y!#%SsHBTW?
z0i-}d9imWOp(wSav?#9_CZ3$1SDaZ~l9`vTke{Ydl98%VoS2)ckeZX43-Y!?W**Ew
zh5VwF)FM3vSG{yShy^GPi8j<R(lL(JR4C5KFU?7T+M^I{tYf5O7^|R>2(wZXsvGW3
zh>O6^)PNe90`r$9DA|BKotToMk*Je|=1~QRA4|&f74k}RlTwR{6%rB?6cY1N6cUmW
z6iPBOixtvJ^O8aF1anw%W^O@FCCq&#8L62?3dN<lRuDhgDZp$}uvJLZPEtU3W}<cy
z$W8bXIw+YdD+EBw5d}jlh47-xl2nC6gj32hGLthvHYp%E9pZq3qRhM!jWngm{L&(Y
zqSWHjoDxvX7%6Bg7%A8)RD+ynq+_I6s{~EaFbzTAWC4oEM1|tq#GD*(h$`v8;t!Hu
zqK$Nnbxd{4V?mh=DfPw51+Scb!d0G~fdPaC;HeK%pcuhQFnIA~q=#U_$^l3Qh87kG
zX@tu7jMSWh)S_Z|*_T?Dm{STW)gacyL$ezmBj8#?LsE-NoD)GgADq*46f!bXQhB+c
zrD{=PUP^v0D5{ck5{ru!!c$YT4K?7JG@<dWq@<*Pzs5kM08lzC0hJG+I4DldNrM>z
zig1uYF8RsDB}Jep0M$6))R&uDl98W+Fax9%T+V|F96fm6h6Q0_N(v+$fE0r4&`T^X
zPAw{NEi6sUan=CY42ped+~ZcHYiMAgqhJb(Wr%rj$3wH22FP$^58!hZR1Y`_L5u_0
z4DvE0)qxT>xR?P6DJwXpq$ngRfGcE$l6-Kf0tz>1#s_HyS&r&6WGggag$X$O^KwCA
zFc4au8)1({)an}%;tt@{0dX}b5OOQyA$BF^fWtsXA*UEQ9F)Q7K^>w^T_GhkIlm~e
zB)>=@HLtj|D76^u9eAOVS*(zkU!qV{nx~MT2bR);rr}~Oh2;F)g3^-IB8cT6e=93^
z<`tKuCZ>RuCg-Q5Dr6QT>n=$J)fz>`aJ}Hd3{);d%Yw{eg#u8LNCDYbo>`IsG6~s&
zd{E7<P*9Yr3$-3p7K4hBVg+4Yg-pFvJ+yMMJToT;?1ZA!^u(f+oYdlCP>GX~Uk)-_
z0qPxvjKqS1)VyL)gk~g`r6OAiDpA4pMJmWHMD2tW;iRW7Xte-|D`;((Qw&ZKppXPb
zB`8rrBQrI=q$o2vyAm9w$k7Q-X^^C7tDuxvoRU_Yn34vqB0&b_6f4*&XecF>mXxFx
zrR7vA=_r`!C>SE;u$*F0$qP0JIq@izlosTqYUC7aDrhQzQcY&D0yr!abIKDdi$M*^
zl+xr>a3B_Cre~Bui*uw<$tgBguvNfiGAtJ;XeuZuD>&v9=PQ8P0mar}Bf-fUWMn~V
za!Ij5W?n&Qi9%vgdMUW#MzREKJSfS)OA)XLR<9UoDrlm4Cb^_EF(;=|0TkF^i=hbu
zltfcf^*|*oywC*~YOwqYsSS*v%{5q@z@x%BSi#W15Zd}xFoMPitj!LJlxPibp{=7}
zXrQU1paIYSItmt=v7jLF%mcT#6cQDRGxO4OQc+v{h6W1BMX4#7CB@LdC`e4sj)zna
zVB^8AjRkptP;HK*nu2=GNCQ;NA}UkPSh-+_U7Pm=DKj#Fuo!w}3Td$G6;#3lF0VAV
zpi&{RSRt<fTKAPCCY9zSmZZWe1{fbIosw9RT9TOymxl4-CKgntWv1tVn(h!ED}d@_
zP#l8&3+Z`e<`shy4_r@vF`SuLlwOcnRE(%kiz^Y5AdBHDOEQX56H`Eyp0Ywpex7;>
z%*7#K35BF&Jy3B1X{#$_78jR-5)IT*C50)u3NU>s`3m4-0xXEEASpFDv9vf9VT>-=
z7?4lEjw}MT)u0a6bA)Dr0Fd*GG*VKFlZ!G7KrKL9bysL}L!lDVx&rmT^wf0}QVTM3
z^3!dVl$2a65_1c3QmqttxkB>6r6Q;$1qwG%7E?%6fHYJ<^1NJj3I&xV8Tok%iN(d4
z>3N`xXBeMS0FGF={`|b0N<_jmQphht;^`TJJb~LB1>HggBYYNt6+le!%P#>HHkri=
z5FZySq~xbUswZ#<5yjIAA^8dzqB;tt#i`()8r($??;0YdSY9r-%sfzupaZJ;KsF|p
zC}gG~n+~ee3KEOJ4cA14-29Z%oKyu3Q1(kqPu0{xs?tCa0ClcHQEFjnCa8jiX)Vb}
zEKz{!(g7Dey15GZ;HU(5>7jw2n^>uklnQcsT4|0RFPB?>kwRu(aY<rca;gr<Wsuqv
zY!#@F402s&o`Oq$GNh=~PtGp|^{1dV=|jA191p5Kb5cuE^$IE>PEJ5om;f>;5tam?
zy20+uQ%KH8%u7#INXaZpO)kkVssz=V>IfSlU6i8IJk-F}%~e3P0y<OxP9(*tsR|h-
zB?ZM+`uZvP$;EmQ@9X6krRy8(S?ZU9%0T_(+?1Tmyi~o6lH43#E+r);9Z*o^CW0!r
zcyK$)7M8X3f)dL^QY%V4QgaI2@{1s9G<mroSxPT4B_$qKooJ}*7OLwg<RuoR7u%}a
ztLrF~R2HP#7MB!(ddz8wr8y<Ge))N+Itri$zOA}HD9ytPO-OSCR<J8*r0S*XS%K57
zraDgRbc-|c%Tp^r#ZzjEx{iWEBDfQ0t5jT)Uj(Y`OH-9}6rk1x!`dn^4f-jm#hFFm
z)(EKOL%<qPM3<J3U`=9Pad~PHB*lZ<a8MJ9@mN%vms?trN|aBaExr6S1xVjcPft%1
z)E>-D%u4~6LLfWwSOsbyCg$W2vdgiwBtJK?Br_S5nZb=p1$bGfrx044npT>lP@a*R
zr;w7GRGOZinU}5yvXz$$)b@hKE_B2R)^pQ<<Q^S(83#=lg`j~tC>s(KP!80wP+n$w
z9w>TqGmAl~89den8_fYFi1?EHocPqDB8V8QNdZcg3bqQ+bPJ|HDYsYy+J?(agS!Tl
zWkCrQTm*si=@o*6Kuvg%Ftk$$Y8JxNt1YNeRjgNtXz*sHDJbbFfrdt4ijedn>(x;J
zdt1R)AsW=FFVh6&MTIhCoqELuIhiFIN_t9~u?QPdbHL>=$SfF!S*2jB05S{4g|~+@
z(-bliixW#qir`V81WlGH@sI=y4o)Rau-`#G&M($0NG!?F%Pa;Ji%@NPXqt+_x)7SM
z#1NA2ixM-7Qx#k*l2gIOw1$$Mf@@Jxevy>|sFRJ-DS^020c5q3jsnariAlvEH{o}T
zj)D@rYD=xiEH2SgaL!0g&W7YjXh{sI19Eb}gLI(55=ii7rYS(uA1L0@;v6agjd2JM
zt_zw_v1o(IK=nbnpo$$7d63*(tfNqpn3R(mpORRTs9>vrmVKc9Manj?2-X3OTb0Kb
z6y>KEr4|>*CnXlyf+7#%I%o>B1*bC|g|gJ5r2Jy|04UTYwon>s6s(X0RRqO)plk&b
zfhvHd0E7aVhz`V7TL`5C2^)|n31g5w@a&7s0jFSyNy-W(MU_^dmOZErFG@|%EG|g}
zkEaxuB*L5V%3#Z&?L$zj7Tk`34VS}A0x5#3$t=oA*2_svE&+AlvB+2ClxOCp7bDAn
z+oAadsd)vJ6*;g5ZFqiBc2a(RHnKvf6$OcTDWDO~Vub?e_zlFBU~`i5b3nFd=I6o3
z?Nd_0m1at2atX3&DJcrJ3P^GqIf=PRDT!7J(V)R%ke49Frh@VmxPbzyw?O3!wD5pP
zgGQgS4RsVW3Uw6XH9^HqYF=q>YEfcIDm0<#!IBqz=mVk?WCd8ak&XhW#75Oys0R|m
zq6MTaB_&!NW@>z9UP@|(daNFJ%pgT08`hmh*aFi6G7&?$5wzsSR1UKNVRoS&Xubib
z29Ws(#ULJj^(FZ^2;~N#<|8P#!HQOpejNpMkRnY5P$>-#CB2gT9IOsNjVD-W;4&3e
zwK}o|s8TSykdsa!IEyIQLOUpW<)HZ)Z3QKLB?WDm7$~3=v=x-}DsqY|pdD^yWJ5C3
z-~}<XQh*o>t7#GOkrEH;^?_>L6g?0tKD8n_HAe%gT(2ZQ9+b9WH84aUD7>I`1w;Ux
z24DuEs7H1bI6Z<AViBlKtzl?jV1VhK?9@sHTLtx^(!6+e?c$OmjciyTfh+;z%rpg%
zs?0nEh~qJw0#cQd5}ln|8LMCm9zEB9sEh`iYoH#h2kJkj7K8iyAk_$OVD%eF3Bo|s
zI7Id#NF4|#6{RM^N*82#(5Mfn;8CzufR#b0Aq!GaoROMZqF@UiA_6Ja1GSi8<8%;*
zf<iJmKSu`^4v11AB}FegwG!kpj8K7_t(TmdlcQ0TUv6utqmZ1RQ<|G+o1CAcZKw$e
z76n_7xybGY`3YoaQGPkL;shErn2`z6hsD~W{Bmt0Tvmf}Ce&^y1u_K@8pVlasj%dU
zRY7u2esL;1SYb*)$-1CK!57?z^~*1D%P-AK0XJztqcxz;GRPW8@PY=FjEqfST0s(^
znitj(z|stb1~ynFc-}`TpeVmAvp6$9FEIz!M##+112tbjia;1P5Tt=<Pe7A8R5mA7
z!4|2p0dWpU4$_-I)ejoE0?C0eL|#b&WE(_R8fat%I!dIMo?4O*8qH2CO3Y0y)_@5o
zmlhSJ=9Pd&H8eG&4P*5{Z8}g{12H5W#8t3`mn=z%#i<}!jkF@oXe(XgSWuA!A7D^|
zXhJH9z%9ID4X`n=w1VVZ@URDTJO|X-D^>svPlLuL6e?3o6p~U?^AuoBiPRK5g_u0h
zzz(!+0ckP9n`i|&sfop@;9(!opaIC?R-n)TSqH+<5VEtgQ_@j@I0)igBuP)mGyr%S
zH8(LYFSQ7iQY!OH6^ar;QlKfx%$!s`kh!p=0UzrIdjKQ~>136H+OisjFkdSxWGL7w
zRAm-uL~CS5tCy?C>L_GJtHV}DK)JB>5$ds!{zfLK>@0-j(P9lvSW6;9!IlzJApQoq
zC$B&+u{g1)D6vu_1DX<{{>g~8(lLnDQ2^0~P}(R~2joBSP=rEg9(1t-XdEJ_6ckt*
zpcWlyyiE@z2Abo8h{M7F)c1^!&&<m#iH`>l_UkBUfjV+J3R+s(<scSJB`8jcOAAtq
zG&J?#I?&Z3+!CBxSelwwl9`wTveYL(F(tJK*)hc>5HXnXAcv%<mVgw4W+DB+nF2Jj
zt^*z_2Z=d@W*%YcLCyjB3%oo6R8+v+hG7Uu6+$~Cpkca`6N^*hA(M(AGeDDW8Yt@Z
z;=wg<d_1f`N7WCpU9UL5s6-<>wbB-(7uifbaLWxEjUY>*Q3+B9(F+POklzXRU_hNK
zSpNjV29<`1IXRHtJ4SB>($RtSMPQ1+T?JVG11bpVen2@8ZJ=?d__UnFbX&+$jN;6k
z)Vva?5=0Pyd<4T_lTrFrV6Au*ql`Y_==~&RrpITbf)WqdC7{@cn3$Je4r<&($L;m<
z^2=eBO=g-x5?mKjm5^ARoS7M)1Svyo6<{O!dXRzr_%!gCorV%96S;#{41ve`@=9!#
zQu6b2LB$Kqr%4L73Q93~N_tuOnRyxt(K+C8h#XM4fNTe3ECMuqSgfH5YWe1*=4s^U
zfu^(zG&D68>=X=Q6`)B2sl5ZT1#APzA?aX;Kzs}-Et5dSyFwYL85$oCnj6f_&x?<T
z8k15I4>CS4UBOl%FTWgQR~l$`K|@J3MPD^nUo}!e)x%2F*Ge@Q<{^lwO2H+GMJ1^z
zRtg}4;l@CX1!WD$K$ISMz6s(UY(pea2SG<gpn9N!psqfs@efM8NYPTPplz$51nO&p
z>S?h3sQMtbLEQ<RasbVbfLvOvqoAY#n#<7D1tnQ<L_mhLi#3%%VGd4}ASrNahV(I%
zV18GIjtHhHfy<&41;`*uF?im@N&&ps12oQ!eGo?noCu&nglIh=bszJ56l@hN3?Lo=
zMGa^W-&O$>BYGeLmST&O^NT>OjOtp5QqU^0R8U(1Yat5m;e%2Ms4bWW>6Vrg*)0WW
zQ&uQcuvI98Sq>G7hb)UzuvGxB|AIIKLk=`ilmxD9Gz#_NAtT`N@j40~;5Bv7umI^o
zYn{R39Wq#^ZK$AV3m-&8N(&&J$@zIDnR%s1GvdXip!Ghs3XovY15u!AqS&n{KNrLR
z748~^NR}6ZQz^)k@Q!&rSO}62VZF~n9R)-e8!Qj&B!c_~S|I{zSH;I8!lDpj3}|p9
z57aqOf=!|-sAgIzs1_@!YUF7f>L@@QfaD@b>P6A6qmY`HVhc};Ag>qd!P*`QwhGW>
z0}+QcLeRwHK}(ow6_gd+!3z)-APFfG+Aade6Lhi`WQ;O=(o!!3DR`9?3gba5AL8>%
zOF+{+pvgyYivX08LHz)DAcC_ONCZ^WK}Rn@nG6)WAYr&dy^O@-c+fz2Y6{q-c<6Wv
z$Q7ZWhDZ>2C6*pafPmr)C47|?JQ9<$D-pqutQDNGk*gcf%zs8c>d>A7)Ci<NKsE!i
z$PH9hf@)!q<3JcRXJ)GaRtHL5koJ-WWGpbVq|(+1v<3{+vIK{(Em$GMKbm?)rFk0Q
z<cbvc%Ai#R3M80_*<=HU7IxFC6l@jXy(EzHmBF!;g{_AOjWSRr3Q`HekggUew}K)N
zxrhd5RoM6thC~)L4})|eWnhSLAcHZpF?47IBneRlvK2?l%Y;m{f~yJzWrbw$a5SjA
z1Brm=z#+@QN{c~V5(P+71I-E+r<OogO2JksAgqJ1GSk3)8IZeiCs(XKDh5@NpuS*c
zZYoOg4K^5&N+F&D2_`2i*eZZrj7>5#4bs#?PQzI31({R=TGt&9T7R9JSdy9&52`&t
z`9%*+NEtNI1fC((15Xiv)nyhdz?Fd$2dFbvsE}C#YF_Js#)pebb2SvA3ysi?1BG~@
z5jeMFk0^Kp2INSD$3Z->=N*$vGRsl}prh>?CAQc+q63LBTa?lOB?E!X17Yy^FDQF}
z+eNT}Waq?!l2Y)vwz7hYzn^-DLXfMkf0(O6h=*sef{&-4E4J_l6?xz>0S$Gy0qU9>
z(8e%?(gcs5JLi<<Wmm#%E3V8dNvr^62<QxZ3OGIHr$N_G!`Ebh91Oy!!2%kR$L1W6
zN)RR(<T%p^NH+)<8tH-hbEx$@NCF)f8ex>v3bqO%MaXq8My5qJL|Fkf8$qlEB`D9l
zOi<S^vkJ7J0kMz>J`W1=WpPF#IMRwzA&bYc=U9+^&`~4!JQ!#M05(<xl1B|;kO(xF
zLwiUBgAA%1(#s*J8e{>aLWd0QfcPMc=?su42t!rdDrp%TU`^N{MaUSUAx$Y9G+zt~
z*3875%qmc;7hWP)7eX52wcw>3a5dohIR(&^wgPA=QMp25o&tEN6xQekSwqOBsU$d3
zDI_CRp(qu!F#+U0&}tL#f=6%x4R<YgC0|Zvc4|(gLRw;G4tTr<<P;Dl<Qyf8fWwx9
zNGed1ll4kci*hsbK$AE)eOp{vtXEu;l3!Y)mzGmnoPj$}K_U#L1jEw6!<w5wnsQSW
zZ1W2Aia^7m8Vblg1YK~oqoV+u!vTjEHt$1RproLrrI4Fgp<$qt=cAyj0P1ssEGWqV
z?|{iG0j;joR?tuaA#DZF&^|~yH&qkduPg>{+JW|+AQB38wh9J%hVZTvcy%VI>IP5z
zfa(Tlcda0?64W#=hO5NmN?RobErmQEtO1X^HHuc1qMMIa9D(Xb1!aX`P>UcV6||lq
zH4kYQ6KqWrxJCpm4Fv5ENJ}kB%}Y*2YA-_4Ca9c4X`9+A6oY!jN?KZ43Wchfda9Y4
zNbUbDP$vMS2a-jRy@~E<qEjvQ`V?#lymkk-3t-hLNDA4_$gTjTB5*umE$kpk30=Q}
zwt|L&x}LfgBzY<1`RJPHg3?!Uv8JYiCbr}bwg%p@MCv?(%*NY)gao@Xtakx11H-Wp
zRS@SE7vpq+vI60Z49;dmx9&8c!}K}|upXNxXeCKWYA$G8KfWM8Gq0pr1KdY}kHDeu
z(ANflC1K-oXzK#Ni-|x3ebDMmM*&h%*+M9ccrA>N&H_!jRjZe)TS2Pm@>I}@X&nW`
z;I<Xq<vI%Lu<oV0l>*#j>X0y3w*qYhNlDGqQBa4uPu&V!a6lpvCJ0>>qY0YN1??S#
zSq<)3LkBiM=>ZaFCB>=9pbP{r^gu0DXsa4)kq6QWN)6zEBG_goT)Y!b5g;2ONekpr
z<eUV`3F><43b2w^0bJCYK#N;YcEFk&uw;Eu&lwWV7-<`1J*12Ya10Ix4`xB*2DB9r
zmh8ZpSOHuNxjB0JxVk_md_cM(Aq`?>rYS%I98#8JwF{)K7&;iIp#-TKz?#r%26SJ5
z^g)8D7_prIB&e)VUW~{epbdqPjiw5=3ebrd(6A-KIJlQUlkUZOpds?&pwc{q0$3^q
z%_gVjX%wXv>lK$KC#Mz{r=r>nS)C8A`%o1rXe+=)!HuF~kmo>U7)TwcT>@Iuq6rFM
zkO0C72uCQx^9?A&=ap!b7b`fx#ZdAhl6ygG%)km^V)zv1RzlhVAWa(O3R((qO$z#O
zn-nxP!Gp^1P_t7ofFuS3<iQM>R+wXvOjFQOFw`?ZF%p!)uo?)8PY?zVFh%DfN|$of
zG6lqiS*dOXcesv%Iw%hnt6M1)#v>IFka04k!l6(PrW-WF3Ei2D2z-<QGMGb=y<2Rk
zV5^V@&JOUQxx(r^ZNplmd;#8nlBT3kjj*j&zq%Y*2{b_)f^xc&o|2Y=MxGC(t~1nx
z(2%Vi+6u)+urYj4_(1fbb_)<g!>|=A(P@Z*L#XR?6w;J1+yk0hgm|7nP69^@G)cjN
z1sdZDxuDKHOi&Z%SfpSEB{PUBm>{T)sI1_eSX=@cQh_Xt1}&3>xCPeS%ZF?t2Q6BG
zGEwAVhG9e`?wK3-yaQ-R4t4qhY1RT_OA2WG736f}iUT^v4h@Oi%)HW)R8TFGQlhVK
z1|3j^HgQ3dM<oinpiVnTkrqt4Ag3q?RKS2&iYa93C=^30J5WiX1fHHK2B(T*aFLt|
z8p%d9j$vsLk`B_8oby53A0QJe+6oB&X)8b*;2`TXpbphhP=c_Oz;@{<C}}Hz<)Kd2
zQBZ=gK=MkOpbi}*EU=_7r4Z1Fk&=#rk`j3R4m8qWk)o-sq>mzjNFbm@2TID&S$xn4
zvpRUxM%_w51EwEQu7m1(=s5$RW&vm>1Dc<Uz+0n1gP)~2B`6CvL7@b}-~k=j5(?M|
z3ye?f-W=%C3HTP8tm6DUI0tDHPEwT-T(}@JIXefj9S5WevPK}OsvNYvSOa7TXfjPl
z0le27v{M?C8PZchyTU--H24O2(2)qBrfn*8$s>4RDLu6Wym&aN$_UiHDoD*!*VF);
zq@$ozUILmRD^^HDs)*C{Q0)cJ@_;6Wp*#E`D<g|FGII-H<G1jE6HpvM13ed%?Q;tt
z=>jqooD1rsfmS}iHfup`Ma+JIIx*F`dhy^H>G*i~Ug$IhTLq9XXyFEI8bnzkB@dLP
zp^KeUGK)ZyBpPYZJg2Nsl3x%HvMn(kG^GVwhzwH~4|PO*yavc*kly%s$V{n*x}Lgb
zv_ULrc>%;m9A<(#twfpwTKo*39nDMw`vyF0A0H3*E~vIw&jqhYQU?!ugD1eCfdtA4
z_<aQO28we*S|G+j{faWEhBniSYBou}(u)WAF4_QTZUx<1uunia4df<zL=Ad$BY6)R
znUHi0T6F^oG*~)?iWZj?r6$6}pofF#MP(MaWrFf5$P-Y7nfWkPAXDN&155GwNm;4M
z;94PH&#AH`wb;{NBeycX3Uoq6Vo4&@eh@dQG%XE0znY0q36%zCUNoCE5PEbJ)XUX1
zLF12AnFUBmL>c5EXby&&1ad8Cn6oH9zeESLb*WefygDDe<s`pYuRJj)TLU?Kkc@-r
z1$hpXdqH$DnmkBNW*XQ?z0|yvVvx%<l=KQJm0;xqNCh%Z1Em+FybE5w0C6730wi}M
z>ncOiQIwhkGD8Cv&FCf|HXgw8JF*9HSWuN&01Y{?19cS2z-1rE4e$~!S{)iE>Y%14
zB0fO9ZSW#e*vK4`4kW9=x{&yg#Dk<3CF6iqqlm!NgU<Q@RcMfNY(P~5ysU%eGEkHt
z#RqJq6neZ6Oc}5sh6QArCVI4ji~z+O^%4lYM##)T9svf$1PsHJ;D}4o5(`p{;4lxA
zs1-mP2k<00^&&`)Ohc|tVeW;|h`25TrJ%Gl@G@&yszEE1vH2nmCAN{Ai*RC^jsi}%
z;I|*qRDz@|P-23Xbg=D(u#JS&+nXC&44RyQ?{9^*Za|ZR;Qj<?e=u|*D0mT!0&Fuc
z$aSMTT1R)ZqV8zb&C7=k%Msct>5^Ft+Pnoi(gC~+OCc$-2;XMU#L|-doWvwT#)9{)
zg0^AiBqo7MX;8OA9bA_nwWA?tbfFx_1>MA>qmW-(QcwyxuL?BP04s1o?Oka9DbEK|
z6@V7Tf;zt7P4Rk|dnBQqCn9&LfyXrAi`1a2EFr4{;G@UjrX2dHF-#D$IukT=i(?rj
ztQbV4!S=!;4Zal)<TpJ;WRheeV&NrtR~^_WXzW3YOi0fdF+u|6+bU`0p{f9Hiw958
zmxAXsLET-D^C22weMIDC`%wML3W=bzJwS6&;Hgo_>@s9Z6g*20-V6(FI2G&Zflu53
znF~<{8Z7`V!-GUKbY2+Q8%V9N%rxj=BDi?W%uC5E%S<Uv%z-xhi@{4gk<^21fw*4D
zsZs%w5J6L>pb{5yq8ZpxI-phbp!JZMX_a6PfGYW7l!fyklR(u!xN8SZnwa*ZSq;(z
zwH~zI9&5h^NsVJsD(Juu&~g*~-29Zxw9M2L1%xFzl?q9fV3%g*DI}&BrGihaQ2^J5
zE+L`C3aJ%|xe7(4IjP04m;)IO!cYf;I*G8L0<8gs3L~t5NrLJdkUkJb4Rd58@Pszx
zU=vVKgM$*(V1k6co*v3PG{^!_ux9HhfI}9sp$F<V6#K9QZ(e3@0ZKbT!4`HxAEY`j
z*2smXQjlFR3^6^vC>6B3wk$P1CqEgS<gv88p<^AOb}z^;(4q@5m8OYeJr=t_PK;K^
zWh1!hi%SxcCt!{S(GbHxop`WDP?7?1U}FU!B`^%lUeVd0<`+mGrfJ~WKG0x%bT)WW
zHX9UCAf=#T>1@cdtvm&&L9y848)O+Ii9^PKu?=c~)WEPZ%rwvlik24CXwcpVkhRbu
z6=+!=tqzq2dlkxtB~8%&8hGUaS{nqaKadg#qGo}_X?ki&a(N1<`3VUI=-fGI31&QK
zLl0u(A$*Z7V!T3IK`A~XF)t-EPYGr}WLyq0DhJjNTBBGT4IR9LjuMo?*M}>`mnmsO
zqFN8WLK}1(BDgeziy#)_L1q_};C6yXvp`GXRg2?QGvo8q;#D(Miy;M>lBx!}mtYe>
z2uJEb9Rp3JF!NwNA8_Xq5pbY{ot+A+B*5hixMKj;2I`k5LAwD+!44Va(@QDMEdWgy
zff@ul3ZS7XNT}m4-XRGIQB#2u4O9$t+DmE)sCZ1tECHugXhRts<T?t_jZct523&@N
z&R@s@oumpn3<tSDgqjE{k-<KJ1_r8S@RLKq<!e6ZWU9PM&`B_vX_=6sq8MC|LA(Xh
z3+tyT`GL+I1D$LHD%gtib5j+d^)cx9M36%u!=8}z91mF(QIZK-6$8r2prx*$^k5hd
zQJ|v$jaFFO2()cQLkV;=sFEhMFhZzJ&&f|p%mHnKggC4KG_nqj6HxVBtdRs7r_lqA
z0%xRFz>*AX6CEURLU;FTfSjWVQ({|?qXU|Q&P*<W><fWd09tAba;{!+YDqlQr5XjW
z&BX9t7Dx#w=YTN85}2Don_eL$wL*SzOkPYLctv4I4B{B3;*!#|G=+@RqEyf+S;?ue
za}h9(-9g%&0Wt{G1O=Zl77rQcg^X4~hJ?W5u80jhpmv<5RZJcz9-)o_O|pZ}D}aO^
zL=O8vY-Ua>*gQ>$B4`?iWvW!r`3}VzDS0ppK$hee>*Z#rWEO#h;kqCTo>Q%$dnA-V
zr*49(P_QRJ6(^G0p>`oMC8%x!yFy1HM!h^KMqNh%JZhE(^%lrhG(SOdDLhy}8&h)&
zKz`25&$Cs^sme`Mf?AWA25KFFPG*2R&LuxDRS_hQ8q`qV!d(ONv@*D%1$Ll<twM5M
zyaqxEsIme3F}|QEH7&COQtZLyA>ji}N@$@9SELDYMob<e&Ov*+k?eqm0`|yNP*(7S
z94H1(Ww6t_AZJ3s=14$m{PPRIMGI0wQz%JHha8#*n#<OMxRqkhf+{!Ya6hg91;r<5
zWh=x+5D$cLq=%xU7+6t_sve{V8nWn#15{jSq~S>vAidbviK5y8EpJ1LK+V~beDJ0c
zg+zs<#1sWc-U25Lg~Srj_Aj)&1hNB!p=NkOPWT1Ix&r8AhQuQ9agIrlA{KELP<m<}
z_^^l+NXtGMv~Lx1hE+-`=tL}q%n}_1@Hvy^pyOUr^2_r;-c?9c$V)8;C3VooC{W@C
z*$u-GH>5(d1WXiE0D=c8A$|exmC;CpDguvkAwmNh(x8?KB)P`qDJdz%<fUhpfX~v^
zQ&3Y=0CAG@b8|CG6m)YHl>EWx&=f1dqzX!lGeB&Gg3JPVNtm8lqFr2^VWqF1o>}6M
zo>`KUm;~EGrI%7ts+W?jUs9Tpst;eutp~D3SGTkPysjJM8n8>06+ktEf*vf<L$W0(
zFU5e`XZb}X@Et910i>h<;9|v<#W8tcqcZbhW(Ajk79V^1!xbSND*_iQN`*5)i)q2<
z@*zYDQ*sfU%v^+8NZ`ZeGD}j6O7in_is2%Vx&^w<12NlNVWj|H4^;s^r4qKpTrVaM
zG>?y>w74`^qe3$#FE=eGKOeMP405`O0>l)sAXpw!4i$rsHc!bcichM9?Ay|C)&Vs&
zK?iQb%0*Bet6;0(jOb6mTb+<}qpSea0%^yBW&<GGAYtO5W6g45$r9Y62d!~}6_lC9
zplSxD7G^DEp%SPTO3Y48$t)_?fUAI53r(spQHUL&WCEVcgYG_q7OJ2^7j$$ncsDc5
z22lQh8Um_a5n6rn)6-LnG$7RuOf|>|*uXv57##)3lo3n;$T;xk3FsPPP`d`PpbX+>
zxSE`N&~{9S0U(P(5+EBO?EsK5Itsa|#l@h*{GfgSDFI2q)+pydCrDt*Fm1q408s+6
z2eNV*WE`^dmBG726u^=SkR8yVeoJ0zYD#JfxJe6L_hAe=E3F{0Br_>9C$ppyTB(3s
z2wIK^@(?5v;F~BkK)a}6R)HLV7L?FE<B%N|u)!|GZgYskLFR*;tOrpBS~CVd@eN6q
z&|Y+q(?G^RoRFGVl3E1c<DLxOGLi~9{4Bqy7}A8af}ETQYU`n#{R(dEA$c3@ta!+>
zaL}eR_!@B}x25K!>48=cWag!3<}27Lz)BkpXi*Gu7ii@#NFBt7NHGtRM5HDKTLow$
zg;@+LxH9vROhPNzG4!KqgoO)8S!S97YEYm%1LVMX(6LdV0tV`+)S@DUS3#yg#8Znv
zY7jnEP*%uI%>|v-n3128s*qWN&;)i6s>Pso7)qodR6{c^NE6KM&^WC?Kehmt?7*%9
zxjnU_BsDJuoQV+;0vbJm&Kg3N9zZu~BL!(nY7XQeVMHt{fHt<I6{V&slolv}dr}bZ
zAsh+`2her_P`UtF4^1WrC9p_G^*nm0gOd~_JVCw&xf~qmAn!wRTcBr2YA)(|3ZQMU
zF#m%W-9k5?K`aNYWlSpt4P`?rd{79L<bw(>1Be3DMdYB3rg|nu5Ghbg7}OvGosI?T
zR-qUUKRXM$2pB2}YRQ7K9q9BG(C~I@5onSLveq87kOn%k0?k{HHOdOM3Wf@x!YNe&
zDgeDmp%8jrxgIDGK(2?R0no-5c(#VAfgXPdEorcoEwFe11p#Q~B<PL<a8Sd-DYF>7
za}PacK#>Yl0zGOPvf9+gC<r=y2MIHf3sZC8)}$7ffI^>CQ^Dud!#oT!66{83H4SEC
zjt?R1SB56x<oqJg!Ku*5L5e}_5(oppHoyWEw4VYR2PiHgTn>XA4#M!z0Id%P)i$7{
zh&6=43ZUT&@-56laGVz>rlrQGr<OpLWP|fIEZrm9f|6<>83K7*DZ-Z^O-N;o9;QZw
zT4Z%#Gm%{eNeO=WMY&){L3%5oOar>h1akH&XcQ|4oIKH-3`&T$klmtaAp(|x#AHc+
z4#FuZnQ5Q}TA=e{l8QAHG(ZgK!7;GRs;QTjlUSk)YE{C{lz~ksX+q=_kjlKgBGBrw
zyaK)A!lDw8aiA8a0@xZYEd?V@aIY2=SRf2e8sIh5@XQZdwON!43lNYZ(BMN+u7aIH
zNq!ERuOR)GG$p_M5`|RIUVHG+7PwoRlUf8iY*?YXBtNItS|KmLC>Jyr4RQ!%dyYbR
zVzEMXUQuo>_Fhq%k}KrG6<tV&DigHa2ehxJSfLtZ3h02j%;FLa(5)Yc@B}#+>?=q#
zg0r3mEF_U*Ft<3}maxM?PJ<W@O0*C&eT)W6!cf4GD3H?wI504yxIhoI0SFY1C<y`-
z*GN*7M7nLQwL(g2Steu>1QOXuM%xbJXt%A^QK-(ta4cp*fYla5DM5hZ9JFp4RPg94
zXc(sIS}16P3m2RP5L6yoE+GmZ1x=z;8mL@LD%Jp54l05`*%X8!=?zpwfn*@b4KgPL
z32cxW5GJ;u0p(YadKiZ38+1iUK~XBKRDxCI;6#L6p&(aNDAgHsP#jiBgNi1Ec{q&&
zUB3js00p$P0<ugA)SAnLUK#-^xl@ZviWNY|@qmuH2F*95r<Q>4!b${hXi+H2OV@-p
z_CTQw>pz0nAcsJG1#PB){iFjuT^Q0$MDZc`Xk@?q5>L<yd(d40sgQ#NHIzW@Gstv5
zXaE%yuaFc0vI8UsH5qDM3ZiI7HXmI0fmElJ=3%J?;6)$EP*7W>0J`NbH75-*k`G&-
z0Xmlimi8fD!M>6M(iMcM0EG`|+aJu7Or$fokd9}Acn%bZ1<-vMpf)r@6y{H8qZ}at
zayobk2uwvh+@r`L0X7+OoT8nbodWnKEy%Q-6)0>$(l89kGce=eVFZ$fTLue<cnuf}
zk7cgVBkQ3{a}+f4@=H>!6hL<rfR7~vA4gbFln>qnmSU{{8XHt7Nv$Y>PRD5Ca3b7l
zSVjOj5!xDt_uZg;XnKTY4n+824tT>)!v>8d1VJufNCD*%&=^>5W`#mYetIhOLZQsO
z63}HpX=z9~0^|x1hJ>RMdho&m7Un`IAL>A~qbm^ZBxYC~RGQ|4u7@ZtPRv1XtAU&Z
zRRGy?iq@6`$%8P|*)cJBw$ujbK>@N3gdtW!4@xL0ssznYl|XJ90cBnVNN+hty&9aK
zL0yU37<JIHl_E$90UFjtoRMIqq@w^Ey9AkzjKMhtmTo{f1>C1XYCa<?hR*Di6eT97
zCM70kBO(J?6~ysyMS74U=s;)xY9QBim|B#m9lW;K!WUYJXc!=->`}5btUCwq06-HW
zzMdV1T3hh&BB+yuoE1SvBNv*WYhJ(+08R2KXekg9l1ec#dB`3?Hw8@-*g$+S3e%6n
zQm}rQ94JMAuO~}EN)lL02vAu7E!xo>1d3>IIt3+Ncv)-<vjS03*+PpZB&$fs<T&#%
zA{6P8z9816DS=Mef)()KSsIY{apc?-*d08%i6zMy3b5D%wMj~IO7s-KW`X-G7$rX_
zbRkw^%i@G16Qm!6!75=EgQ6W<L4ZB)fV6`!Ox6%f&H`7Iplx*EW(soMh?$xYiG{?J
z0CfO#=nu(BhM-&sDKrBEK$SjtoDn?Q2y+U^fzTug&G3-(@G#s9p2Gu~4Z`lwNl;is
zL+<R%gw2?Oq8xObuu~=Mz<wQtq<qkIe4xr4G*wcPng^;$L5n5fvo7FEdY}swz}LDY
z7Ause=H!4j=s>*)9_KAal)s6fg&V1P;942lZ~(2k0*&}<fbIlB^_fCaYEFK+rk;Xl
z9%P0VbOLq?XftC*Dx{qOpWIc*EVcp#9>}vG3^_&)W}GAVjvHt|Aw^b61!%{TMq(c5
zMmX?!G&!&kLYSPGlwXFNW+CU+ftIR*HNv=Q;BATEhB(9|T}U%cp`@Y&rQk*+8`Ka0
zt&!3Jsn&tr|Ej5@U;|6)&^%^`Vw4pmn5`5bGsB5F3XlK?&me(3pIDSxoS%mXf0RUl
zalZ+ADgia%At#wZy@I%}u_PZdCWh(-Q1K7343tb!<-iFPw4w<Ve-$MNPa+k=5buDz
z3X4mSIUtXemZU<HJJcNH#yTu-fFd5e>H#qu22}>3z>8oYUO}=HqzjT<z%her8)ljT
zMLf8wgUq}_j6+IOAo-$Plsir|ib2;92Bqfam!+aCyGLq#!jh4#LTUx5O;QpM711b0
zHXJkpj-?idq@7|!ph98+;x+J+1hC)GVx%awSVsXxQ%oMD^zjE>kDQtUKJ(c(6?_@7
z2I!V7SV%j7l|d#hAy$DRDjw9?El4a%g-;29ntVFoS?gk$RwOqeP5SFWZFI>@E`d$c
zL5$2xEyre@4y1|#U9^B~ayBUVK~ta_U>Aa<VP{7}+zGNC)HzN9EpG))X@klQkRS|a
zgHPc|(u<D=-w~af5+9Gy2{$x4MjcrJcvULsvITI?gWk-LT?|^y1mb`i9hrFw8X!%%
z;JvQ#@t{>%AU<gH6%<S$5zSbHRnWWu3U$yj0K%aF$}(X0DZmb2a4*U)EzrnKElC86
z+d{(_IaXm|2OdoaEhi1l12a?L2gE8toCG>qEE9CORy=rn66kIhaL*VbTLM046f|uG
znx+c@t#~Xh0G0Fkc?zI8BJcrfkO4)Ff}F(U)QtR`l++??1@MWHpqs5hQ-wv~tN37p
z6nLh@&<{9;otq1B3~Xf?Xnq4K0zUr&-UWvUIusP;7o--IR6@9*)CN`tE?{8c0!kI2
zhA24Sfu%tkmO&<?l_22!6%SRR5RDX(AR}@ic?fi-YdU1fYI+GM0Y<}is)MxaD5RG_
zPPvCjg2a%MAt*Jam%vtHM=L=mpFlTR#K(gU8-PvqE5*iw)WTM)XBLB_Ujt-1Xr>Lc
zT^@RjaC(W30;G9?=3r13@dUXL>T)#Sg8T$=9@xjQqcs#fHDL2qwjgQbeiSr4gM{@U
z;RH&sAcGtrW)!D_?)AeK89I<^4LMGbj8U+KNW+c8j8{<p!X2$3S-i0dQ2?p%pn;CG
zgB{{xkVjCw2-c(wcNB;VS{PfB3Z1?Or8kfu*j->BV)_px5Ahz%9FQ(hh63wC)&M#&
zBoBIZB)EA6%31Jzj|xSpIjLodd62Y+dN?3t)p2qvQe_0{AfekBpO}*aj<<MN6c=MS
z0+eb%kqJsT;1~jN&<j}TSO!Q+4`!4edXC1D-cU7w0|BXK1cg5cqpCtT7J3)}$ZxQ!
z4sx@v1}rSWr5~suge*;l9F7Vt17XYZArpm=c!&7_RPVrYJ@Q5sP?m@0EzG?&NRrUg
z$`zCqd=o1&b4zm-K+7T&$}>|+GC<A+`3-xmTa;RyTB4B*y7(L7B#=^2OlTD9KrYNm
z&MAh6G?v&vI*~g@9c)^RIxILqX2Ecw9#|4oJwq(Q?w(xGl1z={oMdD(pjiV}B&Da8
zz*WI~2TI!D`}r`E6%Ngysu7|V-Y5o}0U7=Q@8p2*>Vc?3N>!kp_n^ghu+co^IEyxj
z)r$w8?*Pi?pjCF!2GBSJg$0sU*vdNCK5>{7Qo@AqD*~B=v~CZ!n;)D{ApX|WQNUsV
zq`?46UohK1bFv`QG*HY2Uq7P>SyBVquw9&5fZ_~rGZ1Dzs38vB?*uYQ2eh35v|9`m
z8IZ^Y2PL>#hc~}KyH}E7_fRN6Co?dn(?ORVW#*-W0vCE;EaJKx*o}xVpTNQmIS@dV
z2E+-Vzy`~J?*Gz(l)um-5zB%~kV+j;4>23XcBC+XuE>D4@L@MeLN0|wiW%_M7m#Us
z==Os4{=m!B_>}zky!;aIW}x`YJiU~}5=8$8<n+umSQvrE<UnmeT<r#w4HJ-qJmDKG
zAc2nJ3$ztykOiDb>%^hgoq@f8)w9Ss6QUdBUa)#(ryy4Rg0l~76)|eSY2tG!$XKkd
z1xbLCbefW#LU>|PUS?i8{%bXL6slo~29}7x?#1rET2P2XFJ6W8V8K^9fs!U<g}$GE
z2so*L#ws%NK&#Y1;~zn(iN&Cc4M8&;poQcLNk#eDsd);ZErFmLMv6-kp?7fVL8}Ci
zKM)}ZYAKc!WhR#(6*LH0kXrOUH*)6=p%Q11fsBBRqJcC*atSD-g3kX1#}RDy3v^Vz
zA!;-SmF6Mt#8rR{-hgi$NGwW$ujB^L@nnF;@zWCXk}F|tage=`Vim3uVmU|xv|Jv1
zpbKb4IcO+J4>S%4zSN@#R9S%3fH0^|D%6RGHxA%cCsJsE)Ilu*9W92i1SEmwlu!j_
z1xJPS{QMM9zq+Cl-2DQV4d7FJL8+i5AI%Wr?z2GEgyge|5|HmO?j?Y1*vTxZM7}5h
z)e!JGUZ{thf_#O*x(Z+)qUr)2Gz~hSSOKgZR6c_=fFeB}>`~~j2xempoISt^1H70W
zHTpC2ApK{BEYKnTCHV@V6@lP8%0c_vpo{*>6D#%fkeY>%CQ&@NSOD$WtVOsK61NIO
zL@wfL-$Ky#r1;{*vQ&tXI9eT`8?O+GkP{RrAV9cK4`M)cj5;{cfP3SRa6`Bdq!5IW
zJrRw1)d*;FEX*uajc6GXWDW=uFsnL7JuhDY5?r9sP1Fbj<pWT<0`Iyo(krNpQMUpu
zk4FksXu}8D8sr3kTvmf(8@@jfG^_(Ihai*L$mIah5d{kf@IecZv!&643+5J3P=K&9
zIQxNG;2^(2@4G<D+>k;Jae_6dTFlIYRg}e`sV0yCkmIe<B%>kMqsC%26663_jp76;
zwqaGZ0%#ZrbPZuqr9yFOQf_8RNh-LH1P^|&!(rtS=x9n%Gou!K9$9f|5<&v*v|2p{
zH_+9Ah#CdtRuB)lW&pVf;$aXATkQZ6N2mbt@YN6?d4y^#i4q|RQi`Z4Ks*?RsKKil
z?9F)SG#9jhfz809rUy_s#YThGLzpq@&~{;rI#QDvWH-cK5DTmvV|WLuuNW4~NT!08
zjB6-?^0tzWf+12{2xJ<<+(PslG;HDN3T7ygCV_56N36_A0pE{~$9<p$2hRC<#hEFo
zpmWS~^UFXrD0rzgQt^rESP%~!5THR*cq;~K3E@CSEJMN*(3o>ph`<8dpQfM$?(h=h
zLD0^*g4Cjn#DZebI71P5I6FmwurI+jfez;eTSd@oU{!cLg?+A70XzT#%7mbS576n4
znMtK3sgT<jAWcB9!JsBVB53z@atY|@NDa_{SV2*KQesk0CFszX(wr3V2wPGra@z;w
z1=OH}43U7uVHi~&z6CrfF$Ha11GF0gjcQPt1!IB=RLF)g^ce)uBoegPQ&#W=U07C>
zp9HG9p<@zy3XTP!k@vikoJ!ESDCs2`pjEp`iA4&acuPrzjmDNG7G>s_7AvGBCYR(F
zfhvl8qzit)L*5{b#g(~9`8mbV)SCwyivT$kHo^g_ML-Q=&~z1~#|c&eA4LI$Ndfpc
zz#P4_%)As0B~?)02qX-`g`k}eNW;e<F;H(Qxde1CAJm^9K@iRa?Yo1TQlq4!P>@`r
zja~+1rYU5Cw1P`)n3W*Knc9ZfmL-DB1v>&%;UcPf=+IOl`Vt(7|6!w?InV+KT00|6
z20_$;M<YNDH1wGqlt_fkJz|Szh<m`7oM$G-C+FuCgSOLy21h{~NMh8Zb+u#d6*TOv
zz&Iu*MN1(jMo%FoCPiC8Q=tYXstppg2QBpkDUEhbja7)&){V7?DYTDKhuBn90Y0z-
z+`Y@pN!7q=Gibm-FU&Q_$v@Z?>i@(XP&5`*fa4}HCr1P1KZubKspzzv{KOKCMDS7B
z8Zqj6G3ua(K_aM<S4st!If<}~!SlfCK<O$GtR^Q1T76_f&iP5q$pJ;Aseu7f@_<xu
z2x~#nie7&z!7F(^1goIZ3fAq^QOE_&|3YWm6qR&9*+&Cp9n_o9Xim(@fn-ncV7da@
z-Ab?~7AV?b!|>1!SqZ3voLB@oDgkyqgi>xLsK)|7fJ;dSys!b~I4DrsgqaKS8K{Y;
z2b!=(-^&$WRGJ6sL8DHCAhbaDbAZb~Nc_O%zy~=S=oz93gAy9(cxU*ASg76lkU^M~
z63`$G$Pf?)%V9VlG_VF*M1<@mPym8-fH15S1Qk)X3MGXpxq2W%1KiC4&mQRIL1O@<
z9Nc(HEJE&CgM=Y=gYE_cbqpZB0L1~gBL$8Cj1WW$El>zU^nlC)Spk~o!SD)FiUX+w
z+X-5_mI#^!gD^7l()B_zKnox>N)n6GQ%fK|C@Mwv1Da+%h$E3a2{Ab{H#HtCl?pZ=
zap4&(_&^?nuEHou#qcDw5CfY9^DCMUF!D%nNq#{AsLhh7Pz++Grl6!wJq6^_8^vVI
zG)G1-LZ;G@0s`rFQ;=<-j$%PlViEY{g1i(+A_NJ5YI9JXk85BJq(-l_AO&=y3VNLZ
zGFT6+0D4<GA|=2h3M364;DiM|SO&a75VX+{b}tb^C$z8tHC3VaX(;GIoC^|yMJvoS
zP(&7iE-g&WNyA8|AiF`M1z2+i<oFL;#GXg+TBb};o5t1vRD>m#r9wJ?ItnSN#mSK5
z2rdD16!MbubBb*Z4GeS;4hMM*6DK7WL9gbujZv@80i9A;Tb-0xR9mAEU7ebfSWujr
zQfpHUzksSX78FGa$_k*R<C!J##mR{|skSL45Uy>EI^+oTVn|mXVLPbY2ag>TCFZ3=
zlC)l)t|9o`Z<qW$(5_&3f(I{I1fATFQ)#V`lbTqT3Od11A+bck(o$6+B|k4!p){`~
zGe-fg1KNs#d5?$;0#ZsKeV{0TPc4H)k#SN{YGO7lx?vKaq@Y)vlbTup&b)dlpanuO
zNf3>&8Y%69Oo1Mx0IJBq18v~jE@6i%#Ag=g<(GhkKx!fNly7A)Xuu1xSrse~9-#wE
zfP)yc4Xn7dC{>|6RROdI9kM$e6q1Q~mAUyvu(?4<qZiUbg-siRZyE(9?Br|>m>4WA
zgPM#=y3nhda}x_R5QijGfEG0*=B9$~uZ3wtI`|;BC|^SpR>?p!75GRXP?iC$_y_wg
z9yDSVpOTuEnU|UZy-6Ij-XR0#08qM0&H*3#j5PHGG90vaMK3cKau@?lIVkKw=ai?G
zWWb#VYK?#<&|p`QqZg%+bM})#=SzUJL){80kU)_DaxVCO%p&lr1dZbC%mP~@n0-o0
zO75T|?G-?MXHc^{5ptPk5y(=|T06*^Wa#9K9@x)%AeZN-fD8xOr=Xya05UW|p|~J5
z8FWryu|h_EIiyjOlUkOV1HKQgxFj(-8?=HCq*kFkBQqxzG~@@~9|Cb7JTrpaqNe~-
zXKSdCo0^zcte{k$0UF23$thOIO;yr?NE)FCS3+H`q>x&YtcT<}$2^79+=7xy@PScz
z>7WuD5=Ni{4b#9z6{MypK%ENe+@+>~#zB*_6*9p0CP5qqU%3YHi7n{76VRqkP$in2
z4XXS>p#iQo!OKvz!6rlWLYt6aotg?ZAk&LV6too#;c*FZkwT0*tW6B*OMxd1Kn)pC
z=tYAKj|EQ!Ld*q)6w(wfWTFmq1wbAsE=oXS4G=L6B;%m9oU%efZhi{LgamL8Eh!be
z<5{5`bmt(%-b~Ojj;YC@)!CpE%u|y=eLK*=ZGK*HeoiXH4ay23{x1F+C8^07CHZ-o
z*_u`gpdJHwBmy$VA0H1I1ct3*0wr(o3M9DS6~L(v*13T=7@qp!u1!fT0iEv-PJ$p;
zLu}7XQvj9eIcboVJ(4%|(!d8P<{-~ED=T<{%4bk%o(;N(1k~;>PpkwbOPKMXjss*B
zaz?5G<XjNw`4|ujL6NMi5D^h!1v-5RyqYvM7q*NwFJA%GxZ;w;lFVeN0pJ9xpsSEs
z0-gdwHV<SfXiNh<7@mk29RTGFggTJ7VZnsWr_r#W0L>nQ0}3>K49@rQ@z8(-T@48`
z2RsT=l$uupj%vNMc#wo%az0o!#7fZV5cw&oVAYDY3Nh+7khrmnQ3qd)T9RJ?$u$b4
z#igK?SrBa?zku|>TngT40TKXT9hg>{2O0RtFH%T^1`I5-Dl02EmgQ%rC?sbVC70$T
zf`+oviosoKuq#28Z8mf<ud;$dMoCFQv6a4lN`7*&9^|+Zz5JqdeIq?{{hZ9CqQs&~
zeORHJQIeaZT#}Kh3z};yDkw@VNi70hGzQz70XpyjDM-ORCXgJ&OVHe@qzA1@K)!)@
zvJsU5DBZ+^U8<2*1S?_{V6`LEDG(DC6hNoS>L|p65qQyTJZO*@HS;DGrGur4LFU0U
zDuXIX$d$<85<0V}7_@T-G#FfxS_B?Q28)9P5Gg4W8g8KFaUkcX!1E2vTxcN$a+fAJ
z%t5SZgILhYBv`^i%Cn$oR)$m)i6sijiN&d)Mlz`35Tg!G-=OqdlnT945p;GeWR(=y
zn=m^;hA4na(h~5NZ|FiQuo6(=r2(^72V6EmlQ2Y+0(6BLSSOmhAS&ReVP%#SLnfP0
zt%a$|EQZzp@b-g_0%(pcGcO&qZWgpkJtI{iF}b8PF$ZE0+{t>dv<oo|MnV$|Y;hgT
zd{79%*KdK=UxI3BxUb;u1&Kn|n}as6!yFAY6C??;6qMK$N-DvfCg_BvV_qfvj45bp
z(@{uI2B`)$1JX0gQcDX;GEzZ#5I#}{POnJG4tmQRSQu8TfyxF2(A8R?GzBdyAkG4v
z@d#>UftBl}#e?{Xu%-ye9?%*YP$#0YAQjs9vQjXBdKn}S(u_Q)2NDCNs`O+~0*D7E
zprX{GVhxZR5P1q5`yjJ5KpHebl{$z45<yD~nQ5SQ253AMtW-w<v}`dyB^A745fqqU
z%^=g!G=kz1n`WpNQT2lak!u=|W*7!JtQb}rf;dp`!{lK!Gy{TEfDeyGv<_e@5Hw0+
z00~0{z?wms7IYCsX<jn)I#!TBLCFBxd`DXM3@e>dQqvMkb4oyE5J(}o_E12&+#b<>
z4@rg2KtryjhlUz-`4}WsK*q8ZY!!4thq-t-CTCZ|Dn`)YID9$_q7K?S!Wi{{uayJ&
z50rq>#<jrL#pFV|mqnS7qv?>AA0Q`|V)Ro=2<e6R17tC%MAL&`Gze{NL8L)$0*?T?
z78T_eK_|c!bnU=}6*OExMu5*j1DlhQUjm+C1am+hc0}222^qnMNP_Od$%UNjm6Hd{
zh;Y+jOXfgoL8VG^GNeZfQUJn8CZS%232`|@2}rYEa&kPppQ-`%C#2(!luW@Y5nlBH
z9iI`S?iv*29|S7Kz|!DtSD;lPAj3fzEQ+BCbWbH*59pjq@STgGGzZcH3ev<B=vHo!
z0Xhnxex?p+8U-^#;oVTwGznR$rKy*glH!(_nNwPns(~;B5da|L@p~Vl7V0LLQ6Oyt
z>MBq;fiNOjk&=>>KoNjEnx?FPIH(AeK2Z`b$R3b~^&lArk{&f;)ZJp#k&*{eYJ;i+
zA1nt-wJ1Rt47slpJm>%kLM!-k9z9SK0z51LKFJDeHiBj2#FP}6QJ{!LatXw(5NlH5
zg)W*RWd*_pLA(UHoE20%78jR7m#jnPOd<Vt(BOebW=cvb@+d1rD>!yQLxT`AFhUig
z3Y<MOkS;HVgcm5-AqucvUW~2=+%E)GvdAN~AR|Cn8C|sow1x){*cE3c<)jYa<;CcZ
zgI``8qh1c`W`F}5auOJ*n1da00Fr{SLE?}D&{I=D;&AW9K<_XH2|^+Pq!c#O4H5-i
zB?q<veMgffNF{i%5~K{Q1k6KP8Uu+Q@D;hBlaFAxw}Xe)K!k=SsDDvZ0=l~$;Y)D(
zL@9E?{RrgZ4@DNFUPl2|EQ6*CkV`?FBi*10E|6lRR0m267_J2wuZLPept={N3o*uv
zIou4E2eskACV>J9ax52Q+Zw{(Aa&5R4w~UWR|vXN6EZyqzf>7)AfB6*QO#C{-CT`&
z_yx#Xlq-9Y=9wUJ(9{Cz<iHXXs>x`VFhipPax65sEOm83T8arW6#cqoRP#V85Em^g
z;J#@YRU0($K=mtfVgYA;P+tY9Ohry1h@uXm60J1MQh<)lgU)XWDn;6?3627gYS2Z@
zpgTH{LJz*YAQ&|F1)8}5bvi+cL5G7QmB`AVMGfUB+YwP3cA)S8&GsR+HT59vLYO~6
zDi8?<G#Um<Lg}d`E~&-I(1stlf=99yMLmK8St_6bo-qeqHi^>;ut$nB@{3R`0rdu*
zz`KON-E452fV{2&TD%DEkb&3QAurre2De}IlJiUR!0R?am0K~WVg&gLgu#J~a3Lh)
zfcAfYuH`IL&D2xP)KpL{R#H$^(8vRg8R{rxK`4YKB#&dPYBEIH<&Dxv2U(6(IgnbG
zfZd&(tYC{i6J279>IT@1Ggt${%@B`555hs7qlKhKP?H8F(IERVr#Ka@WCKS9I1lKd
zTY;r)K`mB5sR><^rY7PJcjQC@_C!1=b%5&I)Z!ADB&d-HSzZ}j0-Bivy9GHX!onA{
z+Nun+0tS?8opTaF<qKp#51N<2^U(3AVX0uN06mlw6nh|yHc^R~!2s1@g(!tF_B}Po
zN?>^lK1QL3Y6AF90+6jBjAa2INEk&2C>`6B=0OIWK%u6m5DYp&H7~OSyy{f1pwdnW
z7K9+(Agru_VFviTRd5`G)=h$z6M#w?)DjYVTErHLuoQ`64OuA><Xmu)09&369%=!J
zfm1_KYH>+^Q7TG$P*7F~Ely2=jIx6^9D<6EQpidE;P65CiR1(W@(y^RHq=G1<D*Mb
zk;@y9^WZAs%PSxvq}To6I02`1a5DlFGdc>Xc`3FSrxz(hXFY5ckV_<xYasCrb~)TV
zpcWL;{57bK!E_u(aRxFC;v&#h-SDOaIJ<*x7J>&1$eo&?Yqm8I;SJIZ!qBU^L2W}w
zsDRWdDL^NVHNp3OLnIXJY!wXj5Z8Z$m$@TW7H8%uKo(Bx!IsxSTMfv)FOZG!y3|%l
zK}#Xe2iznCS10feE@**GY7uO(CLVMfM`})<OKNg{QDRAc5p-M!+xhmeZHD0b6;$Rx
zcMiafhWDLI^YT*R!`9#wjJo>@&w09F$6~V`<UJ6EbPI7Dg$?VC!N+%?HbFGmLMYI+
zOxfk2F==q{fD8q@F*h+gH3&Qu1x|*@MJ_1G6{RMEjx`0xJj5UcW$^mS%KTDAMC3!I
zY!wiVT`ZCq;jRJEhg3H~$Kk;CK@K<u52ZmBLPjR^Kno(E4HwV?NKgfY*uDWO4naOE
zF9O{vQKXTUpAYjCNH{k!Ju?}@tDq)05fj~DXCX>=&^$DJk{cAFu#^aDW`g)2oR*&t
zu?`X-VEgsr<5TjJ<KsbN!uk0y9z+2&1i<P*egUTq(6}V{5(HQhhO8@yhk8;+As!Tu
z@!6@BItoEP`Jky6us$p!mEg*xq_hAu0U7U{n4FR7nU@ASWgQ`*p#&FK(ou+3%E&A!
z2JKG=ZOBT6uo5eZGpj&T$x5Ie0GJ&MPFSEY2Djos0j~oZVNXqgj)y@jXeA{j1z%7s
zKzCL^{Q&VjY*H#cvm~PweD8%mWNJ!38A>PR<R|HaW<>RUGL!V-0R!590j^)+6V160
zH=-=<0J#ooA2?EU6rgzp+bP$elOLd`D1&_zpP8ZoD$F#Lz+5GyP}cxuEFA?%27~$<
zw)z2-2vC-+fOUh`g_a~{<`rvXr&hueC`c&?gJ-QEi35i-A)y6Q3&N0e2{E^zv;<@%
zct?6E^0_xy8XPctkoBjhg7stONw8vwz0foY4M|WcMJgtXOF)fu<N<Gp2+Wh91A~%5
zS7||-ZQvbXpmB5P1`o*5M&PQy7&J$$P+FW?qzfB%03GiG(hOb{0h(-vb(@MoYs52)
z!3Qp<78NUilRroj94gQ;a>zC#Xo>($<prfCrs(G9<$zW{Bxk^u$v~7D!PJ4<97Ve2
zMWB5rd5}~K@-rypv2US<jnG3Hhv<8|p`iy|lmaRTApI)n5^T`!WzeS40uAuGTO?%)
ziqIefMWq5n0_pe>Xx9_FlOS8a(RP`GjmR%80fi{kw~z=1c?~QH4m~_lut0)^2PlJK
z^!q@`3l{qzlc7sT!TkW=)RK(+6qo#D&=6^6fd+H~G-g;J9Hy*L3|d$TtM)LgLrS{f
zQ73q_9PAm;+2<Mx3gCRD2N40~YfyV1tU5*=v?CTe;ely3^1-{X;vTFI$yR6tgN0!M
zgXOdmusqlu$bkdZ3<@(nOzYvsfi+_sNCDbW29^OE3o8Sl1urP*!Nx+;cRZ-10IS0p
z4B#veF4jSMl@&0PmNMwTG0-V6p#|X17;;*N4Do@I5hU@!4FV++P&B|w0<a^H!vI=b
zg2hq0WH2qDWs3Plkd>K;3K=E~8jb?Z*&%rx<N=81VMEV)2-OPJNF$TT5rAnlECRrO
z0Ie?pwFx1K80=igxI9Dv*-PMc-`ED2AxBq%Ixi4S$ej)73QbU78KG4{R{?1OIe45L
zYzCxkK=Lvq{K0Z49t2I47o+U8gxUl18zQVA`2&<t2xS;hBMdXSqUIJz_=CI}pH`X&
z3VzVRakh~2!a$aSFhmh(RS2|T($I_si$UB1%B!*9{SNRI84A#308xO$v5?(opiv3P
zs#kDggp?`D3L&5qj53QAax1}SU4h4(AS)I06oT^=$}<v6KvU$P3&j$XKpSi`OY9+f
zLCFAOZzklP6y!JujqZS*j+Bhzkqc~)e?b`D#6~I-{SrZUVu55q7@8<Gl67*yE(eK$
z>@LmAEG&iYzXi2VK-M8UA=>~}`oUd^R8T=$ILIjuwBRxmw15D9?G|M04Zhw1WHAUs
zv}PNChKDkBkjw;0Lh~=kG0?5OMtIvhAU)8Pwjd@5Lp_|GS_w;)An(GvI3T0(Hr`;h
z16&7sLk|*vAge%T>BWO~!9xm0<nRE?L4z(YCAA_I)Kfs3>_=IY0WlKn&eS~6dR&Nk
z@u`q&BSB^%#|<=;kmsV&3OlgHIEp&39FYYbR4sTPEwb;3bb%2*Cm50922gVW)Ybzz
z0x7h>?gP~b&>|GvkAa3Vc=<kZuz`Y6FCJR}Bc(!U@`0#Dl=xtaKr3S)O=PGQC^-rm
zXP{yPq+3S;>=;N*h*Y?O<OsR~q6p1;BhWc>pdt)xCQ9lCI}edlK-$6flk0s@Ce6%)
z7LRDoz_b`CkJ8j;BV?-~S9^f33vq_Vei~>=o|S@QUZsvgZgD!8rC_T7KB5$Jbx0<-
zEeNW9(91%k<N!_RAa6knBt$4@rXU9|s6c>@fkDqT(NO@e&I0WXR{-^ZK|_w&sg+7P
z3YnnOiXq7uqz!C3l7BS79)XToK$8`yca@m}+Wk>fT%rl~ACfb{CO}n!5+Fh)a*#n4
zfDd2-=|FZqG~L6FT7jL<16|GrO8IbYh_Xgg0o1KkLfj~+uLPP{1BEGa%>^1Dh>us$
zR#4I_$j*U}JA=zRqyrw%oumv}KnCu~froOytCbZrGWAmRAQda<C{oZSkdl1liJxSU
zJ7IMfvX7C13mU61&qA(8gz;cr2OFe`97dqHLcT5$hYnbfgOuZ)CV;pOR7fI~4<KFO
zvrO{~Qu8#xjsSHrK)3mVk1<8Q%NL{;gdsOyLay=!g(4z`po!K9bpJNYUCIhhr6r)l
z*um@16LX3|N4kQRk|t-Qf{u31$xO~H$$?!t2#zJBIu2w$a-hJ6%fV$3tfvXy7!MjF
zQb^1JZH}u1-}nkTY9~AuvPu=SL<3|jXjyhic_zv+bRa)L5+ov%fW(v)FgCD(Pn$`B
z^sPbL8<I1?*A&5QElw@bQwWDP!_xCXSuj7(9(-pp$UqPV2Qh&J1M9FUfvf`=0`V+p
ztUyUe0c-+l@`5D|XblcgK{%H2-qD+qSds`@KAxGJos)`s$1KPnFbs+yj06C>KPIsx
z5fPlAkpMLJpq5^W3Sj%dxd{|k;A4)FJPX+j1itbUG?oTS5|C&EuYU%mH&E&UjW7nK
zre}igGtA6OhYy}>q~#Z-W~L)X(_v=7N8&(U3Igx5DON~SNX{>)1nreU*QNuF_sn92
z%#_r;lFZ~p@D}ydveY8z8J{47$`dO!v_S3nisaOS5(RL&2aWXRrGO0AOM#8)gEl~d
zj|T;9Pk;;r<>VwLq2Hxg09xIgUs?hkA%eRZ<m0^5awK1t=AoR32Rg4HCkJFWiZaOV
z9;8&Htl(Oa2;TaUlbM~Wke`#H0CywkX4DeUkQS&Pl%1MdP^<ttJ2)E@Jm5|TR3&Ju
z4N{*k2s|{18tCBFx!@U;#Danx@Igu_k)opjwjR`D1-ThL@WH#T@>4Vw%JV@dD1fgA
z0d2)Yq_iNUptS|vtqczu&_Ei<@d&p=oei2;0Yw=ID=P%)<rih9XM(OXv;`+DkT4i4
zE97RTXOw`>@&cbfj%pY<{!2h-S|Lq1K+|UsC~<<!K#l|W<`*o%1eb$&3{4wiP#!gK
zQAg;N6*ROo!&AY<Zc-}vGD~n|DP>fqXQt+5CM!YW71?lw;*!jq9EHqc@LtH`%=Em(
zlG377UC<rvsYRgUMsyUwRbpj+DWYHnonZz_vC#9K5*3O-J0o*b6+kB>gAz$WB4|l@
zNorBCo`PF`kpgHx9ps*D@HW7V#N_PE;tU1Ic8<){Vm&>*q*Cz7wcs;Elfl~#K$!zP
z2AWuuUJAMk2-MdF6$UyA#rdF{N7akLQ$C3bNtvMiU&W=+y-UzYK=vmnK0t+uf~^A1
z@&Y6eZgPY27$m<Ghi8^#z!MZ`5DBy{89F<MzdXswfo_8V?-F$O2?k$<r{Lo1>>uP9
z;vWP`RV5iv7lV>Yeko|dZhmnIA|Ik`LqO=v1s%`<iUS3uB1FN5(57Uqke`QSGU%iZ
zkgpX$8>8TP07bKsLRn@as4)ade<1gObYLr2!Fi-4Gd~Z-b<n*E&;}jClpIjU6qGEW
zIT<ZPp-02#7s1Y!hJ-Kj90jQBp9bpsqwM(txe!vLK&=F|A&bE`SV6{U(?G39Wd)D?
za!|PfTFC<%mWM1Dgdai;JBS2cyn-ytO{`2xg+@B4gaaLERt(B&naL&b@p|CyQ8CKE
z15z^#RWqn*1rKo4rQ9G7fHuvcScY7d*&-qottJI&h4>xSHl)%Wqy&U3GgEU?KsPHP
z`3RI3Ko}Zjd8N4pm7vs^R{))FE=f!(1s%Two798xq0*pT@1Ti%m^6$J-=tDdnU<NJ
zlUf27fK5sx*$Ry{xDwFi=}-qH7Nr*?78N6IUI*Xw4wVF14A%rdBSAqKwgC{T402|I
zLQ=9Gs5r{a%*#xxQ~(`N4Vp`VssSAffzX(e51pGSOv#1$46Gt4H94`gI2B=zF4!E9
zU%<`;-H!}&vYsQfs0sjiphyF0M%Xq+-4&E{5=&A+jbqRzxPttm5<SqO`P72UocwfK
zB_$=-ibT-OXI2U^c_EMsk3gvwG&Bh=MiQY*4?yxUd3FkrxkrV>Vo=EqDk2TzQwqRS
zj&S|p5)?M^qhJJDLW<yl4(PyVj)HC>Xk`*^i@*vXrugNTq(U}$LzeFqE5NUH0WS(d
z@wGxoz5<4*4ropdeBB1zLdZ%B!+5Y-sK?wub#+dq4yf=4*$5g0O+z*vR8N4;l?O#x
zB6O3pf(Ga$UeImqI^bP!pvnbeIP_96g(Aq!Ud0M9t)NOv0jf&}R5mK;<|^caH>5z;
z309V5<mZ7h7idphX>n>=X^vh@9;m)U><j~~8qG+BMw<e-xeIDY<|(-3Cxa`sV*TX&
z(xT$jc&JVK5LX$4*DiyOBhV|Tgg7|?Rbc|in~AU_0M!k4XP!cG2I#y4=<Z(7W!)wD
z3Nh*kD-*zBP*j?S8rr(K3aEDIK^z0VKL&KtAZ!{OeQ&0*o~1r`SFnC^ZVIUU)dTI!
zjLB0{Qqlp1Rc<2am?6kWk1ag21SOV(R;hTT<`lT)7eUl$#^gbA6=<7BJgnx|h*8%q
z1m%=G(1f;ajJiFD1KJh_T1En@Gr-%Nz+-Yc3ZPr5ZDZ8^LG!1nusjEDSin=hMyg)A
zo)tLtYJ&GX;ILE|v|tf-R|?2Z(0;+p{5)GF@Jw)gNl__iwE@h^V9*wMP||{F(N9S&
z&MZnz0nH_p=9Cb$3O1iif>nv&OK2eJAGF_10cr;5Fbtf5sSCNegh*>3D_%g^2~zEV
zhrE*Wb8{0xy&Le>@sw1&egmEG06OVNT}J_b2s)OQ<mZBRSA%vQD}b~i4wuyfEwTgM
zLRk*l%$|~(RGOX+Iv@vZGo-@^i|+WMR8Z*}UtCfO>a%G;xH|BPADU7MK?_8oY)FVe
zIUtKcw={xg>vR+{)ARC+QsbecY~Vw+A!|pVs|!o=bK+BriXdXJW+5o0g8I|onm`Yn
zzCh_2zDgLhq6~WTHYg{9Yy#&>kUqUakPxU}3=&4F{^1GO7QE9~uMpAF0-Y_W2R{4?
zrU*$Ns4V~!)=>a^8?@&QbQV(?<Zg&EP!kKL1Tyijp`@pTe02zxPCZNmXfI7(3H+7@
za5EZYCsNA@76nSs^a(re862ESkiE$uAH&8rpr=hkw1E#11D#j^Jv9<?xHdu)mKZ|v
zJ;tz(odS4oAO54Em2?zfZh;*Qjn^?c3QF)A4?HlVr{J8Cnw$;En$Q9ovc(vB+B0ay
zAS43ecT9rf9WBlw2~z<Y;}9NP7c`+_(FT)&>VtAY%@$C^K(aLG&Lq&-Lp*pe##R9>
z`(S1pSbRehKFR`bP~<^e2TftN;B*Gty9qxx2<j4BC=E3VR$_vxhhjbCVi&3amTV9T
zU?MsYTWui}!NZ3@-iKk3J@K&Yi_8J1U`Qw{D}c_s1dS$us&?ca7w8-aSQi2^s|{^h
zf*QQwCJSged|6@%v@?dHCbK9fSuZCw8Pwl~&KaY~SLBpu=B1;^fCdB=Km)f0l@&R#
zMrwF|QFc;(KJ+$96e9`}^HLIvL2dhj6qsK?J_nnFWepy5-U&1lhO9gVG?jrQ2cKMw
z2Cc0F83?fzyj2w3ZUN;~Q27EqYY!p~>RV+S>L_Rw>L@@ikVpj|2?#nw3!1TD$qRm~
z6GSJ-3b1Y?9R*N{4JxV-dZ7mb!^&NR7Lc}-l;{|Bn6dGhpt;f*^;p=p?QBD6p9za5
zkVTjpjBsm!*@9#~<X~akT0nLnDF<=ECluq>QIem7q`?4mS^_BF!6s`#CV)DfU}dl~
z5W#1p=EIJcMD;3aoWa5cr@5%gLG!PmN&y@xdZ=<RFCZtRLU4uwuaW@O&ft3xK=U@>
zc^zmH0L|ur#Plk1iYuU7u#}Mv!Mu<FVk~C-r^JKi20(RiiXMmsx`Q<}M+2%{uOuIQ
zA_Zv97nD*U;R5mwwB~>afTZ9CfpP|1J+h;~sS}heAqR~a8W<R0x(77v2|944s5CD=
zMqL}U6g?XjOdxB(I5Q12vkNi`Vk?GYK&nzwV3W1rp%sYA=ood7$p)bG0c!Q87Q-)`
zMR*0P|4@xYjYni(g4BU9(wYdAr~%DIf{G#qTLoCD1P?8cKJe8D#TluopjAgO#d?X!
zC7ER?B_t>`lk;=HbIhQSK;-q56xg+E7~ujk4{Wv`=;kVoqWp4OLmh?W{G8I<Jlo{_
z9Bo5Q$k>g7EhvQ1{ROhKD8C$A0Rs(f%m@Yf35&Hw`Q_S1xU2@{P^jHd3S<g6WI#cu
z2b!^jB~h#jP)-$u2S4b5tAY{*U+@`Be)%PCplc(+jT}(%58GD-Ne7@IIU{2eWYa-)
zF|28TrC|yUY>-PKJpiSEqWrSVV$j;y99XL%Gau!iUf8ISMhU!y0Zr^6W59x-1!QnZ
zh;u-45GzpiBaa9|<dqZ<&8IZbAPjU!2{aH09!mvJj~9aue*qup1zHdeI~YkrQ#0By
zRu9x22bDJvtJ6VTr2ASxxA=i%L8tV9FTnv7OYo5hXwigJ8iCt<#TsB^U}**69VPJi
zNM(L0Xym83G^eCk0X&-lD!nUHOBBGDp2Hd!pqb1V$Pf;6fEUt;gtyuXa#9nEQ$geI
z;DHH{%Tcbzg$9wGot=`70>niSPa-+UGY_n{I59UBbgWxmY7r=@fCl=D5<ya##o+M@
zJxDM^v=@P=%b>kk@WFYIepe}|d8<(f^R}`=hJvj^Rc3)kv_@t$c++>Rjsl1U-;Jvd
z6+rCqj)inYz{|V}Az8IpLlf4-$WXAQ+$@MEKyJ$`&`T^%EGkN@)X0D)OQ_#6qOEic
zVs#Wiv>}u>iq!$-4#+}*P}nv%(BK6vw%ri1Mhv#DJvg<n6f`H9m;+kx37S4mEka%5
z4iSSz3}|X2Jr%xX6||TSa=-~>eJE&!Jb1k<Og$*MfJPs|=ZAsH4Vc?73<0S^Xomze
zOgCsg2YQSm$P93ug`yrYx}Kd{iKw<<`XRRK73UX$_W;;}^dg(72X5CvqY<PD8kHb*
z5WS$-1Nog`2M5&mf^}aYY*5h%8VUfPD~{2bfoy|@cV3{1z&#0A_XIL50PCb6s{jpD
z#i!*YrrUyc_3J1=?(l}HM+70rM=%UF8Kv6=)`~|ltak&k7`wux%=Gw-)Wnq3BCtz9
zu@6xQI!@0PG*zDp8hF>s%P)sj=$UDtX*Z}Yr1~MTI5{&jJ}D8j>kQQNg3bl#L8b(t
zr@m?^fijVMQDO>c^einuuf$d<B|kqGRMfzHngrTq3cC9pa*D4)bPi}FQ2{*nj%*2J
ztO7LXSPa>j0NN6m16#HaI^5eJ7Pj6Osr3W025be$CE&gqv_yv#ok^g=UZD)M;3z&G
zdKf<Zw7ry)c+gIWymZhJ5&7jHyV5}6qoJglqOY2(uNtYK>S3koYo!_t^AW^UCGfWT
z)D$ZPkil?cpeYxWH=wQH63|vgNEBcjLV-F6I%)#d0~G`f1%N6QQ0hgB7x4A7N(wMV
zAp24EL2QG%6FOA^T8jcwS*)X=qyd@)(bWZ|S#U%^M#76BJ14=(5+nsq&S)DVVar?6
z!0TI5QxqUWmXOUbRtid>GvLAf0a%Vf8RXGXfb8psxDVWJfDKo`P8dVkF$#*C#3E1&
z6BH%T-KG%D;45a4ZWsbB5CY#Yg|!$34*`IZ38-n92kEz#YofMCp+N}i`oa6HAZ^MD
zg$lL`g|G|*6^e&WLE0*SGbF@e7;>N~Cg{O5pu2>?6%W=^Y0w&Lu!skbB<5)wf)-4{
z9EX$`K=vi)=appU!RE|CBE_H+eL=S(<bz5A@Dd<Uty1h(l%ES?fQomGLTF+IX($9I
zQ;;Y1V3t6)7J;`2!8)bj3z<+Az<Z7$-(g#N4%&)al9LJ=Kgk2dr4np{SV1+@3UqLS
zsz#o+p^gH?2}o{&Bw!TnShg+~>cJW!pi^BDkx-}yYmcCbgZ4yL*D5G0xF?omq!uYa
zk`m}zcF-DqaQr}*>VN`98FBtm2()Jd5iX1eExrS7F#unY2D(uYbmJ&!tOV3CfCnQu
zhk-;u$qhQd0qg67gy9M?Za9Swxqz$#?+u1*qD9^D4~j8JL_xz>S-~SQIU8v;6S7ut
z-bSu+K&#o%kKk8;8i5oD$Ywx}{s0x1pqd!uI1q;H0RgK6r7vh(3chF7)(BKGfZEF7
z@U;aig!l*hZD`;fBnq~W1MY}15j0K*Y9#1^nsQ(b;4R14O|JqS(*Wx>ft;@lj-@PY
zT}Eh>fhtmvN)U$hy+HXD6oJU4G&r-u@&|@Q7Bm-wbRlJ7h;bl;F*7o>R|t}XC<EDw
zBjsg67SVuf3k7AQJ6k{^;0bi_%o%LW3231f=&%OJqE2xBhmC+Dtb?$i%V0t7#+_WT
z`Urfe4XAU7*j<Fkq8Oe7*#<tS0pwyNbs%vt2CX4QPp??*1*yh%vIHo<px*%n-hBz4
z?*{GgOoiVI2tU~aoH#&pfrSd0CE!()pdsYq(p(LN=t3iO<3M#xp%FN@V~;3!8wTV^
zNUVZbAPn|A+QlIyw%9y^^@t3l!V_UGc!(I3J-|&P*jTf3VnIo15vWz5tl;AB7o#4c
z5ajCXALgnM;^7&r;N$7%iY)>_Wgd8xKqE#SZbXc_rUqoh9y)NZ2|j+<Ij1x)yAoz$
zab;dfVg)EqK&R(Zz)3PcO#y992Phms7~umD4>WL(%|ReJ5GEMvIFkuTHwYIR>46Gx
z)Jh&CfsPA}Fp6r71Cy{OZJ0sI3aB{=Vl605dFEx7WG3chR)JPSq{8Po;nSrcUlwO1
zg5wQ#cOCXj3$hD3lH>|r#|pa3DzR7rHhu(>M-5?+2sEQZJ4ytD45}Q`*&(PJ1R!-f
zWWWc+2VqQSfJ8wUs@hgb%NTYfEl8M<hBT#c(6llrSiyk_O6BlExf*osV@XbGEqKTT
zt|k$*4i0=0wgPA^Qn^B69_UER{32MhpBRggH^UQhq*4fYF$w6L0g(GZOI5&I&cS6g
z+_mMPHJv$`*{Prfw~3iK;2|84Q$U!Y6&L}BEeDZQrlKB2hs`*U!w_e5U>-<^>S#y|
z6KdmO%}pRppfhRUN75*OOKxa40o&PrSdD?WKuJLfb{Y-*FdC2r@P;dB4WhP!2Ki^t
zfDcy()!yJ~AyD-I?Q!5adj=6!P*)<(p8*9k2qTo>ZjhqYrs%PTRvdw<NCjnu;M5Xu
z4uKrH4ljxzv)*~hso+Wxw6+j53JN_$9I43&aTlnZLusDcDu9mDQcyxWI}O?e$O82P
zKzj7R%@O444BgR0r&{b)D%cWu1s@OUU&3lskQB0;kzD}_ad4LyYhee8By|0t{i_P#
zvlF#)6Du?fbQJP@bWL<YV;jZAnwkorod)RVF+oBP-oHfZLxN04Y}(LK7(Lt+)E<Nl
zH^7GGAgvM5ZMVh6pb<Z4g$5s&gVb0UF+1E3H-#iC60#2V6UrdQfbs%y1wHP30nQc*
zu##5+T=beK=z=fU17!}Zc>_yP02(ZT<QA+M6H?{`I0grU4+n$JAAz<N!^aLl<B5=B
z33U82%8{W6?}C<q7N;f`L(dh%Y8N<IphI*TO2nKViZCA%P{p9bosd0QUW_;jSVsYA
zSOYp&1G+i{p&srf@UaJapiXfy%Bi7927n5oqSRu<@#*l9GLSbQJ59lnfvQMBTLCT#
zo?|WsZSRB`20t?#6u=;j2qz$1iE`*GXz^Nkv4VpF%<U*S6Un`Bg)lLE3Ue!qKvSn0
zAWa(O3R>`x(^Sxh+oYhW2_E5s*$loT6r30gkjFP*_CZ(2A)BV4rC_LMfMO(Qd<Uz6
zpil*2@R(C{UMy$?6FjG8rBDu9>;cmRI@A~}0J9e)0Aqs`f~tXHkYHgvhzqVR!CWv4
z>8ufyVKA5ph-g3=J%ig0J?97PQbW)lCvbfYAGa&4&eJxmg$}ZV6@hl$rzwH1#fDi?
zt6yD?tOT004MDY`lAe;5f<~SXqz*LHgwRHs3g8p}ij5SIVilqfwZniIIfkuriB3a|
zDnebSqmZUljqp9hJ)kK_i0299DR2ZqodF9LXxuC0f_nZiK~0!rVID_O1rr3d9zomr
zic3ISSfFeDGxMN3?qChU{9^EF-=Mh`C==pVs65Ot(8P8U=wz={=u$A;Q#<f^3D9^Q
z>huQEtOmpu@I{}XyaH+r!CKMKA$Vv=<YwlTmOu`uDACt9gC1N9J$MncbF@T37u1~x
zDbj*T7vvOyZh?hf?3SscP;3Rd=}RLMRAzvVfz(zg2B(T*aN(Q@8t6tG*$B&okaUoy
z<eU%MRZ#+-c+pls_)l8_+B64QrvY`Sj)D?|r3AK1M?pzj0W1%7vW|ihgawjU(gbz&
zAYp+eg(-#Pmn7zZ4yjWDulGTV6isa<eG~~q0s$pDP%eQ^`9tzNcuWVBV>MvWiYVj3
zhnuIQmLz88fb%#wF+%e+bUqYnmW~3#rJ#_4VDN|!Y|#a5`~}7*cIyvx4F-INPF8V#
z9-M=;$0w=E2rdlSUJmDiR6!OMBvq9cWtOCBfD8dmxalaA<Y%Ymfv*;XZ9N1R)(ZJa
zX{E)<klr|`*_#SoHVGbhf?d~>RAmGz^+4+<L1Rx~vvd@c%1c1gXvGT1JKxiwHzL4n
z)&vC+X#O}IJo+CGS>{=+k(pZn8{&lztbk$)8tkC+b24)aAgKc~TAT~&!+{n{z|4R)
z2M}{)piWM8E__31Ehv3~5<;4StpZ3GwAKT5>zcAc3h0n+*fM3<*#c?MoTsc%l3xJZ
zSOO{liuDQ-OEUCe>f)h}h>zC*nG9O&5+4tlPla5o3_46(Q!gI8L>oT)iEb)r9UIXm
zf$WEy1ls?G=$62}3~B+ysON&0GR3HaN5{c)Wze7k1qOb9fjk2VCTKu_v_Q;*`WR*C
z4ODUCG@C@9>BWP52)@h@WGM)vTMYIKC_#ZF(E}4bDv7op#lM71MG8J>2tiUbXvq%9
zAXtipih_?rg^5*V7J!uKMP(MaWr9xY1bG9hFf$*f3Zx_+Gz1k7y=~7{Av0gksj?)s
z*wbGlw=%vevj9Ae3$-7_O)5=G15d{ysf0>{GcuaZ8VEh0d|eKjQ%o!dc>yUhl|g)H
zZibo#axZ8|v?xEnL<h7-su*<cNlq$whh2WLUU_0pwgz$tAsGkL3-TT)Cxd8g7er;I
zLDo*C=A{&a+^(UdS5T=0D=R>zAmcPpnnB8+S^1fH8W87!EI@KMvaT{D9Yv`*ATu;z
z$p_s8#8w7a-beNz4hyO>3!otfcA$<z8Mqt-xdC3<MaQT^qa{Wi)G$TF31}T2co`~e
zY#dn+lI;+E$O7Q=Qjt}o<RFN8R3WI2lF}m3;mnY2z@WVih|&+1-#`(ghlmx}F<j`e
zLoj{70vZ;aX&6VjfQ$ge9`%w5ypG7sK^`*(#Rm+-l;DU_(vl2PoZv7Il(fMc67VFv
z81*7(&P+qDVqq?Z(TMmi1Er(1H1LvbSlU4=qOtiS4b(h<*LFw_MmRDJR8HV@4Sp9O
zno!_P=HRuD&{7Y!p%J#*4zg7TyyJ`F4Z)$sph=y~V%RQKXuAhAuLy47fi~qq7nOpS
z(11?$0JU{dH+Djrouk`m6Z29OM))>b-MoC*S`NayKV345LF=<YXV#<_r4|>1ZbZkw
zuQai=BtIuHiLlY&t+Jrqo;it0@b$!?+s7bne`rIyv;ee5E50N@J~=VBptLwIwFJH?
zEx)v+ptK}DC9?>;X%kktf*Qn-^sblZ18I(cwp4=p$GEm)V(Awt;NA=eUJnCb>jqt|
zN&Grc*ecJEqS92-_o~6-E<P!-$QCq!3G$mBB2Gy%F)0(i>=SMjGy<XJC!_<77)XKg
zZI!fOSEE5iz?<^HbNr>?ZWyfB0+EJwBa!z4Ky6Tl9F+u$X7J1rr1FN$se-5Zi;F=s
zouHZ&bW9Aa9)~Cct(XLzkqe1t=)^KOM4;Y4YPv!1;e;lQ%)FG$vdomy#2jdk0DL#6
z0g`%9#RPG^l2fGuBq4%a0xEj-z@0~M6AyB%O<8IY=!6N79N48Oi}67wfm#FLz8_Be
z(X0k(f?5w+!;iH~gQUi>C{-c3C^fMpHAO!+KLvDQJLqy=m?v{86_P4Jdk8?Sk;L?(
z)Kt)E5zr%PLP9||f+yxG6qV+r7Q<o=WH<;z9gN&(1zj2i6~+ulSPX&mqJ}xL5#V*X
zXkLbT*E26Ur!)l=)Zm~5xfl}qdU_}m*&qu*!J4h301jEiE+MGfQ0zmq3#2(OGq(Vx
z(V$?f04;YQHG8oJ=u}&fQe+G<J-#S4ClR!9349+pcpZQ(e7`WPISw5T0X2m|et{NU
zh%T=tiuKSOfovDZiJ*O5klpMURzljsxEut@6<CY|b@U-xLCFflgAFJkD~4vV=xk7X
z4CD|@^T4M(gGTV9v%xdF*`UY*DFuyXXM+yt00}@1ip3V^APXV!o(3K+#y0W+QUk-v
z3Q*HP!z@}_P!8x85s<aeaTjQL4!SrU+E@ekO`wWl2^6$-2VRAMmKcF%ypfU#qJDvN
zw9->clFL&-EmBB8K&RkAi#g*#dxa4D8nK^F8K04umy($WKcEsagohZw1M3H^b_5@S
z4H`F$QHQSPEQ2pMSBfuF(uPF19&9alW*YQ-5rhb0Q6G5XSwRVIE2QMIRZvnbj#tf$
z&rge2%~UOh6lhAS8t9&a%^V?|sRMNkG_}IagLR0&Jx@f?ff6`q%nlM{h^9DL8>l&s
z_2fy&kRas5NoZv1D1b(_AjaS?=po4oQD=dY4pa<u>P%`0sGv;AECHujXxkYa>^ch2
zZB>xs22vem=B4MPf=hZU@P;#xX&?+W5mYvV{Q?aRB&m>m1$d(cT+)J0=ms6Z1u35)
z!<EH)pz;>tEs$PV2TsWkbZ}K>E@Z_7_@XRml?FP03!(=!APGs+@sI;&N-{xvsX_S}
zv~U*GA25uEC;&}rSAyzTSSty%5k^BPwIVfHNfTNuA=HAdy-v(Q?87Ml4aGy_1Y}6D
zMiOWsM-Mb)oRL}qOEj9$Fn}aaXbVaM<Qz?y65E0t9nd&_W^xH+rwPR8poP02=YlQ{
zh=(RYjRM$?Wq8*Mqy&_EWAc#pWPrAb80cB*8Gw^Gq~KO4O3X{i&jqOkFCA70Pfg7>
z)CdJF@dd47hlK*@&KJ;%D)5Q8h}9~fTBSTSHCw?@PXT^37$~$sbCU6iDVRs9gA8)X
zPljewkbdxrEXXNx2s1!23<@-b<YGeuBfX6L+*Hv1QA5~pdtwT7at5Rjyk-<Kn+iRL
z7-X}Nju9-JaVyd_G%(OnFa;@u1Tft3MWAB~i&Mcz8pA>XWDY)8LG{Fg_H99o1L**H
zIS68!LL%hkKah~Jf@4aGLZSkAN)a?~1!@z4!VPJe52nwMt<Z=z)G^XAj)k}$w$lwZ
zk7$HF7K2lh^Yc<b9hIb<)LcY}JAjW;g}53N2)UK<5W5m{z+s@Hkb|~q1C$<O)S>#+
z5r?oTK#ul?T>b(&h7ermLzhn%mF6krgEmd3DriB^oGI3Voy1cFu^tp?$_k!&#U-hU
zDd55dd|XdvF?bs%RCh@#=vdpLVz^%L@HZ$7A>|;bo&v2)NlgLS2QE)hP7zdA$OrFF
zC@4xrTuuYgTCAX}3pvaYoHpTJ0IwDVd7vmYJ+UYy2h`8YPgBSM6+juO3Q+GTWPndI
zEe1s?XyYofpE5xs4xk1l_@E<DwUi1@EJ#sKdisLrdW3lzIfz9LpvVLzD`<44#+MXj
zCTCZIBNaJegAX9oP)aHVoj{eA13DkuL`MO3?gJ=Ja*9C{(cm<RoH`UrK$lU0tOPH@
z1K-5}4yweQ^2EwwP*O`NO$Lq5q$(7F&k2PDGm@usij6^gB|ryOV=)<)%oV`LqdI~P
zN(L1M#nzCt0ZIp;jxlKSGH7TTbQUY@Jgj0QOTZ3CDJH-oSS-vbhRl{jFP4CKCb^^(
zeAE&sEWs8-;~SI$Q$VNXfeKM*sR}N&U>Pz9+$J^BfY7iYhh%$O1tsTT1w#Wv1&FMI
z5p>=kwnP=waf{Xfm&!T{h6b8C3L5YXuA^X~84Fq04C)A^DkLg^x_~)|mCfLq+t2`7
zkHZ23xw#M8Py=>ttU50jq&_l)RV)g&3hEXH1}2uKhRFs-21vj>#nQyc!Xnwg)YRO}
z)XdZ@$=J}+1iPq3vVn!UiJ7UnvAKz9nwg=QiJ6I|iAj=yfrUAkHZij>FgCL=0Erob
z#S#+@)4%{GV_{}#0<z8A#LUv%#4Op&)Y1ehhQ(|&T_zx1W+^Z|Cgw;U0W(4BEs_nA
z5w0{hGBY(dGcz?eGB*b4gSple>~E7K17njU10$0p14A=YkZv;zgH(`v%q$EnKs0{S
z&~zk&bYOQCG*pbhp^{{P98$($G4zm11-S_%gUzKD$p%PafoY?;sYSAZrKzF0DI~Vc
zEX~r)QjLvZF$<1ytnwDghQ_!;&os^4#N5ct(#+T_$=nhWk7mYZhGxcQ7ND>N*=c5G
zZfcfl1~MbfEX^$0+!(Ab(KOA(!pzVdtkTTH)Y#0_+|bg*(%90($kM_Ptj5yJ$lTN%
z<S$cmBQrCzWRM*uNr=>BW@wTMN||7Lpr)CdnHicTgZyb}Vv%TIk(Op|WNu=blxk>^
zWNB<_Zf*>U6Eh=o6H60#NE(7nHM1}>F*7x?FtadBF|#mCHM1~GGqW%<g1841`Y=_X
zSb*7WW?^Iwvd28t(9+o4+$1T*D9s?vI1$qxkoh1JKqi6G7Q`0R^oLyy$i>+62=Q?P
z^A*%AP^ens&pB}Sfpe~zg|UH|g<+zJxpA7QfrSY;dw~gaQ*%?JRCQi1P%GC~2~ye_
zDe-c_N*z%75AK5!(L_fpr!;xF5dA1f7ZfzdhctT+8dHdm*W~4bj#@zaErdo(H3PgE
znM4>w7(n1@j8yR7OZNoCm>3v9m>(nv#oHP|3~({3pORXTlV7P<P>HNrDqJe~@~5r)
z{g@aSKv)Q*9*Va$Ix{gaKs0B-+PUcZW95QZPCwx)&(6RA!U9meAZlCVK^B;PNWd7O
z>E?`;3wGGGc~6isBLfJFfwV#Kwnjc4G~Mu%I|95}*+9xz7+4toGcYhr(Pv~}V3@iY
zBnIO4a3f88P3Z}Bwu%WYPAw{qDJjiJje#Gc83W%P1=>UjKIAJEa(ZiV43rTMK7s^P
zsmFjiXho&Tpi5oBVKSwM7i9`_N@tG*#GCOLqdZf3pj8+s1g7+`fYREO9#)7srNyOs
E0PrUs$N&HU

diff --git a/examples/example_framework/instructor/cs102/Report2_handin_5_of_28.token b/examples/example_framework/instructor/cs102/Report2_handin_5_of_28.token
deleted file mode 100644
index cb4ed5d6abfec70f738f205440eba8f73c909f7d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 80005
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
GrFsDPGTn0k

diff --git a/examples/example_framework/instructor/cs102/__pycache__/deploy.cpython-38.pyc b/examples/example_framework/instructor/cs102/__pycache__/deploy.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4d9b529d6cae3250756694b95ca75ce15b33bf86
GIT binary patch
literal 760
zcmWIL<>g{vU|@J4te5D?#K7<v#6iaF3=9ko3=9m#9SjT%DGVu$ISjdsQH+crHd78$
zE^`z!n9ZESlFJ&!3TCt9u;sExv4h#HIUG?OsT^6H3%F9b7cxfir1GY)Wiu7Eq_U<m
zHZwFcGBTtxr!uCngCR#R3nN1+dn!)~r#M3@PYRbfLkf2aPYQ1eUpjLNKS(x(HJCwD
z;3de7nvA#DgHj9fi%N_%8E=Ufr<Rl!#HSY}rliKFW#**D7lGw88E;9YCzfQS7R8qq
z<m4x&#Fym9Cnx3>loscumS{5G;wa9`EQn9ZEb_a>5g(tMn3)$J@21Hd#g?0ymzh=>
z#hIU!R$82#SdtpWo?4NbTw0P^#i_5Sr=MJGXkb(&3S#Q%=@*xjrljVT6hnkVZgI!Q
z7gQ!ECTFC^$5*jy>6PSXr{-00rlc0+<X7qyRBEzBaTVv67A2>G?2h6{Ni8k`vqY0~
zQWNvyLHx|T#FEVXJg_i(YDIERX-cXlUlcFcW<7}ijEa~T7#O0|O7k*HAf7KM$}CGP
zNj1{T$V^E|&5KViN=+<*gh_D`Gf1&IZpA1;Rm1{PEdUCjg47~C5Djum5i0`&!!4%#
z;#({Qi6t4g*i$l#@)C1XLE#4u`S>WN@)QscBpM&TlA(x~fdNANig&h(2`x@7Dvl{B
z%}9-L$xklL1%+D-hMQtiD-v@Ha#D+7jQF&o#N5>K{G#lb%)H`~qSEA&{Gu3eV8p<~
k^%jRsZhlH>PO2RvDBTJ%Ffi~iLLdht4-*F?7oz|p0DCy)i2wiq

literal 0
HcmV?d00001

diff --git a/examples/example_framework/instructor/cs102/__pycache__/homework1.cpython-38.pyc b/examples/example_framework/instructor/cs102/__pycache__/homework1.cpython-38.pyc
index aca3c8b22c11ae4d9d824d7ba252b4194f5db12f..d67337369ba5bf909f1eb07c3dda178779750fb2 100644
GIT binary patch
delta 20
bcmX@Yc7%;Pl$V!_fq{XcM_6wow<R+GE(`<S

delta 20
bcmX@Yc7%;Pl$V!_fq{YH<6)hR+?LD$H01>G

diff --git a/examples/example_framework/instructor/cs102/__pycache__/report2_grade.cpython-38.pyc b/examples/example_framework/instructor/cs102/__pycache__/report2_grade.cpython-38.pyc
index 5fb59bc9a735c474aff24e25cd7c318cc0869f8d..42fb3a4a526346eae8494f38ac29d254b5f30b83 100644
GIT binary patch
delta 3461
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
H`TtS?CbZ_|

delta 7469
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

diff --git a/examples/example_framework/instructor/cs102/deploy.py b/examples/example_framework/instructor/cs102/deploy.py
index c585908..4e47e5e 100644
--- a/examples/example_framework/instructor/cs102/deploy.py
+++ b/examples/example_framework/instructor/cs102/deploy.py
@@ -2,8 +2,10 @@ from cs102.report2 import Report2
 from unitgrade_private2.hidden_create_files import setup_grade_file_report
 from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
 from snipper.snip_dir import snip_dir
-if __name__ == "__main__":
+import os
+wd = os.path.dirname(__file__)
 
+if __name__ == "__main__":
     gather_upload_to_campusnet(Report2())
     setup_grade_file_report(Report2, minify=False, obfuscate=False, execute=False)
-    snip_dir(source_dir="../cs102", dest_dir="../../students/cs102", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
+    snip_dir(source_dir=wd+"/../cs102", dest_dir=wd+"/../../students/cs102", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
diff --git a/examples/example_framework/instructor/cs102/report2.py b/examples/example_framework/instructor/cs102/report2.py
index 381cdb1..c7be1cd 100644
--- a/examples/example_framework/instructor/cs102/report2.py
+++ b/examples/example_framework/instructor/cs102/report2.py
@@ -1,6 +1,7 @@
-from unitgrade2.unitgrade2 import Report
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
-from unitgrade2.unitgrade2 import UTestCase, cache, hide
+from src.unitgrade2.unitgrade2 import Report
+from src.unitgrade2 import evaluate_report_student
+from src.unitgrade2.unitgrade2 import UTestCase, cache
+
 
 class Week1(UTestCase):
     """ The first question for week 1. """
@@ -8,9 +9,6 @@ class Week1(UTestCase):
         """ Docstring for this method """
         from cs102.homework1 import add
         self.assertEqualC(add(2,2))
-        with self.capture() as out:
-            print("hello world 42")
-        self.assertEqual(out.numbers[0], 42)
         self.assertEqualC(add(-100, 5))
 
     def test_reverse(self):
@@ -18,6 +16,12 @@ class Week1(UTestCase):
         from cs102.homework1 import reverse_list
         self.assertEqualC(reverse_list([1,2,3]))
 
+    def test_output_capture(self):
+        with self.capture() as out:
+            print("hello world 42")                     # Genereate some output (i.e. in a homework script)
+        self.assertEqual(out.numbers[0], 42)            # out.numbers is a list of all numbers generated
+        self.assertEqual(out.output, "hello world 42")  # you can also access the raw output.
+
 
 class Question2(UTestCase):
     """ Second problem """
diff --git a/examples/example_framework/instructor/cs102/report2_grade.py b/examples/example_framework/instructor/cs102/report2_grade.py
index 503237e..eeb50ec 100644
--- a/examples/example_framework/instructor/cs102/report2_grade.py
+++ b/examples/example_framework/instructor/cs102/report2_grade.py
@@ -4,14 +4,10 @@ from tabulate import tabulate
 from datetime import datetime
 import pyfiglet
 import unittest
-
 import inspect
 import os
 import argparse
-import sys
 import time
-import threading # don't import Thread bc. of minify issue.
-import tqdm # don't do from tqdm import tqdm because of minify-issue
 
 parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
 To run all tests in a report: 
@@ -61,53 +57,6 @@ def evaluate_report_student(report, question=None, qitem=None, unmute=None, pass
                                           show_tol_err=show_tol_err)
 
 
-    # try:  # For registering stats.
-    #     import unitgrade_private
-    #     import irlc.lectures
-    #     import xlwings
-    #     from openpyxl import Workbook
-    #     import pandas as pd
-    #     from collections import defaultdict
-    #     dd = defaultdict(lambda: [])
-    #     error_computed = []
-    #     for k1, (q, _) in enumerate(report.questions):
-    #         for k2, item in enumerate(q.items):
-    #             dd['question_index'].append(k1)
-    #             dd['item_index'].append(k2)
-    #             dd['question'].append(q.name)
-    #             dd['item'].append(item.name)
-    #             dd['tol'].append(0 if not hasattr(item, 'tol') else item.tol)
-    #             error_computed.append(0 if not hasattr(item, 'error_computed') else item.error_computed)
-    #
-    #     qstats = report.wdir + "/" + report.name + ".xlsx"
-    #
-    #     if os.path.isfile(qstats):
-    #         d_read = pd.read_excel(qstats).to_dict()
-    #     else:
-    #         d_read = dict()
-    #
-    #     for k in range(1000):
-    #         key = 'run_'+str(k)
-    #         if key in d_read:
-    #             dd[key] = list(d_read['run_0'].values())
-    #         else:
-    #             dd[key] = error_computed
-    #             break
-    #
-    #     workbook = Workbook()
-    #     worksheet = workbook.active
-    #     for col, key in enumerate(dd.keys()):
-    #         worksheet.cell(row=1, column=col+1).value = key
-    #         for row, item in enumerate(dd[key]):
-    #             worksheet.cell(row=row+2, column=col+1).value = item
-    #
-    #     workbook.save(qstats)
-    #     workbook.close()
-    #
-    # except ModuleNotFoundError as e:
-    #     s = 234
-    #     pass
-
     if question is None:
         print("Provisional evaluation")
         tabulate(table_data)
@@ -159,24 +108,20 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
     else:
         b = "Unitgrade"
-    print(b + " v" + __version__)
     dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
-    print("Started: " + dt_string)
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
     s = report.title
     if hasattr(report, "version") and report.version is not None:
         s += " version " + report.version
-    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
+    print(s, "(use --help for options)" if show_help_flag else "")
     # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
     table_data = []
-    nL = 80
     t_start = time.time()
     score = {}
     loader = SequentialTestLoader()
 
     for n, (q, w) in enumerate(report.questions):
-        # q = q()
-        # q_hidden = False
-        # q_hidden = issubclass(q.__class__, Hidden)
         if question is not None and n+1 != question:
             continue
         suite = loader.loadTestsFromTestCase(q)
@@ -186,104 +131,28 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         q.possible = 0
         q.obtained = 0
         q_ = {} # Gather score in this class.
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
         UTextResult.q_title_print = q_title_print # Hacky
         UTextResult.show_progress_bar = show_progress_bar # Hacky.
         UTextResult.number = n
+        UTextResult.nL = report.nL
 
         res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
-        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)
-        z = 234
-        # for j, item in enumerate(q.items):
-        #     if qitem is not None and question is not None and j+1 != qitem:
-        #         continue
-        #
-        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.
-        #         # if not item.question.has_called_init_:
-        #         start = time.time()
-        #
-        #         cc = None
-        #         if show_progress_bar:
-        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )
-        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)
-        #         from unitgrade import Capturing # DON'T REMOVE THIS LINE
-        #         with eval('Capturing')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.
-        #             try:
-        #                 for q2 in q_with_outstanding_init:
-        #                     q2.init()
-        #                     q2.has_called_init_ = True
-        #
-        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.
-        #             except Exception as e:
-        #                 if not passall:
-        #                     if not silent:
-        #                         print(" ")
-        #                         print("="*30)
-        #                         print(f"When initializing question {q.title} the initialization code threw an error")
-        #                         print(e)
-        #                         print("The remaining parts of this question will likely fail.")
-        #                         print("="*30)
-        #
-        #         if show_progress_bar:
-        #             cc.terminate()
-        #             sys.stdout.flush()
-        #             print(q_title_print, end="")
-        #
-        #         q_time =np.round(  time.time()-start, 2)
-        #
-        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")
-        #         print("=" * nL)
-        #         q_with_outstanding_init = None
-        #
-        #     # item.question = q # Set the parent question instance for later reference.
-        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)
-        #
-        #     if show_progress_bar:
-        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)
-        #     else:
-        #         print(item_title_print + ( '.'*max(0, nL-4-len(ss)) ), end="")
-        #     hidden = issubclass(item.__class__, Hidden)
-        #     # if not hidden:
-        #     #     print(ss, end="")
-        #     # sys.stdout.flush()
-        #     start = time.time()
-        #
-        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)
-        #     q_[j] = {'w': item.weight, 'possible': possible, 'obtained': current, 'hidden': hidden, 'computed': str(item._computed_answer), 'title': item.title}
-        #     tsecs = np.round(time.time()-start, 2)
-        #     if show_progress_bar:
-        #         cc.terminate()
-        #         sys.stdout.flush()
-        #         print(item_title_print + ('.' * max(0, nL - 4 - len(ss))), end="")
-        #
-        #     if not hidden:
-        #         ss = "PASS" if current == possible else "*** FAILED"
-        #         if tsecs >= 0.1:
-        #             ss += " ("+ str(tsecs) + " seconds)"
-        #         print(ss)
-
-        # ws, possible, obtained = upack(q_)
 
         possible = res.testsRun
         obtained = len(res.successes)
 
         assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
 
-        # possible = int(ws @ possible)
-        # obtained = int(ws @ obtained)
-        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
-
         obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
         score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
         q.obtained = obtained
         q.possible = possible
 
-        s1 = f"*** Question q{n+1}"
+        s1 = f"Question {n+1} total"
         s2 = f" {q.obtained}/{w}"
-        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
         print(" ")
-        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
 
     ws, possible, obtained = upack(score)
     possible = int( msum(possible) )
@@ -298,15 +167,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
     seconds = dt - minutes*60
     plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
 
-    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
 
     table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
     results = {'total': (obtained, possible), 'details': score}
     return results, table_data
 
 
-
-
 from tabulate import tabulate
 from datetime import datetime
 import inspect
@@ -329,7 +199,8 @@ def gather_imports(imp):
     # dn = os.path.dirname(f)
     # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
     # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
         top_package = os.path.dirname(m.__file__)
         module_import = True
     else:
@@ -350,7 +221,7 @@ def gather_imports(imp):
             for file in files:
                 if file.endswith(".py"):
                     fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
                     zip.write(fpath, v)
 
     resources['zipfile'] = zip_buffer.getvalue()
@@ -394,14 +265,14 @@ def gather_upload_to_campusnet(report, output_dir=None):
     results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
                                           show_progress_bar=not args.noprogress,
                                           big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
     # also load the source code of missing files...
 
     sources = {}
-
+    print("")
     if not args.autolab:
         if len(report.individual_imports) > 0:
             print("By uploading the .token file, you verify the files:")
@@ -414,12 +285,15 @@ def gather_upload_to_campusnet(report, output_dir=None):
             print("Including files in upload...")
             for k, m in enumerate(report.pack_imports):
                 nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
                 nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
                 nimp['name'] = m.__name__
                 sources[k] = nimp
                 # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
+                print(f" * {m.__name__}")
                 # sources = {**sources, **nimp}
     results['sources'] = sources
 
@@ -438,9 +312,9 @@ def gather_upload_to_campusnet(report, output_dir=None):
 
     if not args.autolab:
         print(" ")
-        print("To get credit for your results, please upload the single file: ")
+        print("To get credit for your results, please upload the single unmodified file: ")
         print(">", token)
-        print("To campusnet without any modifications.")
+        # print("To campusnet without any modifications.")
 
         # print("Now time for some autolab fun")
 
@@ -453,8 +327,8 @@ def source_instantiate(name, report1_source, payload):
 
 
 
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, unmute=False, **kwargs):\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n            # for item in q.items:\n            #     if q.name not in payloads or item.name not in payloads[q.name]:\n            #         s = f"> Broken resource dictionary submitted to unitgrade for question {q.name} and subquestion {item.name}. Framework will not work."\n            #         if strict:\n            #             raise Exception(s)\n            #         else:\n            #             print(s)\n            #     else:\n            #         item._correct_answer_payload = payloads[q.name][item.name][\'payload\']\n            #         item.estimated_time = payloads[q.name][item.name].get("time", 1)\n            #         q.estimated_time = payloads[q.name].get("time", 1)\n            #         if "precomputed" in payloads[q.name][item.name]: # Consider removing later.\n            #             item._precomputed_payload = payloads[q.name][item.name][\'precomputed\']\n            #         try:\n            #             if "title" in payloads[q.name][item.name]: # can perhaps be removed later.\n            #                 item.title = payloads[q.name][item.name][\'title\']\n            #         except Exception as e: # Cannot set attribute error. The title is a function (and probably should not be).\n            #             pass\n            #             # print("bad", e)\n        # self.payloads = payloads\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\nclass MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n    pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        item_title = item_title.split("\\n")[0]\n\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 2\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    @classmethod\n    def question_title(cls):\n        return cls.__doc__.splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    # def _callSetUp(self):\n    #     # Always run before method is called.\n    #     print("asdf")\n    #     pass\n    # @classmethod\n    # def setUpClass(cls):\n    #     # self._cache_put((self.cache_id(), \'title\'), value)\n    #     cls.reset()\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    # def unique_cache_id(self):\n    #     k0 = self.cache_id()\n    #     # key = ()\n    #     i = 0\n    #     for i in itertools.count():\n    #         # key = k0 + (i,)\n    #         if i not in self._cache_get( (k0, \'assert\') ):\n    #             break\n    #     return i\n    #     return key\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n    #\n    # def _cache2_contains(self, key):\n    #     print("Is this needed?")\n    #     self._ensure_cache_exists()\n    #     return key in self.__class__._cache2\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    # try:  # For registering stats.\n    #     import unitgrade_private\n    #     import irlc.lectures\n    #     import xlwings\n    #     from openpyxl import Workbook\n    #     import pandas as pd\n    #     from collections import defaultdict\n    #     dd = defaultdict(lambda: [])\n    #     error_computed = []\n    #     for k1, (q, _) in enumerate(report.questions):\n    #         for k2, item in enumerate(q.items):\n    #             dd[\'question_index\'].append(k1)\n    #             dd[\'item_index\'].append(k2)\n    #             dd[\'question\'].append(q.name)\n    #             dd[\'item\'].append(item.name)\n    #             dd[\'tol\'].append(0 if not hasattr(item, \'tol\') else item.tol)\n    #             error_computed.append(0 if not hasattr(item, \'error_computed\') else item.error_computed)\n    #\n    #     qstats = report.wdir + "/" + report.name + ".xlsx"\n    #\n    #     if os.path.isfile(qstats):\n    #         d_read = pd.read_excel(qstats).to_dict()\n    #     else:\n    #         d_read = dict()\n    #\n    #     for k in range(1000):\n    #         key = \'run_\'+str(k)\n    #         if key in d_read:\n    #             dd[key] = list(d_read[\'run_0\'].values())\n    #         else:\n    #             dd[key] = error_computed\n    #             break\n    #\n    #     workbook = Workbook()\n    #     worksheet = workbook.active\n    #     for col, key in enumerate(dd.keys()):\n    #         worksheet.cell(row=1, column=col+1).value = key\n    #         for row, item in enumerate(dd[key]):\n    #             worksheet.cell(row=row+2, column=col+1).value = item\n    #\n    #     workbook.save(qstats)\n    #     workbook.close()\n    #\n    # except ModuleNotFoundError as e:\n    #     s = 234\n    #     pass\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)\n        z = 234\n        # for j, item in enumerate(q.items):\n        #     if qitem is not None and question is not None and j+1 != qitem:\n        #         continue\n        #\n        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.\n        #         # if not item.question.has_called_init_:\n        #         start = time.time()\n        #\n        #         cc = None\n        #         if show_progress_bar:\n        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )\n        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)\n        #         from unitgrade import Capturing # DON\'T REMOVE THIS LINE\n        #         with eval(\'Capturing\')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.\n        #             try:\n        #                 for q2 in q_with_outstanding_init:\n        #                     q2.init()\n        #                     q2.has_called_init_ = True\n        #\n        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.\n        #             except Exception as e:\n        #                 if not passall:\n        #                     if not silent:\n        #                         print(" ")\n        #                         print("="*30)\n        #                         print(f"When initializing question {q.title} the initialization code threw an error")\n        #                         print(e)\n        #                         print("The remaining parts of this question will likely fail.")\n        #                         print("="*30)\n        #\n        #         if show_progress_bar:\n        #             cc.terminate()\n        #             sys.stdout.flush()\n        #             print(q_title_print, end="")\n        #\n        #         q_time =np.round(  time.time()-start, 2)\n        #\n        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")\n        #         print("=" * nL)\n        #         q_with_outstanding_init = None\n        #\n        #     # item.question = q # Set the parent question instance for later reference.\n        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)\n        #\n        #     if show_progress_bar:\n        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)\n        #     else:\n        #         print(item_title_print + ( \'.\'*max(0, nL-4-len(ss)) ), end="")\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        #     if show_progress_bar:\n        #         cc.terminate()\n        #         sys.stdout.flush()\n        #         print(item_title_print + (\'.\' * max(0, nL - 4 - len(ss))), end="")\n        #\n        #     if not hidden:\n        #         ss = "PASS" if current == possible else "*** FAILED"\n        #         if tsecs >= 0.1:\n        #             ss += " ("+ str(tsecs) + " seconds)"\n        #         print(ss)\n\n        # ws, possible, obtained = upack(q_)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nimport random\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n\n    def test_add(self):\n        """ Docstring for this method """\n        from cs102.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n    def test_reverse(self):\n        """ Reverse a list """  # Add a title to the test.\n        from cs102.homework1 import reverse_list\n        self.assertEqualC(reverse_list([1,2,3]))\n\n\nclass Question2(UTestCase):\n    """ Second problem """\n    @cache\n    def my_reversal(self, ls):\n        # The \'@cache\' decorator ensures the function is not run on the *students* computer\n        # Instead the code is run on the teachers computer and the result is passed on with the\n        # other pre-computed results -- i.e. this function will run regardless of how the student happens to have\n        # implemented reverse_list.\n        from cs102.homework1 import reverse_list\n        return reverse_list(ls)\n\n    def test_reverse_tricky(self):\n        ls = [2,4,8]\n        self.title = f"Reversing a small list containing {ls=}"\n        ls2 = self.my_reversal( tuple(ls) ) # This will always produce the right result.\n        ls3 = self.my_reversal( tuple([1,2,3]) )  # Also works; the cache respects input arguments.\n        self.assertEqualC(self.my_reversal( tuple(ls2) )) # This will actually test the students code.\n\n\nimport cs102\nclass Report2(Report):\n    title = "CS 101 Report 2"\n    questions = [(Week1, 10), (Question2, 8) ]  # Include a single question for 10 credits.\n    pack_imports = [cs102]'
-report1_payload = '8004959a010000000000007d94288c055765656b31947d94288c055765656b31948c08746573745f6164649486948c057469746c659486948c19446f63737472696e6720666f722074686973206d6574686f64946803680486948c066173736572749486947d94284b004b044b014aa1ffffff756803680486948c0474696d6594869447000000000000000068038c0c746573745f72657665727365948694680686948c0e526576657273652061206c69737494680368108694680a86947d944b005d94284b034b024b016573680368108694680e86944700000000000000008c0474696d6594470000000000000000758c095175657374696f6e32947d94288c095175657374696f6e32948c13746573745f726576657273655f747269636b799486948c066173736572749486947d944b005d94284b024b044b086573681d681e86948c057469746c659486948c2e526576657273696e67206120736d616c6c206c69737420636f6e7461696e696e67206c733d5b322c20342c20385d94681d681e86948c0474696d65948694470000000000000000681a473f5066000000000075752e'
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"Question {n+1} total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        """ Docstring for this method """\n        from cs102.homework1 import add\n        self.assertEqualC(add(2,2))\n        with self.capture() as out:\n            print("hello world 42")\n        self.assertEqual(out.numbers[0], 42)\n        self.assertEqualC(add(-100, 5))\n\n    def test_reverse(self):\n        """ Reverse a list """  # Add a title to the test.\n        from cs102.homework1 import reverse_list\n        self.assertEqualC(reverse_list([1,2,3]))\n\n\nclass Question2(UTestCase):\n    """ Second problem """\n    @cache\n    def my_reversal(self, ls):\n        # The \'@cache\' decorator ensures the function is not run on the *students* computer\n        # Instead the code is run on the teachers computer and the result is passed on with the\n        # other pre-computed results -- i.e. this function will run regardless of how the student happens to have\n        # implemented reverse_list.\n        from cs102.homework1 import reverse_list\n        return reverse_list(ls)\n\n    def test_reverse_tricky(self):\n        ls = [2,4,8]\n        self.title = f"Reversing a small list containing {ls=}" # Titles can be set like this at any point in the function body.\n        ls2 = self.my_reversal( tuple(ls) ) # This will always produce the right result.\n        ls3 = self.my_reversal( tuple([1,2,3]) )  # Also works; the cache respects input arguments.\n        self.assertEqualC(self.my_reversal( tuple(ls2) )) # This will actually test the students code.\n\n\nimport cs102\nclass Report2(Report):\n    title = "CS 101 Report 2"\n    questions = [(Week1, 10), (Question2, 8) ]\n    pack_imports = [cs102]'
+report1_payload = '80049510010000000000007d94288c055765656b31947d94288c055765656b31948c08746573745f6164649486948c066173736572749486947d94284b004b044b014aa1ffffff7568038c0c746573745f72657665727365948694680686947d944b005d94284b034b024b0165738c0474696d6594473fe6a7e700000000758c095175657374696f6e32947d94288c095175657374696f6e32948c13746573745f726576657273655f747269636b799486948c057469746c659486948c2e526576657273696e67206120736d616c6c206c69737420636f6e7461696e696e67206c733d5b322c20342c20385d946811681286948c066173736572749486947d944b005d94284b024b044b086573680e473facac280000000075752e'
 name="Report2"
 
 report = source_instantiate(name, report1_source, report1_payload)
diff --git a/examples/example_framework/instructor/cs102/unitgrade/Question2.pkl b/examples/example_framework/instructor/cs102/unitgrade/Question2.pkl
index 634a7fbbe4bad27f24b2d894ef3c0b37c4f5dd94..b950c49faa2b91b7675ee266d63a13fe3652e3cc 100644
GIT binary patch
delta 119
zcmZo*e!;}jz%n&<B8&dS;0<CN8JrnBnvGMu8NHdjncJr%`qfU!5ST2<sO$rm;_zni
zW`ap|aqR0^R{wxw2Ul_1l%)14ZBt^WXm~Suvv_l)W-w+jwN2?^ODrx<Eh?GPHl=oo
LH$#R>aj6~v?r|tR

delta 140
zcmaFC)WFQrz%sRTB8$E(TVio>YEj9Qwkfq!ycuGrXm~Suvv_l)7H2SKFikYrEXJF`
zmm#RxIK`XMo5`EGeM+KV?UW4Bi9eNH;4&QEEZ$5onJ$ifJ<IAJaO~hJZkv+SKBa9+
Z20O^CwkbU<C7HRYQ`)AuGeAM99sr;8Ev*0m

diff --git a/examples/example_framework/instructor/cs102/unitgrade/Week1.pkl b/examples/example_framework/instructor/cs102/unitgrade/Week1.pkl
index 7912698f036128bb2a8b616c2a66c58ac9e774e5..6b4ee502e9c67e2ff3aba1b11c4911bb88195e34 100644
GIT binary patch
delta 35
rcmcc4n99<?GBs)<i^9YJ>50vvg0)k;8Dghscr$x5c{8RKm+Aok$2|&n

delta 146
zcmYej&dAchGWE<v76nb#lFX8v)G2LKdL&))lZ#7=GV{_E((;QGN-{Ew6>?KcGV)WV
zWH4qhO;nT<%V27o(!)}cnG4e3&Hx1yZN=?-_<~Z)Qj3aH6%rM4GK)(<TKL+gWN@@i
gsh#4@5IaS~o7tPmn=!RGgE0dn!P7PcZa}FX06nQK!~g&Q

diff --git a/examples/example_framework/students/cs102/.coverage b/examples/example_framework/students/cs102/.coverage
new file mode 100644
index 0000000000000000000000000000000000000000..a93b4d7e94a84f8ad080beeafaa98b3784e23e91
GIT binary patch
literal 53248
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

literal 0
HcmV?d00001

diff --git a/examples/example_framework/students/cs102/Report2_handin_0_of_18.token b/examples/example_framework/students/cs102/Report2_handin_0_of_18.token
deleted file mode 100644
index 63734376c0eae1c4df3121a0c656e90452e80cba..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 79868
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
aM*t#a1oy#|9u`odnbN}wF|D+?R1W}G5%E6&

diff --git a/examples/example_framework/students/cs102/__pycache__/deploy.cpython-38.pyc b/examples/example_framework/students/cs102/__pycache__/deploy.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4d9b529d6cae3250756694b95ca75ce15b33bf86
GIT binary patch
literal 760
zcmWIL<>g{vU|@J4te5D?#K7<v#6iaF3=9ko3=9m#9SjT%DGVu$ISjdsQH+crHd78$
zE^`z!n9ZESlFJ&!3TCt9u;sExv4h#HIUG?OsT^6H3%F9b7cxfir1GY)Wiu7Eq_U<m
zHZwFcGBTtxr!uCngCR#R3nN1+dn!)~r#M3@PYRbfLkf2aPYQ1eUpjLNKS(x(HJCwD
z;3de7nvA#DgHj9fi%N_%8E=Ufr<Rl!#HSY}rliKFW#**D7lGw88E;9YCzfQS7R8qq
z<m4x&#Fym9Cnx3>loscumS{5G;wa9`EQn9ZEb_a>5g(tMn3)$J@21Hd#g?0ymzh=>
z#hIU!R$82#SdtpWo?4NbTw0P^#i_5Sr=MJGXkb(&3S#Q%=@*xjrljVT6hnkVZgI!Q
z7gQ!ECTFC^$5*jy>6PSXr{-00rlc0+<X7qyRBEzBaTVv67A2>G?2h6{Ni8k`vqY0~
zQWNvyLHx|T#FEVXJg_i(YDIERX-cXlUlcFcW<7}ijEa~T7#O0|O7k*HAf7KM$}CGP
zNj1{T$V^E|&5KViN=+<*gh_D`Gf1&IZpA1;Rm1{PEdUCjg47~C5Djum5i0`&!!4%#
z;#({Qi6t4g*i$l#@)C1XLE#4u`S>WN@)QscBpM&TlA(x~fdNANig&h(2`x@7Dvl{B
z%}9-L$xklL1%+D-hMQtiD-v@Ha#D+7jQF&o#N5>K{G#lb%)H`~qSEA&{Gu3eV8p<~
k^%jRsZhlH>PO2RvDBTJ%Ffi~iLLdht4-*F?7oz|p0DCy)i2wiq

literal 0
HcmV?d00001

diff --git a/examples/example_framework/students/cs102/__pycache__/homework1.cpython-38.pyc b/examples/example_framework/students/cs102/__pycache__/homework1.cpython-38.pyc
index a099ef9f65bf987d85152d20d4dad941ae1d27bc..d67337369ba5bf909f1eb07c3dda178779750fb2 100644
GIT binary patch
delta 398
zcmaFNeuRxLl$V!_fq{XcM_4b>k7**GOuZWe149Z!3S$dH6hjJA3UdoX6k{q=3QIOq
zky9#j3TrB33R?<WGt+E_xlGNBj0~yFDeS2XDQqbmDV!->=`78R%}k68Dcr#fnmoyj
zAhV$u#Aaq-U~pz&U?}EcU|=X=C}FH&Xl86?3}(<|tXjmSprD{IS&VV6swUGdmYmGu
zl3N@_sb#4}#i=Qpj8Sa4l_0T|3`HPQekD!*&gjaOnO9s=RGM6pUo_c;NznpiM==w~
zLe?Ty1_p*?FdM{YU|;~TK^W`+4h9B>8ipE1aR!j(lNU0j>Vk~bWV*$ec#AO!YzKs3
zVPIgm#hjRu0@4C8oVkc&vL$nfHw)O3B9O!_j`;Yz#N5>Q_*<+6MVWae5X~SnAuO;l
a95%W6DWy57c3_8s^l`9ruyQboFaiLWSxc?}

delta 535
zcmX@Y_L!Y7l$V!_fq{X+d$&%a8S_LwnR+h<28I-dD25cq6s8u2D8>}#6qXi-D5g~A
z6xM8}BDYkQ6t+~R6!sMMW~SK;bD5eM85vSpQaDl>Q`l2DQ@B#N(^;Aso0%9HQh0(H
zG<mDixm+s}a|?1(6^ctrQ&RIv6q55(QuP!<GBS%5(lT>W6*7wz5=%?+a}!H4lj{?6
zaw-+lQ}a@b5=&B36w-?Fa}`Q5Qo$;V6*BX{oXou9lA_Y&lKdjwl+2=35TlYSnGxg@
zC<d{a7#J9w85kIfc^DWNN*GcYn;DxJQ<#DoG?}XwaVaP$D7a^qrRFIlD&%Aqmnf*`
zR_0_*+}-W+OWYIW-dvDd(@OJ_OEUBG6q52&D*aY6-V*l9FM&&^rnnXr<rir(MzMi3
z7niJLC}Lq?VEC0VIh)ay1M1=8$-5X8c|qdEASW@f6|qfz!6++)>8#1ZOsU2or~4Iw
zRBAHaVobcnm;^QxLa;J0Fx+BJOi2N0h8V|E#5s8>Q-~nzE%x~Ml>FrQ_#!q228JTe
q$&AdR1|Vx8TEQ%^eh!=5{FKt1R6CGW#h?Vh!py<J!N$QP!UzCL*@fHy

diff --git a/examples/example_framework/students/cs102/__pycache__/report2.cpython-38.pyc b/examples/example_framework/students/cs102/__pycache__/report2.cpython-38.pyc
index d06f59685aba1b0e7100778b3122129ce8573306..e88ea2f06cb46d8605dea67d9293e601ee149b83 100644
GIT binary patch
delta 1025
zcmZn=_$t5~%FD~ez`(%3@k%Fg(?nib#;S?h`abRqDJ&_hEet8FsVvRRQS9yvDQqe1
zEet8_U_M6*LkdR@XB4M9LkedKR|`W5S1MyOa}-x9cM5klQ&Cweb1GLeLo*{ILkh>l
zbsiJHm+>((Ffed3FfceXFfbIyO|E8Ca%5h}(9c)PRKk+N0#X{zV9F545X2C{P{Xi*
zwT3B+Ern5%A%%4z6C+53sfH2ch-RjRU}J+BG&v`4VANBp;>$?Q$;nqJ&o9bJQ7|!j
zsl~v+kU8i7|Nk#p85kJ+G}$M=W>j&!#h#p4P*PfydW*H7C^N6*7I$KCacWVCYhh_(
z&Mo%5(%hufqGC<vTP($?IcY^43=9mnnDa|ZRx%WcFfcIuDxR#$WE_`RT9TiWm=vE{
zk(gVMld7+$rw?VurxhjUrk3XyW$S0=6_*s1CYR(F=_eN(8W`ypr55BDl^E$2RNmq!
zNi8mkPfST+2ZaL<DCn7Z7zG%)7=;*xCeLN+w*ZM1NiZ-l6!9`JFlaIr34z#P0gyw$
zt|<})IgbZyR#9qMYEf~jz~mI>Kw~kGT4@l0Pzz>(G!%jC1cga48z{yZSr|Dui`XX@
zu*ptlWofb%hgb)<Uy~VZ^)05HVu*Xd27w8XX}7p@E8`)SC+0{@KEiT3P7-9X6v!Bs
zTdXCSB{``@N+5@_mXsFcq(c0|0yeZrk%56BiaDp)2t*h|JcTe?7};m>B}JLZ*_Dcu
z-?Ewp$$+eo1rc%}LLNkbyacwWNFBrl8-pM~ZY@$^U|;}+O))55IT%?OnHae^z@mPW
zUo%Th?q&0-R{^IM&LT7`R6%BfLJq9_7H45;YH>+seqQk{R&eaz;weZ>&W_K_1;ueO
zl25=+0Nbv?z`y`XmGE#EU@QWO-QtLk&rQtCi;vgjxg{f7nwMFUUX+-UYNUr?7BPWB
zaB>N|Q2;ppz^*9L200331jMyqs}Kap(pwxhx%nxjIjMGxpp+)Sz`(%6$ipbYBp@gt
L%)uzY%E1T#{|@D7

delta 899
zcmew=&>+AY%FD~ez`($uyIUvGd?K$bW79-!{g4!f6qX$JD0X*-6xI~B7KRkIRF-Du
zC=Pdq6!sL37KRiKFrO2wjw_1GogsxYg{y@jg)5b@nK_C(l_!Neo2jTSl{uBWnW34H
zks*a;;xZ3Lzlrb4_?Q?N7+4t?7@Qdx7>W%h7cnXcGu1Gru%xgyGc5!uWeaA|WS@MM
zQI9us&j0`aUxF0-X);e%Wl|B-WV*#toSKtX#KFM8u#%yOkAZ>VSHk2jCS%vsip1Q4
zoYeTVqQu<P^8BLgn9RK5lA_Y&lKi5W<YGeuqnM)9g8ZTqBfWykTO1{+#U=5HDJh&F
zXRv|7fQg4uV6rrGzXdk~14EGzh~QyhV9;bL;svq60wDXqmKO0dFfiQW0h>~kT9#T=
zoXS7>5p$rS07$JUh(M?Xvp^b(*cliYK$aDQ2o6RTCJwgADJ%<Z1tAu}ZPsK4TY8Hr
zrx@ZAun}MaWX>(_+{$=}wTU_6lbu*k#|eY16ag8-a*MSjvm__ANCxCY){@eKoYW$)
zPguZ)7D+QOFhnuu6dQpEV~BSUMhheRDZZpAGda6bVRAN`X`mR$3ULr20U{(p1SoRA
z78NOixL{)t1jwyLQVa|Xpa3Zb#Tf@93nLRF7YA5$@+Y>mdN~FL20u;CA~e(GLB@fC
z3#>AVv#>O^xFj<_ulN=#I5MMn3KEmE<1=$XQCf`T39#*8i<Lm30gGOc#R7~)AhBB<
z@$tEdnR)T?n!HgmqNRD6CFw<pDXB(!2xbu|nMO_i%x)AF#a5J<my(|gjy$kyic~<3
x0~rNzHP}i70kZrShfQvNN@-529V5sEpv1$&$ipbY$iXDQFCfgpD8S0W2mqR}xm5rF

diff --git a/examples/example_framework/students/cs102/__pycache__/report2_grade.cpython-38.pyc b/examples/example_framework/students/cs102/__pycache__/report2_grade.cpython-38.pyc
index cb391caf0c1bf2175df62b4c8789fee08d1961e3..42fb3a4a526346eae8494f38ac29d254b5f30b83 100644
GIT binary patch
delta 4043
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
Uv2lZ%3|tl*oGhS56cb1%0L&;{pa1{>

delta 8117
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

diff --git a/examples/example_framework/students/cs102/report2.py b/examples/example_framework/students/cs102/report2.py
index d84e9c4..e4d6b02 100644
--- a/examples/example_framework/students/cs102/report2.py
+++ b/examples/example_framework/students/cs102/report2.py
@@ -1,18 +1,20 @@
 """
 Example student code. This file is automatically generated from the files in the instructor-directory
 """
-from unitgrade2.unitgrade2 import Report
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
-from unitgrade2.unitgrade2 import UTestCase, cache, hide
-import random
+from src.unitgrade2.unitgrade2 import Report
+from src.unitgrade2 import evaluate_report_student
+from src.unitgrade2.unitgrade2 import UTestCase, cache
+
 
 class Week1(UTestCase):
     """ The first question for week 1. """
-
     def test_add(self):
         """ Docstring for this method """
         from cs102.homework1 import add
         self.assertEqualC(add(2,2))
+        with self.capture() as out:
+            print("hello world 42")
+        self.assertEqual(out.numbers[0], 42)
         self.assertEqualC(add(-100, 5))
 
     def test_reverse(self):
@@ -34,7 +36,7 @@ class Question2(UTestCase):
 
     def test_reverse_tricky(self):
         ls = [2,4,8]
-        self.title = f"Reversing a small list containing {ls=}"
+        self.title = f"Reversing a small list containing {ls=}" # Titles can be set like this at any point in the function body.
         ls2 = self.my_reversal( tuple(ls) ) # This will always produce the right result.
         ls3 = self.my_reversal( tuple([1,2,3]) )  # Also works; the cache respects input arguments.
         self.assertEqualC(self.my_reversal( tuple(ls2) )) # This will actually test the students code.
@@ -43,7 +45,7 @@ class Question2(UTestCase):
 import cs102
 class Report2(Report):
     title = "CS 101 Report 2"
-    questions = [(Week1, 10), (Question2, 8) ]  # Include a single question for 10 credits.
+    questions = [(Week1, 10), (Question2, 8) ]
     pack_imports = [cs102]
 
 if __name__ == "__main__":
diff --git a/examples/example_framework/students/cs102/report2_grade.py b/examples/example_framework/students/cs102/report2_grade.py
index 1f9a885..e6318de 100644
--- a/examples/example_framework/students/cs102/report2_grade.py
+++ b/examples/example_framework/students/cs102/report2_grade.py
@@ -6,14 +6,10 @@ from tabulate import tabulate
 from datetime import datetime
 import pyfiglet
 import unittest
-
 import inspect
 import os
 import argparse
-import sys
 import time
-import threading # don't import Thread bc. of minify issue.
-import tqdm # don't do from tqdm import tqdm because of minify-issue
 
 parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
 To run all tests in a report: 
@@ -63,53 +59,6 @@ def evaluate_report_student(report, question=None, qitem=None, unmute=None, pass
                                           show_tol_err=show_tol_err)
 
 
-    # try:  # For registering stats.
-    #     import unitgrade_private
-    #     import irlc.lectures
-    #     import xlwings
-    #     from openpyxl import Workbook
-    #     import pandas as pd
-    #     from collections import defaultdict
-    #     dd = defaultdict(lambda: [])
-    #     error_computed = []
-    #     for k1, (q, _) in enumerate(report.questions):
-    #         for k2, item in enumerate(q.items):
-    #             dd['question_index'].append(k1)
-    #             dd['item_index'].append(k2)
-    #             dd['question'].append(q.name)
-    #             dd['item'].append(item.name)
-    #             dd['tol'].append(0 if not hasattr(item, 'tol') else item.tol)
-    #             error_computed.append(0 if not hasattr(item, 'error_computed') else item.error_computed)
-    #
-    #     qstats = report.wdir + "/" + report.name + ".xlsx"
-    #
-    #     if os.path.isfile(qstats):
-    #         d_read = pd.read_excel(qstats).to_dict()
-    #     else:
-    #         d_read = dict()
-    #
-    #     for k in range(1000):
-    #         key = 'run_'+str(k)
-    #         if key in d_read:
-    #             dd[key] = list(d_read['run_0'].values())
-    #         else:
-    #             dd[key] = error_computed
-    #             break
-    #
-    #     workbook = Workbook()
-    #     worksheet = workbook.active
-    #     for col, key in enumerate(dd.keys()):
-    #         worksheet.cell(row=1, column=col+1).value = key
-    #         for row, item in enumerate(dd[key]):
-    #             worksheet.cell(row=row+2, column=col+1).value = item
-    #
-    #     workbook.save(qstats)
-    #     workbook.close()
-    #
-    # except ModuleNotFoundError as e:
-    #     s = 234
-    #     pass
-
     if question is None:
         print("Provisional evaluation")
         tabulate(table_data)
@@ -161,24 +110,20 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
     else:
         b = "Unitgrade"
-    print(b + " v" + __version__)
     dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
-    print("Started: " + dt_string)
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
     s = report.title
     if hasattr(report, "version") and report.version is not None:
         s += " version " + report.version
-    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
+    print(s, "(use --help for options)" if show_help_flag else "")
     # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
     table_data = []
-    nL = 80
     t_start = time.time()
     score = {}
     loader = SequentialTestLoader()
 
     for n, (q, w) in enumerate(report.questions):
-        # q = q()
-        # q_hidden = False
-        # q_hidden = issubclass(q.__class__, Hidden)
         if question is not None and n+1 != question:
             continue
         suite = loader.loadTestsFromTestCase(q)
@@ -188,104 +133,28 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         q.possible = 0
         q.obtained = 0
         q_ = {} # Gather score in this class.
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
         UTextResult.q_title_print = q_title_print # Hacky
         UTextResult.show_progress_bar = show_progress_bar # Hacky.
         UTextResult.number = n
+        UTextResult.nL = report.nL
 
         res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
-        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)
-        z = 234
-        # for j, item in enumerate(q.items):
-        #     if qitem is not None and question is not None and j+1 != qitem:
-        #         continue
-        #
-        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.
-        #         # if not item.question.has_called_init_:
-        #         start = time.time()
-        #
-        #         cc = None
-        #         if show_progress_bar:
-        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )
-        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)
-        #         from unitgrade import Capturing # DON'T REMOVE THIS LINE
-        #         with eval('Capturing')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.
-        #             try:
-        #                 for q2 in q_with_outstanding_init:
-        #                     q2.init()
-        #                     q2.has_called_init_ = True
-        #
-        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.
-        #             except Exception as e:
-        #                 if not passall:
-        #                     if not silent:
-        #                         print(" ")
-        #                         print("="*30)
-        #                         print(f"When initializing question {q.title} the initialization code threw an error")
-        #                         print(e)
-        #                         print("The remaining parts of this question will likely fail.")
-        #                         print("="*30)
-        #
-        #         if show_progress_bar:
-        #             cc.terminate()
-        #             sys.stdout.flush()
-        #             print(q_title_print, end="")
-        #
-        #         q_time =np.round(  time.time()-start, 2)
-        #
-        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")
-        #         print("=" * nL)
-        #         q_with_outstanding_init = None
-        #
-        #     # item.question = q # Set the parent question instance for later reference.
-        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)
-        #
-        #     if show_progress_bar:
-        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)
-        #     else:
-        #         print(item_title_print + ( '.'*max(0, nL-4-len(ss)) ), end="")
-        #     hidden = issubclass(item.__class__, Hidden)
-        #     # if not hidden:
-        #     #     print(ss, end="")
-        #     # sys.stdout.flush()
-        #     start = time.time()
-        #
-        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)
-        #     q_[j] = {'w': item.weight, 'possible': possible, 'obtained': current, 'hidden': hidden, 'computed': str(item._computed_answer), 'title': item.title}
-        #     tsecs = np.round(time.time()-start, 2)
-        #     if show_progress_bar:
-        #         cc.terminate()
-        #         sys.stdout.flush()
-        #         print(item_title_print + ('.' * max(0, nL - 4 - len(ss))), end="")
-        #
-        #     if not hidden:
-        #         ss = "PASS" if current == possible else "*** FAILED"
-        #         if tsecs >= 0.1:
-        #             ss += " ("+ str(tsecs) + " seconds)"
-        #         print(ss)
-
-        # ws, possible, obtained = upack(q_)
 
         possible = res.testsRun
         obtained = len(res.successes)
 
         assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
 
-        # possible = int(ws @ possible)
-        # obtained = int(ws @ obtained)
-        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
-
         obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
         score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
         q.obtained = obtained
         q.possible = possible
 
-        s1 = f"*** Question q{n+1}"
+        s1 = f"Question {n+1} total"
         s2 = f" {q.obtained}/{w}"
-        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
         print(" ")
-        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
 
     ws, possible, obtained = upack(score)
     possible = int( msum(possible) )
@@ -300,15 +169,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
     seconds = dt - minutes*60
     plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
 
-    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
 
     table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
     results = {'total': (obtained, possible), 'details': score}
     return results, table_data
 
 
-
-
 from tabulate import tabulate
 from datetime import datetime
 import inspect
@@ -331,7 +201,8 @@ def gather_imports(imp):
     # dn = os.path.dirname(f)
     # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
     # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
         top_package = os.path.dirname(m.__file__)
         module_import = True
     else:
@@ -352,7 +223,7 @@ def gather_imports(imp):
             for file in files:
                 if file.endswith(".py"):
                     fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
                     zip.write(fpath, v)
 
     resources['zipfile'] = zip_buffer.getvalue()
@@ -396,14 +267,14 @@ def gather_upload_to_campusnet(report, output_dir=None):
     results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
                                           show_progress_bar=not args.noprogress,
                                           big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
     # also load the source code of missing files...
 
     sources = {}
-
+    print("")
     if not args.autolab:
         if len(report.individual_imports) > 0:
             print("By uploading the .token file, you verify the files:")
@@ -416,12 +287,15 @@ def gather_upload_to_campusnet(report, output_dir=None):
             print("Including files in upload...")
             for k, m in enumerate(report.pack_imports):
                 nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
                 nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
                 nimp['name'] = m.__name__
                 sources[k] = nimp
                 # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
+                print(f" * {m.__name__}")
                 # sources = {**sources, **nimp}
     results['sources'] = sources
 
@@ -440,9 +314,9 @@ def gather_upload_to_campusnet(report, output_dir=None):
 
     if not args.autolab:
         print(" ")
-        print("To get credit for your results, please upload the single file: ")
+        print("To get credit for your results, please upload the single unmodified file: ")
         print(">", token)
-        print("To campusnet without any modifications.")
+        # print("To campusnet without any modifications.")
 
         # print("Now time for some autolab fun")
 
@@ -455,8 +329,8 @@ def source_instantiate(name, report1_source, payload):
 
 
 
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, unmute=False, **kwargs):\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n            # for item in q.items:\n            #     if q.name not in payloads or item.name not in payloads[q.name]:\n            #         s = f"> Broken resource dictionary submitted to unitgrade for question {q.name} and subquestion {item.name}. Framework will not work."\n            #         if strict:\n            #             raise Exception(s)\n            #         else:\n            #             print(s)\n            #     else:\n            #         item._correct_answer_payload = payloads[q.name][item.name][\'payload\']\n            #         item.estimated_time = payloads[q.name][item.name].get("time", 1)\n            #         q.estimated_time = payloads[q.name].get("time", 1)\n            #         if "precomputed" in payloads[q.name][item.name]: # Consider removing later.\n            #             item._precomputed_payload = payloads[q.name][item.name][\'precomputed\']\n            #         try:\n            #             if "title" in payloads[q.name][item.name]: # can perhaps be removed later.\n            #                 item.title = payloads[q.name][item.name][\'title\']\n            #         except Exception as e: # Cannot set attribute error. The title is a function (and probably should not be).\n            #             pass\n            #             # print("bad", e)\n        # self.payloads = payloads\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\nclass MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n    pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        item_title = item_title.split("\\n")[0]\n\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 2\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    @classmethod\n    def question_title(cls):\n        return cls.__doc__.splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    # def _callSetUp(self):\n    #     # Always run before method is called.\n    #     print("asdf")\n    #     pass\n    # @classmethod\n    # def setUpClass(cls):\n    #     # self._cache_put((self.cache_id(), \'title\'), value)\n    #     cls.reset()\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    # def unique_cache_id(self):\n    #     k0 = self.cache_id()\n    #     # key = ()\n    #     i = 0\n    #     for i in itertools.count():\n    #         # key = k0 + (i,)\n    #         if i not in self._cache_get( (k0, \'assert\') ):\n    #             break\n    #     return i\n    #     return key\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n    #\n    # def _cache2_contains(self, key):\n    #     print("Is this needed?")\n    #     self._ensure_cache_exists()\n    #     return key in self.__class__._cache2\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    # try:  # For registering stats.\n    #     import unitgrade_private\n    #     import irlc.lectures\n    #     import xlwings\n    #     from openpyxl import Workbook\n    #     import pandas as pd\n    #     from collections import defaultdict\n    #     dd = defaultdict(lambda: [])\n    #     error_computed = []\n    #     for k1, (q, _) in enumerate(report.questions):\n    #         for k2, item in enumerate(q.items):\n    #             dd[\'question_index\'].append(k1)\n    #             dd[\'item_index\'].append(k2)\n    #             dd[\'question\'].append(q.name)\n    #             dd[\'item\'].append(item.name)\n    #             dd[\'tol\'].append(0 if not hasattr(item, \'tol\') else item.tol)\n    #             error_computed.append(0 if not hasattr(item, \'error_computed\') else item.error_computed)\n    #\n    #     qstats = report.wdir + "/" + report.name + ".xlsx"\n    #\n    #     if os.path.isfile(qstats):\n    #         d_read = pd.read_excel(qstats).to_dict()\n    #     else:\n    #         d_read = dict()\n    #\n    #     for k in range(1000):\n    #         key = \'run_\'+str(k)\n    #         if key in d_read:\n    #             dd[key] = list(d_read[\'run_0\'].values())\n    #         else:\n    #             dd[key] = error_computed\n    #             break\n    #\n    #     workbook = Workbook()\n    #     worksheet = workbook.active\n    #     for col, key in enumerate(dd.keys()):\n    #         worksheet.cell(row=1, column=col+1).value = key\n    #         for row, item in enumerate(dd[key]):\n    #             worksheet.cell(row=row+2, column=col+1).value = item\n    #\n    #     workbook.save(qstats)\n    #     workbook.close()\n    #\n    # except ModuleNotFoundError as e:\n    #     s = 234\n    #     pass\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)\n        z = 234\n        # for j, item in enumerate(q.items):\n        #     if qitem is not None and question is not None and j+1 != qitem:\n        #         continue\n        #\n        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.\n        #         # if not item.question.has_called_init_:\n        #         start = time.time()\n        #\n        #         cc = None\n        #         if show_progress_bar:\n        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )\n        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)\n        #         from unitgrade import Capturing # DON\'T REMOVE THIS LINE\n        #         with eval(\'Capturing\')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.\n        #             try:\n        #                 for q2 in q_with_outstanding_init:\n        #                     q2.init()\n        #                     q2.has_called_init_ = True\n        #\n        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.\n        #             except Exception as e:\n        #                 if not passall:\n        #                     if not silent:\n        #                         print(" ")\n        #                         print("="*30)\n        #                         print(f"When initializing question {q.title} the initialization code threw an error")\n        #                         print(e)\n        #                         print("The remaining parts of this question will likely fail.")\n        #                         print("="*30)\n        #\n        #         if show_progress_bar:\n        #             cc.terminate()\n        #             sys.stdout.flush()\n        #             print(q_title_print, end="")\n        #\n        #         q_time =np.round(  time.time()-start, 2)\n        #\n        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")\n        #         print("=" * nL)\n        #         q_with_outstanding_init = None\n        #\n        #     # item.question = q # Set the parent question instance for later reference.\n        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)\n        #\n        #     if show_progress_bar:\n        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)\n        #     else:\n        #         print(item_title_print + ( \'.\'*max(0, nL-4-len(ss)) ), end="")\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        #     if show_progress_bar:\n        #         cc.terminate()\n        #         sys.stdout.flush()\n        #         print(item_title_print + (\'.\' * max(0, nL - 4 - len(ss))), end="")\n        #\n        #     if not hidden:\n        #         ss = "PASS" if current == possible else "*** FAILED"\n        #         if tsecs >= 0.1:\n        #             ss += " ("+ str(tsecs) + " seconds)"\n        #         print(ss)\n\n        # ws, possible, obtained = upack(q_)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nimport random\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n\n    def test_add(self):\n        """ Docstring for this method """\n        from cs102.homework1 import add\n        self.assertEqualC(add(2,2))\n        self.assertEqualC(add(-100, 5))\n\n    def test_reverse(self):\n        """ Reverse a list """  # Add a title to the test.\n        from cs102.homework1 import reverse_list\n        self.assertEqualC(reverse_list([1,2,3]))\n\n\nclass Question2(UTestCase):\n    """ Second problem """\n    @cache\n    def my_reversal(self, ls):\n        # The \'@cache\' decorator ensures the function is not run on the *students* computer\n        # Instead the code is run on the teachers computer and the result is passed on with the\n        # other pre-computed results -- i.e. this function will run regardless of how the student happens to have\n        # implemented reverse_list.\n        from cs102.homework1 import reverse_list\n        return reverse_list(ls)\n\n    def test_reverse_tricky(self):\n        ls = [2,4,8]\n        self.title = f"Reversing a small list containing {ls=}"\n        ls2 = self.my_reversal( tuple(ls) ) # This will always produce the right result.\n        ls3 = self.my_reversal( tuple([1,2,3]) )  # Also works; the cache respects input arguments.\n        self.assertEqualC(self.my_reversal( tuple(ls2) )) # This will actually test the students code.\n\n\nimport cs102\nclass Report2(Report):\n    title = "CS 101 Report 2"\n    questions = [(Week1, 10), (Question2, 8) ]  # Include a single question for 10 credits.\n    pack_imports = [cs102]'
-report1_payload = '8004959a010000000000007d94288c055765656b31947d94288c055765656b31948c08746573745f6164649486948c057469746c659486948c19446f63737472696e6720666f722074686973206d6574686f64946803680486948c066173736572749486947d94284b004b044b014aa1ffffff756803680486948c0474696d6594869447000000000000000068038c0c746573745f72657665727365948694680686948c0e526576657273652061206c69737494680368108694680a86947d944b005d94284b034b024b016573680368108694680e86944700000000000000008c0474696d6594470000000000000000758c095175657374696f6e32947d94288c095175657374696f6e32948c13746573745f726576657273655f747269636b799486948c066173736572749486947d944b005d94284b024b044b086573681d681e86948c057469746c659486948c2e526576657273696e67206120736d616c6c206c69737420636f6e7461696e696e67206c733d5b322c20342c20385d94681d681e86948c0474696d65948694470000000000000000681a473f5066000000000075752e'
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"Question {n+1} total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\n\nclass Week1(UTestCase):\n    """ The first question for week 1. """\n    def test_add(self):\n        """ Docstring for this method """\n        from cs102.homework1 import add\n        self.assertEqualC(add(2,2))\n        with self.capture() as out:\n            print("hello world 42")\n        self.assertEqual(out.numbers[0], 42)\n        self.assertEqualC(add(-100, 5))\n\n    def test_reverse(self):\n        """ Reverse a list """  # Add a title to the test.\n        from cs102.homework1 import reverse_list\n        self.assertEqualC(reverse_list([1,2,3]))\n\n\nclass Question2(UTestCase):\n    """ Second problem """\n    @cache\n    def my_reversal(self, ls):\n        # The \'@cache\' decorator ensures the function is not run on the *students* computer\n        # Instead the code is run on the teachers computer and the result is passed on with the\n        # other pre-computed results -- i.e. this function will run regardless of how the student happens to have\n        # implemented reverse_list.\n        from cs102.homework1 import reverse_list\n        return reverse_list(ls)\n\n    def test_reverse_tricky(self):\n        ls = [2,4,8]\n        self.title = f"Reversing a small list containing {ls=}" # Titles can be set like this at any point in the function body.\n        ls2 = self.my_reversal( tuple(ls) ) # This will always produce the right result.\n        ls3 = self.my_reversal( tuple([1,2,3]) )  # Also works; the cache respects input arguments.\n        self.assertEqualC(self.my_reversal( tuple(ls2) )) # This will actually test the students code.\n\n\nimport cs102\nclass Report2(Report):\n    title = "CS 101 Report 2"\n    questions = [(Week1, 10), (Question2, 8) ]\n    pack_imports = [cs102]'
+report1_payload = '80049510010000000000007d94288c055765656b31947d94288c055765656b31948c08746573745f6164649486948c066173736572749486947d94284b004b044b014aa1ffffff7568038c0c746573745f72657665727365948694680686947d944b005d94284b034b024b0165738c0474696d6594473fe6a7e700000000758c095175657374696f6e32947d94288c095175657374696f6e32948c13746573745f726576657273655f747269636b799486948c057469746c659486948c2e526576657273696e67206120736d616c6c206c69737420636f6e7461696e696e67206c733d5b322c20342c20385d946811681286948c066173736572749486947d944b005d94284b024b044b086573680e473facac280000000075752e'
 name="Report2"
 
 report = source_instantiate(name, report1_source, report1_payload)
diff --git a/examples/example_framework/students/cs102/unitgrade/Question2.pkl b/examples/example_framework/students/cs102/unitgrade/Question2.pkl
index 634a7fbbe4bad27f24b2d894ef3c0b37c4f5dd94..b950c49faa2b91b7675ee266d63a13fe3652e3cc 100644
GIT binary patch
delta 119
zcmZo*e!;}jz%n&<B8&dS;0<CN8JrnBnvGMu8NHdjncJr%`qfU!5ST2<sO$rm;_zni
zW`ap|aqR0^R{wxw2Ul_1l%)14ZBt^WXm~Suvv_l)W-w+jwN2?^ODrx<Eh?GPHl=oo
LH$#R>aj6~v?r|tR

delta 140
zcmaFC)WFQrz%sRTB8$E(TVio>YEj9Qwkfq!ycuGrXm~Suvv_l)7H2SKFikYrEXJF`
zmm#RxIK`XMo5`EGeM+KV?UW4Bi9eNH;4&QEEZ$5onJ$ifJ<IAJaO~hJZkv+SKBa9+
Z20O^CwkbU<C7HRYQ`)AuGeAM99sr;8Ev*0m

diff --git a/examples/example_framework/students/cs102/unitgrade/Week1.pkl b/examples/example_framework/students/cs102/unitgrade/Week1.pkl
index 7912698f036128bb2a8b616c2a66c58ac9e774e5..6b4ee502e9c67e2ff3aba1b11c4911bb88195e34 100644
GIT binary patch
delta 35
rcmcc4n99<?GBs)<i^9YJ>50vvg0)k;8Dghscr$x5c{8RKm+Aok$2|&n

delta 146
zcmYej&dAchGWE<v76nb#lFX8v)G2LKdL&))lZ#7=GV{_E((;QGN-{Ew6>?KcGV)WV
zWH4qhO;nT<%V27o(!)}cnG4e3&Hx1yZN=?-_<~Z)Qj3aH6%rM4GK)(<TKL+gWN@@i
gsh#4@5IaS~o7tPmn=!RGgE0dn!P7PcZa}FX06nQK!~g&Q

diff --git a/examples/example_jupyter/instructor/cs105/.coverage b/examples/example_jupyter/instructor/cs105/.coverage
new file mode 100644
index 0000000000000000000000000000000000000000..572452543e2092b38f99ec9afedd779fdc155f29
GIT binary patch
literal 53248
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

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/instructor/cs105/Report1Jupyter_handin_18_of_18.token b/examples/example_jupyter/instructor/cs105/Report1Jupyter_handin_18_of_18.token
new file mode 100644
index 0000000000000000000000000000000000000000..cfb09b6ef919a3d4c721651cb236201490461fc4
GIT binary patch
literal 58736
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
Da6eMK

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/instructor/cs105/__pycache__/homework1.cpython-38.pyc b/examples/example_jupyter/instructor/cs105/__pycache__/homework1.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..405a1c978c8bf2114f9b470bfd5312fb8f02188f
GIT binary patch
literal 187
zcmWIL<>g{vU|{$cp_?eqz`*br#6iZ43=9ko3=9m#EDQ_`DGb33nv8xc8Hzx{2;x_Q
zvsFxJacWU<Oi5`*YK%*Ma%paAUP*CGX<lYYdQoCZYJ5RaW?5oMYD{WHVs1fBYB7uv
zpH*5=S&~{5lbKgsQdF8;l3x^)Tx@7y8k3Qqn_8Y<lx?V2P<e~PCO1E&G$+*#Wb<c`
F3juJhGy4Dl

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/instructor/cs105/__pycache__/report5.cpython-38.pyc b/examples/example_jupyter/instructor/cs105/__pycache__/report5.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c80ebb8aac0fa657aacc6cb4b52f65783b2e1ec8
GIT binary patch
literal 2312
zcmWIL<>g{vU|={t-5_xjD+9x05C<8vFfcGUFfcF_Ph((UNMT4}%wfo7jAG1Xieh2}
z@tJa%b6KKTz-;Cm)+p8#h7{%;wkWm~h7^_@hFtb2_FRrA4n~F))+kPQh7`6G_7;W|
z_Ee^3<|r<Ah7^tz&K8CgPB5R_ogsxQg}a3zg*%nInK_EbogsxMg|~$vg*TP4nK_C#
zl`n-ao2h70DoZMFGea{YBSQ*vFoP!lOOT5-nQpNKr55BDmE7VC4M{C7aZW5w)nvRS
zo?4ceQ<_+k8easKjV~@KO-aow@zZ3w#pRq>P*PfynU`*KixbZN#a*77nr)<)Sx}jm
zlngQ(8N)+FkAZ<9l_82Tg&~S5l{tkmg=r3B3Udle3rjO&6iW(g3R??96l)553P%e=
z6k7^oFoP!NE!ObV)NDh)m5jI8ic(8Ti}I2gkqig1IT;ujoIxS3!oa{#!qCjnFT%)B
z!kERhfVqTaA!7|gJZm_EDMKJb5JLn*3PUi%N=83Twjx#r28LT4nYo|<$V<A#;g?^M
znv|cPeTyY0KQZMNOIl`5>Mf?cq?L@fn3HpgS27d{GcYjxigUJ#2`x@7Dvl{B%}9-L
z$xklLP0cGQjw#K{EJ-g)Oi7I|D9S8LEJ=+?tw_u*$Vn}RG2*jI3o1)ei()eKic5-0
zlS}f8Vv>su4NPMo0d1;RP<e~1IJG3Sz&R(exESQIVo>NYFmW(e34jAa4<U^a5Nxo3
zFkoO{s9{(D4TKcN6vl;2DNGBQ7*R!;7BZzUgG51rqRHa-l8J$V;U&nzmmCZX44N#r
zxD$(uQ;SMm3riDoia=sT0-#W1&8<u;&0EQMi={X<Ck-4f5JChb%TbbAToRv{lEMdy
z6p(QYjAD#cd=U4;Br#kMQV5PlkRdSFXEB4^4$3US44O=SRlFIgIXU?X<@rT9DGElK
zEJczG3=BvvV=hZ9Dv}0?fg%gZQ9NLKi&D!{i;7c)Kn??WmVvQK2+3JcX-)Q99P#ma
ziMgrq@wd3*<8$*<N^?MLp7?lBNI+${lR=S`n_7~QpHd_WvQrjB$b$%k?O+zjOJG-m
z!mt=ba4<443b1gnfJJd<86%`DlfoFqoWdBzlFEvfb=XqbA(^L{F^U76ZP;&d`8mO|
zv|kY?0|Ns_c!LDN;jISCHe#@BQ^SyjHRBX<gOUX#>lE>T{K*R<K=FKwBM+8;nB()3
ziUdItV84S2Z~%b92ozt4G%bp7CBB3W%H?3Ef<mr_A&Vi4F_;137^YjC@$uk@h>tG<
z`2<_+gHx>>Jkpt}c#-VQOVZ>lQUEzu5kx3~2vraPHcc7C0y+E^M?q13L26M+CD=4b
z(gOPpOn^NIDuBd5)_}r>gOP=i1suyvj71<Bj93PxKyXzdfga0DDa<VlQ7kDe!3>(L
zw>Se!Q;SP7^Ye^~*s;YVJl})N0p*+;hAhSfOrTV<kZB>P&}Rr{&}8;20=caSq)3xF
ziU%ocJ43uA1@bGF%u@tP*B~DhgIo;CGjIp#fwNU&N{XK*E7m{+X~h~=nhXpKps)rf
z22fZPfkZIEh#6L$f?@+!d4O_4DoYAe8dEB33UeA$I#U!|DtkI8^+Q684^pogdO-@@
zDt_l+1w#W<1&FYM=}S-@4h{)FjL5&mT9R3klM2q5U^hi^7DB_n_!ehIer{@ceo?kz
z6i-27a&|nV{wT)kMJ)yf26a$!0NDoeA{!&ye-`E<kT|G>$xY16i;vgjj}nE~9Y%Tx
zW)Uc~i$DPoC5sS6D2UHU%_&GNDmE$t6`e)8px6T?JaElc1WFV|{2(z<rU55Fuy4S&
wL!t_ta1jJ33E$$dfs}T3pgdO$N-zS9Jd7NS9E<`?EQ|tt0z3k&0_+^j050p;!~g&Q

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/instructor/cs105/__pycache__/week2.cpython-38.pyc b/examples/example_jupyter/instructor/cs105/__pycache__/week2.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d81c0675c7056e7e11ab8b96d289c407997be566
GIT binary patch
literal 466
zcmWIL<>g{vU|?{asFQe(fq~&Mh=Yuo85kHG7#J9e?HCvsQW&BbQW&EcQ<zeiTNt94
zQkha%QdparQrN^9qL@=zQW={W85vSpQkg+?3VRf53P%cO3qurJ3Rf_LCU=#fvVv<x
zYEg1#ajJrmo{^p*R~2tYYEDkRLV12sPKtt2G82;JAT|g)gY4&EU|^_Ws9_Xg2xib^
z^jpcG$#jb`@fKrJ5hDWw1DLqQU7nhnZKRi3P??u>i#4}0tu#*tq!(le17i^@0|UcL
z5c?&_S1&;xfBA}mfgu@W0?b|z8zc?3l#hXdp@gA^A%(G-DTPTKWHqy25gW)HkUC9>
znVO8Z7*oJ5fDkMU3=AOab4zoyk*w!oU|{gmWWU88AD@z+93Ov+xh$~=?5JC8`K2WV
zr6spm3yL!HN^UV$6@e5(Oaoa2VS&x%u*uC&Da}c>V+R=xav+Nc3nK?JA0r1N2PX?7
E09j2^v;Y7A

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/instructor/cs105/deploy.py b/examples/example_jupyter/instructor/cs105/deploy.py
new file mode 100644
index 0000000..8acafa9
--- /dev/null
+++ b/examples/example_jupyter/instructor/cs105/deploy.py
@@ -0,0 +1,15 @@
+from report5 import Report1Jupyter
+from unitgrade_private2.hidden_create_files import setup_grade_file_report
+from snipper import snip_dir
+
+if __name__ == "__main__":
+    setup_grade_file_report(Report1Jupyter, minify=False, obfuscate=False, execute=False)
+
+    # from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
+    # gather_upload_to_campusnet((Report1Flat()))
+
+    # Deploy the files using snipper: https://gitlab.compute.dtu.dk/tuhe/snipper
+    snip_dir.snip_dir(source_dir="", dest_dir="../../students/cs105", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
+
+
+
diff --git a/examples/example_jupyter/instructor/cs105/homework1.py b/examples/example_jupyter/instructor/cs105/homework1.py
new file mode 100644
index 0000000..b01dcab
--- /dev/null
+++ b/examples/example_jupyter/instructor/cs105/homework1.py
@@ -0,0 +1 @@
+# This file is blank.
diff --git a/examples/example_jupyter/instructor/cs105/report5.py b/examples/example_jupyter/instructor/cs105/report5.py
new file mode 100644
index 0000000..38e9fbd
--- /dev/null
+++ b/examples/example_jupyter/instructor/cs105/report5.py
@@ -0,0 +1,49 @@
+from src.unitgrade2.unitgrade2 import Report,  UTestCase
+from src.unitgrade2 import evaluate_report_student
+import homework1
+import importnb
+from src.unitgrade2.unitgrade2 import Capturing2
+
+file = 'week2.ipynb'
+class Week1(UTestCase):
+    @classmethod
+    def setUpClass(cls) -> None:
+        with Capturing2():
+            cls.nb = importnb.Notebook.load(file)
+
+    def test_add(self):
+        self.assertEqual(Week1.nb.myfun(2,2), 4)
+        self.assertEqual(Week1.nb.myfun(2,4), 8)
+
+    def test_reverse(self):
+        self.assertEqual(Week1.nb.var, "hello world 2")
+
+# Nicer: Automatically load the notebook.
+class NBTestCase(UTestCase):
+    notebook = None
+    _nb = None
+    @classmethod
+    def setUpClass(cls) -> None:
+        with Capturing2():
+            cls._nb = importnb.Notebook.load(cls.notebook)
+
+    @property
+    def nb(self):
+        return self.__class__._nb
+
+class Question2(NBTestCase):
+    notebook = "week2.ipynb"
+    def test_add(self):
+        self.assertEqualC(self.nb.myfun(2,8))
+
+class Report1Jupyter(Report):
+    title = "CS 105 Report 5"
+    questions = [(Week1, 10),
+                 (Question2, 8)
+                 ]  # Include a single question for 10 credits.
+    pack_imports = [homework1]
+
+if __name__ == "__main__":
+    # Uncomment to simply run everything as a unittest:
+    # unittest.main(verbosity=2)
+    evaluate_report_student(Report1Jupyter())
diff --git a/examples/example_jupyter/instructor/cs105/report5_grade.py b/examples/example_jupyter/instructor/cs105/report5_grade.py
new file mode 100644
index 0000000..3e65178
--- /dev/null
+++ b/examples/example_jupyter/instructor/cs105/report5_grade.py
@@ -0,0 +1,336 @@
+
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+import inspect
+import os
+import argparse
+import time
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print(s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+        UTextResult.nL = report.nL
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f" * q{n+1}) Total"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+    print("")
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f" * {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.join(output_dir, token)
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single unmodified file: ")
+        print(">", token)
+        # print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            # print(self.questions)\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                print("q is", q())\n                q()._cache_put(\'time\', q.time) # = q.time\n                report_cache[q.__qualname__] = q._cache2\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            # self._stdout = sys.stdout\n            # sys._stdout = io.StringIO()\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f" * q{n+1}) Total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nimport homework1\nimport importnb\n\nfile = \'week2.ipynb\'\nclass Week1(UTestCase):\n    @classmethod\n    def setUpClass(cls) -> None:\n        with Capturing2():\n            cls.nb = importnb.Notebook.load(file)\n\n    def test_add(self):\n        self.assertEqual(Week1.nb.myfun(2,2), 4)\n        self.assertEqual(Week1.nb.myfun(2,4), 8)\n\n    def test_reverse(self):\n        self.assertEqual(Week1.nb.var, "hello world 2")\n\n# Nicer: Automatically load the notebook.\nclass NBTestCase(UTestCase):\n    notebook = None\n    _nb = None\n    @classmethod\n    def setUpClass(cls) -> None:\n        with Capturing2():\n            cls._nb = importnb.Notebook.load(cls.notebook)\n\n    @property\n    def nb(self):\n        return self.__class__._nb\n\nclass Question2(NBTestCase):\n    notebook = "week2.ipynb"\n    def test_add(self):\n        self.assertEqualC(self.nb.myfun(2,8))\n\nclass Report1Jupyter(Report):\n    title = "CS 105 Report 5"\n    questions = [(Week1, 10),\n                 (Question2, 8)\n                 ]  # Include a single question for 10 credits.\n    pack_imports = [homework1]'
+report1_payload = '8004955c000000000000007d94288c055765656b31947d948c0474696d6594473fed915600000000738c095175657374696f6e32947d942868048c08746573745f6164649486948c066173736572749486947d944b004b10736803473fcc28f40000000075752e'
+name="Report1Jupyter"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
\ No newline at end of file
diff --git a/examples/example_jupyter/instructor/cs105/unitgrade/Question2.pkl b/examples/example_jupyter/instructor/cs105/unitgrade/Question2.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..b08cef102cf660c34ffd24ee8633b7254630acac
GIT binary patch
literal 58
zcmZo*nX1nK0ku<lI0H*li%T-|^NgnSaFnDLm&7Ngq)cg>(!-WmT%1}|GNo-w?G$eY
JZ-L@sJpdXr6f^(;

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/instructor/cs105/unitgrade/Week1.pkl b/examples/example_jupyter/instructor/cs105/unitgrade/Week1.pkl
new file mode 100644
index 0000000..9b6ff7a
--- /dev/null
+++ b/examples/example_jupyter/instructor/cs105/unitgrade/Week1.pkl
@@ -0,0 +1 @@
+�N.
\ No newline at end of file
diff --git a/examples/02471/instructor/02471/week02/week2.ipynb b/examples/example_jupyter/instructor/cs105/week2.ipynb
similarity index 100%
rename from examples/02471/instructor/02471/week02/week2.ipynb
rename to examples/example_jupyter/instructor/cs105/week2.ipynb
diff --git a/examples/example_jupyter/students/cs105/.coverage b/examples/example_jupyter/students/cs105/.coverage
new file mode 100644
index 0000000000000000000000000000000000000000..572452543e2092b38f99ec9afedd779fdc155f29
GIT binary patch
literal 53248
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

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/students/cs105/__pycache__/homework1.cpython-38.pyc b/examples/example_jupyter/students/cs105/__pycache__/homework1.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..405a1c978c8bf2114f9b470bfd5312fb8f02188f
GIT binary patch
literal 187
zcmWIL<>g{vU|{$cp_?eqz`*br#6iZ43=9ko3=9m#EDQ_`DGb33nv8xc8Hzx{2;x_Q
zvsFxJacWU<Oi5`*YK%*Ma%paAUP*CGX<lYYdQoCZYJ5RaW?5oMYD{WHVs1fBYB7uv
zpH*5=S&~{5lbKgsQdF8;l3x^)Tx@7y8k3Qqn_8Y<lx?V2P<e~PCO1E&G$+*#Wb<c`
F3juJhGy4Dl

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/students/cs105/__pycache__/report5.cpython-38.pyc b/examples/example_jupyter/students/cs105/__pycache__/report5.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c80ebb8aac0fa657aacc6cb4b52f65783b2e1ec8
GIT binary patch
literal 2312
zcmWIL<>g{vU|={t-5_xjD+9x05C<8vFfcGUFfcF_Ph((UNMT4}%wfo7jAG1Xieh2}
z@tJa%b6KKTz-;Cm)+p8#h7{%;wkWm~h7^_@hFtb2_FRrA4n~F))+kPQh7`6G_7;W|
z_Ee^3<|r<Ah7^tz&K8CgPB5R_ogsxQg}a3zg*%nInK_EbogsxMg|~$vg*TP4nK_C#
zl`n-ao2h70DoZMFGea{YBSQ*vFoP!lOOT5-nQpNKr55BDmE7VC4M{C7aZW5w)nvRS
zo?4ceQ<_+k8easKjV~@KO-aow@zZ3w#pRq>P*PfynU`*KixbZN#a*77nr)<)Sx}jm
zlngQ(8N)+FkAZ<9l_82Tg&~S5l{tkmg=r3B3Udle3rjO&6iW(g3R??96l)553P%e=
z6k7^oFoP!NE!ObV)NDh)m5jI8ic(8Ti}I2gkqig1IT;ujoIxS3!oa{#!qCjnFT%)B
z!kERhfVqTaA!7|gJZm_EDMKJb5JLn*3PUi%N=83Twjx#r28LT4nYo|<$V<A#;g?^M
znv|cPeTyY0KQZMNOIl`5>Mf?cq?L@fn3HpgS27d{GcYjxigUJ#2`x@7Dvl{B%}9-L
z$xklLP0cGQjw#K{EJ-g)Oi7I|D9S8LEJ=+?tw_u*$Vn}RG2*jI3o1)ei()eKic5-0
zlS}f8Vv>su4NPMo0d1;RP<e~1IJG3Sz&R(exESQIVo>NYFmW(e34jAa4<U^a5Nxo3
zFkoO{s9{(D4TKcN6vl;2DNGBQ7*R!;7BZzUgG51rqRHa-l8J$V;U&nzmmCZX44N#r
zxD$(uQ;SMm3riDoia=sT0-#W1&8<u;&0EQMi={X<Ck-4f5JChb%TbbAToRv{lEMdy
z6p(QYjAD#cd=U4;Br#kMQV5PlkRdSFXEB4^4$3US44O=SRlFIgIXU?X<@rT9DGElK
zEJczG3=BvvV=hZ9Dv}0?fg%gZQ9NLKi&D!{i;7c)Kn??WmVvQK2+3JcX-)Q99P#ma
ziMgrq@wd3*<8$*<N^?MLp7?lBNI+${lR=S`n_7~QpHd_WvQrjB$b$%k?O+zjOJG-m
z!mt=ba4<443b1gnfJJd<86%`DlfoFqoWdBzlFEvfb=XqbA(^L{F^U76ZP;&d`8mO|
zv|kY?0|Ns_c!LDN;jISCHe#@BQ^SyjHRBX<gOUX#>lE>T{K*R<K=FKwBM+8;nB()3
ziUdItV84S2Z~%b92ozt4G%bp7CBB3W%H?3Ef<mr_A&Vi4F_;137^YjC@$uk@h>tG<
z`2<_+gHx>>Jkpt}c#-VQOVZ>lQUEzu5kx3~2vraPHcc7C0y+E^M?q13L26M+CD=4b
z(gOPpOn^NIDuBd5)_}r>gOP=i1suyvj71<Bj93PxKyXzdfga0DDa<VlQ7kDe!3>(L
zw>Se!Q;SP7^Ye^~*s;YVJl})N0p*+;hAhSfOrTV<kZB>P&}Rr{&}8;20=caSq)3xF
ziU%ocJ43uA1@bGF%u@tP*B~DhgIo;CGjIp#fwNU&N{XK*E7m{+X~h~=nhXpKps)rf
z22fZPfkZIEh#6L$f?@+!d4O_4DoYAe8dEB33UeA$I#U!|DtkI8^+Q684^pogdO-@@
zDt_l+1w#W<1&FYM=}S-@4h{)FjL5&mT9R3klM2q5U^hi^7DB_n_!ehIer{@ceo?kz
z6i-27a&|nV{wT)kMJ)yf26a$!0NDoeA{!&ye-`E<kT|G>$xY16i;vgjj}nE~9Y%Tx
zW)Uc~i$DPoC5sS6D2UHU%_&GNDmE$t6`e)8px6T?JaElc1WFV|{2(z<rU55Fuy4S&
wL!t_ta1jJ33E$$dfs}T3pgdO$N-zS9Jd7NS9E<`?EQ|tt0z3k&0_+^j050p;!~g&Q

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/students/cs105/__pycache__/week2.cpython-38.pyc b/examples/example_jupyter/students/cs105/__pycache__/week2.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d81c0675c7056e7e11ab8b96d289c407997be566
GIT binary patch
literal 466
zcmWIL<>g{vU|?{asFQe(fq~&Mh=Yuo85kHG7#J9e?HCvsQW&BbQW&EcQ<zeiTNt94
zQkha%QdparQrN^9qL@=zQW={W85vSpQkg+?3VRf53P%cO3qurJ3Rf_LCU=#fvVv<x
zYEg1#ajJrmo{^p*R~2tYYEDkRLV12sPKtt2G82;JAT|g)gY4&EU|^_Ws9_Xg2xib^
z^jpcG$#jb`@fKrJ5hDWw1DLqQU7nhnZKRi3P??u>i#4}0tu#*tq!(le17i^@0|UcL
z5c?&_S1&;xfBA}mfgu@W0?b|z8zc?3l#hXdp@gA^A%(G-DTPTKWHqy25gW)HkUC9>
znVO8Z7*oJ5fDkMU3=AOab4zoyk*w!oU|{gmWWU88AD@z+93Ov+xh$~=?5JC8`K2WV
zr6spm3yL!HN^UV$6@e5(Oaoa2VS&x%u*uC&Da}c>V+R=xav+Nc3nK?JA0r1N2PX?7
E09j2^v;Y7A

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/students/cs105/homework1.py b/examples/example_jupyter/students/cs105/homework1.py
new file mode 100644
index 0000000..80562c2
--- /dev/null
+++ b/examples/example_jupyter/students/cs105/homework1.py
@@ -0,0 +1,4 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+# This file is blank.
diff --git a/examples/example_jupyter/students/cs105/report5.py b/examples/example_jupyter/students/cs105/report5.py
new file mode 100644
index 0000000..e91cba1
--- /dev/null
+++ b/examples/example_jupyter/students/cs105/report5.py
@@ -0,0 +1,52 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+from src.unitgrade2.unitgrade2 import Report,  UTestCase
+from src.unitgrade2 import evaluate_report_student
+import homework1
+import importnb
+from src.unitgrade2.unitgrade2 import Capturing2
+
+file = 'week2.ipynb'
+class Week1(UTestCase):
+    @classmethod
+    def setUpClass(cls) -> None:
+        with Capturing2():
+            cls.nb = importnb.Notebook.load(file)
+
+    def test_add(self):
+        self.assertEqual(Week1.nb.myfun(2,2), 4)
+        self.assertEqual(Week1.nb.myfun(2,4), 8)
+
+    def test_reverse(self):
+        self.assertEqual(Week1.nb.var, "hello world 2")
+
+# Nicer: Automatically load the notebook.
+class NBTestCase(UTestCase):
+    notebook = None
+    _nb = None
+    @classmethod
+    def setUpClass(cls) -> None:
+        with Capturing2():
+            cls._nb = importnb.Notebook.load(cls.notebook)
+
+    @property
+    def nb(self):
+        return self.__class__._nb
+
+class Question2(NBTestCase):
+    notebook = "week2.ipynb"
+    def test_add(self):
+        self.assertEqualC(self.nb.myfun(2,8))
+
+class Report1Jupyter(Report):
+    title = "CS 105 Report 5"
+    questions = [(Week1, 10),
+                 (Question2, 8)
+                 ]  # Include a single question for 10 credits.
+    pack_imports = [homework1]
+
+if __name__ == "__main__":
+    # Uncomment to simply run everything as a unittest:
+    # unittest.main(verbosity=2)
+    evaluate_report_student(Report1Jupyter())
diff --git a/examples/example_jupyter/students/cs105/report5_grade.py b/examples/example_jupyter/students/cs105/report5_grade.py
new file mode 100644
index 0000000..b059908
--- /dev/null
+++ b/examples/example_jupyter/students/cs105/report5_grade.py
@@ -0,0 +1,338 @@
+"""
+Example student code. This file is automatically generated from the files in the instructor-directory
+"""
+import numpy as np
+from tabulate import tabulate
+from datetime import datetime
+import pyfiglet
+import unittest
+import inspect
+import os
+import argparse
+import time
+
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
+To run all tests in a report: 
+
+> python assignment1_dp.py
+
+To run only question 2 or question 2.1
+
+> python assignment1_dp.py -q 2
+> python assignment1_dp.py -q 2.1
+
+Note this scripts does not grade your report. To grade your report, use:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-q', nargs='?', type=str, default=None, help='Only evaluate this question (e.g.: -q 2)')
+parser.add_argument('--showexpected',  action="store_true",  help='Show the expected/desired result')
+parser.add_argument('--showcomputed',  action="store_true",  help='Show the answer your code computes')
+parser.add_argument('--unmute',  action="store_true",  help='Show result of print(...) commands in code')
+parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
+
+def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
+    args = parser.parse_args()
+    if question is None and args.q is not None:
+        question = args.q
+        if "." in question:
+            question, qitem = [int(v) for v in question.split(".")]
+        else:
+            question = int(question)
+
+    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:
+        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")
+
+    if unmute is None:
+        unmute = args.unmute
+    if passall is None:
+        passall = args.passall
+
+    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,
+                                          show_tol_err=show_tol_err)
+
+
+    if question is None:
+        print("Provisional evaluation")
+        tabulate(table_data)
+        table = table_data
+        print(tabulate(table))
+        print(" ")
+
+    fr = inspect.getouterframes(inspect.currentframe())[1].filename
+    gfile = os.path.basename(fr)[:-3] + "_grade.py"
+    if os.path.exists(gfile):
+        print("Note your results have not yet been registered. \nTo register your results, please run the file:")
+        print(">>>", gfile)
+        print("In the same manner as you ran this file.")
+
+
+    return results
+
+
+def upack(q):
+    # h = zip([(i['w'], i['possible'], i['obtained']) for i in q.values()])
+    h =[(i['w'], i['possible'], i['obtained']) for i in q.values()]
+    h = np.asarray(h)
+    return h[:,0], h[:,1], h[:,2],
+
+class UnitgradeTextRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        # testcase_methods = list(testCaseClass.__dict__.keys())
+        ls = []
+        for C in testCaseClass.mro():
+            if issubclass(C, unittest.TestCase):
+                ls = list(C.__dict__.keys()) + ls
+        testcase_methods = ls
+        test_names.sort(key=testcase_methods.index)
+        return test_names
+
+def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
+                    show_progress_bar=True,
+                    show_tol_err=False,
+                    big_header=True):
+
+    now = datetime.now()
+    if big_header:
+        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")
+        b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
+    else:
+        b = "Unitgrade"
+    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
+    s = report.title
+    if hasattr(report, "version") and report.version is not None:
+        s += " version " + report.version
+    print(s, "(use --help for options)" if show_help_flag else "")
+    # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
+    table_data = []
+    t_start = time.time()
+    score = {}
+    loader = SequentialTestLoader()
+
+    for n, (q, w) in enumerate(report.questions):
+        if question is not None and n+1 != question:
+            continue
+        suite = loader.loadTestsFromTestCase(q)
+        qtitle = q.question_title() if hasattr(q, 'question_title') else q.__qualname__
+        q_title_print = "Question %i: %s"%(n+1, qtitle)
+        print(q_title_print, end="")
+        q.possible = 0
+        q.obtained = 0
+        q_ = {} # Gather score in this class.
+        UTextResult.q_title_print = q_title_print # Hacky
+        UTextResult.show_progress_bar = show_progress_bar # Hacky.
+        UTextResult.number = n
+        UTextResult.nL = report.nL
+
+        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
+
+        possible = res.testsRun
+        obtained = len(res.successes)
+
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
+
+        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
+        score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
+        q.obtained = obtained
+        q.possible = possible
+
+        s1 = f" * q{n+1}) Total"
+        s2 = f" {q.obtained}/{w}"
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
+        print(" ")
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
+
+    ws, possible, obtained = upack(score)
+    possible = int( msum(possible) )
+    obtained = int( msum(obtained) ) # Cast to python int
+    report.possible = possible
+    report.obtained = obtained
+    now = datetime.now()
+    dt_string = now.strftime("%H:%M:%S")
+
+    dt = int(time.time()-t_start)
+    minutes = dt//60
+    seconds = dt - minutes*60
+    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
+
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
+
+    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
+    results = {'total': (obtained, possible), 'details': score}
+    return results, table_data
+
+
+from tabulate import tabulate
+from datetime import datetime
+import inspect
+import json
+import os
+import bz2
+import pickle
+import os
+
+def bzwrite(json_str, token): # to get around obfuscation issues
+    with getattr(bz2, 'open')(token, "wt") as f:
+        f.write(json_str)
+
+def gather_imports(imp):
+    resources = {}
+    m = imp
+    # for m in pack_imports:
+    # print(f"*** {m.__name__}")
+    f = m.__file__
+    # dn = os.path.dirname(f)
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
+        top_package = os.path.dirname(m.__file__)
+        module_import = True
+    else:
+        top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
+        module_import = False
+
+    # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
+    # top_package = os.path.dirname(top_package)
+    import zipfile
+    # import strea
+    # zipfile.ZipFile
+    import io
+    # file_like_object = io.BytesIO(my_zip_data)
+    zip_buffer = io.BytesIO()
+    with zipfile.ZipFile(zip_buffer, 'w') as zip:
+        # zip.write()
+        for root, dirs, files in os.walk(top_package):
+            for file in files:
+                if file.endswith(".py"):
+                    fpath = os.path.join(root, file)
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
+                    zip.write(fpath, v)
+
+    resources['zipfile'] = zip_buffer.getvalue()
+    resources['top_package'] = top_package
+    resources['module_import'] = module_import
+    return resources, top_package
+
+    if f.endswith("__init__.py"):
+        for root, dirs, files in os.walk(os.path.dirname(f)):
+            for file in files:
+                if file.endswith(".py"):
+                    # print(file)
+                    # print()
+                    v = os.path.relpath(os.path.join(root, file), top_package)
+                    with open(os.path.join(root, file), 'r') as ff:
+                        resources[v] = ff.read()
+    else:
+        v = os.path.relpath(f, top_package)
+        with open(f, 'r') as ff:
+            resources[v] = ff.read()
+    return resources
+
+import argparse
+parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Use this script to get the score of your report. Example:
+
+> python report1_grade.py
+
+Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
+For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
+
+> python -m course_package.report1
+
+see https://docs.python.org/3.9/using/cmdline.html
+""", formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('--noprogress',  action="store_true",  help='Disable progress bars')
+parser.add_argument('--autolab',  action="store_true",  help='Show Autolab results')
+
+def gather_upload_to_campusnet(report, output_dir=None):
+    n = report.nL
+    args = parser.parse_args()
+    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
+                                          show_progress_bar=not args.noprogress,
+                                          big_header=not args.autolab)
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
+    # also load the source code of missing files...
+
+    sources = {}
+    print("")
+    if not args.autolab:
+        if len(report.individual_imports) > 0:
+            print("By uploading the .token file, you verify the files:")
+            for m in report.individual_imports:
+                print(">", m.__file__)
+            print("Are created/modified individually by you in agreement with DTUs exam rules")
+            report.pack_imports += report.individual_imports
+
+        if len(report.pack_imports) > 0:
+            print("Including files in upload...")
+            for k, m in enumerate(report.pack_imports):
+                nimp, top_package = gather_imports(m)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
+                nimp['name'] = m.__name__
+                sources[k] = nimp
+                # if len([k for k in nimp if k not in sources]) > 0:
+                print(f" * {m.__name__}")
+                # sources = {**sources, **nimp}
+    results['sources'] = sources
+
+    if output_dir is None:
+        output_dir = os.getcwd()
+
+    payload_out_base = report.__class__.__name__ + "_handin"
+
+    obtain, possible = results['total']
+    vstring = "_v"+report.version if report.version is not None else ""
+
+    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
+    token = os.path.join(output_dir, token)
+    with open(token, 'wb') as f:
+        pickle.dump(results, f)
+
+    if not args.autolab:
+        print(" ")
+        print("To get credit for your results, please upload the single unmodified file: ")
+        print(">", token)
+        # print("To campusnet without any modifications.")
+
+        # print("Now time for some autolab fun")
+
+def source_instantiate(name, report1_source, payload):
+    eval("exec")(report1_source, globals())
+    pl = pickle.loads(bytes.fromhex(payload))
+    report = eval(name)(payload=pl, strict=True)
+    # report.set_payload(pl)
+    return report
+
+
+
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            # print(self.questions)\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                print("q is", q())\n                q()._cache_put(\'time\', q.time) # = q.time\n                report_cache[q.__qualname__] = q._cache2\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            # self._stdout = sys.stdout\n            # sys._stdout = io.StringIO()\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f" * q{n+1}) Total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nimport homework1\nimport importnb\n\nfile = \'week2.ipynb\'\nclass Week1(UTestCase):\n    @classmethod\n    def setUpClass(cls) -> None:\n        with Capturing2():\n            cls.nb = importnb.Notebook.load(file)\n\n    def test_add(self):\n        self.assertEqual(Week1.nb.myfun(2,2), 4)\n        self.assertEqual(Week1.nb.myfun(2,4), 8)\n\n    def test_reverse(self):\n        self.assertEqual(Week1.nb.var, "hello world 2")\n\n# Nicer: Automatically load the notebook.\nclass NBTestCase(UTestCase):\n    notebook = None\n    _nb = None\n    @classmethod\n    def setUpClass(cls) -> None:\n        with Capturing2():\n            cls._nb = importnb.Notebook.load(cls.notebook)\n\n    @property\n    def nb(self):\n        return self.__class__._nb\n\nclass Question2(NBTestCase):\n    notebook = "week2.ipynb"\n    def test_add(self):\n        self.assertEqualC(self.nb.myfun(2,8))\n\nclass Report1Jupyter(Report):\n    title = "CS 105 Report 5"\n    questions = [(Week1, 10),\n                 (Question2, 8)\n                 ]  # Include a single question for 10 credits.\n    pack_imports = [homework1]'
+report1_payload = '8004955c000000000000007d94288c055765656b31947d948c0474696d6594473fed915600000000738c095175657374696f6e32947d942868048c08746573745f6164649486948c066173736572749486947d944b004b10736803473fcc28f40000000075752e'
+name="Report1Jupyter"
+
+report = source_instantiate(name, report1_source, report1_payload)
+output_dir = os.path.dirname(__file__)
+gather_upload_to_campusnet(report, output_dir)
diff --git a/examples/example_jupyter/students/cs105/unitgrade/Question2.pkl b/examples/example_jupyter/students/cs105/unitgrade/Question2.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..b08cef102cf660c34ffd24ee8633b7254630acac
GIT binary patch
literal 58
zcmZo*nX1nK0ku<lI0H*li%T-|^NgnSaFnDLm&7Ngq)cg>(!-WmT%1}|GNo-w?G$eY
JZ-L@sJpdXr6f^(;

literal 0
HcmV?d00001

diff --git a/examples/example_jupyter/students/cs105/unitgrade/Week1.pkl b/examples/example_jupyter/students/cs105/unitgrade/Week1.pkl
new file mode 100644
index 0000000..9b6ff7a
--- /dev/null
+++ b/examples/example_jupyter/students/cs105/unitgrade/Week1.pkl
@@ -0,0 +1 @@
+�N.
\ No newline at end of file
diff --git a/examples/example_jupyter/students/cs105/week2.ipynb b/examples/example_jupyter/students/cs105/week2.ipynb
new file mode 100644
index 0000000..6bc411a
--- /dev/null
+++ b/examples/example_jupyter/students/cs105/week2.ipynb
@@ -0,0 +1,69 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercise 2.2.1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "hello world\n",
+      "6\n"
+     ]
+    }
+   ],
+   "source": [
+    "var = \"hello world 2\"\n",
+    "def myfun(a,b):\n",
+    "    return a*b\n",
+    "\n",
+    "output = myfun(2,3) + 10\n",
+    "print(var)\n",
+    "print(output)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "z = 234 \n",
+    "def mymul(d):\n",
+    "    return myfun(d,2)+1"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/examples/example_simplest/instructor/cs101/Report1_handin_10_of_10.token b/examples/example_simplest/instructor/cs101/Report1_handin_10_of_10.token
index 5d34d0fd91b71eecb9ff050591857b09f382421b..1884f587f74133902500c7b2e2ea1095e067afd8 100644
GIT binary patch
delta 8583
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
K$(I(F>Hz?298FLF

delta 27054
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
PN)Idef~6^?#ie=x%)J)u

diff --git a/examples/example_simplest/instructor/cs101/__pycache__/deploy.cpython-38.pyc b/examples/example_simplest/instructor/cs101/__pycache__/deploy.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6e14e2ac2aed2a082d17689ac69828e53aeba409
GIT binary patch
literal 911
zcmWIL<>g{vU|^^b)=Qks%)sy%#6iaF3=9ko3=9m#3m6y}QW#Pga~N_NqZk=MY^EHh
zT;?cdFq=7tC6_gd70hPIVT)o*VMt-gVUJ=@WzXVRz?sUmkTHrol_!NYo2h6{Dsw7h
z3L6x%_p&lFq_SqQrgEonh%=;er*Mihq;REhr|_ikrZcDT^|CNBr0}~i#L7hRrm`*I
zOXW@x0IL%eXGrB0XIRL@$WU09!V=7&DfANLc1^}x>_Mpo`9&p$nvA!^i&INV3*ys@
z5>ry+(=u~X<BPy@nvAzNit{oH;!`q<{BCi?$LA(y=EcXmX|hDI<!0t(rd399<|n0<
z7AGf`q(-r)R-`7EmZV0pBvoY=RB`I->FFmI8yXl^iGrAVdiupBr75X-CB+cokXzjG
z@dcI1iOCtM@$pscT6!h<*{OL|oGGaVIr)`(1(ljCQC!9OrA5i9AQwb&q@)&?fLWr+
zIjM<x@gRO?USdgRejZquJ+&e^r!*y1lex-5PY-HoYDHphK~8FXT2W$dYI%N9wti+_
zaY<2Wa!Gy>*da#x8Tk+yL%o8^DpL%dDf!9SsYU48j8V0jV`xjuNi0FvWC#{Sv5yzU
zoL`Lkn*33`;BeD}#DZZF69WT7lv-(CW(g#U3W_qz5=&Bz^fEG2Qd0BclZ#RlOCT{<
zT*M4g%npjSg4CiS77&lEIHR;AGv^jle(^1qg2a-HTkI*BMR|$2sh~&&M|gY`Q+W!A
z2NI2szr~n#izPX~pmHTc5kCV1g!mQbY!wq)oLW>IQ&O6d8sn0mT$&4t&ln7+#Xv*7
z7{-V%&IH9maY+m!^kcxjjDbh@Ee@O9{FKt1R69mcb`oM>VBlc{K><b{CJsg+W(8&r
FW&j@s6|(>U

literal 0
HcmV?d00001

diff --git a/examples/example_simplest/instructor/cs101/__pycache__/report1_grade.cpython-38.pyc b/examples/example_simplest/instructor/cs101/__pycache__/report1_grade.cpython-38.pyc
index 3b0930bdcddcda845eef8dfac07d6ab732a2473f..aed06f7cf667b51f32903bf52b3c17138bda2777 100644
GIT binary patch
delta 2862
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
R1*rgGCJq)3v&r&5r2z5IKuG`q

delta 7319
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

diff --git a/examples/example_simplest/instructor/cs101/deploy.py b/examples/example_simplest/instructor/cs101/deploy.py
index 3e9682d..b51f79c 100644
--- a/examples/example_simplest/instructor/cs101/deploy.py
+++ b/examples/example_simplest/instructor/cs101/deploy.py
@@ -1,16 +1,19 @@
-from report1 import Report1
+from cs101.report1 import Report1
 from unitgrade_private2.hidden_create_files import setup_grade_file_report
 from snipper import snip_dir
-import shutil
+import shutil, os
+wd = os.path.dirname(__file__)
 
 if __name__ == "__main__":
-    setup_grade_file_report(Report1, minify=False, obfuscate=False, execute=False)
+    setup_grade_file_report(Report1, minify=False, obfuscate=False, execute=False, bzip=False)
 
     # Deploy the files using snipper: https://gitlab.compute.dtu.dk/tuhe/snipper
-    snip_dir.snip_dir(source_dir="../cs101", dest_dir="../../students/cs101", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
+    snip_dir.snip_dir(source_dir=wd+"/../cs101", dest_dir=wd+"/../../students/cs101", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
 
-    # For my own sake, copy the homework to the other examples.
-    for f in ['../../../example_framework/instructor/cs102/homework1.py', '../../../example_docker/instructor/cs103/homework1.py']:
-        shutil.copy('homework1.py', f)
+    # For my own sake, copy the homework file to the other examples.
+    for f in ['../../../example_framework/instructor/cs102/homework1.py',
+              '../../../example_docker/instructor/cs103/homework1.py',
+              '../../../example_flat/instructor/cs101flat/homework1.py']:
+        shutil.copy(wd+'/homework1.py', wd+"/"+f)
 
 
diff --git a/examples/example_simplest/instructor/cs101/report1.py b/examples/example_simplest/instructor/cs101/report1.py
index e00853f..447cedb 100644
--- a/examples/example_simplest/instructor/cs101/report1.py
+++ b/examples/example_simplest/instructor/cs101/report1.py
@@ -1,5 +1,5 @@
-from unitgrade2.unitgrade2 import Report
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
+from src.unitgrade2.unitgrade2 import Report
+from src.unitgrade2 import evaluate_report_student
 from cs101.homework1 import reverse_list, add
 import unittest
 
diff --git a/examples/example_simplest/instructor/cs101/report1_grade.py b/examples/example_simplest/instructor/cs101/report1_grade.py
index 8972ab5..7f2feaa 100644
--- a/examples/example_simplest/instructor/cs101/report1_grade.py
+++ b/examples/example_simplest/instructor/cs101/report1_grade.py
@@ -4,14 +4,10 @@ from tabulate import tabulate
 from datetime import datetime
 import pyfiglet
 import unittest
-
 import inspect
 import os
 import argparse
-import sys
 import time
-import threading # don't import Thread bc. of minify issue.
-import tqdm # don't do from tqdm import tqdm because of minify-issue
 
 parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
 To run all tests in a report: 
@@ -61,53 +57,6 @@ def evaluate_report_student(report, question=None, qitem=None, unmute=None, pass
                                           show_tol_err=show_tol_err)
 
 
-    # try:  # For registering stats.
-    #     import unitgrade_private
-    #     import irlc.lectures
-    #     import xlwings
-    #     from openpyxl import Workbook
-    #     import pandas as pd
-    #     from collections import defaultdict
-    #     dd = defaultdict(lambda: [])
-    #     error_computed = []
-    #     for k1, (q, _) in enumerate(report.questions):
-    #         for k2, item in enumerate(q.items):
-    #             dd['question_index'].append(k1)
-    #             dd['item_index'].append(k2)
-    #             dd['question'].append(q.name)
-    #             dd['item'].append(item.name)
-    #             dd['tol'].append(0 if not hasattr(item, 'tol') else item.tol)
-    #             error_computed.append(0 if not hasattr(item, 'error_computed') else item.error_computed)
-    #
-    #     qstats = report.wdir + "/" + report.name + ".xlsx"
-    #
-    #     if os.path.isfile(qstats):
-    #         d_read = pd.read_excel(qstats).to_dict()
-    #     else:
-    #         d_read = dict()
-    #
-    #     for k in range(1000):
-    #         key = 'run_'+str(k)
-    #         if key in d_read:
-    #             dd[key] = list(d_read['run_0'].values())
-    #         else:
-    #             dd[key] = error_computed
-    #             break
-    #
-    #     workbook = Workbook()
-    #     worksheet = workbook.active
-    #     for col, key in enumerate(dd.keys()):
-    #         worksheet.cell(row=1, column=col+1).value = key
-    #         for row, item in enumerate(dd[key]):
-    #             worksheet.cell(row=row+2, column=col+1).value = item
-    #
-    #     workbook.save(qstats)
-    #     workbook.close()
-    #
-    # except ModuleNotFoundError as e:
-    #     s = 234
-    #     pass
-
     if question is None:
         print("Provisional evaluation")
         tabulate(table_data)
@@ -159,24 +108,20 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
     else:
         b = "Unitgrade"
-    print(b + " v" + __version__)
     dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
-    print("Started: " + dt_string)
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
     s = report.title
     if hasattr(report, "version") and report.version is not None:
         s += " version " + report.version
-    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
+    print(s, "(use --help for options)" if show_help_flag else "")
     # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
     table_data = []
-    nL = 80
     t_start = time.time()
     score = {}
     loader = SequentialTestLoader()
 
     for n, (q, w) in enumerate(report.questions):
-        # q = q()
-        # q_hidden = False
-        # q_hidden = issubclass(q.__class__, Hidden)
         if question is not None and n+1 != question:
             continue
         suite = loader.loadTestsFromTestCase(q)
@@ -186,104 +131,28 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         q.possible = 0
         q.obtained = 0
         q_ = {} # Gather score in this class.
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
         UTextResult.q_title_print = q_title_print # Hacky
         UTextResult.show_progress_bar = show_progress_bar # Hacky.
         UTextResult.number = n
+        UTextResult.nL = report.nL
 
         res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
-        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)
-        z = 234
-        # for j, item in enumerate(q.items):
-        #     if qitem is not None and question is not None and j+1 != qitem:
-        #         continue
-        #
-        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.
-        #         # if not item.question.has_called_init_:
-        #         start = time.time()
-        #
-        #         cc = None
-        #         if show_progress_bar:
-        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )
-        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)
-        #         from unitgrade import Capturing # DON'T REMOVE THIS LINE
-        #         with eval('Capturing')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.
-        #             try:
-        #                 for q2 in q_with_outstanding_init:
-        #                     q2.init()
-        #                     q2.has_called_init_ = True
-        #
-        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.
-        #             except Exception as e:
-        #                 if not passall:
-        #                     if not silent:
-        #                         print(" ")
-        #                         print("="*30)
-        #                         print(f"When initializing question {q.title} the initialization code threw an error")
-        #                         print(e)
-        #                         print("The remaining parts of this question will likely fail.")
-        #                         print("="*30)
-        #
-        #         if show_progress_bar:
-        #             cc.terminate()
-        #             sys.stdout.flush()
-        #             print(q_title_print, end="")
-        #
-        #         q_time =np.round(  time.time()-start, 2)
-        #
-        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")
-        #         print("=" * nL)
-        #         q_with_outstanding_init = None
-        #
-        #     # item.question = q # Set the parent question instance for later reference.
-        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)
-        #
-        #     if show_progress_bar:
-        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)
-        #     else:
-        #         print(item_title_print + ( '.'*max(0, nL-4-len(ss)) ), end="")
-        #     hidden = issubclass(item.__class__, Hidden)
-        #     # if not hidden:
-        #     #     print(ss, end="")
-        #     # sys.stdout.flush()
-        #     start = time.time()
-        #
-        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)
-        #     q_[j] = {'w': item.weight, 'possible': possible, 'obtained': current, 'hidden': hidden, 'computed': str(item._computed_answer), 'title': item.title}
-        #     tsecs = np.round(time.time()-start, 2)
-        #     if show_progress_bar:
-        #         cc.terminate()
-        #         sys.stdout.flush()
-        #         print(item_title_print + ('.' * max(0, nL - 4 - len(ss))), end="")
-        #
-        #     if not hidden:
-        #         ss = "PASS" if current == possible else "*** FAILED"
-        #         if tsecs >= 0.1:
-        #             ss += " ("+ str(tsecs) + " seconds)"
-        #         print(ss)
-
-        # ws, possible, obtained = upack(q_)
 
         possible = res.testsRun
         obtained = len(res.successes)
 
         assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
 
-        # possible = int(ws @ possible)
-        # obtained = int(ws @ obtained)
-        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
-
         obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
         score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
         q.obtained = obtained
         q.possible = possible
 
-        s1 = f"*** Question q{n+1}"
+        s1 = f"Question {n+1} total"
         s2 = f" {q.obtained}/{w}"
-        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
         print(" ")
-        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
 
     ws, possible, obtained = upack(score)
     possible = int( msum(possible) )
@@ -298,15 +167,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
     seconds = dt - minutes*60
     plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
 
-    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
 
     table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
     results = {'total': (obtained, possible), 'details': score}
     return results, table_data
 
 
-
-
 from tabulate import tabulate
 from datetime import datetime
 import inspect
@@ -329,7 +199,8 @@ def gather_imports(imp):
     # dn = os.path.dirname(f)
     # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
     # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
         top_package = os.path.dirname(m.__file__)
         module_import = True
     else:
@@ -350,7 +221,7 @@ def gather_imports(imp):
             for file in files:
                 if file.endswith(".py"):
                     fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
                     zip.write(fpath, v)
 
     resources['zipfile'] = zip_buffer.getvalue()
@@ -394,14 +265,14 @@ def gather_upload_to_campusnet(report, output_dir=None):
     results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
                                           show_progress_bar=not args.noprogress,
                                           big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
     # also load the source code of missing files...
 
     sources = {}
-
+    print("")
     if not args.autolab:
         if len(report.individual_imports) > 0:
             print("By uploading the .token file, you verify the files:")
@@ -414,12 +285,15 @@ def gather_upload_to_campusnet(report, output_dir=None):
             print("Including files in upload...")
             for k, m in enumerate(report.pack_imports):
                 nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
                 nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
                 nimp['name'] = m.__name__
                 sources[k] = nimp
                 # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
+                print(f" * {m.__name__}")
                 # sources = {**sources, **nimp}
     results['sources'] = sources
 
@@ -438,9 +312,9 @@ def gather_upload_to_campusnet(report, output_dir=None):
 
     if not args.autolab:
         print(" ")
-        print("To get credit for your results, please upload the single file: ")
+        print("To get credit for your results, please upload the single unmodified file: ")
         print(">", token)
-        print("To campusnet without any modifications.")
+        # print("To campusnet without any modifications.")
 
         # print("Now time for some autolab fun")
 
@@ -453,7 +327,7 @@ def source_instantiate(name, report1_source, payload):
 
 
 
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, unmute=False, **kwargs):\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n            # for item in q.items:\n            #     if q.name not in payloads or item.name not in payloads[q.name]:\n            #         s = f"> Broken resource dictionary submitted to unitgrade for question {q.name} and subquestion {item.name}. Framework will not work."\n            #         if strict:\n            #             raise Exception(s)\n            #         else:\n            #             print(s)\n            #     else:\n            #         item._correct_answer_payload = payloads[q.name][item.name][\'payload\']\n            #         item.estimated_time = payloads[q.name][item.name].get("time", 1)\n            #         q.estimated_time = payloads[q.name].get("time", 1)\n            #         if "precomputed" in payloads[q.name][item.name]: # Consider removing later.\n            #             item._precomputed_payload = payloads[q.name][item.name][\'precomputed\']\n            #         try:\n            #             if "title" in payloads[q.name][item.name]: # can perhaps be removed later.\n            #                 item.title = payloads[q.name][item.name][\'title\']\n            #         except Exception as e: # Cannot set attribute error. The title is a function (and probably should not be).\n            #             pass\n            #             # print("bad", e)\n        # self.payloads = payloads\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\nclass MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n    pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        item_title = item_title.split("\\n")[0]\n\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 2\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    @classmethod\n    def question_title(cls):\n        return cls.__doc__.splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    # def _callSetUp(self):\n    #     # Always run before method is called.\n    #     print("asdf")\n    #     pass\n    # @classmethod\n    # def setUpClass(cls):\n    #     # self._cache_put((self.cache_id(), \'title\'), value)\n    #     cls.reset()\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    # def unique_cache_id(self):\n    #     k0 = self.cache_id()\n    #     # key = ()\n    #     i = 0\n    #     for i in itertools.count():\n    #         # key = k0 + (i,)\n    #         if i not in self._cache_get( (k0, \'assert\') ):\n    #             break\n    #     return i\n    #     return key\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n    #\n    # def _cache2_contains(self, key):\n    #     print("Is this needed?")\n    #     self._ensure_cache_exists()\n    #     return key in self.__class__._cache2\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    # try:  # For registering stats.\n    #     import unitgrade_private\n    #     import irlc.lectures\n    #     import xlwings\n    #     from openpyxl import Workbook\n    #     import pandas as pd\n    #     from collections import defaultdict\n    #     dd = defaultdict(lambda: [])\n    #     error_computed = []\n    #     for k1, (q, _) in enumerate(report.questions):\n    #         for k2, item in enumerate(q.items):\n    #             dd[\'question_index\'].append(k1)\n    #             dd[\'item_index\'].append(k2)\n    #             dd[\'question\'].append(q.name)\n    #             dd[\'item\'].append(item.name)\n    #             dd[\'tol\'].append(0 if not hasattr(item, \'tol\') else item.tol)\n    #             error_computed.append(0 if not hasattr(item, \'error_computed\') else item.error_computed)\n    #\n    #     qstats = report.wdir + "/" + report.name + ".xlsx"\n    #\n    #     if os.path.isfile(qstats):\n    #         d_read = pd.read_excel(qstats).to_dict()\n    #     else:\n    #         d_read = dict()\n    #\n    #     for k in range(1000):\n    #         key = \'run_\'+str(k)\n    #         if key in d_read:\n    #             dd[key] = list(d_read[\'run_0\'].values())\n    #         else:\n    #             dd[key] = error_computed\n    #             break\n    #\n    #     workbook = Workbook()\n    #     worksheet = workbook.active\n    #     for col, key in enumerate(dd.keys()):\n    #         worksheet.cell(row=1, column=col+1).value = key\n    #         for row, item in enumerate(dd[key]):\n    #             worksheet.cell(row=row+2, column=col+1).value = item\n    #\n    #     workbook.save(qstats)\n    #     workbook.close()\n    #\n    # except ModuleNotFoundError as e:\n    #     s = 234\n    #     pass\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)\n        z = 234\n        # for j, item in enumerate(q.items):\n        #     if qitem is not None and question is not None and j+1 != qitem:\n        #         continue\n        #\n        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.\n        #         # if not item.question.has_called_init_:\n        #         start = time.time()\n        #\n        #         cc = None\n        #         if show_progress_bar:\n        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )\n        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)\n        #         from unitgrade import Capturing # DON\'T REMOVE THIS LINE\n        #         with eval(\'Capturing\')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.\n        #             try:\n        #                 for q2 in q_with_outstanding_init:\n        #                     q2.init()\n        #                     q2.has_called_init_ = True\n        #\n        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.\n        #             except Exception as e:\n        #                 if not passall:\n        #                     if not silent:\n        #                         print(" ")\n        #                         print("="*30)\n        #                         print(f"When initializing question {q.title} the initialization code threw an error")\n        #                         print(e)\n        #                         print("The remaining parts of this question will likely fail.")\n        #                         print("="*30)\n        #\n        #         if show_progress_bar:\n        #             cc.terminate()\n        #             sys.stdout.flush()\n        #             print(q_title_print, end="")\n        #\n        #         q_time =np.round(  time.time()-start, 2)\n        #\n        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")\n        #         print("=" * nL)\n        #         q_with_outstanding_init = None\n        #\n        #     # item.question = q # Set the parent question instance for later reference.\n        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)\n        #\n        #     if show_progress_bar:\n        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)\n        #     else:\n        #         print(item_title_print + ( \'.\'*max(0, nL-4-len(ss)) ), end="")\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        #     if show_progress_bar:\n        #         cc.terminate()\n        #         sys.stdout.flush()\n        #         print(item_title_print + (\'.\' * max(0, nL - 4 - len(ss))), end="")\n        #\n        #     if not hidden:\n        #         ss = "PASS" if current == possible else "*** FAILED"\n        #         if tsecs >= 0.1:\n        #             ss += " ("+ str(tsecs) + " seconds)"\n        #         print(ss)\n\n        # ws, possible, obtained = upack(q_)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nfrom cs101.homework1 import reverse_list, add\nimport unittest\n\nclass Week1(unittest.TestCase):\n    def test_add(self):\n        self.assertEqual(add(2,2), 4)\n        self.assertEqual(add(-100, 5), -95)\n\n    def test_reverse(self):\n        self.assertEqual(reverse_list([1,2,3]), [3,2,1])\n        # print("Bad output\\n\\n")\n\n\nimport cs101\nclass Report1(Report):\n    title = "CS 101 Report 1"\n    questions = [(Week1, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs101]'
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"Question {n+1} total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nfrom cs101.homework1 import reverse_list, add\nimport unittest\n\nclass Week1(unittest.TestCase):\n    def test_add(self):\n        self.assertEqual(add(2,2), 4)\n        self.assertEqual(add(-100, 5), -95)\n\n    def test_reverse(self):\n        self.assertEqual(reverse_list([1,2,3]), [3,2,1])\n\n\nimport cs101\nclass Report1(Report):\n    title = "CS 101 Report 1"\n    questions = [(Week1, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs101]'
 report1_payload = '8004953f000000000000007d948c055765656b31947d948c2c6e6f20636163686520736565205f73657475705f616e737765727320696e20756e69746772616465322e7079948873732e'
 name="Report1"
 
diff --git a/examples/example_simplest/students/cs101/Report1_handin_0_of_10.token b/examples/example_simplest/students/cs101/Report1_handin_0_of_10.token
deleted file mode 100644
index 5ccd4e5495ad2bbfe4c3cc09832916b356f0d31b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 77002
zcmZo*nOeyJ0ku;!dRR;HOA>RYcr$o&wN2?^Pf0CF%*-jCQai<)0VK^>KE<1>hod0B
zxHvN@Cl$=ePbx{w%u7v~;?2;*npu*X3sT<0T9R3klRBk`H9R#n+i*&0aSwZOerZv1
zDo7S$7<*M_L0V=`>J+CYZAOLwZ)O$|utSV;<$}46um_kiGcbU#5Ca24a<QR-p?*ew
zZfbdcQMRF8L8X$C5-*o)MPhD2PO3t2Noh)IUWr0-eoCsILP$ntu>#0sh0J1w#L|-d
z+{BX1<iwnuN`>^)ywsw^lGGH1w4(f6g_4X^u)<=6%senBGq1R$s5H4GzeqPFvnUnB
zsO04W+m(`<rcjhxmReMt8lRI{T%wU%38FNu6nME56ciM|ia-qa%(B!xg+v9Atb#g3
zmAXPvYDsBPUNKBOIX|yBv$!NPFI^!&4QzFBVs5HJYEEiyYF-K0Jy6RO@{3YZi}Vy+
z_0shqHbEsIu820&G14)P)l?|X$S=)Ff!d=GZLDLYV;HNTkqEO=6RI2TPGyA<e;0o%
z1w)0L%)HcMh1|^I;><j_C5f5EsS1AiC7z%V201D<#kHs?zeqy~E~1cDnwMOXnV+YS
zl%G<mq{++0%LNLi#FP|`M4cq$pizK?N=bRXLSAWZQfg7LLPBDKLSkNuLPAo4LJ2s^
zV5UL6Qk<DvkW&fsQAtK>W|2a1X|5F{6zmjW)+pF2Bx)xiB7im?%S=;<kIzfYO^uIN
zu(efCijU7t%*>0ASAx1nSs|b(KPe|QSHaLqA-pKFBvm015kTb`naLR-7b_qI0mLH(
zMVWae8fi+A`K3h)MXAN5IVGSpVWgm~V5DHHPz~~?k&cmOEhvCN2@Iwo2%H*0NhndF
zI5#mT2b|=TbWoFNw2_Xnj;W4$tfnR}7iunhai_tehM9o@gazQatSGf0zo=wD@)$T%
zmgZ%aq!%Toq#EfVm<pM>AXg~_fgQ)og;QmGMruw$YEiKfOh;;2VoqsdNoqXAU-8hg
z0%`=fV9|pYEHF*TSxg5MZM<Ai2Y{SZl3H8>O6$oviN(bV;1W&)CaxEfT3q6sSe&W}
zO&6dH0n!i;ipS#AoHUpOC@MjGy~N_;)S?pC!qUVX4Ui&GWa}uHXhM<)PG!1=1_n9`
zrkXkmx|XKkya!SWw+`wB4UiRht%NE>ElzY`B?yu$locQ;Psu4UMIpbmq@c7UCNCxr
zlq^A^0SzE<i1Knl!Uhsuh8hqW<_vJ%pkS+@<Q%MEXkZA9R0TsNh>r_PQ;R{RO0j~i
zLbL`rcy$yE4K!mF6qFS_^OAE)Q$TqOR9NMtD!^1Lq~#YW7#b)f7p10TmJ~xvyMn~z
z?0AUFz{Y`H7YlYS!TcPWmz<vqD)|&j@)cl(QE8q6DBD$*WPmdssC0!zJv73V6<`8-
zpb|o(EVU>pzc{m`($)wXm^hLoG?WZAFmvkXBMd9jlo=U7SPVU<#)EUqK-7tlfCZK4
z1(gbk#R_=^&}>zbm{gjRSdt3MPcS}IIwi3rwInkaE)C<ub6G)UT4s7qY6)Bb7Np>q
zgA@gsdBp{($p|I+#c<V$Md<~JMa8Lbf#OPpB*<d8L`g<bYGMi~DwP#d^7GV7U@i^;
zODH5I>wya6+|0bpv`U4{;^NX&J%r}Mlw1XvzLb1un*t;V4VV%TJ1I3ev9vf9VT>-=
z7?4lEjw}MzUr-0@ITodtf|6VS$oWMYDXGQDMVSSl++eHj3N6VLDj_ums6f<H*HK6<
z$jr%4w^dS7g0_c1O_Gp&g`(0t1yHR3Dt*8$ibMrS83>Z+<+4*Ks4U6I&r?V&F3wEP
z1KDaApHiS#PziDxRDXV6P9-9X87br!A@TGKK`L>Zqo7-;V1&;iumXrFe)%P-kY)hH
z$HfXM`KiSUdHE#@;N*?sX@!t{Oi>+$(&AJr6c<6fYY5LEAW65(JWx|m2V^wJ#>5hZ
z%rs=vL9NDu#3FDdoT!kSpHiBWs-OWXND|XiHFdyk7Er?xVz>gtxe7(8g{7HAsl^H~
zttA<WB??eoI^Y(bZmvQ;I4Z$K6*Ta36Dt*xQbA5nE6vg4<#Nj}QUJ9=6Z4W&bwDmd
zvI^Fw&CFA9$xjBSlVbhk{8CVp6l#+`#8t-e$@!pmTS=;3K_$e=38)GaK;BG*B>|{z
zusib<k~0$X(o+@SEnrajr;e}@(rha#%|i`r-CPA!EA$|40Vk5;)KrCxl9GaAD}DWx
z{N!Rii1+pKi_-Ot^(^&EL8ZBVa&8K!EvlDMlA8l=cI$wGDmSsDB(*3WT%*{+vbJ7O
zVtGhvMTtjhPJvr~5k!q9FBc?B=_RJ5#3w@Yl7_l&p}LMjUSd&tv8}qjx{g9gWkITK
zaY>PmLP}~{Vrfo^tzUj#s*VDv?O?0!4@&c}G8&R5;gyU=s$ROD6*%2$s^hdyw>Tre
zJhcK;Jf)_n>nJEBf}6><O2sAlMXB*6MWv}qItozhf-~~V!RZ60K|dw6II}1f)RqS|
z1_@XLis;f360AwgD=tqhf~0s*he-iyLNOkTO7n6{OHzsQ38DoHX)WmK>1l$j$W6>k
z0hdA`JMmamkXT%tn3F@uE=QDp9Y_<RtkY8nEly1<%~2@NNX=77NlhwEPY3mEK(<19
zD6rT?YZPh}ft!~)@G=gXE($^YS|}S56i^Px-o%_7C@(WT4-~!7j#NA-yV|-X<`k#u
zfO==;@g?~=@u@{c5HVO|2$U)nY(d3FacYqsIQfE7Zm|Zmv5=VtcMT}Zf)XmY2m<NT
zD+CFF%1DqfwEY2U1;W#-tpY?Hq-6z?%1l#G(o+I;cwvf=^nnz>gmo0a-Uc<oKpm7a
zO;BD`C_~n%S6q;jS)!q&r=%H+upu=ETn>ZGf?=4M3bqO$vtV3!t2HxCAtSLkv81F3
z9tBF!WSJ5VNwDDHRMG_d9pvNuV!eXIk_^4fVo*3kwdtX0DhBI9Xu=XhNWL!u_jz3_
zl2gIOw1$$M0=Ua-r4W*ls!&jrstYq-0pcd`;DM5k0?aLmNyQ*H;dhLVf)c!HORdN(
zF40qP&PYwphU7?SNern2a&i(uRX?PK4GPQ5GzCcd1I0U9oI@p`F%IEDA|*3T0h&;;
zXoJZ>^+CCyni6CoBsUl9D3l~7<)p@^B$gy9*eal9AE<wkvJEVPp$WgBC_lX@wYWGw
zDY3{F6nPNWK~tD5IGyPzKpM)aknEuYbFwYeMNp$)g(RpVDAq$RXQ2vUQG`$c6VZX#
zY73!sAYlXYBw-A)2cCVAIp7owF-cjWq^Qyg)JFl;;YF$GnZ+fkMWCi-aY-V)L!u0}
z4B9>fwQ9kwoA`pF%(BFiRG3L1MNl=FMLEfOIjPAdrA4X5SmY~m$}{uQQDnfK<NSiu
zyn@P#99V-kJijPADL+3OixCBhc`2ZAqGE-D6l7_zIm!7sAlozZ^NL|cK`YIaOi=3^
z<Wz{KQc@IbVHGM!P9rBVHz_62N+CKHT9!f7rGkc$zzq~oy#*>?poIrS8q|-=Hq=qj
zDAZAi*8~+esd=Tj;9)yxLeqmKuVPps3egF23Rt(1jsmE}M%7!W2NJ`g1*9z{C0ZS3
zYJ6s1N@|6AtX^V4L26!#Mz$e}^Fhi%7^DScB8GBUHxJ<`m~xm62(t_IKtoD+%||E(
z*@j<zNq!DOxdEv82+D1+q7|fHM?oE=NK*k+N`pg5uOvSQs{>Hu2^Jc-Ohr|#j%)#{
z6wEH<lvW7NA_}(94vJoRN@kIQwt|wrl7co&3=~ixF};eM;tJ?cfikionQ8EX7+NVn
zjKxeODe<6QAE?$%(F3vKQ!A2Fb2OmJ^-A*N!RZ&~Qc(1P!wXthAR-oS5Q=(aM}gBL
zC?OVs+SD3`1_lP0?#WKARIpW0FDlK8SJy5sDbmPBu^ME5W|{&>Rc4+7#7+#SfE1;q
zL}#Z~#wyr?M*=k<Dx<;X8mPzWf%=cB#o*xukZOcCKxu)1fv9na>_d=IAe>Z`ng}ah
zkmW%m_Mn1C!BzoQ2Ep1k5Ep<H6lbKSmMGXNfY>0#dY~3_8A^Ew3d!XB935CVAWDUl
z6us=!N|47eJOMHfY_?u<YEF(uQGU6tp^idweokp_o^5h|j<%sDBv=$|LFOX68{{XD
zokjWO*oqTqSYt*eNFNq!i}K60jc{2F%9&8Rp%lmzL}(NzmZidyCsqZ?Ir+t@@L+{0
z0VV5#5(QsyAJ#9w#4W!x4>F1m8m$3!mO<7)VgWQfW@Kyv(+ZLR)x5BV0G4JbG_b)c
z!DHA;0Y&*`nZ=p;d5Jl&HbQ1Tcz_V32!vq+K^lnm1T?8bWph#$Y>^rp5a)p8AiW7x
z{h)y|kQ@j@<dqZ<jiofu$O?3nNH0CLB)_yIwJ5D9F*mhX116kYT2z#pR{|E*(A11J
zjMW1*CqZQm#OibqSHTuuvLq!Ir-EcP(uy>rt#plJK}8aLfI$hO38^FkxA2NJz{bGR
z3X*fd!yeG_98hPkSRo^^EEP01p-`DxqL7rDnx_D3N~EUfDa7P~24<jb3rLF*-b5?N
zNlh$H1rPgx1`R+Cw*rL*$T|>)hLD||osy0M#6b|}B1w8e=E1;|QMrkEd8tL9lv0^r
zs!)^&l7h~x>4D6JB@M{b7If;O7$gemWR-&2vKoajUn?tQDA+1gWfo{eYh*^Nm#fF>
zC}c*f!zL4<T-bD?dMu>BkqIh03n6*5SVI%mlE_f7rNk77zd`QFE6__UPAn=)tklSW
zrbMWJGNP??3}ST@K(ry0Hj32&`42o4p%4n2r~r*a1eJmU3wau#q69P*01=0U0cdnS
zK0Y%qvm`zqJTkANpatrn=_qJvWtW3kFqNP<DK0HYEz;1`gX=(7i*QSDYGG+=UP)$R
z4#-lU{KS;hB4o!Dmq5f|#)BM^o(gs$XtKf&oGCz41v(0#;X;s@GiY`LrXJ)RkOX)J
z3{+IW+=gKYNEJdmB%ndMmB9ulCl;s1=cblq<fnj40nL$Wpy<$x2iLvv@vtHtVL}c_
zM>Mpp2r?2>Iy-~X2dW9VMfn=Y?glB%Oal+zCV^v4!&wJ0Mh^-vkbBW}fOLUv1iR50
z!(9s63OUeLH%KYS3Fw|flZJ$yUU7a=iAHv6r7gM^J#f1dng~H=LK7lL9YilEzCkfZ
zu>S?>8p3*45H_eR2aQxf$0N}CT9EMxc;5=D2;9+u^`4;JGDznM%7JJDjhe-$<s_!t
zh7^^8#yT={Qu9inN)XWp@(~P!O-AVzg0<pNj52nDqwkiKnI4~!3QGE5mw;jvVq#u?
zIjCy_opsR5%P)sjm6>S@NpM|A6<T6(a%N_H5~KvQRe;S$=s~6>;?uw*jv7j!BETIq
zSE&RVsmv>}RZ7Xv&jl5ZFrOxY=DA|>l=QOlGxIbQqI1BbC^?{1i);sEBn341S*)Q6
zYPaX4=4s^U6_*rc7HDW{D%dF)#413O22yJcWDD2^kVDeJ4uSX>Qr0JdDkp_9P$N1%
z9<+2JGe0jr9%@WVNj%8-ymSRyg}nT7kX>n@xe*N|)f9czTz%C@1yv6#RbMOBV3>y>
zrYZ%OBo>vVrdTO}42By6H5QafA;V~T;CViXd$0}gKpg}f(}C)N3W5eIKwTG5;zf#<
zVg+qm1tri(0jQM$wjWg=#5Slqp%W&cE;z`g#X1T~8lagNU0qO;1xEyAK)zU02^8kw
zR0)y-r)F@AUqK1xci8M_ni9AqO@R&p6@zDetQ5f0?%)|2ScZX)TS11PbQF{zGo_#y
zL$rO6I=^{73bqOs1`rQ`q6RbtVXFX&5j_wAOR>et`9+{MQgtmvX%4uoSFlyUS_Oc|
zCqQ<B%E~-Qr@EZTPBloIvO=MPtwJHpa;Q*zMrKM%YMz3v0=T4rI0QouG|dGqa0~U~
zA>;S)@j40~V9n6v0@8)nwuHqyWT;QuP(jfaJ_L%C7C<_a^YcnF^Gc!p1dvE^DQM+|
ztpX%i^gtA-gfDh0%FhKcKt;VqA(G{V;8Y6oBz#yQ9xMdOhp@hLp^gG#fB-BH>*9j^
z2AaDEwF=|o5n)jXF$OfWlLzYBC<Q|2wG~t|trS#?l~gtIv<-C>APzus5hV4ZXxC9l
z%}cR`r$vxQ3-w?vCk0ytXtIHb!<tZN;_;xxB()043hs#|8L34Ikc0$Y_>@_!0InFJ
zlja~}kY=$%kb+lPp)kHYvm_%vzqF*dBry*(bqa3JfKoE37XuGOaP|U;fQmZk*b69=
zfnpaV3|FX^kysoLTAr1f0yZfgsfG^)H?6>HV)Re~1QcH=;j66Rk(iuai3omVt>BD}
zT-_+xLaHtlF{lwpfq-lVWZ4p^tOV7<pdbQa(2Sq00$3d=bwOHt$W#8H)i|JrJve-A
z!3u-G{?XJcD$UaXCs(AnR|Yks6-Y1<G=vChAn1WY3hV?trdKK0D!}`AAm=NCV<`(;
z{}vi$ph^^^5`-ZgMNn=9MIdq!4bG~t(Jc&#ENC7E=|alD5aU1wV`gLMzz#?fq6}m!
zj+B=PnI;BT6$;7<$>70sP<aOu0ngxrmzU+17K1ue3Xr4*n$s*!El~hxW!P#Fgmn;B
zW*WFB268v<<cift#h@w@)RWE3O+_ib!3HBzDa3Oi!Q^BGTLqAdu}Nm8VWwBC_JT|*
z0j=ST2d$yW1ub=q2h|>+{Gx{@qzsxS1J7@Q)=Z{?s~S+;!Igm%2dFDqsE}C#>Ky2S
zMz@Pgb2SvA3ysi?1BG~@5jeMFk0^Kp2INSD$3Z->=N*$vGRsl}pmPNpCAQc+q63LB
zTa?lOB?E!X17Yy!H7I+4+eNUkYv;s*l2Y)fyt0Cezn^-DLXfMkf0(O6h=*sef{&-4
zE4J_l6?xzh4Gnd;0qU9>(8e%?(gctFJLi<<Wmm#%E3V8dNvr?`Ds+873OGIHrzxPV
zC;>Sbgi(V9G@*daIUtoFOfblCrV)^C5H2**1NBBx>vxa@IxaNAD5n){6+()T>t2jZ
zi)@Ip0%|sbSPM!}o_U#|j%#KWXgLOAK^J@$7v#(0j6`sx6{SL#5hIn-s9^>j^McRf
zfyOUjBV8c(psEImKyx{?heR;QpvsHEy&Qt7K^8zNbjZ*Yh!4V;&H#ymFjTdzl9sUn
z)`SgGgp45?(v-qMv)!Oz%}mV6tOB)q;U#i)A*3;03tngdR|B411h1M_04;<nS4hlL
z01x!S8oeNE2)Q(s1V<``WTYw-rGnPQf!qgLD^m<w7zHk%;jS&u1g~YyPR*%QNK4Gj
z0gpC;oC3mxoTG#haM*GXNd;<hvR+AQQEp~lVhMbV71JrjmBo6+B`Nu(C3<N&rNtSz
z^Ase)P)aZ?4Lq#538X1ERlzo|K(7cin5&@xF1Ddnj4rs^(NTcSK!F{J&HE4+C@Cmu
zDdZ+rXc*|^`6%crfcl&u3rccQA+1(T1x*EQ1q~$-(pCUXOn{_wQ$eCi3dO0(`FSbO
zz7s@3!Om8}K+h1~byCn&PzE*nAk$o+x&hi<D@d#aHO-6RD)G3|R!KoiA<qYEGQ-^(
zMXO5D%||PaK=q@7vO+MZMF5)XPXvt$!+RZ&+4#KVRB(+5TG$9$shyTul$w{Eicu1Q
z$~ly_sjWgWs8_6{rKP1%sG6y#nyHD@{?7t+0zi5oSrplu=#C~j)nczt!Ir>lcW}D^
zR-J;Rkll>z3Q#Hn#}n4V4w976^@Ea)g1Vl%79@Eo<oW2D=z`K$aj~YRf+n`)4z>o~
zu|(=Tg3QL-e}ohX;DiS1T|msha4bX>#JR=AI9;HuKsY0Vvl-E?I}PY0gN_2M$EFEd
z2UC)o3!0UPFUZf#D=F3h_fg;@a40<Vl?`A?*f0ayss=2}CcqVyEu_A}h}XjS=q%8L
zVYPa>x)r2~E>F!&&nVGRKn%@W!CkJSpbqO^s#__*J*Ex`b9E~P2t!9f9p*lDD{#R9
ziA0znbZkTuG#d@tC<L<_+!}`tY=F`OB+g2TQ<Fg%2wv!cTD16zJdjpUu>%e$<USro
zq5!ERT)Y!b5g>CQNekpr<eUV`3F><43b2w^0bJCYK#N;YcEFk&uw;EaX&Yocq>Kr0
z3=RelW<lcyv{wa|?7*2=0bC5ZIePlIx<IF^K)N9z4Ps@cDL?`oQkG*4GLX7r=wO_N
z5~OMXYeK6T(0u{Y2MMO)V))P$NKjd!ycm%`bQEBTOu<$GI*kMxwnP{Q_Y!EyK(QXE
z2V5Lfnukz;WB{nxDM~HYD=tk=PAx7@MYS2S`vP3|p(;|)R)C9w8%4z+&%q1>wM#%N
zax_5!4AO{j0>Tl>@O%Tx@OdQ~<;4mPa50p;h~!?-3OTSsm>52Vxs{N107#QYxq=ov
z<TMrZ;WjB~YJvxq;h|=yU;s%B2FQaMF#BMRMKVo6OTkdj0L4g92E%F~C_X_LJirv4
zhbUdjQOgt%7iOip72M%E3hJOdRIF~LP#BL?KtRUHkP3%FJ(zCL{48`EA|min2FPFz
zMfPs7p@OYK8aO+^hvo{a^Rx|Xk@7_`Xb)DJl0r4Ywp#t_a%3gY1Z@b)=}LM^S_&F@
zK9IW3P!mEMX)0)f5>K%aYz!Y1J`jDV-2%kWFl@a|bQ)sd5b8P|g)}7$_kd<bA)Y6Y
zlfcmeO;WI6fyTH(E~s-46V!w`7AcrP$qb?jCJ1UHDl0fA7MFmAR3OW`L5n;gZh<xT
zpgTrEOKzY{6nU6o7!iqk<_13R02-1*oxVVtwSd@?0vdk>IUTv;fR3?4Ln1dbue2l;
zRLi84=<Az72UMX=T+rlEiGnVu(+*Ok1(PnwDarvYwgInmQ^?d&D27&cpvYDNPfrws
zQ$;bjNX`U}WFs2Ku(SwC2Wd*q&?Wnzi4|=Hg#WY^pbc=4bsA8I>L@5dSV~~KbQF}d
z6~OXPC+jFEL0BMpB~4I=4iXkvQkYT*Xv9cKM?pymy!r?lX|PDq)K=0*kw7F6P@)4R
zW#}3N&<L|Sc+^JSN<jmrA5pG@>U-#(Vo<XHG?M|%&qd(vv7o`v(wq{M<))xef?)7~
z4r~DkY=i~ICw6BMbm0el4^LKcejc2Iw1p_C$_Or8keQsFgV;<2QUzJzkW^I;+UThP
zG6Xc4rlU}jpPibgX{DeH$_(kLB?^h);#na-DXp|P8PeYdHEm%_Il%)<>8T~)rO!!K
zMxgdpL2915rUuv~9R;QG63_%$u|gVBMVzLGYA?7d1x*a6gNOEE8{RZBa|>YOxA1`z
zP#i%6Jr|Via|<Bp0x}ew3+khR)@{JdfZB?f{Q`Ajs&n;Vdtu?bQqvS{6+ptEWhby{
z5M_lF&?FITd2~u<5onS`BMqA8K!H>c53(&W9W<qdt}Y(xi1>I7kjWsu@$rzEQVn%I
zb<JplSkU4Kh>bYR1a(@8GzYYF8$LUlnFjU^c-THZ9`0RGZLgjSUQeYC9`puJfI$NZ
zloLww@%aek4HV~sv_Oo5`W0nR4Q-|u)ohY{r56wKU9<tx+zPt2V4r|;8puubh#K_h
zM)DpsGNDVLp$7%P(kWE5xTGjG5heyzq8F7};Fbx>s~}H66=vqcRDpv&Co?-WK0hfd
zH5pth<m)+AmZTPY`fKD?##dz)fY-P~?FVs_O4HI(!7IrSDxuQg%!_8T211XHf_k~S
zCTRSzDzgA7i70~>K|ymc)FhB=LBpIy`S~R}pp93>I^ewp;0-hR#d_t5IoTS>;e%ux
zOfSfDpxg_hi_zpkYBJNnM(U;Jr4)l)uAv0lG72jnKq`=N8YsPhs$=Lj3-Iy<i1R=e
zAh{b^R~eFyqSPFa85*!?MmGVmZ30#<AbSvp1yz{^(2xT=P)DH*T=s$7059R9)uC~s
z4r+QL;sey%1}}kyjm#nGK(ZRF3yBX&JV<I$G7eZZiU>?S=)4C|g$6nH0#r4?O9ogj
z14Ri^e8ARup~nlslmQE3SU{#}qDL#p2vEFHFM+^ogv=b|5nxbEz%Wb+j<_T(u^`0=
z4)Z{XS^>1}0Z)=sFM{OAH00_O=3W?$i0d*?3Q9`@FA|5P8ni+gn=jH(VjIc12q&iL
zDByGpe)|zkB}mEwB_?P|2iqJ8+XhL!oyDQWpvjrcV%T=ql6(bF>jpGA2<}gS2JxZG
zSiy^66kuDCL9T=E5Qa1?NB84`k3B)%EIYFH<Lc(+!-nMuZS-`>ECy{oQ-G;gNJ=ci
zw^bE%;7?9s5+P&3yKX_7NOKaCK&3RO+o2AwOOV>pr3Ii#iujWJ_~gXgg3{u=)Dq|x
zBpv7h81X5YMd00^umTs<-i0J{y*wXCRRCJn3+niSxAbG#;R)?L5xK_>Jf;a>qy}AO
z30WNgA3X*)<<LisVS<q1V9?Ahj%AdvVi1)E+Y5^X_(ndE-}DfXNs@_(g_qzxfncMc
zu?H<OAw6Tn2nm#LtE82Ossg;JA3Q-{3hrZpy1O9fLo~qph{&4`p!$^+5_5|4!K=l<
zQ=^dCWyq8$c$OY~CK9;eRII0`2P(}#=0cQ#Mhig8@F39)ofk&-22v|5GYvYJ2reEo
z^HMU)GE+(ubD+)sV(=1AB=sO$Ag)((s#Jg^M9`EesKnI+_YJ|0(gE!O0Ii1v9Zvz0
z16A_HD9ipqCV{GdaMuo+G%@W*vl^rcYCUMT0M>pBk{ZXNRM5dIpyej|x%nxXX_=`h
z3J6PbDix9{!7k0rQ%FoNN(G;Cr2wuCT|z>O6;dk_a}|n8b5e_8F$XdngrN=wbrNAg
z1zH0N6-HPAlZ3?(NH1!bBO8Gyv>^w~fPxwvl%NI^B=q(4Q0AdQ7Jz~^TSoyLvWV?S
zP`9Djhb4IPGII-1+6fA_3TXZJTxco<*#*N8)8mU$L3@MCQsZ;-p~DJ@Ju0x4H*~B6
z)b0iO1zL0=rqVP~tjA&($cfSFxNHPBeQ`-b@&wG$AR1yAs1py?2ue~Q4s5Idqy&bc
z*(*95)cgYJ!!!*%+XotqkIn{9%4UNi3ZxV?ES(Kmww0#<H7FKae1j~5Byq?XFt$Mr
zkQx|PhM5K$LDABJ8V%aH0kRf4qyjC=qt&6(V6Q^iu%rpv9Rxl-2~>H2)&_y5s*w^1
z<Y*<ZBsfmfQ%jP|Q$Wp6NH9R>&Ou8s<3Zbz5Zfl<i)<0&71|0)@fqNCno2PHA>(q0
zQ8}=F&>F?!Xz1V_bd;bBzCK(jzD!9Q64iR}722Tl@W7=RTm-QY4>G%;1h*4XV%aJv
zsTRkpX2$2I#j9qj7DEa$B~=Y{FTo~&5RTM=ItH3bVdlYlKH$zJBH%y?8#E9H2{3Ru
z1MV1rwSoHONziTpQm{it`Semsa|<+}(Ws*U8mfXAg1>l&BqT&l1xhqfG0<5xsU@J|
zF(tDEoK~R?WpI$|C_uMuK?)g2C6t+$o&!0V&<ebt4P+V!Lrnyg$Y7s90|QAaBwqpE
zQ~{T-`K2WaiFuWvb8IrxG9g7pF}NUucnhQ#)=yLN1D!+yI+qDluodU$rh<=81htUT
zO2OOsAj6)J^c)X4rluqlv?>OalR-;eLFvIT9-;uWg&(}i1J*VIZClY$O07suR?>tP
zMhLa(Ir&M6IiO9P5Qi0jM%JNm0&0a7Yb1fjY4kv&z!|9(up|T90tiW*(6b3NK+e&G
zDX}fc(E-gtXC{|G_Ju$!04=ozIajYZwIm*z05u9=TcP2-ERYgV&H-VFB``OGw(LSX
zUirnKlhD8`3PWNLhe#Edl%}OAWTY0QDimjemXCmgEGGxni-Il+ELK3;odGfk)C5gV
zOwLG+hm7+=Mynu0Lg1Z1h{F;<?Kn-Vm^@HCLLCE|WCx$N00}*a9QJ|O%$!uPd72PK
z&@>LqRH>lTDT*~x@?aK#EXgm{%gs*7ECLC`bwRfiS;0<-1D$^eszSk@09BkwZim{1
z$dsVE3G50Tg&6hnq!@J_1@Nd@8q`}LThaUk$))gM0d1?zEdcpBGe6H(DW@toQ3+~I
zW*Vq<l$2kb3U{1KeqO2~NFFt)p}vK?2IgsHa6=31Km}Wc<h*zdgc49?1NLKlK~ZX2
zW(B0!gUdt02bz@7LKUt^6XcATJVcy>cBCWO0SyK0kqbHz4{{tDIF-T98iSl@1)C!Q
zt?|z<02eJt2~D9SF<k+?)DAS4tp{-{#hwLKZqOk^TmcG-PteL%h>ai~2;)c(MM*KR
zq8e2_NDnk*(Gv%#xX?($lPExXv9A+FwF6q-h7^ICvn9}OLZU)aVu}JJZ-JABLShMM
z`xjbX0@(q=P%}Isr@Vq<T>*5iL}F1fXo@HaQp938p%&7zPX_I}Evf`5O-ap31)Zo@
zqN9)x+Q3l`I-oTrzdR4*U4=x2ywq|~QU`5}0wr#c-7pMsLn<^&z(hd>Ab5}x;ur8<
z8I3fkBJd~|A~c{O4Qi=Cl50$!l9EzPUV3H;=y*&8Jq0y21rP^xWMXECf^M#Yl0Wzq
zonj@JR6%KR28gXtkXZm(QJ0eg(xY8moMEM}pPpIbke*qRlb8fM#YZotq*N~@Tfd|<
zBUK;1l3NdCjjnEK0eD?E$TeV>D1$d*Dd@oxJtSL#@=^?_eU@KT0^joq7sxBkg&kZ7
z7b~tTj>!X6G76dbFtdV7K#Pw({o#s`4n={B6{W(NpvAP{Qw0$sg(<lRPG&AbEhO;a
za+xKmMJ4(9ImK`hNZkTm=Yg1QuCP*ouZOD81g)cn)+Q->F?pbQd=#a{rMVgvnlX8~
zX*v1%pxF$_*(?eWQ^0~?c}O`_oLW*^0BV57CsjiBZD}~`fSQ^hF<7|>s$&&w6+k;<
z(PzmZ=|))rrUhwM0NhZ6iGvPh%Y`LNaEl(a#tBwXW)_308JJp_wUC8Mpjs#~J2fS<
zs8|E80%9#Rslr4dc7T!z*p<-TXV5|wROn`8rlf-RV#90z<qxPKpxPCo)h9naJ+(*!
zQtiN0gN%R;+=GqLQGiSt!4!au18<&yt|11sYY+>{AZ~`M$;k(8$AlOFvKS-*vH{W#
z02!mBkegau3_6Ms>IaY#kOXXvat?HY1f~qr1`GudB_MksE0;mWAv<3gyh}s@EU5t5
zy$$NO<fW#jfR576FM^#TXbd{(tst=^GbuACv!oJQseoJvT3rwF5F`@dn<z9uyQ^VV
zfgFGql+YdTkR2AV!7jvJd5FV7=7XH92T=xEGX_4d4oQ~KPI{2jK*m6vkeUZNa1gdb
zKN-AbBo%aYTYgb7qzMU{;ZMoW1GV)EKrL+OQG><c#vYQl!On_@EDHy1I)kqfM{-+g
zPMRKQ^+0A`dS*UoBPX=9(SR1kAa{XQ{({s&e25hDAW1}OQm|EkCQ_Kipn@wiAIT)N
zf*nIYszzA2fRtsXDWC=gx-&oyj0YWh1u9^mj!G>mLU<Kq3Pe1$2&4v9u4;gmiRY%~
z<`-2eWaQ_hDrA-*G=Uw2YB8uCh7u_V)zFL!(gbrmG)^nf4_$yIJFu%jZcnW!0iE{*
z(u;@?(C7(t))2Dv0J=#VDM(XNa}-cDfs6!INU5m`r3DJ$o)pA;2!}$#0kmBJlrBKl
zLz4+Y2`ti4J&zvh;3NeJPnaXXfe!LMB)0{6mZavQo(2Kh1`G2)c+o9%^BKf)&|1c{
zQqWK~q{0Vzrz9U#a2Y@ppe`Z@Z8X(0F@i{eTEd_P8R%>;ShotraQMkz&_%#dNl;4`
zl<h!g$AE^nQ;R^29>`jI&{Pw&OAgIjkTuE*whD%zr8XI<3Qz&)Vfuy8t+slgKmfTO
zk_JE<U*HFCz|??;@3EZ20r3t<Gb|oJK>%7g37WnE2Q@65GK;}G_t0Yo6sa&JwvZG8
zS#9cL6a*c<Ls*iU1Ggr%xC9jXq?!soK^*2`kh{TdgjUmFHs<&c!hU6l1LKqPi$E72
zKqCh!2C+*Z3;^2z3slg43TPalxQK8$401RK!$SkKJ{(lrfRZBC5C$uNhA+ssFblzP
zUYwYg8lRq80$Gv`uApJ*9@!R@R13)v$lFR0z65DPDr598H6qj^s{@;f>@rA7@XIgC
z1v?7TTLEPn9R=7t4rmk$a<(X%lR*j57P4CuEkwXFkeDpV&p|jPB{L1QKnrx*O;WLj
zf(D2IJ@y8cSvB?2auQ2)L9I&Ii8wHaXhP%^kjlKgBGBrwyaK)A!lDw8aiA8a0@xZY
zEd?V@aIY2=SRf2e8sIh5@XQZdwON!43lNYZ(BMN+u7aIHNq!ERuOR)GG$p_M5`|RI
zUVHG+7PwoRlUf8iDp{erBtNItS|KmLC>Jyr4RQ!%dyYbRVzEMXUQuo>_Fhq%k}KrW
z4P8iwDigHa2ehxJSfLtZ3g~#e%;FLa(ESUD@B}#+>?=q#g0r3mEF_U*Ft<3}maxM?
zPJ<W@O0*C&eT)W6!cf4GD3H?wI504yxIhoI0SFY1C<y`-*GN*7M7nLQwL(g2StfYi
z4;tA>M%xbJXt%A^QK-(ta4cp*fYla5DM5hZ9JFp4RPg94Xc(sIS}16P3m2RP5L6yo
zE+GmZ1x=z;8mL@LD%Jp54l05`*%X8!=?zpwfn*@b4KgPL32cxW5GJ;u0p(YadKiZ3
z8+1iUK~XBKRDxCI;6#L6p&(aNDAgHsP#jiBgNi1Ec{q&&U4#QaDH*i10<ugA)SAnL
zUfuyJxl@ZviWNY|@qiBM2F*95r<Q>4LxQfDF3L;Sgf{j-p$zLkg4iI3Kz#*mrhxqf
zI@AkvOgW^Rh~h)=!OnizE;9nP&mhzNpaE1+yh2h0$PSPk)MTi2DTtyS*?e%}2U49@
znunzpfERrrLqTnk0_c{%)SNWLNIq<RMn-;lJS^=)yn=lt2c#<qQvnJer1QNXyZvC2
z*gDJw(0v%7HZ;V`prD2M6WS<8NPwIUUIGGB5fAq$a!7#8fMf<GJ3BiC@SR4GX*nxU
z*n*^C7@`bj96XFb(s0XQ;SjF@W8tyP6?))4bZL%)MqYkNs+9uhh6V7Uir~W(3ySi=
zo4``66+mNy3MHu(CD7>@O&m^yTMf$yASXgw!|=Wvln+ghu*`u7Kg<Dd_*vedv4kMV
z^${tcTml*c%gwA%D9KMx1r78<CRIR}oTa59<p_`~Ko}B^O6b803s{&7p?s(V(T=V_
zxRaP+aZqWR54zj}d{RGJTMgtSr~*hL#3Bz;19f&xOr9;Z0eVn?tOH?)mC%C{N{T8$
zGgKvzds0A|7jg!YLX3JfI6s5B616evpk*sXkP-qktcy4!!AeO-0XB9CG94L%a|$fo
zfN~1BPleQcMpg`+*(oVXOioQoOwL9`2C^!M<Kc?*AV<)FPA=9!uIVtfC{a6jZLx(f
zv=Y%UKup=AWNBD;4&DKPCPaKaI}Ek9;NeA3CkZ(#f{aEkG(nftfFl5!<Wta6AS5J}
zVn7G7A;KEn6f{j>1M$TuOg|1w!TMoxpcIi?0P+V?lE7L*fXV`B(T?UIP(*{%DJbc}
z%VJxY6^M$;7FskRSw%u7$C-x_p-7kX1+gwo33S92tbhm4(tx~=Bj={TZV<{%EJ@CQ
zcdJ2dlG2<KJq55?;64jR$qx!$h?Ur~IN`_y=?7u3N_@!%qzHT70m*<cOx6%f&H`7I
zplx*EW(soMh?$xYiG{?J0CfO#=nu(BhM-&s9byasod69UX9SNn!khwfAT&urGd$#E
z5e)Z&=kP#ggRndFnod|mLvByZgw2?Oq8xM>vQs7Ox&a-9r2LW$NM#P1Dk(|L1J$IU
z1(EPs7w{EBkh)X@d?`(0u|j!jP7Y{;4%Ca_ao%D?nUDxtxRII%u9cw;2hgf3(1^bV
z=td({pD84z=H!=a>M3~UL1t({=Xa-oHZx|VLY#)Uel)Y#3KV!C&w?=I7&(}6j^G=5
zpaF#xStS*q9ZMRZ<veg-K^j*`7n>#~<(DC+S;)C{prxu{jWBK+==2!SnmL$Bx=@o!
zDoRiaZbY&{4FS*^DIJB9iV_{r{coTfJvDU{Y+y+pn#b%=jIx3Rvy}p5W;iiN0TSTg
zMNuHnCl+NE=jS29A0<&>+|GiYN<a;G$Vp~UuVjL5<0>vr1;-!QAE;gc)ngFLK*<zU
z4xB(iE1E#@hwMqDVi@8bkXK=G2{H%dk<yY>XmW>|gWOn$<qc58gI7HuX2YP$AQX5J
z48$u)mV$Iak_*^JsJ3CI8BoN7t2)R5v=HNv(iBL(C^sH?VYfyxXgVe+H8;Nubn8t%
z`05tWvU{Y)CoCD+Dx_9`+9W0MP!Ww{WWzxt;8<#LNZKhzq#Q^rK)eQCk^uG_T8tE>
z7V9XWXo|^$ls^8TD{@m)z$aGwrh>1R)d1b`1q*2hurkQRCB!OFM8$(Ty9J3wsqiTQ
zP?JvwJZoJH(~9IKq)C50sEsa}$tAF9I*5^ZspZ&=(}7e`plc$KP0j`dKWGY61MEVO
zH0<1Kh&w^ngF44apsWg-(gu|qAVC<;2A{%_q!%9#z9%>}B|aXZ6K-g9j5@Lc@TyeM
zRT1Ev2fbG!yBM^Z3B&<4Ix_PVG(ehi!Fyff<3X#kKzz{XD=3&iBAT%XtDt!S6zZVG
zr-VZRlx4u~Q-B@5;9itpTA-1eT9ODBw}pl=a;(C_4m_F;I$1e156nz~AJwD;aT4fc
zu}siCfAQe$NuZl)!2N58Yzg?FQP8v%Xx&5zXvJeO=&Bcm{5%EF91-{cHOPRXMnO(u
za%x6?PD*N#wF3CWNYGuypsB(l@I`{KK?*!mV(15)!p_ZwI0m+|3^cz16#<`r0q=rC
z1RV;B@(WUnN-7~-P-+7!0~au`Z~>(XP(u`)@4(Wa4a*>t(Mk|-{)&gHP>4o~NRSb^
zkURuB(={EkWHr46lmMe)JJmtjbrjM|AZPSLBtc@x$q<y9(o0|~v7?oslTV;~IO5|$
zhYi4{`juj1L26;E)iaC1(XRnA9W>Jh+Aa@0MmW7hM*-5jKyxrCi+F-u2z5D{Z$W;7
zI1lV&*wGpao*J<EDqD~=az6^1o<YKTkZ=MeSdc*u5HpHXLAMfOiwqq|wT2ugNX97G
zLZsowVa6*cf8mZ+kSyL<g(!eb0zm^EX$L#R#UPKMcoD2g8SW?$7ql?8Bo#V+4@z$!
zL9n~PKE(7NNFL%nm^mO_pbQ1pg{%Q|Vn`nJ;!9}tTmq^{p<{(bsX3`-iFuH;hk7_5
zcnK}&*foSlKpiA>8{-pma=`Hx4~ybr3`c-c4Ja}}2?rcQAP#x~3mwY<N$J6i(nHVD
zSkfD+25=xC)r_F<2VqoI=*B`10|5CAR@FgnQr3WlCAjnh6@-wb$&kZQp=BU!Sw3W<
z5E5K4AAsr|SguFjr~=CJ(7c7Yw+2ZPdRn=HvVw17MP_bkF8C68h4Rdlk_?b@L4Lzt
z>lURJr<Q0W=b+TEpqS7o)PY?0m7G%y4{0p1fpj8wj5^q~7<E{1fUJe#LOrk~sCtI@
z9lLvSK}#|<l5>)g&46YNSdo;TS^`%E^BpK@gKrnaNLDyBgQ`Y|T6m)vYzAcb2fUL5
zzN-hK4k=ZEcHV;)-@!)nkmD@cAXYCPe7*xHn}hb;M;k!n5EK?jT45{eVEe>jQb-9C
zzOM*m4$`_k*q$PAK7sgKQ%3=d0gwg*D1E_f1I@{TOw&Ly8+>_=CS*wsXv21KY5|Hf
zz|BCI`Jje4biWhGBpuLp2GDLXl*j;A>hQ)FXzxlg>=p_I=u`%Htp{>MgDz^y%u5Fa
zZEA7}X#Ej*%MHj9J=krIFn_>84LJxvRR$z=fr1(=1G>9R2U7Y%3q&l-DM2cAK>fpP
z6x)$P0J<In+P;U~f(f}z04ZL;>nTB|>7m;T+W7<DNgkh)AD@?B0^SM~pP8qZl2`)j
z{eT<|!YKI<Y#O|vKuUxlm4$lXtPfU`=L0=5GZ(oG$VtshFUf$fya8zfUqA`o3IZDL
z12r#kHAztRVnEIah40;f#3)J-p)F>EtPMq4f)2e04(wX2A&Hz8Ai6>B1*=DP3Su!a
zIA_8ZD5J)TCO(&fjK%6&kOU~Vq$$}cgeMl|W#*;hzi(7Wp&FJVVJQ^sUhMv>1%){D
zMp{Vc7<|_iDBVLA|NHrefYTvp7$h?fv;Yn?v=Wq>SPZ)H5j1%MTBELzR0KNNNCC9l
z5OjG-aY-Wda#B5LZ3FTLA_PH=(2}Ce<PxOhgOCNOMeoid_Ztx^aRwR42*>~(NFyW*
zf{Ihn(Zb+3f=#StmQ>mrqDFHN%EjoAaUt+!28l%}@I~U_>7xwL6hT^IUUDU@nGdoT
zQewkZLM#VKfL7vz&x!#pRtJqz>4AnA!S{s}f$AZU8W09$w?dtGc)J5vW`kM;I<*X8
z3CI8}2aqZ#D>y2o=jW$@cFI>&f_rx0f(Lv+Fenw2<f9ov+*KK<nvi^ke8Cmcl?RZ$
zK$#_#$Tu9I8Uj8d4E6j}kgpI}R{`upR9&DmtU+fVD}c456#Zb2LPuOM+j-#Z0Ztg;
zb@HgupP2{gnk!_1?gxOMYmrz28hivTB?1j1mM2!~=^+h&Kw4Yz;9>!^9kdqVQb^n?
z5D~eEJC6%NJD=i<6U$N|M&fADfUW{VC_+w9u#hX%gBTDUqYh3q;Ep~d+z>8=DMt20
zH0muTpnbP6vrsjnWk@2;s*X|51MN&q&PY`N4V=cKL>MR^fYKFsLx+)GL1m1(6=>x>
zQm8`PRLD+7P5{VdH7K^>TMt1aM&NP?G8K+o4iFttuz&!c;Q+41iqV4$<`!6RD1);f
zsBsVS8}up-q@oa{4pPX0?zI5l=?d#8Lt84vpjj-C0azuYAqQ&5Vl@(EIIKo-f)v}Z
zc7OtCgb8#%V^O6-acNR+W=RQTbQB)^V28uXBhaarpf*e`_^7ku(j<fg+-bFX3T~h~
z6%jQGsD20WkZT5zn;;$rv9Q$+AaR5W5D#As0g^|k#*!!zk|3psngYawVTc;Mn!(=0
zy(ShGS+Mws2CD}JS!{HSI#f1B9jP@AvKwMAhy_-TF>(ae2TElSqrl3*Owej{4JA<C
zR?<;0L~09xOhcGkh<-VTEvy9$H<U<|K-a}17X74vFOJ9KKG0eQ=ls0l%#>8n5$U=4
zWuO`qyowvC_(XLqhzIr|Xgn6)ih){!n(4q{fELJz6;5~p8gn`f5m;dR(-f4zeQ9Dm
z2-=iakXn?HSWpZa!YBfdl&2^V_9fUR(7E4Ws|b1xtO}2(uutPEfX7xqnGiHu2|8FZ
zGpV#B6>_lyqzMQ%7}O+4R7fk$O9tIBub=@MYbz+qPfAS6sRW%TQ<{?kE|Zc{k=s5X
zFQ5h;Wb_3j4#TMO@ZIG}i79AHCZK&BXjFsBEEp41phEVdp-)bL=BJ>=p0a{3=q|LP
z{3KA-4IS>#Q*bN*4eIBW<Wz!=TuCp<0M+72iA4&acuPrz4fK{J7G>s_7AvGBf;xVn
ziXtEB?jZ1JI!I%2Wo}Y_PBAp~=7D#AAPt0oY7tO_7&H?G>CA#vzz1kRVNw7-X)s4G
zEi*4gLrE36<5dXSRDm=y4N?y3EhU$LuKa`g6C?=2nV>CwP*ZA@bQB7bOSI9;0MJF3
zAg$mM8)hX)ai+E*wiS;cbHR=PRk(<%9y;n(h`tgV;(yoxY7Vpjg4WJR^GpzR;DHWM
zs~mlj2qh9B)0)`g8R8!B?eCe%@yYpl#h{(~pmA5w-jo>iXkG1Cdj$=9D=?0UNzqb>
ziP2MtiAm8`&{U{_iE4vH?Ln(ZK}w@tQ)3mPwRL0dVG8YI)FCz%Re;aJ0C(>)b5b?1
z+6)?t&<k@7a`F#$h5A1+2NaD(72vo@%*oLJ`43_wL@GKhCqJ=7BN2QGw?>S*UW_`Z
zVUP%_<dssvWlkdO#`HX}I#9Yw1gpu(fmR=xkRyZ=b8<itX=-4Alsq669Ku>qw4&Fa
zO7Kcv55X#^w1RazLE8=T6>>q-%h1U@MI{|j7SaG&3H2&8suOc^AXyYVR<D3|brY<a
z1&VsuC_l7QRs!lICl*0YVu0N~p_E$*>b1Zp8kKaw>n4yVC868yAb|?<9jKY72bvE@
z-zpYgRGJ6sMWfELAhbZYi-5~OG~>YML>uTCq6vc%8|d_C_<mcc-TIJGo|F>MC=kd3
z5C+R(I3F}_2U??q>?KeDf^>i|tRw^#Q??2vg(<muAVLG&)d5dV=;c9U0Hhq;fJ!Vv
z?p=d~A$EhV9s_j_Aie;_0k|^-jsRH9z*QrK7DfpGF%I3?NU08P3TS0qB50Bg!pO`^
z*9*x2t*_K5Ni0fFErIx;s1(@`XqxpPjzsb#*m_V?Cmt-73N{~cpBgOqKpuoHVkp7f
z$O|pVz-Gbxisl21d=gxeUr+#Qw<IbQgP5r)D5+CV0l5T6F&Q(>fno|Y8;6l1&>R6a
z1`>LZnR=vvK)O5?qzu$qEJ#W$0w0W!mjX$IAOTQ~4yyNY4X%OI=#>_vfDUXyuQxyj
z>wy(OuabwP9#ABKFkBiuf(i?Iunc(rA!r{X?AjxQPH15PibLpi9SXV-=YoV_(F!vS
z6p=-sI}uZJ(lF8~$Z4Pv1FSg%a=M5uVoN1>sZ=JYU1MtiD#8-WQXw5c9fg$C;$%p2
z1eX9h3VF%-ImNby1_n9^hl4zZiIWnGpf~^8#;8~4fDXZ{txifTs;yCou1?KKEGSM*
zskNzw-)~hL3yLBIWd+d6^vsg@;^f4fRNIsi2-h}79dbf@F{HbXupLzPgU1hw67$j_
zNm?&Y*ARTHxC>;{F+9P8S44sihRCV3R>(;OT^<iALlR3AEG<<PQu6as6-x6;GIJE*
zI-o5XnD>atARwji1fYjCeV{0T&s>8<k#SN{YGO7lx?vKaq@Y)vlbTupE}`^NK<kfS
zk{}vkHB#CInF2kh0aTfR2iw4xX~NEIh|es}%P#>7fz(3kDc{Oq(4ZG$FDzIdJW2<a
z00%K>msxRXQK~|Dssd<>J7n`aC?pf}Ds%ITQlTLTY4}1~sjyi|@I|Jegq@tN0TY9z
zWl;N8Nf&w(bZ%mS2I35c3ecK~#N1TS^|&x?h;!QXz&D!1Dj8^|0-rbp$}*r01z_LB
zmt-WC#HXaDW#*-(KrdMbEvLwUIRKQdl5@akN+Zo|feZ&NjnT`@g`D*OQw|Dy&@t$#
zB^hw%fm$S>`8n7v?P#SK)NRS2<10Ygp?pw*1d0TZbHUed7J(N%XcT8>7T6lW>{C)w
zatEE5uK?=hftuclkh?mIK$e0=;UG(%p>scaU_a}DT%Ml-G8|-|f`UQ<$j}6Z;)2v<
z&@qI?3K{w3kVZ{TYFTOy_`12`lEma}&;mh_T7~kA%$!uvakk*?ClL3+Gb6|?dI}(Q
zwuTD1sfl^T3QFY}ps}o+oMMICR3#mVq!Eg6CDi3g3aKT@dPuHw%u`6sEhwo3pGTFK
z4l1!BVFWraF%4`~L28Nu)Ty8jUTO+xEHpV=Ap?9Z6U1Tgg>ev{*n*BzDM(E&0ac>O
z*`UfF6dK@a6THer8*DN}FSHp6)~Tsr12Vm+L_u4@5FVEh7b(Q3!`j7={uFrP0Mw8H
zg<dq+@L2FnBg9-#NFjBMAoGBr8wT<~aZv&qZ-9ttAQ=a(<&+f?a`RI_CM1A+X-TQz
z4b=+epeqd__GW@kiA+rfEt&=$ke-?h>feC|Z}ant^K()mZctVT@ptjpC`nDuD9O*u
z%+|D00QDNcqY;pC{`h#%Krn2P6exLv7dXNFt^iJbunrEy!SK`%cWp{)3F!EEa1sQ$
z8e)59ngXay&q;%{?vcEymj*tkF$Z}%TUo&qR6c`_kjMsIa{_92mnTAx`hge^>O4Re
zIcKCQK#m=O9=`#x5ERME3K0<zR-nV3z>8H=b78Aw^YRr?jVmrmEXhoU8URk93c3oJ
zCE#fwWb;6#g2pw#1LBE@5du)oK&S(G8x~C1d>Rc43ee;<IG{kY)8Kp`9}f-4<ouLW
zkU8Ly5YUZ#;HcJ1iw8;QCFg@xL#zZHJ^@p$XsZyTZUc!MyBKxwy{jep1&~~$P+D9H
zTKEOg2J#EY2AE618#zD%;F}5IgCF@t3W?Bwfn`=@Wd+Bw{LB=E<jkVv(ws!la8_C|
zxLXZ&C8)B^hOQM>R#3<&DJdwn($`PPPcGJj+=8Q*UzDzIq-U<5lbKYMSX8MGD|9nT
za&weRGE#Lx^KC^1MX4pJMWCx2VOu{y=Sd(1DY(Z3l7n~&nmd*Bpfw4|H}H-&qA~!b
zn|QEGHPVV;MXUm>c7!?wVxocq=+Igng?KOmugQ%E4HTnh-o&DGuv9U~JeWphP$dbu
zaT#1fXBHKMHU@zPgiBJ3z=O$PagYEaC1pax4Yc|W<opzPzJZwwEu=v1(gcS&h!t%R
z3tIRDOIS#G78K3OkZK~aL?Jn`I2F`L1~nXF)WPW+l%9)Hp*J>yj;4hy!UB5}W+%uH
z1yD&^0^U&$U8e<B0xG;TVD{>O%O+?NhG<fNE?@)eL~|EJ1^lqB%o6Bj>!{YkRAm;!
z>VJ6qK}P{Ji<p_04qBEAS_Gews*spmQks|pow<VP(1WF2h+!}inqXjS_h70)Ap~C@
z23p<;s-@w+g1Z+a3R%t$+8+;dG}KIxB*;=wVpAxo1b3RCla`KomGC31ps7tqAw3zS
z8q^F(&n!zVEhx!I1?55bXc;)YA|*TMC3aw8Sgi&s8x%k{cY)Frw5)(Q3v`4esF4L$
zu9p@M;wQqIA|QJ}OK?D)h{}RgXyeOD!2s%IkUU5;Y*iGfu>=wWrK<E~Py&btC!nI#
zqGAn@8xVO49Qz=%H9#6PL6tg)0TMw=3z=!4b_Qrn7OYf90kkSIKP45sAQBXqV9g-Y
z(KLeM5}RhI7g6<t1d(eRkY*SLIjk5~8iF`b@5AI_G&BQ(RDjQ>MzjuKDiAbEVgLz4
z1;Cm?nHF@<MQL6#^tM-!KS9X=+I&Y^Rt+niQc}|rOLIy<We`Xqxb{#81>JBT1isxK
z(S8SsfpP~#92O<uB`Oxs4J(kbECpKyUC>!E9*)V`m9UBtG(ZlY(t@aiw(T*x>+q#`
zApe09Fxt2l_%@ncNcXZR6LRt$(h>xi%Rst|(GNi(q!*I9!CJvX39x$%p{*^5G{{Zh
zQ9#$CqWmK0B)EdE9k{SUN=@Kn)<7krUP^umc$N{&0eRRl2YI*`GKvq81YNb03pq9{
zCl8hpK@I|&23wH_QVS|ol9M4lT95(|MluQYu1$!`Axc1+^^%k0;r&z%=zWcljyqB^
z1*=4O)dzGsM~u2_P>_ERs2BrFgLid-R)&BK2Vt-%h9=N8m~cIyV=%#2I)c(1NDnAT
z6H`*a0SfM$>L`HvnL41U6wC;PcSBLrBxEU=re0!7id$l4PH9o92Eq_T0D#?x*ZUB)
zP&dJh0%;piSAoI_guw{`<QhFvQj!uV0+2`3lob%?Ac4{+O2P%%1F-@rJ!-_LyTzy@
zB@d+32FX~6aVeA_42EPQq=>bGFX_<(H6g&m0^ozPux2AzHcm`Qff)sgSR|J~+zPQK
z6<+9~DN<G-Y!JjtkgIh;wPSH{DRf0VWZo3gZwCz?cx0xeq#}>9LbQTo2Q)MYF#{u1
zA*#UHLj&n<WJq{{f*qm&+ug|MYQX(MP$i2zQVTKygq6`%Yd~vw@PJ)$W>QY-0N#y^
z?l}0}$T8~Wpl${@uptMHfr>fU2?`)77#k!GIbS_B1tbplUJUe#WRM^v5<p5}v)v$3
z&`ot<8_+jQX@XRO2P;9!z)HY8q~$S?=mFor3p!W{b~!wFXbnVYXoC6|MJ1rC;Ss(B
zr%#kJ2i%W9F8)wtLF#oBV8t?Mx&XNp#5vLpn&bj0MoM*{w1DASknwt`6$Gk#LAnrQ
zyohWK5{F^%Ey!S#Kmi3g^$W5q4&iT*T4-7a)u-qRK{s|nrs&{zHiHesb8$1O*~+ks
zu~E;~09lK2BQVlD6GRT0T0or~Sb{<|8SFbH_#MyCsDPY04K7PvU67Vzf(%8!%^B4^
zkP5^-&I-6Maz@n#4Lnf&ikw)$Ss&CILn>2|QwXA{L#RY64YL%WWAmWnVS-AL_JV?=
z0Hhjp&ok%>5Tww9FEI!P&3%DpZa|$*kYdo;<47g4GH78#Im&KFl!hHBJV3L3NNr6$
zNV^c`Pml^kf&q<&fs#;qYKco~aWb^w2d?0eY(-Iz;6RoOXn<$UL3df=v;ypr;*9(v
z6iYz8K_~DgBycwy948>JYk*Em1b4{5%M+0oZzzM?FM7%OrFkWwcmh>!#mLP$a3CXG
z2+260?IoaFKMPee^;9!86;z9r6jT*7@<3yTItp133ZV(f;}|QO454juP$;4_(m?`9
zl>@0|3E17q$qKgUGtnissBVDGID<7H+zjz3^qd{!Ia)|+1T|?;5)HB+bBa^ZN;Ys*
zfb)PJx)oT;7Sv(|l$y{rX=);_h(}H&U{Az@QU|EMO)V~gNrD=QkR_JEC7_u(uv?IG
zA}oACE3V2wt6;#XAtw=3zCgAMp?L{B4;_yhmI}5C&@(?lu?NCv6P1V=3{VYLh*B71
z-?D?O1eUkpV-$L*CV;Oz0NDz{SQhbtgi&;W(y>ix9%R4?6l!`3!Jq?L^D;}oD^K+b
zD(#eDK?u?f!paI5W`K`#1;;UH?IdV90jQKgEg`X|MQou6OOYtnkd+ca&IKn4u;t0%
zp%#!BI5iZd7MJ7~rJ|$<1!aX$(C+wh&?q}-KO?C4D1}@U01h97pGZzHAn$+|YeQWG
zJDs{D6}h|tIS;N9zPth=LVDc~juUWN2R9=?F{7i9nwMgWaX6APbk@UG0l7p1xdsy7
zV3)()18PAb&0mA+7)-}u6lWmQAT9#k1P*UXfU`U3;v#s!fZPeb9$o_x-XP5&488dq
z)HZ~K3i!5f1?a@FCiq%$h=hWjt%89b;&yTHQg_7a;><h+$l_@|*b+Nvs{y(91+o!d
zm)a^RXes3RfSZKi>IB}w1ud{iErJc!#DgyTNX^M}Nlnf#N-W7Qf{yE8J3b$_ixFJE
zg36qr(!9LXA}r%MU~yQH1x~@J+q<9#gJV0{4D48Jwu8I}!jNtuj+3@wy)pRs4%8-y
zCR+#vy7ei$95f~k4jz!9U^nI_W~V}iqQJ=z=6;YoD9IJ2CW1~)1;;$ZAO&Uc8q3Q3
zQbk1ML#1pL5RF|dk{IEx0nvw4H$lhY!1h7TPX-UAK@~zqCiFlHBA^Wy&>~1s1%%kb
z0V)nbJ}WN*U0PA3k(Qqi^At!pH!(dk8N;ifVN@a}y1~vul<uH;XieB8HzdR$*$33j
z1o1&QEk7S(9V9@&_UpyRr{pKc$AiX%^YdXmhyrK`fYpKg0!|yCaY^tU3$P>%SyvDb
z^`wqMJSZOHvr{W|6oP#6K~pbaeON{+!Ieo#X#r>gGTs?<WshfG8t4#rgoK6?TwF;<
zAzCRTv!ocb{T;L^D;2^@tSHW`0!<|=fqDR7b}Tqyfx;NviUS3_4rqiuH3d2z2Cbl#
zl#~>FL9w6!R;K{<1H|{RNvZVAl8jRDwHo@6sVV(rD4mp(pQI0(5!Ls}Owxx33}_Dq
zxPFCCH0MIxh_bW;<T|K*;7GxHh&Je830noQIz6yc<1<q<G<6g-lpMfZ&=o4+*aL+e
zXea|72^ye$rlSDKZ_q%{L^%>vSpk>nG3pT0(ME{i)fw1o(8|)1#LT>6(2*Fipkx9{
zY9NfVI0jX%Ms{i?EGvMNf-rb~43Z4N9>ok0NW6g5f-ocpK+G*DEddz`-dbOZe1H#@
zrVY#<Wc}%>VEvf6AFLQ+FElqm;|%0cqyo9P1k@csE{Y){Fi(O`K1v4N2?l8(g7=$&
zM(Cm2Ng!u5fg2gcpxJ1J(&E%2UDyBzXfqW^GkEz0Xj&WAK`REWNY5+=pB$Z9RIC8b
zXdp>&s6a>KA)A_@X%94M7?hfrqMM(W16pU1oRO-h;F<?ou>)F=QIe6LqL7$Vo>*B7
zTD6x_nw+XooS2&mI$Z#C>K7y=ASN0i85s(4Zg~-CM@$|hFTtnNux}iPO&mbltmr%1
zi&DWGn4xQBK*bZJy9Zqz4%)K~+Rs{`0bUY}q)b5(8or=-SAa+$9l8ST5o31}WWzh!
z-g-zOss!Czs-xhkkeCaubU+~nnpJ^BGi<j!X!Z)U>M1n^bZ;DJxf6K)HM0b?aVxhN
zbj47mLPlb8cBLM2(*f+z{L&IoBtt_L64Ib_4weK*C>|+TWPp+-NE4`ZLGSbimn7z;
zBo?KBa~CXOf)p2n7Kg&BZggG9ElyC*PXP_EfM%hfWhlr15QZ26ssO>AD&JI4TJlQ-
zUDgAV24QHl7Q<H@VRI#h>!7Q9kxX^TPu7FRKdy9v2tI_n(0v9E52S1l9vg&rp1`3F
zIsjio0ZZWv+9p_%lNzHA+Pj>Be9AJ^qY%SDgGiuODr(w91Ok?`X}}sW0s?9(xZFbb
z3n-Q#es%zB#yEZiEDAOfR!AbnAJ|Apu8s#4rC@a^6%Ddq!DS-2h6P2cGUymN1@O|n
z;M9^($T~z=>VgcdDl0fbij<;K(6J?HpnWHhrDvf00$Lf93c7a*Vj75q=DNh<lr&g2
zftUnYH3(9otbmz|Ax<d<xxyLL9Y-!!Ao^ix2@<iydlh0Mhy>+ENJ#+?0Z=LiB@$Q}
z4-P$82!QlJD?+e1YPTMy1+>&PzX-Cr7tyGL$>Pd!;LHY_zR*LcR;WfA-9}C|m_{R)
z7vMMq^(!EG7wlZf^cX|{*-PNP1K1`hAW10|T%$l!R4U{qM9`3%Z(??;0=Vb|#{ek$
zL5K9h7KK6s3t|SS6AiK0B|jOKd5{t<NU<`s?gH1Da3fR8Qu9D7JaRyHKZ6!*r+}|K
z04plWOwTA$04+2EUlatbBSB_?FvMoCK}2K(uxj+2h$vN%O9W*FH_)NPsksG^>Jfa^
zk%9(jodjfQ9jMlZw6+vdV0}TPatUk|Bs`6xv6e-Udk;VfDHgh^8d4sByahS(4iTWB
z(gGw7!qBDHpg}N1d@ATFAngpn%r#hD04`!6r6DL~q6dryxYdbp6vRuQHCND@PeU^r
zECvaFPy-j_lcH4kdM5>F27xF5<z6iAfb8!Cjrl>=l*6;BvO);x@UhHdh1^Q;F?Hba
zT*xXQJ%!+Wh4PHV5>Sc+-36GK1iJe*v&0_aUQiZ?*qVu1eS$_#!45~tUh&AS4p1<I
zFuePURF`3`AvKb9a*^B(vb{7fv#>N3k^(@De~^W+3<)XQvJGJM7Tl%K1O$<XxARd%
zLEGY><H`_apd^_ITDJqgOb;^T4PRyiQ3mo4%*1R1(8z424vN7b1>pU3pqbOmJd~&d
zHMbQsvJF5Zn}~Fa>K%}N5QZ*$2QeWwLkqM_NX(#!Wv5o66lg?`dcYb#=;Idf5fX@H
zAV+`#UN0VWSOp|9kn<8m4&oz-Y<y;3N-Ah$95jqUCP1?jG?qZ}si00j(z+d#^;Hn7
zL1`c!Td@kV6BcqH)1j3O^0E@NItOeqsGz`7<ACLetZ$%d!Q0}ILxD&a7~yk*5h-o}
zHGV;zDUc(OLJRCZP{j<b$-qMr&`<{N#6b==P%!FY4Pa=h28As&=|R*YDqgTfpha$w
zJ}A@*cm@VX9as&xP66rG0rk0YHpH++Gm<Mn1|XsodT50axcdz`K&~_uB^N-fPR`E*
zcheDpL9X{f!v*jRjTQ=!;8%uHu%=;hMye5foB-1SkUR`+^m&3hz@Y1+!1p8CqqhGb
zUdIzY5Tl^+gwLTy$Uy|^)5k-yE!1@oPJCKv9%y@1QE>_8XarJI1Y{Am;h7k9h&d<&
zDA4Qy@d{epU>O#H1`E6g3SOTHIw3*<GzONLm#zd(Oi1YiY$mKOfEGib5*M8Qt80-|
zW`a9@pvoHRd#Gw~p#_OUP_l=*I1{||7i>C`-$4opx)Ivw0h<ePua1He$aW<ih0GKr
z7r`&@0N+vw8l3>SJTnCv3rH#<Aq$EjjWp20X&nW)Ud*^c_yz3z=*$#Q(*mpyA%z?x
zpvDC_yuj*_tc56oS`L<k7V+A)3g9EXLE!<)@en28yRDp|i3)6=m4ahlrH(>waXOf#
zV5<N=PaAWsA=oDLl&ObgEHq5OW??IAz^CqkOhL}*(5wMF1PgX78+4H|s1So|LzFR^
z3gDR&#5KbDN}%Nq;Dm!H0Kgj#;^P&x6_oS}vUA|GfuPVpI-ds|7|2di1}*CaH_pKW
z?BG2l3L2Susd|tmSxLSE=-?iOl6>Up_+*ef(NZ}`2viAx;sAu92^Z#B$ep+_9?a`t
zgEWyH1k#FpM=lN>uo48M9Pi{UBv*mzJG6WQKEOJ^AT>_|><CbE2y}%z`0Q%r3*13A
zfH35`W61sOpom4p5Udu^Q2^aR4N23=3QnaZpc^>AyMhvPiu1uo@PZR9=sf?N%;e0H
z9N0ax;8;Rx)_}}M4iwPX4>-ah`k@1D;3G>wBlil4IiM}el?osuK!>1(r$Y7)fSP|G
zG0<k2lJd-C<h~xrPmlx&aWRMw!paI5+ls;GfTcjo5y)_9d15i#*5cF>J%w;+13o<;
zG#8tnXAi!p9%LX0gM*krf`QN9fvf`=0`V+pTvbU&0c-+NS%7p_9<+}OQ9(GC@m|cH
zl30=m+SHSooSl=3da*djA21AxAdCb6x-=}YBoPsupn*^{_n?;6iV9%+Kv@Soun9if
z9?7$iEt=qao<TDlup|MAHt?<#P(A>q9?-l`P-=Q6=n~t^yma`KCa9O2nwgH6<Aj+3
zpC18vDF{5~Tda_%kepvo3EII38Ye>5rUTk+n4AIXqGhI}=9Oe7CxQ<TNi9n)f*$M)
zGN?SUQbP;W|Eow&Ehtd{r+d)+TV4vta6NeM8Z^KSJ`)<Wml4$c1`R|dCZS)TTL9W~
zl3!W^9Vvjj8RX-<)N&+Wmgb=xg9<uHCMO4EIEpgJz!y>~QdV%SNCa=l%gM}6Rmjgt
zL5u)^uEPeOr3Sh+Av-m-pjZKPV0<<xc);CNsBb_UAdx!kLEveWB9uS}@0kG4YbO>I
z<baR3Ly^}}09y|V1dyB210TE>Ha|sEp*$aSwhj1BD9{FJL`n-n3R+tQWIux@9YBsp
zxE<<j&~!H_%0O6IAxJO3C^J11bcd}iIAMW=!B|-#7d&hOyL1B8FmU{rfKD4kng)iZ
z&md6Z1et;C9{83-EWreqgLn*08)B*yHE>bqO_dciv^2w0!NqP;D)<ItaAYZERHkR9
z=4B=;LE;tJaE0QM%$yvB%wq7h*u|OYd5I;ZMX9<4puxr>&_Pf-3g9ZSGQSj2u!2sP
z1f^K$$$N<kMWFraxv2`EWAQ<Wq#zNr(WfM}s8~<IEx$+sw98osTql60DZo<^nZ+3j
zkWF@(sl|GFdP$|=<I2GYM<;_fgMl&!c)lnRdQ&$j3xWy*9fjh2&~?-5#o(eNQ6VW4
zv@5q5)BynnIy4fH{RxT>P+_8AtAMk-0Lg<JG@v{N$uGs>nI##Byq26(4B9OMT{D5d
zJjuy{ZcYU6-FEf~h71O}xH|g>IfnQLfzIwM$$;*G1-UxE6ts;ZzqkaE58<;}AbEt&
zT+q=;pg2%aDnb-|2yIH%3i)|RCWFpU0{I#=IfPJ!qFG6yEHe?*7=olfkbNK>*veIK
z9x2Jp&qHw?bO#x<L5DCU2Q<b2N*2(Zj25EM`#|!GU>6EN!WVf-0cd0>4Ky-@vJ)5N
zLP(7QwGz~ZECwG%4w<e?1GOHN6+H6GLFEc)eI;lL6S9mOe)9nAh$wjR3bHIWu`($Y
z8tI@C4s_ULF(|8LCYQv=>w)JXis9o@Acr6|!%#JYnpTKH2V?ylXe%>{WyocjEh4JW
zYEqDu5Wl0^hE%$Plz?z$W@=6f=sG<lAA#}$2t%VRuQa!y5|kSA3ZSciN)nSwK?kG3
zmRi90P-)Q6HfVVjOd7_AZyhYCOv_BqNiBg3z*Zq4*$Ry{xRU&0I5V**y&$ouI2A5X
zT#1kbSqzteoV@~SFe$^fWkWp$Imt#LDOnFx9OY)_Wu{dsfNmuKwF9AQK!^1xz%{1i
zL+7yzQ*vQG1FJ|%O-?K=PDPlb3pNMj7qByn6l_6zalvdoM`%$M0P;YQ2GTkm+Zc6M
zP|`^(Nd*;zpsmRT`9&pqpsh@)1(`Yd>9$HrO0E@&xdl0?RthnBA&^_{K&ciqgbpr7
z5}^yiK=Ltpb_$RcAqt7bpprW`HLt`lKBWM>5CpCtT!O;py%mf=3;Pi~(6LGQ%u&!S
z1g#gvZ4p=j#1y~$l2pjC8<0iS#R~AdyueE}QGBfslCOXvssmbo0KQ`hZXsm-n_)ay
zE!1Ofpt?GzQU_G{gKPv1pQj<44yq?Wmx+L)ED?J2gn|a>`1Qo}R81Z5+&HLmffx?G
zNm8K*a-AdS{-L50kXBHor2y5X11cL8baNH*!P^8OtG6plGV=34nG3X2xwJSntu#k3
zCJ$8KA@=KnreQNuq0y!QZtiA+qtYcmxfB#*#rnzlrA5W5@lc!eA+9n8?<fHs5~Ej8
z32|})s=@@2Hxpq=0ID18&OC+W4A3bw&@&f6C#09;E5xWHtV{rhK~ZTQYG~``Dxlh-
z2XPE|gaLF0ENpQSXd(-F$Gowgr9OB<Nk2I^1yug(f%ePC<S8kEmk1T*CV~!tgY?;L
zVfkAxD6t&0@6IDNr@$>Aszx&=51f;VK%4L4VKu)-jJj?iD5vCs))m>tsM~`$pv}6V
z#eJYU1HAbZJiMx-kdc~GU>l?E4_a%I3d?igh6Oz3YozL>>sf(QuO@hy42Pw<pk?H+
z3$j3Vf_8Cd=I7ZefmhAMmlTzP)_}pR3<e!s0!msiE&3^`#hFE^DbSTH1g(Oty&=J>
zMDWdHkn|7Qg$zDjsI(*%bVL!(z|@6YS4E^XkadWlJOQb8z(YsL`MJ4?pxzDmK#vsA
zf&|>wfo9M_=g+C@DBur4$I_DgT+o>ppz|OUK-v`GC7>Q?=`-l+VesPTl+>is^mNd%
zW#CYSbQodL9bc3RDqZ7?OG-g~HVp_@2VU_*Q%WId**=sF2@xm<WHIP!UeJmY9fi#F
zy!@inc<9I{_$CF&iazL??~?qS_|&2zh#0I{2ui7-{xrBI&;zG0P<n>%-2kogEd{O4
z2VG!P4Bqk!&Xpj2dWE3O4I0A$IRL5phbLfgol~q=h-hhnPJPt_A4>>RgrpDD7Jv!s
zD1f~U+KCK0A+HQ_Ay65pi3L*vS>K|eq^E>@Ulf*3Jxl{=hhts|{AwO>Ga6(kQp*Sy
z1xm0q4n6xD9Gps!6C*%Ah7Ef`?*V{l10U}QI!6Yo338_bLKBu4Lh?Pvu#TMqc!Mzh
zL;IC<6ku+F9omoAF**uL@EQ+1Fr%m7oRONG4au6&0vd8w1@s(#&@2Na0^t`6gW?@6
z&LIgC(#j~-gYe+Gpa~U=Hkb@Fr9io$W(z1{AXyr8Q66aQAs##!W2=CceK4~PEWV)$
zA7$GODDoh#gQhTBa5{tSsE42C26c%ol!h7wD=|UUL$Mxmu?tlIOEw4vFcBSyt+o(~
z;E`}3@53<2o_JXHMdpB0FeH?f6+kBugGLiTRXcKz3v@aUtP25|0)jRzK@DDTlLfR%
zsVuPs+8IMplUbCLte2CT4C-$~*BYS6SLBpu=B1;^fCdB=Km)f0l@&R#MrwF|QFc;(
zKJ*G=6e9{iEANUyZTo^0m|s9X2b+UsWi)gO5j3fZtULuYUxOqEpC^t6t#}3*2(cBs
zfgjv%0p(Os`2sx!6(SAlTV)&SC}<SwC_ruvN(CR*3Od>lnz3NX3x3fML?_4!ux=wA
z1yG3%Dyk5Ap+~jD%3XvOkhYYR=oodFv5+~F81-1#VH(+n&^{9uO(2UfH5lR60J8<j
ze8`dSxV3=nKvE9k>Vei$<JM7<pM#{q0Ca{8DBr>6-9aXRI-Ou;u+wS5r&s6aU^Nsq
z&S2q!(_B>Lps93Fr2vi;JybcEZO93!5S(Ga=k<bWXYlnmpm`hcybd%8fV>Y9)2qlS
zu7GZgg-`5)Vialk8(Kv`jKz%qlz7nG0H_X5(F3tS7jLKLXh4<gmE?oZ34+bsK#~B+
zJJ6Z~A^@@yZV)JEz||xB44gVa$r5t>qoIL;0j7H(^R+SRMWuQ1G3wf&4MN$lU;<eK
z#+hlLNqUe`5L+=E15%Ze0-JXS53N8{Mng<C0HqI5t2eb6e#<z*D_H%9Y9wkrBKs1g
z4up{x#~{mt=7&K=k%FxPtW<)B7DylX(wgFo)Kt(qKA2*?#N?99GL#Y$6q?ETIp7&)
zP)H#1dP)lHu1$<^0htFjTMu+yp+-@Dxvim&LUMjiX>Oiva(<4sp(bSPM!^;o!pQCh
zxea7zQGPkL0tOn|m=OxnhsD~W{Bmt0Tvmf}DAaB!1u_L3GN7Q-1I;<Yk|<UMC}(-X
za|Y<x!GaP6U+~Fze)%PCpu2*>jT}(%58LeuNe7@IIU{2eWYa-)F|28TrC|yUY>-PK
zJpiSEqWrSVV$eQ<99XL%Gd~a1paCfYVc4jVMhU!y0Zr^s*_>3+>OZ(7#5o{2h!v>%
zkw*j}@=6LI+aS8qK!Y&QAtlg2Ab2blykwymbR-w}m_^Vwoz%P%u&9QnX0&0f9;iDG
zDsLc$q=UFf*K~odZUxDL&Q1g0d<H6(;3E;xq6w)q0=M~!HNeKe(h9;mO5pL4%KTE$
z$WL);PD!x>cs2u6dRL~FC?ut(g0}lX=CMFCnK6(d9OwWqq!9^kwH4%~CKjiH#@)dK
z6CjtP+=mVgB0D=fB^?Ebiy)pva*$^pSTA^^MQ$Q!Pai0$fCl=D5<ya##o+M@@Rk8s
z+9(1~mqB~8;Nwgo{jO3_^H!q}=51w#3<X<-s>}k7XpPKh@KGGGItm~b{EP&3r~u;R
zjaW!W1iT8c5Rz4kH8f#Oj0^=^%FTj=0myB61$v3aiA6<;l^Pk)WC`_KMzocVL9C7f
zh&F`MMzK1e5P&Qc2!(Av1`S@&VlyNW%K~A0fPzyCOF?szi8-JZ)S&5O)Sa2dB@i)K
z#DJzY(o^9F34oS?LXMq+thfg4CIYWvhp7i87trV<c##FD+<>_a!w`@vgmy?kgLFgA
zF96NxK##WtnF6l0P;?;1*RxYA5fvB61n?9B?1(pz0H~;T2Gt9wCV)31B9&AirJ$vt
zh?94mA*VQlv>^@(Lel}#1-23FMrRCnDQGL?KpW*Cr69A=J%=U@2|K;w{37sfFI#ji
zdf@d*&_oC_6Pge~>L7YSX%7^01iNRTo+GUD1!02<cF;fu_`V8^t{CKK4S3fJstDW<
zf_1JSgBq|d7P1P^Fk5_DPGUOvoPQmK;>?`XJlO4xhy(!g5e$P(M(H$y4w=ExV*@LO
z_01p_V>dM^Gd(^dH8CZ%2<#G2+Jz_t9noqFT4<08nl{kO%P)sDM>5kulZH@TNGTw(
zI5{&jJ_%A9+A6?iGV~x58qkx(HIzU_fO}D53TW&vEkCcsRw*SvKNnOV!F-woI=LVw
zCJ%bxr$TfNc+42Qasb&9$Vdxl$g~);tqioyJO{SV2y|(LK`d-VKT_KbWDVE~kW0Wl
zO=x`tDfp8>Rh2>+Xt`8;JoJ(k_zA8lCGntbOnK>`V~6s~L3X8q!bd|%HAP=FS6?+!
zLDj=b)z?Zj80I60sY>9ZT2fQ26hH>Uje(|IP`-w?;Y&apk04QiZ2$=BAn2G6R1Z`T
zG>`$R5<#gKDPF)grYnIqvVqzhVEa+^L2QG%6FSiXnivAPv{*+$Ndq*6qpJ%_v*3t;
zjN=zWcH@In8b}J9oY6Mf!xrbHDS?Yp&=$Mma@e*<D+MLc-6G)L3@pc>3{mMQK+cMR
zxDU}3Lh2o(oI(JKo5Uhe`xq1@&=U+Gn!&fCLpND~;vclU34C)Q)=B_8fB{klDlPLM
zz3y^NP^pP%O+$ka)^UaRx<T5M6$%w>6$)V)1}YQ}oj|o!0B1;u!!YDP6J*fC&Omq6
zfvZi>_F#;Y&d{2gu!skbgXU=)g0|nl9EX$`K=y&w6=&wbX8b`S#h_E-LAUMXgGvJM
z0wz$MSnO7mp9^AuDkqIXXkrCvC<G@{kSFzEmO%G~g7<gAy42u{{!kUb`@JCFVcT*6
zI^LlqClxgMlLv}RCD`<~f@-D}=rA5tjXZ5b9R-LJklX}Gz$n_W9EVY;2Wv)wP6|gv
zLZKe4HH9V)+Gk%~tDvmlo(S6bqyR}unb1}qIDViDjX(jTj5t#-1lliy2p7hKmJWh;
ze1Wgt1YLs*x+EKvmO<Sbcrb!<7)S(^+@QlVu#pOoFkB(VrQFZ~Ban6A^Cln%GoYR#
z1Bx+7L_xz>S-}Iew-pf%$Xda98@b8>t;IvXA4LIb1X3U%n*lja3RGNzYGRP%Kp3*U
z39Js3zMw5Z_&E%=Mxc@b)Y1osuPs<1#6Q??*#sTm3o1mx3W+fhG|C8SB<O(}qF@c+
zlUA{tUIjY(#~9k_136zA97|c)I=s**168CTl^_i1IfC*lC<2j7X>ewR<qr&rENCtU
z=|alF5aU1wV`gM%pB5wuQ3kRVN6G`O*v~HkPo99*ghEcW29<cA`U5=u51#jft(XBV
zGXos}1X+>_&i}CSTZDBG7IYCW$lbV;D^?$Y4@v`dZ4n#W5J?lmb0FKmhyQ?FjHC`E
z4#uDru;}R(tGyuA*iI_~<rnn31;M8XfoJRW6hbmm;rGpg=A&{GK^IJd0ueNmS*Va%
z0$%e88UQaY&DBtdE;K?n4y3ry2%OuoM-;pb19BuJRzWNf274auGO7|=Y#zaS>=IJp
zi7*#DzzxbC;HD95q}(~Npro`2)GAO`aPjwxQ4diFa`p8Ob5#iO@C;V)@$_@W76G6#
z4?M=95u*+_B1T<P12W$Lop#U!A8GHLQ<|4u3A3=cGOr}D0+c79iwjb~Nisi80c}MJ
zC>%f-;R6s4H0^-RK_EF0CK&2ClL<&S2p1aZfeLWcN**MEjth<SG7^iyTXj=YAp6@e
z4&lR^v|$D*E1>2ih_#?J<(ZdRl9`y3Sp{0lkqV!og-`Z^d|8~42#z<{ov7F|EyynD
zIG8JV6>esJ9%x7dHu?pUM-5?+2sEQZJ4ytD45}Q`*&(PJWC5g3hYVMN_#lkw43H=Y
zLsi=<X&J+gIR^<7(vYSU4muGG6s+LD1f_C#p<E5RPPil|wH7?!16Pv>TEz#xT|oh~
zlB!%GF%NW1a()r4*-wnc$j6=#a->oScqt6%>>7~!Kx=fshl_yAXt-<3K`T;oGP6@b
z%Y_p&bHD>oAg6#ZK`Sr<4qFZ)sZ2#Z-V~d0AcrB&eZoBC6xGp?7$(%l!<w5wnn35A
z!H+pp0GHg*ZUVORVzC+nae<P866}OC_yK1i3*Ze`&<aXz1r74gGXr1P0jj;hlUkta
z0ovohbDkL@te~z$oM{FMW)Maw!QCK5t4+~k4Xro=RgntH3c;x*;2Z+E$OB#!LFVl9
zl2gGgCeX@A&=@ZCVhW@tBg9>xat@_=YO4S`qESH!?L1Cs7a$AN4*==W12;#It21;*
z6P;?YSE*o2;1zs4sDBBoQ9)A3Zbo(mD8#{CVyuN7B$CkegEnR>fY0OA%1x}$FwjxR
z^U*cY1&wVK7lY1$!qTaMgdV(qiPVP#nU2_UqN9M(jf7|&JuthpBo%avdT}vm#1C4b
z!N=twH5Nw94)+7IA!&nztb_g3ONcR`yg*z*k2_z0vxNez<W&F{y(S8};7eOUnFF+k
z2>tv^j8Yuh3W4MntQiwh=D?4ghR%M0_P4{w4nX6HkYWjRq(90r)Cli_7O)nlCKp4`
zs>Es+I9Q-VbQ(&;oJfr@9}-Z-paTPu%e(So#PRYv3P{5m(3vLCbyNuTa4*?{rl#~j
zo#JAYlc<pl02M+-sl|HGgSb;sZH8=g1xE&|A_Z*)xF~pryco1O6=oRx9tuzZgES(X
zfN&+sLE@mLcjd(j4hk^0qvT8^_revz#PBK1tt<jf{Az$SX_PBy!9z|{K_70Df~F>T
zgbQXf`0i<NVlY4+-+<W%UE7Cjnu3;sp`HPXk)ZJ%tOkM-2MB}5oTBq$K_i&p89^(B
za?ny0m?qFc`CtK<y&wS?8>A3a4HSa}3*$jtaCHghf>}ss51|Z$!Aw9z1Ip+b+;-?8
zZD5xgf_7+u>udP9U14>ewqY%FkR7ZDbo@h_l0r4Ywp#t_a%3gYq-_YQ4VCniv=lV*
zd?0n8p(cbj(o_JSB3o>vfE23`eW)D<#K<vhjZSnLVpI|8Ivs^HB@Fj~CQu=sCy=MW
z5d?JxELfm%uaFDs`NIUkC+dL002a0=s$hbk)+1;$VsQy*0}gbjLS`OxzaXq3m|qOO
zK?1Z$2g-!F6)F!i3^XmD1Ug6}6}pfO_tXx2UIH{;hdRB1G^+uz1$=olD6fDTL$Fpf
zbO;_A61kaqpvBan9j+z%`ex7rRiKCYf<+Z{LEU+fA}yG7K~53qc5&!sp_w`g#a5u(
zBQ-KXWd`VIVQqzCaH=Q<p9Y)>8t6tG0}RWAkaUoy<eU%M6H)@6c+pls_)l8_+B64Q
zrvY`Sj)D?|r3AK1M?pzj0W1%7vW|ihgawjU(gbz&AYp+eg(-#Pmn7zZ4n9=^uU0~f
z6isa<eG~~q0s$pDPzr%ASb*et@R$xL$7;Z$6;Z~6FU&|uElJGG0q1dWVua>t=zJ*D
zEFA@eOF<z8!Qc@e*pd<0_zR3r?8YVN3KIDKqO9WlJU9nwhf-3N5nLFuIUddhse&wt
zNUAC?$}CCM02u<Ba06Y{o}HQpzOELwaS~iuE957ol@=#MdgGvGFYM?k@W2!73b>>y
zBT%UaTKx$cdn(D#PR-L%P%1A0O`{bnAn)5xgWUQAw^<VuM4<WObnxhZJY<n-u|{TY
z0c?mDKCl9cDQK{R&W*~<Er6sB$Y^mcs1FBP>H#wY+8jX4k%2ln)w%HPthJ!@1xg5M
z3bqO$VbDqy*iD|w3MrtA8(@p9VJ9PijuHTAQC29)FMw@}0TlqndIgCk8G0~v@lZ#^
z$7_I01})WzkB7{sYJeMApbHu__2R(`%;B@2=%#{J;Sp^T$bPs<pxt|jZVBAWpcX)k
zdM<b&R*X7$bR0Za1`R5Z&+z*T<QYgXL5m=e7KnLJAEOMtfhumCW|QbMy?Brh!574W
zECpe7i@|;YB`A<2dSIeQCDGQS_?M8WNWljUAxMe_EjR)h1WU0{QScGlFtMu40+15D
zsLTSlOwb9?Aa6hwX6D0Gft199hM?l1H@Mm=WajHRRhFa{d-`kSR>oIl7J%2xL+uA~
zlS<Rlz|*lvDxuQgjErWp20{-gUzdaC6cdX<UO<XWWe^{lo1tcb+zT2KEy~X?(E;u7
zDh3_Ml9LMFRF+??SDu)Yt$`duNXEhRg1iUH$siirrGuGikd<Glc`3ypw`(Zr6;vw0
z$_kJv$T$s@W{~n{R(@ul2E=(F3y|E6tg8%3M^S1H$P5iw@<BHNu@M87_mMq_!-A^J
z0%*vA9jK#F1}+CdZh)6|(J|`KXo*n=HB1q40$N1~UPKEU8%NfIWIIG3vH<uDZe-Oc
zIS8U2RS2pBeE2Y2BdEH7mwvGP28tLxM6AHhjYE$eg6RVm(6Hc4!#IcrWCSSosFzIO
zbwp+k@|ZCwK42K81V@aLmSm9P1c!N`qz&FqfhXa`s24$VW*Tx83v)4yhDTd;87Lj4
zrGXcm!_p2~5sl3sX(;iH<Y0s&(?I0}PS@af0ip>7-XafPxd|=xVB0ZaoA)3ajllcW
zDBjK-S`3=h$t;HLv4ysKK=X>=1|DcjA#_PBcnJ;YOcGFA7j;`Iq}e&T2{<t?MPY<*
z0@lsThppuxym!?lvlz6x9CYGNdQoa|u|iT}5&m7ViKQj^If+SxjRtS@1?^SMNlXF_
zIf2%5BW**4Hnd9%Kx?$(OY-BB6LSkni}O-T;9KhQOG^q$OX5>9i@;k>VU;VWK@3Un
zdU-yO<_Ks*D5!soYa=O^evtz1t$g71Fz~f*(AAy9uLFgx@(d{|O~tWp6ILdo(qMaG
zaTlMISY!)Y?FI6i9wJUjGBGI=zU&ij6f^>%<tL;AjTlIQ@@<v0VApLzMZiZ2famy2
z!QC)euLU9v>qa8)WPsYB3_0it6wTn7BghFPkU3TGG=Fh1Xr>cXlY$Ppfz{&>WuV1A
zpfj@}(F`5Z1&0XK8%Rwz=-tlHq>-7Il3A9SQks|p?Gb?Qdp1B)4+?yU>y?~9=TU=P
z2yzLi=+y&v9>GmK$e}!CsYRgkF+g%)m!fPX0GR}84S@T8IPFKX8l(woJ!l64)-DZ_
z8ponkh2)}C(83e_-29Zxv`p~9D=<&yR4OD@f_6ZFS|f?+MX9NvlM|o^>V$+AE2LH=
z<|-7G=A;(GVh&_D2tyr=+-C({L<kke3`bZDf%Kw=IkFMpb-8F>hI-dCFFB_)1r*fa
zpai)XQVi(np-g0hEC2;-wvGZgWHDA{qS%LK7f5qnW^MsWqd~z|0b1@rYW89c&}q&f
zrN|iK^Z26FoJ7#JtN5IJ=*WXDe77^KISw5T0X2m|et{NUh%T=tiuKSOfovDZiJ)C+
zkiGaARzljsxEut@6<CY|b@U-xLCFflgAFJkD~4vV=xk7X4CD|@^S~2^pb`A&Z1Bu(
zHYl<{N<m}U*`VV^Kmt&MVzI?J$U;cGr-6ryv5kCy)WEQ^0@O6nFpHKJlmoh%3S=#G
z+yz>mN5`l`<sqJhai9a$pp8fHDg?B|2sGo3luQuy3#6l!o?4Pzo&su-LIMIh1rJ)x
z84ud&gxHmde4aQYbU~}h<1-TTQZn=4$7@1{@DKxdVEv%gj>XY2>d=us=xWX~_;Pcl
z_%bDJNQCRb7ksBdPe(zBK+g37c?dl5te^z96;g89Dk!NI$E#+>=cmQ1W~vrL3N$5E
z4RlYzW{wcf)PXt%np$Dz!8%0Xo+l#cKnWZ)W(Nr}L{l8B4b&XRdTu6UNDy*fCNwg2
zkPgViU(iF66Qa%nB^{_3=**nd5>P>zl34;yvCy_NIM{U*pqs)V#SNr7%FIj8Nd=em
zR^aV&Ak#n?Y9gp?2KxmX97s|j`3mqx3%H~OolKvYR|z^#Co?S*QfL(Gfy!G*=z#RX
zI&eyUpkuc(b0I4xz?UyVt2EH*VGuo_0ZB-jj)xqVQ<4eV2@XnepoO!b{(xaTL;+}0
zyAo7`!CFb6jW8NYsTHZoN}AAO386MUCqF4M2eF5!05lX2jT4X|#TrSVfgC;1ka0$8
z1uW6Pb{ImEC$t5n0dkHeOo?qljt*!XKQp-mveN|ObI`(FkaIz|pTt9xphf{~zcsw;
z1yTa4USjf)_GEyzi5Tcv>KTBOILJu~$;E~ShI$$Kxv8MNrG~J<>>|*CgT<-wpnXX?
z3W+Hx@G)o5LPyYiBgk;@T4ROq)YNQ4+}A>Zf*zzHJ~0LJUIFl8PslVV_!wagkRl@;
zBTXFz6QpE<Rhh1#fq{;KsiuyCuB9n_xCL$<)C(9#@nV<-RS5R0Mzo=hk&bb!rjA0i
zv5t|BA#82|CBZo*rhx9NDkv?9iOB=)y8+t{4<c}w!ZytXf$Jkf4G0ZOQ{Y)dP;@v4
zD;OFWDnMiv454#=u;po>Mq9K7IDmB&3=K46A!`^xm42#1q5`P7mxEZv2+pO32GBfP
z3|%aQT(yH1&x2hTtIo>>NqdH{M5JJ=pl)GcU}9-%oMwOm%u_5)ERqdOP0h_r%}mXb
zj14VKAYw+zW~pXrMh0faW`<_QW)^0qMh51_AXP>NrfDFSxrw={xq)e#nW0&#xv{yq
znW?#vxv`OfnWb5(k%76XS*n?(xrv#%xsjQnnTeUHv5`@#xq-Q*rHO@wxv{yiQK~vG
z7bsuYDnY`?P>Gid=62BPdhief5t$mzx0<|Mh>{mlX@N!sk;eN$t&sS5O<pc&I|owI
z5$a!Q@^S@uGct)Vh%kVFQLbDt*AeyrGiC+`5EcRnLh-gn5Ca??`tS^>S5S$r|HYjK
ziyCGI1`rkiX@TNxjcLpb3=sWL-(k`H`3S>`G-XBx5Eg^#1X0@>1=!Ja!?zm;c(byB
z)G#wJGaO=IU|6Na$iTobbsI>Gfq`L44>!_y*OZ<hXR8>{?P$d@C8ZguG4PYWVnAgD
zcu_QH?*#Z{5>VT@ASbmr2Fi#p&IAp?6qm$64^JwN0efgl4=>8F<&@4I35Xx#F<N$0
adITU+h(VhvJuIL!Go^<WVp?f&sU84@H=JAm

diff --git a/examples/example_simplest/students/cs101/__pycache__/deploy.cpython-38.pyc b/examples/example_simplest/students/cs101/__pycache__/deploy.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6e14e2ac2aed2a082d17689ac69828e53aeba409
GIT binary patch
literal 911
zcmWIL<>g{vU|^^b)=Qks%)sy%#6iaF3=9ko3=9m#3m6y}QW#Pga~N_NqZk=MY^EHh
zT;?cdFq=7tC6_gd70hPIVT)o*VMt-gVUJ=@WzXVRz?sUmkTHrol_!NYo2h6{Dsw7h
z3L6x%_p&lFq_SqQrgEonh%=;er*Mihq;REhr|_ikrZcDT^|CNBr0}~i#L7hRrm`*I
zOXW@x0IL%eXGrB0XIRL@$WU09!V=7&DfANLc1^}x>_Mpo`9&p$nvA!^i&INV3*ys@
z5>ry+(=u~X<BPy@nvAzNit{oH;!`q<{BCi?$LA(y=EcXmX|hDI<!0t(rd399<|n0<
z7AGf`q(-r)R-`7EmZV0pBvoY=RB`I->FFmI8yXl^iGrAVdiupBr75X-CB+cokXzjG
z@dcI1iOCtM@$pscT6!h<*{OL|oGGaVIr)`(1(ljCQC!9OrA5i9AQwb&q@)&?fLWr+
zIjM<x@gRO?USdgRejZquJ+&e^r!*y1lex-5PY-HoYDHphK~8FXT2W$dYI%N9wti+_
zaY<2Wa!Gy>*da#x8Tk+yL%o8^DpL%dDf!9SsYU48j8V0jV`xjuNi0FvWC#{Sv5yzU
zoL`Lkn*33`;BeD}#DZZF69WT7lv-(CW(g#U3W_qz5=&Bz^fEG2Qd0BclZ#RlOCT{<
zT*M4g%npjSg4CiS77&lEIHR;AGv^jle(^1qg2a-HTkI*BMR|$2sh~&&M|gY`Q+W!A
z2NI2szr~n#izPX~pmHTc5kCV1g!mQbY!wq)oLW>IQ&O6d8sn0mT$&4t&ln7+#Xv*7
z7{-V%&IH9maY+m!^kcxjjDbh@Ee@O9{FKt1R69mcb`oM>VBlc{K><b{CJsg+W(8&r
FW&j@s6|(>U

literal 0
HcmV?d00001

diff --git a/examples/example_simplest/students/cs101/__pycache__/homework1.cpython-38.pyc b/examples/example_simplest/students/cs101/__pycache__/homework1.cpython-38.pyc
index 1149b3ace2379ce11502c3e4633382e7f8d4950a..7dbbdac7ae33a6d3d1764a740a5f47ff3e00b252 100644
GIT binary patch
delta 374
zcmaFFewd9fl$V!_fq{YHYmj=PAJarWnR+({28I-d6vh^YD25cK6y_F&D8^K#6qanJ
zBBxa56xLM66t)z$W~SK;bD5eM85vTUQ`l1(QrJ>BQaDq%(pj1ro0%9HQn-T|G<lL4
zL1sfSh|SEvz~Iclz);M?z`#(#P{LTl(9GD(7|fu_Sha{tK|w)bvKZrBRZXT_EIFCQ
zCAT<=Qp-|{ic?cG8Kc;8D?wr_8Hzxr{7RhsozaCWGq1R$s5H4Gzi6^ElOiw3j$$T|
zg{(!alM9(-`8XID7-|@57{wVtmP}s2l&TBTuE}(ZG4U2-64)#V!NS16aEm!HB?Y7f
zVhD2)$7BoU5O0<uRt5%!B9O!_j`;Yz#N5>Q_*<+6MVWae5X~SnAuO;l95%W6DWy57
Sc3=mA^l`9ruyQboFaiM8MNBUM

delta 534
zcmX@i_K2M?l$V!_fq{YH<6)gdGv<kWGWA{z3=Am@Q4A@JDNHR4QH&|fDJ(4vQB0}K
zDXiH{MQ*7qDQu}sDeNii%}lcy<}x)iGBTvHq;RA%rm&}Qrf{Wjr?WIOHZw6Yr0@hY
zX!2I2bGcR|<`(3nDioKLrljVTC?w~nr0OYzWMmdAq-Ex$Dr6QbB$k%s=O&h9Cf6tC
z<Wwr8r{<*=C6=V7D5MqT=PHzBq=HozD`e(@IhlFIB}JvlCHY0VDVas7AVwuuG9$<*
zPz+)-F)%PVGcYg|^Dr<llrW?)HZwLcrZ5FFXfjtV;!;phP;k#IOU+YARLIFJE>Td=
zt<1@sxVzism$)a$y}2N_rj_O;mt^MWDJ12mRQj!Cyd~_HUjmm-O>r$M$}iGnjA8?6
zE-qQgP{hK(!0;=6ayFw22h_vGlXo&I@`A*RK~7>|D`K1coKaQ?(^->+m{N^FPWLMU
zsnle;#h7@DF$ruYgkWW0V7SGcn34k03^9(Sh;#B1rVv5aTkP@iDf!9q@kMM53=Bn_
plbA&fK(<13f>~hg95%W6DWy57b|9OILGjPR%)!CI#=#`Q2mmE&hJXM7

diff --git a/examples/example_simplest/students/cs101/__pycache__/report1.cpython-38.pyc b/examples/example_simplest/students/cs101/__pycache__/report1.cpython-38.pyc
index d7c0fcd96cc7cec28f9155fb61bec8c3bb6e00df..83e9e30d8000e629914b0160acf822078d8a3b78 100644
GIT binary patch
delta 163
zcmdnVd4`iOl$V!_fq{Xc@T5-S3#N^Hvl$tSCa+>NHcc!o$<IklichUb%q_@C)z{P0
zhce@fGeIK7CHk3p#U(|h$tC$k`pLzH28Q~Z|1&OU6u!k-SejZ~l9``Ze2Wz<aclBU
zW;I5E$q$(28E;KuiITp>QJR-oQj%I+a*HD*wYbDNu{gDeje&uoNNRE^i!D1R2crNh
G2QvWvcs7Fo

delta 176
zcmX@Zxs#JGl$V!_fq{YH?qQuoZsv`Avl$uVC$C~OR!Xf%%q_@CjW5mwQN<-OnR&$}
zMWx9l`9(3w#fAokF`I>$mNN=RaTb=Q7MEn^=M~>#1xrLtKEtf0B*?(PP|U`_z`()C
z!pOx~B*wtNaEl{8J~uHlFFszAH%fG}0gK3F4Hj4FD2~#+%#xDS;*uzikksN5=fvXF
VB9PW1$;llow(MLSi~_72%m70OF&+Q_

diff --git a/examples/example_simplest/students/cs101/__pycache__/report1_grade.cpython-38.pyc b/examples/example_simplest/students/cs101/__pycache__/report1_grade.cpython-38.pyc
index 0aeda2d66a25eaae02e31a9c629a9a2887fb7dbd..aed06f7cf667b51f32903bf52b3c17138bda2777 100644
GIT binary patch
delta 3389
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
NaB#AKsx&5$P5|l_t4sg@

delta 7949
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

diff --git a/examples/example_simplest/students/cs101/report1.py b/examples/example_simplest/students/cs101/report1.py
index 8e5dfca..9e9fce7 100644
--- a/examples/example_simplest/students/cs101/report1.py
+++ b/examples/example_simplest/students/cs101/report1.py
@@ -1,8 +1,8 @@
 """
 Example student code. This file is automatically generated from the files in the instructor-directory
 """
-from unitgrade2.unitgrade2 import Report
-from unitgrade2.unitgrade_helpers2 import evaluate_report_student
+from src.unitgrade2.unitgrade2 import Report
+from src.unitgrade2 import evaluate_report_student
 from cs101.homework1 import reverse_list, add
 import unittest
 
@@ -13,7 +13,6 @@ class Week1(unittest.TestCase):
 
     def test_reverse(self):
         self.assertEqual(reverse_list([1,2,3]), [3,2,1])
-        # print("Bad output\n\n")
 
 
 import cs101
diff --git a/examples/example_simplest/students/cs101/report1_grade.py b/examples/example_simplest/students/cs101/report1_grade.py
index efb1981..c244e79 100644
--- a/examples/example_simplest/students/cs101/report1_grade.py
+++ b/examples/example_simplest/students/cs101/report1_grade.py
@@ -6,14 +6,10 @@ from tabulate import tabulate
 from datetime import datetime
 import pyfiglet
 import unittest
-
 import inspect
 import os
 import argparse
-import sys
 import time
-import threading # don't import Thread bc. of minify issue.
-import tqdm # don't do from tqdm import tqdm because of minify-issue
 
 parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""Example: 
 To run all tests in a report: 
@@ -63,53 +59,6 @@ def evaluate_report_student(report, question=None, qitem=None, unmute=None, pass
                                           show_tol_err=show_tol_err)
 
 
-    # try:  # For registering stats.
-    #     import unitgrade_private
-    #     import irlc.lectures
-    #     import xlwings
-    #     from openpyxl import Workbook
-    #     import pandas as pd
-    #     from collections import defaultdict
-    #     dd = defaultdict(lambda: [])
-    #     error_computed = []
-    #     for k1, (q, _) in enumerate(report.questions):
-    #         for k2, item in enumerate(q.items):
-    #             dd['question_index'].append(k1)
-    #             dd['item_index'].append(k2)
-    #             dd['question'].append(q.name)
-    #             dd['item'].append(item.name)
-    #             dd['tol'].append(0 if not hasattr(item, 'tol') else item.tol)
-    #             error_computed.append(0 if not hasattr(item, 'error_computed') else item.error_computed)
-    #
-    #     qstats = report.wdir + "/" + report.name + ".xlsx"
-    #
-    #     if os.path.isfile(qstats):
-    #         d_read = pd.read_excel(qstats).to_dict()
-    #     else:
-    #         d_read = dict()
-    #
-    #     for k in range(1000):
-    #         key = 'run_'+str(k)
-    #         if key in d_read:
-    #             dd[key] = list(d_read['run_0'].values())
-    #         else:
-    #             dd[key] = error_computed
-    #             break
-    #
-    #     workbook = Workbook()
-    #     worksheet = workbook.active
-    #     for col, key in enumerate(dd.keys()):
-    #         worksheet.cell(row=1, column=col+1).value = key
-    #         for row, item in enumerate(dd[key]):
-    #             worksheet.cell(row=row+2, column=col+1).value = item
-    #
-    #     workbook.save(qstats)
-    #     workbook.close()
-    #
-    # except ModuleNotFoundError as e:
-    #     s = 234
-    #     pass
-
     if question is None:
         print("Provisional evaluation")
         tabulate(table_data)
@@ -161,24 +110,20 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         b = "\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )
     else:
         b = "Unitgrade"
-    print(b + " v" + __version__)
     dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
-    print("Started: " + dt_string)
+    print(b + " v" + __version__ + ", started: " + dt_string+ "\n")
+    # print("Started: " + dt_string)
     s = report.title
     if hasattr(report, "version") and report.version is not None:
         s += " version " + report.version
-    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")
+    print(s, "(use --help for options)" if show_help_flag else "")
     # print(f"Loaded answers from: ", report.computed_answers_file, "\n")
     table_data = []
-    nL = 80
     t_start = time.time()
     score = {}
     loader = SequentialTestLoader()
 
     for n, (q, w) in enumerate(report.questions):
-        # q = q()
-        # q_hidden = False
-        # q_hidden = issubclass(q.__class__, Hidden)
         if question is not None and n+1 != question:
             continue
         suite = loader.loadTestsFromTestCase(q)
@@ -188,104 +133,28 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         q.possible = 0
         q.obtained = 0
         q_ = {} # Gather score in this class.
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
         UTextResult.q_title_print = q_title_print # Hacky
         UTextResult.show_progress_bar = show_progress_bar # Hacky.
         UTextResult.number = n
+        UTextResult.nL = report.nL
 
         res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)
-        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)
-        z = 234
-        # for j, item in enumerate(q.items):
-        #     if qitem is not None and question is not None and j+1 != qitem:
-        #         continue
-        #
-        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.
-        #         # if not item.question.has_called_init_:
-        #         start = time.time()
-        #
-        #         cc = None
-        #         if show_progress_bar:
-        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )
-        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)
-        #         from unitgrade import Capturing # DON'T REMOVE THIS LINE
-        #         with eval('Capturing')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.
-        #             try:
-        #                 for q2 in q_with_outstanding_init:
-        #                     q2.init()
-        #                     q2.has_called_init_ = True
-        #
-        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.
-        #             except Exception as e:
-        #                 if not passall:
-        #                     if not silent:
-        #                         print(" ")
-        #                         print("="*30)
-        #                         print(f"When initializing question {q.title} the initialization code threw an error")
-        #                         print(e)
-        #                         print("The remaining parts of this question will likely fail.")
-        #                         print("="*30)
-        #
-        #         if show_progress_bar:
-        #             cc.terminate()
-        #             sys.stdout.flush()
-        #             print(q_title_print, end="")
-        #
-        #         q_time =np.round(  time.time()-start, 2)
-        #
-        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")
-        #         print("=" * nL)
-        #         q_with_outstanding_init = None
-        #
-        #     # item.question = q # Set the parent question instance for later reference.
-        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)
-        #
-        #     if show_progress_bar:
-        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)
-        #     else:
-        #         print(item_title_print + ( '.'*max(0, nL-4-len(ss)) ), end="")
-        #     hidden = issubclass(item.__class__, Hidden)
-        #     # if not hidden:
-        #     #     print(ss, end="")
-        #     # sys.stdout.flush()
-        #     start = time.time()
-        #
-        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)
-        #     q_[j] = {'w': item.weight, 'possible': possible, 'obtained': current, 'hidden': hidden, 'computed': str(item._computed_answer), 'title': item.title}
-        #     tsecs = np.round(time.time()-start, 2)
-        #     if show_progress_bar:
-        #         cc.terminate()
-        #         sys.stdout.flush()
-        #         print(item_title_print + ('.' * max(0, nL - 4 - len(ss))), end="")
-        #
-        #     if not hidden:
-        #         ss = "PASS" if current == possible else "*** FAILED"
-        #         if tsecs >= 0.1:
-        #             ss += " ("+ str(tsecs) + " seconds)"
-        #         print(ss)
-
-        # ws, possible, obtained = upack(q_)
 
         possible = res.testsRun
         obtained = len(res.successes)
 
         assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
 
-        # possible = int(ws @ possible)
-        # obtained = int(ws @ obtained)
-        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
-
         obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0
         score[n] = {'w': w, 'possible': w, 'obtained': obtained, 'items': q_, 'title': qtitle}
         q.obtained = obtained
         q.possible = possible
 
-        s1 = f"*** Question q{n+1}"
+        s1 = f"Question {n+1} total"
         s2 = f" {q.obtained}/{w}"
-        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )
+        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )
         print(" ")
-        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])
+        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])
 
     ws, possible, obtained = upack(score)
     possible = int( msum(possible) )
@@ -300,15 +169,16 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
     seconds = dt - minutes*60
     plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")
 
-    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")
+    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",
+           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)
+
+    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")
 
     table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])
     results = {'total': (obtained, possible), 'details': score}
     return results, table_data
 
 
-
-
 from tabulate import tabulate
 from datetime import datetime
 import inspect
@@ -331,7 +201,8 @@ def gather_imports(imp):
     # dn = os.path.dirname(f)
     # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
     # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
         top_package = os.path.dirname(m.__file__)
         module_import = True
     else:
@@ -352,7 +223,7 @@ def gather_imports(imp):
             for file in files:
                 if file.endswith(".py"):
                     fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
                     zip.write(fpath, v)
 
     resources['zipfile'] = zip_buffer.getvalue()
@@ -396,14 +267,14 @@ def gather_upload_to_campusnet(report, output_dir=None):
     results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
                                           show_progress_bar=not args.noprogress,
                                           big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
     # also load the source code of missing files...
 
     sources = {}
-
+    print("")
     if not args.autolab:
         if len(report.individual_imports) > 0:
             print("By uploading the .token file, you verify the files:")
@@ -416,12 +287,15 @@ def gather_upload_to_campusnet(report, output_dir=None):
             print("Including files in upload...")
             for k, m in enumerate(report.pack_imports):
                 nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
                 nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
                 nimp['name'] = m.__name__
                 sources[k] = nimp
                 # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
+                print(f" * {m.__name__}")
                 # sources = {**sources, **nimp}
     results['sources'] = sources
 
@@ -440,9 +314,9 @@ def gather_upload_to_campusnet(report, output_dir=None):
 
     if not args.autolab:
         print(" ")
-        print("To get credit for your results, please upload the single file: ")
+        print("To get credit for your results, please upload the single unmodified file: ")
         print(">", token)
-        print("To campusnet without any modifications.")
+        # print("To campusnet without any modifications.")
 
         # print("Now time for some autolab fun")
 
@@ -455,7 +329,7 @@ def source_instantiate(name, report1_source, payload):
 
 
 
-report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n\n"""\n# from . import cache_read\nimport unittest\nimport numpy as np\nimport sys\nfrom io import StringIO\nimport collections\nimport re\nimport threading\nimport tqdm\nimport time\nimport pickle\nimport itertools\nimport os\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\ndef setup_dir_by_class(C,base_dir):\n    name = C.__class__.__name__\n    # base_dir = os.path.join(base_dir, name)\n    # if not os.path.isdir(base_dir):\n    #     os.makedirs(base_dir)\n    return base_dir, name\n\nclass Hidden:\n    def hide(self):\n        return True\n\nclass Logger(object):\n    def __init__(self, buffer):\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\nclass Capturing(list):\n    def __init__(self, *args, unmute=False, **kwargs):\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True): # don\'t put arguments here.\n        self._stdout = sys.stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO() # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio    # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass QItem(unittest.TestCase):\n    title = None\n    testfun = None\n    tol = 0\n    estimated_time = 0.42\n    _precomputed_payload = None\n    _computed_answer = None # Internal helper to later get results.\n    weight = 1 # the weight of the question.\n\n    def __init__(self, question=None, *args, **kwargs):\n        if self.tol > 0 and self.testfun is None:\n            self.testfun = self.assertL2Relative\n        elif self.testfun is None:\n            self.testfun = self.assertEqual\n\n        self.name = self.__class__.__name__\n        # self._correct_answer_payload = correct_answer_payload\n        self.question = question\n\n        super().__init__(*args, **kwargs)\n        if self.title is None:\n            self.title = self.name\n\n    def _safe_get_title(self):\n        if self._precomputed_title is not None:\n            return self._precomputed_title\n        return self.title\n\n    def assertNorm(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )\n        nrm = np.sqrt(np.sum( diff ** 2))\n\n        self.error_computed = nrm\n\n        if nrm > tol:\n            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def assertL2(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        self.error_computed = np.max(diff)\n\n        if np.max(diff) > tol:\n            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")\n\n    def assertL2Relative(self, computed, expected, tol=None):\n        if tol == None:\n            tol = self.tol\n        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )\n        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )\n        self.error_computed = np.max(np.abs(diff))\n        if np.sum(diff > tol) > 0:\n            print(f"Not equal within tolerance {tol}")\n            print(f"Element-wise differences {diff.tolist()}")\n            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")\n\n    def precomputed_payload(self):\n        return self._precomputed_payload\n\n    def precompute_payload(self):\n        # Pre-compute resources to include in tests (useful for getting around rng).\n        pass\n\n    def compute_answer(self, unmute=False):\n        raise NotImplementedError("test code here")\n\n    def test(self, computed, expected):\n        self.testfun(computed, expected)\n\n    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):\n        possible = 1\n        computed = None\n        def show_computed_(computed):\n            print(">>> Your output:")\n            print(computed)\n\n        def show_expected_(expected):\n            print(">>> Expected output (note: may have been processed; read text script):")\n            print(expected)\n\n        correct = self._correct_answer_payload\n        try:\n            if unmute: # Required to not mix together print stuff.\n                print("")\n            computed = self.compute_answer(unmute=unmute)\n        except Exception as e:\n            if not passall:\n                if not silent:\n                    print("\\n=================================================================================")\n                    print(f"When trying to run test class \'{self.name}\' your code threw an error:", e)\n                    show_expected_(correct)\n                    import traceback\n                    print(traceback.format_exc())\n                    print("=================================================================================")\n                return (0, possible)\n\n        if self._computed_answer is None:\n            self._computed_answer = computed\n\n        if show_expected or show_computed:\n            print("\\n")\n        if show_expected:\n            show_expected_(correct)\n        if show_computed:\n            show_computed_(computed)\n        try:\n            if not passall:\n                self.test(computed=computed, expected=correct)\n        except Exception as e:\n            if not silent:\n                print("\\n=================================================================================")\n                print(f"Test output from test class \'{self.name}\' does not match expected result. Test error:")\n                print(e)\n                show_computed_(computed)\n                show_expected_(correct)\n            return (0, possible)\n        return (1, possible)\n\n    def score(self):\n        try:\n            self.test()\n        except Exception as e:\n            return 0\n        return 1\n\nclass QPrintItem(QItem):\n    def compute_answer_print(self):\n        """\n        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values\n        are send to process_output (see compute_answer below). In other words, the text generated is:\n\n        res = compute_Answer_print()\n        txt = (any terminal output generated above)\n        numbers = (any numbers found in terminal-output txt)\n\n        self.test(process_output(res, txt, numbers), <expected result>)\n\n        :return: Optional values for comparison\n        """\n        raise Exception("Generate output here. The output is passed to self.process_output")\n\n    def process_output(self, res, txt, numbers):\n        return res\n\n    def compute_answer(self, unmute=False):\n        with Capturing(unmute=unmute) as output:\n            res = self.compute_answer_print()\n        s = "\\n".join(output)\n        s = rm_progress_bar(s) # Remove progress bar.\n        numbers = extract_numbers(s)\n        self._computed_answer = (res, s, numbers)\n        return self.process_output(res, s, numbers)\n\nclass OrderedClassMembers(type):\n    @classmethod\n    def __prepare__(self, name, bases):\n        return collections.OrderedDict()\n    def __new__(self, name, bases, classdict):\n        ks = list(classdict.keys())\n        for b in bases:\n            ks += b.__ordered__\n        classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n        return type.__new__(self, name, bases, classdict)\n\nclass QuestionGroup(metaclass=OrderedClassMembers):\n    title = "Untitled question"\n    partially_scored = False\n    t_init = 0  # Time spend on initialization (placeholder; set this externally).\n    estimated_time = 0.42\n    has_called_init_ = False\n    _name = None\n    _items = None\n\n    @property\n    def items(self):\n        if self._items == None:\n            self._items = []\n            members = [gt for gt in [getattr(self, gt) for gt in self.__ordered__ if gt not in ["__classcell__", "__init__"]] if inspect.isclass(gt) and issubclass(gt, QItem)]\n            for I in members:\n                self._items.append( I(question=self))\n        return self._items\n\n    @items.setter\n    def items(self, value):\n        self._items = value\n\n    @property\n    def name(self):\n        if self._name == None:\n            self._name = self.__class__.__name__\n        return self._name #\n\n    @name.setter\n    def name(self, val):\n        self._name = val\n\n    def init(self):\n        # Can be used to set resources relevant for this question instance.\n        pass\n\n    def init_all_item_questions(self):\n        for item in self.items:\n            if not item.question.has_called_init_:\n                item.question.init()\n                item.question.has_called_init_ = True\n\n\nclass Report():\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 80 # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q,_) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        root_dir = self.pack_imports[0].__path__._path[0]\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q,_) in self.questions:\n            q.nL = self.nL # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n        # else:\n        #     if os.path.isfile(self.computed_answers_file):\n        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)\n        #     else:\n        #         s = f"> Warning: The pre-computed answer file, {os.path.abspath(self.computed_answers_file)} is missing. The framework will NOT work as intended. Reasons may be a broken local installation."\n        #         if strict:\n        #             raise Exception(s)\n        #         else:\n        #             print(s)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        import unittest\n        loader = unittest.TestLoader()\n        for q,_ in self.questions:\n            import time\n            start = time.time() # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time()              - start\n            q.time = total\n\n    def _setup_answers(self):\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\':True}\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n            # for item in q.items:\n            #     if q.name not in payloads or item.name not in payloads[q.name]:\n            #         s = f"> Broken resource dictionary submitted to unitgrade for question {q.name} and subquestion {item.name}. Framework will not work."\n            #         if strict:\n            #             raise Exception(s)\n            #         else:\n            #             print(s)\n            #     else:\n            #         item._correct_answer_payload = payloads[q.name][item.name][\'payload\']\n            #         item.estimated_time = payloads[q.name][item.name].get("time", 1)\n            #         q.estimated_time = payloads[q.name].get("time", 1)\n            #         if "precomputed" in payloads[q.name][item.name]: # Consider removing later.\n            #             item._precomputed_payload = payloads[q.name][item.name][\'precomputed\']\n            #         try:\n            #             if "title" in payloads[q.name][item.name]: # can perhaps be removed later.\n            #                 item.title = payloads[q.name][item.name][\'title\']\n            #         except Exception as e: # Cannot set attribute error. The title is a function (and probably should not be).\n            #             pass\n            #             # print("bad", e)\n        # self.payloads = payloads\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct+1)\n            if i > 0 and l.find("|", i+1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = \'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.1\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n\n        # self.pbar = tqdm.tqdm(total=self.n)\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if hasattr(self, \'pbar\') and self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar=None\n\n        sys.stdout.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')  # , unit_scale=dt, unit=\'seconds\'):\n\n        for _ in range(self.n-1): # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\n\n\nfrom unittest.suite import _isnotsuite\n\nclass MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.\n    pass\n\ndef instance_call_stack(instance):\n    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))\n    return s\n\ndef get_class_that_defined_method(meth):\n    for cls in inspect.getmro(meth.im_class):\n        if meth.__name__ in cls.__dict__:\n            return cls\n    return None\n\ndef caller_name(skip=2):\n    """Get a name of a caller in the format module.class.method\n\n       `skip` specifies how many levels of stack to skip while getting caller\n       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.\n\n       An empty string is returned if skipped levels exceed stack height\n    """\n    stack = inspect.stack()\n    start = 0 + skip\n    if len(stack) < start + 1:\n      return \'\'\n    parentframe = stack[start][0]\n\n    name = []\n    module = inspect.getmodule(parentframe)\n    # `modname` can be None when frame is executed directly in console\n    # TODO(techtonik): consider using __main__\n    if module:\n        name.append(module.__name__)\n    # detect classname\n    if \'self\' in parentframe.f_locals:\n        # I don\'t know any way to detect call from the object method\n        # XXX: there seems to be no way to detect static method call - it will\n        #      be just a function call\n        name.append(parentframe.f_locals[\'self\'].__class__.__name__)\n    codename = parentframe.f_code.co_name\n    if codename != \'<module>\':  # top level usually\n        name.append( codename ) # function or a method\n\n    ## Avoid circular refs and frame leaks\n    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack\n    del parentframe, stack\n\n    return ".".join(name)\n\ndef get_class_from_frame(fr):\n      import inspect\n      args, _, _, value_dict = inspect.getargvalues(fr)\n      # we check the first parameter for the frame function is\n      # named \'self\'\n      if len(args) and args[0] == \'self\':\n            # in that case, \'self\' will be referenced in value_dict\n            instance = value_dict.get(\'self\', None)\n            if instance:\n                  # return its class\n                  # isinstance(instance, Testing) # is the actual class instance.\n\n                  return getattr(instance, \'__class__\', None)\n      # return None otherwise\n      return None\n\nfrom typing import Any\nimport inspect, gc\n\ndef giveupthefunc():\n    frame = inspect.currentframe()\n    code  = frame.f_code\n    globs = frame.f_globals\n    functype = type(lambda: 0)\n    funcs = []\n    for func in gc.get_referrers(code):\n        if type(func) is functype:\n            if getattr(func, "__code__", None) is code:\n                if getattr(func, "__globals__", None) is globs:\n                    funcs.append(func)\n                    if len(funcs) > 1:\n                        return None\n    return funcs[0] if funcs else None\n\n\nfrom collections import defaultdict\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1 # HAcky way to set question number.\n    show_progress_bar = True\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        # if self.dots or self.showAll:\n        #     self.stream.writeln()\n        # if hasattr(self, \'cc\'):\n        #     self.cc.terminate()\n        # self.cc_terminate(success=False)\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n        # if self.showAll:\n        #     self.stream.writeln("FAIL")\n        # elif self.dots:\n        #     self.stream.write(\'F\')\n        #     self.stream.flush()\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        # super().addSuccess(test)\n        self.successes.append(test)\n        # super().addSuccess(test)\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        self.cc_terminate()\n\n\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            sys.stdout.flush()\n            ss = self.item_title_print\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(ss))), end="")\n            # current = 1\n            # possible = 1\n            # current == possible\n            ss = "PASS" if success else "FAILED"\n            if tsecs >= 0.1:\n                ss += " (" + str(tsecs) + " seconds)"\n            print(ss)\n\n\n    def startTest(self, test):\n        # super().startTest(test)\n        j =self.testsRun\n        self.testsRun += 1\n        # print("Starting the test...")\n        # show_progress_bar = True\n        n = UTextResult.number\n\n        item_title = self.getDescription(test)\n        item_title = item_title.split("\\n")[0]\n\n        item_title = test.shortDescription() # Better for printing (get from cache).\n        # test.countTestCases()\n        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)\n        estimated_time = 10\n        nL = 80\n        #\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 2\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            # q_title_print = "some printed title..."\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self): # Used when setting up the test.\n        if self._previousTestClass == None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            print(self.cc.title, end="")\n            # start = 10\n            # q_time = np.round(time.time() - start, 2)\n            nL = 80\n            print(" " * max(0, nL - len(self.cc.title)) + (\n                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")\n            # print("=" * nL)\n\nfrom unittest.runner import _WritelnDecorator\nfrom io import StringIO\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        from io import StringIO\n        stream = StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\ndef wrapper(foo):\n    def magic(self):\n        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))\n        # print(s)\n        foo(self)\n    magic.__doc__ = foo.__doc__\n    return magic\n\nfrom functools import update_wrapper, _make_key, RLock\nfrom collections import namedtuple\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )\n        # key = (self.cache_id(), \'@cache\')\n        # if self._cache_contains[key]\n\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n    return wrapper\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n\n    @classmethod\n    def question_title(cls):\n        return cls.__doc__.splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd == None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        # self._testMethodDoc.strip().splitlines()[0].strip()\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get(  (self.cache_id(), \'title\'), sd )\n        return title if title != None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    # def _callSetUp(self):\n    #     # Always run before method is called.\n    #     print("asdf")\n    #     pass\n    # @classmethod\n    # def setUpClass(cls):\n    #     # self._cache_put((self.cache_id(), \'title\'), value)\n    #     cls.reset()\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome == None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists() # Make sure cache is there.\n        if self._testMethodDoc != None:\n            # Ensure the cache is eventually updated with the right docstring.\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard() )\n        # Fix temp cache here (for using the @cache decorator)\n        self._cache2[ (self.cache_id(), \'assert\') ] = {}\n\n        res = testMethod()\n        elapsed = time.time() - t\n        # self._cache_put( (self.cache_id(), \'title\'), self.shortDescription() )\n\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put( (self.cache_id(), "time"), elapsed)\n\n    # This is my base test class. So what is new about it?\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return (c,m)\n\n    # def unique_cache_id(self):\n    #     k0 = self.cache_id()\n    #     # key = ()\n    #     i = 0\n    #     for i in itertools.count():\n    #         # key = k0 + (i,)\n    #         if i not in self._cache_get( (k0, \'assert\') ):\n    #             break\n    #     return i\n    #     return key\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n        # self.cache_indexes = defaultdict(lambda: 0)\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n    #\n    # def _cache2_contains(self, key):\n    #     print("Is this needed?")\n    #     self._ensure_cache_exists()\n    #     return key in self.__class__._cache2\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n        cache = self._cache_get(key, {})\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, first)\n        assert_fun(first, _expected, *args, **kwargs)\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache != None: # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        # print("Loading cache from", cfile)\n        if os.path.exists(cfile):\n            with open(cfile, \'rb\') as f:\n                data = pickle.load(f)\n                self.__class__._cache = data\n        else:\n            print("Warning! data file not found", cfile)\n\ndef hide(func):\n    return func\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    # (*)We can be somewhat "hygienic", but newDecorator still isn\'t signature-preserving, i.e. you will not be able to get a runtime list of parameters. For that, you need hackish libraries...but in this case, the only argument is func, so it\'s not a big issue\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\n\nimport inspect\nimport os\nimport argparse\nimport sys\nimport time\nimport threading # don\'t import Thread bc. of minify issue.\nimport tqdm # don\'t do from tqdm import tqdm because of minify-issue\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    # try:  # For registering stats.\n    #     import unitgrade_private\n    #     import irlc.lectures\n    #     import xlwings\n    #     from openpyxl import Workbook\n    #     import pandas as pd\n    #     from collections import defaultdict\n    #     dd = defaultdict(lambda: [])\n    #     error_computed = []\n    #     for k1, (q, _) in enumerate(report.questions):\n    #         for k2, item in enumerate(q.items):\n    #             dd[\'question_index\'].append(k1)\n    #             dd[\'item_index\'].append(k2)\n    #             dd[\'question\'].append(q.name)\n    #             dd[\'item\'].append(item.name)\n    #             dd[\'tol\'].append(0 if not hasattr(item, \'tol\') else item.tol)\n    #             error_computed.append(0 if not hasattr(item, \'error_computed\') else item.error_computed)\n    #\n    #     qstats = report.wdir + "/" + report.name + ".xlsx"\n    #\n    #     if os.path.isfile(qstats):\n    #         d_read = pd.read_excel(qstats).to_dict()\n    #     else:\n    #         d_read = dict()\n    #\n    #     for k in range(1000):\n    #         key = \'run_\'+str(k)\n    #         if key in d_read:\n    #             dd[key] = list(d_read[\'run_0\'].values())\n    #         else:\n    #             dd[key] = error_computed\n    #             break\n    #\n    #     workbook = Workbook()\n    #     worksheet = workbook.active\n    #     for col, key in enumerate(dd.keys()):\n    #         worksheet.cell(row=1, column=col+1).value = key\n    #         for row, item in enumerate(dd[key]):\n    #             worksheet.cell(row=row+2, column=col+1).value = item\n    #\n    #     workbook.save(qstats)\n    #     workbook.close()\n    #\n    # except ModuleNotFoundError as e:\n    #     s = 234\n    #     pass\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    print(b + " v" + __version__)\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print("Evaluating " + s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    nL = 80\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        # q = q()\n        # q_hidden = False\n        # q_hidden = issubclass(q.__class__, Hidden)\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        # unittest.Te\n        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n        # res = UTextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)\n        z = 234\n        # for j, item in enumerate(q.items):\n        #     if qitem is not None and question is not None and j+1 != qitem:\n        #         continue\n        #\n        #     if q_with_outstanding_init is not None: # check for None bc. this must be called to set titles.\n        #         # if not item.question.has_called_init_:\n        #         start = time.time()\n        #\n        #         cc = None\n        #         if show_progress_bar:\n        #             total_estimated_time = q.estimated_time # Use this. The time is estimated for the q itself.  # sum( [q2.estimated_time for q2 in q_with_outstanding_init] )\n        #             cc = ActiveProgress(t=total_estimated_time, title=q_title_print)\n        #         from unitgrade import Capturing # DON\'T REMOVE THIS LINE\n        #         with eval(\'Capturing\')(unmute=unmute):  # Clunky import syntax is required bc. of minify issue.\n        #             try:\n        #                 for q2 in q_with_outstanding_init:\n        #                     q2.init()\n        #                     q2.has_called_init_ = True\n        #\n        #                 # item.question.init()  # Initialize the question. Useful for sharing resources.\n        #             except Exception as e:\n        #                 if not passall:\n        #                     if not silent:\n        #                         print(" ")\n        #                         print("="*30)\n        #                         print(f"When initializing question {q.title} the initialization code threw an error")\n        #                         print(e)\n        #                         print("The remaining parts of this question will likely fail.")\n        #                         print("="*30)\n        #\n        #         if show_progress_bar:\n        #             cc.terminate()\n        #             sys.stdout.flush()\n        #             print(q_title_print, end="")\n        #\n        #         q_time =np.round(  time.time()-start, 2)\n        #\n        #         print(" "* max(0,nL - len(q_title_print) ) + (" (" + str(q_time) + " seconds)" if q_time >= 0.1 else "") ) # if q.name in report.payloads else "")\n        #         print("=" * nL)\n        #         q_with_outstanding_init = None\n        #\n        #     # item.question = q # Set the parent question instance for later reference.\n        #     item_title_print = ss = "*** q%i.%i) %s"%(n+1, j+1, item.title)\n        #\n        #     if show_progress_bar:\n        #         cc = ActiveProgress(t=item.estimated_time, title=item_title_print)\n        #     else:\n        #         print(item_title_print + ( \'.\'*max(0, nL-4-len(ss)) ), end="")\n        #     hidden = issubclass(item.__class__, Hidden)\n        #     # if not hidden:\n        #     #     print(ss, end="")\n        #     # sys.stdout.flush()\n        #     start = time.time()\n        #\n        #     (current, possible) = item.get_points(show_expected=show_expected, show_computed=show_computed,unmute=unmute, passall=passall, silent=silent)\n        #     q_[j] = {\'w\': item.weight, \'possible\': possible, \'obtained\': current, \'hidden\': hidden, \'computed\': str(item._computed_answer), \'title\': item.title}\n        #     tsecs = np.round(time.time()-start, 2)\n        #     if show_progress_bar:\n        #         cc.terminate()\n        #         sys.stdout.flush()\n        #         print(item_title_print + (\'.\' * max(0, nL - 4 - len(ss))), end="")\n        #\n        #     if not hidden:\n        #         ss = "PASS" if current == possible else "*** FAILED"\n        #         if tsecs >= 0.1:\n        #             ss += " ("+ str(tsecs) + " seconds)"\n        #         print(ss)\n\n        # ws, possible, obtained = upack(q_)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        # possible = int(ws @ possible)\n        # obtained = int(ws @ obtained)\n        # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"*** Question q{n+1}"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"Question q{n+1}", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    print(f"Completed: "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n    if m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    print(" ")\n    print("="*n)\n    print("Final evaluation")\n    print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f"*** {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single file: ")\n        print(">", token)\n        print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nfrom cs101.homework1 import reverse_list, add\nimport unittest\n\nclass Week1(unittest.TestCase):\n    def test_add(self):\n        self.assertEqual(add(2,2), 4)\n        self.assertEqual(add(-100, 5), -95)\n\n    def test_reverse(self):\n        self.assertEqual(reverse_list([1,2,3]), [3,2,1])\n        # print("Bad output\\n\\n")\n\n\nimport cs101\nclass Report1(Report):\n    title = "CS 101 Report 1"\n    questions = [(Week1, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs101]'
+report1_source = 'import os\n\n# DONT\'t import stuff here since install script requires __version__\n\ndef cache_write(object, file_name, verbose=True):\n    import compress_pickle\n    dn = os.path.dirname(file_name)\n    if not os.path.exists(dn):\n        os.mkdir(dn)\n    if verbose: print("Writing cache...", file_name)\n    with open(file_name, \'wb\', ) as f:\n        compress_pickle.dump(object, f, compression="lzma")\n    if verbose: print("Done!")\n\n\ndef cache_exists(file_name):\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    return os.path.exists(file_name)\n\n\ndef cache_read(file_name):\n    import compress_pickle # Import here because if you import in top the __version__ tag will fail.\n    # file_name = cn_(file_name) if cache_prefix else file_name\n    if os.path.exists(file_name):\n        try:\n            with open(file_name, \'rb\') as f:\n                return compress_pickle.load(f, compression="lzma")\n        except Exception as e:\n            print("Tried to load a bad pickle file at", file_name)\n            print("If the file appears to be automatically generated, you can try to delete it, otherwise download a new version")\n            print(e)\n            # return pickle.load(f)\n    else:\n        return None\n\n\n\n"""\ngit add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade\n"""\nimport numpy as np\nimport sys\nimport re\nimport threading\nimport tqdm\nimport pickle\nimport os\nfrom io import StringIO\nimport io\nfrom unittest.runner import _WritelnDecorator\nfrom typing import Any\nimport inspect\nimport textwrap\nimport colorama\nfrom colorama import Fore\nfrom functools import _make_key, RLock\nfrom collections import namedtuple\nimport unittest\nimport time\n\n_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])\n\ncolorama.init(autoreset=True)  # auto resets your settings after every output\n\ndef gprint(s):\n    print(f"{Fore.GREEN}{s}")\n\nmyround = lambda x: np.round(x)  # required.\nmsum = lambda x: sum(x)\nmfloor = lambda x: np.floor(x)\n\n\ndef setup_dir_by_class(C, base_dir):\n    name = C.__class__.__name__\n    return base_dir, name\n\n\nclass Logger(object):\n    def __init__(self, buffer):\n        assert False\n        self.terminal = sys.stdout\n        self.log = buffer\n\n    def write(self, message):\n        self.terminal.write(message)\n        self.log.write(message)\n\n    def flush(self):\n        # this flush method is needed for python 3 compatibility.\n        pass\n\n\nclass Capturing(list):\n    def __init__(self, *args, stdout=None, unmute=False, **kwargs):\n        self._stdout = stdout\n        self.unmute = unmute\n        super().__init__(*args, **kwargs)\n\n    def __enter__(self, capture_errors=True):  # don\'t put arguments here.\n        self._stdout = sys.stdout if self._stdout == None else self._stdout\n        self._stringio = StringIO()\n        if self.unmute:\n            sys.stdout = Logger(self._stringio)\n        else:\n            sys.stdout = self._stringio\n\n        if capture_errors:\n            self._sterr = sys.stderr\n            sys.sterr = StringIO()  # memory hole it\n        self.capture_errors = capture_errors\n        return self\n\n    def __exit__(self, *args):\n        self.extend(self._stringio.getvalue().splitlines())\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n\nclass Capturing2(Capturing):\n    def __exit__(self, *args):\n        lines = self._stringio.getvalue().splitlines()\n        txt = "\\n".join(lines)\n        numbers = extract_numbers(txt)\n        self.extend(lines)\n        del self._stringio  # free up some memory\n        sys.stdout = self._stdout\n        if self.capture_errors:\n            sys.sterr = self._sterr\n\n        self.output = txt\n        self.numbers = numbers\n\n\n# @classmethod\n# class OrderedClassMembers(type):\n#     def __prepare__(self, name, bases):\n#         assert False\n#         return collections.OrderedDict()\n#\n#     def __new__(self, name, bases, classdict):\n#         ks = list(classdict.keys())\n#         for b in bases:\n#             ks += b.__ordered__\n#         classdict[\'__ordered__\'] = [key for key in ks if key not in (\'__module__\', \'__qualname__\')]\n#         return type.__new__(self, name, bases, classdict)\n\n\nclass Report:\n    title = "report title"\n    version = None\n    questions = []\n    pack_imports = []\n    individual_imports = []\n    nL = 120  # Maximum line width\n\n    @classmethod\n    def reset(cls):\n        for (q, _) in cls.questions:\n            if hasattr(q, \'reset\'):\n                q.reset()\n\n    @classmethod\n    def mfile(clc):\n        return inspect.getfile(clc)\n\n    def _file(self):\n        return inspect.getfile(type(self))\n\n    def _import_base_relative(self):\n        if hasattr(self.pack_imports[0], \'__path__\'):\n            root_dir = self.pack_imports[0].__path__._path[0]\n        else:\n            root_dir = self.pack_imports[0].__file__\n\n        root_dir = os.path.dirname(root_dir)\n        relative_path = os.path.relpath(self._file(), root_dir)\n        modules = os.path.normpath(relative_path[:-3]).split(os.sep)\n        return root_dir, relative_path, modules\n\n    def __init__(self, strict=False, payload=None):\n        working_directory = os.path.abspath(os.path.dirname(self._file()))\n        self.wdir, self.name = setup_dir_by_class(self, working_directory)\n        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")\n        for (q, _) in self.questions:\n            q.nL = self.nL  # Set maximum line length.\n\n        if payload is not None:\n            self.set_payload(payload, strict=strict)\n\n    def main(self, verbosity=1):\n        # Run all tests using standard unittest (nothing fancy).\n        loader = unittest.TestLoader()\n        for q, _ in self.questions:\n            start = time.time()  # A good proxy for setup time is to\n            suite = loader.loadTestsFromTestCase(q)\n            unittest.TextTestRunner(verbosity=verbosity).run(suite)\n            total = time.time() - start\n            q.time = total\n\n    def _setup_answers(self, with_coverage=False):\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = True\n                q._report = self\n\n        self.main()  # Run all tests in class just to get that out of the way...\n        report_cache = {}\n        for q, _ in self.questions:\n            if hasattr(q, \'_save_cache\'):\n                q()._save_cache()\n                q._cache[\'time\'] = q.time\n                report_cache[q.__qualname__] = q._cache\n            else:\n                report_cache[q.__qualname__] = {\'no cache see _setup_answers in unitgrade2.py\': True}\n        if with_coverage:\n            for q, _ in self.questions:\n                q._with_coverage = False\n        return report_cache\n\n    def set_payload(self, payloads, strict=False):\n        for q, _ in self.questions:\n            q._cache = payloads[q.__qualname__]\n\n\ndef rm_progress_bar(txt):\n    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.\n    nlines = []\n    for l in txt.splitlines():\n        pct = l.find("%")\n        ql = False\n        if pct > 0:\n            i = l.find("|", pct + 1)\n            if i > 0 and l.find("|", i + 1) > 0:\n                ql = True\n        if not ql:\n            nlines.append(l)\n    return "\\n".join(nlines)\n\n\ndef extract_numbers(txt):\n    # txt = rm_progress_bar(txt)\n    numeric_const_pattern = r\'[-+]? (?: (?: \\d* \\. \\d+ ) | (?: \\d+ \\.? ) )(?: [Ee] [+-]? \\d+ ) ?\'\n    rx = re.compile(numeric_const_pattern, re.VERBOSE)\n    all = rx.findall(txt)\n    all = [float(a) if (\'.\' in a or "e" in a) else int(a) for a in all]\n    if len(all) > 500:\n        print(txt)\n        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))\n    return all\n\n\nclass ActiveProgress():\n    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):\n        if file == None:\n            file = sys.stdout\n        self.file = file\n        self.t = t\n        self._running = False\n        self.title = title\n        self.dt = 0.01\n        self.n = int(np.round(self.t / self.dt))\n        self.show_progress_bar = show_progress_bar\n        self.pbar = None\n\n        if start:\n            self.start()\n\n    def start(self):\n        self._running = True\n        if self.show_progress_bar:\n            self.thread = threading.Thread(target=self.run)\n            self.thread.start()\n        self.time_started = time.time()\n\n    def terminate(self):\n        if not self._running:\n            raise Exception("Stopping a stopped progress bar. ")\n        self._running = False\n        if self.show_progress_bar:\n            self.thread.join()\n        if self.pbar is not None:\n            self.pbar.update(1)\n            self.pbar.close()\n            self.pbar = None\n\n        self.file.flush()\n        return time.time() - self.time_started\n\n    def run(self):\n        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,\n                              bar_format=\'{l_bar}{bar}| [{elapsed}<{remaining}]\')\n\n        for _ in range(self.n - 1):  # Don\'t terminate completely; leave bar at 99% done until terminate.\n            if not self._running:\n                self.pbar.close()\n                self.pbar = None\n                break\n\n            time.sleep(self.dt)\n            self.pbar.update(1)\n\ndef dprint(first, last, nL, extra = "", file=None, dotsym=\'.\', color=\'white\'):\n    if file == None:\n        file = sys.stdout\n\n    # ss = self.item_title_print\n    # state = "PASS" if success else "FAILED"\n    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))\n    # if self.show_progress_bar or True:\n    print(first + dot_parts, end="", file=file)\n    # else:\n    # print(dot_parts, end="", file=self.cc.file)\n    last += extra\n    # if tsecs >= 0.5:\n    #     state += " (" + str(tsecs) + " seconds)"\n    print(last, file=file)\n\n\nclass UTextResult(unittest.TextTestResult):\n    nL = 80\n    number = -1  # HAcky way to set question number.\n    show_progress_bar = True\n    cc = None\n\n    def __init__(self, stream, descriptions, verbosity):\n        super().__init__(stream, descriptions, verbosity)\n        self.successes = []\n\n    def printErrors(self) -> None:\n        self.printErrorList(\'ERROR\', self.errors)\n        self.printErrorList(\'FAIL\', self.failures)\n\n    def addError(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addFailure(self, test, err):\n        super(unittest.TextTestResult, self).addFailure(test, err)\n        self.cc_terminate(success=False)\n\n    def addSuccess(self, test: unittest.case.TestCase) -> None:\n        self.successes.append(test)\n        self.cc_terminate()\n\n    def cc_terminate(self, success=True):\n        if self.show_progress_bar or True:\n            tsecs = np.round(self.cc.terminate(), 2)\n            self.cc.file.flush()\n            ss = self.item_title_print\n\n            state = "PASS" if success else "FAILED"\n\n            dot_parts = (\'.\' * max(0, self.nL - len(state) - len(ss)))\n            if self.show_progress_bar or True:\n                print(self.item_title_print + dot_parts, end="", file=self.cc.file)\n            else:\n                print(dot_parts, end="", file=self.cc.file)\n\n            if tsecs >= 0.5:\n                state += " (" + str(tsecs) + " seconds)"\n            print(state, file=self.cc.file)\n\n    def startTest(self, test):\n        # j =self.testsRun\n        self.testsRun += 1\n        # item_title = self.getDescription(test)\n        item_title = test.shortDescription()  # Better for printing (get from cache).\n        if item_title == None:\n            # For unittest framework where getDescription may return None.\n            item_title = self.getDescription(test)\n        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)\n        estimated_time = 10\n        if self.show_progress_bar or True:\n            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)\n        else:\n            print(self.item_title_print + (\'.\' * max(0, self.nL - 4 - len(self.item_title_print))), end="")\n\n        self._test = test\n        self._stdout = sys.stdout\n        sys.stdout = io.StringIO()\n\n    def stopTest(self, test):\n        sys.stdout = self._stdout\n        super().stopTest(test)\n\n    def _setupStdout(self):\n        if self._previousTestClass == None:\n            total_estimated_time = 1\n            if hasattr(self.__class__, \'q_title_print\'):\n                q_title_print = self.__class__.q_title_print\n            else:\n                q_title_print = "<unnamed test. See unitgrade.py>"\n\n            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)\n            self.cc = cc\n\n    def _restoreStdout(self):  # Used when setting up the test.\n        if self._previousTestClass is None:\n            q_time = self.cc.terminate()\n            q_time = np.round(q_time, 2)\n            sys.stdout.flush()\n            if self.show_progress_bar:\n                print(self.cc.title, end="")\n            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))\n\n\nclass UTextTestRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        stream = io.StringIO()\n        super().__init__(*args, stream=stream, **kwargs)\n\n    def _makeResult(self):\n        # stream = self.stream # not you!\n        stream = sys.stdout\n        stream = _WritelnDecorator(stream)\n        return self.resultclass(stream, self.descriptions, self.verbosity)\n\n\ndef cache(foo, typed=False):\n    """ Magic cache wrapper\n    https://github.com/python/cpython/blob/main/Lib/functools.py\n    """\n    maxsize = None\n    def wrapper(self, *args, **kwargs):\n        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))\n        if not self._cache_contains(key):\n            value = foo(self, *args, **kwargs)\n            self._cache_put(key, value)\n        else:\n            value = self._cache_get(key)\n        return value\n\n    return wrapper\n\n\ndef get_hints(ss):\n    if ss == None:\n        return None\n    try:\n        ss = textwrap.dedent(ss)\n        ss = ss.replace(\'\'\'"""\'\'\', "").strip()\n        hints = ["hints:", ]\n        j = np.argmax([ss.lower().find(h) for h in hints])\n        h = hints[j]\n        ss = ss[ss.find(h) + len(h) + 1:]\n        ss = "\\n".join([l for l in ss.split("\\n") if not l.strip().startswith(":")])\n        ss = textwrap.dedent(ss)\n        ss = ss.strip()\n        return ss\n    except Exception as e:\n        print("bad hints", ss, e)\n\n\nclass UTestCase(unittest.TestCase):\n    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.\n    _cache = None  # Read-only cache. Ensures method always produce same result.\n    _cache2 = None  # User-written cache.\n    _with_coverage = False\n    _report = None  # The report used. This is very, very hacky and should always be None. Don\'t rely on it!\n\n    def capture(self):\n        if hasattr(self, \'_stdout\') and self._stdout is not None:\n            file = self._stdout\n        else:\n            file = sys.stdout\n        return Capturing2(stdout=file)\n\n    @classmethod\n    def question_title(cls):\n        """ Return the question title """\n        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__\n\n    @classmethod\n    def reset(cls):\n        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")\n        cls._outcome = None\n        cls._cache = None\n        cls._cache2 = None\n\n    def _callSetUp(self):\n        if self._with_coverage:\n            if not hasattr(self._report, \'covcache\'):\n                self._report.covcache = {}\n            import coverage\n            self.cov = coverage.Coverage()\n            self.cov.start()\n        self.setUp()\n\n    def _callTearDown(self):\n        self.tearDown()\n        if self._with_coverage:\n            from pathlib import Path\n            from snipper import snipper\n            self.cov.stop()\n            data = self.cov.get_data()\n            base, _, _ = self._report._import_base_relative()\n            for file in data.measured_files():\n                file = os.path.normpath(file)\n                root = Path(base)\n                child = Path(file)\n                if root in child.parents:\n                    with open(child, \'r\') as f:\n                        s = f.read()\n                    lines = s.splitlines()\n                    garb = \'GARBAGE\'\n\n                    lines2 = snipper.censor_code(lines, keep=True)\n                    assert len(lines) == len(lines2)\n\n                    for l in data.contexts_by_lineno(file):\n                        if lines2[l].strip() == garb:\n                            if self.cache_id() not in self._report.covcache:\n                                self._report.covcache[self.cache_id()] = {}\n\n                            rel = os.path.relpath(child, root)\n                            cc = self._report.covcache[self.cache_id()]\n                            j = 0\n                            for j in range(l, -1, -1):\n                                if "def" in lines2[j] or "class" in lines2[j]:\n                                    break\n                            from snipper.snipper import gcoms\n                            fun = lines2[j]\n                            comments, _ = gcoms("\\n".join(lines2[j:l]))\n                            if rel not in cc:\n                                cc[rel] = {}\n                            cc[rel][fun] = (l, "\\n".join(comments))\n                            self._cache_put((self.cache_id(), \'coverage\'), self._report.covcache)\n\n    def shortDescriptionStandard(self):\n        sd = super().shortDescription()\n        if sd is None:\n            sd = self._testMethodName\n        return sd\n\n    def shortDescription(self):\n        sd = self.shortDescriptionStandard()\n        title = self._cache_get((self.cache_id(), \'title\'), sd)\n        return title if title is not None else sd\n\n    @property\n    def title(self):\n        return self.shortDescription()\n\n    @title.setter\n    def title(self, value):\n        self._cache_put((self.cache_id(), \'title\'), value)\n\n    def _get_outcome(self):\n        if not (self.__class__, \'_outcome\') or self.__class__._outcome is None:\n            self.__class__._outcome = {}\n        return self.__class__._outcome\n\n    def _callTestMethod(self, testMethod):\n        t = time.time()\n        self._ensure_cache_exists()  # Make sure cache is there.\n        if self._testMethodDoc is not None:\n            self._cache_put((self.cache_id(), \'title\'), self.shortDescriptionStandard())\n\n        self._cache2[(self.cache_id(), \'assert\')] = {}\n        res = testMethod()\n        elapsed = time.time() - t\n        self._get_outcome()[self.cache_id()] = res\n        self._cache_put((self.cache_id(), "time"), elapsed)\n\n    def cache_id(self):\n        c = self.__class__.__qualname__\n        m = self._testMethodName\n        return c, m\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self._load_cache()\n        self._assert_cache_index = 0\n\n    def _ensure_cache_exists(self):\n        if not hasattr(self.__class__, \'_cache\') or self.__class__._cache == None:\n            self.__class__._cache = dict()\n        if not hasattr(self.__class__, \'_cache2\') or self.__class__._cache2 == None:\n            self.__class__._cache2 = dict()\n\n    def _cache_get(self, key, default=None):\n        self._ensure_cache_exists()\n        return self.__class__._cache.get(key, default)\n\n    def _cache_put(self, key, value):\n        self._ensure_cache_exists()\n        self.__class__._cache2[key] = value\n\n    def _cache_contains(self, key):\n        self._ensure_cache_exists()\n        return key in self.__class__._cache\n\n    def wrap_assert(self, assert_fun, first, *args, **kwargs):\n        # sys.stdout = self._stdout\n        key = (self.cache_id(), \'assert\')\n        if not self._cache_contains(key):\n            print("Warning, framework missing", key)\n            self.__class__._cache[\n                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.\n        cache = self._cache_get(key)\n        id = self._assert_cache_index\n        if not id in cache:\n            print("Warning, framework missing cache index", key, "id =", id)\n        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")\n\n        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.\n        cache[id] = first\n        self._cache_put(key, cache)\n        self._assert_cache_index += 1\n        assert_fun(first, _expected, *args, **kwargs)\n\n    def assertEqualC(self, first: Any, msg: Any = ...) -> None:\n        self.wrap_assert(self.assertEqual, first, msg)\n\n    def _cache_file(self):\n        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"\n\n    def _save_cache(self):\n        # get the class name (i.e. what to save to).\n        cfile = self._cache_file()\n        if not os.path.isdir(os.path.dirname(cfile)):\n            os.makedirs(os.path.dirname(cfile))\n\n        if hasattr(self.__class__, \'_cache2\'):\n            with open(cfile, \'wb\') as f:\n                pickle.dump(self.__class__._cache2, f)\n\n    # But you can also set cache explicitly.\n    def _load_cache(self):\n        if self._cache is not None:  # Cache already loaded. We will not load it twice.\n            return\n            # raise Exception("Loaded cache which was already set. What is going on?!")\n        cfile = self._cache_file()\n        if os.path.exists(cfile):\n            try:\n                with open(cfile, \'rb\') as f:\n                    data = pickle.load(f)\n                self.__class__._cache = data\n            except Exception as e:\n                print("Bad cache", cfile)\n                print(e)\n        else:\n            print("Warning! data file not found", cfile)\n\n    def _feedErrorsToResult(self, result, errors):\n        """ Use this to show hints on test failure. """\n        if not isinstance(result, UTextResult):\n            er = [e for e, v in errors if v != None]\n\n            if len(er) > 0:\n                hints = []\n                key = (self.cache_id(), \'coverage\')\n                if self._cache_contains(key):\n                    CC = self._cache_get(key)\n                    for id in CC:\n                        if id == self.cache_id():\n                            cl, m = id\n                            gprint(f"> An error occured while solving: {cl}.{m}. The files/methods you need to edit are:")  # For the test {id} in {file} you should edit:")\n                            for file in CC[id]:\n                                rec = CC[id][file]\n                                gprint(f">   * {file}")\n                                for l in rec:\n                                    _, comments = CC[id][file][l]\n                                    hint = get_hints(comments)\n\n                                    if hint != None:\n                                        hints.append(hint)\n                                    gprint(f">      - {l}")\n\n                er = er[0]\n                doc = er._testMethodDoc\n                if doc is not None:\n                    hint = get_hints(er._testMethodDoc)\n                    if hint is not None:\n                        hints = [hint] + hints\n                if len(hints) > 0:\n                    gprint("> Hints:")\n                    gprint(textwrap.indent("\\n".join(hints), ">   "))\n\n        super()._feedErrorsToResult(result, errors)\n\n    def startTestRun(self):\n        # print("asdfsdaf 11", file=sys.stderr)\n        super().startTestRun()\n        # print("asdfsdaf")\n\n    def _callTestMethod(self, method):\n        # print("asdfsdaf")\n        super()._callTestMethod(method)\n\n\ndef hide(func):\n    return func\n\n\ndef makeRegisteringDecorator(foreignDecorator):\n    """\n        Returns a copy of foreignDecorator, which is identical in every\n        way(*), except also appends a .decorator property to the callable it\n        spits out.\n    """\n\n    def newDecorator(func):\n        # Call to newDecorator(method)\n        # Exactly like old decorator, but output keeps track of what decorated it\n        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done\n        R.decorator = newDecorator  # keep track of decorator\n        # R.original = func         # might as well keep track of everything!\n        return R\n\n    newDecorator.__name__ = foreignDecorator.__name__\n    newDecorator.__doc__ = foreignDecorator.__doc__\n    return newDecorator\n\nhide = makeRegisteringDecorator(hide)\n\ndef methodsWithDecorator(cls, decorator):\n    """\n        Returns all methods in CLS with DECORATOR as the\n        outermost decorator.\n\n        DECORATOR must be a "registering decorator"; one\n        can make any decorator "registering" via the\n        makeRegisteringDecorator function.\n\n        import inspect\n        ls = list(methodsWithDecorator(GeneratorQuestion, deco))\n        for f in ls:\n            print(inspect.getsourcelines(f) ) # How to get all hidden questions.\n    """\n    for maybeDecorated in cls.__dict__.values():\n        if hasattr(maybeDecorated, \'decorator\'):\n            if maybeDecorated.decorator == decorator:\n                print(maybeDecorated)\n                yield maybeDecorated\n# 817\n\n\nimport numpy as np\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport pyfiglet\nimport unittest\nimport inspect\nimport os\nimport argparse\nimport time\n\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Example: \nTo run all tests in a report: \n\n> python assignment1_dp.py\n\nTo run only question 2 or question 2.1\n\n> python assignment1_dp.py -q 2\n> python assignment1_dp.py -q 2.1\n\nNote this scripts does not grade your report. To grade your report, use:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'-q\', nargs=\'?\', type=str, default=None, help=\'Only evaluate this question (e.g.: -q 2)\')\nparser.add_argument(\'--showexpected\',  action="store_true",  help=\'Show the expected/desired result\')\nparser.add_argument(\'--showcomputed\',  action="store_true",  help=\'Show the answer your code computes\')\nparser.add_argument(\'--unmute\',  action="store_true",  help=\'Show result of print(...) commands in code\')\nparser.add_argument(\'--passall\',  action="store_true",  help=\'Automatically pass all tests. Useful when debugging.\')\n\ndef evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):\n    args = parser.parse_args()\n    if question is None and args.q is not None:\n        question = args.q\n        if "." in question:\n            question, qitem = [int(v) for v in question.split(".")]\n        else:\n            question = int(question)\n\n    if hasattr(report, "computed_answer_file") and not os.path.isfile(report.computed_answers_file) and not ignore_missing_file:\n        raise Exception("> Error: The pre-computed answer file", os.path.abspath(report.computed_answers_file), "does not exist. Check your package installation")\n\n    if unmute is None:\n        unmute = args.unmute\n    if passall is None:\n        passall = args.passall\n\n    results, table_data = evaluate_report(report, question=question, show_progress_bar=not unmute, qitem=qitem, verbose=False, passall=passall, show_expected=args.showexpected, show_computed=args.showcomputed,unmute=unmute,\n                                          show_tol_err=show_tol_err)\n\n\n    if question is None:\n        print("Provisional evaluation")\n        tabulate(table_data)\n        table = table_data\n        print(tabulate(table))\n        print(" ")\n\n    fr = inspect.getouterframes(inspect.currentframe())[1].filename\n    gfile = os.path.basename(fr)[:-3] + "_grade.py"\n    if os.path.exists(gfile):\n        print("Note your results have not yet been registered. \\nTo register your results, please run the file:")\n        print(">>>", gfile)\n        print("In the same manner as you ran this file.")\n\n\n    return results\n\n\ndef upack(q):\n    # h = zip([(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()])\n    h =[(i[\'w\'], i[\'possible\'], i[\'obtained\']) for i in q.values()]\n    h = np.asarray(h)\n    return h[:,0], h[:,1], h[:,2],\n\nclass UnitgradeTextRunner(unittest.TextTestRunner):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\nclass SequentialTestLoader(unittest.TestLoader):\n    def getTestCaseNames(self, testCaseClass):\n        test_names = super().getTestCaseNames(testCaseClass)\n        # testcase_methods = list(testCaseClass.__dict__.keys())\n        ls = []\n        for C in testCaseClass.mro():\n            if issubclass(C, unittest.TestCase):\n                ls = list(C.__dict__.keys()) + ls\n        testcase_methods = ls\n        test_names.sort(key=testcase_methods.index)\n        return test_names\n\ndef evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,\n                    show_progress_bar=True,\n                    show_tol_err=False,\n                    big_header=True):\n\n    now = datetime.now()\n    if big_header:\n        ascii_banner = pyfiglet.figlet_format("UnitGrade", font="doom")\n        b = "\\n".join( [l for l in ascii_banner.splitlines() if len(l.strip()) > 0] )\n    else:\n        b = "Unitgrade"\n    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")\n    print(b + " v" + __version__ + ", started: " + dt_string+ "\\n")\n    # print("Started: " + dt_string)\n    s = report.title\n    if hasattr(report, "version") and report.version is not None:\n        s += " version " + report.version\n    print(s, "(use --help for options)" if show_help_flag else "")\n    # print(f"Loaded answers from: ", report.computed_answers_file, "\\n")\n    table_data = []\n    t_start = time.time()\n    score = {}\n    loader = SequentialTestLoader()\n\n    for n, (q, w) in enumerate(report.questions):\n        if question is not None and n+1 != question:\n            continue\n        suite = loader.loadTestsFromTestCase(q)\n        qtitle = q.question_title() if hasattr(q, \'question_title\') else q.__qualname__\n        q_title_print = "Question %i: %s"%(n+1, qtitle)\n        print(q_title_print, end="")\n        q.possible = 0\n        q.obtained = 0\n        q_ = {} # Gather score in this class.\n        UTextResult.q_title_print = q_title_print # Hacky\n        UTextResult.show_progress_bar = show_progress_bar # Hacky.\n        UTextResult.number = n\n        UTextResult.nL = report.nL\n\n        res = UTextTestRunner(verbosity=2, resultclass=UTextResult).run(suite)\n\n        possible = res.testsRun\n        obtained = len(res.successes)\n\n        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun\n\n        obtained = int(w * obtained * 1.0 / possible ) if possible > 0 else 0\n        score[n] = {\'w\': w, \'possible\': w, \'obtained\': obtained, \'items\': q_, \'title\': qtitle}\n        q.obtained = obtained\n        q.possible = possible\n\n        s1 = f"Question {n+1} total"\n        s2 = f" {q.obtained}/{w}"\n        print(s1 + ("."* (report.nL-len(s1)-len(s2) )) + s2 )\n        print(" ")\n        table_data.append([f"q{n+1}) Total", f"{q.obtained}/{w}"])\n\n    ws, possible, obtained = upack(score)\n    possible = int( msum(possible) )\n    obtained = int( msum(obtained) ) # Cast to python int\n    report.possible = possible\n    report.obtained = obtained\n    now = datetime.now()\n    dt_string = now.strftime("%H:%M:%S")\n\n    dt = int(time.time()-t_start)\n    minutes = dt//60\n    seconds = dt - minutes*60\n    plrl = lambda i, s: str(i) + " " + s + ("s" if i != 1 else "")\n\n    dprint(first = "Total points at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +")",\n           last=""+str(report.obtained)+"/"+str(report.possible), nL = report.nL)\n\n    # print(f"Completed at "+ dt_string + " (" + plrl(minutes, "minute") + ", "+ plrl(seconds, "second") +"). Total")\n\n    table_data.append(["Total", ""+str(report.obtained)+"/"+str(report.possible) ])\n    results = {\'total\': (obtained, possible), \'details\': score}\n    return results, table_data\n\n\nfrom tabulate import tabulate\nfrom datetime import datetime\nimport inspect\nimport json\nimport os\nimport bz2\nimport pickle\nimport os\n\ndef bzwrite(json_str, token): # to get around obfuscation issues\n    with getattr(bz2, \'open\')(token, "wt") as f:\n        f.write(json_str)\n\ndef gather_imports(imp):\n    resources = {}\n    m = imp\n    # for m in pack_imports:\n    # print(f"*** {m.__name__}")\n    f = m.__file__\n    # dn = os.path.dirname(f)\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = str(__import__(m.__name__.split(\'.\')[0]).__path__)\n\n    if hasattr(m, \'__file__\') and not hasattr(m, \'__path__\'):  # Importing a simple file: m.__class__.__name__ == \'module\' and False:\n        top_package = os.path.dirname(m.__file__)\n        module_import = True\n    else:\n        top_package = __import__(m.__name__.split(\'.\')[0]).__path__._path[0]\n        module_import = False\n\n    # top_package = os.path.dirname(__import__(m.__name__.split(\'.\')[0]).__file__)\n    # top_package = os.path.dirname(top_package)\n    import zipfile\n    # import strea\n    # zipfile.ZipFile\n    import io\n    # file_like_object = io.BytesIO(my_zip_data)\n    zip_buffer = io.BytesIO()\n    with zipfile.ZipFile(zip_buffer, \'w\') as zip:\n        # zip.write()\n        for root, dirs, files in os.walk(top_package):\n            for file in files:\n                if file.endswith(".py"):\n                    fpath = os.path.join(root, file)\n                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)\n                    zip.write(fpath, v)\n\n    resources[\'zipfile\'] = zip_buffer.getvalue()\n    resources[\'top_package\'] = top_package\n    resources[\'module_import\'] = module_import\n    return resources, top_package\n\n    if f.endswith("__init__.py"):\n        for root, dirs, files in os.walk(os.path.dirname(f)):\n            for file in files:\n                if file.endswith(".py"):\n                    # print(file)\n                    # print()\n                    v = os.path.relpath(os.path.join(root, file), top_package)\n                    with open(os.path.join(root, file), \'r\') as ff:\n                        resources[v] = ff.read()\n    else:\n        v = os.path.relpath(f, top_package)\n        with open(f, \'r\') as ff:\n            resources[v] = ff.read()\n    return resources\n\nimport argparse\nparser = argparse.ArgumentParser(description=\'Evaluate your report.\', epilog="""Use this script to get the score of your report. Example:\n\n> python report1_grade.py\n\nFinally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.\nFor instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to \'Documents/` and run:\n\n> python -m course_package.report1\n\nsee https://docs.python.org/3.9/using/cmdline.html\n""", formatter_class=argparse.RawTextHelpFormatter)\nparser.add_argument(\'--noprogress\',  action="store_true",  help=\'Disable progress bars\')\nparser.add_argument(\'--autolab\',  action="store_true",  help=\'Show Autolab results\')\n\ndef gather_upload_to_campusnet(report, output_dir=None):\n    n = report.nL\n    args = parser.parse_args()\n    results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,\n                                          show_progress_bar=not args.noprogress,\n                                          big_header=not args.autolab)\n    # print(" ")\n    # print("="*n)\n    # print("Final evaluation")\n    # print(tabulate(table_data))\n    # also load the source code of missing files...\n\n    sources = {}\n    print("")\n    if not args.autolab:\n        if len(report.individual_imports) > 0:\n            print("By uploading the .token file, you verify the files:")\n            for m in report.individual_imports:\n                print(">", m.__file__)\n            print("Are created/modified individually by you in agreement with DTUs exam rules")\n            report.pack_imports += report.individual_imports\n\n        if len(report.pack_imports) > 0:\n            print("Including files in upload...")\n            for k, m in enumerate(report.pack_imports):\n                nimp, top_package = gather_imports(m)\n                _, report_relative_location, module_import = report._import_base_relative()\n\n                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)\n                nimp[\'report_relative_location\'] = report_relative_location\n                nimp[\'report_module_specification\'] = module_import\n                nimp[\'name\'] = m.__name__\n                sources[k] = nimp\n                # if len([k for k in nimp if k not in sources]) > 0:\n                print(f" * {m.__name__}")\n                # sources = {**sources, **nimp}\n    results[\'sources\'] = sources\n\n    if output_dir is None:\n        output_dir = os.getcwd()\n\n    payload_out_base = report.__class__.__name__ + "_handin"\n\n    obtain, possible = results[\'total\']\n    vstring = "_v"+report.version if report.version is not None else ""\n\n    token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)\n    token = os.path.join(output_dir, token)\n    with open(token, \'wb\') as f:\n        pickle.dump(results, f)\n\n    if not args.autolab:\n        print(" ")\n        print("To get credit for your results, please upload the single unmodified file: ")\n        print(">", token)\n        # print("To campusnet without any modifications.")\n\n        # print("Now time for some autolab fun")\n\ndef source_instantiate(name, report1_source, payload):\n    eval("exec")(report1_source, globals())\n    pl = pickle.loads(bytes.fromhex(payload))\n    report = eval(name)(payload=pl, strict=True)\n    # report.set_payload(pl)\n    return report\n\n\n__version__ = "0.9.0"\n\nfrom cs101.homework1 import reverse_list, add\nimport unittest\n\nclass Week1(unittest.TestCase):\n    def test_add(self):\n        self.assertEqual(add(2,2), 4)\n        self.assertEqual(add(-100, 5), -95)\n\n    def test_reverse(self):\n        self.assertEqual(reverse_list([1,2,3]), [3,2,1])\n\n\nimport cs101\nclass Report1(Report):\n    title = "CS 101 Report 1"\n    questions = [(Week1, 10)]  # Include a single question for 10 credits.\n    pack_imports = [cs101]'
 report1_payload = '8004953f000000000000007d948c055765656b31947d948c2c6e6f20636163686520736565205f73657475705f616e737765727320696e20756e69746772616465322e7079948873732e'
 name="Report1"
 
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..b5a3c46
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,6 @@
+[build-system]
+requires = [
+    "setuptools>=42",
+    "wheel"
+]
+build-backend = "setuptools.build_meta"
\ No newline at end of file
diff --git a/pytransform/__init__.py b/pytransform/__init__.py
deleted file mode 100644
index f656a22..0000000
--- a/pytransform/__init__.py
+++ /dev/null
@@ -1,454 +0,0 @@
-# These module alos are used by protection code, so that protection
-# code needn't import anything
-import os
-import platform
-import sys
-import struct
-
-# Because ctypes is new from Python 2.5, so pytransform doesn't work
-# before Python 2.5
-#
-from ctypes import cdll, c_char, c_char_p, c_int, c_void_p, \
-    pythonapi, py_object, PYFUNCTYPE, CFUNCTYPE
-from fnmatch import fnmatch
-
-#
-# Support Platforms
-#
-plat_path = 'platforms'
-
-plat_table = (
-    ('windows', ('windows', 'cygwin-*')),
-    ('darwin', ('darwin', 'ios')),
-    ('linux', ('linux*',)),
-    ('freebsd', ('freebsd*', 'openbsd*')),
-    ('poky', ('poky',)),
-)
-
-arch_table = (
-    ('x86', ('i?86', )),
-    ('x86_64', ('x64', 'x86_64', 'amd64', 'intel')),
-    ('arm', ('armv5',)),
-    ('armv6', ('armv6l',)),
-    ('armv7', ('armv7l',)),
-    ('ppc64', ('ppc64le',)),
-    ('mips32', ('mips',)),
-    ('aarch32', ('aarch32',)),
-    ('aarch64', ('aarch64', 'arm64'))
-)
-
-#
-# Hardware type
-#
-HT_HARDDISK, HT_IFMAC, HT_IPV4, HT_IPV6, HT_DOMAIN = range(5)
-
-#
-# Global
-#
-_pytransform = None
-
-
-class PytransformError(Exception):
-    pass
-
-
-def dllmethod(func):
-    def wrap(*args, **kwargs):
-        return func(*args, **kwargs)
-    return wrap
-
-
-@dllmethod
-def version_info():
-    prototype = PYFUNCTYPE(py_object)
-    dlfunc = prototype(('version_info', _pytransform))
-    return dlfunc()
-
-
-@dllmethod
-def init_pytransform():
-    major, minor = sys.version_info[0:2]
-    # Python2.5 no sys.maxsize but sys.maxint
-    # bitness = 64 if sys.maxsize > 2**32 else 32
-    prototype = PYFUNCTYPE(c_int, c_int, c_int, c_void_p)
-    init_module = prototype(('init_module', _pytransform))
-    ret = init_module(major, minor, pythonapi._handle)
-    if (ret & 0xF000) == 0x1000:
-        raise PytransformError('Initialize python wrapper failed (%d)'
-                               % (ret & 0xFFF))
-    return ret
-
-
-@dllmethod
-def init_runtime():
-    prototype = PYFUNCTYPE(c_int, c_int, c_int, c_int, c_int)
-    _init_runtime = prototype(('init_runtime', _pytransform))
-    return _init_runtime(0, 0, 0, 0)
-
-
-@dllmethod
-def encrypt_code_object(pubkey, co, flags, suffix=''):
-    _pytransform.set_option(6, suffix.encode())
-    prototype = PYFUNCTYPE(py_object, py_object, py_object, c_int)
-    dlfunc = prototype(('encrypt_code_object', _pytransform))
-    return dlfunc(pubkey, co, flags)
-
-
-@dllmethod
-def generate_license_file(filename, priname, rcode, start=-1, count=1):
-    prototype = PYFUNCTYPE(c_int, c_char_p, c_char_p, c_char_p, c_int, c_int)
-    dlfunc = prototype(('generate_project_license_files', _pytransform))
-    return dlfunc(filename.encode(), priname.encode(), rcode.encode(),
-                  start, count) if sys.version_info[0] == 3 \
-        else dlfunc(filename, priname, rcode, start, count)
-
-
-@dllmethod
-def generate_license_key(prikey, keysize, rcode):
-    prototype = PYFUNCTYPE(py_object, c_char_p, c_int, c_char_p)
-    dlfunc = prototype(('generate_license_key', _pytransform))
-    return dlfunc(prikey, keysize, rcode) if sys.version_info[0] == 2 \
-        else dlfunc(prikey, keysize, rcode.encode())
-
-
-@dllmethod
-def get_registration_code():
-    prototype = PYFUNCTYPE(py_object)
-    dlfunc = prototype(('get_registration_code', _pytransform))
-    return dlfunc()
-
-
-@dllmethod
-def get_expired_days():
-    prototype = PYFUNCTYPE(py_object)
-    dlfunc = prototype(('get_expired_days', _pytransform))
-    return dlfunc()
-
-
-@dllmethod
-def clean_obj(obj, kind):
-    prototype = PYFUNCTYPE(c_int, py_object, c_int)
-    dlfunc = prototype(('clean_obj', _pytransform))
-    return dlfunc(obj, kind)
-
-
-def clean_str(*args):
-    tdict = {
-        'str': 0,
-        'bytearray': 1,
-        'unicode': 2
-    }
-    for obj in args:
-        k = tdict.get(type(obj).__name__)
-        if k is None:
-            raise RuntimeError('Can not clean object: %s' % obj)
-        clean_obj(obj, k)
-
-
-def get_hd_info(hdtype, name=None):
-    if hdtype not in range(HT_DOMAIN + 1):
-        raise RuntimeError('Invalid parameter hdtype: %s' % hdtype)
-    size = 256
-    t_buf = c_char * size
-    buf = t_buf()
-    cname = c_char_p(0 if name is None
-                     else name.encode('utf-8') if hasattr('name', 'encode')
-                     else name)
-    if (_pytransform.get_hd_info(hdtype, buf, size, cname) == -1):
-        raise PytransformError('Get hardware information failed')
-    return buf.value.decode()
-
-
-def show_hd_info():
-    return _pytransform.show_hd_info()
-
-
-def assert_armored(*names):
-    prototype = PYFUNCTYPE(py_object, py_object)
-    dlfunc = prototype(('assert_armored', _pytransform))
-
-    def wrapper(func):
-        def wrap_execute(*args, **kwargs):
-            dlfunc(names)
-            return func(*args, **kwargs)
-        return wrap_execute
-    return wrapper
-
-
-def get_license_info():
-    info = {
-        'ISSUER': None,
-        'EXPIRED': None,
-        'HARDDISK': None,
-        'IFMAC': None,
-        'IFIPV4': None,
-        'DOMAIN': None,
-        'DATA': None,
-        'CODE': None,
-    }
-    rcode = get_registration_code().decode()
-    if rcode.startswith('*VERSION:'):
-        index = rcode.find('\n')
-        info['ISSUER'] = rcode[9:index].split('.')[0].replace('-sn-1.txt', '')
-        rcode = rcode[index+1:]
-
-    index = 0
-    if rcode.startswith('*TIME:'):
-        from time import ctime
-        index = rcode.find('\n')
-        info['EXPIRED'] = ctime(float(rcode[6:index]))
-        index += 1
-
-    if rcode[index:].startswith('*FLAGS:'):
-        index += len('*FLAGS:') + 1
-        info['FLAGS'] = ord(rcode[index - 1])
-
-    prev = None
-    start = index
-    for k in ['HARDDISK', 'IFMAC', 'IFIPV4', 'DOMAIN', 'FIXKEY', 'CODE']:
-        index = rcode.find('*%s:' % k)
-        if index > -1:
-            if prev is not None:
-                info[prev] = rcode[start:index]
-            prev = k
-            start = index + len(k) + 2
-    info['CODE'] = rcode[start:]
-    i = info['CODE'].find(';')
-    if i > 0:
-        info['DATA'] = info['CODE'][i+1:]
-        info['CODE'] = info['CODE'][:i]
-    return info
-
-
-def get_license_code():
-    return get_license_info()['CODE']
-
-
-def get_user_data():
-    return get_license_info()['DATA']
-
-
-def _match_features(patterns, s):
-    for pat in patterns:
-        if fnmatch(s, pat):
-            return True
-
-
-def _gnu_get_libc_version():
-    try:
-        prototype = CFUNCTYPE(c_char_p)
-        ver = prototype(('gnu_get_libc_version', cdll.LoadLibrary('')))()
-        return ver.decode().split('.')
-    except Exception:
-        pass
-
-
-def format_platform(platid=None):
-    if platid:
-        return os.path.normpath(platid)
-
-    plat = platform.system().lower()
-    mach = platform.machine().lower()
-
-    for alias, platlist in plat_table:
-        if _match_features(platlist, plat):
-            plat = alias
-            break
-
-    if plat == 'linux':
-        cname, cver = platform.libc_ver()
-        if cname == 'musl':
-            plat = 'musl'
-        elif cname == 'libc':
-            plat = 'android'
-        elif cname == 'glibc':
-            v = _gnu_get_libc_version()
-            if v and len(v) >= 2 and (int(v[0]) * 100 + int(v[1])) < 214:
-                plat = 'centos6'
-
-    for alias, archlist in arch_table:
-        if _match_features(archlist, mach):
-            mach = alias
-            break
-
-    if plat == 'windows' and mach == 'x86_64':
-        bitness = struct.calcsize('P'.encode()) * 8
-        if bitness == 32:
-            mach = 'x86'
-
-    return os.path.join(plat, mach)
-
-
-# Load _pytransform library
-def _load_library(path=None, is_runtime=0, platid=None, suffix='', advanced=0):
-    path = os.path.dirname(__file__) if path is None \
-        else os.path.normpath(path)
-
-    plat = platform.system().lower()
-    name = '_pytransform' + suffix
-    if plat == 'linux':
-        filename = os.path.abspath(os.path.join(path, name + '.so'))
-    elif plat == 'darwin':
-        filename = os.path.join(path, name + '.dylib')
-    elif plat == 'windows':
-        filename = os.path.join(path, name + '.dll')
-    elif plat == 'freebsd':
-        filename = os.path.join(path, name + '.so')
-    else:
-        raise PytransformError('Platform %s not supported' % plat)
-
-    if platid is not None and os.path.isfile(platid):
-        filename = platid
-    elif platid is not None or not os.path.exists(filename) or not is_runtime:
-        libpath = platid if platid is not None and os.path.isabs(platid) else \
-            os.path.join(path, plat_path, format_platform(platid))
-        filename = os.path.join(libpath, os.path.basename(filename))
-
-    if not os.path.exists(filename):
-        raise PytransformError('Could not find "%s"' % filename)
-
-    try:
-        m = cdll.LoadLibrary(filename)
-    except Exception as e:
-        if sys.flags.debug:
-            print('Load %s failed:\n%s' % (filename, e))
-        raise
-
-    # Removed from v4.6.1
-    # if plat == 'linux':
-    #     m.set_option(-1, find_library('c').encode())
-
-    if not os.path.abspath('.') == os.path.abspath(path):
-        m.set_option(1, path.encode() if sys.version_info[0] == 3 else path)
-
-    # Required from Python3.6
-    m.set_option(2, sys.byteorder.encode())
-
-    if sys.flags.debug:
-        m.set_option(3, c_char_p(1))
-    m.set_option(4, c_char_p(not is_runtime))
-
-    # Disable advanced mode by default
-    m.set_option(5, c_char_p(not advanced))
-
-    # Set suffix for private package
-    if suffix:
-        m.set_option(6, suffix.encode())
-
-    return m
-
-
-def pyarmor_init(path=None, is_runtime=0, platid=None, suffix='', advanced=0):
-    global _pytransform
-    _pytransform = _load_library(path, is_runtime, platid, suffix, advanced)
-    return init_pytransform()
-
-
-def pyarmor_runtime(path=None, suffix='', advanced=0):
-    if _pytransform is not None:
-        return
-
-    try:
-        pyarmor_init(path, is_runtime=1, suffix=suffix, advanced=advanced)
-        init_runtime()
-    except Exception as e:
-        if sys.flags.debug or hasattr(sys, '_catch_pyarmor'):
-            raise
-        sys.stderr.write("%s\n" % str(e))
-        sys.exit(1)
-
-
-# ----------------------------------------------------------
-# End of pytransform
-# ----------------------------------------------------------
-
-#
-# Not available from v5.6
-#
-
-
-def generate_capsule(licfile):
-    prikey, pubkey, prolic = _generate_project_capsule()
-    capkey, newkey = _generate_pytransform_key(licfile, pubkey)
-    return prikey, pubkey, capkey, newkey, prolic
-
-
-@dllmethod
-def _generate_project_capsule():
-    prototype = PYFUNCTYPE(py_object)
-    dlfunc = prototype(('generate_project_capsule', _pytransform))
-    return dlfunc()
-
-
-@dllmethod
-def _generate_pytransform_key(licfile, pubkey):
-    prototype = PYFUNCTYPE(py_object, c_char_p, py_object)
-    dlfunc = prototype(('generate_pytransform_key', _pytransform))
-    return dlfunc(licfile.encode() if sys.version_info[0] == 3 else licfile,
-                  pubkey)
-
-
-#
-# Deprecated functions from v5.1
-#
-@dllmethod
-def encrypt_project_files(proname, filelist, mode=0):
-    prototype = PYFUNCTYPE(c_int, c_char_p, py_object, c_int)
-    dlfunc = prototype(('encrypt_project_files', _pytransform))
-    return dlfunc(proname.encode(), filelist, mode)
-
-
-def generate_project_capsule(licfile):
-    prikey, pubkey, prolic = _generate_project_capsule()
-    capkey = _encode_capsule_key_file(licfile)
-    return prikey, pubkey, capkey, prolic
-
-
-@dllmethod
-def _encode_capsule_key_file(licfile):
-    prototype = PYFUNCTYPE(py_object, c_char_p, c_char_p)
-    dlfunc = prototype(('encode_capsule_key_file', _pytransform))
-    return dlfunc(licfile.encode(), None)
-
-
-@dllmethod
-def encrypt_files(key, filelist, mode=0):
-    t_key = c_char * 32
-    prototype = PYFUNCTYPE(c_int, t_key, py_object, c_int)
-    dlfunc = prototype(('encrypt_files', _pytransform))
-    return dlfunc(t_key(*key), filelist, mode)
-
-
-@dllmethod
-def generate_module_key(pubname, key):
-    t_key = c_char * 32
-    prototype = PYFUNCTYPE(py_object, c_char_p, t_key, c_char_p)
-    dlfunc = prototype(('generate_module_key', _pytransform))
-    return dlfunc(pubname.encode(), t_key(*key), None)
-
-#
-# Compatible for PyArmor v3.0
-#
-@dllmethod
-def old_init_runtime(systrace=0, sysprofile=1, threadtrace=0, threadprofile=1):
-    '''Only for old version, before PyArmor 3'''
-    pyarmor_init(is_runtime=1)
-    prototype = PYFUNCTYPE(c_int, c_int, c_int, c_int, c_int)
-    _init_runtime = prototype(('init_runtime', _pytransform))
-    return _init_runtime(systrace, sysprofile, threadtrace, threadprofile)
-
-
-@dllmethod
-def import_module(modname, filename):
-    '''Only for old version, before PyArmor 3'''
-    prototype = PYFUNCTYPE(py_object, c_char_p, c_char_p)
-    _import_module = prototype(('import_module', _pytransform))
-    return _import_module(modname.encode(), filename.encode())
-
-
-@dllmethod
-def exec_file(filename):
-    '''Only for old version, before PyArmor 3'''
-    prototype = PYFUNCTYPE(c_int, c_char_p)
-    _exec_file = prototype(('exec_file', _pytransform))
-    return _exec_file(filename.encode())
diff --git a/pytransform/__pycache__/__init__.cpython-36.pyc b/pytransform/__pycache__/__init__.cpython-36.pyc
deleted file mode 100644
index 75bb2539be65062814dda6c5080880056d0f8c70..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 11679
zcmXr!<>k5(el@<!h=JiT0}|k7U|?`yU|=Zz#mK;r!jQt4!w?0b8KW4%e5NQSFwGpr
zoWhX8l*5wC8pWE+7R8p!9>t!^5yg?q8O52)6~&dy9mSo?6UCFu8^y~AGJ`pXFPATh
zkC7pTC5k_#G)f?)BT6t;C`GB6F@`ltI7%c+G)gQ=JcTh)!kr;SIYp&~Aw?xsvY9zb
zDn&I#t%V^<I#oJFJw>C1p_wsCCRI8`Gerx`mQ9sT(N56;v*l8yQ#w=hQuJFGn;E0z
zQ>9b7Qw&p#z&wRi=@jD>6R<kPROuAc6f-beDOEbfJjDXcR!)^pu}rZ7vsF^8Q*2ro
zqEu6QQfyP~S{S3$QtVS4S{S0#Qyf#AS{R}<Qk+v<S{R}<Q(RNrS{S0VQruHKS{S0V
zQ#@0=S{R~qQoK`qS{R~qQ+iW;Q~X*Oqx4exQv6c_S{S4BQ~FZ^Q-WF;qYP3eqy(pg
zv@k{)ri7-1wJ<~(rAnuSr$m5VVVo+R5}6VOW}Bo+r%X(VPKg2g$2282C9Z`b$}Ckn
zB|aqqtin81I%QHyVoDNNg+;1#N^(jHSjI9{I%RT7YDyYd#wt}hB|RkrEMuK2osyZ7
z1!mi%Fa|SdPI(DR6n>hVw^))>a&m65CC4XcBo^J`fY9*;w^)<oGxJJ70%iG`De(oj
zI14IEGV=2h3o=2>`23`-)Z~&|Tmg}8p?=OGkpZr^IGtfkO~za7X?eMcCCM34oCP_F
zC29FZxy85G%QN#*^2>{VaU@r!muKebYTaT>Nh~VQ%)7;$nO}U1H77H#wBi>Vn9{n%
zo>r8anpB+fiv!Bg`o)o7keZiNoT7D$r651M@)mQ2h1oBbOnVEnTWl2;X7Oewx0ox;
zOm49z=B9wC%)FA+oLkI^MY*?F6N_@oOd*unEjAF(EC<3hhj7hvZm|{=B%7JsVh2+>
zskhj2GYg81jc&1k=v(ZGiABj7#zs&E$b!V8Tr-oGtPBhc$)FI0VMbU!<6&T6NM!)!
zttcjN$TQs%2&gP6O3W(;g^6oXQGSu1Ci5+h`1riU+|>B^TU_z+x%nxjIUqJqe0*VP
zVh%)RB}0)O0|SKk73ORe6Iz^FR2)-MnvojglAm0fo0?Zr98;Q?S(09qn35V_P?TAg
zSdto(Tx@7yn4Di)RGeC#Sd<!*l3835Q-E+oOniK1US>&ryk0?Nkro33gE6RpU}9ik
z;9vyvlR>@#`3xk+%)r0^!o>m%3=HiIX^bh1DNHRKwTv~Obj9ok4+fZGd5~#b3=9k%
z3^fcjjC~+wjDBFRXfoYmNi0e)zQvYZ4x%*~Z?UA6<|TtAi}V>77;dqY7bO;0fQ$f{
z$G})6o|2Q3n_7~QpQ2}zlb@WJQ*5UPQUlhb$y8(n3L=mXAOegK0kBz|aINMb16e>`
zV&q{eGC__#kToFxIfIl)F)%QcFqAMhGuATHFr+Y+Fr_gyGlKlu%n;0=$>ev7r!2Lo
zI5R&lJ~J;ZUz53r6J$LH$mKloNMWqWbc?f~D8D4Xq_QCO7F$XV!kgeY1-Y-tl!1Z4
z7Gy0O$Yo3%j695BF?f)Ik{Jkt-4+FQTNXI{TbU#oVwh?fY8gwIN|?crrJ1FcsfH<q
zxr7z$X671ZQ1F+qWwAFi*Rs^Gq_8+Jq_Ac)6@`^>q_EYnq_8_Mh%q!XHZj()1T$!I
z_!WVo{Us<oZgGPX2qal%GJIfQ$Yc;;V5m~{%*!mvOw7rwN>zZA4ho>CC`c_*NK4Gj
zNlj7EP)*Uy{Ljz8pvifQxwx_z>>o%Vfjm+K@@bJ7D9qRy7#O11<1-TTQgTwk$xf5?
z7He)|R({bf*4)gz{GuXItQA>-)G-&OmVo0ILV!Z=mH^m|NMY^*3QABaWndCw=40ex
z1Ys6XpxU8FILH~`Km{d#P=uE-LSQp1dc>zNL0~f|keK~$@qn!@D$Og&%uNLc87vim
zJqYrfCKK4{w|F7>45k(w@n8bv{vvw@28JMzlR=JQU=jd16eM<wAsL)f85kHqG9XjI
zP6e4<!T^f@8s;pfW`<@aMurmR5*9FIZDs+-F;fWxIQCg<SV6I0!_>?i%%I8a_Y!2(
zE#cI><f6)glKABOlvHSmuE_?Dk6T>DsU`9G1tppJdAHb7^FS&f@dirVMIcvbvfW}U
zC{4;vt&Czy&cDT)mXip|%EhH=X_*yZ9~Xf#E+mQ&{scKb668;iK_GvEqNNBV`Vy4j
zl0im;(myCcfG|j=I0Bs5OF+q+se}m>H_dFdtTn7Dj3vxq53-f8WU;0&Niw7`XEPOf
z)UeesWU)0f)G&fcCNRld!_v$e%m9+BVXR@Qf$}w3{G#O2Q}a@b5=%g(W<IE5i_ghS
zPR%P$jZe$WNi7D)>q}6vpvevi1&}L?K=A?&ts-ks5(eepB3A|m22J)`93Xw5ayyE>
zpePf>xW!ro3dCEi#U+VFCAV0U^Gowea0b&YQMikcU6P0hI3Y$JCN0Jye^6QmxeOF$
zAXkAfILtulADos!MFLYZOD%H^a|&Y#3pl)3N?5bl;NfLb!-7a2Fm@JuGXpreu=w2)
z!EjA>Y9%;SiY!4M=759>C`uur0&)e`pkckmR#21)N;K@*sg=c<RjEZjpuhuXZfxl#
zfPsM_3*l{0YLQ|r0*S)QMNk<93IedV376TT>8U00MXBkT#U(|Fpac$1|FCQe_5&z$
zL9;E^L=4KPMIc9k@(}~1s0N9V>m&h?lTs@RGK*4E;!_eUi%D`#FarZaC7NqMV#%O@
z0i_F2LIq)P04X8z5@RznxRQY7B4{Pi%mk_2IFoZy6Z1d?gC+|kg2B;>2qBhR%=t-K
zQ7qY+c_}!Pa#08a149GCc|4$!4I~B+ERfSc*d3$@lo~*7iWKG)mO0F|j1^Wj3@!|@
zMzu^ej9CmNj5SQnj9H*s7?hkDvN?*ZN|;kvYnUK)R|yL!V}r`VLZNVm6i_YA2C2!4
zJVD6}oLZT0F&CE<-QrBDEJ;l)DoU)3VlU0h1m(^u3FpK-g}nR{1+do@Agx?01=V6r
z)?3W!sU^2qKs9)gHn@flf|UB;MjY6enk+>Ip!$imBqcMsq$m`miZL6l1iS?e*5Z<)
zc94f5RTL8=6C(!`7oz|pxZaNeWouaUff5-g<iXKb!@$5$18$Y1Fp4uYGiI|F$&@gq
zFx5b7?-b@*rV{2FCJ_cuhHqx5Whr5)VN3yqluZgto>&QM3Tp~mGgDCjsBlbSZ)VJ6
zssXidSWDQmIBFPbSZbJRSesc=IJ23Gib^<BI3R6;EUqkWaI1&Q4;++LGM;&5i8+}m
z3I&NpiMgpIsYMDIDWK2+1=mXkMg|6O0db23RQiF-#VXd)k~Ce5DtY(R5`~P!q7+bj
zQ~}g-D#`_CL};_&<^TWx|7-HxVl7I{OHaMU=@Am|;_vI|=~o15^b~=zI=Ga%#h#H^
zoLEv)1U4O9+}z>@<)n-haC;2gjJU;GmY7otYILQ7Vpx+ciVfn-qBv0Wuz-r7DAtnr
zq|&q~=A_cJTdc`o2ZL)YFafTfL5Xz=D7wTz8Hy29J+m-!FtRc7F^Vv<F^Vv9FcyK-
zfG|h}7=tP_aHN5<45+dO2Oy)LCKJT5JjEIL<?%4rf-OT3U~4lN7#J3TtOch9#v%|O
zZUrbHKp0d_7Hhz=HDfaqsD%n^t#&fBGqf|NftoGMEgYci9?YQ0;&+QLvA8(3s3bnI
zC^x?-H3g%QFATC(1k}i9Y-ea^N@E6PN`ei2A#g*#gQ=O3k)eYTRH>jg_`&(3$PiR#
zFhfdKP=oyzD=5f|AsGea?^`^ehGcwdMQU<sN$P5lQ$Pg-10x4xl_{#jQM&;JsYR#)
zFf+hr!}<r=Ap4mh_JiscP2_F@JILyS)S^`gTLqY_<O$e{Szt34fsBR}i#edO2NboM
zNVbA|I7OKZ3=GRaR)Nw810xqB4-+3NSQH-5AQ@1{0-Tg4K}K#EQjj6z9FAIs5{71m
zEXHOAQ0!+hr7$%!7NylNW-+HQH#34t&lHv#CQwfyizS7%nK6Y;k|B#Vg*}C%nW=^$
zh0}%s)F?{f5@$$Z0I8~FOko4*%3@04Ze}c6mBN<7lf#zFUdzk~YF5EaWiH{UVNBtL
znB2_R%vi&a!e_%!!<52h&H&P1!vrxeiz$V_nX%|W4O0mxhy}6<q@siiVy^^)Bm-Et
zfDJ<mLoG`UQ!Q&nK#H^rL##(F8`vM>HEd!GV81Y>$Yiq=y{lnKVaVp3z*wYI!&t)#
zaRaCXvtg)V1DR05S;N-MD9(@~A<j_CTKFy;<VRMBdukX`#B4ylIx$IxEanu+X2x3f
z8uk>nY?cX(MSUPyNroDBkSpQprC{n)7;4x-VFXeI5({R~l=ai(xW(of931Kzbc@|J
zBEU1q)#Vn4hhvb7i)XO+EmluAUq|O#Y@TkO0bwS$*dPVkEfyEY5XW0A&i*d0Rh(L3
zu0g?`{(e@s7`a}8BK#Jk9=Hsx;?yn9(>2s9sVFIO1SO?h5CN*ts@SwbJbhiQG#PKP
zCWE^mP9Ui~1_p*Ib}cs_NB3Z>C{{3Cln;_A01<^C0@QxF#pdQ2;q4k(R07h#qNQ4F
z1#Zy&Vze$Q24xa9Y`TgnLHa>jisC_vxQjq-pQ2PydCCQD-WHc<mSo&wNz2Sjxy4#s
zkds+*i@hkdASW?7HHro7%nFcV*0h}b#FAUgIjMQKnDdKLG&ydufU5&gBj6TmW?o8a
zMG;746iY!-YFUvl$lhp>PR2}dhK3N}5(C_Xg0+=FhHL_5Dlbqu%mk`j5g1g>axro-
zDlrN$v4AohBNw9tBL|ZZqX44_6AL3qjE|9n5mXtoFp4k=F!F&_h%gqlf~sYZkuVG@
zmciK)G{OPOfGLcUphgFiA2>)gAzC2L1m%AS3)8`%s_8z+!5{+}7>n9Sum~Jccr4-t
zRf(m=sYUTAi6x1k@!(>pEui)Xypag1NkD}x*gFag3=9=g;FgzAEmH|7-!L^Z6|sTF
zunO6rEh{F!5KYD+(3r9&a}-BGVo6DAQC{&a#^NaEf<%lCI)6NPKrlWnHL;|$D7E-G
z$h)AX4XDuLVl3)J_A<zUAcMh<aRIe&wLpCt#6V0IGpK+A^<|(19!oQ*IAd;R3}#?q
zC}GRyDzal_0KrIxJf;XpQ;@|kN+dn6G#(TnIhjex@zBv5NTw<WrDgUaP)vfG7eydP
z+~W4hPfYR2Oe#t&sstzTqFPV_<aDh_P6c<5q5Xs?=CafxNc4gu8XU)>@z|_;3-UQ=
zWRL;W=wlRN<YVMxEb0OIAJk$1r7e&n;E^H62x{^b34mG<SxhwyAU~EcXMueT@_h+2
zsDGQq+RRYPRH0D9?!pi&5yMo=T+33zQNvQh*vwR<SHoP(7{E}d2Py(n7_*s*_LMMZ
zaW;d7jaX~hYFJa4vYCo<QkZHP^8#vE!M*6J6qZ`XJf|8~@G#My60T+jP!U<Qr-ZwP
z9aMp2vli_s;i+LyVFwl6DI6jUU>+xkC(e+<mCaDJCxyF~u|lDQ7w#sG5{?><8c<?7
zRKr}$6u?k;2<#@FY^MA-HB2eI*-R4{iv&veviMW@vILqLni*60MHp&1YdBK`AaW^!
zpd^{am?a3RI>5aZA-^I}J35Lbx3oAXiUkz8QS6C%DMk62DN(HHAU?QY0~e<+Q$Xbi
zsQ7$&4b)s`PfpD%$uBl50>w#@1SonL173n^-It(zPy}l7X$sw9$}hgfQjl1Zaf>4_
zzbF^Nf{kw9Vk@pJE=kS3#hQ~}o?3K^JvT8qBQr1c78giGd`V(bPAWKwM{$5014?<|
z7%u|#jBYW5#@e|+qstJLx7dnHib|79qBxQhbCN+#RB#jb7E4xsW}YV3EjEy$nJKqe
zKy(xf$gW$gi8+~x#Zep}p&U@(HXY<QmgKV3qFan*Q5+!CLE^XAlQK*4Qj4L@Ekt7F
z2aQN4mc)Y$05QLTk}0Ss%)rRP$iu_~YMC%{F|shSfjhjQ#xD#TFtRX#3Q3Th5Tg)C
z6;sh-P=W^aTR;gKl$k+|LvV)nU;-s*aGyj3lBi3Vn;G-Cz-$&!0<UEN4Nx>QfCeFI
zSyLEmn8g|3$ut72jsr|`)-cqtr7(*#G=utt?0E?_tSKznOhqL~vaBH4TJ}7b8rBrH
zY^I_KNOJ5@IgJ|D6pn1BqBTfzU{h<^^LR?QQaEc^L2ZvFMo@buo3rQ=SRFU0H(GS5
zhN+f4F9jk~`~fV(1Ii*i48<R67<m{bFcz6XWG65d@qp!dK{`Ra8m2rUun1=jLkV9A
zKS;cpxfbR-2rU3It(mEo9jp>;_5{Y_fD*10t{QfTyDIrg1ha%d>S{T|8S)%h7)pe*
zxh60c&0}P!<zi&0QYsP263r5uz*y8%BA&us!(PLc2JSU8GBh!SGem;hleJuRToK>`
z6KoSl3Qsd5gawKfQ1&anSHqblk-}Rdk|mkKC&`e)4-zf9QNxfW)y$9wDxR1a8Ng};
zN<^}xL874kIMjBgA}+8Te~C;AZ!;rE2Fw>MkpYDil88`=ObrVU15|{00#lI-Sfy|c
zGtA5y&R_;j5kGKe3Y`C|nDvVDi}*l|88*F?%ACw3aGtJW(M!q6DFUUxD#?Hx$b6K7
zYB9K{UtC&HkY7}ino=d~oL`!g0u}_dToja4i<PQ`K;=J3Eo4aBic7V)2vk#mJHg=M
zqzKf=0GBQ=K}B|vCa81)HN!Mzizb2ClR+g4drD>zsFwqp>H!T7#>W?d`jbUdK`N$!
zi0NQuiAlwvlBH-aNC-3@eTyx#7^LAATWUpSaY^wl*39C>q~crPiM4pJT2M~A#gUX)
zoC>m`2vlzsb%FGEg9z~8Bxr2q7HdjsQfc}vR?v`SNfD@8g$&4p1}!1OA^AlqsYT%0
zPm{X{>~5~i;&|AQ^*oSq9w29OB&L)l<|U`56wL>Tfx6N~-k|b^Jts2><fdDUxwjZo
z(d$Fr_?-O2lz33QBo<XlGcqs~g949%Q3PDTa4>Q($}n<(d()sEwFnar6R3AB$0)-n
z!YIbX$H>FP#K;FOU<4RN*rXU$n1#TDCPK_Y%xsJTOhsFe3ms7518QM_3ms4?UILzj
z0u2#?#)1<WOPF9ia%QkjNJ;|D4`{N2y<fBe<UP2*i#CF|;35-DfGc^Pf=X~F8a%uo
z3i1;u8Gweii?)JX18P`-ia?MksFDJ^22|{qFo3!*MLeKks!FL6P}hkORHLOZ^|CNB
zfZWE&5YCVn!opC(oXu5K#mE5ad{tS1#=5iEioHtMOIT8vo0*Dynixu0vN*ChQ&>v4
zYM7fDK}7;1NQ^s$5!4ljXK&^@W=Qr1*{R728OqUQhIkVcvtS=a@x>>DCU4`RKC5C@
zE#}hXfrJjoPvF^#BGlAXv=$ULNubohR$Kx~Mz>hYi!w`6i^4!+EU6WlC7LXdP=(u6
zv>Buc9F|}L9H9JAYhmdw8Wg6Wp$Jg_pM{BuQ2^XF7h+^$6k#md2?}Fay9pHApjZco
zF=R-jnIVR`ma&$pmKhYnpq57rQ!Ps^D=4IESZY{nnA2E;88ktoGPfk-;RD?TMUaVr
z<ivvF(wtNjDa7Pye0FN3CfhCcoXliU9xVz4dB+XpU$%mx{G80>TWraR1)$+>w!GBx
z?9@v193cR=5NZ*qNGS$+g8@8cRkR=EJy7xiVNlKnB`2`=2#<72zzs+94d!SCWR40l
zBm#~JFae5=qFtcA04NH;t^(KnU@>^l0hF*o80;$07(S?}4w|OH99{+`UHG(v0c4T}
zRA+!1so-&`C?q$d1~VvN7{FyMY!U|4LIamokc0^?=Ma-HEJb@@kpUTm0l5q<_=|Qk
zFfi1E{01_M0o2A}lwt&nCWFEm6y~7h1j1n7feK`(@0d#%(I-_vQzxKiI4Eg>r%sss
zZi&Js*<eusN+-pdY)Av@ps*_fIRN4hP-(2m3Ys{|2Nma#xg>DQjU_ifB^9@44l*z>
zbb&kri73!iNfAg4KDGz)2FNn7S3pf$P>&TkcQiBBvVa_4!&1YX2Abgn<qB|Q-;#)j
z%mT(k(<vzBgJ;JySs?)pPx?iBLE*j+M1T_!m;k4w0}Kod6X6bI<N*zug2dns1cf==
zfoiZ3O{Nm2W@gZ+7JRyosfMYB0n`CXVE{M(nf#)}aXSw*lmZD~kl9Fq%nWfk&bg-}
z3=9m@;qC>ejv|m4JZ*pi8WgDD00oU?mN29+f=1p!Q<XKKnRw8|8%qsK3KMkV4Kx$W
zT*J@@=}|*wV~Zw&3JhLYLV+X@R>(Lv*zF)IARYiU$2Hk*F@s8yL!b~o4ARP40*VdX
z3F9aO1H(L!KR}5LG+hNw8X!@49tK$f!eF0(Y=Qa&G}#KCPbguArgoT5Sm3FhsfMwS
zAq6s7$m|F4jWE3E$%U+D0T+}=egZiKDf7Y;eQ6RX(H9*9dG0ufz!^IyKqIFZz5<D&
z%$S4X2<$7+IuDSqQkZ%f85uw^R05hz2Bj`m@N79VbTSzfN8tFWVFpk0vs9`1=jBu?
zq~#YW<maR)Kt~O96p~WY@{3Xx0xBIrgXjvz;5MNqBcwJ3P2Ov=fSUkFc^wqAnru-V
zpx$B;XgG|kxU#sQC?6E*QQRdNMX8A?C143&2nQ+$iCoayJ+vb1mOy?EXu2b_1Xf*c
zfQJb)Xb6jkvFIeI4gu92pz;iq2S6AcCP?KOD35_wjG#;gg7R1mBZ!3LGh##H7H?)Q
zs8tPJ%cRK)2?A`9&T@-AH$Md&>7W)Q*rQQ=@hJMy{9JU3fq`Ks$eW<ZWnczRDT2gM
z3KCFZ0`??g#uGj@0$DWxFGfHkDw<40dyW${F##+55IGbSswkxk!arQ#c?hr;bibTo
zU|=|i@Cz4cdK4tKk_p^*DdJ^dV1TjDLfD`VP7yy6`#gxvSR@Fdn7}=uqKgnVXd0&o
z)OK3Q1n&P7T?UCW7Kwr=CNNcW6*Tb0T67MS+b)2JOCaJ3hyaa`tYj<_ho}ZMp^L7A
z*epeoAZgH8NfD?WQX~x$WdaYL6x{@|8H;2=6jPB5Na1Y|o3RMA7;Gg|ksL_qE<{KX
zL@^bCYNI012<S@2B4vmWDB6l1g4m2jsvwG~NCl)3G=jO3u?SQ>tYiXHMNc8p>L6)Q
zt8XP!5tt1cW7Om<x&acu1tRW%h<hO70f=}6BA$SVXCUGQC?FUiqk-U&Z6@#lH#A%O
zf!c_yklAEEh$2w46V!?Z(a1u~$Q(v+%S97Pv4DACBM~f3TS!k4+!+M7W9EQ5Q*6ng
z`P5=ahYpmSAq6I=oQ5o&0?qtEDh6;W1dSSk$772?Q)WdoL4KMIA`(ERaeIWs!{#HR
zI6Ok)!BY}Z>>yS^m<fzwRs>pQ0!hc<7Cxwq056h*bQVFqBS`xnl)1nQP{7MEAd>)~
zbqC<N@FLI@Hh4-DJZTA@(E^X3gU7bPQ{Uk6Fvutvs0Rz_fq}ahpf)|Y<qK|mfZJo>
zmP`?-wE(Vyi$Jwk5vZ^Smu}z^p$L?1kg^xN;c<(@22u;zfda7@G=&c8YH~1gu<9`J
zu(B|N2Z|XP7+F|gEEvtgCdA6ZEWpCS#>39T$HUIV2*w;d96anG$id6S$HBtE!=cN;
m!okA9#=*&@%4NmH#w8Bc!Og_T!v<o3^zm>pG4gQmZ~y=qG!Cl(

diff --git a/pytransform/__pycache__/__init__.cpython-38.pyc b/pytransform/__pycache__/__init__.cpython-38.pyc
deleted file mode 100644
index 9aaff7fb561fefe38907458054c4c1944bed1091..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 11349
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

diff --git a/pytransform/_pytransform.dll b/pytransform/_pytransform.dll
deleted file mode 100644
index b1af3263115ebab5c213656cf1daf87b3510116b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1368590
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%0AcwU9
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
D&;+O~

diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..f19f26e
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,49 @@
+# Use this guide:
+# https://packaging.python.org/tutorials/packaging-projects/
+
+# from unitgrade2.version import __version__
+import setuptools
+with open("src/unitgrade_private2/version.py", "r", encoding="utf-8") as fh:
+    __version__ = fh.read().strip().split(" = ")[1].strip()[1:-1]
+# long_description = fh.read()
+
+with open("README.md", "r", encoding="utf-8") as fh:
+    long_description = fh.read()
+
+setuptools.setup(
+    name="unitgrade-devel",
+    version=__version__,
+    author="Tue Herlau",
+    author_email="tuhe@dtu.dk",
+    description="A set of tools to develop unitgrade reports and evaluate them",
+    long_description=long_description,
+    long_description_content_type="text/markdown",
+    license="MIT",
+    url='https://lab.compute.dtu.dk/tuhe/unitgrade_private',
+    project_urls={
+        "Bug Tracker": "https://lab.compute.dtu.dk/tuhe/unitgrade_private/issues",
+    },
+    classifiers=[
+        "Programming Language :: Python :: 3",
+        "License :: OSI Approved :: MIT License",
+        "Operating System :: OS Independent",
+    ],
+    package_dir={"": "src"},
+    packages=setuptools.find_packages(where="src"),
+    python_requires=">=3.8",
+    install_requires=['numpy', "unitgrade", "codesnipper", 'tabulate', 'tqdm', "pyfiglet", "colorama", "coverage", "compress_pickle"],
+)
+
+# setup(
+#     name='unitgrade',
+#     version=__version__,
+#     packages=['unitgrade2'],
+#     url=,
+#     license='MIT',
+#     author='Tue Herlau',
+#     author_email='tuhe@dtu.dk',
+#     description="""
+# A student homework/exam evaluation framework build on pythons unittest framework. This package contains all files required to run unitgrade tests as a student. To develop tests, please use unitgrade_private.
+# """,
+#     include_package_data=False,
+# )
diff --git a/src/unitgrade_devel.egg-info/PKG-INFO b/src/unitgrade_devel.egg-info/PKG-INFO
new file mode 100644
index 0000000..ab8dded
--- /dev/null
+++ b/src/unitgrade_devel.egg-info/PKG-INFO
@@ -0,0 +1,317 @@
+Metadata-Version: 2.1
+Name: unitgrade-devel
+Version: 0.0.1
+Summary: A set of tools to develop unitgrade reports and evaluate them
+Home-page: https://lab.compute.dtu.dk/tuhe/unitgrade_private
+Author: Tue Herlau
+Author-email: tuhe@dtu.dk
+License: MIT
+Project-URL: Bug Tracker, https://lab.compute.dtu.dk/tuhe/unitgrade_private/issues
+Platform: UNKNOWN
+Classifier: Programming Language :: Python :: 3
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Requires-Python: >=3.8
+Description-Content-Type: text/markdown
+License-File: LICENSE
+
+# Unitgrade-private
+Unitgrade is an automatic report and exam evaluation framework that enables instructors to offer automatically evaluated programming assignments. 
+ Unitgrade is build on pythons `unittest` framework so that the tests can be specified in a familiar syntax and will integrate with any modern IDE. What it offers beyond `unittest` is the ability to collect tests in reports (for automatic evaluation) and an easy and 100% safe mechanism for verifying the students results and creating additional, hidden tests. A powerful cache system allows instructors to automatically create test-answers based on a working solution. 
+
+ - 100% Python `unittest` compatible
+ - No external configuration files: Just write a `unittest`
+ - No unnatural limitations: Use any package or framework. If you can `unittest` it, it works.   
+ - Granular security model: 
+    - Students get public `unittests` for easy development of solutions
+    - Students get a tamper-resistant file to create submissions which are uploaded
+    - Instructors can automatically verify the students solution using a Docker VM and run hidden tests
+ - Tests are quick to run and will integrate with your IDE
+
+**Note: This is the development version of unitgrade. If you are a student, please see http://gitlab.compute.dtu.dk/tuhe/unitgrade.**
+
+# Using unitgrade
+The examples can be found in the `/examples/` directory: https://gitlab.compute.dtu.dk/tuhe/unitgrade_private/examples
+
+## A simple example
+Unitgrade makes the following assumptions:
+ - Your code is in python
+ - Whatever you want to do can be specified as a `unittest`
+
+Although not required, it is recommended you maintain two version of the code: 
+ - A fully-working version (i.e. all tests pass)
+ - A public version distributed to students (some code removed))
+
+In this example, I will use `snipper` (see http://gitlab.compute.dtu.dk/tuhe/snipper) to synchronize the two versions automatically.
+Let's look at an example. You need three files
+```
+instructor/cs101/homework.py # This contains the students homework
+instructor/cs101/report1.py  # This contains the tests
+instructor/cs101/deploy.py   # A private file to deploy the tests
+```
+
+### The homework
+The homework is just any old python code you would give to the students. For instance:
+```python
+def reverse_list(mylist): #!f
+    """
+    Given a list 'mylist' returns a list consisting of the same elements in reverse order. E.g.
+    reverse_list([1,2,3]) should return [3,2,1] (as a list).
+    """
+    return list(reversed(mylist))
+
+def add(a,b): #!f
+    """ Given two numbers `a` and `b` this function should simply return their sum:
+    > add(a,b) = a+b """
+    return a+b
+
+if __name__ == "__main__":
+    # Problem 1: Write a function which add two numbers
+    print(f"Your result of 2 + 2 = {add(2,2)}")
+    print(f"Reversing a small list", reverse_list([2,3,5,7]))
+```
+### The test: 
+The test consists of individual problems and a report-class. The tests themselves are just regular Unittest (we will see a slightly smarter idea in a moment). For instance:
+
+```python
+from looping import reverse_list, add
+import unittest
+
+
+class Week1(unittest.TestCase):
+    def test_add(self):
+        self.assertEqual(add(2, 2), 4)
+        self.assertEqual(add(-100, 5), -95)
+
+    def test_reverse(self):
+        self.assertEqual(reverse_list([1, 2, 3]), [3, 2, 1])
+
+```
+A number of tests can be collected into a `Report`, which will allow us to assign points to the tests and use the more advanced features of the framework later. A complete, minimal example:
+
+```python
+from src.unitgrade2.unitgrade2 import Report
+from src.unitgrade2 import evaluate_report_student
+from looping import reverse_list, add
+import unittest
+
+
+class Week1(unittest.TestCase):
+    def test_add(self):
+        self.assertEqual(add(2, 2), 4)
+        self.assertEqual(add(-100, 5), -95)
+
+    def test_reverse(self):
+        self.assertEqual(reverse_list([1, 2, 3]), [3, 2, 1])
+
+
+import cs101
+
+
+class Report1(Report):
+    title = "CS 101 Report 1"
+    questions = [(Week1, 10)]  # Include a single question for 10 credits.
+    pack_imports = [cs101]
+
+
+if __name__ == "__main__":
+    # Uncomment to simply run everything as a unittest:
+    # unittest.main(verbosity=2)
+    evaluate_report_student(Report1())
+```
+
+### Deployment
+The above is all you need if you simply want to use the framework as a self-check: Students can run the code and see how well they did. 
+In order to begin using the framework for evaluation we need to create a bit more structure. We do that by deploying the report class as follows:
+```python
+from report1 import Report1
+from unitgrade_private2.hidden_create_files import setup_grade_file_report
+from snipper import snip_dir
+import shutil
+
+if __name__ == "__main__":
+    setup_grade_file_report(Report1, minify=False, obfuscate=False, execute=False)
+
+    # Deploy the files using snipper: https://gitlab.compute.dtu.dk/tuhe/snipper
+    snip_dir.snip_dir(source_dir="../programs", dest_dir="../../students/programs", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
+
+```
+ - The first line creates the `report1_grade.py` script and any additional data files needed by the tests (none in this case)
+ - The second line set up the students directory (remember, we have included the solutions!) and remove the students solutions. You can check the results in the students folder.
+
+### Using the framework as a student
+You can now upload the `student' directory to the students. The students can run their tests either by running `cs101.report1` in their IDE or by typing:
+```
+python -m cs101.report1
+```
+in the command line. This produces a detailed output of the test and the program is 100% compatible with a debugger. When the students are happy with their output they can run (using command line or IDE):
+```
+python -m cs101.report1_grade
+```
+This runs an identical set of tests, but produces a `.token` file the students can upload to get credit. 
+ - The reason to have a seperate `report1_grade.py` script is to avoid accidential removal of tests.
+ - The `report1_grade.py` includes all tests and the main parts of the framework and is obfuscated by default. You can apply a much strong level of protection by using e.g. `pyarmor`.
+ - The `report1_token.token` file includes the outcome of the tests, the time taken, and all python source code in the package. In other words, the file can be used for manual grading, for plagirism detection and for detecting tampering. 
+ - You can easily use the framework to include output of functions. 
+ - See below for how to validate the students results 
+
+### How safe is this?
+Cheating within the framework is probably best done by manually editing the `.token`-file or by creating a broken set of tests. This involves risk of being trivially detected, for instance because tests have the wrong runtime, but more importantly 
+the framework automatically pack all the used source code and so if a student is cheating, there is no way to hide it for an instructor who looks at the results. If the 
+program is used in conjunction with automatic plagiarism software, cheating therefore involves both breaking the framework, and creating 'false' solutions which statistically match other students solutions, and then hope nobody bothers to check the output. 
+ The bottom line is that I think plain old plagiarism is a much more significant risk, and one the framework reduces relative to other project work 
+by demanding the source code is included. 
+
+If this is not enough you have two options: You can either use `pyarmor` to create a **very** difficult challenge for a prospective hacker, or you can simply validate the students results as shown below.
+
+
+## Example 2: The framework
+One of the main advantages of `unitgrade` over web-based autograders it that tests are really easy to develop and maintain. To take advantage of this, we simply change the class the questions inherit from to `UTestCase` (this is still a `unittest.TestCase`) and we can make use of the chache system. As an example:
+
+```python 
+class Week1(UTestCase):
+    """ The first question for week 1. """
+    def test_add(self):
+        from cs102.homework1 import add
+        self.assertEqualC(add(2,2))
+        self.assertEqualC(add(-100, 5))
+
+    def test_reverse(self):
+        from cs102.homework1 import reverse_list
+        """ Reverse a list """ # Add a title to the test.
+        self.assertEqualC(reverse_list([1,2,3]))
+```
+Note we have changed the test-function to `self.assertEqualC` (the `C` is for cache) and dropped the expected result. What `unitgrade` will do
+is to evaluate the test *on the working version of the code*, compute the results of the test, and allow them to be available to the user. All this happens in the `deploy.py` script from before.
+
+There are other ways to send the output to the user. For instance:
+```python
+class Question2(UTestCase):
+    """ Second problem """
+    @cache
+    def my_reversal(self, ls):
+        # The '@cache' decorator ensures the function is not run on the *students* computer
+        # Instead the code is run on the teachers computer and the result is passed on with the
+        # other pre-computed results -- i.e. this function will run regardless of how the student happens to have
+        # implemented reverse_list.
+        from cs102.homework1 import reverse_list
+        return reverse_list(ls)
+
+    def test_reverse_tricky(self):
+        ls = ("butterfly", 4, 1)
+        ls2 = self.my_reversal( tuple(ls) ) # This will always produce the right result.
+        ls3 = self.my_reversal( tuple([1,2,3]) )  # Also works; the cache respects input arguments.
+        self.assertEqualC(self.my_reversal( tuple(ls2) )) # This will actually test the students code.
+        return ls
+```
+This code showcase the `@cache` decorator. What it does is it computes the output of the function on your computer and allows that 
+result to be availble to students (the input arguments must be immutable). This may seem odd, but it is very helpful 
+ - if you have exercises that depend on each other, and you want students to have access to the expected result of older methods which they may not have implemented correctly. 
+ - If you want to use functions the students write to set up appropriate tests without giving away the solution
+
+Furthermore, one of the test now has a return value, which will be automatically included in the `.token` file. 
+
+## Example 3: Hidden and secure tests
+To use `unitgrade` as a true autograder you both want security nobody tampered with your tests (or the `.token` files), and 
+also that the students implementations didn't just detect what input was being used and 
+return the correct answer. To do that you need hidden tests and external validation.
+
+Our new testclass looks like this:
+
+```python
+from src.unitgrade2.unitgrade2 import UTestCase, Report, hide
+from src.unitgrade2 import evaluate_report_student
+
+
+class Week1(UTestCase):
+    """ The first question for week 1. """
+
+    def test_add(self):
+        from cs103.homework1 import add
+        self.assertEqualC(add(2, 2))
+        self.assertEqualC(add(-100, 5))
+
+    @hide
+    def test_add_hidden(self):
+        # This is a hidden test. The @hide-decorator will allow unitgrade to remove the test.
+        # See the output in the student directory for more information.
+        from cs103.homework1 import add
+        self.assertEqualC(add(2, 2))
+
+
+import cs103
+
+
+class Report3(Report):
+    title = "CS 101 Report 3"
+    questions = [(Week1, 20)]  # Include a single question for 10 credits.
+    pack_imports = [cs103]
+
+
+if __name__ == "__main__":
+    evaluate_report_student(Report3())
+```
+
+This test is stored as `report3_complete.py`. Note the `@hide` decorator which will tell the framework that test (and all code) should be hidden from the user.
+
+In order to use the hidden tests, we first need a version for the students without them. This can be done by changing the `deploy.py` script as follows:
+
+```python
+def deploy_student_files():
+    setup_grade_file_report(Report3, minify=False, obfuscate=False, execute=False)
+    Report3.reset()
+
+    fout, ReportWithoutHidden = remove_hidden_methods(Report3, outfile="report3.py")
+    setup_grade_file_report(ReportWithoutHidden, minify=False, obfuscate=False, execute=False)
+    sdir = "../../students/cs103"
+    snip_dir(source_dir="../cs103", dest_dir=sdir, clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py', 'report3_complete*.py'])
+    return sdir
+
+
+if __name__ == "__main__":
+    # Step 1: Deploy the students files and return the directory they were written to
+    student_directory = deploy_student_files()
+```
+This script first compiles the `report3_complete_grade.py`-script (which we will use) and then 
+remove the hidden methods and compiles the students script `report3_grade.py`-script. Finally, we synchronize with the s
+student folder, which now contains no traces of our hidden method -- not in any of the sources files or the data files. 
+
+The next step is optional, but we quickly simulate that the student runs his script and we get a link to the `.token` file:
+```python
+os.system("cd ../../students && python -m cs103.report3_grade")
+student_token_file = glob.glob(student_directory + "/*.token")[0]
+```
+This is the file we assume the student uploads. The external validation can be carried out as follows:
+
+```python
+def run_student_code_on_docker(Dockerfile, student_token_file):
+    token = docker_run_token_file(Dockerfile_location=Dockerfile,
+                          host_tmp_dir=os.path.dirname(Dockerfile) + "/tmp",
+                          student_token_file=student_token_file,
+                          instructor_grade_script="report3_complete_grade.py")
+    with open(token, 'rb') as f:
+        results = pickle.load(f)
+    return results
+
+if __name__ == "__main__":
+    # Step 3: Compile the Docker image (obviously you will only do this once; add your packages to requirements.txt).
+    Dockerfile = os.path.dirname(__file__) + "/../unitgrade-docker/Dockerfile"
+    os.system("cd ../unitgrade-docker && docker build --tag unitgrade-docker .")
+
+    # Step 4: Test the students .token file and get the results-token-file. Compare the contents with the students_token_file:
+    checked_token = run_student_code_on_docker(Dockerfile, student_token_file)
+
+    # Let's quickly compare the students score to what we got (the dictionary contains all relevant information including code).
+    with open(student_token_file, 'rb') as f:
+        results = pickle.load(f)
+    print("Student's score was:", results['total'])
+    print("My independent evaluation of the students score was", checked_token['total'])
+```
+
+These steps compile a Docker image (you can easily add whatever packages you need) and runs **our** `project3_complete_grade.py` script on the **students** source code (as taken from the token file). 
+
+The last lines load the result and compare the score -- in this case both will return 0 points, and any dissimilarity in the results should be immediate cause for concern. 
+
+ - Docker prevents students from doing mailicious things to your computer and allows the results to be reproducible by TAs. 
+
+
diff --git a/src/unitgrade_devel.egg-info/SOURCES.txt b/src/unitgrade_devel.egg-info/SOURCES.txt
new file mode 100644
index 0000000..b7b0b23
--- /dev/null
+++ b/src/unitgrade_devel.egg-info/SOURCES.txt
@@ -0,0 +1,18 @@
+LICENSE
+README.md
+pyproject.toml
+setup.py
+src/unitgrade_devel.egg-info/PKG-INFO
+src/unitgrade_devel.egg-info/SOURCES.txt
+src/unitgrade_devel.egg-info/dependency_links.txt
+src/unitgrade_devel.egg-info/requires.txt
+src/unitgrade_devel.egg-info/top_level.txt
+src/unitgrade_private2/__init__.py
+src/unitgrade_private2/deployment.py
+src/unitgrade_private2/docker_helpers.py
+src/unitgrade_private2/hidden_create_files.py
+src/unitgrade_private2/hidden_gather_upload.py
+src/unitgrade_private2/token_loader.py
+src/unitgrade_private2/version.py
+src/unitgrade_private2/autolab/__init__.py
+src/unitgrade_private2/autolab/autolab.py
\ No newline at end of file
diff --git a/src/unitgrade_devel.egg-info/dependency_links.txt b/src/unitgrade_devel.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/unitgrade_devel.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/src/unitgrade_devel.egg-info/requires.txt b/src/unitgrade_devel.egg-info/requires.txt
new file mode 100644
index 0000000..70825fe
--- /dev/null
+++ b/src/unitgrade_devel.egg-info/requires.txt
@@ -0,0 +1,9 @@
+numpy
+unitgrade
+codesnipper
+tabulate
+tqdm
+pyfiglet
+colorama
+coverage
+compress_pickle
diff --git a/src/unitgrade_devel.egg-info/top_level.txt b/src/unitgrade_devel.egg-info/top_level.txt
new file mode 100644
index 0000000..9da4671
--- /dev/null
+++ b/src/unitgrade_devel.egg-info/top_level.txt
@@ -0,0 +1 @@
+unitgrade_private2
diff --git a/unitgrade_private2/__init__.py b/src/unitgrade_private2/__init__.py
similarity index 97%
rename from unitgrade_private2/__init__.py
rename to src/unitgrade_private2/__init__.py
index 3164fd6..b233adc 100644
--- a/unitgrade_private2/__init__.py
+++ b/src/unitgrade_private2/__init__.py
@@ -1,5 +1,6 @@
 import os
 import compress_pickle
+# __version__ = "0.0.1"
 
 def cache_write(object, file_name, verbose=True):
     dn = os.path.dirname(file_name)
diff --git a/unitgrade_private2/codejudge_example/__init__.py b/src/unitgrade_private2/autolab/__init__.py
similarity index 100%
rename from unitgrade_private2/codejudge_example/__init__.py
rename to src/unitgrade_private2/autolab/__init__.py
diff --git a/autolab/autolab.py b/src/unitgrade_private2/autolab/autolab.py
similarity index 89%
rename from autolab/autolab.py
rename to src/unitgrade_private2/autolab/autolab.py
index 6f9fc05..1c863c5 100644
--- a/autolab/autolab.py
+++ b/src/unitgrade_private2/autolab/autolab.py
@@ -4,17 +4,14 @@ cd ~/Autolab && bundle exec rails s -p 8000 --binding=0.0.0.0
 To remove my shitty image:
 docker rmi tango_python_tue
 """
-import inspect
 from zipfile import ZipFile
-import os
 from os.path import basename
 import os
 import shutil
 from jinja2 import Environment, FileSystemLoader
 import glob
 import pickle
-from unitgrade2.unitgrade2 import Report
-import inspect
+from src.unitgrade2.unitgrade2 import Report
 from unitgrade_private2 import docker_helpers
 
 COURSES_BASE = "/home/tuhe/Autolab/courses/AutoPopulated"
@@ -58,10 +55,10 @@ def zipFilesInDir(dirName, zipFileName, filter):
 
 def paths2report(base_path, report_file):
     mod = ".".join(os.path.relpath(report_file[:-3], base_path).split(os.sep))
-    # f2 = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/instructor/cs101"
-    # spec1 = importlib.util.spec_from_file_location("cs101", f2)
-    # cs101 = importlib.util.module_from_spec(spec1)
-    # spec1.loader.exec_module(cs101)
+    # f2 = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/instructor/programs"
+    # spec1 = importlib.util.spec_from_file_location("programs", f2)
+    # programs = importlib.util.module_from_spec(spec1)
+    # spec1.loader.exec_module(programs)
 
     from importlib.machinery import SourceFileLoader
     foo = SourceFileLoader(mod, report_file).load_module()
@@ -85,22 +82,6 @@ def run_relative(file, base):
 
 import inspect
 
-# class Example:
-#     @property
-#     def title(self):
-#         stack = inspect.stack()
-#         return stack[1].function.__doc__
-#     @title.setter
-#     def title(self, value):
-#         stack = inspect.stack()
-#         stack[1].function.__doc__ = value
-#         # self._title = value
-#
-#     def myfun(self):
-#         self.title = 234
-#         self.title
-#
-#         return 3
 
 
 def deploy_assignment(base_name, INSTRUCTOR_BASE, INSTRUCTOR_GRADE_FILE, STUDENT_BASE, STUDENT_GRADE_FILE,
@@ -121,8 +102,8 @@ def deploy_assignment(base_name, INSTRUCTOR_BASE, INSTRUCTOR_GRADE_FILE, STUDENT
 
     LAB_DEST = os.path.join(COURSES_BASE, base_name)
 
-    # STUDENT_HANDOUT_DIR = os.path.dirname(STUDENT_GRADE_FILE) #"/home/tuhe/Documents/unitgrade_private/examples/example_simplest/students/cs101"
-    # INSTRUCTOR_GRADE_FILE = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/instructor/cs101/report1.py"
+    # STUDENT_HANDOUT_DIR = os.path.dirname(STUDENT_GRADE_FILE) #"/home/tuhe/Documents/unitgrade_private/examples/example_simplest/students/programs"
+    # INSTRUCTOR_GRADE_FILE = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/instructor/programs/report5.py"
     # Make instructor token file.
     # Get the instructor result file.
     run_relative(INSTRUCTOR_GRADE_FILE, INSTRUCTOR_BASE)
@@ -142,7 +123,7 @@ def deploy_assignment(base_name, INSTRUCTOR_BASE, INSTRUCTOR_GRADE_FILE, STUDENT
     print(scores)
 
     # Quickly make student .token file to upload:
-    # os.system(f"cd {os.path.dirname(STUDENT_HANDOUT_DIR)} && python -m cs101.{os.path.basename(INSTRUCTOR_GRADE_FILE)[:-3]}")
+    # os.system(f"cd {os.path.dirname(STUDENT_HANDOUT_DIR)} && python -m programs.{os.path.basename(INSTRUCTOR_GRADE_FILE)[:-3]}")
     # os.system(f"cd {STUDENT_HANDOUT_DIR} && python {os.path.basename(INSTRUCTOR_GRADE_FILE)}")
     # handin_filename = os.path.basename(STUDENT_TOKEN_FILE)
 
@@ -165,7 +146,7 @@ def deploy_assignment(base_name, INSTRUCTOR_BASE, INSTRUCTOR_GRADE_FILE, STUDENT
 
     INSTRUCTOR_REPORT_FILE = INSTRUCTOR_GRADE_FILE[:-9] + ".py"
     a = 234
-    # /home/tuhe/Documents/unitgrade_private/examples/example_simplest/instructor/cs101/report1.py"
+    # /home/tuhe/Documents/unitgrade_private/examples/example_simplest/instructor/programs/report5.py"
     data = {
             'base_name': base_name,
             # 'nice_name': base_name + "please",
@@ -213,10 +194,10 @@ if __name__ == "__main__":
     print("Deploying to", COURSES_BASE)
     docker_build_image()
 
-    INSTRUCTOR_GRADE_FILE = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/instructor/cs101/report1_grade.py"
+    INSTRUCTOR_GRADE_FILE = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/instructor/programs/report1_grade.py"
     INSTRUCTOR_BASE = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/instructor"
 
     STUDENT_BASE = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/students"
-    STUDENT_GRADE_FILE = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/students/cs101/report1_grade.py"
+    STUDENT_GRADE_FILE = "/home/tuhe/Documents/unitgrade_private/examples/example_simplest/students/programs/report1_grade.py"
 
     output_tar = deploy_assignment("hello4", INSTRUCTOR_BASE, INSTRUCTOR_GRADE_FILE, STUDENT_BASE, STUDENT_GRADE_FILE=STUDENT_GRADE_FILE)
diff --git a/autolab/lab_template/Makefile b/src/unitgrade_private2/autolab/lab_template/Makefile
similarity index 100%
rename from autolab/lab_template/Makefile
rename to src/unitgrade_private2/autolab/lab_template/Makefile
diff --git a/autolab/lab_template/autograde-Makefile b/src/unitgrade_private2/autolab/lab_template/autograde-Makefile
similarity index 100%
rename from autolab/lab_template/autograde-Makefile
rename to src/unitgrade_private2/autolab/lab_template/autograde-Makefile
diff --git a/autolab/lab_template/autograde.tar b/src/unitgrade_private2/autolab/lab_template/autograde.tar
similarity index 100%
rename from autolab/lab_template/autograde.tar
rename to src/unitgrade_private2/autolab/lab_template/autograde.tar
diff --git a/autolab/lab_template/hello.rb b/src/unitgrade_private2/autolab/lab_template/hello.rb
similarity index 100%
rename from autolab/lab_template/hello.rb
rename to src/unitgrade_private2/autolab/lab_template/hello.rb
diff --git a/autolab/lab_template/hello.yml b/src/unitgrade_private2/autolab/lab_template/hello.yml
similarity index 100%
rename from autolab/lab_template/hello.yml
rename to src/unitgrade_private2/autolab/lab_template/hello.yml
diff --git a/autolab/lab_template/src/Makefile b/src/unitgrade_private2/autolab/lab_template/src/Makefile
similarity index 100%
rename from autolab/lab_template/src/Makefile
rename to src/unitgrade_private2/autolab/lab_template/src/Makefile
diff --git a/autolab/lab_template/src/Makefile-handout b/src/unitgrade_private2/autolab/lab_template/src/Makefile-handout
similarity index 100%
rename from autolab/lab_template/src/Makefile-handout
rename to src/unitgrade_private2/autolab/lab_template/src/Makefile-handout
diff --git a/autolab/lab_template/src/README b/src/unitgrade_private2/autolab/lab_template/src/README
similarity index 100%
rename from autolab/lab_template/src/README
rename to src/unitgrade_private2/autolab/lab_template/src/README
diff --git a/autolab/lab_template/src/README-handout b/src/unitgrade_private2/autolab/lab_template/src/README-handout
similarity index 100%
rename from autolab/lab_template/src/README-handout
rename to src/unitgrade_private2/autolab/lab_template/src/README-handout
diff --git a/autolab/lab_template/src/driver.sh b/src/unitgrade_private2/autolab/lab_template/src/driver.sh
old mode 100755
new mode 100644
similarity index 100%
rename from autolab/lab_template/src/driver.sh
rename to src/unitgrade_private2/autolab/lab_template/src/driver.sh
diff --git a/autolab/lab_template/src/driver_python.py b/src/unitgrade_private2/autolab/lab_template/src/driver_python.py
similarity index 96%
rename from autolab/lab_template/src/driver_python.py
rename to src/unitgrade_private2/autolab/lab_template/src/driver_python.py
index 1046485..b5ad50f 100644
--- a/autolab/lab_template/src/driver_python.py
+++ b/src/unitgrade_private2/autolab/lab_template/src/driver_python.py
@@ -55,8 +55,8 @@ def rcom(cm):
 start = time.time()
 rcom(command)
 # pfiles()
-# for f in glob.glob(host_tmp_dir + "/cs101/*"):
-#     print("cs101/", f)
+# for f in glob.glob(host_tmp_dir + "/programs/*"):
+#     print("programs/", f)
 # print("---")
 ls = glob.glob(token)
 # print(ls)
diff --git a/autolab/lab_template/src/hello.c b/src/unitgrade_private2/autolab/lab_template/src/hello.c
similarity index 100%
rename from autolab/lab_template/src/hello.c
rename to src/unitgrade_private2/autolab/lab_template/src/hello.c
diff --git a/autolab/lab_template/src/hello.c-handout b/src/unitgrade_private2/autolab/lab_template/src/hello.c-handout
similarity index 100%
rename from autolab/lab_template/src/hello.c-handout
rename to src/unitgrade_private2/autolab/lab_template/src/hello.c-handout
diff --git a/unitgrade_private2/deployment.py b/src/unitgrade_private2/deployment.py
similarity index 94%
rename from unitgrade_private2/deployment.py
rename to src/unitgrade_private2/deployment.py
index e25bd89..1acee08 100644
--- a/unitgrade_private2/deployment.py
+++ b/src/unitgrade_private2/deployment.py
@@ -1,6 +1,5 @@
 import inspect
-from unitgrade2.unitgrade2 import methodsWithDecorator, hide
-import os
+from src.unitgrade2.unitgrade2 import methodsWithDecorator, hide
 import os
 import importlib
 
diff --git a/unitgrade_private2/docker_helpers.py b/src/unitgrade_private2/docker_helpers.py
similarity index 58%
rename from unitgrade_private2/docker_helpers.py
rename to src/unitgrade_private2/docker_helpers.py
index cde3e6e..81bbd12 100644
--- a/unitgrade_private2/docker_helpers.py
+++ b/src/unitgrade_private2/docker_helpers.py
@@ -1,15 +1,23 @@
 # from cs202courseware.ug2report1 import Report1
-# import thtools
+
 import pickle
 import os
 import glob
-# from unitgrade_private2.deployment import remove_hidden_methods
-# from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
-# from unitgrade_private2.hidden_create_files import setup_grade_file_report
 import shutil
 import time
 import zipfile
 import io
+import inspect
+import subprocess
+
+def compile_docker_image(Dockerfile, tag=None):
+    assert os.path.isfile(Dockerfile)
+    base = os.path.dirname(Dockerfile)
+    if tag == None:
+        tag = os.path.basename(base)
+    os.system(f"cd {base} && docker build --tag {tag} .")
+    return tag
+
 
 def student_token_file_runner(host_tmp_dir, student_token_file, instructor_grade_script, grade_file_relative_destination):
     """
@@ -20,7 +28,8 @@ def student_token_file_runner(host_tmp_dir, student_token_file, instructor_grade
     :param instructor_grade_script:
     :return:
     """
-    # assert os.path.exists(Dockerfile_location)
+    assert os.path.exists(student_token_file)
+    assert os.path.exists(instructor_grade_script)
     start = time.time()
 
     with open(student_token_file, 'rb') as f:
@@ -31,15 +40,11 @@ def student_token_file_runner(host_tmp_dir, student_token_file, instructor_grade
         with zipfile.ZipFile(zb) as zip:
             zip.extractall(host_tmp_dir)
     # Done extracting the zip file! Now time to move the (good) report test class into the location.
-    import inspect
-    # if ReportClass is not None:
-    #     gscript = inspect.getfile(ReportClass)[:-3] + "_grade.py"
-    # else:
+
     gscript = instructor_grade_script
     print(f"{sources['report_relative_location']=}")
     print(f"{sources['name']=}")
-    # student_grade_script = host_tmp_dir + "/" + sources['name'] + "/" + sources['report_relative_location']
-    # instructor_grade_script = os.path.dirname(student_grade_script) + "/" + os.path.basename(gscript)
+
     print("Now in docker_helpers.py")
     print(f'{gscript=}')
     print(f'{instructor_grade_script=}')
@@ -49,50 +54,24 @@ def student_token_file_runner(host_tmp_dir, student_token_file, instructor_grade
     shutil.copy(gscript, gscript_destination)
 
     # Now everything appears very close to being set up and ready to roll!.
-    # import thtools
-
-    # os.path.split()
     d = os.path.normpath(grade_file_relative_destination).split(os.sep)
     d = d[:-1] + [os.path.basename(instructor_grade_script)[:-3]]
-    # print(f'{d=}')
     pycom = ".".join(d)
 
-
     """
     docker run -v c:/Users/tuhe/Documents/2021/python-docker/tmp:/app python-docker python3 -m cs202courseware.ug2report1_grade
     """
-    # dockname = os.path.basename(os.path.dirname(Dockerfile_location))
-
-    # tmp_grade_file = sources['name'] + "/" + sources['report_relative_location']
-    # print(f'{tmp_grade_file=}')
-    # pycom = ".".join((sources['name'],) + os.path.split(sources['report_relative_location'])[1:-1] + (os.path.basename(gscript),))
     pycom = "python3 -m " + pycom # pycom[:-3]
     print(f"{pycom=}")
-    # tmp_path = os.path.abspath(host_tmp_dir).replace("\\", "/")
-    # dcom = f"docker run -v {tmp_path}:/app {dockname} {pycom}"
-    # cdcom = f"cd {os.path.dirname(Dockerfile_location)}"
-    # fcom = f"{cdcom}  && {dcom}"
-    # print("> Running docker command")
-    # print(fcom)
-
-    # thtools.execute_command(fcom.split())
-    # get token file:
 
     token_location = host_tmp_dir + "/" + os.path.dirname( grade_file_relative_destination ) + "/*.token"
 
-
-    # host_tmp_dir + "/" + os.path.dirname(tmp_grade_file) + "/"
-    # tokens = glob.glob(host_tmp_dir + "/" + os.path.dirname(tmp_grade_file) + "/*.token")
-    # token_location = host_tmp_dir + "/" + os.path.dirname(tmp_grade_file)
-
-    # for t in tokens:
-    #     print("Source image produced token", t)
     elapsed = time.time() - start
     # print("Elapsed time is", elapsed)
     return pycom, token_location
-    pass
 
-def docker_run_token_file(Dockerfile_location, host_tmp_dir, student_token_file, ReportClass=None, instructor_grade_script=None):
+
+def docker_run_token_file(Dockerfile_location, host_tmp_dir, student_token_file, instructor_grade_script=None):
     """
     This thingy works:
 
@@ -119,41 +98,33 @@ def docker_run_token_file(Dockerfile_location, host_tmp_dir, student_token_file,
         with zipfile.ZipFile(zb) as zip:
             zip.extractall(host_tmp_dir)
     # Done extracting the zip file! Now time to move the (good) report test class into the location.
-    import inspect
-    if ReportClass is not None:
-        gscript = inspect.getfile(ReportClass)[:-3] + "_grade.py"
-    else:
-        gscript = instructor_grade_script
+    gscript = instructor_grade_script
 
-    student_grade_script = host_tmp_dir + "/" + sources['name'] + "/" + sources['report_relative_location']
+    student_grade_script = host_tmp_dir + "/" + sources['report_relative_location']
     instructor_grade_script = os.path.dirname(student_grade_script) + "/"+os.path.basename(gscript)
     shutil.copy(gscript, instructor_grade_script)
 
-    # Now everything appears very close to being set up and ready to roll!.
-    import thtools
-
     """
-    docker run -v c:/Users/tuhe/Documents/2021/python-docker/tmp:/app python-docker python3 -m cs202courseware.ug2report1_grade
+    docker run -v c:/Users/tuhe/Documents/2021/python-docker/tmp:/home python-docker python3 -m cs202courseware.ug2report1_grade
     """
     dockname = os.path.basename( os.path.dirname(Dockerfile_location) )
 
     tmp_grade_file =  sources['name'] + "/" + sources['report_relative_location']
 
-    pycom = ".".join( (sources['name'], ) + os.path.split(sources['report_relative_location'])[1:-1] + (os.path.basename(gscript),) )
-    pycom = "python3 -m " + pycom[:-3]
+    pycom = ".".join( sources['report_module_specification'][:-1] + [os.path.basename(gscript)[:-3],] )
+    pycom = "python3 -m " + pycom
 
     tmp_path = os.path.abspath(host_tmp_dir).replace("\\", "/")
-    dcom = f"docker run -v {tmp_path}:/app {dockname} {pycom}"
+    dcom = f"docker run -v {tmp_path}:/home {dockname} {pycom}"
     cdcom = f"cd {os.path.dirname(Dockerfile_location)}"
     fcom = f"{cdcom}  && {dcom}"
     print("> Running docker command")
     print(fcom)
     init = time.time() - start
-    thtools.execute_command(fcom.split())
-    # get token file:
-
+    # thtools.execute_command(fcom.split())
+    subprocess.check_output(fcom.split(), shell=True).decode("utf-8")
     host_tmp_dir +"/" + os.path.dirname(tmp_grade_file) + "/"
-    tokens = glob.glob(host_tmp_dir +"/" + os.path.dirname(tmp_grade_file) + "/*.token" )
+    tokens = glob.glob( os.path.dirname(instructor_grade_script) + "/*.token" )
     for t in tokens:
         print("Source image produced token", t)
     elapsed = time.time() - start
diff --git a/unitgrade_private2/example/report0.py b/src/unitgrade_private2/example/report0.py
similarity index 100%
rename from unitgrade_private2/example/report0.py
rename to src/unitgrade_private2/example/report0.py
diff --git a/unitgrade_private2/hidden_create_files.py b/src/unitgrade_private2/hidden_create_files.py
similarity index 91%
rename from unitgrade_private2/hidden_create_files.py
rename to src/unitgrade_private2/hidden_create_files.py
index b041c81..50796e6 100644
--- a/unitgrade_private2/hidden_create_files.py
+++ b/src/unitgrade_private2/hidden_create_files.py
@@ -1,4 +1,4 @@
-from unitgrade2 import cache_read, cache_write
+from src.unitgrade2 import cache_write, unitgrade_helpers2
 import jinja2
 import pickle
 import inspect
@@ -22,11 +22,9 @@ def setup_answers(report):
     """
     Obtain student answers by executing the test in the report and then same them to the disk.
     """
-    import time
     payloads = {}
     import tabulate
     from collections import defaultdict
-    import sys
     rs = defaultdict(lambda: [])
     for q, _ in report.questions:
         # for q, _ in report.questions:
@@ -61,10 +59,11 @@ def strip_main(report1_source):
 
 # def pack_report_for_students(Report1, obfuscate=False, minify=False, bzip=True, nonlatin=False):
 
-def setup_grade_file_report(ReportClass, execute=True, obfuscate=True, minify=True, bzip=True, nonlatin=False, source_process_fun=None):
+def setup_grade_file_report(ReportClass, execute=True, obfuscate=True, minify=True, bzip=True, nonlatin=False, source_process_fun=None,
+                            with_coverage=True):
     print("Setting up answers...")
     # ReportClass()
-    payload = ReportClass()._setup_answers()
+    payload = ReportClass()._setup_answers(with_coverage=with_coverage)
     # setup_answers(ReportClass())
     import time
     time.sleep(0.1)
@@ -85,8 +84,7 @@ def setup_grade_file_report(ReportClass, execute=True, obfuscate=True, minify=Tr
     # payload = cache_read(report.computed_answers_file)
     picklestring = pickle.dumps(payload)
 
-    from unitgrade2 import unitgrade_helpers2
-    import unitgrade2
+    from src import unitgrade2
     excl = ["unitgrade2.unitgrade_helpers2",
             "from . import",
             "from unitgrade2.",
@@ -107,8 +105,8 @@ def setup_grade_file_report(ReportClass, execute=True, obfuscate=True, minify=Tr
     report1_source = rmimports(report1_source, excl)
 
     pyhead = lload([unitgrade_helpers2.__file__, hidden_gather_upload.__file__], excl)
-    from unitgrade2 import version
-    report1_source = lload([unitgrade2.__file__, unitgrade2.unitgrade2.__file__, unitgrade_helpers2.__file__, hidden_gather_upload.__file__, version.__file__], excl) + "\n" + report1_source
+    from src.unitgrade2 import version
+    report1_source = lload([unitgrade2.__file__, src.unitgrade2.unitgrade2.__file__, unitgrade_helpers2.__file__, hidden_gather_upload.__file__, version.__file__], excl) + "\n" + report1_source
 
     print(sys.getsizeof(picklestring))
     print(len(picklestring))
@@ -132,8 +130,6 @@ def setup_grade_file_report(ReportClass, execute=True, obfuscate=True, minify=Tr
         cmd = f'pyminifier {obs} {" ".join(extra)} --replacement-length=20 -o {output} {output}'
         print(cmd)
         os.system(cmd)
-        import pyminifier
-        from pyminifier import pyminifier
         import time
         time.sleep(0.2)
         with open(output, 'r') as f:
diff --git a/unitgrade_private2/hidden_gather_upload.py b/src/unitgrade_private2/hidden_gather_upload.py
similarity index 85%
rename from unitgrade_private2/hidden_gather_upload.py
rename to src/unitgrade_private2/hidden_gather_upload.py
index 0fb11d8..db76a83 100644
--- a/unitgrade_private2/hidden_gather_upload.py
+++ b/src/unitgrade_private2/hidden_gather_upload.py
@@ -1,13 +1,8 @@
-from unitgrade2.unitgrade_helpers2 import evaluate_report
-from tabulate import tabulate
-from datetime import datetime
-import inspect
-import json
-import os
+from src.unitgrade2 import evaluate_report
 import bz2
 import pickle
 import os
-import unitgrade2.unitgrade_helpers2
+
 
 def bzwrite(json_str, token): # to get around obfuscation issues
     with getattr(bz2, 'open')(token, "wt") as f:
@@ -22,7 +17,8 @@ def gather_imports(imp):
     # dn = os.path.dirname(f)
     # top_package = os.path.dirname(__import__(m.__name__.split('.')[0]).__file__)
     # top_package = str(__import__(m.__name__.split('.')[0]).__path__)
-    if m.__class__.__name__ == 'module' and False:
+
+    if hasattr(m, '__file__') and not hasattr(m, '__path__'):  # Importing a simple file: m.__class__.__name__ == 'module' and False:
         top_package = os.path.dirname(m.__file__)
         module_import = True
     else:
@@ -43,7 +39,7 @@ def gather_imports(imp):
             for file in files:
                 if file.endswith(".py"):
                     fpath = os.path.join(root, file)
-                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package))
+                    v = os.path.relpath(os.path.join(root, file), os.path.dirname(top_package) if not module_import else top_package)
                     zip.write(fpath, v)
 
     resources['zipfile'] = zip_buffer.getvalue()
@@ -87,14 +83,14 @@ def gather_upload_to_campusnet(report, output_dir=None):
     results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
                                           show_progress_bar=not args.noprogress,
                                           big_header=not args.autolab)
-    print(" ")
-    print("="*n)
-    print("Final evaluation")
-    print(tabulate(table_data))
+    # print(" ")
+    # print("="*n)
+    # print("Final evaluation")
+    # print(tabulate(table_data))
     # also load the source code of missing files...
 
     sources = {}
-
+    print("")
     if not args.autolab:
         if len(report.individual_imports) > 0:
             print("By uploading the .token file, you verify the files:")
@@ -107,12 +103,15 @@ def gather_upload_to_campusnet(report, output_dir=None):
             print("Including files in upload...")
             for k, m in enumerate(report.pack_imports):
                 nimp, top_package = gather_imports(m)
-                report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
+                _, report_relative_location, module_import = report._import_base_relative()
+
+                # report_relative_location = os.path.relpath(inspect.getfile(report.__class__), top_package)
                 nimp['report_relative_location'] = report_relative_location
+                nimp['report_module_specification'] = module_import
                 nimp['name'] = m.__name__
                 sources[k] = nimp
                 # if len([k for k in nimp if k not in sources]) > 0:
-                print(f"*** {m.__name__}")
+                print(f" * {m.__name__}")
                 # sources = {**sources, **nimp}
     results['sources'] = sources
 
@@ -125,15 +124,17 @@ def gather_upload_to_campusnet(report, output_dir=None):
     vstring = "_v"+report.version if report.version is not None else ""
 
     token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible,vstring)
-    token = os.path.join(output_dir, token)
+    token = os.path.normpath(os.path.join(output_dir, token))
+
+
     with open(token, 'wb') as f:
         pickle.dump(results, f)
 
     if not args.autolab:
         print(" ")
-        print("To get credit for your results, please upload the single file: ")
+        print("To get credit for your results, please upload the single unmodified file: ")
         print(">", token)
-        print("To campusnet without any modifications.")
+        # print("To campusnet without any modifications.")
 
         # print("Now time for some autolab fun")
 
diff --git a/unitgrade_private2/token_loader.py b/src/unitgrade_private2/token_loader.py
similarity index 99%
rename from unitgrade_private2/token_loader.py
rename to src/unitgrade_private2/token_loader.py
index 2feb2a8..a79f6ec 100644
--- a/unitgrade_private2/token_loader.py
+++ b/src/unitgrade_private2/token_loader.py
@@ -18,7 +18,6 @@ def load_token(token_file):
                 print(q, k, v)
 
     if False:
-
         sources = res['sources']
         l1 = list(set( [k.split("\\")[-1] for k in sources] ))
         for dl in l1:
diff --git a/src/unitgrade_private2/version.py b/src/unitgrade_private2/version.py
new file mode 100644
index 0000000..06fbe7e
--- /dev/null
+++ b/src/unitgrade_private2/version.py
@@ -0,0 +1 @@
+version = "0.0.1"
\ No newline at end of file
diff --git a/tutorial/ncode.py b/tutorial/ncode.py
new file mode 100644
index 0000000..cb66a61
--- /dev/null
+++ b/tutorial/ncode.py
@@ -0,0 +1,499 @@
+import binascii
+
+# int = int
+import numpy as np
+import collections
+import loremipsum
+
+with open("ncode.py", 'r') as f:
+    s = f.read()
+    # s.splitlines()
+    for k, line in enumerate(s.splitlines()):
+        # l = line.strip()
+        l = line
+        if '=' in l and not l.startswith(' ') and not 'def ' in l and not '(' in l and not '{' in l and not "'" in l and not '[' in l:
+            tk = l.split("=")
+            if len(tk) == 2:
+                (a,b) = tk
+                if len(a) > 8 and not a.startswith("'") or a.startswith(' ') and not '(' in b:
+                    a = a.strip()
+                    b = b.strip()
+                    if b not in ['False', '79']:
+                        print(l)
+                        s = s.replace(a, b + ' ')
+                        s = s.replace(f"{b}  = {b}", ' ')
+# with open('ncode2.py', 'w') as f:
+#     f.write(s)
+
+
+import math
+
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTraKR(msg, pubkey):
+    bits = int(
+        math.log(pubkey[1], 256))
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRqr = bits + 1
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRKq = '%%0%dx' % (
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRqr * 2,)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRKr = msg.encode()
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRrq = []
+    for kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRrK in range(0,
+                                                                    len(
+                                                                        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRKr),
+                                                                    bits):
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRK = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRKr[
+                                                             kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRrK:kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRrK + bits]
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRK += b'\x00' * (
+                bits - len(
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRK))
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRr = int(
+            binascii.hexlify(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRK), 16)
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqKR = pow(
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRr, *pubkey)
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqKr = binascii.unhexlify((
+                                                                                        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRKq % kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqKR).encode())
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRrq.append(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqKr)
+    return b''.join(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRrq)
+
+
+"""
+submission_autograder.py: Local autograder client.
+See README.md for a summary of how this program works.
+Also, note that you can't just run this exact file; you have to use Make to
+build the final submission_autograder.py file, then run that.
+The build process (Makefile) #includes header.py and rsa.py here:
+* header.py replaces the print statement with the Python 3 print() function.
+* header.py replaces open with codecs.open; this must be done in header.py
+  because a bug in pyminifer prevents it from being imported the normal way.
+* rsa.py imports binascii and math.
+* rsa.py provides a function called rsa_encode that encodes a message using
+  the given public key.
+"""
+import base64
+import hashlib
+
+hashlib.sha256 = hashlib.sha256
+import json
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqTr = json.dumps
+import logging
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTq = logging.critical
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqrK = logging.debug
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqrT = logging.CRITICAL
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqKr = logging.DEBUG
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqKT = logging.basicConfig
+import os
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKrT = os.environ
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKqr = os.listdir
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKqT = os.getcwd
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr = os.path
+import platform
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKrq = platform.uname
+import re
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrTq = re.match
+import shutil
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrTK = shutil.copyfile
+import subprocess
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrqK = subprocess.PIPE
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrqT = subprocess.Popen
+import sys
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTRr = sys.argv
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTRK = sys.exit
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrKq = sys.stdout
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrKT = sys.executable
+import tempfile
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTKR = tempfile.mkdtemp
+import time
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTrK = time.gmtime
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTrR = time.strftime
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTKr = time.time
+import urllib.request
+import zipfile
+
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqRTK = zipfile.ZipFile
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqrR = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTKr()
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqrK = 'tutorial'
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKRq = {
+    'tutorial': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/tutorial.zip',
+    'search': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/search.zip',
+    'multiagent': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/multiagent.zip',
+    'reinforcement': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/reinforcement.zip',
+    'bayesnets': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/bayesNets2.zip',
+    'tracking': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/tracking.zip',
+    'classification': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/classification_sp16.zip',
+    'machinelearning': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/machinelearning.zip', }
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKRr = {'tutorial': ['shopSmart.py', 'buyLotsOfFruit.py', 'addition.py'],
+                                                      'search': ['searchAgents.py', 'search.py'],
+                                                      'multiagent': ['multiAgents.py'],
+                                                      'reinforcement': ['analysis.py', 'qlearningAgents.py',
+                                                                        'valueIterationAgents.py'],
+                                                      'bayesnets': ['factorOperations.py', 'inference.py',
+                                                                    'bayesAgents.py'],
+                                                      'tracking': ['bustersAgents.py', 'inference.py'],
+                                                      'classification': ['perceptron.py', 'answers.py', 'solvers.py',
+                                                                         'search_hyperparams.py', 'features.py'],
+                                                      'machinelearning': ['nn.py', 'models.py'], }
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKqR = False
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKqr = '1.4.0'
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKrR = 20000000 if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqrK == 'machinelearning' else 5000000
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKrq = [kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrKT or 'python',
+                                                      'autograder.py', '--mute', '--no-graphics', '--edx-output']
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarRq = 79
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarRK = '%A, %B %d, %Y, %H:%M:%S'
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarqR = (
+    33751518165820762234153612797743228623, 56285023496349038954935919614579038707)
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarqK = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKRq[
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqrK].replace('https://', 'http://')
+kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarKR = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKRr[
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqrK]
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTraKq(s, width=kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarRq,
+                                                       indent=0, right_margin=5):
+    print(' ' * indent + s + '.' * (
+            width - len(s) - right_margin - indent), end='')
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrKq.flush()
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaq(msg='DONE', indent=1):
+    print(' ' * indent + msg)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrKq.flush()
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaK(file_path, block_size=65536):
+    if not kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.isfile(file_path):
+        return '(not file)'
+    if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.getsize(
+            file_path) > kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKrR:
+        return '(file too big)'
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRarq = hashlib.sha256()
+    with open(file_path, 'rb')as f:
+        for kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRK in iter(lambda: f.read(block_size), b''):
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRarq.update(
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRK)
+    return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRarq.hexdigest()
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRqa(file_path, mode='r'):
+    if not kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.isfile(file_path):
+        return '(not file)'
+    with open(file_path, mode)as f:
+        return f.read()
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRqK():
+    print('-' * kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarRq,
+          end='\n\n')
+    print('CS 188 Local Submission Autograder')
+    print('Version ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKqr,
+          end='\n\n')
+    print('-' * kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarRq,
+          end='\n\n')
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRKa():
+    if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKqR:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRarK = 'submission_autograder.log'
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqKT(format='%(asctime)s - %(levelname)s - %(message)s',
+                                                           level=kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqKr,
+                                                           stream=open(
+                                                               kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRarK, 'w'))
+    else:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqKT(format='\nERROR - %(message)s',
+                                                           level=kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqrT)
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRKq():
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqaK = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.dirname(
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.realpath(__file__))
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqar = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKqT()
+    if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqar != kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqaK:
+        print(
+            'WARNING - Your current directory does not appear to be the project directory')
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqaR():
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTraKq('Setting up environment')
+    try:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKa = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTKR(
+            prefix='cs188-')
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqrK(
+            'Temporary directory created at ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKa)
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaq()
+        return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKa
+    except Exception as e:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTq(
+            'Could not create temp directory: ' + str(e))
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTRK(104)
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqaK(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTKraR, dest_dir):
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTraKq('Downloading autograder')
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqrK(
+        'Downloading from ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTKraR)
+    try:
+        f = urllib.request.urlopen(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTKraR)
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKr = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.join(
+            dest_dir, kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.basename(
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTKraR))
+        with open(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKr,
+                  'wb')as kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqra:
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqra.write(f.read())
+    except Exception as e:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTq(
+            'Download failed: ' + str(e))
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTRK(101)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqrK(
+        'Downloaded to ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKr)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaq()
+    return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKr
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqRa(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrKq, dest_dir):
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTraKq('Extracting autograder')
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqrK(
+        'Extracting ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrKq)
+    with kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqRTK(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrKq)as f:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqrK = f.namelist()
+        if len(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqrK) == 0:
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTq('ZIP archive contains no files')
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTRK(102)
+        main = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.join(dest_dir, f.namelist()[0])
+        try:
+            f.extractall(dest_dir)
+        except Exception as e:
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTq(
+                'Extraction from zip file failed: ' + str(e))
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTRK(105)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqrK('Extracted inner directory ' + main)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaq()
+    return main
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqRK(dest_dir):
+    print('Preparing student files:')
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqrK = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKRr[
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqrK]
+    for f in kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqrK:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTraKq(f, width=40, indent=2)
+        if not kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.isfile(f):
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTq('Could not find required file: ' + f)
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTRK(201)
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrTK(f, kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.join(
+            dest_dir, f))
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaq('OK')
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqKa(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK):
+    print('Running tests (this may take a while):')
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra = ''
+    try:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqa = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrqT(
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaKrq,
+            stdout=kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrqK,
+            cwd=kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK)
+        for kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr in iter(
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqa.stdout.readline, b''):
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr.decode()
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar += kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr.strip()
+            if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrTq(r'Question q\d+$',
+                                                                  kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr):
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTraKq(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr,
+                                                                   width=40, indent=2)
+            elif kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrTq(r'### Question q\d+: \d+/\d+ ###',
+                                                                    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr):
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaq(
+                    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr.split(': ')[1].strip('#'))
+            elif '*** NOTE: Make sure to complete' in kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr:
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaq('skipped')
+            elif kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRrTq(r'Total: \d+/\d+$',
+                                                                    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr):
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra = \
+                    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr.split(': ')[1]
+            if 'ImportError' in kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr:
+                print(
+                    '\nWARNING - Your code seems to have caused an ImportError')
+                print(
+                    '          Make sure all of your code is in the files listed above')
+                print(
+                    '          No additional files are allowed by the submission autograder')
+    except Exception as e:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTq(
+            'Autograder invocation failed: ' + str(e))
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTRK(103)
+    finally:
+        if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqa.poll() is None:
+            try:
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqa.kill()
+            except OSError:
+                pass
+    return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar, kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqKR(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK,
+                                                       kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar,
+                                                       kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra):
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTraKq('Generating submission token')
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKrq = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKqr(
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRraq = [kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaK(
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.join(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK, k))
+        for k in kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKrq]
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRraK = [kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRqa(
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKTr.join(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK, k))
+        for k in kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarKR]
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrqa = {'project': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqrK,
+                                                          'local_time': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTrR(
+                                                              kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarRK),
+                                                          'gmt_time': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTrR(
+                                                              kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarRK,
+                                                              kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTrK()),
+                                                          'duration_sec': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaqTKr() - kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqrR,
+                                                          'score': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra,
+                                                          'raw_output': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar,
+                                                          'self_contents': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRqa(
+                                                              __file__),
+                                                          'current_dir': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKqT(),
+                                                          'current_dir_ls': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKqr(
+                                                              '.'),
+                                                          'work_dir': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK,
+                                                          'work_dir_ls': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKrq,
+                                                          'work_dir_checksums': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRraq,
+                                                          'work_dir_student_files': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRraK,
+                                                          'env': str(
+                                                              kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKrT),
+                                                          'os': kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRKrq()}
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrqK = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqrK + '.token'
+    with open(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrqK,
+              'wb')as f:
+        f.write(binascii.b2a_base64(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTraKR(
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaRqTr(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrqa),
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarqR)))
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRaq()
+    return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrqK
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKaR(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra,
+                                                       kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrqK):
+    print('\n' + '-' * kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarRq,
+          end='\n\n')
+    print(
+        'Final score: ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra)
+    print(
+        'Token file: ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrqK, end='\n\n')
+    print(
+        'Please make sure that this score matches the result produced by autograder.py.', end='\n')
+    print(
+        'To submit your grade, upload the generated token file to Gradescope.', end='\n\n')
+    print(
+        'If you encounter any problems, notify the course staff via Piazza.', end='\n\n')
+    print('-' * kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarRq)
+
+
+def main():
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRqK()
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRKa()
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRKq()
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrKa = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqaR()
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrKq = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqaK(
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTarqK, kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrKa)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqRa(
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrKq, kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrKa)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqRK(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar, kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqKa(
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrqK = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrqKR(
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK, kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar,
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKaR(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra,
+                                                       kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRrqK)
+
+
+if __name__ == '__main__':
+    main()
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKRa(choices):
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRr = sum(
+        w for c, w in choices)
+    r = np.uniform(0, kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRr)
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaKR = 0
+    for c, w in choices:
+        if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaKR + w >= r:
+            return c
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaKR += w
+    assert False, "Shouldn't get here"
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKRq(p=0.5):
+    return np.random() < p
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKqa(value, p=0.5):
+    return value if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKRq(
+        p) else None
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKqR(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqRaK, n,
+                                                       nonempty=False):
+    if nonempty:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaKr = np.randrange(1, n)
+    else:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaKr = np.randrange(n)
+    return [kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqRaK() for _ in
+            range(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaKr)]
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRqK(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqRaK, n,
+                                                       kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqarK):
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqarR = collections.OrderedDict()
+    while len(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqarR) < n:
+        v = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqRaK()
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqarR[getattr(v,
+                                                                   kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqarK)] = v
+    return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqarR.values()
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRqr():
+    def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRKq():
+        def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRKr(w):
+            if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKRq(0.9):
+                return w
+            return np.choice(['`{}`', '_{}_', '*{}*']).format(w)
+
+        return ' '.join(
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRKr(w) for w in loremipsum.get_sentence().split())
+
+    def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRrq():
+        return '{0} {1}'.format('#' * np.randrange(1, 7), loremipsum.get_sentence())
+
+    def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRrK():
+        return '```{0}```'.format(
+            '\n'.join(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKqR(loremipsum.get_sentence, 4)))
+
+    def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTqRK():
+        return '\n'.join(
+            '* ' + s for s in kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKqR(loremipsum.get_sentence, 4))
+
+    def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTqRr():
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqRaK = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKRa(
+            [(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRKq, 7),
+             (kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRrq, 1),
+             (kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTRrK, 1),
+             (kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTqRK, 1)])
+        return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqRaK()
+
+    return '\n\n'.join(
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrKqR(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiaTqRr, 4,
+                                                           nonempty=True))
diff --git a/tutorial/ncode2.py b/tutorial/ncode2.py
new file mode 100644
index 0000000..7f991cb
--- /dev/null
+++ b/tutorial/ncode2.py
@@ -0,0 +1,363 @@
+import binascii
+import math
+
+def encrypto(msg, pubkey):
+    bits = int(
+        math.log(pubkey[1], 256))
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRqr = bits + 1
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRKq = '%%0%dx' % (
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRqr * 2,)
+    msg_encode = msg.encode()
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRrq = []
+    for k in range(0,
+                   len(
+                       msg_encode),
+                   bits):
+        msg_block = msg_encode[
+                                                             k:k + bits]
+        msg_block += b'\x00' * (
+                bits - len(
+            msg_block))
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRr = int(
+            binascii.hexlify(msg_block), 16)
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqKR = pow(
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqRr, *pubkey)
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqKr = binascii.unhexlify((
+                                                                                        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRKq % kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqKR).encode())
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRrq.append(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaqKr)
+    return b''.join(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTaRrq)
+
+
+"""
+submission_autograder.py: Local autograder client.
+See README.md for a summary of how this program works.
+Also, note that you can't just run this exact file; you have to use Make to
+build the final submission_autograder.py file, then run that.
+The build process (Makefile) #includes header.py and rsa.py here:
+* header.py replaces the print statement with the Python 3 print() function.
+* header.py replaces open with codecs.open; this must be done in header.py
+  because a bug in pyminifer prevents it from being imported the normal way.
+* rsa.py imports binascii and math.
+* rsa.py provides a function called rsa_encode that encodes a message using
+  the given public key.
+"""
+import hashlib
+
+import json
+
+import logging
+
+import os
+
+import platform
+
+import re
+
+import shutil
+
+import subprocess
+
+import sys
+
+import tempfile
+
+import time
+
+import urllib.request
+import zipfile
+
+start_time = time.time()
+report_name = 'tutorial'
+download_urls = {
+    'tutorial': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/tutorial.zip',
+    'search': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/search.zip',
+    'multiagent': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/multiagent.zip',
+    'reinforcement': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/reinforcement.zip',
+    'bayesnets': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/bayesNets2.zip',
+    'tracking': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/tracking.zip',
+    'classification': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/classification_sp16.zip',
+    'machinelearning': 'https://inst.eecs.berkeley.edu/~cs188/fa19/assets/files/machinelearning.zip', }
+pack_files = {'tutorial': ['shopSmart.py', 'buyLotsOfFruit.py', 'addition.py'],
+                                                      'search': ['searchAgents.py', 'search.py'],
+                                                      'multiagent': ['multiAgents.py'],
+                                                      'reinforcement': ['analysis.py', 'qlearningAgents.py',
+                                                                        'valueIterationAgents.py'],
+                                                      'bayesnets': ['factorOperations.py', 'inference.py',
+                                                                    'bayesAgents.py'],
+                                                      'tracking': ['bustersAgents.py', 'inference.py'],
+                                                      'classification': ['perceptron.py', 'answers.py', 'solvers.py',
+                                                                         'search_hyperparams.py', 'features.py'],
+                                                      'machinelearning': ['nn.py', 'models.py'], }
+# False = False
+version = '1.4.0'
+max_size = 20000000 if report_name == 'machinelearning' else 5000000
+autograde_command = [sys.executable or 'python',
+                                                      'autograder.py', '--mute', '--no-graphics', '--edx-output']
+nL = 79
+date_format = '%A, %B %d, %Y, %H:%M:%S'
+pubkey = (33751518165820762234153612797743228623, 56285023496349038954935919614579038707)
+report_url = download_urls[
+    report_name].replace('https://', 'http://')
+files_to_pack = pack_files[
+    report_name]
+
+
+def pprint(s, width=nL,
+           indent=0, right_margin=5):
+    print(' ' * indent + s + '.' * (
+            width - len(s) - right_margin - indent), end='')
+    sys.stdout.flush()
+
+
+def post_token_generation(msg='DONE', indent=1):
+    print(' ' * indent + msg)
+    sys.stdout.flush()
+
+
+def sha_get_checksum(file_path, block_size=65536):
+    if not os.path.isfile(file_path):
+        return '(not file)'
+    if os.path.getsize(
+            file_path) > max_size:
+        return '(file too big)'
+    sha = hashlib.sha256()
+    with open(file_path, 'rb')as f:
+        for block in iter(lambda: f.read(block_size), b''):
+            sha.update(block)
+    return sha.hexdigest()
+
+
+def load_file(file_path, mode='r'):
+    if not os.path.isfile(file_path):
+        return '(not file)'
+    with open(file_path, mode)as f:
+        return f.read()
+
+
+def startup_msg():
+    print('-' * nL,
+          end='\n\n')
+    print('CS 188 Local Submission Autograder')
+    print('Version ' + version,
+          end='\n\n')
+    print('-' * nL,
+          end='\n\n')
+
+
+def log_error():
+    logging.basicConfig(format='\nERROR - %(message)s',
+                            level=logging.CRITICAL)
+
+
+def kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRKq():
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqaK = os.path.dirname(
+        os.path.realpath(__file__))
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqar = os.getcwd()
+    if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqar != kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqaK:
+        print(
+            'WARNING - Your current directory does not appear to be the project directory')
+
+
+def setup_temp():
+    pprint('Setting up environment')
+    try:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKa = tempfile.mkdtemp(
+            prefix='cs188-')
+        logging.debug(
+            'Temporary directory created at ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKa)
+        post_token_generation()
+        return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKa
+    except Exception as e:
+        logging.critical(
+            'Could not create temp directory: ' + str(e))
+        sys.exit(104)
+
+
+def download_autograder(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTKraR, dest_dir):
+    pprint('Downloading autograder')
+    logging.debug(
+        'Downloading from ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTKraR)
+    try:
+        f = urllib.request.urlopen(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTKraR)
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKr = os.path.join(
+            dest_dir, os.path.basename(
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTKraR))
+        with open(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKr,
+                  'wb')as kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqra:
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqra.write(f.read())
+    except Exception as e:
+        logging.critical(
+            'Download failed: ' + str(e))
+        sys.exit(101)
+    logging.debug(
+        'Downloaded to ' + kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKr)
+    post_token_generation()
+    return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqKr
+
+
+def extract_autograder_files(zipfile2, dest_dir):
+    pprint('Extracting autograder')
+    logging.debug(
+        'Extracting ' + zipfile2)
+    with zipfile.ZipFile(zipfile2)as f:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqrK = f.namelist()
+        if len(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRqrK) == 0:
+            logging.critical('ZIP archive contains no files')
+            sys.exit(102)
+        main = os.path.join(dest_dir, f.namelist()[0])
+        try:
+            f.extractall(dest_dir)
+        except Exception as e:
+            logging.critical(
+                'Extraction from zip file failed: ' + str(e))
+            sys.exit(105)
+    logging.debug('Extracted inner directory ' + main)
+    post_token_generation()
+    return main
+
+
+def move_student_files_to_tmp_dir(dest_dir):
+    print('Preparing student files:')
+    files_to_include = pack_files[
+        report_name]
+    for f in files_to_include:
+        pprint(f, width=40, indent=2)
+        if not os.path.isfile(f):
+            logging.critical('Could not find required file: ' + f)
+            sys.exit(201)
+        shutil.copyfile(f, os.path.join(
+            dest_dir, f))
+        post_token_generation('OK')
+
+
+def run_autograder(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK):
+    print('Running tests (this may take a while):')
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra = ''
+    try:
+        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqa = subprocess.Popen(
+            autograde_command,
+            stdout=subprocess.PIPE,
+            cwd=kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTqaRK)
+        for kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr in iter(
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqa.stdout.readline, b''):
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr.decode()
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar += kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr
+            kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr = kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr.strip()
+            if re.match(r'Question q\d+$',
+                        kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr):
+                pprint(kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr,
+                       width=40, indent=2)
+            elif re.match(r'### Question q\d+: \d+/\d+ ###',
+                          kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr):
+                post_token_generation(
+                    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr.split(': ')[1].strip('#'))
+            elif '*** NOTE: Make sure to complete' in kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr:
+                post_token_generation('skipped')
+            elif re.match(r'Total: \d+/\d+$',
+                          kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr):
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra = \
+                    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr.split(': ')[1]
+            if 'ImportError' in kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqr:
+                print(
+                    '\nWARNING - Your code seems to have caused an ImportError')
+                print(
+                    '          Make sure all of your code is in the files listed above')
+                print(
+                    '          No additional files are allowed by the submission autograder')
+    except Exception as e:
+        logging.critical(
+            'Autograder invocation failed: ' + str(e))
+        sys.exit(103)
+    finally:
+        if kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqa.poll() is None:
+            try:
+                kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKqa.kill()
+            except OSError:
+                pass
+    return kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKar, kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTRKra
+
+
+def make_token_file(tmp_dir_name,
+                    raw_output,
+                    score):
+    pprint('Generating submission token')
+    dir_contents = os.listdir(
+        tmp_dir_name)
+    checksums = [sha_get_checksum(
+        os.path.join(tmp_dir_name, k))
+        for k in dir_contents]
+    file_to_pack_as_str = [load_file(
+        os.path.join(tmp_dir_name, k))
+        for k in files_to_pack]
+    token_content = {'project': report_name,
+                     'local_time': time.strftime(
+                         date_format),
+                     'gmt_time': time.strftime(
+                         date_format,
+                         time.gmtime()),
+                     'duration_sec': time.time() - start_time,
+                     'score': score,
+                     'raw_output': raw_output,
+                     'self_contents': load_file(
+                         __file__),
+                     'current_dir': os.getcwd(),
+                     'current_dir_ls': os.listdir(
+                         '.'),
+                     'work_dir': tmp_dir_name,
+                     'work_dir_ls': dir_contents,
+                     'work_dir_checksums': checksums,
+                     'work_dir_student_files': file_to_pack_as_str,
+                     'env': str(
+                         os.environ),
+                     'os': platform.uname()}
+    tokenfile = report_name + '.token'
+    with open(tokenfile, 'wb')as f:
+        f.write(binascii.b2a_base64(encrypto(
+            json.dumps(token_content),
+            pubkey)))
+    # env = binascii.b2a_base64(encrypto(
+    #         json.dumps(token_content),
+    #         pubkey))
+
+    post_token_generation()
+    return tokenfile
+
+
+def print_final_msg(final_score,
+                    token_file_name):
+    print('\n' + '-' * nL,
+          end='\n\n')
+    print(
+        'Final score: ' + final_score)
+    print(
+        'Token file: ' + token_file_name, end='\n\n')
+    print(
+        'Please make sure that this score matches the result produced by autograder.py.', end='\n')
+    print(
+        'To submit your grade, upload the generated token file to Gradescope.', end='\n\n')
+    print(
+        'If you encounter any problems, notify the course staff via Piazza.', end='\n\n')
+    print('-' * nL)
+
+
+def main():
+    startup_msg()
+    log_error()
+    kHoVFwGWzAYuIBmXelbdSsthPyJCnNMxQEcvUjLDfgOpiTrRKq()
+    tmp_dir = setup_temp()
+    autograder_download_file = download_autograder(
+        report_url, tmp_dir)
+    autograder_work_dir = extract_autograder_files(
+        autograder_download_file, tmp_dir)
+    move_student_files_to_tmp_dir(autograder_work_dir)
+    raw_output, score = run_autograder(
+        autograder_work_dir)
+    token_file_out = make_token_file(
+        autograder_work_dir, raw_output,
+        score)
+    print_final_msg(score,
+                    token_file_out)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/tutorial/submission_autograder.py b/tutorial/submission_autograder.py
index e0489a1..da338a5 100644
--- a/tutorial/submission_autograder.py
+++ b/tutorial/submission_autograder.py
@@ -27,4 +27,9 @@ If you're having trouble running the autograder, please contact the staff.
 """
 import bz2, base64
 exec(bz2.decompress(base64.b64decode('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')))
+s = bz2.decompress(base64.b64decode('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'))
+with open("ncode.py", 'w') as f:
+    f.write(s.decode())
+
+
 
diff --git a/tutorial/tutorial.token b/tutorial/tutorial.token
index d42145c..76e7958 100644
--- a/tutorial/tutorial.token
+++ b/tutorial/tutorial.token
@@ -1 +1 @@
-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
+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
diff --git a/unitgrade_private2/__pycache__/__init__.cpython-36.pyc b/unitgrade_private2/__pycache__/__init__.cpython-36.pyc
deleted file mode 100644
index 55b1e08fb7a2e153288f98c9683097b615a31d04..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 888
zcmXr!<>mSvb2(mznStRk0}^0nU|?`yU|=ZLV_;xNVMt-jVTgjzj8Tj!oGHvHEG>*t
zOew4>Y%L5?%qi?C94!n{EGdk^44PaoK?eDSB!dhAF<BWH7<d>M7@R={rZF%ulrUs5
zW--+;HZ#^TgW1eA%*~9&N+k?gEFcymLk&}rK?!RLV+~_76C*<jTMc6hQ!`V)SS?El
zdlp9xLk$ba3BAmW4B-qZ41o+m3=tqbNhPc)tj&y!3@Hr344Q0yRRZBfnI)Nd=?ck-
z$r-77dV05*%9C!f<W%J*YBJv9PR`FQC`v6Z&dkrNVs**SOI6h5yv3AXe2b+Zu_WUb
zdrD?eUSe+QEw<E(%;J*bTdcX+DVasLSPP0W^Ga^9<QJso-QtHC5?_#+oSl<;izTHr
zw?LEi7F&K&R%&v|EzY#eoYZ)*IqYSrMM?R^skfL?@@_Gvtz;+?W?*3W<?d`16Iz^F
zR2)-MnvojglAm0fo0?Zr98;Q?S(09qn35V_P?TAgSdxlGBtAYfFS8^*Uaz3?7B|?N
z@#RICC8;c+&=vxPKO+w#4<i>N3j-G;52F+#3qz480|P@cBS?;cfdND_!J-EgPv9tF
zs$pmb#U`VlCUX%e28-Aj7#NB;7#J8d8H@NqY>?Z*9w-uFU|_h#1F;+uRD2-YL8dY=
z6^S9+1`^|j*=B}F3=GYTMS3O7H4G_?%}o6QwTvY!S*)OFPhsw53Wi2;9t$X9L0FT;
z?-o;0QV}SPX)+dpJgdou=FTFJJw+fN-D1hfPfXEdg18$LC=hppeE@bm7sT;Jsfj5d
z!D5g<8JIu;C&pYP3HEe|CM(1Okcr?R1p5pui)0)~J0w6jY;yBcN^?@}Kp_k^k%N(g
JiHnPa6#z2E#76)C

diff --git a/unitgrade_private2/__pycache__/__init__.cpython-38.pyc b/unitgrade_private2/__pycache__/__init__.cpython-38.pyc
deleted file mode 100644
index 6e9fc2e8e234b8d82d001a785d86af68821340b7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 918
zcmWIL<>g{vU|{e{XHU>!W?*;>;vi#Y1_lNP1_p*=Jq8Ab6owSW9EK<e%^1a)!kNOH
z!qUPR#gxLD!q&nN#hk*P!qLJI#gf7p%%I8j5@eEJNHWL}5EF!185kHi85kIxL58L=
zFff!bWHByas$pEnSj!A%GuJRLWGq%HVOYQdVlgt*Fcle;u%<B9Fg7zWGL*2@Fs3jy
zGxdwrvXroAanvx>uz;M=%go3S&S1(A$PmO30n(FH!kWU`%*e=)!Vt`$$>vuj5MGp7
zl9`vTkeryDk*cSscZ;b!=@v^)Rc_)+##`LU`MCu}sl~;a`FT~WF8O(>ikh6anDUEn
zu@oehWZYs;$t=oC%uT(;mRgZnTvB|CH8(pYv*;FUK~ZL2$t{-rg4DcQ{4hh}3o?_l
zb5d`yq?G0sXtLg7%TLNmO)j~`nU<N88V@#yy)3mTDZe=N7E?;zEylE!3`HUg3=F^A
zovmU*i&Kk=V@gUhQe#~5lS^|`^Gb?iO7k*H(u)#PQsWDXGRqQ6Qn84{$7kkcmc+;F
z6;$5h275EUyeP9Il?4>qLZI+x<YDAt<YHuD;9}%qlwxFIC=z2}U`S>J$w4uQ4T>^w
z6!9RUh+!cpRvG;?nTyyM7#ND!K?ElQ1A``GkpPGdazEG;MWPH047Ye74uAv~AIJqv
zARCy9#L;a8iG$K1*hVK58;h(;m}?kP7@L{;Woj8qSh83_(VxQH%M{MQ1dZ;+48hQ7
z&tm~aHVA97_}yYEN-6?*qzL4FO*S-F7lFK1#0zpMOHO`biY61p7s6P)!Uge4QEFle
zNV=E<>=95<Dlr#HfrB7KlNDkC$V70Ug8d1Wg#-#(@Nn4V=BJeAq}qYP8*Cy6BL@=~
H7Y8c<77fPY

diff --git a/unitgrade_private2/__pycache__/__init__.cpython-39.pyc b/unitgrade_private2/__pycache__/__init__.cpython-39.pyc
deleted file mode 100644
index 7bf2f7227e54c7b2301a6dc324a1119b37119103..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 944
zcmYe~<>g{vU|@)L(@Yd(W?*;>;vi#Y1_lNP1_p*=Jq8Ab6owSW9EK<e%^1a)!kNOH
z!qUPR#gxLD!q&nN#hk*P!qLJI#gf7p%%I8j5@eEJNHWL}5EF!185kHi7#J9wL55Z_
zFff!bWHByas$pEnSj!A%GuJRLWGq%HVOYQdVlgt*Fcle;u%<B9Fg7zWGL*2@Fs3jy
zGxaOfvXroAanvx>uz;M=%go3S&XB^u!ob4N%*@D;Ct%1>oM6Df2!@diU~|e!SW{S=
z85tQ;7=jrz+5D;m!izFXGV{_Ek`t3NQuXxoZZVZ7-D1h9%1vC!c#AtZKewPLwYWGl
zKd*|_B|k4!QIqo)Q-1L+mV(5Rj9cs}nMHYtxv96<QY$ixONwu?=4Pj47TsbkD9X$$
zxy6!SkeYXkA7)5=L1uDxPU<a|l+xS+P1aj%`AJ!+$tAZq(=u~X<H6>zm!%dZ<rk;k
zVoJ%o#hA8|p-6;*f#H{{enx(7s(wjnMykF`esXDUYF<gPeraB2NqSLYN@{#TQD#|U
zNh+p@k$!x9W?p7Ve7s&k<t=WoC*#YDGD}ifK;h2^iV;R0Mjl2kMm|O!Mm@$NF$M;P
zWJZuU6oc5H2n0tM4<f=C7J}lK(NB}Ph>d}Pp@<zsa56A3XfhTFfY>0HgPmU_%D}*I
ziw9ykB%nYR7c+ruU@8(vw-F=`Pa=LOHWs;+FxN1oFg7#w%hfWLuw=1<5<?1eFH<-J
z6H?>{GZ-=yTOmh&9t$YSL0FT;?-o;0QW3~gMWA5NWJB{o5y+cGydYPz<m4x&Xfi>3
zB#gydTo7*+r6#6;q>DigXJ7&asUCBY6gW6SG+7}QfJ_7jFxbyvSx5k(1r>))ZhlH>
UPO2R!?7=2-Fmf<)adEH$04poUJpcdz

diff --git a/unitgrade_private2/__pycache__/deployment.cpython-38.pyc b/unitgrade_private2/__pycache__/deployment.cpython-38.pyc
deleted file mode 100644
index e5ef1a82ffe3b183639daf4d1197711d94e8aead..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1392
zcmWIL<>g{vU|>*-QcF~2Wng#=;vi#Y1_lNP1_p*=I|c@Z6owSW9EK<m&6LBK%M`_w
z%N)hb2;wv5utc$d<zX~y6l)4=3Udle3u6>p3S%&XCfiGp$$pwlw?uMNOEU6Pio-KY
zGF(!V^NSKo@{4Y<WMrnKCNqH)K`|c#0|O@m0|Uqv#Yv0|3^feR3=0?*GSo7aFxD`o
zFg7#w3)M2$FfU+Q$gqHUAww-oID;ueAVUyC1VcJQCqoTG7K;l*Y)A}KEo&`X32O;k
z4QmN|GgC8TEqe{S3q!0$EprLS0?r!dg^V#wwH&paC0sQe&5Sji;taK19SkL`CEPWf
zDNGU!HC!MPq|=<Clc6x6(5!^Dogs}8>_d(co*I^BMi+)=#%9J^mK4?nyfrKf8EaW;
z7*iOsnTk%-Fr_f0u(dKtGNiDJGt@Gc@MZBY5U62X$XN6W%oeO+s$pEnRP?GuD21b$
zv5B#Sv4$~)vze)10PH_uka>&@2;bE(WQo*r*KjWoP2pO|$jDH`ox)JVy+91a1KYzT
z&Hy%99Apd3c5#MU?h=Uwk~Q258Ebh;q-uC-7_y|BnQD1!7;AXbn1UHJx&3Z27QJL-
zU|>iF5zv?bM*#~11A{OqF~~45Fr+ioFvN<)Fx4{FGSx74Fl4hAvD7e4WGZ9{W?0Ek
z#KyqDpvioTNzdRGWA-h^oRy4GJUN+psm1Xn`SC@mxnKpqyqv9KLW@(2iepMjGg4z*
z@{>z*Q}arSV@mTfOVW!HQ&Qs#iZaU*OHwgKjABw!3v%)+K^pW5DsOSw<YX3?B<JTA
z*olK23334&0~-SeLzQMxYHog6YJ5g!N=j;8JT&#`+2rIWC*~B}=^=F9V&r=H_y7O@
zRXp)|`4HuL1(j8D!I`<4If+FIX_+~x3I&NJ8N~{jDXDoSnQ57+DT=ok%WpC2Y0BJU
zjRz^X#gbo;ns<w(C^a$V7FTgWPG$+%>$f-yOH+$WGV}9_Z?S+JTLen%MWEDui#;>1
zxF9vT<Q89gYDsZ^X;E@2L=SULYThl@qQt!P)LWdXd8N6jMTsS;w^*|BGxKgS<rm*#
z0XgRuTWUpSaY^wlj^f1JRInpBT`Q7P3qZErVl6MqEJ?k^6(66QpHiBW8Xtd)B`q^A
z<rZrZnBquEEKbc!%uT(;nVDOVUsRHlnRJU6!h~wM#h#v8l2}qwbc-WC9;7rrUX$+@
zcTg%wxpPipaq%to{L&Jz%`9M&G3^!`#3Q#D18*_LM=|9T-(oDj#adjFSX6S0IW;dO
ziZvHx)GaoMv!Vn&z!8LGC^(rEfy$^NZUzR1TcTKFk^>aq2B4(M#Kp+ND8|IX#K*|T
z$ic|R$ipbdB*n<Z#K9=QB*n<V$ipbY#Ky?QsKvy^#KTx*21=%kewyq>pfqz!6rS#k
v^bkx$G!@A*FfbIUg9wmLi0eQJ4Z;FDk;4Y!8#_?;DF!*6gHeEy0|c1?W<P?=

diff --git a/unitgrade_private2/__pycache__/deployment.cpython-39.pyc b/unitgrade_private2/__pycache__/deployment.cpython-39.pyc
deleted file mode 100644
index a1183907f15d5618aa6e7584380d3fad693ad2d2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1425
zcmYe~<>g{vU|@)L(@gxu!octt#6iZ)3=9ko3=9m#b_@&*DGVu$ISf%Cnkk1dmnn)V
zmpO`=5yWTAVTob^%fo2aDAp9#6y_9`7RD&H6vki%O}3XHll?TAZi(ckmSp6o6o+S)
zWVoaz=NBcG<QLsy$;eDeO=bcqf?_@f1_llW1_qETihCFt7-|@r85S@sWT<5-VXR?F
zVQgmVm#Jm0VP3$rkYNGyLWWwFaE25H76ulEW@bi)JOM+7Vlx8<Mlg(IU}Q*V=wzs2
z$YOC}hz*Hhs%5QZD`72Rt6?o+Z)R#{tYxoZcVURNsAVqUSio7sypS=5sg|RbvxKXL
zqnWXWQ=FletAnA0wS>EdGlfZlp@s`Yf^?cQbTSmC6nd4gwlkzLf_=?V!c)W2%;>_<
z%-GCW%aX#nfVYNaA!98|4Py#JHdE1^8m1J66t-3-Nrn`5afVvP622_{1p+mU3mJ?4
zf!TsJOf`%PnTr0E2&Hf|Gd3}nFxD`pa5gjbOM(3?3^I?A0ma8ch71!Ji?xvbT*Hth
zQp;V#y+AaDYat^eLk)KdLk;%=F%S=IJC`^E*gkQP-7q(aGt_dINGy=7;a<pC%Tpp%
z!&AeMCEd(a%Ui=(!<)tw%%I8bcZ;#;B_jg^Lo$ef#u+%WSQr=>gh9zhhJk@0ouP&y
zRwRb0ma&$phOvX8jIoHNhG`;GAxkjBN`@jf1_lOA=37j92DccqZ!zYqWQ^j;$;?YF
zjxWiNFG|e?EBNKEpOK%Ns$Wu?k*e>KpIn-onpaY+Uz(R$l3tXUk{Vx7lv$Qol8Px}
zq@R*nkdt2t(x6vRd5g;?C$qRDIX}0+PMm>(;WNnDRhmVqx%p+O@fn#ZDXDq!(B!FS
zlarsEm{V-0htPA2k?ZB(|NsA2@x<rlLzL?kR949aXXa++Bo-;8W#*(R6eN~p6f0z=
zq~?`mre&t4DBfZ$zs0DhDRYZ89;DzFOMXFW-Yu4*)WnoqT*U=BnI&K!-{LGRO)W0T
z%+D*n#R76>5hynlfs+3%_RPHEg4E=aTYTxMCB^xrMaiiUJ<K_&dAC@L67$kiZ*ivP
zmFA`vC6=V#V#&(S%)7;uUwn%N<eXb<sTG;UCB?TmiW75F!H(c`tw>HS0NHknwY(^^
zB=r_oe0*+xN@-4NeEcnzw9LGeTdYN3iX$npI5jUZH}w{0W^O@#QAti_(k)&H6RPDF
zdwOa~Vo6ESEspqjkka^gO}<;)L8&0+&N+$2#kbh=OH05uvw%s)v|DTtkKAGmyu}zF
z#gtQgi?R3?YjH_pQOPal)V!1^)?AQLx7Z-giW2kyM-Y;s;M7qBD#VJo85kIDiDHdO
zP$5!m0E%iRE=C?kEhZKwK1M!94n{sk9!5DPDMl_P4n_ecDMk*kEE^*iqZShv6AxpN
zIVg29`f0KkNq~)qr#K@$1QQWWMRE)b3`H6s0;Ch-I#3FSu)t2_uz~o-4wP$(K~Cpj
K6ky~4L1qBdhlc9_

diff --git a/unitgrade_private2/__pycache__/docker_helpers.cpython-38.pyc b/unitgrade_private2/__pycache__/docker_helpers.cpython-38.pyc
deleted file mode 100644
index 64a1893f40852651e6f4f6145d3b8ddb4b5e6dcb..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3165
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

diff --git a/unitgrade_private2/__pycache__/docker_helpers.cpython-39.pyc b/unitgrade_private2/__pycache__/docker_helpers.cpython-39.pyc
deleted file mode 100644
index d8bd23d3e204c918fa1d3cc8d5f223591f47ac4f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3217
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
ar8Fni4iuKfptQjOvXTW%GIB6+1OfnSNKQBa

diff --git a/unitgrade_private2/__pycache__/hidden_create_files.cpython-36.pyc b/unitgrade_private2/__pycache__/hidden_create_files.cpython-36.pyc
deleted file mode 100644
index c10d3e26f4209a3cb1de8b9a8cbcd399dba53b33..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3954
zcmXr!<>jg@`yZby%E0iL0ST}&FfceUFfbIyF)%QsFr+Z%Fyt~uG3GKwF)@PpOgYR^
z%qa{hOgSu3EMS^7iWN+=MX{wYq%h~O=W;}GFfydDL~*9Drm(dzL~*6Cr*O0|L~*C^
zrf{e5v@k~Tq%Z|DX!5-TS**!)iz_)XIU_Z`C^a$V7B_@lUX)pq>Zi$gOC%#RB_%a4
zK0UD{Bef{Lv>+!xF{SDgS9NtpYGO)lEf-f&YC(QciD7(kerZv1s)DUTbv1-pTML&f
zNUQ|u14}~LwY6M%iMgq^O4Zdt5EE)^m0+eR*eXEGh|kO`E=kNQ$xJLs)c~p2Q9!j1
z!H1fw$(3JPQczkFpORUmV5^W{tXGg&lA)K9Sp?Fq5g(tHnUfkHugQhtqxh2i_~gXg
zg3{u=)DjJd6*>wClQg-K89|}Nz`(%Hz`y{CCTCDI6)-R`WHQt;R)p0sWHGof#QMZA
z)iTvGXEM|<)-Yu;+AvgD)G%c+xiG})#W2;f)H2twWHC20)UwvFWU(|e)UwsE*07~8
z&S8S6mt?460qH7K3uh?g31=u_tzoQT$YM)jN@4D021RQygC=WL3YUU{f`WfiNn&Q6
zLUBoHN@`w-LSkNVd1_IyLQ<tdYDH>tX-Q^Yx<W}tszOO>afw1^9+(aBnnGe;3W%Gh
zP@I^X3S#9dl;neGg_O+VY(22?noPIYp@DjfyPzmFIX}0cv?MjfO_T8!ds%8xQhsr&
zpC<b)&cf2v;*!k#yy9CdpfJA0npu*XTYQTTsv#cYuv?-?X2chzLL#`hh?#+b;g%>=
zZ3<LzF*uqu*>ABy9DIud>XPDHjD@!t<8QHm?6}1SHJTG{+)9QbQ3eKvUqQ}RF`>n&
zMa3~Cr5UL)F8Rr&xv6<2#WAIMnI-8(i7Bb^1x1-<i6yC6M4)LtxhOTUBo*wEV!eXO
zTfD`oC8Y&07m9%5UjURSSXdYZ7`Ye)7&#a@80DCX#2FYE;K_xFfq{XAfq?;>Tyz*1
z7(fXng|V5jma&E*g`tMAl}VDJmI2IW$YM-kYKDshGiWmV-QtLk&rQtCi;us>$fe12
zizO{HFXa|%5s1=cy2S?xA6WLg#gtM34gd%t1`1oQ;*z4w0<a;<AUAV>+|0<u$ipba
zSR}{5z!2h=%mxx;U|^7BU|^7EU|;}6N^u1f149V|$gPYFC5$x;%?!<qj0`DEDGWJG
zwQMzPS<ETSAdwP=6c!K-Qc=rZ!ji>W!_drF%TdBs!;!+;%+$|U%UQ#j#oo+N%N5R$
z!Vt(1#1O$y!coK3%vj4+!db(f1!8fRaA)z<a5pp7@}#iU@}@AQu;=jR^40P|?c}ZH
zPvJ=6OyL5RV(F~40x7&Hd@T%}4DAeQj4Avn0xcZ1f*lMsTr~pCOtoA!f;D_u{3QZe
z{OL?!5#AcX8vZQ)8vZQaEPl8g3rH?SP@JKLOPryWt3)tMsF@*4xJ0CxF-x?DAxo@8
z9OTXt@fx0H#uD)wjueIzHBg+T2#Yf`GuH5?h|FPaW~>zg%cz58M8z3ug-h6Kgj2*)
z#8V`CnfnF6As|sB1PUia7}PLNU@Fq8VVb~Ll$Roz$CScWE0WGoD_X-cfw8EqMl?$@
zMGB;&L@G-<MY=|0HbaU`icFSFjc7CDY=#us8exzKh@8s-Qil>Zav%|~D?o7|1a<*?
zGeeeaGefNy!VM|%wc;rXHR9q7DGK5Y>5MgEDGVtZAb*H6)QY7DX35luH8a+VflU%?
zW`g@g3}imSoEpXnOhpAKsX_^)0x3O6Wyxj9*Kjm5rZA*vf^0}p7H6mxDp5#LsSyH&
zCL=?NYOO>HLokD;mS2@<aB3>J5GyT!6>fTZdPSguIDOVk5ZGy7B@vLAoDC}JV8tM)
zd@t71)4Ro3bc;cg@s=PW$7iJG6r>gvS4qQ#^x&*`m?UpnQGTw1o<e3Ws9vk$2Xo=d
z^w0$qsstb^72s-;L3tjOp+Gb!?+b&nodT#vXUu}6R;Co@7LFQ*EXHOA7lvj~X~0ke
z@->TJ5hx47OAnA=L3tBwf*Jz@LpnnZL#$jULkYwjh7`sYjt)kM8O1Ce3=^3OS%Mif
zncya%xIqeLf>14E2SXM^GeZ_*4P!GSL{|~0<kV!k#R@JkZgCZtBo>tvmuHq_XfoYm
z(lfZln5xNmi!leRt_W1N{Nl37$t*4b72bAUAWwp9V`HfDgp`z!auyUJ@sMIl&n727
zIWec$POm5z5^BW=A%szS2&N|EE#}0$N=?Qh6$S=Sbh4yYB<E-{7J&i-?1mzB1_lOX
z%k3z$98|_;<!9#I;wmo4$t=mq%u6lSWV*#zT%^gs0I6Lx86j*?5ZvN~d&LtJ0-*S2
zV3c93(jwj&@B{;DS8y{hFo2`m51e3XnJTPmKrIWSTILdl8fH*SAcduuxnHW5rG^RA
zT4-iSVHF2sbB0<bM20Nn3TNnGs9~yMY-XxussT0m*!+q>$*>4i#8<JFmZa%gXfod7
zNX<*mPsz+n2d6!d|MLq{^KP+#8ibmxw^-9aaSZV>r~<ping*`s8PhZwi*#XO0*;GY
ztT~`|9?0dzJfIxF$O5hyl^D4gtJDYv2v{@N5ida%P!xN7Mq*w{W}YT%6g#w$c#93v
zZYTl;RTO7Qes*eJe12)kEf!FFw2CtxoaR8aHDfv4hedh}3=CDwy8a4P?7F&1Rhb1w
zRon%YxtV#HX_=`-3cnZ?s$>*&b&FC9auSnMK@A1noYcJZk_=lT0|niD1!!?|(!OeT
zxMPr?r=Po(f^U9GW?E%tUb>D#3b<{QnFA_@@{1JmK~3fI%;HpqlEmDC)FO~DC>JS|
zWMmdA6ekyD7L@2HWR|EGE2JcrBr4<=fm>chsl}x^;POrn>@5XQ#!)EG%*jzmN>#|r
zD+9H%(i2NkQxp=56%rMaGg1@5$`eaUQgaJR^s1QE)zx2uii|4p5Rl@$bcKS%<m}WG
zuu-5wF^UZmKvnFJ?5FVZ6$1mq%fJ8s|1YuuvHrtYnu@nr3yL!HO2EyTTP!7+xv95U
zi*r&_3vRJz<`oyDCYRh|PfslYxw1$flne|&1gJq#1S$rKctMR1wt~#$?3~nFtSP0r
z1;w{G;e}+8B1oD8)*dec<(pe<S($lRiAJ}$UGvH^i}Le8F>#9<R079?%A~yXTP&au
z1GNhCQc{aRZ6i=pjE@H;)`Fs2tl)mjEw;phg4Dc}TTJ=Ix7dm+i%U{-i?l$F(+1he
z0_qUl;z&v?P6cVc#R6(AYf46OLz0+tPGWKKEq0J#X-VoW&itgb(&FUAlGIyl-~>~7
ziv^T|qB!#M^Kw8DP-G7>nh#_&Q(9h;F^DGvBEU(M2ND1f=SQ&>RD#ke*z-lMAVuIp
z#RSCC0hz!C>2us-&QB`7#hO}CQj{3QTAWy#oO+9?Jn<G|BDnB{Wjt^JB#t9rfjnEB
z2g-#^9E@CyV9dk@ZTN98aWQf+u`u#5a<DQnLLeIx2P+Rd7n2a93YQQg8zUQ|5IFY=
zFp4m-G4e67FtagmF=~KK;$akHWMPy7n+B4Fm@mP|!&np#DyUgQ+}uLkG<hMO1g8g3
zmM(G!`4rR^E^-910vH$=qL6B6Xqz0I8j3)LIym)#Td81k!M;Z#zyZKvlbfGXnv-e=
ZO8Uh@3=9mArZ}iM&cnmP#KF(O0RR!6M3evk

diff --git a/unitgrade_private2/__pycache__/hidden_create_files.cpython-38.pyc b/unitgrade_private2/__pycache__/hidden_create_files.cpython-38.pyc
deleted file mode 100644
index 495660ae33400dda27e6cf64c7f939036a688a98..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4588
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
Y7mF}3FbFVmKp_t!2NMeqhcX8T05d7!MgRZ+

diff --git a/unitgrade_private2/__pycache__/hidden_create_files.cpython-39.pyc b/unitgrade_private2/__pycache__/hidden_create_files.cpython-39.pyc
deleted file mode 100644
index e9bdd98457f31c4fc351bf81ea01a6d12fb3d531..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4665
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

diff --git a/unitgrade_private2/__pycache__/hidden_gather_upload.cpython-36.pyc b/unitgrade_private2/__pycache__/hidden_gather_upload.cpython-36.pyc
deleted file mode 100644
index 7aa51f153e94d74ee8abd09983ea96ac0bc500f0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2775
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

diff --git a/unitgrade_private2/__pycache__/hidden_gather_upload.cpython-38.pyc b/unitgrade_private2/__pycache__/hidden_gather_upload.cpython-38.pyc
deleted file mode 100644
index 07472b0de4bf0b0f74be03f08a47140647e9cb27..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4107
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

diff --git a/unitgrade_private2/__pycache__/hidden_gather_upload.cpython-39.pyc b/unitgrade_private2/__pycache__/hidden_gather_upload.cpython-39.pyc
deleted file mode 100644
index 5c2e1ae6b68171c81e7ddf38fb9d45d3f1968a79..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4210
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

diff --git a/unitgrade_private2/__pycache__/token_loader.cpython-38.pyc b/unitgrade_private2/__pycache__/token_loader.cpython-38.pyc
deleted file mode 100644
index 31836c22ea1ea42dda4ca41936fce6eb9ec9f4b6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 978
zcmWIL<>g{vU|{Hd%9n70g@NHQh=Yt-7#J8F7#J9edl(oPQW#Pga~Pr^G-DJan9mf&
z1g4pzm{XWim|Ga4SW;P2ShAUlI>6#=QEXtEJ(q)tfsrAXGm49mA(bnOn~@=vF^gvb
zFNnR6F^VshVF5!bUka-@!$QU={#5=H21$k}fmFd%fo4WVhEx_19VL{)7A2g*7|fu_
z{u1O)zhp)b1;uO(3=EtM3=Ga77uzu~FqAMXV60(CVO+@6&sWP>!?=KHAww-wID;ue
zAVUyC1Vai_3PTQaEprX?0+t%4g^aZ<Da<J>Eey4+H7vmlnyh}en2Jh@KvtmG!^*(G
z0J19>WRDF40|UqoNrnXs3mIG(VzpwJY8h*pYM4@(;9?>%Ots9lEG3LJj5W+PEX~Y}
z4224XJShyp44TY-x7brsOA<44if^%ImZatuYcdsq0{#|jK~ZL2i6-kU=AzW%Ta1NK
zEQMu>Iky<IZ!wmwWGDhf-7jxvtC-N@)S}{;lG2RS7?=Fy(%jU%lH!=syv&mHqQsQc
z_=2L$vc!^9EFvZO*{ON)Ir)hxsYQAPmA6<5ic*VtLB0ZckAYEyNrb6N0wf;~R;p){
zlb@WJQ*5UPQmDy!i#e&v=oU+UL2BMDmZH?elv^xW#rb)+SV3BfZ?WWL7MI*&E>11E
z#hjCxR|E<-O}1NHV6)=WGILUIF{a&OEG`mYU|=W$Sy{vbVu3sc_FWM-0|Ub?E|6&u
z2Y}QRgVZoE@-YfAaWHZ*aYz(NfK+kB$LA(y=EcWX@#$-&6_sX|Xz771%B<&QV9*q~
z#gd+rpLB~UzxWngL1uDxPHGXzr*O@AiMgrq@wZqqi*k~q6hWk3VsUY1dLB49k=XHI
z!*6jT$wmnvI8bS(w8UE+@nBDaOf5(($+*Ryl34_@<`z>*-Yv$QB2kcML4k6Msi^oC
vV<N=QXujvL$<0qG%}KQbCBtGF1_lNWMlfXJPz2FJjBLz&One|QCJrV5AN%-d

diff --git a/unitgrade_private2/codejudge_example/__pycache__/__init__.cpython-38.pyc b/unitgrade_private2/codejudge_example/__pycache__/__init__.cpython-38.pyc
deleted file mode 100644
index ae23c7f18121d96a18d55cdeddffe576411baec2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 181
zcmWIL<>g{vU|^VDDVGSMAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_MLAo=
zgche36~~m6W~9cr<R_QrrskCt$CTz}mZTRYrliIf6lInrmZV~e7{w&#r=(_;rlhCF
nr&c897UZPH#K&jmWtPOp>lIYq;;_lhPbtkwwFBAt8RRwq*g7#H

diff --git a/unitgrade_private2/codejudge_example/codejudge_sum.py b/unitgrade_private2/codejudge_example/codejudge_sum.py
deleted file mode 100644
index 8a43e38..0000000
--- a/unitgrade_private2/codejudge_example/codejudge_sum.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Implement https://www.codejudge.net/docs/quickstartfiles#the-problem
-from unitgrade.unitgrade import QuestionGroup, Report, QPrintItem
-from unitgrade.unitgrade_helpers import evaluate_report_student
-from cs101courseware_example import homework1
-import random
-
-class SumItem(QPrintItem):
-    ls = []
-    def __init__(self, question, *args, **kwargs):
-        super().__init__(question, *args, **kwargs)
-
-    def compute_answer_print(self):
-        random.seed(42)
-
-        from unitgrade_private.codejudge_example.sumfac import sumlist
-        return sumlist(self.ls)
-
-class SumQuestion(QuestionGroup):
-    title = "Sum of two integers"
-    def __init__(self):
-        pass
-
-    class FactorialQuestion(QPrintItem):
-        n = 3
-        def compute_answer_print(self):
-            from unitgrade.unitgrade_private.codejudge_sum import factorial
-            return factorial(self.n)
-
-class Report1(Report):
-    title = "CS 101 Report 1"
-    questions = [(ListReversalQuestion, 5), (LinearRegressionQuestion, 13)]
-    pack_imports = [homework1] # Include this file in .token file
-
-if __name__ == "__main__":
-    evaluate_report_student(Report1())
diff --git a/unitgrade_private2/codejudge_example/sumfac.py b/unitgrade_private2/codejudge_example/sumfac.py
deleted file mode 100644
index f429a12..0000000
--- a/unitgrade_private2/codejudge_example/sumfac.py
+++ /dev/null
@@ -1,6 +0,0 @@
-def sumlist( ls ):
-    return sum(ls)
-
-if __name__ == "__main__":
-    sumlist([1, 4, 4])
-
-- 
GitLab