Skip to content
Snippets Groups Projects
Commit 2b248fe6 authored by tuhe's avatar tuhe
Browse files

Reorg for new version

parent c190e1bd
No related branches found
No related tags found
No related merge requests found
Showing
with 91 additions and 29 deletions
......@@ -31,23 +31,89 @@ Let's look at an example. You need three files
```
instructor/cs101/homework.py # This contains the students homework
instructor/cs101/report1.py # This contains the tests
instructor/cs101/deploy.py # This deploys the tests
instructor/cs101/deploy.py # A private file to deploy the tests
```
### The homework
The homework is just any old python code.
The homework is just any old python code you would give to the students. For instance:
```python
def add(a,b):
# Write a function which add two numbers!
return a+b # naturally, this part would NOT be destributed to students
def reverse_list(mylist): #!f
"""
Given a list 'mylist' returns a list consisting of the same elements in reverse order. E.g.
reverse_list([1,2,3]) should return [3,2,1] (as a list).
"""
return list(reversed(mylist))
def add(a,b): #!f
""" Given two numbers `a` and `b` this function should simply return their sum:
> add(a,b) = a+b """
return a+b
if __name__ == "__main__":
# Problem 1: Write a function which add two numbers
print(f"Your result of 2 + 2 = {add(2,2)}")
print(f"Reversing a small list", reverse_list([2,3,5,7]))
```
### The test:
The test consists of individual problems and a report-class. The tests themselves are just regular Unittest. For instance:
The test consists of individual problems and a report-class. The tests themselves are just regular Unittest (we will see a slightly smarter idea in a moment). For instance:
```python
from homework1 import reverse_list, add
import unittest
class Week1(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2,2), 4)
self.assertEqual(add(-100, 5), -95)
def test_reverse(self):
self.assertEqual(reverse_list([1,2,3]), [3,2,1])
```
A number of tests can be collected into a `Report`, which will allow us to assign points to the tests and use the more advanced features of the framework later. A complete, minimal example:
```python
from unitgrade2.unitgrade2 import Report
from unitgrade2.unitgrade_helpers2 import evaluate_report_student
from homework1 import reverse_list, add
import unittest
class MyTest(unittest.TestCase):
# Write a function which add two numbers!
return a+b # naturally, this part would NOT be destributed to students
class Week1(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2,2), 4)
self.assertEqual(add(-100, 5), -95)
def test_reverse(self):
self.assertEqual(reverse_list([1,2,3]), [3,2,1])
import cs101
class Report1(Report):
title = "CS 101 Report 1"
questions = [(Week1, 10)] # Include a single question for 10 credits.
pack_imports = [cs101]
if __name__ == "__main__":
# Uncomment to simply run everything as a unittest:
# unittest.main(verbosity=2)
evaluate_report_student(Report1())
```
## Deployment
The above is all you need if you simply want to use the framework as a self-check: Students can run the code and see how well they did.
In order to begin using the framework for evaluation we need to create a bit more structure. We do that by deploying the report class as follows:
```python
from report1 import Report1
from unitgrade_private2.hidden_create_files import setup_grade_file_report
from snipper import snip_dir
import shutil
if __name__ == "__main__":
setup_grade_file_report(Report1, minify=False, obfuscate=False, execute=False)
# Deploy the files using snipper: https://gitlab.compute.dtu.dk/tuhe/snipper
snip_dir.snip_dir(source_dir="../cs101", dest_dir="../../students/cs101", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
```
- The first line creates the `report1_grade.py` script and any additional data files needed by the tests (none in this case)
- The second line set up the students directory (remember, we have included the solutions!) and remove the students solutions. You can check the results in the students folder.
No preview for this file type
......@@ -14,14 +14,10 @@ def deploy_student_files():
setup_grade_file_report(Report3, minify=False, obfuscate=False, execute=False)
Report3.reset()
# from cs103.report3_complete import Report3
# gather_upload_to_campusnet(Report3())
fout, ReportWithoutHidden = remove_hidden_methods(Report3, outfile="report3.py")
setup_grade_file_report(ReportWithoutHidden, minify=False, obfuscate=False, execute=False)
sdir = "../../students/cs103"
snip_dir(source_dir="../cs103", dest_dir=sdir, clean_destination_dir=True,
exclude=['*.token', 'deploy.py', 'report3_complete*.py'])
snip_dir(source_dir="../cs103", dest_dir=sdir, clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py', 'report3_complete*.py'])
return sdir
def run_student_code_on_docker(Dockerfile, student_token_file):
......@@ -36,13 +32,11 @@ def run_student_code_on_docker(Dockerfile, student_token_file):
if __name__ == "__main__":
# Step 1: Deploy the students files and return the directory they were written to
student_directory = deploy_student_files()
# Step 2: Simulate that the student run their report script and generate a .token file.
os.system("cd ../../students && python -m cs103.report3_grade")
student_token_file = glob.glob(student_directory + "/*.token")[0]
# Let's quickly check the students score:
with open(student_token_file, 'rb') as f:
results = pickle.load(f)
print("Student's score was:", results['total'])
# Step 3: Compile the Docker image (obviously you will only do this once; add your packages to requirements.txt).
Dockerfile = os.path.dirname(__file__) + "/../unitgrade-docker/Dockerfile"
......@@ -50,4 +44,9 @@ if __name__ == "__main__":
# Step 4: Test the students .token file and get the results-token-file. Compare the contents with the students_token_file:
checked_token = run_student_code_on_docker(Dockerfile, student_token_file)
print("My results of the students score was", checked_token['total'])
# Let's quickly compare the students score to what we got (the dictionary contains all relevant information including code).
with open(student_token_file, 'rb') as f:
results = pickle.load(f)
print("Student's score was:", results['total'])
print("My independent evaluation of the students score was", checked_token['total'])
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
......@@ -6,4 +6,4 @@ if __name__ == "__main__":
gather_upload_to_campusnet(Report2())
setup_grade_file_report(Report2, minify=False, obfuscate=False, execute=False)
snip_dir(source_dir="../cs102", dest_dir="../../students/cs102", clean_destination_dir=True, exclude=['*.token', 'deploy.py'])
snip_dir(source_dir="../cs102", dest_dir="../../students/cs102", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
......@@ -2,15 +2,12 @@ from report1 import Report1
from unitgrade_private2.hidden_create_files import setup_grade_file_report
from snipper import snip_dir
import shutil
# from unitgrade_private2.hidden_gather_upload import gather_upload_to_campusnet
if __name__ == "__main__":
# gather_upload_to_campusnet(Report1())
setup_grade_file_report(Report1, minify=False, obfuscate=False, execute=False)
# Deploy the files using snipper: https://gitlab.compute.dtu.dk/tuhe/snipper
snip_dir.snip_dir(source_dir="../cs101", dest_dir="../../students/cs101", clean_destination_dir=True, exclude=['*.token', 'deploy.py'])
snip_dir.snip_dir(source_dir="../cs101", dest_dir="../../students/cs101", clean_destination_dir=True, exclude=['__pycache__', '*.token', 'deploy.py'])
# For my own sake, copy the homework to the other examples.
for f in ['../../../example_framework/instructor/cs102/homework1.py', '../../../example_docker/instructor/cs103/homework1.py']:
......
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment