Skip to content
Snippets Groups Projects
Commit 1e149dd3 authored by tuhe's avatar tuhe
Browse files

Fixed bugs relating to version change (unitgrade_private2 -> unitgrade_private)

parent 2420b4d6
Branches
No related tags found
No related merge requests found
Showing
with 99 additions and 44 deletions
......@@ -16,8 +16,19 @@ Unitgrade is an automatic report and exam evaluation framework that enables inst
- Automatic Moss anti-plagiarism detection
- CMU Autolab integration (Experimental)
### Install
Simply use `pip`
```terminal
pip install unitgrade-devel
```
This will install `unitgrade-devel` (this package) and all dependencies to get you started.
# Using unitgrade
The examples can be found in the `/examples/` directory: https://gitlab.compute.dtu.dk/tuhe/unitgrade_private/examples
The examples can be found in the `/examples` directory: https://gitlab.compute.dtu.dk/tuhe/unitgrade_private/-/tree/master/examples
### Videos
For videos see the `/videos` directory : https://gitlab.compute.dtu.dk/tuhe/unitgrade_private/-/tree/master/videos
## A simple example
Unitgrade makes the following assumptions:
......@@ -73,7 +84,6 @@ class Week1(unittest.TestCase):
self.assertEqual(reverse_list([1,2,3]), [3,2,1])
```
A number of tests can be collected into a `Report`, which will allow us to assign points to the tests and use the more advanced features of the framework later. A complete, minimal example:
```python
# example_simplest/instructor/cs101/report1.py
import unittest
......@@ -101,19 +111,12 @@ if __name__ == "__main__":
### Deployment
The above is all you need if you simply want to use the framework as a self-check: Students can run the code and see how well they did.
In order to begin using the framework for evaluation we need to create a bit more structure. We do that by deploying the report class as follows:
```python
# example_simplest/instructor/cs101/deploy.py
from cs101.report1 import Report1
from unitgrade_private.hidden_create_files import setup_grade_file_report
from snipper import snip_dir
a = 34 #!i
print(a)
a
z = 23 #!i
if __name__ == "__main__":
setup_grade_file_report(Report1) # Make the report1_grade.py report file
......@@ -178,7 +181,7 @@ One of the main advantages of `unitgrade` over web-based autograders it that tes
```python
# example_framework/instructor/cs102/report2.py
from unitgrade2 import UTestCase
from unitgrade import UTestCase
class Week1(UTestCase):
def test_add(self):
......@@ -217,7 +220,7 @@ When this is run, the titles are shown as follows:
| | | |_ __ _| |_| | \/_ __ __ _ __| | ___
| | | | '_ \| | __| | __| '__/ _` |/ _` |/ _ \
| |_| | | | | | |_| |_\ \ | | (_| | (_| | __/
\___/|_| |_|_|\__|\____/_| \__,_|\__,_|\___| v0.1.0, started: 09/09/2021 19:52:23
\___/|_| |_|_|\__|\____/_| \__,_|\__,_|\___| v0.1.5, started: 16/09/2021 17:42:18
CS 101 Report 2 (use --help for options)
Question 1: Week1
......@@ -231,7 +234,7 @@ Question 2: The same problem as before with nicer titles
* q2.2) Checking if reverse_list([1, 2, 3]) = [3, 2, 1]............................................................PASS
* q2) Total...................................................................................................... 8/8
Total points at 19:52:23 (0 minutes, 0 seconds)....................................................................18/18
Total points at 17:42:18 (0 minutes, 0 seconds)....................................................................18/18
```
What happens behind the scenes when we set `self.title` is that the result is pre-computed on the instructors machine and cached. This means the last test will display the correct result regardless of how `reverse_list` has been implemented by the student. The titles are also shown correctly when the method is run as a unittest.
......@@ -269,7 +272,6 @@ Finally, notice how one of the tests has a return value. This will be automatica
To use `unitgrade` as part of automatic grading, it is recommended you check the students output locally and use hidden tests. Fortunately, this is very easy.
Let's start with the hidden tests. As usual we write a complete report script (`report3_complete.py`), but this time we use the `@hide`-decorator to mark tests as hidden:
```python
# example_docker/instructor/cs103/report3_complete.py
from unitgrade import UTestCase, Report, hide
......@@ -305,7 +307,6 @@ if __name__ == "__main__":
snip_dir("./", student_directory, exclude=['__pycache__', '*.token', 'deploy.py', 'report3_complete*.py', '.*'])
```
Just to check, let's have a quick look at the students report script `report3.py`:
```python
# example_docker/instructor/cs103/report3.py
from unitgrade import UTestCase, Report, hide
......@@ -393,7 +394,7 @@ The files in the whitelist/student directory can be either `.token` files (which
When done just call moss as follows:
```python
# example_moss/moss_example.py
from unitgrade_private2.plagiarism.mossit import moss_it, get_id
from unitgrade_private.plagiarism.mossit import moss_it, get_id
if __name__ == "__main__":
# Extract the moss id ("12415...") from the perl script and test:
......@@ -439,12 +440,12 @@ class Week1(UTestCase):
Hints:
* Insert a breakpoint and check what your function find_primes(4) actually outputs
"""
self.assertEqual(find_primes(4), [2,3])
self.assertEqual(find_primes(4), [2, 3], msg="The list should only contain primes <= 4")
class Report1Hints(Report):
title = "CS 106 Report 1"
questions = [(Week1, 10)]
pack_imports = [homework1]
pack_imports = [homework_hints]
```
When students run this homework it will fail and display the hints from the two methods:
......@@ -457,9 +458,9 @@ collected and displayed. This feature requires no external configuration; simply
# Citing
```bibtex
@online{unitgrade_devel,
title={Unitgrade-devel (0.1.2): \texttt{pip install unitgrade-devel}},
title={Unitgrade-devel (0.1.7): \texttt{pip install unitgrade-devel}},
url={https://lab.compute.dtu.dk/tuhe/unitgrade_private},
urldate = {2021-09-09},
urldate = {2021-09-16},
month={9},
publisher={Technical University of Denmark (DTU)},
author={Tue Herlau},
......
......@@ -16,9 +16,20 @@ Unitgrade is an automatic report and exam evaluation framework that enables inst
- Automatic Moss anti-plagiarism detection
- CMU Autolab integration (Experimental)
### Install
Simply use `pip`
```terminal
pip install unitgrade-devel
```
This will install `unitgrade-devel` (this package) and all dependencies to get you started.
# Using unitgrade
The examples can be found in the `/examples` directory: https://gitlab.compute.dtu.dk/tuhe/unitgrade_private/-/tree/master/examples
### Videos
For videos see the `/videos` directory : https://gitlab.compute.dtu.dk/tuhe/unitgrade_private/-/tree/master/videos
## A simple example
Unitgrade makes the following assumptions:
- Your code is in python
......
......@@ -3,12 +3,6 @@ from cs101.report1 import Report1
from unitgrade_private.hidden_create_files import setup_grade_file_report
from snipper import snip_dir
a = 34 #!i
print(a)
a
z = 23 #!i
if __name__ == "__main__":
setup_grade_file_report(Report1) # Make the report1_grade.py report file
......
......@@ -3,7 +3,7 @@
| | | |_ __ _| |_| | \/_ __ __ _ __| | ___
| | | | '_ \| | __| | __| '__/ _` |/ _` |/ _ \
| |_| | | | | | |_| |_\ \ | | (_| | (_| | __/
\___/|_| |_|_|\__|\____/_| \__,_|\__,_|\___| v0.1.0, started: 09/09/2021 19:52:23
\___/|_| |_|_|\__|\____/_| \__,_|\__,_|\___| v0.1.5, started: 16/09/2021 17:42:18
CS 101 Report 2 (use --help for options)
Question 1: Week1
......@@ -17,4 +17,4 @@ Question 2: The same problem as before with nicer titles
* q2.2) Checking if reverse_list([1, 2, 3]) = [3, 2, 1]............................................................PASS
* q2) Total...................................................................................................... 8/8
Total points at 19:52:23 (0 minutes, 0 seconds)....................................................................18/18
Total points at 17:42:18 (0 minutes, 0 seconds)....................................................................18/18
# example_hints/instructor/cs106/homework_hints.py
def find_primes(n): #!f
"""
Return a list of all primes up to (and including) n
Hints:
* Remember to return a *list* (and not a tuple or numpy ndarray)
* Remember to include n if n is a prime
* The first few primes are 2, 3, 5, ...
"""
primes = [p for p in range(2, n+1) if is_prime(n) ]
return primes
def is_prime(n): #!f
"""
Return true iff n is a prime
Hints:
* A number is a prime if it has no divisors
* You can check if k divides n using the modulo-operator. I.e. n % k == True if k divides n.
"""
for k in range(2, n):
if k % n == 0: # This line is intentionally buggy so that we see the hint!
return False
return True
\ No newline at end of file
# example_in_progress/in_progress.py
self.title = f"Checking if reverse_list({ls}) = {reverse}" # Programmatically set the title
def ex_test_output_capture(self):
with self.capture() as out:
print("hello world 42") # Genereate some output (i.e. in a homework script)
self.assertEqual(out.numbers[0], 42) # out.numbers is a list of all numbers generated
self.assertEqual(out.output, "hello world 42") # you can also access the raw output.
class Question2(UTestCase):
@cache
def my_reversal(self, ls):
# The '@cache' decorator ensures the function is not run on the *students* computer
# Instead the code is run on the teachers computer and the result is passed on with the
# other pre-computed results -- i.e. this function will run regardless of how the student happens to have
# implemented reverse_list.
return reverse_list(ls)
def test_reverse_tricky(self):
ls = (2,4,8)
ls2 = self.my_reversal(tuple(ls)) # This will always produce the right result, [8, 4, 2]
print("The correct answer is supposed to be", ls2) # Show students the correct answer
self.assertEqualC(reverse_list(ls)) # This will actually test the students code.
return "Buy world!" # This value will be stored in the .token file
\ No newline at end of file
......@@ -5,9 +5,9 @@ class Week1(UTestCase):
Hints:
* Insert a breakpoint and check what your function find_primes(4) actually outputs
"""
self.assertEqual(find_primes(4), [2,3])
self.assertEqual(find_primes(4), [2, 3], msg="The list should only contain primes <= 4")
class Report1Hints(Report):
title = "CS 106 Report 1"
questions = [(Week1, 10)]
pack_imports = [homework1]
\ No newline at end of file
pack_imports = [homework_hints]
\ No newline at end of file
@online{unitgrade_devel,
title={Unitgrade-devel (0.1.2): \texttt{pip install unitgrade-devel}},
title={Unitgrade-devel (0.1.7): \texttt{pip install unitgrade-devel}},
url={https://lab.compute.dtu.dk/tuhe/unitgrade_private},
urldate = {2021-09-09},
urldate = {2021-09-16},
month={9},
publisher={Technical University of Denmark (DTU)},
author={Tue Herlau},
......
No preview for this file type
......@@ -7,4 +7,3 @@ if __name__ == "__main__":
setup_grade_file_report(Report2)
snip_dir("./", "../../students/cs102", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
evaluate_report_student(Report2(),show_privisional=False, noprogress=True) #!o #!o
......@@ -54,6 +54,7 @@ class Question2(UTestCase): #!s=c
self.assertEqualC(reverse_list(ls)) # This will actually test the students code.
return "Buy world!" # This value will be stored in the .token file #!s=c
import cs102
class Report2(Report):
title = "CS 101 Report 2"
......@@ -61,4 +62,4 @@ class Report2(Report):
pack_imports = [cs102]
if __name__ == "__main__":
evaluate_report_student(Report2())
evaluate_report_student(Report2(), unmute=True)
......@@ -54,6 +54,7 @@ class Question2(UTestCase):
self.assertEqualC(reverse_list(ls)) # This will actually test the students code.
return "Buy world!" # This value will be stored in the .token file
import cs102
class Report2(Report):
title = "CS 101 Report 2"
......@@ -61,4 +62,4 @@ class Report2(Report):
pack_imports = [cs102]
if __name__ == "__main__":
evaluate_report_student(Report2())
evaluate_report_student(Report2(), unmute=True)
File deleted
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment