From 7e820f223f4b9ce5cc9c87d56f0e203e26e467b1 Mon Sep 17 00:00:00 2001
From: Tue Herlau <tuhe@dtu.dk>
Date: Thu, 2 Sep 2021 15:33:58 +0200
Subject: [PATCH] Updates

---
 LICENSE                                       |  19 +
 MANIFEST.in                                   |   1 -
 README.md                                     |  36 +-
 cs101courseware_example/instructions.py       |   2 +-
 dist/unitgrade-0.0.2-py3-none-any.whl         | Bin 0 -> 17438 bytes
 dist/unitgrade-0.0.2.tar.gz                   | Bin 0 -> 17257 bytes
 dist/unitgrade-0.0.5.tar.gz                   | Bin 30274 -> 0 bytes
 pyproject.toml                                |   6 +
 setup.py                                      |  43 +-
 {unitgrade2 => src/unitgrade2}/__init__.py    |   3 +-
 .../__pycache__/__init__.cpython-38.pyc       | Bin 0 -> 1306 bytes
 .../__pycache__/unitgrade2.cpython-38.pyc     | Bin 0 -> 22713 bytes
 src/unitgrade2/unitgrade2.py                  | 705 ++++++++++++++
 .../unitgrade2}/unitgrade_helpers2.py         |  43 +-
 src/unitgrade2/version.py                     |   1 +
 unitgrade.egg-info/PKG-INFO                   |  10 -
 unitgrade.egg-info/SOURCES.txt                |  21 -
 unitgrade.egg-info/dependency_links.txt       |   1 -
 unitgrade.egg-info/requires.txt               |   4 -
 unitgrade.egg-info/top_level.txt              |   2 -
 unitgrade/Report_resources_do_not_hand_in.dat | Bin 64 -> 0 bytes
 unitgrade/version.py                          |   2 +-
 .../__pycache__/__init__.cpython-38.pyc       | Bin 1373 -> 0 bytes
 .../__pycache__/__init__.cpython-39.pyc       | Bin 1400 -> 0 bytes
 .../__pycache__/unitgrade2.cpython-38.pyc     | Bin 29204 -> 0 bytes
 .../unitgrade_helpers2.cpython-38.pyc         | Bin 6959 -> 0 bytes
 unitgrade2/__pycache__/version.cpython-38.pyc | Bin 167 -> 0 bytes
 unitgrade2/__pycache__/version.cpython-39.pyc | Bin 164 -> 0 bytes
 unitgrade2/unitgrade/ListQuestion.pkl         | Bin 466 -> 0 bytes
 unitgrade2/unitgrade2.py                      | 891 ------------------
 unitgrade2/version.py                         |   1 -
 31 files changed, 793 insertions(+), 998 deletions(-)
 create mode 100644 LICENSE
 delete mode 100644 MANIFEST.in
 create mode 100644 dist/unitgrade-0.0.2-py3-none-any.whl
 create mode 100644 dist/unitgrade-0.0.2.tar.gz
 delete mode 100644 dist/unitgrade-0.0.5.tar.gz
 create mode 100644 pyproject.toml
 rename {unitgrade2 => src/unitgrade2}/__init__.py (90%)
 create mode 100644 src/unitgrade2/__pycache__/__init__.cpython-38.pyc
 create mode 100644 src/unitgrade2/__pycache__/unitgrade2.cpython-38.pyc
 create mode 100644 src/unitgrade2/unitgrade2.py
 rename {unitgrade2 => src/unitgrade2}/unitgrade_helpers2.py (84%)
 create mode 100644 src/unitgrade2/version.py
 delete mode 100644 unitgrade.egg-info/PKG-INFO
 delete mode 100644 unitgrade.egg-info/SOURCES.txt
 delete mode 100644 unitgrade.egg-info/dependency_links.txt
 delete mode 100644 unitgrade.egg-info/requires.txt
 delete mode 100644 unitgrade.egg-info/top_level.txt
 delete mode 100644 unitgrade/Report_resources_do_not_hand_in.dat
 delete mode 100644 unitgrade2/__pycache__/__init__.cpython-38.pyc
 delete mode 100644 unitgrade2/__pycache__/__init__.cpython-39.pyc
 delete mode 100644 unitgrade2/__pycache__/unitgrade2.cpython-38.pyc
 delete mode 100644 unitgrade2/__pycache__/unitgrade_helpers2.cpython-38.pyc
 delete mode 100644 unitgrade2/__pycache__/version.cpython-38.pyc
 delete mode 100644 unitgrade2/__pycache__/version.cpython-39.pyc
 delete mode 100644 unitgrade2/unitgrade/ListQuestion.pkl
 delete mode 100644 unitgrade2/unitgrade2.py
 delete mode 100644 unitgrade2/version.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/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 822df1c..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1 +0,0 @@
-include *.dat
diff --git a/README.md b/README.md
index 460eea5..c1a3fc8 100644
--- a/README.md
+++ b/README.md
@@ -4,47 +4,35 @@ Unitgrade is an automatic report and exam evaluation framework that enables inst
  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.   
+ - No external configuration files, just write a `unittest`
+ - No unnatural limitations: 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
+    - Instructors can automatically verify the students solution using Docker VM and by running hidden tests
+    - Allow export of assignments to Autolab (no `make` file mysteries!)
  - Tests are quick to run and will integrate with your IDE
 
 ## Installation
-Unitgrade can be installed through pip using 
+Unitgrade can be installed using `pip`:
 ```
-pip install git+https://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git
+pip install unitgrade
 ```
 This will install unitgrade in your site-packages directory. If you want to upgrade an old installation of unitgrade:
 ```
-pip install git+https://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade
+pip install unitgrade --upgrade
 ```
 If you are using anaconda+virtual environment you can install it as
 ```
 source activate myenv
 conda install git pip
-pip install git+https://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git
+pip install unitgrade
 ```
-Alternatively, simply use git-clone of the sources and add unitgrade to your python path.
 
 When you are done, you should be able to import unitgrade:
 ```
 import unitgrade
 ```
-## Testing installation
-I have provided an example project which illustrates all main features in a self-contained manner and which should 
-work immediately upon installation. The source can be found here: https://lab.compute.dtu.dk/tuhe/unitgrade/-/tree/master/cs101courseware_example
-To run the example, first start a python console:
-```
-python
-```
-Then run the code
-```
-from cs101courseware_example import instructions
-```
-This will print on-screen instructions for how to use the system tailored to your user-specific installation path.
 
 ## Evaluating a report
 Homework is broken down into **reports**. A report is a collection of questions which are individually scored, and each question may in turn involve multiple tests. Each report is therefore given an overall score based on a weighted average of how many tests are passed.
