From f20a5fc8a14527f81fc01165448566b6ed995157 Mon Sep 17 00:00:00 2001
From: Tue Herlau <tuhe@dtu.dk>
Date: Sat, 28 Aug 2021 18:30:09 +0200
Subject: [PATCH] Changes

---
 .../__pycache__/homework1.cpython-38.pyc      | Bin 1318 -> 1208 bytes
 .../__pycache__/unitgrade2.cpython-38.pyc     | Bin 26380 -> 26946 bytes
 .../unitgrade_helpers2.cpython-38.pyc         | Bin 6801 -> 6825 bytes
 unitgrade2/unitgrade2.py                      |  49 +++++++++++++-----
 unitgrade2/unitgrade_helpers2.py              |  19 ++++---
 5 files changed, 45 insertions(+), 23 deletions(-)

diff --git a/cs101courseware_example/__pycache__/homework1.cpython-38.pyc b/cs101courseware_example/__pycache__/homework1.cpython-38.pyc
index 674ec1107c08d6922af8e6e3b30d52d30cb68107..0d3386b94e926f441ec02b6e5452a23dc1d8f02d 100644
GIT binary patch
delta 264
zcmZ3+wS$v4l$V!_fq{YH8=G2U`$S$@#)OI5-cqSNDcspiMKP&d%?ykTsoWqkg)x{x
zlV{?LW=74)GK^AeYzzzxMQoF87_%9<C$C`KF3Qcoz@W)^i!rANA_bD?nq0!9$tX1W
zFVh=Ffyu9!o#l|^7#J9C@h0ULm*nTg=Va!kCKgFg_GXckR0K(I#K-3*X6D7mYx3S=
z%`43<s4NnhT+0#|2(qR~2xK@+U0z~tYJ5DBtzbJq-nzwMlbfGXnv-hB$iTo*4ARBH
V$iv9PD8R<S!NJMF!@<bL2mt9VI931v

delta 415
zcmdnNxr~c9l$V!_fq{X+g-tDS-9%nl#*B&D-byLlDLgF<Q9P-<DZJTCMJcIV%?ykT
zsXQPug)x{xlW*dLX2q3^ek&O?nQyV>R_0_Dm)v42N-ZwUDY?a%UBu47z)-|K*@Q8h
zk!SJ(#_gg!3=9mKjJFtbpi&@t?#Ve!nhC-T3=GMPAU8lUh|R>nz~Iclz);M=z`#(#
zP{Yv77|c+_1~G)WxHMOj@fK4~F|uI{3=ANb#21(5ii325j9_3a5}Q1Y=?$ac<Ys2)
z0Enx=R)bXYCgm5G<mbibWagzN7RiA$34q+d$j2zg#Ky?O$iu|ND8N{x3R27wAD^3;
znHL|g$#;u2uQa!yvPfdG7)xLT$Y(_$PZWuPOol1WOUzA;k4JJK*m7>LQ8u~xDWy57
fb|9Y?i!d-SaDXgh6ky}v;9%uo=iuRBWMc#X+MiKF

diff --git a/unitgrade2/__pycache__/unitgrade2.cpython-38.pyc b/unitgrade2/__pycache__/unitgrade2.cpython-38.pyc
index aa46009fef3a824583373629a6d857240757d712..a70e7b1190a2294f68b5e051feddd744b6c88a79 100644
GIT binary patch
delta 8176
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
Omw-?<2Q!B-2NM8^H*+ii

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

diff --git a/unitgrade2/__pycache__/unitgrade_helpers2.cpython-38.pyc b/unitgrade2/__pycache__/unitgrade_helpers2.cpython-38.pyc
index 85a4965da5d65114c8709bc88a2d0be4810d2f9e..5f1fcf25687cedd7203740db7a57b848a3ce5503 100644
GIT binary patch
delta 1097
zcmbPey3&+4l$V!_fq{YH&wq`?V-tC08G|-z3o$aPPPSuIQgUZVQAkm2VMtL-<;hZL
zW{y%!QA<%yQE6d}Qc7VAX3$jMT)=pYjnQPYIY$sPqyFYDZXHI(_Q~6Mav57EtMcAv
z?3v8SSIyhaz`#(<#K6G7!C2%w`HYY~(=Cz7YQma~%##Cz_lZX_FfdF2Dd7OQgpr4l
zkCBhDN_DcGh`B#Vt|**=fuTqOP6UBiG9V&?fq|hPq!Vg5h#!*712P7Rbr={J*cliY
zoI$EYm?y8~+frY`*UV5WR>EJykR{N}=)y38F}5s*sa8COsaB#^GDWCXs)jLzA)B-4
zRgHLxusA~vV>WZqtHMJyVhaRoBo;E(O4mqa3DwG^h(P6K(wM{;YGq3}YGhLcQbc>1
z7#UI+Yb4@@!K6qgL#<p2V~SXgXs%eTJYzjWjckc{yhM$Big<~5ibOBd0?8Wbg^aZd
zDU!8{H40f$wMr$@H40fW&5X6mFcz4WZDtf_0JG#kERfo4rU{J29VPNjj5SIrjM*#`
z7>kybDAY*SD2p(pNQp4iC`mIkGv+a+FxD#9NP@)cYvgKVQl#gw)`-@K+c4B9*GR;R
z)F^@7D+BS-Y=*f^wJIsHH4<4Ovl&w4Y9wbf%w?%nE#at9Ns+G+E|IQLX=aoFIYkvj
zi!g{Y)ToLxG&3?XlyIcTg6JBd1&S#O2=m}()q@OUPG?%k$jDH5s6?qow3#u6xmK-K
zsaCl}p+vbxshP2vu~rGpRtB?`Ym{mj;)QFJYZ&51N|+WfFJ!3Yt>In3nWDImu~wi&
zp@eq<??Q$e5ebH7##;3n^%Ny3hFXmp^%{*7B@qS*hFVQ<x@D-<D&fdTQLPaWXGl>K
zXQ<Jt(MVBmW)f#e(E#%_Q#8RmEr?&he$Y-4C{d|l$Pxhsd5WAk1DGca;z2x7qg<nu
z##AGkqBDo7R=Y;KMktLbm_bu_@_fM=jB_Si2u<I-LxhEqF>Uf*QGG_O$!|q-8C54o
zi)HYqGB7aQVkybYO)UZ?-N}!|Y7CP=Vw}aL$;qk3#i_-&*iws%@{5XZaik??=9Ctt
z7T@A?EG|whD#^^xa|KCF&K8$t)S28VUMFyiy(GT4B(bRE7He^Geo^XV83}#H*2z8+
zdW^RwS4$W$PMf?&LY<Lm@-+!1RxTzjHl@kGB|I3FC%Z_x^4#Jm&C4t)Ni8lZYMDGi
wawgv`u8`E?5}*9Ul+>c4h{<YF+KhISgQSf3nYqF^*o0Vw*cliZ7#aQn0BNup$^ZZW

delta 1075
zcmZ2!I?<Fjl$V!_fq{XcE>tbCaw4xRqr*mRAx1{!$##rN0x2pfiYZDhj8O_HjKK_=
zs+*e_kFhbDZuaB|VrDehJcnC{k+Ea)NuFHBw#nwaw;6jU3-eX$_AoFo6f-d}FmNyy
z`7$stge3ETY=B~21_lOp1_lOakg88ilM@BD)VnjJ2&D+OFr)~V@MZBgGuMjMh&40R
zikAq~Fk}ffGrBNLV2pK&VXBpgVXBp^l}Zt*m9Ak-VaVnz`cos3A}Y>M!<fxn^r!Gj
zjrang8p(x>wK6r5S;DolDPmB0*)%3GhFZB2jvBcXffVsxCPs!7#u~|Zkrc+7ddYav
zOom$d6vh;Z9I;&SS_MXi8o3gQc*z=t6v+~a6scaO1yVIK3mIz_Q>1H^Y811iYn5x1
zOJr&kvt*kYB^YW|YNSf!YE)8WL>Ow6r5TzTMZjV;QZ*_y@-?z4vU6B#L~A5$7;02%
zB;!SEl)+ZZK^#{<n_(_ft!j#VjbxVSY=#tt8mZX~b6INDN;qm%Qxt22OJr(PLDrPW
z)Tn`I5e9LF8Z~i-W=2Ma5{?vk5M3j*Kt4qYVj##o6tkGqnHDlKG8A4ZQK%7ZW{hF3
zRj*a9RVk4xQLIsJu4im!tW^ecRGL9-l^W$5hIo-0l^TY4(GsQw%nKQ6d24tVaHc3P
zWULh^kt^X{z`Ky4Mnr<4nXy)*Mk7T<ilJ7sMx#bEMMZ=`f}vI`MKwjOg`rlvgd;`0
zMnIe)MMIpSM!QBcMYEYnoFPRE%+pHI2JzfdbRd2K`$0EFphT&LAxpHGQJf(~L7V~1
z69MrczNk^DQBGs35lzvX!&IwNqf;Z4#uUt;sXw_=cn0J2$wDI2C(q-vk*?BBElbQP
zO)N=`FG?-QFDlWq$;nSn%qh0hn|y~)lTmmw8~;9o1O^6%<)Ea<0ZN~YJdAvde2i6g
zxV7HqH+KMODhg*{U?`G+6G0%B3<CqhEs@~V!qU{dlFY=MkksN5pZvs>)S_h|JD`~&
zee*IAc1Fh7$?HV*8MP<h6U}8*p6nx*p%4So&Qg+@n|h0*G%vHHB(=EY78k;h$%n;i
zcp^cH*iws%@{5Wm7l_L;>Q3$xuM>@8FNrTMNh~V4#af)4UzA#u&cMJhSw=#iv3;_S
zgdStm<Z1~6#)*^HNT@S23$abUBB8|0$1XDYw}c0y;$#;|SN5VtkQdq}PnDcG*<MP6
Y(Pnanlo2lrR~QGI5Gw;C10%yf0M0EI=l}o!

diff --git a/unitgrade2/unitgrade2.py b/unitgrade2/unitgrade2.py
index 95b071c..50a8c52 100644
--- a/unitgrade2/unitgrade2.py
+++ b/unitgrade2/unitgrade2.py
@@ -414,6 +414,8 @@ class ActiveProgress():
         self.time_started = time.time()
 
     def terminate(self):
+        if not self._running:
+            raise Exception("Stopping a stopped progress bar. ")
         self._running = False
         self.thread.join()
         if hasattr(self, 'pbar') and self.pbar is not None:
@@ -528,6 +530,8 @@ def giveupthefunc():
 from collections import defaultdict
 
 class UTextResult(unittest.TextTestResult):
+    nL = 80
+    show_progress_bar = True
     def __init__(self, stream, descriptions, verbosity):
         super().__init__(stream, descriptions, verbosity)
         self.successes = []
@@ -535,9 +539,24 @@ class UTextResult(unittest.TextTestResult):
     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)
@@ -552,21 +571,22 @@ class UTextResult(unittest.TextTestResult):
         #     (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)
-        show_progress_bar = True
-        nL = 80
-        if show_progress_bar:
-            tsecs = np.round( self.cc.terminate(), 2)
+        self.cc_terminate()
+
+
+
+    def cc_terminate(self, success=True):
+        if self.show_progress_bar:
+            tsecs = np.round(self.cc.terminate(), 2)
             sys.stdout.flush()
             ss = self.item_title_print
-            print(self.item_title_print + ('.' * max(0, nL - 4 - len(ss))), end="")
-            #
-            #     if not hidden:
+            print(self.item_title_print + ('.' * max(0, self.nL - 4 - len(ss))), end="")
             current = 1
             possible = 1
-            # tsecs = 2
-            ss = "PASS" if current == possible else "*** FAILED"
+            # current == possible
+            ss = "PASS" if success else "FAILED"
             if tsecs >= 0.1:
-                ss += " ("+ str(tsecs) + " seconds)"
+                ss += " (" + str(tsecs) + " seconds)"
             print(ss)
 
 
@@ -574,16 +594,19 @@ class UTextResult(unittest.TextTestResult):
         # super().startTest(test)
         self.testsRun += 1
         # print("Starting the test...")
-        show_progress_bar = True
+        # show_progress_bar = True
         n = 1
         j = 1
         item_title = self.getDescription(test)
         item_title = item_title.split("\n")[0]
+
+        # test.countTestCases()
+
         self.item_title_print = "*** q%i.%i) %s" % (n + 1, j + 1, item_title)
         estimated_time = 10
         nL = 80
         #
-        if show_progress_bar:
+        if self.show_progress_bar:
             self.cc = ActiveProgress(t=estimated_time, title=self.item_title_print)
         else:
             print(self.item_title_print + ('.' * max(0, nL - 4 - len(self.item_title_print))), end="")
@@ -625,7 +648,7 @@ class UTextTestRunner(unittest.TextTestRunner):
         super().__init__(*args, stream=stream, **kwargs)
 
     def _makeResult(self):
-        stream = self.stream # not you!
+        # stream = self.stream # not you!
         stream = sys.stdout
         stream = _WritelnDecorator(stream)
         return self.resultclass(stream, self.descriptions, self.verbosity)
diff --git a/unitgrade2/unitgrade_helpers2.py b/unitgrade2/unitgrade_helpers2.py
index 17004c3..c1961ea 100644
--- a/unitgrade2/unitgrade_helpers2.py
+++ b/unitgrade2/unitgrade_helpers2.py
@@ -44,7 +44,6 @@ parser.add_argument('--unmute',  action="store_true",  help='Show result of prin
 parser.add_argument('--passall',  action="store_true",  help='Automatically pass all tests. Useful when debugging.')
 
 
-
 def evaluate_report_student(report, question=None, qitem=None, unmute=None, passall=None, ignore_missing_file=False, show_tol_err=False):
     args = parser.parse_args()
     if question is None and args.q is not None:
@@ -141,6 +140,12 @@ class UnitgradeTextRunner(unittest.TextTestRunner):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
 
+class SequentialTestLoader(unittest.TestLoader):
+    def getTestCaseNames(self, testCaseClass):
+        test_names = super().getTestCaseNames(testCaseClass)
+        testcase_methods = list(testCaseClass.__dict__.keys())
+        test_names.sort(key=testcase_methods.index)
+        return test_names
 
 def evaluate_report(report, question=None, qitem=None, passall=False, verbose=False,  show_expected=False, show_computed=False,unmute=False, show_help_flag=True, silent=False,
                     show_progress_bar=True,
@@ -161,14 +166,7 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
     nL = 80
     t_start = time.time()
     score = {}
-
     # Use the sequential test loader instead. See here:
-    class SequentialTestLoader(unittest.TestLoader):
-        def getTestCaseNames(self, testCaseClass):
-            test_names = super().getTestCaseNames(testCaseClass)
-            testcase_methods = list(testCaseClass.__dict__.keys())
-            test_names.sort(key=testcase_methods.index)
-            return test_names
     loader = SequentialTestLoader()
     # loader = unittest.TestLoader()
     # loader.suiteClass = MySuite
@@ -267,14 +265,15 @@ def evaluate_report(report, question=None, qitem=None, passall=False, verbose=Fa
         # ws, possible, obtained = upack(q_)
 
         possible = res.testsRun
-        obtained = possible - len(res.errors)
+        obtained = len(res.successes)
 
+        assert len(res.successes) +  len(res.errors) + len(res.failures) == res.testsRun
 
         # possible = int(ws @ possible)
         # obtained = int(ws @ obtained)
         # obtained = int(myround(int((w * obtained) / possible ))) if possible > 0 else 0
 
-        obtained = w * int(obtained * 1.0 / possible )
+        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
-- 
GitLab