@@ -83,12 +71,12 @@ To register your results, please run the file:
 >>> cs101report1_grade.py
 In the same manner as you ran this file.
 ```
-Once you are happy with the result, run the alternative, not-easy-to-tamper-with script called `cs101report1_grade.py`:
+Once you are happy with the result run the script with the `_grade.py`-postfix, in this case `cs101report1_grade.py`:
 
 ```
 python cs101report1_grade.py
 ```
-This runs the same tests, and generates a file `Report0_handin_18_of_18.token`. The file name indicates how many points you got. Upload this file to campusnet.
+This runs the same tests, and generates a file `Report0_handin_18_of_18.token`. The file name indicates how many points you got. Upload this file to campusnet (and no other). 
 
 ### Why are there two scripts?
 The reason why we use a standard test script, and one with the `_grade.py` extension, is because the tests should both be easy to debug, but at the same time we have to prevent accidential changes to the test scripts. Hence, we include two versions of the tests.
@@ -97,7 +85,7 @@ The reason why we use a standard test script, and one with the `_grade.py` exten
  - **My non-grade script and the `_grade.py` script gives different number of points**
 Since the two scripts should contain the same code, the reason is nearly certainly that you have made an (accidental) change to the test scripts. Please ensure both scripts are up-to-date and if the problem persists, try to get support.
    
- - **Why is there a `*_resources_do_not_hand_in.dat` file? Should I also upload it?**
+ - **Why is there a `unitgrade` directory with a bunch of pickle files? Should I also upload them?**
 No. The file contains the pre-computed test results your code is compared against. If you want to load this file manually, the unitgrade package contains helpful functions for doing so.
    
  - **I am worried you might think I cheated because I opened the '_grade.py' script/token file**
@@ -135,7 +123,7 @@ Yes.
 That the script `report1_grade.py` is difficult to read is not the principle safety measure. Instead, it ensures there is no accidential tampering. If you muck around with these files and upload the result, we will very likely know.     
 
 - **I have private data on my computer. Will this be read or uploaded?**
-No. The code will look for and upload your solutions, but it will not read/look at other directories in your computer. In the example provided with this code, this means you should expect unitgrade to read/run all files in the `cs101courseware_example`-directory, but **no** other files on your computer (unless some code in this directory load other files). So as long as you keep your private files out of the base courseware directory, you should be fine. 
+No. The code will look for and upload your solutions, but it will not read/look at other directories in your computer. In the example provided with this code, this means you should expect unitgrade to read/run all files in the `cs101courseware_example`-directory, but **no** other files on your computer. So as long as you keep your private files out of the base courseware directory, you should be fine. 
 
 - **Does this code install any spyware/etc.? Does it communicate with a website/online service?**
 No. Unitgrade makes no changes outside the courseware directory and it does not do anything tricky. It reads/runs code and write the `.token` file.
diff --git a/cs101courseware_example/instructions.py b/cs101courseware_example/instructions.py
index b6e149b..9786bd4 100644
--- a/cs101courseware_example/instructions.py
+++ b/cs101courseware_example/instructions.py
@@ -18,7 +18,7 @@ for d in os.listdir(wdir):
     if "__" not in d and d != "instructions.py":
         print("> ", d)
 print("")
-fprint("The file homework1.py is the file you edit as part of the course; you are welcome to open it and inspect the content, but right now it consists of some simple programming tasks plus instructions.")
+fprint("The file looping.py is the file you edit as part of the course; you are welcome to open it and inspect the content, but right now it consists of some simple programming tasks plus instructions.")
 fprint("The file cs101report1.py contains the actual tests of the program. All the tests are easily readable and the script will work with your debugger if you are using pycharm, however, we will run the script for the command line. ")
 fprint("To do so, open a console, and change directory to the cs103 main directory using e.g.:")
 tprint(f'cd "{wdir}"')
diff --git a/dist/unitgrade-0.0.2-py3-none-any.whl b/dist/unitgrade-0.0.2-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..88df3c4dfc76af895eddef0e9e1a54c7a0cc5fc6
GIT binary patch
literal 17438
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

literal 0
HcmV?d00001

diff --git a/dist/unitgrade-0.0.2.tar.gz b/dist/unitgrade-0.0.2.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..24bc625650b200d9016cc5ada901d05c91e0706f
GIT binary patch
literal 17257
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

literal 0
HcmV?d00001

diff --git a/dist/unitgrade-0.0.5.tar.gz b/dist/unitgrade-0.0.5.tar.gz
deleted file mode 100644
index debd32cec15ab13d6feb708942d2a2a9f1400e1a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

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

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/setup.py b/setup.py
index 29108c8..aaa1240 100644
--- a/setup.py
+++ b/setup.py
@@ -1,14 +1,35 @@
-from setuptools import setup
-from unitgrade.version import __version__
-setup(
-    name='unitgrade',
+# Use this guide:
+# https://packaging.python.org/tutorials/packaging-projects/
+
+# from unitgrade2.version import __version__
+import setuptools
+with open("src/unitgrade2/version.py", "r", encoding="utf-8") as fh:
+    __version__ = fh.read().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",
     version=__version__,
-    packages=['unitgrade', 'cs101courseware_example'],
+    author="Tue Herlau",
+    author_email="tuhe@dtu.dk",
+    description="A student homework/exam evaluation framework build on pythons unittest framework.",
+    long_description=long_description,
+    long_description_content_type="text/markdown",
     url='https://lab.compute.dtu.dk/tuhe/unitgrade',
-    license='Apache',
-    author='Tue Herlau',
-    author_email='tuhe@dtu.dk',
-    description='A lightweight student evaluation framework build on unittest',
-    include_package_data=True,
-    install_requires=['numpy', 'jinja2', 'tabulate', 'sklearn', 'compress_pickle', "pyfiglet"],
+    project_urls={
+        "Bug Tracker": "https://lab.compute.dtu.dk/tuhe/unitgrade/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",
+    license="MIT",
+    install_requires=['numpy', 'tabulate', 'tqdm', "pyfiglet", "colorama", "coverage"],
 )
diff --git a/unitgrade2/__init__.py b/src/unitgrade2/__init__.py
similarity index 90%
rename from unitgrade2/__init__.py
rename to src/unitgrade2/__init__.py
index 23b1c9d..d62d54d 100644
--- a/unitgrade2/__init__.py
+++ b/src/unitgrade2/__init__.py
@@ -1,4 +1,3 @@
-from unitgrade2.version import __version__
 import os
 
 # DONT't import stuff here since install script requires __version__
@@ -34,4 +33,4 @@ def cache_read(file_name):
     else:
         return None
 
-from unitgrade2.unitgrade2 import Hidden, myround, mfloor, msum, Capturing, ActiveProgress
+from unitgrade2.unitgrade2 import myround, mfloor, msum, Capturing, ActiveProgress
diff --git a/src/unitgrade2/__pycache__/__init__.cpython-38.pyc b/src/unitgrade2/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4429c41fb31c60f6c1074d20620caf2572fce98e
GIT binary patch
literal 1306
zcmWIL<>g{vU|_hl*dWo3m4V?gh=Yuo85kHG7#J9eofsGxQW#Pga~Pr+Qn*r>Q&?IU
zqZm_IQ`lM<qL@<HQ#e`}qL@<{QaE#1a#^ETbJ?QUa@nKUb2*|oayg?o85vR-gBdir
zUxG~c3rPkU3}S*X8v_FaCj$e6GsvPmkVT9s3^@$7%q5IjObeK67#A|uvVhqvH7pAm
zi?vD^7qEg@j0`nQMHVG&DNHqt%}k68CG0hfDa_4G{bIGOHOyHYH4HVZDJ&_hz08aZ
z;S8n>feb+m5g<KTC2T2d&5Vo;DGb33n(Tf>j0_A6RRZBfnI)Nd=?ck-$r-77dV05*
z%9C!f<W%J*u4IhjPR`FQC`v6Z&dkrNVs**SOI6h5yu}X_jW5Vd&dy1_#gt!si=`m3
zB;yu)N@h`BVs7d!w$zHu;*#Q9thw1KnMJo)3yL!HN^Y^_7o_IhVo52@Ezo4U#g?Cx
zm6}{~i!&`VCp8|djlC?jC@H@<wTP900Tjl0w;0n_G873hFfjbGakh#HElw>ejwvb4
zNR4sHPcF?(%_}L6Db33)NiRxFNsTEkN=EREV&da7^D;}~<Mj$EZ*hY?7++qLS&|Ae
zyjTPj4U8O&Jd8YyT#PIXT#P)7Qj9DNMIeb}P~d<RfG~&+iaT&z@h~tjlrUs5E?}x*
zSO|(<Mn6sFB2aV|u`@6*6mc>zFlaIs@q^ePXM^2dBn(P$JP;>9LPh`-@k}7&nTkXi
z7#L7&WMN=n03}kejeUsJ!3a(f%pjYK+Nz97SZWwjn3|dT<!YH~7_(Swm_UiNmnocq
z2^#Z@8NwNYp=ltTp|FdEp@c1)tEh>Qp_ZAEp-QfVJ%zP~0g{d&siTCwh8dJfKxrq1
zp_aLhIf5aQp|C50A&&)=azGfCdTuclB^7}}rU>NVDy5L3%+wTxl6-}n{KOQ6M1`cp
z6a`2UQ2<4;LSji(u4kG;Nk%G^Ur>;mSX2zsk(8>CSXz>wn^=;WoS2hSsgRzUms*rq
zlA5BUP?=w<keryOP*PM0Qks&QlUkChkXfRmkYAFKT2!7{oT`wLU!DiGH7~VXp)9os
zlx8(KzzGR0dWt}Cc#8$3{1&HcMRICENoIat5jQC2SRgS6N+Cspph#m(g~T8@F2T{r
z1&PL@)Wj4}#K9606AvR3BM+k*qW~ipBL|}lbCDFtK-OFAxs^rvrFkj0*mBcy^7D&s
zvE&w)=HB9TPAn)XEy~PGzs2X6T#{Lq8c>v<4$5qrj3Js_5I2L;A~<<~4T}<mCv_t|
z1hYsQl-OiIge-`V0}=8d0_<o60d_uzO>TZlX-=vgC|MVCFfcH1uyAp6uyXJN0CxU1
ASO5S3

literal 0
HcmV?d00001

diff --git a/src/unitgrade2/__pycache__/unitgrade2.cpython-38.pyc b/src/unitgrade2/__pycache__/unitgrade2.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3f772f63e4a0c6727d15b104e6cf981814c53043
GIT binary patch
literal 22713
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

literal 0
HcmV?d00001

diff --git a/src/unitgrade2/unitgrade2.py b/src/unitgrade2/unitgrade2.py
new file mode 100644
index 0000000..a0290ca
--- /dev/null
+++ b/src/unitgrade2/unitgrade2.py
@@ -0,0 +1,705 @@
+"""
+git add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade
+"""
+import numpy as np
+import sys
+import re
+import threading
+import tqdm
+import pickle
+import os
+from io import StringIO
+import io
+from unittest.runner import _WritelnDecorator
+from typing import Any
+import inspect
+import textwrap
+import colorama
+from colorama import Fore
+from functools import _make_key, RLock
+from collections import namedtuple
+import unittest
+import time
+
+_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
+
+colorama.init(autoreset=True)  # auto resets your settings after every output
+
+def gprint(s):
+    print(f"{Fore.GREEN}{s}")
+
+myround = lambda x: np.round(x)  # required.
+msum = lambda x: sum(x)
+mfloor = lambda x: np.floor(x)
+
+
+def setup_dir_by_class(C, base_dir):
+    name = C.__class__.__name__
+    return base_dir, name
+
+
+class Logger(object):
+    def __init__(self, buffer):
+        assert False
+        self.terminal = sys.stdout
+        self.log = buffer
+
+    def write(self, message):
+        self.terminal.write(message)
+        self.log.write(message)
+
+    def flush(self):
+        # this flush method is needed for python 3 compatibility.
+        pass
+
+
+class Capturing(list):
+    def __init__(self, *args, stdout=None, unmute=False, **kwargs):
+        self._stdout = stdout
+        self.unmute = unmute
+        super().__init__(*args, **kwargs)
+
+    def __enter__(self, capture_errors=True):  # don't put arguments here.
+        self._stdout = sys.stdout if self._stdout == None else self._stdout
+        self._stringio = StringIO()
+        if self.unmute:
+            sys.stdout = Logger(self._stringio)
+        else:
+            sys.stdout = self._stringio
+
+        if capture_errors:
+            self._sterr = sys.stderr
+            sys.sterr = StringIO()  # memory hole it
+        self.capture_errors = capture_errors
+        return self
+
+    def __exit__(self, *args):
+        self.extend(self._stringio.getvalue().splitlines())
+        del self._stringio  # free up some memory
+        sys.stdout = self._stdout
+        if self.capture_errors:
+            sys.sterr = self._sterr
+
+
+class Capturing2(Capturing):
+    def __exit__(self, *args):
+        lines = self._stringio.getvalue().splitlines()
+        txt = "\n".join(lines)
+        numbers = extract_numbers(txt)
+        self.extend(lines)
+        del self._stringio  # free up some memory
+        sys.stdout = self._stdout
+        if self.capture_errors:
+            sys.sterr = self._sterr
+
+        self.output = txt
+        self.numbers = numbers
+
+
+# @classmethod
+# class OrderedClassMembers(type):
+#     def __prepare__(self, name, bases):
+#         assert False
+#         return collections.OrderedDict()
+#
+#     def __new__(self, name, bases, classdict):
+#         ks = list(classdict.keys())
+#         for b in bases:
+#             ks += b.__ordered__
+#         classdict['__ordered__'] = [key for key in ks if key not in ('__module__', '__qualname__')]
+#         return type.__new__(self, name, bases, classdict)
+
+
+class Report:
+    title = "report title"
+    version = None
+    questions = []
+    pack_imports = []
+    individual_imports = []
+    nL = 120  # Maximum line width
+
+    @classmethod
+    def reset(cls):
+        for (q, _) in cls.questions:
+            if hasattr(q, 'reset'):
+                q.reset()
+
+    @classmethod
+    def mfile(clc):
+        return inspect.getfile(clc)
+
+    def _file(self):
+        return inspect.getfile(type(self))
+
+    def _import_base_relative(self):
+        if hasattr(self.pack_imports[0], '__path__'):
+            root_dir = self.pack_imports[0].__path__._path[0]
+        else:
+            root_dir = self.pack_imports[0].__file__
+
+        root_dir = os.path.dirname(root_dir)
+        relative_path = os.path.relpath(self._file(), root_dir)
+        modules = os.path.normpath(relative_path[:-3]).split(os.sep)
+        return root_dir, relative_path, modules
+
+    def __init__(self, strict=False, payload=None):
+        working_directory = os.path.abspath(os.path.dirname(self._file()))
+        self.wdir, self.name = setup_dir_by_class(self, working_directory)
+        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")
+        for (q, _) in self.questions:
+            q.nL = self.nL  # Set maximum line length.
+
+        if payload is not None:
+            self.set_payload(payload, strict=strict)
+
+    def main(self, verbosity=1):
+        # Run all tests using standard unittest (nothing fancy).
+        loader = unittest.TestLoader()
+        for q, _ in self.questions:
+            start = time.time()  # A good proxy for setup time is to
+            suite = loader.loadTestsFromTestCase(q)
+            unittest.TextTestRunner(verbosity=verbosity).run(suite)
+            total = time.time() - start
+            q.time = total
+
+    def _setup_answers(self, with_coverage=False):
+        if with_coverage:
+            for q, _ in self.questions:
+                q._with_coverage = True
+                q._report = self
+
+        self.main()  # Run all tests in class just to get that out of the way...
+        report_cache = {}
+        for q, _ in self.questions:
+            # print(self.questions)
+            if hasattr(q, '_save_cache'):
+                q()._save_cache()
+                print("q is", q())
+                q()._cache_put('time', q.time) # = q.time
+                report_cache[q.__qualname__] = q._cache2
+            else:
+                report_cache[q.__qualname__] = {'no cache see _setup_answers in unitgrade2.py': True}
+        if with_coverage:
+            for q, _ in self.questions:
+                q._with_coverage = False
+        return report_cache
+
+    def set_payload(self, payloads, strict=False):
+        for q, _ in self.questions:
+            q._cache = payloads[q.__qualname__]
+
+
+def rm_progress_bar(txt):
+    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.
+    nlines = []
+    for l in txt.splitlines():
+        pct = l.find("%")
+        ql = False
+        if pct > 0:
+            i = l.find("|", pct + 1)
+            if i > 0 and l.find("|", i + 1) > 0:
+                ql = True
+        if not ql:
+            nlines.append(l)
+    return "\n".join(nlines)
+
+
+def extract_numbers(txt):
+    # txt = rm_progress_bar(txt)
+    numeric_const_pattern = r'[-+]? (?: (?: \d* \. \d+ ) | (?: \d+ \.? ) )(?: [Ee] [+-]? \d+ ) ?'
+    rx = re.compile(numeric_const_pattern, re.VERBOSE)
+    all = rx.findall(txt)
+    all = [float(a) if ('.' in a or "e" in a) else int(a) for a in all]
+    if len(all) > 500:
+        print(txt)
+        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))
+    return all
+
+
+class ActiveProgress():
+    def __init__(self, t, start=True, title="my progress bar", show_progress_bar=True, file=None):
+        if file == None:
+            file = sys.stdout
+        self.file = file
+        self.t = t
+        self._running = False
+        self.title = title
+        self.dt = 0.01
+        self.n = int(np.round(self.t / self.dt))
+        self.show_progress_bar = show_progress_bar
+        self.pbar = None
+
+        if start:
+            self.start()
+
+    def start(self):
+        self._running = True
+        if self.show_progress_bar:
+            self.thread = threading.Thread(target=self.run)
+            self.thread.start()
+        self.time_started = time.time()
+
+    def terminate(self):
+        if not self._running:
+            raise Exception("Stopping a stopped progress bar. ")
+        self._running = False
+        if self.show_progress_bar:
+            self.thread.join()
+        if self.pbar is not None:
+            self.pbar.update(1)
+            self.pbar.close()
+            self.pbar = None
+
+        self.file.flush()
+        return time.time() - self.time_started
+
+    def run(self):
+        self.pbar = tqdm.tqdm(total=self.n, file=self.file, position=0, leave=False, desc=self.title, ncols=100,
+                              bar_format='{l_bar}{bar}| [{elapsed}<{remaining}]')
+
+        for _ in range(self.n - 1):  # Don't terminate completely; leave bar at 99% done until terminate.
+            if not self._running:
+                self.pbar.close()
+                self.pbar = None
+                break
+
+            time.sleep(self.dt)
+            self.pbar.update(1)
+
+def dprint(first, last, nL, extra = "", file=None, dotsym='.', color='white'):
+    if file == None:
+        file = sys.stdout
+
+    # ss = self.item_title_print
+    # state = "PASS" if success else "FAILED"
+    dot_parts = (dotsym * max(0, nL - len(last) - len(first)))
+    # if self.show_progress_bar or True:
+    print(first + dot_parts, end="", file=file)
+    # else:
+    # print(dot_parts, end="", file=self.cc.file)
+    last += extra
+    # if tsecs >= 0.5:
+    #     state += " (" + str(tsecs) + " seconds)"
+    print(last, file=file)
+
+
+class UTextResult(unittest.TextTestResult):
+    nL = 80
+    number = -1  # HAcky way to set question number.
+    show_progress_bar = True
+    cc = None
+
+    def __init__(self, stream, descriptions, verbosity):
+        super().__init__(stream, descriptions, verbosity)
+        self.successes = []
+
+    def printErrors(self) -> None:
+        self.printErrorList('ERROR', self.errors)
+        self.printErrorList('FAIL', self.failures)
+
+    def addError(self, test, err):
+        super(unittest.TextTestResult, self).addFailure(test, err)
+        self.cc_terminate(success=False)
+
+    def addFailure(self, test, err):
+        super(unittest.TextTestResult, self).addFailure(test, err)
+        self.cc_terminate(success=False)
+
+    def addSuccess(self, test: unittest.case.TestCase) -> None:
+        self.successes.append(test)
+        self.cc_terminate()
+
+    def cc_terminate(self, success=True):
+        if self.show_progress_bar or True:
+            tsecs = np.round(self.cc.terminate(), 2)
+            self.cc.file.flush()
+            ss = self.item_title_print
+
+            state = "PASS" if success else "FAILED"
+
+            dot_parts = ('.' * max(0, self.nL - len(state) - len(ss)))
+            if self.show_progress_bar or True:
+                print(self.item_title_print + dot_parts, end="", file=self.cc.file)
+            else:
+                print(dot_parts, end="", file=self.cc.file)
+
+            if tsecs >= 0.5:
+                state += " (" + str(tsecs) + " seconds)"
+            print(state, file=self.cc.file)
+
+    def startTest(self, test):
+        # j =self.testsRun
+        self.testsRun += 1
+        # item_title = self.getDescription(test)
+        item_title = test.shortDescription()  # Better for printing (get from cache).
+        if item_title == None:
+            # For unittest framework where getDescription may return None.
+            item_title = self.getDescription(test)
+        self.item_title_print = " * q%i.%i) %s" % (UTextResult.number + 1, self.testsRun, item_title)
+        estimated_time = 10
+        if self.show_progress_bar or True:
+            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar, file=sys.stdout)
+        else:
+            print(self.item_title_print + ('.' * max(0, self.nL - 4 - len(self.item_title_print))), end="")
+
+        self._test = test
+        self._stdout = sys.stdout
+        sys.stdout = io.StringIO()
+
+    def stopTest(self, test):
+        sys.stdout = self._stdout
+        super().stopTest(test)
+
+    def _setupStdout(self):
+        if self._previousTestClass == None:
+            total_estimated_time = 1
+            if hasattr(self.__class__, 'q_title_print'):
+                q_title_print = self.__class__.q_title_print
+            else:
+                q_title_print = "<unnamed test. See unitgrade.py>"
+
+            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)
+            self.cc = cc
+
+    def _restoreStdout(self):  # Used when setting up the test.
+        if self._previousTestClass is None:
+            q_time = self.cc.terminate()
+            q_time = np.round(q_time, 2)
+            sys.stdout.flush()
+            if self.show_progress_bar:
+                print(self.cc.title, end="")
+            print(" " * max(0, self.nL - len(self.cc.title)) + (" (" + str(q_time) + " seconds)" if q_time >= 0.5 else ""))
+
+
+class UTextTestRunner(unittest.TextTestRunner):
+    def __init__(self, *args, **kwargs):
+        stream = io.StringIO()
+        super().__init__(*args, stream=stream, **kwargs)
+
+    def _makeResult(self):
+        # stream = self.stream # not you!
+        stream = sys.stdout
+        stream = _WritelnDecorator(stream)
+        return self.resultclass(stream, self.descriptions, self.verbosity)
+
+
+def cache(foo, typed=False):
+    """ Magic cache wrapper
+    https://github.com/python/cpython/blob/main/Lib/functools.py
+    """
+    maxsize = None
+    def wrapper(self, *args, **kwargs):
+        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)))
+        if not self._cache_contains(key):
+            value = foo(self, *args, **kwargs)
+            self._cache_put(key, value)
+        else:
+            value = self._cache_get(key)
+        return value
+
+    return wrapper
+
+
+def get_hints(ss):
+    if ss == None:
+        return None
+    try:
+        ss = textwrap.dedent(ss)
+        ss = ss.replace('''"""''', "").strip()
+        hints = ["hints:", ]
+        j = np.argmax([ss.lower().find(h) for h in hints])
+        h = hints[j]
+        ss = ss[ss.find(h) + len(h) + 1:]
+        ss = "\n".join([l for l in ss.split("\n") if not l.strip().startswith(":")])
+        ss = textwrap.dedent(ss)
+        ss = ss.strip()
+        return ss
+    except Exception as e:
+        print("bad hints", ss, e)
+
+
+class UTestCase(unittest.TestCase):
+    _outcome = None  # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.
+    _cache = None  # Read-only cache. Ensures method always produce same result.
+    _cache2 = None  # User-written cache.
+    _with_coverage = False
+    _report = None  # The report used. This is very, very hacky and should always be None. Don't rely on it!
+
+    def capture(self):
+        if hasattr(self, '_stdout') and self._stdout is not None:
+            file = self._stdout
+        else:
+            # self._stdout = sys.stdout
+            # sys._stdout = io.StringIO()
+            file = sys.stdout
+        return Capturing2(stdout=file)
+
+    @classmethod
+    def question_title(cls):
+        """ Return the question title """
+        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ is not None else cls.__qualname__
+
+    @classmethod
+    def reset(cls):
+        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")
+        cls._outcome = None
+        cls._cache = None
+        cls._cache2 = None
+
+    def _callSetUp(self):
+        if self._with_coverage:
+            if not hasattr(self._report, 'covcache'):
+                self._report.covcache = {}
+            import coverage
+            self.cov = coverage.Coverage()
+            self.cov.start()
+        self.setUp()
+
+    def _callTearDown(self):
+        self.tearDown()
+        if self._with_coverage:
+            from pathlib import Path
+            from snipper import snipper
+            self.cov.stop()
+            data = self.cov.get_data()
+            base, _, _ = self._report._import_base_relative()
+            for file in data.measured_files():
+                file = os.path.normpath(file)
+                root = Path(base)
+                child = Path(file)
+                if root in child.parents:
+                    with open(child, 'r') as f:
+                        s = f.read()
+                    lines = s.splitlines()
+                    garb = 'GARBAGE'
+
+                    lines2 = snipper.censor_code(lines, keep=True)
+                    assert len(lines) == len(lines2)
+
+                    for l in data.contexts_by_lineno(file):
+                        if lines2[l].strip() == garb:
+                            if self.cache_id() not in self._report.covcache:
+                                self._report.covcache[self.cache_id()] = {}
+
+                            rel = os.path.relpath(child, root)
+                            cc = self._report.covcache[self.cache_id()]
+                            j = 0
+                            for j in range(l, -1, -1):
+                                if "def" in lines2[j] or "class" in lines2[j]:
+                                    break
+                            from snipper.snipper import gcoms
+                            fun = lines2[j]
+                            comments, _ = gcoms("\n".join(lines2[j:l]))
+                            if rel not in cc:
+                                cc[rel] = {}
+                            cc[rel][fun] = (l, "\n".join(comments))
+                            self._cache_put((self.cache_id(), 'coverage'), self._report.covcache)
+
+    def shortDescriptionStandard(self):
+        sd = super().shortDescription()
+        if sd is None:
+            sd = self._testMethodName
+        return sd
+
+    def shortDescription(self):
+        sd = self.shortDescriptionStandard()
+        title = self._cache_get((self.cache_id(), 'title'), sd)
+        return title if title is not None else sd
+
+    @property
+    def title(self):
+        return self.shortDescription()
+
+    @title.setter
+    def title(self, value):
+        self._cache_put((self.cache_id(), 'title'), value)
+
+    def _get_outcome(self):
+        if not (self.__class__, '_outcome') or self.__class__._outcome is None:
+            self.__class__._outcome = {}
+        return self.__class__._outcome
+
+    def _callTestMethod(self, testMethod):
+        t = time.time()
+        self._ensure_cache_exists()  # Make sure cache is there.
+        if self._testMethodDoc is not None:
+            self._cache_put((self.cache_id(), 'title'), self.shortDescriptionStandard())
+
+        self._cache2[(self.cache_id(), 'assert')] = {}
+        res = testMethod()
+        elapsed = time.time() - t
+        self._get_outcome()[self.cache_id()] = res
+        self._cache_put((self.cache_id(), "time"), elapsed)
+
+    def cache_id(self):
+        c = self.__class__.__qualname__
+        m = self._testMethodName
+        return c, m
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self._load_cache()
+        self._assert_cache_index = 0
+
+    def _ensure_cache_exists(self):
+        if not hasattr(self.__class__, '_cache') or self.__class__._cache == None:
+            self.__class__._cache = dict()
+        if not hasattr(self.__class__, '_cache2') or self.__class__._cache2 == None:
+            self.__class__._cache2 = dict()
+
+    def _cache_get(self, key, default=None):
+        self._ensure_cache_exists()
+        return self.__class__._cache.get(key, default)
+
+    def _cache_put(self, key, value):
+        self._ensure_cache_exists()
+        self.__class__._cache2[key] = value
+
+    def _cache_contains(self, key):
+        self._ensure_cache_exists()
+        return key in self.__class__._cache
+
+    def wrap_assert(self, assert_fun, first, *args, **kwargs):
+        # sys.stdout = self._stdout
+        key = (self.cache_id(), 'assert')
+        if not self._cache_contains(key):
+            print("Warning, framework missing", key)
+            self.__class__._cache[
+                key] = {}  # A new dict. We manually insert it because we have to use that the dict is mutable.
+        cache = self._cache_get(key)
+        id = self._assert_cache_index
+        if not id in cache:
+            print("Warning, framework missing cache index", key, "id =", id)
+        _expected = cache.get(id, f"Key {id} not found in cache; framework files missing. Please run deploy()")
+
+        # The order of these calls is important. If the method assert fails, we should still store the correct result in cache.
+        cache[id] = first
+        self._cache_put(key, cache)
+        self._assert_cache_index += 1
+        assert_fun(first, _expected, *args, **kwargs)
+
+    def assertEqualC(self, first: Any, msg: Any = ...) -> None:
+        self.wrap_assert(self.assertEqual, first, msg)
+
+    def _cache_file(self):
+        return os.path.dirname(inspect.getfile(self.__class__)) + "/unitgrade/" + self.__class__.__name__ + ".pkl"
+
+    def _save_cache(self):
+        # get the class name (i.e. what to save to).
+        cfile = self._cache_file()
+        if not os.path.isdir(os.path.dirname(cfile)):
+            os.makedirs(os.path.dirname(cfile))
+
+        if hasattr(self.__class__, '_cache2'):
+            with open(cfile, 'wb') as f:
+                pickle.dump(self.__class__._cache2, f)
+
+    # But you can also set cache explicitly.
+    def _load_cache(self):
+        if self._cache is not None:  # Cache already loaded. We will not load it twice.
+            return
+            # raise Exception("Loaded cache which was already set. What is going on?!")
+        cfile = self._cache_file()
+        if os.path.exists(cfile):
+            try:
+                with open(cfile, 'rb') as f:
+                    data = pickle.load(f)
+                self.__class__._cache = data
+            except Exception as e:
+                print("Bad cache", cfile)
+                print(e)
+        else:
+            print("Warning! data file not found", cfile)
+
+    def _feedErrorsToResult(self, result, errors):
+        """ Use this to show hints on test failure. """
+        if not isinstance(result, UTextResult):
+            er = [e for e, v in errors if v != None]
+
+            if len(er) > 0:
+                hints = []
+                key = (self.cache_id(), 'coverage')
+                if self._cache_contains(key):
+                    CC = self._cache_get(key)
+                    for id in CC:
+                        if id == self.cache_id():
+                            cl, m = id
+                            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:")
+                            for file in CC[id]:
+                                rec = CC[id][file]
+                                gprint(f">   * {file}")
+                                for l in rec:
+                                    _, comments = CC[id][file][l]
+                                    hint = get_hints(comments)
+
+                                    if hint != None:
+                                        hints.append(hint)
+                                    gprint(f">      - {l}")
+
+                er = er[0]
+                doc = er._testMethodDoc
+                if doc is not None:
+                    hint = get_hints(er._testMethodDoc)
+                    if hint is not None:
+                        hints = [hint] + hints
+                if len(hints) > 0:
+                    gprint("> Hints:")
+                    gprint(textwrap.indent("\n".join(hints), ">   "))
+
+        super()._feedErrorsToResult(result, errors)
+
+    def startTestRun(self):
+        # print("asdfsdaf 11", file=sys.stderr)
+        super().startTestRun()
+        # print("asdfsdaf")
+
+    def _callTestMethod(self, method):
+        # print("asdfsdaf")
+        super()._callTestMethod(method)
+
+
+def hide(func):
+    return func
+
+
+def makeRegisteringDecorator(foreignDecorator):
+    """
+        Returns a copy of foreignDecorator, which is identical in every
+        way(*), except also appends a .decorator property to the callable it
+        spits out.
+    """
+
+    def newDecorator(func):
+        # Call to newDecorator(method)
+        # Exactly like old decorator, but output keeps track of what decorated it
+        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done
+        R.decorator = newDecorator  # keep track of decorator
+        # R.original = func         # might as well keep track of everything!
+        return R
+
+    newDecorator.__name__ = foreignDecorator.__name__
+    newDecorator.__doc__ = foreignDecorator.__doc__
+    return newDecorator
+
+hide = makeRegisteringDecorator(hide)
+
+def methodsWithDecorator(cls, decorator):
+    """
+        Returns all methods in CLS with DECORATOR as the
+        outermost decorator.
+
+        DECORATOR must be a "registering decorator"; one
+        can make any decorator "registering" via the
+        makeRegisteringDecorator function.
+
+        import inspect
+        ls = list(methodsWithDecorator(GeneratorQuestion, deco))
+        for f in ls:
+            print(inspect.getsourcelines(f) ) # How to get all hidden questions.
+    """
+    for maybeDecorated in cls.__dict__.values():
+        if hasattr(maybeDecorated, 'decorator'):
+            if maybeDecorated.decorator == decorator:
+                print(maybeDecorated)
+                yield maybeDecorated
+# 817
diff --git a/unitgrade2/unitgrade_helpers2.py b/src/unitgrade2/unitgrade_helpers2.py
similarity index 84%
rename from unitgrade2/unitgrade_helpers2.py
rename to src/unitgrade2/unitgrade_helpers2.py
index 8421562..d007fd2 100644
--- a/unitgrade2/unitgrade_helpers2.py
+++ b/src/unitgrade2/unitgrade_helpers2.py
@@ -2,19 +2,13 @@ import numpy as np
 from tabulate import tabulate
 from datetime import datetime
 import pyfiglet
-from unitgrade2 import Hidden, myround, msum, mfloor, ActiveProgress
-from unitgrade2 import __version__
+from unitgrade2 import msum
 import unittest
-# from unitgrade2.unitgrade2 import MySuite
 from unitgrade2.unitgrade2 import UTextResult
-
 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: 
@@ -109,31 +103,27 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
                     show_tol_err=False,
                     big_header=True):
 
-    from unitgrade2.version import __version__
+    from src.unitgrade2.version import __version__
     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)
+    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)
@@ -143,12 +133,11 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         q.possible = 0
         q.obtained = 0
         q_ = {} # Gather score in this class.
-        from unitgrade2.unitgrade2 import UTextTestRunner
-        # unittest.Te
-        # q_with_outstanding_init = [item.question for item in q.items if not item.question.has_called_init_]
+        from src.unitgrade2.unitgrade2 import UTextTestRunner
         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)
 
@@ -157,20 +146,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) )
@@ -185,10 +170,12 @@ 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") +")")
+    from src.unitgrade2.unitgrade2 import dprint
+    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
-
-
diff --git a/src/unitgrade2/version.py b/src/unitgrade2/version.py
new file mode 100644
index 0000000..a0235ce
--- /dev/null
+++ b/src/unitgrade2/version.py
@@ -0,0 +1 @@
+__version__ = "0.0.2"
\ No newline at end of file
diff --git a/unitgrade.egg-info/PKG-INFO b/unitgrade.egg-info/PKG-INFO
deleted file mode 100644
index cc1c911..0000000
--- a/unitgrade.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: unitgrade
-Version: 0.0.5
-Summary: A lightweight student evaluation framework build on unittest
-Home-page: https://lab.compute.dtu.dk/tuhe/unitgrade
-Author: Tue Herlau
-Author-email: tuhe@dtu.dk
-License: Apache
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/unitgrade.egg-info/SOURCES.txt b/unitgrade.egg-info/SOURCES.txt
deleted file mode 100644
index 9026e79..0000000
--- a/unitgrade.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MANIFEST.in
-README.md
-setup.py
-cs101courseware_example/Report0_resources_do_not_hand_in.dat
-cs101courseware_example/Report1_resources_do_not_hand_in.dat
-cs101courseware_example/Report2_resources_do_not_hand_in.dat
-cs101courseware_example/__init__.py
-cs101courseware_example/cs101report1.py
-cs101courseware_example/cs101report1_grade.py
-cs101courseware_example/cs101report2.py
-cs101courseware_example/cs101report2_grade.py
-cs101courseware_example/homework1.py
-cs101courseware_example/instructions.py
-unitgrade/__init__.py
-unitgrade/unitgrade.py
-unitgrade/unitgrade_helpers.py
-unitgrade.egg-info/PKG-INFO
-unitgrade.egg-info/SOURCES.txt
-unitgrade.egg-info/dependency_links.txt
-unitgrade.egg-info/requires.txt
-unitgrade.egg-info/top_level.txt
\ No newline at end of file
diff --git a/unitgrade.egg-info/dependency_links.txt b/unitgrade.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/unitgrade.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/unitgrade.egg-info/requires.txt b/unitgrade.egg-info/requires.txt
deleted file mode 100644
index b8b3f85..0000000
--- a/unitgrade.egg-info/requires.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-jinja2
-tabulate
-sklearn
-compress_pickle
diff --git a/unitgrade.egg-info/top_level.txt b/unitgrade.egg-info/top_level.txt
deleted file mode 100644
index 5f808ad..0000000
--- a/unitgrade.egg-info/top_level.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-cs101courseware_example
-unitgrade
diff --git a/unitgrade/Report_resources_do_not_hand_in.dat b/unitgrade/Report_resources_do_not_hand_in.dat
deleted file mode 100644
index 9c15fa98decdca1da9d38c1989086f8c4c1ce960..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 64
zcmexsUKJ6=z`*kC+7>q^21Q0O1_p)_{ill=8CV)vYp3WjFfcHDl6clIp?P5j1EVbK
S4&8?J^4mVwGJ+&nBBKC!^%DsI

diff --git a/unitgrade/version.py b/unitgrade/version.py
index a23ef3f..a68927d 100644
--- a/unitgrade/version.py
+++ b/unitgrade/version.py
@@ -1 +1 @@
-__version__ = "0.1.8"
\ No newline at end of file
+__version__ = "0.1.0"
\ No newline at end of file
diff --git a/unitgrade2/__pycache__/__init__.cpython-38.pyc b/unitgrade2/__pycache__/__init__.cpython-38.pyc
deleted file mode 100644
index ac7b672193da207e651f61b4bee3e1791e27a656..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1373
zcmWIL<>g{vU|>*7S4^y8Wng#=;vi#Y1_lNP1_p-WAO;486owSW9EM!RC`LvQn<<AW
ziYbLVg(Zcxg)xdbg)N1>g&~S1g(HQtg&~SHg&~D2hb@;qianPjiX)dZiZhohiYu2p
ziaVDliieRQg(;XpljkMKHciG`-0|^csYS(^`FZj2ej&*qdqFZF%*MdLz{$YC;0$s{
z9>^VxDGWIbwag`qSxgI<YZw<Y*0O-vEHx|(8H=?_7#FaDSd0ucOhpzYY$;4NjLl4p
z3?=L}j48~`O#NcDtToJ895oCztRUC-GBYxSGng_2G6XS1fb?XQu%)mygMAsypvmr6
z#K^$FP$dvvlv$FQm#&bUn4FQSr>A#|sXXZxOHNg8;!4I_+{yX51x2aFATLz0y5#4j
zDr$1x;)jXG7i1=9=cL|Z$}hgfQjl1Zaf>}AvnVeyH}w`<YDH#oN%1Y#-0YOhqFby5
zMVWaew^;HEQuA)Hq?G0sXtLd6%TLNmO)j~`nU<N88V}aSUY1&vlwX`$#LmFLaEmD=
z?-pa)N`@j)1_p*-7S2{Np~b01#W5wN8L2TY`N^fZsd**EF{OE#CFw<pDX9pSQA~V%
zW?p7Ve7s&k<t=Wo=i<wYGD}iH0beWviULLsMjl2UMlMDc1};V(Mkz)Xh9YqW28Lu%
zz<?BhFo+F`H*h@hFfcHbFk~?<V5(tQ$QaC^$>^uaT*Se^z)-{qBDfhC7&IA+1VL<&
zlfmvT5(9aK2jT=ssDKm{Gl7g}Dw06Ak%fVQ0hE5hHufP>1|v8%FoSF^YO69TVX0wA
zVQOaTm#bx}Va#H!VM<|6Vd-TGXJCTH`eKG~hG1y?hcgs*u`radWpfoZF*4LLGcr`k
zm9VF<)-XWQ5F}-ku-7nyQV1yBq%hPn*D*&hL^2e1MKI*Cq%Z_CfG{lO++r$9DgwE+
zh!vEMltPL!Q&SX5@)dIO6H^ot6_OHD6d=h%0TjIoi6vFJo@ojt8L3cyK|yL_Q87qI
zQmR5?X-R%=Vo7FlVopw_LV9XmYEfcIYKo3RWqzqba$=rBNl_(8X-aBNYDua>W{HkM
zeo01ZQF&%@szOSBc^=f(ywq|9XqMCD04E}}=qcg@#RdyV`7KV@isaOSlFa<PB3@9;
zu|Q%Dl=O-~DdZMoDkKKMaS4t_E=V*Mr6#6;_^^b;#KXwM$it|{D8R_Y$iXPXTqFxJ
zknI+mM`lV&YThmO+{&W-(!7*gY`JMU`T0e+SaOR?b8m4vCl-{H7G>t8-{NyjF3BuQ
z4JgV_2W2=-#t=>3C?R;#HqwK7s|b{CAf5sxR&e?O+jdJ7Nil+1BnL{3@*qM1L@0s?
qB@m$uBEVil5Fk(8;;_lhPbtkwwF4#oVo+M-VdP-p;^tuG;0FL^J4#Xj

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

literal 1400
zcmYe~<>g{vU|>*k(@YFyWng#=;vi#Y1_lNP1_p-WAO;486owSW9EM!RC`LvQn<<AW
ziYbLVg(Zcxg)xdbg)N1>g&~S1g(HQtg&~SHg&~D2hb@;qianPjiX)dZiZhohiYu2p
ziaVDliieRQg(;XpljkMKHciG`-0|^csYS(^`FZj2ej&*qdqFZF%*MdLz`?-4;0$s{
z6UZHmDGWIbwag`qSxgI<YZw<Y*0O-vEHx|(8H=?_7#FaDSd0ucOhpzYY$;4NjLl4p
z3?=L}j48~`O#KSAtToJ895oCztRUC-GBYxSGo&!EFt9K*Gcz*e2^caIXBaRrf?*^B
z*qpi&wiLEzu+M`TG}--%7#SECsszG|GD|Y^(iM^ulQUBF^z?2ql_%X|$*IasT*(;4
zot&RrP?TB>@>UhAOMYIeq9*4pewb){L1uDxPU<bD{Nh_I1&JjYx7brMi}Dh4Q*W`Q
zR%8~J6yIXa%}&WIy2V;hl$lp@izUAxHSZQnN@;F^CfhBx{G_bZ<dR#QX_+~x@nCK2
zWvN9;`NgS4pfHPKO3Ay$n6{FkNSJ|v;g_j?Mt*Lpeo1LYs=iBpa%paAUP-ZjX<lYY
zdQoCZDuQLCA0MBYmst`YuUAlciyQ2-`0}F6l2nkX#R8x>VdP-sVdP=tV&r4wVbo(R
z5@lduNCt%nND_oWY)~YEBaMfFfuV#Ui*W%{4Z}jlU<OS_KTYN$b_NE9B2dH@fzqHR
zV-d(?uv;O72m=GdEgp#Vkl+vmr2r<7@k~Wx=r*!2Fff1&0^2wTkxUrDNrM?=bJ3J4
zyAqZfh7=}nB4Dav%wnx!N?}f6>17IMU_wd);S9kHh784S$cZ4Fp>PHZLkU~u1V)Bh
zW=4i8wG#Fe)*1##(t;$8680KqP$CIuh-64%sAaBWE}Q|O4Hyg<@>o(Bf*C*<mVj<C
z6(tpcTwcTqN=`~4MVYB73MKgpIr)hx3W*9yi75(@RH6WiWrf6&s$9=Bg_4X^D8HZ}
zHL<7|q$4R+A+fY1KR2-?GdVFQr&1w3H7~U&u_QG`N1-ymR3SMrPobo!5~MUGH7B(s
zRUxxPM<Kr?BekeJvp7{DCBHlmYHMC<xdJpdYI1<n5?W*x@q*%p1*H5Ir)x!WYC%b6
zeqIqMo;6t@@d!#QMM5BDjH!_L1f{|vaHMiUBDE+rF$ENj#UMcjMh+$(MkYocMk7W(
zMlMDUMg`^~X$A%cP)hg6Oi4-2yTzVcS(IOzmvW0OH!UYWzvvcAZgFYuEl%gef|Amr
z%)Inle2&Q_nPsT~MfvHVe5c76qRAU21W)8fdQfi_fl?8~Q=p^^PEBCjZiyl(Mlg$H
zK#5frM96^%c@UuhA{0Rc*lP#^<eys{Ho5sJr8%i~psY{~N|`*294uVi9IPDt05~s6
A&Hw-a

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

literal 29204
zcmWIL<>g{vU|@*7t&@1Wo`K;ph=YvT7#J8F7#J9ey_gsnQW&BbQW#U1au}l+!8B78
zGni(HVo704Va{RAWs72Cgs5SUVh77{L~(#=&L~bW%@xH3rn#fI!8A`4518hS;sw)u
zQG6*ZDXc9FQT!=vU|JxB9ZU<RaHMdyFhmKtGo)~(aJMj|a5pnW3A;0-@TBmzFr@IN
ziZnAviMlhS@TKs#Fr@IOiZwGwiMunT2&4$MFr)~kiZ?SyNw_nl2&D+OFr)~lGG<9O
zGe=3eGo*;5h_*1Kh^9(4Ge=3gGo*;6h_^7Lh^NXlGe^m~Go(nQNVYJfNT$lBNcA#D
z$+<J6NT<lOFr>&dGeya#$fn4(FhnV&$fqc@FhnW3Go&b{D77%8C^a)hDWx!`DCa2W
zszj+UGNh=asJ1Xfsivr<sJAdgsik<OXr^ejFh;4TXs773FhpsjFsA6{Xy$4~X+gtL
zJ4zcIE;>;<DS9dTEeuh*DU2xwIqbQ5QF@FF?hGl0DMl>}DMqP`S^CY)Q3ffDDaJX5
zxkgb&U=!f6;?9s_l49DzkYbw3m}T6|9A%PXmSWz*5M`Rem|~G*mTMkmo@)_hk!u-c
z3D#+u!=7suWyQ#lYL#M@Vx3}>Vw+-@&eF^jWu4-k;*jFl!Wd=a&XD4i;@rZJ;tUN<
z+Z2}+*A|8-yA-z+_ZEgI`&9c>yJp5HyA+QU&lZL#hZLq@22G!;7OwQn5{1N+6a_s6
zH8lkgCpkYiH?u@RH&;Q)zn~;DKd)E`CRI>coB?7h6l4}CWabr@B<AFR^k^3sXISa$
zr)QQpq-U1oBqr%4=jRrbmZa*Xl$7eFWb2odW~Azu=4F<o7bT{o>Vd4$)h#Um^SHQP
zg3`L*O2%6p!6ikRdFh`1$&4T&C<d{a85kIxK{)`FQA!vVFxD_EWDI6l$>^uabc-pk
z;1+99eraCHO2%7^6)PEvI2jliepxwN#e^2878S>UtdDWYPcF?(%_}L6fjb1jGD2eN
z6;$5hu*pfxO-f0$6J}sw_zZGL5jO(^1BSbpVD92zU|=X=s9|Vk3}z@|VPIg;WW2>(
zT$)?N&cFb157<#fAoqif5&?<xU^5ekUm>P46|pifFhsGY<>coV;WS(nZaBz+Am@WH
z$Y2m39FPJG3=B04Sqxc>wM;dPHB4ztFo!eU;*5_^&PgmTj*q{^5g(tIn420OugQFi
z(K(7EDX};;J|(m077Iui;wMmOgFSXjs5rHxv;ZU@pHvAkLmU)qpa5ZD<X|Zh0(ltZ
z7Gw-^6S#N-g-I$y6k`fQ6cZ@BwJ=06r!WUIXtLa5^T<p|NzKEE08rup`v+u23Mff1
z`GtU;wUY4`OL1yW8khqiK!JaYB_lH>RUYIjki86yRooDx^+4i&nk+^93=9mnxZ>k;
z^HWN5Qsd)q@x;d$mL}$aJRBci1o9BXIIzFL1jyhbP*RbDnajZl<|iZj6T}AD3HGZB
z0|Nu5UsG6G7@}BGSX0<q7@}BH*n=4~Ic~A}<fo^n7A1r9g3JJ65F3QSeg}nW2}2fR
z4MRLAE*avPQy5^e$#RRixU%>bTX9KBerd@qj*`@(+|0bhoLkH}`RSTWMPeY|vL%(K
zrKJ`jc?;wtP~>OkWtPOpD}%fR3SkCD4#p~eh<o(n;~}yb4g)1Lu)}1aiEII54dX&a
zMo@xdg0T@!WG<2gIfAvkD6=HB2o!`ccd_TD78fU`r=mHmNRfeoK^@^H9>yvjsGGoM
z5J)Akuz{Eg&MTat3<D;>9%oI<DJ{;>2H5}#WCkX<`Cth@O*U{UDUtwblLQe8AOhs9
zB2ZXCOa_|=CP0Q3Nii@mD1nRwRp%Ux94s6xU@?p|0uE@9LNl~9lEOTPshuH>5nMHM
zMKPyvr?97Rv@k}oq;RHifl^F60}DeGTQGwr&n-^p#DbDiP<iU-rpZ(Uii%rorFprf
zC8_Z60eKEoo`50@l<bQ^fnNhkM+`MgH4O2LB}~l>S<E%eH7tFMj0}h<W4Xm14@pr)
zs^GXQE-gqcDguRqCM!5ifh~kcvLqIz7vEybE(g&o8H@NpVTA}6kR}6=cR}I8z{tkP
z##ki;cRW0mg<vEzkn6$8EDD;;QW&zCiUdj+vzYQ&KxJDELp(zXb2CE?Lp+GjT4Ykf
zR>P3R(#%-G7|)c)0b+w#HH<|8C5&0@H4O0_AoV4T@tojL;HrV86;19UHITEVK?Eo)
zi$Gy^i!;6$TxDhEgS`rlPjFsKEh@Uj7GGQfqFEsnUotpCQsYyLit>w!p=rEGA7mmp
zG{6KXselUL)Vz|^qWE}IP{4r7MFvI*Mh-?cMm{DECKg5xFuO_^Ihde2;E@X}CP2x_
z9b}9VIG7fIav|dariBa(m=`iYa%BP|I4D@-LBYdbq*ud`#Zkf<&xwd|u3K!W6(y;8
zDMg@Maf>58wWKUDr!@5zS8+j3W=T$FUTQIV2!Va33-X>Gs6vF4HANaA0kBuW1lYeE
z@$sn@pn?V*ogg6wMiEAkH__7qM42XIh$cJMEC@<SMJAvm$qTK-l2dbX;^UEWq!!2l
zAUldcWiZH*#h{eO!6?GY#RnF{$dRCw1}?QhF@afXgKH=*cw88vL;);+fukS<90gen
z3m6wNfTEz5DTQ$Xa}Co%##-hQmKx?}##)vdh6Su35k`g@h6GS#v6ZmLgVHKzkxLCj
z7FP*-Ja-Lq4MRLn4NDC}JTEAcG@1NvF>-10fn%o#6wyV-pg>^B%FoQZ#h+SHQk0ln
z5}#L^o0M8qTx19e0<`oD3Wy?jY~5nZFD)r3ExE-G)dS1cpy<2B3Xbnv%q0~iMb;p*
zIN=01U_lY!4N7vL@M2)(W8`AwVB~^EC<hZ8BT~vW(t|}ltnx)FRzU_KMIG20unnN1
z(F<e)C~7zui$HvgXahwnC>In@K`BT<{iP_D6s9QF6y_+l6h=@VDT*V7C5kge23)*?
zs$b41E^y(>5XGG$3oc$6qj*x}Qn*uiS{S2vQ{+>4Q}|jKqxe$zQv|^MB*7G+7KSK+
z6a{cUhA~PI(tn8(N>K#&To|K-Q>0R)TNt85z{Rv^FoUMjE!IHKlGI$kB2Yu-`NJxa
zb?y&u*}nwwP|7<{CI*!_;8HpTnu<~wvssGdY8bK@Qy8*2z$|d7ohJkrGpGTT-wg5K
z44%bW!w}B~F4@>iIGP!<IBS?{m_a2wC|!ZgNT^}RVyj_@=K`gwl}r$KX>#9UF3Hci
z#a@zHT#{CrcS|6#xHz?_#K$NoH7Btovn=%%H$=o0)KG#H@F15K34#(KM`3AdF{md|
z1gf*amBcO9lFX8vR81C0UEu~wKA@CUqzPhyb0{LNK@~(2D6T>698kf)1xim$Tuf|C
zpp;d`2M$7bMS+t0KmiF#BH)4r)Ybvj3n>iQoJ9g4Rxl`k!JF(%Q9|(rMXAuvOG-T0
zjYXi0TZFBZz#m_nn3fu!o>~G?Spae)IL$F~fhsXksJl>AC4-_8lqx|Oq#A_5&g%n3
zD>Jwf;{!Rambrv+0aFR6fM8t6n8gBSF)d`2V8~)w$XE;Fvz9O}V5?zCVH9Rq$heTP
zmbC^H#q2e#HO$#8MO`HvDNHrYvl&vDYglJ9%w=h2WMnAeNMWgAS-`oFVK&2DCXfgy
z@@p7tm>_EBGNrKgGD9kRO*X%mpwRmz?U!GokP3=ih4RdjjLbZRlKh<1qQt!9RD~)@
zYlXc0qFjaiG=-E*P&+aeBwU_Ytnf?HH76C+>C!FFEKWs|Eml~`c#Ao=I9-#w$O#nX
zpi=S{b7E5QE%wCX#G<0a$|#n!oWznSmg2&qk|JJEI^qLYobj;exy4#gl$lp@i>)L-
zC$qSu$Q4w{uz?fQEe^OMj?{{R)Z~)X6tF$FSU@g}V$LhdMJiT6CCV)>NDB7LFUl<i
zMI<D#fvQ|NMiC}9CJsgsMj^&30Z61G6r;o^$Qz)93yx1vsZ)b9J`u4AjZ2mqmW80E
z7bs34Y)~9dC}B%stYMzblmbc#VDZ^Z(3oUPVXk3Wz>X4=9N?IQ=m4b<xDJ$9t&+zR
zp(Xh_wpFs$3Mr{&nTeo$s{o42yaK)4#0m{i_-Wb}flBu(ejNo=Q6EqgaDqd+2ow}W
zexSJZ2SpxpZem4I0Ein1B7#5!D8^Pon~T990Z{b_(H#onf<h7!P2d>ffCRdaQ4=VB
zKpj|6cZ7{mijjwjk5LK~JJ6y4rVt};K;3k3+^oQx*HGgIl)sR3B1~4CVIiY9gERv;
zCxXJ72^53yIAp6~0p-Glj44dnEJaI7*i)E6c@dK5O4z}<kOL*|K#fi&m@1U`O1J7U
zc+^+vY6q?-ia<3VI0}luA<hK}Gt>|-3I_!tIK)A@rwBFJiy}a>r~zE$!oa}L3kq9A
z+LvNfViaN&V&nsbt{8IKM-=`T1um%21&1=IXakjGu+AvsEfJIgwji-GCqFR-Yw0SC
zToOYS&Hy<MR3I@hR!Kq}gGCi?_kfCCP{jrwOM#>;Yz4az!q9lA&9mV)GgV2T+YD3W
zhEipN+zG<qkN}PJlrW?)HZwLcf?S}<<X6Q9s!kP>^HWk4GE$3DH5qRS`{kE-<`zK8
z%+wTDP)7mQPXP6^AWjCy8aPMrL5sQg#JuA2)S~%tM>1B4KpcsxAQ{wz0M$Dn3}S-<
z1nfRgZmMBezyK;e7BWFfe{d*iG8TapXflHf)*?hU1-k-FfStku^2{P62XH|g01{3H
z4T6EJ1YuCS0Hgy{f)rOUGBBht)^emU)N-aUr7*WJ)N+A)w+yx1poCM)QzcWwQlwMD
zn8F6Fs+ek6QrLSLYdOOi@~T)EN|>{`incH^)bcViRK?V=7B8t`E1puqn8E>4U&5He
z3F_L+W=P?h%Ur|T%*4o0!(GDzl1t%EVaQ>v<tt&V;akAAkO3rC!k7Y;tKmpvVq*wr
zh-6sA7R(UNV9JofP|I7#8^I9CkjE4OYB#WhTTI7lIBOW<*=v}J&($y&T`OTs;RTsg
z!&LMLW>XDw(YqS18cvXSl|&8e1jb@ef0Uz!vxX;yua}9DA)FyE1LBtnj751+-+0up
zO<*hzLh=hg)Gq>anL%ciFxEiqf|?DpFNGV)^-RHNE>B?u$p$lM3i=g+IyD&C1(aw(
z@mvgQy+aZ$BXn>Rk}yDtSHRBBP9ZYCv`7KcQLtLc2rgnY86jx|oHD=!D6((y6=&p^
z!>jIiQ1M#~N_?Oayh;O-R6q@>g8a<9l43oZoc!d(oMJmYRBhxr)eYoSS7<W;>Rbhl
zy!?_>D}~&|N`;KXvQ&kn)YLqMf};H7)Z*gQ6l;Z|)Wj5plGKV4h2rF*%z_e4tD*!@
z?Z#LHuB5;|0~1KzgEckc*MRZ?(cXh=yT!1Q5j>7i6~tvrZBQj2o{^fTP*PNxnU}6m
zlCMxynx_EDoeJQwUIq0kX?2B4P=ta@q>_xH)N+NyJOyy0%L-iYR0UGoQMN_qpg?7U
zq#01iR>_8>7MH+cDXl0!7uAuv>Iy0Osl^I;`6UXui6zMy3b5c)C`v6Z%_-4S02=^t
zwkBtkczkkxQBi7g3AB)e71rR?S`-Irn{c{TB&UMsIv^buPEc<-H7PMUJBlkUzbH4c
zBtEqw`IZ18{X)vyqIi(w`N1XQE%vh1qNM!d)F@tXnuWOv%7vE0Dd6ahVlPN6E>6tJ
ziDE0x%t_5F0e5?%I12KMi!+mQQX!#{2&$n${hlaxs1I&2rWU1vM8OFUOn_4#7b52@
z1*JSttBZk=1=QbW;b387WCF1m1sDY&VvHi-@gp8a4n`#=E=Ew(mIJH;G~mL-$Of+P
z*%&z(g}~}K80Fy2UW7#`SrJrXfLsEqDT=Ka7#ON}K$Xct25`xy!NO3&n9WsW!pKm|
z$jDH|1uj)tK%@0347H4PjIc5lJSoKt>2rdMCQT-A5ErF_!WlY#l!+w(Sc{YMi&C$F
z{0?#k10xe752FC11Y;F9q-X)lYcl#FAvaAnH!#o?Lmx>3_xM150k^Ae@qv1;xrrsI
zpdMjvY7uC-u_zrh4Z~KRnwg$a0`Afld4L=i1|lLs1gJ4p6b)j<fCx}RgLozj#LWf~
zpus()DjnSI1-ZY-j)8#zWJob+gbEZlptyu$CO$q6RxVyHZZ2*PW)2oEW)5a9L$D5v
z@efc94=Uk{K|?*5!&cDA2F?_=6!sRzDAp8?U<OUDTU>zwpner-SOO)IL9IGaM1umR
z7^OV}noDF(WM^Vv;8K7B_td=9qQsI^SVk_-$V|>q$SejGJV~kGES;L7r{Gknkdm5~
zSejF!qmYzek^w1kL4)`upt34op(F#O7&2v{P+ANsy1>0Y4Lv<QO@+i_h4R##91vZU
zT2fk+rvM(5EQUKHu_#rcI5jT?WG%FCkB8J(3L3?!sS40+2`w5Fl2UW>%Qf{BJo6Ot
zOEOZ66w339Qi^q;uBa$cNQZhWMIp1;iVJQ{QEIV*E!;3iaAPbU;!aJtqLPXd1zQD;
z#Joxc*dz=rbP&cSCgqo<BJ@B9-(dP++%(W+rvj)K4xP=>g?g%_qC^wnEYS3q9;k@d
zK=r#uQ7Xt&6(u?fP!lzE6l`E67PK6-Lo&z;61r9jkQw2`9B4Qzq~#ZZy`5N;S)88-
z_iB|Rdi;YLxOxg98Sn&=S*!pm1XICL19m8?8~rpH!Py>b-#`R4-XKAJ50w2u36z1i
zN*<AhVRO;YIEJW2=@^14YEa?^Cu|U>1~wuD&YaLes$0xOsl`RMpnQvE$nzE-s`KB%
z9RupAz%!H{sw&hD1E{wID%8R50CkW{7-|?(7<(D}`D&SJz+=X>%%GNNAVUyC1Vakb
z0w&NnaV<*;a}5h<<hX<dOtXUKYid~2Kx4$LH4F>bApC`(nN()KBGBj|q}pW%k9HU3
zf&63vstEaua^nk%^3#h_i;Lrv5{rr~K~kWit_U=^r3o2b0oP$gpklr#AEb-180#P~
zsKomK3I@=84+A3)qY!A=j*)|r2Q^4g<I+!)(G7EY4eUga6TlTVI9iYhaG9CQz`$@9
zWF06NIT$(kIhcz;Vz^61(6}P3R7?f0p=n`g22G|hgG)x%6xLt{O}1OY{zWONMX4#y
zpeb?RRPYEoMn?*i?!fT|8esq}P*@0`IbyoSot&SOlbQ?~N-4g@4K>asGr0uTs{#*`
zvV!K;i_yGwi#s0FV=hQ6N{x^I1@a!qCI+S|d8jeSuF^wNi;}`YK?1^H7lOvyN*HRG
zL30qGR8zy`!Vt?>%UZ)y!<xlp&QQxzC;*v#uVHavXlAToPGPoTC}Cc}QUmTD)-W$*
z0nK>$q0|l_XMyq#xZ?nt7folVVTcu|Wvl@WPO}%W)G$tDDg<d{)MP>$;Rhvn&>9Xs
zgImnmsg>y7=duBf?SYbr9U~(H19+x}je&`QgP}?vdkEyEmdD2<IuHo`prFi$L}h%u
zChIL0kjb}LvQsOIi>g8Cn5Cq$AoUh|d_33)SYijoO;H)Bw&w&llv6U3OQM*vi*GR|
zp*gmwo`HekFDQ;c2@;gzL1|rxu}T_`OEKq?Z*ha|$xSWE$WJLM2jxJJ!AO>Y!VJ9N
zqNtdGf#D~}Mo{c>FfuW6F@eQ!C;A-psSu_pmK5eF))bZ~wiKo)_7v7Ajuh4?&QvaN
zvjCJKxKp{acv3i0*umL@JCzGO9RiZ!P36tvN#O>~JvW0UMZinIqWB<7zoPiT8A#w3
zZy<F1-@Pcmw4h2bG!Hzmo}vJo7jOgjE{g0K7#L6!6{rCN@)?LO1`TC(Fk~^LFk~|o
zd8IRSFvNowxwSBWCvBKhm|8eG7_t~aX%>V*Nza8LR;-o@qzhD5b}*!{^nw>66dHlV
zf*CYfQ7r_eV$d)eI2D5$U*J?MQ_Bd-(x5dAMJy#uHH;<9%}j_C4UQR2mRszZdBvcy
z<|y{eVsI4R;>s*8E=>Zn!7a3vOhpx-l*W`^0@ef}K&hpuih+Sa5R}3}1qdjGb1`r+
zRH>r`onB^1YA#ae7?HLyvLeV6!k~l!n$ZV)LJSlhDGb@{MJy!@9Sk*$%}huc65JF8
z6^NRQx7gEDOA<>;ii%o6X%8_#hU!jGynx)v!Jx@l1e(CnWWL1~4|X9WJFz7e6r|>*
zK+Cu&_FPEOd5h5#;%%_OATw{Vf_3qNd=F|@GJrZIjB<>i5%(%#EFpk<m<?ncczz3M
ztpa0F2Ll7cN=WzN7Av@g2yp=-A9XV@Fo=Qd2PFUoCY0a=H4Q+*;KCEMhyye*1x|z_
zplP-&(3Bf!I0#<gGv8tbFPcJ{2Lt;RY#o>YITPH~lmgia3Q3TkxfrX2P<;zpazv_U
zL9<BEF~eKTWr;cHUImqB3LtAie!}8akaxje1(oKYp-S*DAjA|b-nhjAS_GtmFc94j
zAZe8F1lbG9&|phIeI8JFx-i7bff8sIV-`~}TMc6tBWQI3XayvQ9nVzA26hT)L`svT
z2ozo5G<QoNBe6I>IWZ?EH3hO7sb~VCuXu|El&~O9hll$uagdAR6LWIFi8UTp2o-C9
z`~b>*4B&PO7h{zwYHZ-przwD~{}?4ukXTfbnV6GP84vD#rbMxofSp(bDuRn9g7Ow9
zuE44D7Dqu*enDzcNhR2Cx7dnPOF(N!K#>LZQPE_Odax%D1UMOiCPP?2P6w?mLhmaw
zF>-ORFmf?7F><kjXbzSlka|tVTb#M6C5hmY33pvlgr%-XXNY1=XNY1;XNY1?VUFTR
z<%EpaHZw+Xr9!%rpqhajx=fe{vPd|JH$@CSVJ;3{3d|VA4_N{nC6FQkpE3t^B_(gM
z1*I0`7nM};6oF|4aDCzT5>x}ABqdNX0wq&$QUY~yp-D+9hN+gZmZ=2P_+V^iDq^bv
zFL+^OfFvW(Y6;e&)Z)|<P3Bvi@C0y+JtMIgT=2~Vr6J~9%*i>$w-^g=F(NM?0S7ur
zfjKD9A$b=(4b1~_v>w=C6la366v(MyXM*&DYZLGaR&eIhWGZR~RSTekH!U+KRg*D_
zIXNd8J>jzEf+TH0)`Id7XjK~2O0WcmmGF=OHNZhumN0=9sDc*GLab#5TMM2xD5?Xc
zFKqdnH6CQEBivTTDws#X5-7HUYy{OjV2^@^LO}76!YIiA%GMydma&96i)8^Ts49iB
z*=iU-Q<yc33z=$}z_J`QOeqX0Os!0k3=0_-aF#G<ae>yyfTkvDnA4!W7*LqL{QLj^
ze@*UNJOzo#+3}gVpfpnqTD4e^SdtMRe~UF9#JI(jUwn%N%wkW;ECQ9Ox7dqPb3h_R
z3qj$|0h+!Bac{ALS2NvWE>10gcKf0@it_VIKucP0@fJZ>J3x$Ohb$1qXt9ezT@nv!
z&&R{`xPSr>6!#2_Lg2oT3}clHH2Sb=a6{>1fYKQVgF_ZHpj5(;1zH>cBAII#7O;Sp
za)CmrgtdmDhPjz322?G9R&ua|7IV2U#0tbP)w0yG)__)hu*7o~8h}DMo3khaJpIoE
z?rB0Nel(f<G#Nq5*or`X6z-yBptP|Z6jJPoNyVUmDgq7Qg9EP!G*=kKQl64o1g_DF
zW`Wc(<@wy=E>10h4YtA>(;GnTXm;qFT9jaUeo=O2UOFgrQ<F>biz<uef~=YcBG8IC
zP}{^C6o%jy0;2?z5NPoS6KFXqEEK_|YkWL-<PfFS1O+=NX@Ua}G@_cqn8J|5P|H-q
z1nLCUGS@I<fjU8MkRSrfGS{-zuz~8JTJ{=H*9WxXf}@5hi?xO^g{c>`>VgBjb`Gqj
zhFyZ8ma~Slh9#c4Pz+R4X);5GF+n9QWMDY6q*9ap76)kYIcP{GiVHMM?USFFl3D}_
zGnSIf+|(#h(1a*Rs@Sb4KNrMsPApEn#TSxVQ3B!xmFDH87TsblD$Ud60*^cwZ2<+>
zR#33Bfi$NUA%)^LkT7d;Nn%k+6l-y5W=ZNT){^`ZjAp?tmfXb5ym(LmgCdlH3ADnH
z4?O<M1x~P4+|XbKsl&+h@X!S%P1w+HCPOV~*%6})L##^-Q!P_1a|u%oQwpd+_NZZM
z2CqM4WT;`vVgZF~3X=_p%?irqS!^~8g+eLJDJ+?c2tH_7Mw8X=7I%DcVp(c@a$<5u
zY7xkTRXTb33Sh1RXizU6vI-qCMqdmXCIba}I%w;GkzPS1XzAb{P>_LAY7uB+w`ebj
z3o_{z8`N0PqFz`D0Ih|fGPqLcEk0Cxv*BUM2&$DqRRk9!4<jFw0ArOXG%Qhdpk#PZ
zF$%9UK#3nzl)5m)io`J0GS{-yFxD_<F-kJjFvHtMpg7QE2B)PWkn@Z7fod^Ua2ko?
zfaba4B2X4YN+4+2Y%>D`LpjLhAk#oA_o{@TZbi<`Om3jzIndBDXtYKMTl)t*A5xr|
zp9gW!Vo=5x%FIj2EXzzOP0WE7dBsJWKtbOKB0zO&(E<<)R45m%2eCjNF9Ju_eh?Sr
zI;2_=>~>J*E}G83z@QIuHb?^~xS@mPj4Vu`rVkS%XqcRXolAs^hl2;K8YKyXN>&gC
z7Z9LfrgU)9UBIxA!G$3<0#Z<<fEHLWr!dvBfJQ{JS&G6y#YYN=$12XSkO{Q-Dh0G;
z2PV#%0v3merLfhq)UXuufLbD;Q9DM4LY@@%1<atD5VXqQ?-!#gq#yi?u?Ad(g+K=B
zSfDF8(=zi?iaJ4|02->(WGey<MMkmZL6%}N=0q_UfCeTCb8azaB83q+cnTR97^*?R
z16l#cz{JAH16_?Nz$gQr6XIbk0;xd>6i^BPVQ`>;nqDc4uzqj}LlzULx~^ebzzo`n
zQ_BpQysu#fcf6rXSyNcDS&Do>6%u%|nk|JDvc$ESsfn=$RE@LwRXIiLYRB3uXxLkU
zaZHMqLX4h5Op3OGra}!=NLwLB&t5@OK@+4Z+BG#+AzE8E)*h<L9>vk1h7rio;10YF
z0|NuN@2gVFn8HxQn9Wu!k-`X~ixfa(tIdpgY@jw`Gi+#z=@z425om%*lj#;{i%nw5
zE#}O;5>05goiPzTU_rh1K2X4d>;(0OtCZ2!+F~1t%KXB}z))obFO~EVtb$4_h493p
zyv)3G9fgwoe1%-ld;xTnUQv_%7E@8`Eq2g&SY}RY6nmI!kduF~YZN;ubtLA1c6FrY
zL1s3=b7m}%R3e&JnwwgbnH-;-pH~d3ltG<~yeOukid)QyIT&3;(5P=G$XB3MA)w>}
zD!lj@K@*02jNmb0+<gYnQg7IxY6=gi2ybDGVutQ$VSz5GWrd6&MX{xD2Qz5$-r{pi
z2CX6ufDS!}{Nm581Wm?+2ci{{5{r^S#UW_*2nd7NAPi2Jppge?j~}#njuE^v8nl#=
zA)dK}rG#|>Xh}P$d(JG)u#mACq=p^5ZknTpsmQ5@0kjYjx~hTM&+YlFnIN#!UX$w<
zW63R!_@dH0P+Wi)f!<<DDJePu%7Gx;i$Dd&EylcCg5ddHlwtE-h?2MHB1i*B0BlCl
zRS*|kaDfSM_5>ALQ{mwa-T}eJ$i^ta$i~dVSS5}cIJnoj!mA6=s_7JvPeJ}>EK)0B
z$^tcUSU?Sz8isgK8;}*W;)Ri+gdN=WW{Bs2Hd;bJ4Zo7aqV&`fP0pfAAjg7Se2Wvb
z9w0F#GcP@gEhGc9IHG6=sA<6l5ibIJ5L|=ufSNJ!;1)+J)|FjgwF^Ps1$iE_;X{Ct
zi?K=s&7)v5P;xh@(GT|}s2dHc6pQ&v7@-TRKy6--pP7nOK<l1Ctzt$7Pyv(z8n6oi
zt!)Oc{ROiYu&1zqn{W(SYzsI*bJZ!Jog!={oLO88xIz39o&`J$LFVyFFo4Gjs}zGv
z@(T(;vyh1j#UN&C3Q9WFQ*gV*QUIDc0auQEkPrlAMM%Wo00k(h{D!nUZh?cav>+uB
z)GkZT$uCYVLhLY61}O%GY0*s(3tQ)m6FQSvlDYyEpy1-25j1rVN<UnTBH)6ajfsn~
zN&+o#;Tll_7*u?M(j_=+fhMX;7_vYCzz9l0ph*GH0whqTPGRi@ZI@vMZ>V8RVUu8J
z2DS6dz%4%ZVxJm@ELNmIWo2Y2Oe^7Bz*WPL#SIN~)&)E%Y#?@_9ysx_Lt4ykFF_Mj
zRjSoFpc$yz>ZHV?+8TxE>eQUXg5uPaTAS*kR8Si<GcUb1R+GJGHz*8QKz&s30*Xw~
zEK3w?PHJLVY7|RKYH@NDYhH4GPH_}hQesg&WH|@8e%0i?#Zpq3l3R2I6uO9D2haY4
zV}`XTF)uw85{Gv{ia?QZi?ui>HMOAVGDzSyD5FD07K^a;T0nVZ8z^Q#16K@;VvJ1x
zIhchQ*}x0LS(tbjtAx<vrKmK|Pm?*M=sW`h1E{46S}un)T>>g9z!|6rG}i^rgGhA}
zDC!^+1LqhR7^Z+M1`TL&Fmmy5uygPgfkZVKZ*j+G7U$)cfV%@2(GM!tz|jvHIZk0*
zz)->nt=t*1m_Qw(X3%aGMsQ=C#qSrRE{X}D916nV`WIvrD2GCqf39SNG!#Lr0g)UH
zDh0q>V$U!#Fcg8hcU7w3&Bb}iphkX94yZ6m&PJ|CA$xOIvJ`=`(k<rP!~*bG>n-No
zqI^xJTO2U$MMa=U0*4Bi09kcQ7$yrIH-s2|8WdEZI-G$~im~VwXqPI;7oge(ghAN?
zUhaT~EJ33wpibjLP@<OrCwk@@#w?a>wj!PyMkWSEhG0<p4n8Ez3La^RVoOgg$t}u{
z;>gT}?2ZKo2x!CtG^-RJugMg}0-E<JnuEpNvY^E`;1Rp{l8nTX_>|PN%)Hc;c#wwt
zl=C1TfFhfLQ2?Cli{60D@I?0tDDXiZ1xGPxg*wP93mIw|K^2BLLoE|%exn(@8$g^P
zo1sVrv;h~?2a{v~58yDTgVsAUEMTr-hU_;e@~dH40Gc{v1?6Q>b2y7Fo2@7ZEXth4
zmck;*kj0(_maSpV;>h9z^{i7^vzd$9z-qu{Kpk@(V+z{>t{N85@RTNdq7owmgL`U;
zLZSj_zy`FpAW;E4&RYcP(1DhPK(ev|WE4gZ958y2uz;_CNGQ(EEJ#oQ&B|n^Wu_J@
zWaO7aT2wiyWvMyEAY+S55|gt*>q9_l70NR*b5a%3Q%g!fg*?PU*s=zYL-Z6t%4`i4
za#IuYiWQW~GeAAhoSb5X+*BnUh@=sUa3$2)N(!kZ$$D_7Ip!&(<`$GxDnK?6f|kZW
z7FndGC}gIA4Jt@YQGmKLwIVq+HAMm9)(r5XBe1I=6K9~hrU=v|1NZf+IBXzcVpntw
zR6KEm)7~x6AV6|<(HT%jj1!a&!P}c5Jql1EbBiM_9<u5Zl9$-h;z0`mL5)qwYz8Q=
zX|hMLfC8Whw7vmc4n=W;=BD#X(uxvuQ^6xZx7Z-oM{$7kg8~gLv)|%|ge%zCtDtlX
zD%BV`Ktm3oC2BlOprL9OMjj?E7RXXHE*2K1qEF~a8C1N$lQL+{8+hOb)N^B806rif
zh6Oa}0O~G-1|FIji@ZR?50VTiOrROW8kPm1ZVR;MR^(N}Qp1|UoWjt|3|cW8%%I5v
zsgS^d3Jw!ZXg20aPX#rRz%xn3;1IpVoSs@z)D8-6wkW2wB5;sHwmO2Ug(xnt+IUbd
zF9IERfF2?uh`bG2@)!>e&7Yv40gc^)7Rd@Ri!kvpvas+l6@39&!+49?F|QI7>7W7%
zj6vZ6YMFwwb`JySKmzda7N`Pef|OCUOeLU0LYP1^xwVk23~C`Wg3B?VT2Kd#6*S|Y
z%~7OR!VU|M8b&yu1r$CtOdx&@%L0xXaJDYt1g$$sVa;YK(u1_63-xMPiaKgoQrILJ
zprOg`hvHa}i$O&!xS{~XB4{~akt3+g0vFY21gPW&R}unDuu4KcJ+myew4fv-HLWx+
z8MAr-6|0~W7#|Os`A^TuPfE-wh7J#c^Nl7KIGUn(l1qz<QejE>J*YjwnHCS#03H~>
z#gv{L#S4m~qEyg6dC(q8P-H`L4=77%vfW|@N7^kGkeyMiAnnCb93ZEGmK8*?f>_13
zSU?nd?DL}dgolZNp%^sJ2#R)4JC28ug%Q;I0xjSK4Iyzb7X5`J0dDBxIZ(R72whNx
z1q$Wj7A(^^pecXwv^nUM7mg@4&}9D{M)0H!OB6d;hAV};g(Hds%mz*DbAT2FWPz3f
zu%+<LVFK@aWQpQUkxT*Yd<5-;6iyLo0i75lnj!|?2`Qc;(ZUcV2;S`|6wIJ0b&ER`
zG>#brUZ`6H+RgFu|NsC0Lr@m0fD!{J8H3yp4u=wkX3&WrjG)bm3z-?gUHW(?P@54p
zje*!#$XQ&P3|_)r3?01#4`Zh$=HB7~wFN;dxj{#oK*mf#H8~_Mz{v|#3MqjCALIg1
zHCiQt<Xm{a3p_RsDXTG>J|Lao><2OnG!6=?RkIjDJ1W3DCUBzxHq6fK7scut6yzTi
z#p34Z>7&UU#RpzA2;TSMlUZDHiw(St8I+C^GjmEo3(&Cj0=N;niq+sAVB=$~5=Zs`
zk}8y;Mo>V591fzvD^5!oKzrzG7@9%DJB&3<5a(xsOO9UXIRGn}{oFJeZ?QwednGGm
zb0>Hh8ZlT6j_6xli76>=5D(nqNluQ3_dQlZca?zFQQu-tEh;KPjgng&i7Aj>F#2$B
zF^Vvv#tTdd<$fw+2em*sK?G<q0-9rrxEUE3j8WVnh8(;IPr{ZhgQjIsCL&PUk)TCV
zpw=<$K#Usjj&Ml%2}{_ZHBXR2hKG@X0XnS@Sw@T~AVG;29LB+rv~L4<BNGpI6}lUt
zics7IihWSq5u9|}KwIM&vKWflK%3rR{pb|%fL{q~78_{9fDu%uaMUuFfOgk#q%fCo
zrGR#{aHp_JFqH6s_OVMaG&6}Xh%<l+7SIlt8pfii6plQm6wX@a8m1JkY}TTx8s-%4
z65bl7W=3&_6drK~a|W=9;Jq!N?5)Y`7g7Xj!4`oUGT<`%CCI7Zwhm|mX=+|d6ia|(
zaBvhGC<D2=6kPzF{KKT6@rzTTI5jyxFQr&hlMmAO29+t0K^vyzWJvc3(dh&AwQmW4
zmJ2}k@<Nu0LPpZS8|lE~)S#077ISe)5wvhA;$Q?F##2(9np_;kRE$0qSOkhRUr=m-
z=TyKe>p?q%wOBwyX(EhO63FQXIb)#24yefvkDYbU*a58wWdW^*Vl-!9Vu%OlSkOck
zWJDP>K>!;40F60=m#Wy+fST-}5o{LFHs2IRaRyLZNSvXDC5>4OH15Hg!d%Om!cq$w
zFJmiC0oDGXPCR(bgsm5}mXsq;3mo69DeNU&DI7IyDV!1vC7^v;tj&z@_~uIChQv4M
zgaU9Z@<8?(Rq<(QX(<${X6mVCYAUD}zXYXQa3v73k{L2g2JU);#+wikUIbbc1&;6{
zAy5|Jjp6`JpA`p{<`w-1Rn=^e!O<wb^wbiURLEwX%>2At0>v5mMaUvW;-HKTHXYOt
zE&{FhL5g5d+(xm+gACVXhqU>?#S&u{cz_^^3z0Y=D>%R@f)n0g0r}<@CwR;XG*1@;
zigp=L{maD0$j8ja#08pCW8z|x01db^u`!A<X)#raA}0X2UX*GDl;A;07o0aiYd1k<
z1|&|w1M;9LHl`G&X2_TqQx<bAQyxnSGpMBp>b8O6FomU;xfXPa3qw438I2|@Bt~xW
z79ywiDg~R;JWzWbwDGC9L{A|&HB|w5Xxgp_v|dS*{gx1DO=?+YerYkttInW>v5)~R
zP;0eF9u&^tAO;6ED4e1BB}xQ5_ZW}1p#rP{qzqCSgToXYoIH>TvS9GpMP;B61z7-E
zp97x4U}9kwK+8nP8c>1}RJnmN5;z!ZpqU69j1{0&T;Rhv7{QBN8B;(@5f~9gT?y#$
z4aO|+21QWPPGPBKD&a_BE#XRGt6>6X0LCm%SQe;ZOkvMvEh<RiDB-DL1Q%_b;tY9A
zDNN$vEr#GM!Q}@j*FcRnaJmNPgI|ma;6e^uiWP}~f>9Kl=8HfJwjc=>JnREX58$E<
zeY6m~$rqf9z=aklO&3XkjDS?MQEZ?H&rOBQx`D$POn?KMFTN<XxFo+Q6%yP{px}m-
zTcGn6Kr==H%q)yjj8gxrq>z&>sy5KkEW+Sn4Wv;ka8{89`3IaLK#ij!HV~H|M1bnm
zB2dF2iX|B|*UbS=REfo@MFJpcP$60*2VyCL2xSlfUakmsI+y^r8bF=^7YTA8mxF3o
z*hC-?3m+#B3lFD=AQwM}6bBDjl_ujY!T4~{kyAN&E~&}+MTsT(;Bp3(XW<x>Y(N}v
zy9hR~0d5jAg4UZxF@pv}L1%V>8@Zqb<E*#%!Jz~41Z1)vB^`pI4wR)qUG8Gg1Qlph
zHHRUWv6h(;v~UA7x&k?Li4nBBKa;VBX*v_=hz@YNfptki4T&NqP{gv_V#>@f0yz`X
z00V_B@>wn5tz{5-kb3ks4M_Q9P<VklkDw*XY_JT4a6i1|i{cTG6F{B;XDE;{pcN^#
zjF90YP;V1d6V)(ef!YPEpuGo>HVqq6l2rxOp4^aad*Jb#B4$wJg4Q#@nmS-NgX0)X
zfa3TTcYJPQb}FP3F$3;)CeW~Vl{8w|>mjMd+*SZ`b`faZUlGm(rN+p>FbQM{DAG6>
zd02};A{Ze7iU1HU2BkYh`lw|DtuwA+jAsCkmoj6nHU@<|c%d$6`5Nxw)(-I5f{?}`
zXkg+A`d|pCFAc)r{xrx?P&EM^crAJgs--}sA6fwm?ols*_oy|>i$H63ix7S3+{E-u
zEM4oOXQ2Kkble*>#tLeTrRC>Cj0Z;&D_HA%SjaIjN-<T5VK*Ptjfjs=$xj9ifEH<i
zl7Kdd0LQo{hy^y09jbdC$V`wA85nt3I2em`LD_)$79V69B_68k7AH97<FivMZ?OjX
z<R@oqGT!0>*KQ@H1v#mp^U;zsQa$t1@<B%emK5J&%grn<PA$I0o|{-voLQB6ivu(+
z0AitT(*Y#}P*j6(F=)mmg|U{YouQpEjR`zZ&H<`wLBmH?Q3}4G@PjT*fjSI4ZkJI~
zQcw&zGBcwTd|ak}L1jrsex80ZlupXYPtpg?bLjhICh3Dl4NCI!bBgr}D!~SzCL~Zk
z1Vu0SSVPdxAy8*?Awvo%^?`F_4O0hWGjkeq8WXgQ$h?rT*aeiR(im$P=P}hV^+8Ua
zVgc<H0`>RuxN1P>P=N+{S!zJrHkkaX*c`x%Y&6+!aex`|nJJKx9<=o07C&Tx3}}wI
zBr!9u_!bvb0CbELj18Jsge*ycjE;fN`>6yaPtd^=E1AI2e~T3~WRikNP2f0Q4~lot
z^Z)~+3=0>d03#o0UP}z@5=4rHhB8>MCJWfOA{$T|G6fN!v;vkYvIcR%>53I>!YYvI
z;8exJ!pO&61X^YZs+~cFKOBR?8N@06gFd7J+BO8*LJ2;@Ac`%OJq0wd0$K^nk;)G0
z1A#`|qBy}N1Ly!<jwmiL8#2hk4Q4|IS$LqkCwNo&!0Ti|X7H!-X9=VTfez4Z2CbWg
z473QQKn7ZbQXm5@!eCP*Q>0orqC_A^<3@?5=z|Z&WsDMo9*ipvITklcB1JhxrG+6%
zGQ}WODpe|lF-2_-bBcP3Mhk0{H26SVhA0{6fw;0Mx+!`s3{i66T24NgLDTRSXDFzK
z04+{KO^cvH2$VIz^#UlmN<e)@@IJO+2Jp&4@X>&pOyD!SAZNy58`NNj9+!6r6fvO6
zhJmq45N@X)R2HQm23ZYK3AP$ko`TB26vk}kA_Wi&G#CnM=cO=7f;ZCzgB%80hr(PX
ztq=s+KMI;yfGr4C053aMfQ$lbvJ~ksGBALK(Tg$*z-w}fK&z})GGd*q;e#0hX<#3P
zdx9C<=_@V)1)LtLBHVtF0}tkcCb>a10O(*w@KiMum;@j82|AJ?7`|}CQz0=IyhFaY
zv?x^p5oqA0$r_rV$%eet)Rfc|g~Ytd-29?cg~YrRh0GF#;?&gKVuiBQBG9P_$=Q{9
znk?Wh(k%|qw%O$T+*I(YvRmwstZh^TS{Dq-P~g%Ul%a}13%O2#JPhizf>siO1~IEZ
zts<zm!OlSOEhyGN7?f~|K?i|>8WW)7Ou<9?%%GhCpzdr5=txS|W(LUO1yG9!JYuZL
zj?}0C#e0!DD0hPl12>AISc_9jLJMGR3a})&$q08dxU9;_2?i;<2zNSk`6GC^3F>t4
zoFP~liu++H4`d~{P5`Ah(9x2h<0L^Y2gMt-Hr8Z?BznZ)18DdX)U8b{a>*~xgY0-k
zb006*;*eB`k{ci=g6bjA5HWa=57~JzRVXe5g)Rt#T?p!zLPk|VGk@S6dQ3$Ups`6%
zNW<L83=X^^8Bnt42X~BpQ$c&u{1S6hp<#K8sW=6#NqI{Gz2hBRl9-p0Sd?-X<Z5u5
z0B^8hW2{m_Bu!kJP&@&0JjmPN3=V2ML+UwjYm*T&ewM<R#spbQ4qo5PT%=LM6bx>C
zfljjnb&WKci#$Qe!wN)z7V$%OC>42t1VAd#6Er9U9)lbYt{=cBfq}a~&_G9bI*OBF
zDFf_ekmn&zhJ`UBICvpZ4o;0=0-TLNE&-jsRt$<Z1}5YT1TL6R#)v>_;2{HQgMzGq
z>=}lI2s8<LftpK9MV27Xf_z^Dnkho}G05(>ARmLw#j;5VBn<WuD7S&qI>?eDF%S!U
z7$H-UTqdY=g&aJ{ki`ft`iq<)c7r<cU^X^?-{JwEsFz<_0xE7kf*b)3c1AJK*~6gG
zOlYtpD?<qjP%RC@U<ZQsHIy)bR&s(y%s^EDBgkP)DGb@nMMmIJG4SenkOx35o`npc
z)(_b6pq&XU3mH<F(m+d-8Jj_)lVFo-m?RiLt3aVU7r^>$7?8|jP6HhU1{>yQ@hbv_
z=PfqKv1H&S%bFZu>Xt}+Y96SNhLoqEQ&5Xbilg|Da+^zjGE!uLQ!Z#PK@n&%JhY=1
z#RVF*f@Ds}Kw3U%WQ-lUWCksA!40*X98m2I(ee!x#*m&qXbP5#3ADJLjgbd5xFU(j
zq0kbjxCEjLC6$9RCOl1m+Qg8Q0LqwIOy~!UGlM5n!L?_RJ19j!1}APYCf{O2KbEfu
zltkH?p*w#;#U1EGScId%ZMXQ$6b#pZTm<f8gZg-&vM!4eG#m!%Nka+>@ZK`mQQ4q*
zM@<$;c?Z&Pi#r~)lpYc*w}j&%F$dwsXXd4(R=^4kP-O+_W22VX;4?vZ5Do{erLPh~
zI2?X>HmHCAwJAXu#0EJWoN__uiNM-U&5+`mF$<J#nTnJ^)e30XDxL|d0yO?-1ro_(
z0S{`qz*Vq-s!7mx1kiHuB2d!NWJMaR1Brr8MNBRM%VEorMZSy-3_>8UfXXk>LBw33
zqgCXPJcA_>W1Wrxdkj`QftJ{Toy-ItDqva&KZ2eGY$YU_fE-u^I)Wb-;-KEbEq3V4
zCtBJr0u|~KAg6)~Lr`)-tGtslzz23>I1V1_D2@Y7*D+=>)iBy1?I&eMavV4~A<4H0
z<gOx6F9zLBprTfWfSU?ROHj%%P-X&QaDagpkAcc_aDaivdl|Esve{r&2(o)Xfd#Fa
zA@1P>b*;bzxK6QPWMEK0aSCb%2L(@Zejd30h7v{~BS2*;=q$%#P>lg`52(}x?I~Ko
z2wDkHtWW}4dCLkuWeqgnz?unKT>+X=V5w!VVXtA!W-sz60UdG3n!-}U-ps<tP{X!>
zwT2xu$5_h&%AlaL$!eJAF+olouVJcTt6>M1t!y={HEf`=xrTv-A&Vu26+G_&N!@II
zMLwV<)l%>lFnBH=w7p0H)T__TORrMHEeGwOgY$J2OJ<6KEo6ZpJGk^I0tFhl6%0;Y
zMZut&6O<sq#j++Rc&;D{dVFX+=y+V#w9KO767&u(s7HB=DKjOCGah!-3R+6J#SQAc
zLJJ!eP&9#3BWP3(G6D-4;Q}oL0G-Rk!w8-{fYyab`t&rJi^4!o^aVvdcnT7fxIx7W
z2!q(5h(t+Ppj-$Fe9-JVsJMU()iD)CfXo4%(h19Z2!lZh0^)p7!n(x+DIvk<|2i9i
zoDNF842<CEN2nu_m7tW@pkfd1CeW^XQ0spI6L>V90km>#AtQLgiXn?Ni%pyXG?E_7
zpvml4#f`XBM8AqfuOK@|lf4MOTMe>F4Yacovc(bH>;TmX*b2E@+|be;w35^m$pfG%
z8mI@5RG_#Y6sDl?0Ea1P^(rKD)G~sm(HAg-NfyvXkA;lIdL@htSdm2-8Nh33*}?mw
z5=uBg`^%b{`o(IQpzCGXv$#Ro19X&@DFgKA7tnHKW<PL=eT%6)Nt3523KUgvuis+L
zEC%h!18vj0#Q_>FP01`OMil$ESn>-}^KP*fWF}|lq~2mlDa|ban+A>OTdc{TaJa>Y
zetiabtCR&OctBlyQ0GpBQHY5Lbfyb(Kp{40p#&7DP=*H-=ol?fGXdNZ;{zo-NP87D
zhMdK`032Z8?IWPo-Aw%wwM->!3qU0WBWQpPw5u^5d@ds-Nb<N!I8&HFry4-oxth#=
zx0s5Os$`(qUQr<>u_RFe<STH`7<`11CKtFniynAvsTG;UCB;Q?pfCmPiMz!DY7Ic@
zBhVBJbULdj5u_jq)IVYYnGVShAP+(o;RZ1>FgSz43cQa3wB?400~}Udj3SV^KUl&7
z84pQa;1kO9G!-BNYoPoOX()l3&Jf3f>YO5bkj>z2Q%)cjsLNgC3Szl|2yiPA)N3gM
zt?&f5K8vP;iUUxivB)2!1k|nqw^1Oq8K~X_muHaD4xI77f^<ZJ6oV5Nc#|B+OSlKi
z?HCyt_JUfIpu>TnvoA~>pxx&zOpIJ?JnTHIJZv0npzT;Jpe<Rf9D*ER5iS<cbr>9c
zBFr4j9Na}9b5IfvsDuDva1H~dBKXA&;4s%@ECP+lf!PoOR49S3Y6$>^Kcp-I^D&GC
zWnK_22JN4R4&#F7b~-_$rwkp8@eH6-MLHPc89PAT80M<A;1O8RL1&Obqhf_bh2;E#
zO3-T3wEUvf%yh(rl8yrW<g?6_)Vz|+<is4%0@hT}7z^B-^2ACFElnK-&@#`05{1N^
z;(P_rNPJ!j$ZWk7*z}YF?34h|dR5R+6=)%4Vp2}3LS_lvu;PNul48)wVtQa96c2*}
z0))Xc4xlDKXb8BOv6iue5jIHyDf=03al&oYWCDloEykdgOt%EkeRzu}FSQ&#frb?N
zpbe0bpwI_*-<UZV*_f*IKt)kdYI-K<N{r0Bbhtjm04}m=noN*v02+DIWGu=8rA2V|
z$^@}MaePYxmx;k3tHBLcHa^hOQl_FDMg|6yMiwaAL5T@8&RYz+K>$=7fx3t;46$n9
zmC%sgs$4ao4K$3|OhsHJETH8opk1qB42%qgT#zFR6SpuToqY#S6*)NykOj%$O{mU3
z!QjKw6<l1M{ev7s{DVN})|F(Wf};tPobpRSE2Hv@OBCQ?k618_q%F6!xI`f-RUuJ9
zsR$942u(`X3i){mW0Mo}6hNT_8tg+TLeZ<FP?nhpI_3`U7LW#P5v2g0ipb2*Lvk5p
z=RN2~FwpTga3gX+hvI<_S<--pLU?9L20X?!phv{z7r{>1&;dJ66LI<-=ybU>P;SX7
zwt|}q3MlYOHVx=;J9_D<CB^xrMaik)t&kdNnhKf<$_gI&<)B=W4q8K=lcSK43A#TD
ze&kRwBy$v{GcqvvX|fi*26dR(z^inj)g(v;-0IV0hK%rn1fuwI6DyNap`J*EPEml9
zBsevSVDo7PC?$fV8TddO=|Fd3fX?^@otpz%+yvS}>j)lPhD?I9=9T6aR6@>A2ageg
z$16c;wWtJCBA)^g*FnSs5CPhgQUtD~I6>DZfoF-pZJ=B1xs~8s(QdKi7MJGUV#|eG
z8V1Vt;LE9QvE?Uar6!kvZ>=c;t%-n~2M5XtMW7R1z-JbL4^acJf(4%}1wKCnyn`0J
zV-&m_5WKG>iVw6@1T+w#R}9)`UIe<v5WJNFvJ(Ncd>g!U`4(GAC1?v(5x9N<H_t#v
zSb^8H7X1Txi3^mwL5q8$_~B-PHsYlg6@jLVi?)Llfu>=>^Fp^c!ATM{I|f>Q%uocH
zjVdw#nPCX3nz`bgK|94kGkxG$9dPXet_#2=0yrul#TGao!2~F_Zo${lgKC~)&~7Le
zR?q+m=u|HV4JScsdl)&GIN14E1b79c1^9*P8CV5m1h|E?`FuF|IJo%?dDu8uIM}#U
pI0SeY1(-Mlc$kC=c^G+^gm^eOK>M_Wn7D+6>KQ~hm^p+wm;izo$3Fl7

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

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

diff --git a/unitgrade2/__pycache__/version.cpython-38.pyc b/unitgrade2/__pycache__/version.cpython-38.pyc
deleted file mode 100644
index 1e804a3c2f2261406205db1c73302a4acb70b698..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 167
zcmWIL<>g{vU|`sqpqMDiz`*br#6iZ43=9ko3=9m#91IK$DGX5zDU87knoL!!26~oy
z27a21x47fu%TkMqGxPJ}<5w~iF)=Veh+pQ;RxzQ)sYS&xC8ZguF)sPZrManjCB-qN
ld6^~YMTse?2$oR{)C|3X%3B;Zx%nxjIjMFa%Rhr$0|4qjDn$SQ

diff --git a/unitgrade2/__pycache__/version.cpython-39.pyc b/unitgrade2/__pycache__/version.cpython-39.pyc
deleted file mode 100644
index 613bef2848d43d5e78803c81d3d366c27a5e2c62..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 164
zcmYe~<>g{vU|>*k(@Yd)U|@I*;vi#21_lNP1_p*=4h9B>6ox2<6vki%O{OYV13gPU
z13yj1Tio&SWvNBQnfZC~@hcgMm>3u!#4i*5jQreG{gTp*RDGBH<kH;Kypm%5(!9))
i^rFO+R0PXNA8LSJLFFwDo80`A(wtN~kj<Y#P5}VquqU+u

diff --git a/unitgrade2/unitgrade/ListQuestion.pkl b/unitgrade2/unitgrade/ListQuestion.pkl
deleted file mode 100644
index b201d4b453d94b66ed44ac821d72534a90b09811..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 466
zcmZo*nR=X&0Ss!VX!Mx*WEPhMmZlb$Waj7ThK8gTmpCUDr|QBP`AJ!+$t6}Lsl_Gn
znRz9t>8VA<R)$kzr)YRHdoy`6rjlud5y*%hj>O`WwBp2+v?)DIM#fW8dw7uDGo^<Y
z#oj624DBFoP@6N@GdR2%!6Fz2f#lkzfPBbWl39|II;BSdWRwET3wnBbQ+ilRGILX>
zxZ5vGT>uJ@(hT+<9+0Z|;*z4wy!7HJU=uQg-9fS-oFUkwTLA_Um_Pxn6=s2MaYlYo
d$rO;8!eEKq{GwD?2o_;A+9(+>z;1r29ssAsrmFw|

diff --git a/unitgrade2/unitgrade2.py b/unitgrade2/unitgrade2.py
deleted file mode 100644
index c094340..0000000
--- a/unitgrade2/unitgrade2.py
+++ /dev/null
@@ -1,891 +0,0 @@
-"""
-git add . && git commit -m "Options" && git push &&  pip install git+ssh://git@gitlab.compute.dtu.dk/tuhe/unitgrade.git --upgrade
-
-"""
-# from . import cache_read
-import unittest
-import numpy as np
-import sys
-from io import StringIO
-import collections
-import re
-import threading
-import tqdm
-import time
-import pickle
-import itertools
-import os
-
-myround = lambda x: np.round(x)  # required.
-msum = lambda x: sum(x)
-mfloor = lambda x: np.floor(x)
-
-def setup_dir_by_class(C,base_dir):
-    name = C.__class__.__name__
-    # base_dir = os.path.join(base_dir, name)
-    # if not os.path.isdir(base_dir):
-    #     os.makedirs(base_dir)
-    return base_dir, name
-
-class Hidden:
-    def hide(self):
-        return True
-
-class Logger(object):
-    def __init__(self, buffer):
-        self.terminal = sys.stdout
-        self.log = buffer
-
-    def write(self, message):
-        self.terminal.write(message)
-        self.log.write(message)
-
-    def flush(self):
-        # this flush method is needed for python 3 compatibility.
-        pass
-
-class Capturing(list):
-    def __init__(self, *args, stdout=None, unmute=False, **kwargs):
-        self._stdout = stdout
-        self.unmute = unmute
-        super().__init__(*args, **kwargs)
-
-    def __enter__(self, capture_errors=True): # don't put arguments here.
-        self._stdout = sys.stdout if self._stdout == None else self._stdout
-        self._stringio = StringIO()
-        if self.unmute:
-            sys.stdout = Logger(self._stringio)
-        else:
-            sys.stdout = self._stringio
-
-        if capture_errors:
-            self._sterr = sys.stderr
-            sys.sterr = StringIO() # memory hole it
-        self.capture_errors = capture_errors
-        return self
-
-    def __exit__(self, *args):
-        self.extend(self._stringio.getvalue().splitlines())
-        del self._stringio    # free up some memory
-        sys.stdout = self._stdout
-        if self.capture_errors:
-            sys.sterr = self._sterr
-
-class Capturing2(Capturing):
-    def __exit__(self, *args):
-        lines = self._stringio.getvalue().splitlines()
-        txt = "\n".join(lines)
-        numbers = extract_numbers(txt)
-        self.extend(lines)
-        del self._stringio    # free up some memory
-        sys.stdout = self._stdout
-        if self.capture_errors:
-            sys.sterr = self._sterr
-
-        self.output = txt
-        self.numbers = numbers
-
-
-class QItem(unittest.TestCase):
-    title = None
-    testfun = None
-    tol = 0
-    estimated_time = 0.42
-    _precomputed_payload = None
-    _computed_answer = None # Internal helper to later get results.
-    weight = 1 # the weight of the question.
-
-    def __init__(self, question=None, *args, **kwargs):
-        if self.tol > 0 and self.testfun is None:
-            self.testfun = self.assertL2Relative
-        elif self.testfun is None:
-            self.testfun = self.assertEqual
-
-        self.name = self.__class__.__name__
-        # self._correct_answer_payload = correct_answer_payload
-        self.question = question
-
-        super().__init__(*args, **kwargs)
-        if self.title is None:
-            self.title = self.name
-
-    def _safe_get_title(self):
-        if self._precomputed_title is not None:
-            return self._precomputed_title
-        return self.title
-
-    def assertNorm(self, computed, expected, tol=None):
-        if tol == None:
-            tol = self.tol
-        diff = np.abs( (np.asarray(computed).flat- np.asarray(expected)).flat )
-        nrm = np.sqrt(np.sum( diff ** 2))
-
-        self.error_computed = nrm
-
-        if nrm > tol:
-            print(f"Not equal within tolerance {tol}; norm of difference was {nrm}")
-            print(f"Element-wise differences {diff.tolist()}")
-            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")
-
-    def assertL2(self, computed, expected, tol=None):
-        if tol == None:
-            tol = self.tol
-        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )
-        self.error_computed = np.max(diff)
-
-        if np.max(diff) > tol:
-            print(f"Not equal within tolerance {tol=}; deviation was {np.max(diff)=}")
-            print(f"Element-wise differences {diff.tolist()}")
-            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol=}, {np.max(diff)=}")
-
-    def assertL2Relative(self, computed, expected, tol=None):
-        if tol == None:
-            tol = self.tol
-        diff = np.abs( (np.asarray(computed) - np.asarray(expected)) )
-        diff = diff / (1e-8 + np.abs( (np.asarray(computed) + np.asarray(expected)) ) )
-        self.error_computed = np.max(np.abs(diff))
-        if np.sum(diff > tol) > 0:
-            print(f"Not equal within tolerance {tol}")
-            print(f"Element-wise differences {diff.tolist()}")
-            self.assertEqual(computed, expected, msg=f"Not equal within tolerance {tol}")
-
-    def precomputed_payload(self):
-        return self._precomputed_payload
-
-    def precompute_payload(self):
-        # Pre-compute resources to include in tests (useful for getting around rng).
-        pass
-
-    def compute_answer(self, unmute=False):
-        raise NotImplementedError("test code here")
-
-    def test(self, computed, expected):
-        self.testfun(computed, expected)
-
-    def get_points(self, verbose=False, show_expected=False, show_computed=False,unmute=False, passall=False, silent=False, **kwargs):
-        possible = 1
-        computed = None
-        def show_computed_(computed):
-            print(">>> Your output:")
-            print(computed)
-
-        def show_expected_(expected):
-            print(">>> Expected output (note: may have been processed; read text script):")
-            print(expected)
-
-        correct = self._correct_answer_payload
-        try:
-            if unmute: # Required to not mix together print stuff.
-                print("")
-            computed = self.compute_answer(unmute=unmute)
-        except Exception as e:
-            if not passall:
-                if not silent:
-                    print("\n=================================================================================")
-                    print(f"When trying to run test class '{self.name}' your code threw an error:", e)
-                    show_expected_(correct)
-                    import traceback
-                    print(traceback.format_exc())
-                    print("=================================================================================")
-                return (0, possible)
-
-        if self._computed_answer is None:
-            self._computed_answer = computed
-
-        if show_expected or show_computed:
-            print("\n")
-        if show_expected:
-            show_expected_(correct)
-        if show_computed:
-            show_computed_(computed)
-        try:
-            if not passall:
-                self.test(computed=computed, expected=correct)
-        except Exception as e:
-            if not silent:
-                print("\n=================================================================================")
-                print(f"Test output from test class '{self.name}' does not match expected result. Test error:")
-                print(e)
-                show_computed_(computed)
-                show_expected_(correct)
-            return (0, possible)
-        return (1, possible)
-
-    def score(self):
-        try:
-            self.test()
-        except Exception as e:
-            return 0
-        return 1
-
-class QPrintItem(QItem):
-    def compute_answer_print(self):
-        """
-        Generate output which is to be tested. By default, both text written to the terminal using print(...) as well as return values
-        are send to process_output (see compute_answer below). In other words, the text generated is:
-
-        res = compute_Answer_print()
-        txt = (any terminal output generated above)
-        numbers = (any numbers found in terminal-output txt)
-
-        self.test(process_output(res, txt, numbers), <expected result>)
-
-        :return: Optional values for comparison
-        """
-        raise Exception("Generate output here. The output is passed to self.process_output")
-
-    def process_output(self, res, txt, numbers):
-        return res
-
-    def compute_answer(self, unmute=False):
-        with Capturing(unmute=unmute) as output:
-            res = self.compute_answer_print()
-        s = "\n".join(output)
-        s = rm_progress_bar(s) # Remove progress bar.
-        numbers = extract_numbers(s)
-        self._computed_answer = (res, s, numbers)
-        return self.process_output(res, s, numbers)
-
-class OrderedClassMembers(type):
-    @classmethod
-    def __prepare__(self, name, bases):
-        return collections.OrderedDict()
-    def __new__(self, name, bases, classdict):
-        ks = list(classdict.keys())
-        for b in bases:
-            ks += b.__ordered__
-        classdict['__ordered__'] = [key for key in ks if key not in ('__module__', '__qualname__')]
-        return type.__new__(self, name, bases, classdict)
-
-class QuestionGroup(metaclass=OrderedClassMembers):
-    title = "Untitled question"
-    partially_scored = False
-    t_init = 0  # Time spend on initialization (placeholder; set this externally).
-    estimated_time = 0.42
-    has_called_init_ = False
-    _name = None
-    _items = None
-
-    @property
-    def items(self):
-        if self._items == None:
-            self._items = []
-            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)]
-            for I in members:
-                self._items.append( I(question=self))
-        return self._items
-
-    @items.setter
-    def items(self, value):
-        self._items = value
-
-    @property
-    def name(self):
-        if self._name == None:
-            self._name = self.__class__.__name__
-        return self._name #
-
-    @name.setter
-    def name(self, val):
-        self._name = val
-
-    def init(self):
-        # Can be used to set resources relevant for this question instance.
-        pass
-
-    def init_all_item_questions(self):
-        for item in self.items:
-            if not item.question.has_called_init_:
-                item.question.init()
-                item.question.has_called_init_ = True
-
-
-class Report():
-    title = "report title"
-    version = None
-    questions = []
-    pack_imports = []
-    individual_imports = []
-    nL = 80 # Maximum line width
-
-    @classmethod
-    def reset(cls):
-        for (q,_) in cls.questions:
-            if hasattr(q, 'reset'):
-                q.reset()
-
-    @classmethod
-    def mfile(clc):
-        return inspect.getfile(clc)
-
-    def _file(self):
-        return inspect.getfile(type(self))
-
-    def _import_base_relative(self):
-        root_dir = self.pack_imports[0].__path__._path[0]
-        root_dir = os.path.dirname(root_dir)
-        relative_path = os.path.relpath(self._file(), root_dir)
-        modules = os.path.normpath(relative_path[:-3]).split(os.sep)
-        return root_dir, relative_path, modules
-
-    def __init__(self, strict=False, payload=None):
-        working_directory = os.path.abspath(os.path.dirname(self._file()))
-
-        self.wdir, self.name = setup_dir_by_class(self, working_directory)
-        # self.computed_answers_file = os.path.join(self.wdir, self.name + "_resources_do_not_hand_in.dat")
-        for (q,_) in self.questions:
-            q.nL = self.nL # Set maximum line length.
-
-        if payload is not None:
-            self.set_payload(payload, strict=strict)
-        # else:
-        #     if os.path.isfile(self.computed_answers_file):
-        #         self.set_payload(cache_read(self.computed_answers_file), strict=strict)
-        #     else:
-        #         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."
-        #         if strict:
-        #             raise Exception(s)
-        #         else:
-        #             print(s)
-
-    def main(self, verbosity=1):
-        # Run all tests using standard unittest (nothing fancy).
-        import unittest
-        loader = unittest.TestLoader()
-        for q,_ in self.questions:
-            import time
-            start = time.time() # A good proxy for setup time is to
-            suite = loader.loadTestsFromTestCase(q)
-            unittest.TextTestRunner(verbosity=verbosity).run(suite)
-            total = time.time()              - start
-            q.time = total
-
-    def _setup_answers(self):
-        self.main()  # Run all tests in class just to get that out of the way...
-        report_cache = {}
-        for q, _ in self.questions:
-            if hasattr(q, '_save_cache'):
-                q()._save_cache()
-                q._cache['time'] = q.time
-                report_cache[q.__qualname__] = q._cache
-            else:
-                report_cache[q.__qualname__] = {'no cache see _setup_answers in unitgrade2.py':True}
-        return report_cache
-
-    def set_payload(self, payloads, strict=False):
-        for q, _ in self.questions:
-            q._cache = payloads[q.__qualname__]
-
-def rm_progress_bar(txt):
-    # More robust version. Apparently length of bar can depend on various factors, so check for order of symbols.
-    nlines = []
-    for l in txt.splitlines():
-        pct = l.find("%")
-        ql = False
-        if pct > 0:
-            i = l.find("|", pct+1)
-            if i > 0 and l.find("|", i+1) > 0:
-                ql = True
-        if not ql:
-            nlines.append(l)
-    return "\n".join(nlines)
-
-def extract_numbers(txt):
-    # txt = rm_progress_bar(txt)
-    numeric_const_pattern = '[-+]? (?: (?: \d* \. \d+ ) | (?: \d+ \.? ) )(?: [Ee] [+-]? \d+ ) ?'
-    rx = re.compile(numeric_const_pattern, re.VERBOSE)
-    all = rx.findall(txt)
-    all = [float(a) if ('.' in a or "e" in a) else int(a) for a in all]
-    if len(all) > 500:
-        print(txt)
-        raise Exception("unitgrade.unitgrade.py: Warning, too many numbers!", len(all))
-    return all
-
-class ActiveProgress():
-    def __init__(self, t, start=True, title="my progress bar",show_progress_bar=True):
-        self.t = t
-        self._running = False
-        self.title = title
-        self.dt = 0.1
-        self.n = int(np.round(self.t / self.dt))
-        self.show_progress_bar = show_progress_bar
-
-        # self.pbar = tqdm.tqdm(total=self.n)
-        if start:
-            self.start()
-
-    def start(self):
-        self._running = True
-        if self.show_progress_bar:
-            self.thread = threading.Thread(target=self.run)
-            self.thread.start()
-        self.time_started = time.time()
-
-    def terminate(self):
-        if not self._running:
-            raise Exception("Stopping a stopped progress bar. ")
-        self._running = False
-        if self.show_progress_bar:
-            self.thread.join()
-        if hasattr(self, 'pbar') and self.pbar is not None:
-            self.pbar.update(1)
-            self.pbar.close()
-            self.pbar=None
-
-        sys.stdout.flush()
-        return time.time() - self.time_started
-
-    def run(self):
-        self.pbar = tqdm.tqdm(total=self.n, file=sys.stdout, position=0, leave=False, desc=self.title, ncols=100,
-                              bar_format='{l_bar}{bar}| [{elapsed}<{remaining}]')  # , unit_scale=dt, unit='seconds'):
-
-        for _ in range(self.n-1): # Don't terminate completely; leave bar at 99% done until terminate.
-            if not self._running:
-                self.pbar.close()
-                self.pbar = None
-                break
-
-            time.sleep(self.dt)
-            self.pbar.update(1)
-
-
-
-from unittest.suite import _isnotsuite
-
-# class MySuite(unittest.suite.TestSuite): # Not sure we need this one anymore.
-#     raise Exception("no suite")
-#     pass
-
-def instance_call_stack(instance):
-    s = "-".join(map(lambda x: x.__name__, instance.__class__.mro()))
-    return s
-
-def get_class_that_defined_method(meth):
-    for cls in inspect.getmro(meth.im_class):
-        if meth.__name__ in cls.__dict__:
-            return cls
-    return None
-
-def caller_name(skip=2):
-    """Get a name of a caller in the format module.class.method
-
-       `skip` specifies how many levels of stack to skip while getting caller
-       name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.
-
-       An empty string is returned if skipped levels exceed stack height
-    """
-    stack = inspect.stack()
-    start = 0 + skip
-    if len(stack) < start + 1:
-      return ''
-    parentframe = stack[start][0]
-
-    name = []
-    module = inspect.getmodule(parentframe)
-    # `modname` can be None when frame is executed directly in console
-    # TODO(techtonik): consider using __main__
-    if module:
-        name.append(module.__name__)
-    # detect classname
-    if 'self' in parentframe.f_locals:
-        # I don't know any way to detect call from the object method
-        # XXX: there seems to be no way to detect static method call - it will
-        #      be just a function call
-        name.append(parentframe.f_locals['self'].__class__.__name__)
-    codename = parentframe.f_code.co_name
-    if codename != '<module>':  # top level usually
-        name.append( codename ) # function or a method
-
-    ## Avoid circular refs and frame leaks
-    #  https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack
-    del parentframe, stack
-
-    return ".".join(name)
-
-def get_class_from_frame(fr):
-      import inspect
-      args, _, _, value_dict = inspect.getargvalues(fr)
-      # we check the first parameter for the frame function is
-      # named 'self'
-      if len(args) and args[0] == 'self':
-            # in that case, 'self' will be referenced in value_dict
-            instance = value_dict.get('self', None)
-            if instance:
-                  # return its class
-                  # isinstance(instance, Testing) # is the actual class instance.
-
-                  return getattr(instance, '__class__', None)
-      # return None otherwise
-      return None
-
-from typing import Any
-import inspect, gc
-
-def giveupthefunc():
-    frame = inspect.currentframe()
-    code  = frame.f_code
-    globs = frame.f_globals
-    functype = type(lambda: 0)
-    funcs = []
-    for func in gc.get_referrers(code):
-        if type(func) is functype:
-            if getattr(func, "__code__", None) is code:
-                if getattr(func, "__globals__", None) is globs:
-                    funcs.append(func)
-                    if len(funcs) > 1:
-                        return None
-    return funcs[0] if funcs else None
-
-
-from collections import defaultdict
-
-class UTextResult(unittest.TextTestResult):
-    nL = 80
-    number = -1 # HAcky way to set question number.
-    show_progress_bar = True
-    def __init__(self, stream, descriptions, verbosity):
-        super().__init__(stream, descriptions, verbosity)
-        self.successes = []
-
-    def printErrors(self) -> None:
-        # if self.dots or self.showAll:
-        #     self.stream.writeln()
-        # if hasattr(self, 'cc'):
-        #     self.cc.terminate()
-        # self.cc_terminate(success=False)
-        self.printErrorList('ERROR', self.errors)
-        self.printErrorList('FAIL', self.failures)
-
-    def addError(self, test, err):
-        super(unittest.TextTestResult, self).addFailure(test, err)
-        self.cc_terminate(success=False)
-
-    def addFailure(self, test, err):
-        super(unittest.TextTestResult, self).addFailure(test, err)
-        self.cc_terminate(success=False)
-        # if self.showAll:
-        #     self.stream.writeln("FAIL")
-        # elif self.dots:
-        #     self.stream.write('F')
-        #     self.stream.flush()
-
-    def addSuccess(self, test: unittest.case.TestCase) -> None:
-        # super().addSuccess(test)
-        self.successes.append(test)
-        # super().addSuccess(test)
-        #     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)
-        self.cc_terminate()
-
-
-
-    def cc_terminate(self, success=True):
-        if self.show_progress_bar or True:
-            tsecs = np.round(self.cc.terminate(), 2)
-            sys.stdout.flush()
-            ss = self.item_title_print
-            print(self.item_title_print + ('.' * max(0, self.nL - 4 - len(ss))), end="")
-            # current = 1
-            # possible = 1
-            # current == possible
-            ss = "PASS" if success else "FAILED"
-            if tsecs >= 0.1:
-                ss += " (" + str(tsecs) + " seconds)"
-            print(ss)
-
-
-    def startTest(self, test):
-        # super().startTest(test)
-        j =self.testsRun
-        self.testsRun += 1
-        # print("Starting the test...")
-        # show_progress_bar = True
-        n = UTextResult.number
-
-        item_title = self.getDescription(test)
-        # item_title = item_title.split("\n")[0]
-        item_title = test.shortDescription() # Better for printing (get from cache).
-        if item_title == None:
-            # For unittest framework where getDescription may return None.
-            item_title = self.getDescription(test)
-        # test.countTestCases()
-        self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)
-        estimated_time = 10
-        nL = 80
-        #
-        if self.show_progress_bar or True:
-            self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print, show_progress_bar=self.show_progress_bar)
-        else:
-            print(self.item_title_print + ('.' * max(0, nL - 4 - len(self.item_title_print))), end="")
-
-        self._test = test
-
-    def _setupStdout(self):
-        if self._previousTestClass == None:
-            total_estimated_time = 1
-            if hasattr(self.__class__, 'q_title_print'):
-                q_title_print = self.__class__.q_title_print
-            else:
-                q_title_print = "<unnamed test. See unitgrade.py>"
-
-            # q_title_print = "some printed title..."
-            cc = ActiveProgress(t=total_estimated_time, title=q_title_print, show_progress_bar=self.show_progress_bar)
-            self.cc = cc
-
-    def _restoreStdout(self): # Used when setting up the test.
-        if self._previousTestClass == None:
-            q_time = self.cc.terminate()
-            q_time = np.round(q_time, 2)
-            sys.stdout.flush()
-            print(self.cc.title, end="")
-            # start = 10
-            # q_time = np.round(time.time() - start, 2)
-            nL = 80
-            print(" " * max(0, nL - len(self.cc.title)) + (
-                " (" + str(q_time) + " seconds)" if q_time >= 0.1 else ""))  # if q.name in report.payloads else "")
-            # print("=" * nL)
-
-from unittest.runner import _WritelnDecorator
-from io import StringIO
-
-class UTextTestRunner(unittest.TextTestRunner):
-    def __init__(self, *args, **kwargs):
-        from io import StringIO
-        stream = StringIO()
-        super().__init__(*args, stream=stream, **kwargs)
-
-    def _makeResult(self):
-        # stream = self.stream # not you!
-        stream = sys.stdout
-        stream = _WritelnDecorator(stream)
-        return self.resultclass(stream, self.descriptions, self.verbosity)
-
-def wrapper(foo):
-    def magic(self):
-        s = "-".join(map(lambda x: x.__name__, self.__class__.mro()))
-        # print(s)
-        foo(self)
-    magic.__doc__ = foo.__doc__
-    return magic
-
-from functools import update_wrapper, _make_key, RLock
-from collections import namedtuple
-_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
-
-def cache(foo, typed=False):
-    """ Magic cache wrapper
-    https://github.com/python/cpython/blob/main/Lib/functools.py
-    """
-    maxsize = None
-    def wrapper(self, *args, **kwargs):
-        key = (self.cache_id(), ("@cache", foo.__name__, _make_key(args, kwargs, typed)) )
-        # key = (self.cache_id(), '@cache')
-        # if self._cache_contains[key]
-
-        if not self._cache_contains(key):
-            value = foo(self, *args, **kwargs)
-            self._cache_put(key, value)
-        else:
-            value = self._cache_get(key)
-        return value
-    return wrapper
-
-
-class UTestCase(unittest.TestCase):
-    _outcome = None # A dictionary which stores the user-computed outcomes of all the tests. This differs from the cache.
-    _cache = None  # Read-only cache. Ensures method always produce same result.
-    _cache2 = None  # User-written cache.
-
-    def capture(self):
-        return Capturing2(stdout=self._stdout)
-
-    @classmethod
-    def question_title(cls):
-        """ Return the question title """
-        return cls.__doc__.strip().splitlines()[0].strip() if cls.__doc__ != None else cls.__qualname__
-
-    @classmethod
-    def reset(cls):
-        print("Warning, I am not sure UTestCase.reset() is needed anymore and it seems very hacky.")
-        cls._outcome = None
-        cls._cache = None
-        cls._cache2 = None
-
-    def _callSetUp(self):
-        self._stdout = sys.stdout
-        import io
-        sys.stdout = io.StringIO()
-        super().setUp()
-        # print("Setting up...")
-
-    def _callTearDown(self):
-        sys.stdout = self._stdout
-        super().tearDown()
-        # print("asdfsfd")
-
-    def shortDescriptionStandard(self):
-        sd = super().shortDescription()
-        if sd == None:
-            sd = self._testMethodName
-        return sd
-
-    def shortDescription(self):
-        # self._testMethodDoc.strip().splitlines()[0].strip()
-        sd = self.shortDescriptionStandard()
-        title = self._cache_get(  (self.cache_id(), 'title'), sd )
-        return title if title != None else sd
-
-    @property
-    def title(self):
-        return self.shortDescription()
-
-    @title.setter
-    def title(self, value):
-        self._cache_put((self.cache_id(), 'title'), value)
-
-    def _get_outcome(self):
-        if not (self.__class__, '_outcome') or self.__class__._outcome == None:
-            self.__class__._outcome = {}
-        return self.__class__._outcome
-
-    def _callTestMethod(self, testMethod):
-        t = time.time()
-        self._ensure_cache_exists() # Make sure cache is there.
-        if self._testMethodDoc != None:
-            # Ensure the cache is eventually updated with the right docstring.
-            self._cache_put((self.cache_id(), 'title'), self.shortDescriptionStandard() )
-        # Fix temp cache here (for using the @cache decorator)
-        self._cache2[ (self.cache_id(), 'assert') ] = {}
-
-        res = testMethod()
-        elapsed = time.time() - t
-        # self._cache_put( (self.cache_id(), 'title'), self.shortDescription() )
-
-        self._get_outcome()[self.cache_id()] = res
-        self._cache_put( (self.cache_id(), "time"), elapsed)
-
-    # This is my base test class. So what is new about it?
-    def cache_id(self):
-        c = self.__class__.__qualname__
-        m = self._testMethodName
-        return (c,m)
-
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-        self._load_cache()
-        self._assert_cache_index = 0
-        # self.cache_indexes = defaultdict(lambda: 0)
-
-    def _ensure_cache_exists(self):
-        if not hasattr(self.__class__, '_cache') or self.__class__._cache == None:
-            self.__class__._cache = dict()
-        if not hasattr(self.__class__, '_cache2') or self.__class__._cache2 == None:
-            self.__class__._cache2 = dict()
-
-    def _cache_get(self, key, default=None):
-        self._ensure_cache_exists()
-        return self.__class__._cache.get(key, default)
-
-    def _cache_put(self, key, value):
-        self._ensure_cache_exists()
-        self.__class__._cache2[key] = value
-
-    def _cache_contains(self, key):
-        self._ensure_cache_exists()
-        return key in self.__class__._cache
-
-    def wrap_assert(self, assert_fun, first, *args, **kwargs):
-        key = (self.cache_id(), 'assert')
-        if not self._cache_contains(key):
-            print("Warning, framework missing", key)
-        cache = self._cache_get(key, {})
-        id = self._assert_cache_index
-        if not id in cache:
-            print("Warning, framework missing cache index", key, "id =", id)
-        _expected = cache.get(id, first)
-        assert_fun(first, _expected, *args, **kwargs)
-        cache[id] = first
-        self._cache_put(key, cache)
-        self._assert_cache_index += 1
-
-    def assertEqualC(self, first: Any, msg: Any = ...) -> None:
-        self.wrap_assert(self.assertEqual, first, msg)
-
-    def _cache_file(self):
-        return os.path.dirname(inspect.getfile(self.__class__) ) + "/unitgrade/" + self.__class__.__name__ + ".pkl"
-
-    def _save_cache(self):
-        # get the class name (i.e. what to save to).
-        cfile = self._cache_file()
-        if not os.path.isdir(os.path.dirname(cfile)):
-            os.makedirs(os.path.dirname(cfile))
-
-        if hasattr(self.__class__, '_cache2'):
-            with open(cfile, 'wb') as f:
-                pickle.dump(self.__class__._cache2, f)
-
-    # But you can also set cache explicitly.
-    def _load_cache(self):
-        if self._cache != None: # Cache already loaded. We will not load it twice.
-            return
-            # raise Exception("Loaded cache which was already set. What is going on?!")
-        cfile = self._cache_file()
-        # print("Loading cache from", cfile)
-        if os.path.exists(cfile):
-            with open(cfile, 'rb') as f:
-                data = pickle.load(f)
-                self.__class__._cache = data
-        else:
-            print("Warning! data file not found", cfile)
-
-def hide(func):
-    return func
-
-def makeRegisteringDecorator(foreignDecorator):
-    """
-        Returns a copy of foreignDecorator, which is identical in every
-        way(*), except also appends a .decorator property to the callable it
-        spits out.
-    """
-    def newDecorator(func):
-        # Call to newDecorator(method)
-        # Exactly like old decorator, but output keeps track of what decorated it
-        R = foreignDecorator(func)  # apply foreignDecorator, like call to foreignDecorator(method) would have done
-        R.decorator = newDecorator  # keep track of decorator
-        # R.original = func         # might as well keep track of everything!
-        return R
-
-    newDecorator.__name__ = foreignDecorator.__name__
-    newDecorator.__doc__ = foreignDecorator.__doc__
-    # (*)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
-    return newDecorator
-
-hide = makeRegisteringDecorator(hide)
-
-def methodsWithDecorator(cls, decorator):
-    """
-        Returns all methods in CLS with DECORATOR as the
-        outermost decorator.
-
-        DECORATOR must be a "registering decorator"; one
-        can make any decorator "registering" via the
-        makeRegisteringDecorator function.
-
-        import inspect
-        ls = list(methodsWithDecorator(GeneratorQuestion, deco))
-        for f in ls:
-            print(inspect.getsourcelines(f) ) # How to get all hidden questions.
-    """
-    for maybeDecorated in cls.__dict__.values():
-        if hasattr(maybeDecorated, 'decorator'):
-            if maybeDecorated.decorator == decorator:
-                print(maybeDecorated)
-                yield maybeDecorated
-
diff --git a/unitgrade2/version.py b/unitgrade2/version.py
deleted file mode 100644
index acb984f..0000000
--- a/unitgrade2/version.py
+++ /dev/null
@@ -1 +0,0 @@
-__version__ = "0.9.0"
\ No newline at end of file
-- 
GitLab