diff --git a/docs/snips/0_homework1.py b/docs/snips/0_homework1.py index 39004d78f9042ae6bddc4a8d632132f81a5e0e0d..7f833877f682e9f6790e69610479e1cc395d9fbc 100644 --- a/docs/snips/0_homework1.py +++ b/docs/snips/0_homework1.py @@ -1,20 +1,15 @@ -# example_moss/tmp/submissions/s1002/0_homework1.py +# example_moss/tmp/submissions/s1001/0_homework1.py 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). """ - ls = [] - for l in mylist: - ls = [l] + ls - return ls - # return list(reversed(mylist)) + 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 """ - sum = a + b - return sum + return a+b if __name__ == "__main__": # Example usage: diff --git a/docs/snips/0_homework1_stripped.py b/docs/snips/0_homework1_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..7f833877f682e9f6790e69610479e1cc395d9fbc --- /dev/null +++ b/docs/snips/0_homework1_stripped.py @@ -0,0 +1,17 @@ +# example_moss/tmp/submissions/s1001/0_homework1.py +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__": + # Example usage: + print(f"Your result of 2 + 2 = {add(2,2)}") + print(f"Reversing a small list", reverse_list([2,3,5,7])) \ No newline at end of file diff --git a/docs/snips/deploy_autolab_a.py b/docs/snips/deploy_autolab_a.py index 7c490a7713fffb1e575f9c1cbb085ec4ee70b3e1..ce14defe5c6e6601358e0f32afbda04c5dfae6e4 100644 --- a/docs/snips/deploy_autolab_a.py +++ b/docs/snips/deploy_autolab_a.py @@ -1,4 +1,4 @@ -# autolab_example_py_upload/instructor/cs102_autolab/deploy_autolab.py + # autolab_example_py_upload/instructor/cs102_autolab/deploy_autolab.py # Step 1: Download and compile docker grading image. You only need to do this once. download_docker_images("../docker") # Download docker images from gitlab (only do this once). dockerfile = f"../docker/docker_tango_python/Dockerfile" diff --git a/docs/snips/deploy_autolab_a_stripped.py b/docs/snips/deploy_autolab_a_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..9d04cd79df1cbaa504ea3e694879bb8a72e125da --- /dev/null +++ b/docs/snips/deploy_autolab_a_stripped.py @@ -0,0 +1,6 @@ +# autolab_example_py_upload/instructor/cs102_autolab/deploy_autolab.py +# Step 1: Download and compile docker grading image. You only need to do this once. +download_docker_images("../docker") # Download docker images from gitlab (only do this once). +dockerfile = f"../docker/docker_tango_python/Dockerfile" +autograde_image = 'tango_python_tue2' # Tag given to the image in case you have multiple images. +compile_docker_image(Dockerfile=dockerfile, tag=autograde_image, no_cache=False) # Compile docker image. \ No newline at end of file diff --git a/docs/snips/deploy_autolab_b.py b/docs/snips/deploy_autolab_b.py index 51c186d99ca0972cb9d59867c9c8983c46b91ba3..96082fcda1c7fc0db23cea3448cedc56b6be50cb 100644 --- a/docs/snips/deploy_autolab_b.py +++ b/docs/snips/deploy_autolab_b.py @@ -1,4 +1,4 @@ -# autolab_example_py_upload/instructor/cs102_autolab/deploy_autolab.py + # autolab_example_py_upload/instructor/cs102_autolab/deploy_autolab.py # Step 2: Create the cs102.tar file from the grade scripts. instructor_base = f"." student_base = f"../../students/cs102_autolab" diff --git a/docs/snips/deploy_autolab_b_stripped.py b/docs/snips/deploy_autolab_b_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..62303d160b49af1c058636324bfac8b3438d93e6 --- /dev/null +++ b/docs/snips/deploy_autolab_b_stripped.py @@ -0,0 +1,14 @@ +# autolab_example_py_upload/instructor/cs102_autolab/deploy_autolab.py +# Step 2: Create the cs102.tar file from the grade scripts. +instructor_base = f"." +student_base = f"../../students/cs102_autolab" + +from report2_test import Report2 +# INSTRUCTOR_GRADE_FILE = +output_tar = new_deploy_assignment("cs105h", # Autolab name of assignment (and name of .tar file) + INSTRUCTOR_BASE=instructor_base, + INSTRUCTOR_GRADE_FILE=f"{instructor_base}/report2_test_grade.py", + STUDENT_BASE=student_base, + STUDENT_GRADE_FILE=f"{instructor_base}/report2_test.py", + autograde_image_tag=autograde_image, + homework_file="homework1.py") \ No newline at end of file diff --git a/docs/snips/deploy_docker_a_stripped.py b/docs/snips/deploy_docker_a_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..b3d8cb42f1d1c7436ad515763e6523e545d7ffc1 --- /dev/null +++ b/docs/snips/deploy_docker_a_stripped.py @@ -0,0 +1,10 @@ +# example_docker/instructor/cs103/deploy.py +if __name__ == "__main__": + # Step 1: Deploy the students files and return the directory they were written to + setup_grade_file_report(Report3) # Create report3_complete_grade.py which tests everything + + fout, Report = remove_hidden_methods(Report3, outfile="report3.py") # Create report3.py without @hide-methods + setup_grade_file_report(Report) # Create report3_grade.py for the students + + student_directory = "../../students/cs103" + snip_dir("./", student_directory, exclude=['*.token', 'deploy.py', 'report3_complete*.py', '.*']) \ No newline at end of file diff --git a/docs/snips/deploy_docker_b.py b/docs/snips/deploy_docker_b.py index 7861a0918b8d874a29b56d200be5bcef14222d1a..b619acdda924078edeb5b8c4adfd53fdd7076f43 100644 --- a/docs/snips/deploy_docker_b.py +++ b/docs/snips/deploy_docker_b.py @@ -1,3 +1,3 @@ -# example_docker/instructor/cs103/deploy.py + # example_docker/instructor/cs103/deploy.py os.system("cd ../../students && python -m cs103.report3_grade") student_token_file = glob.glob(student_directory + "/*.token").pop() \ No newline at end of file diff --git a/docs/snips/deploy_docker_b_stripped.py b/docs/snips/deploy_docker_b_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..75b28f43445243c7e7fb7220b7432b62a7cc375a --- /dev/null +++ b/docs/snips/deploy_docker_b_stripped.py @@ -0,0 +1,3 @@ +# example_docker/instructor/cs103/deploy.py +os.system("cd ../../students && python -m cs103.report3_grade") +student_token_file = glob.glob(student_directory + "/*.token").pop() \ No newline at end of file diff --git a/docs/snips/deploy_docker_c.py b/docs/snips/deploy_docker_c.py index fa831e5ccbf1835ccfa263f1af3dca1d821a9f09..ab632f20259e6e1376a1cea978094f4223b6a144 100644 --- a/docs/snips/deploy_docker_c.py +++ b/docs/snips/deploy_docker_c.py @@ -1,4 +1,4 @@ -# example_docker/instructor/cs103/deploy.py + # example_docker/instructor/cs103/deploy.py # Step 3: Compile the Docker image (obviously you should only do this once). download_docker_images(destination="../docker") # Download an up-to-date docker image from gitlab. Dockerfile = "../docker/unitgrade-docker/Dockerfile" # Location of just downloaded docker file diff --git a/docs/snips/deploy_docker_c_stripped.py b/docs/snips/deploy_docker_c_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..5a2f567ac15521191077b3d47f97ac87f807fe97 --- /dev/null +++ b/docs/snips/deploy_docker_c_stripped.py @@ -0,0 +1,5 @@ +# example_docker/instructor/cs103/deploy.py +# Step 3: Compile the Docker image (obviously you should only do this once). +download_docker_images(destination="../docker") # Download an up-to-date docker image from gitlab. +Dockerfile = "../docker/unitgrade-docker/Dockerfile" # Location of just downloaded docker file +compile_docker_image(Dockerfile, tag="unitgrade-docker") \ No newline at end of file diff --git a/docs/snips/deploy_docker_d.py b/docs/snips/deploy_docker_d.py index 816b5bbdab8d604fce23bac107a272a699ffc2dd..9f1d46b500186fff9e1d46b072260cd800e0d4c2 100644 --- a/docs/snips/deploy_docker_d.py +++ b/docs/snips/deploy_docker_d.py @@ -1,4 +1,4 @@ -# example_docker/instructor/cs103/deploy.py + # example_docker/instructor/cs103/deploy.py # Step 4: Test the students code in the .token file and get the results-token-file: token = docker_run_token_file(Dockerfile_location=Dockerfile, host_tmp_dir=os.path.dirname(Dockerfile) + "/home", diff --git a/docs/snips/deploy_docker_d_stripped.py b/docs/snips/deploy_docker_d_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..2b9a3b54170546194fb8e7b23c18b3d61af48e0c --- /dev/null +++ b/docs/snips/deploy_docker_d_stripped.py @@ -0,0 +1,7 @@ +# example_docker/instructor/cs103/deploy.py +# Step 4: Test the students code in the .token file and get the results-token-file: +token = docker_run_token_file(Dockerfile_location=Dockerfile, + host_tmp_dir=os.path.dirname(Dockerfile) + "/home", + student_token_file=student_token_file, + instructor_grade_script="report3_complete_grade.py", + tag="unitgrade-docker") \ No newline at end of file diff --git a/docs/snips/deploy_docker_e.py b/docs/snips/deploy_docker_e.py index 8e99da206cf1468a66e44cb8cb739f84482f0e49..0b31d986e2f40e73032a5a00bbcd5f2f3c1b09fe 100644 --- a/docs/snips/deploy_docker_e.py +++ b/docs/snips/deploy_docker_e.py @@ -1,4 +1,4 @@ -# example_docker/instructor/cs103/deploy.py + # example_docker/instructor/cs103/deploy.py # Load the two token files and compare their scores checked_token, _ = load_token(token) results, _ = load_token(student_token_file) diff --git a/docs/snips/deploy_docker_e_stripped.py b/docs/snips/deploy_docker_e_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..68630dea92bb28174ab77a84346886b177659df8 --- /dev/null +++ b/docs/snips/deploy_docker_e_stripped.py @@ -0,0 +1,7 @@ +# example_docker/instructor/cs103/deploy.py +# Load the two token files and compare their scores +checked_token, _ = load_token(token) +results, _ = load_token(student_token_file) + +print("Student's score was:", results['total']) +print("My independent evaluation of the students score was", checked_token['total']) \ No newline at end of file diff --git a/docs/snips/deploy_stripped.py b/docs/snips/deploy_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..52b364eeef9597dcaa5bc479d6db2e2ba5329fec --- /dev/null +++ b/docs/snips/deploy_stripped.py @@ -0,0 +1,10 @@ +# 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 + +if __name__ == "__main__": + setup_grade_file_report(Report1) # Make the report1_grade.py report file + + # Deploy the files using snipper: https://gitlab.compute.dtu.dk/tuhe/snipper + snip_dir("./", "../../students/cs101", exclude=['__pycache__', '*.token', 'deploy.py']) \ No newline at end of file diff --git a/docs/snips/homework1.py b/docs/snips/homework1.py index 54fe19e25b256c7cfaee3d59c8f6d833b2e8a984..a5a9b65c22002cb97ce6e80fd2063010159c8af5 100644 --- a/docs/snips/homework1.py +++ b/docs/snips/homework1.py @@ -1,4 +1,4 @@ -# autolab_example_py_upload/instructor/cs102_autolab/homework1.py +# example_flat/instructor/cs101flat/homework1.py def reverse_list(mylist): #!f """ Given a list 'mylist' returns a list consisting of the same elements in reverse order. E.g. @@ -9,8 +9,9 @@ def reverse_list(mylist): #!f 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*2 + return a+b -if __name__ == "__main__": # Example usage: +if __name__ == "__main__": + # Example usage: print(f"Your result of 2 + 2 = {add(2,2)}") print(f"Reversing a small list", reverse_list([2,3,5,7])) \ No newline at end of file diff --git a/docs/snips/homework1_stripped.py b/docs/snips/homework1_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..a5a9b65c22002cb97ce6e80fd2063010159c8af5 --- /dev/null +++ b/docs/snips/homework1_stripped.py @@ -0,0 +1,17 @@ +# example_flat/instructor/cs101flat/homework1.py +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__": + # Example usage: + print(f"Your result of 2 + 2 = {add(2,2)}") + print(f"Reversing a small list", reverse_list([2,3,5,7])) \ No newline at end of file diff --git a/docs/snips/homework_hints_hints_stripped.py b/docs/snips/homework_hints_hints_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..ea41a2e3e2d31e10ef848eb12f3ca6157f384232 --- /dev/null +++ b/docs/snips/homework_hints_hints_stripped.py @@ -0,0 +1,23 @@ +# 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 diff --git a/docs/snips/in_progress.py b/docs/snips/in_progress.py index 64a406d0ea52af8172d2c6c8f7a414eeaa451e31..228d1e2d128c9a005534151f286388717b172073 100644 --- a/docs/snips/in_progress.py +++ b/docs/snips/in_progress.py @@ -1,4 +1,4 @@ -# example_in_progress/in_progress.py + # 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): diff --git a/docs/snips/in_progress_stripped.py b/docs/snips/in_progress_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..228d1e2d128c9a005534151f286388717b172073 --- /dev/null +++ b/docs/snips/in_progress_stripped.py @@ -0,0 +1,25 @@ + # 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 diff --git a/docs/snips/moss_example_stripped.py b/docs/snips/moss_example_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..c8eb528ba6ac306b3996dff2cdc769ff764ad120 --- /dev/null +++ b/docs/snips/moss_example_stripped.py @@ -0,0 +1,7 @@ +# example_moss/moss_example.py +from unitgrade_private.plagiarism.mossit import moss_it, get_id + +if __name__ == "__main__": + # Extract the moss id ("12415...") from the perl script and test: + id = get_id("../../../02465private/admin/moss.pl") + moss_it(whitelist_dir="whitelist", submissions_dir="student_submissions", moss_id=id) \ No newline at end of file diff --git a/docs/snips/problem1_vectors.txt b/docs/snips/problem1_vectors.txt new file mode 100644 index 0000000000000000000000000000000000000000..c64c795333ebe0e33d4b9caf7de7a53c17624e66 --- /dev/null +++ b/docs/snips/problem1_vectors.txt @@ -0,0 +1,15 @@ +(1,2) (1,2) (1,2) +(1,2) (2,2) (1,2) +(1,2) (1,2) (1,2) + +(9,8) (2,-2) (2,-2) +(2,-2) (2,-2) (2,-2) +(2,-2) (2,-2) (9,8) + +(10,10) (3,0) (3,0) +(3,0) (4,0) (3,0) +(3,0) (3,0) (10,10) +Result of scaling A by 2 +(2,4) (2,4) (2,4) +(2,4) (4,4) (2,4) +(2,4) (2,4) (2,4) diff --git a/docs/snips/report1_all.py b/docs/snips/report1_all.py index 2c9e51bb6ba8a087d40e4a57d442b37802388a41..67c1bf367647e31250d69eb0363c8e5db27da89e 100644 --- a/docs/snips/report1_all.py +++ b/docs/snips/report1_all.py @@ -18,9 +18,4 @@ class Report1(Report): pack_imports = [cs101] # Include all .py files in this folder if __name__ == "__main__": - # from HtmlTestRunner import HTMLTestRunner - import HtmlTestRunner - unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(output='example_dir')) - - - # evaluate_report_student(Report1()) \ No newline at end of file + evaluate_report_student(Report1()) \ No newline at end of file diff --git a/docs/snips/report1_all_stripped.py b/docs/snips/report1_all_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..67c1bf367647e31250d69eb0363c8e5db27da89e --- /dev/null +++ b/docs/snips/report1_all_stripped.py @@ -0,0 +1,21 @@ +# example_simplest/instructor/cs101/report1.py +import unittest +from unitgrade import Report, evaluate_report_student +import cs101 +from cs101.homework1 import reverse_list, add + +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]) + +class Report1(Report): + title = "CS 101 Report 1" + questions = [(Week1, 10)] # Include a single question for a total of 10 credits. + pack_imports = [cs101] # Include all .py files in this folder + +if __name__ == "__main__": + evaluate_report_student(Report1()) \ No newline at end of file diff --git a/docs/snips/report1_stripped.py b/docs/snips/report1_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..b3c7ad0e7105accb5e82c7c7e0846475b971672c --- /dev/null +++ b/docs/snips/report1_stripped.py @@ -0,0 +1,10 @@ +# example_simplest/instructor/cs101/report1.py +from cs101.homework1 import reverse_list, add + +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]) \ No newline at end of file diff --git a/docs/snips/report1hints_stripped.py b/docs/snips/report1hints_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..1e987d6985cc5df2330e4f0348e4da1944c176f4 --- /dev/null +++ b/docs/snips/report1hints_stripped.py @@ -0,0 +1,13 @@ +# example_hints/instructor/cs106/report1hints.py +class Week1(UTestCase): + def test_find_all_primes(self): + """ + Hints: + * Insert a breakpoint and check what your function find_primes(4) actually outputs + """ + 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 = [homework_hints] \ No newline at end of file diff --git a/docs/snips/report2.py b/docs/snips/report2.py index ab18c20d27ea9d9d1acfedf973f08bbac51ca60f..27528c75d9ba6bd537be0cfeb986ac775484c003 100644 --- a/docs/snips/report2.py +++ b/docs/snips/report2.py @@ -1,8 +1,6 @@ # example_framework/instructor/cs102/report2.py from unitgrade import UTestCase, cache - - class Week1(UTestCase): @classmethod def setUpClass(cls) -> None: @@ -12,5 +10,5 @@ class Week1(UTestCase): self.assertEqualC(add(2,2)) self.assertEqualC(add(-100, 5)) - # def test_reverse(self): - # self.assertEqualC(reverse_list([1, 2, 3])) \ No newline at end of file + def test_reverse(self): + self.assertEqualC(reverse_list([1, 2, 3])) \ No newline at end of file diff --git a/docs/snips/report2_b.py b/docs/snips/report2_b.py index cd07d0fd665b3b6b55cdd52c6a17052b83c12069..510320ff5e49563628e47e6d6e46bdd09783447a 100644 --- a/docs/snips/report2_b.py +++ b/docs/snips/report2_b.py @@ -1,16 +1,15 @@ # example_framework/instructor/cs102/report2.py -# class Week1Titles(UTestCase): -# """ The same problem as before with nicer titles """ -# def test_add(self): -# """ Test the addition method add(a,b) """ -# self.assertEqualC(add(2,2)) -# print("output generated by test") -# self.assertEqualC(add(-100, 5)) -# # self.assertEqual(2,3, msg="This test automatically fails.") -# -# def test_reverse(self): -# ls = [1, 2, 3] -# reverse = reverse_list(ls) -# self.assertEqualC(reverse) -# # Although the title is set after the test potentially fails, it will *always* show correctly for the student. -# self.title = f"Checking if reverse_list({ls}) = {reverse}" # Programmatically set the title \ No newline at end of file +class Week1Titles(UTestCase): + """ The same problem as before with nicer titles """ + def test_add(self): + """ Test the addition method add(a,b) """ + self.assertEqualC(add(2,2)) + print("output generated by test") + self.assertEqualC(add(-100, 5)) + + def test_reverse(self): + ls = [1, 2, 3] + reverse = reverse_list(ls) + self.assertEqualC(reverse) + # Although the title is set after the test potentially fails, it will *always* show correctly for the student. + self.title = f"Checking if reverse_list({ls}) = {reverse}" # Programmatically set the title \ No newline at end of file diff --git a/docs/snips/report2_b_stripped.py b/docs/snips/report2_b_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..510320ff5e49563628e47e6d6e46bdd09783447a --- /dev/null +++ b/docs/snips/report2_b_stripped.py @@ -0,0 +1,15 @@ +# example_framework/instructor/cs102/report2.py +class Week1Titles(UTestCase): + """ The same problem as before with nicer titles """ + def test_add(self): + """ Test the addition method add(a,b) """ + self.assertEqualC(add(2,2)) + print("output generated by test") + self.assertEqualC(add(-100, 5)) + + def test_reverse(self): + ls = [1, 2, 3] + reverse = reverse_list(ls) + self.assertEqualC(reverse) + # Although the title is set after the test potentially fails, it will *always* show correctly for the student. + self.title = f"Checking if reverse_list({ls}) = {reverse}" # Programmatically set the title \ No newline at end of file diff --git a/docs/snips/report2_c.py b/docs/snips/report2_c.py index 65c06b3c4aa87b4efdec678235b8a8bcc5e05906..aa444a6283536738901c1d496d0ccc32a9d6179a 100644 --- a/docs/snips/report2_c.py +++ b/docs/snips/report2_c.py @@ -1,16 +1,16 @@ # example_framework/instructor/cs102/report2.py -# 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 +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 diff --git a/docs/snips/report2_c_stripped.py b/docs/snips/report2_c_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..aa444a6283536738901c1d496d0ccc32a9d6179a --- /dev/null +++ b/docs/snips/report2_c_stripped.py @@ -0,0 +1,16 @@ +# example_framework/instructor/cs102/report2.py +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 diff --git a/docs/snips/report2_stripped.py b/docs/snips/report2_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..27528c75d9ba6bd537be0cfeb986ac775484c003 --- /dev/null +++ b/docs/snips/report2_stripped.py @@ -0,0 +1,14 @@ +# example_framework/instructor/cs102/report2.py +from unitgrade import UTestCase, cache + +class Week1(UTestCase): + @classmethod + def setUpClass(cls) -> None: + a = 234 + + def test_add(self): + self.assertEqualC(add(2,2)) + self.assertEqualC(add(-100, 5)) + + def test_reverse(self): + self.assertEqualC(reverse_list([1, 2, 3])) \ No newline at end of file diff --git a/docs/snips/report2_test_b_stripped.py b/docs/snips/report2_test_b_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..75ffe46c12d70b0cd67a2be5af68445852f5644b --- /dev/null +++ b/docs/snips/report2_test_b_stripped.py @@ -0,0 +1,16 @@ +# autolab_example_py_upload/instructor/cs102_autolab/report2_test.py +class Week1Titles(UTestCase): + """ The same problem as before with nicer titles """ + def test_add(self): + """ Test the addition method add(a,b) """ + self.assertEqualC(add(2,2)) + print("output generated by test") + self.assertEqualC(add(-100, 5)) + # self.assertEqual(2,3, msg="This test automatically fails.") + + def test_reverse(self): + ls = [1, 2, 3] + reverse = reverse_list(ls) + self.assertEqualC(reverse) + # Although the title is set after the test potentially fails, it will *always* show correctly for the student. + self.title = f"Checking if reverse_list({ls}) = {reverse}" # Programmatically set the title \ No newline at end of file diff --git a/docs/snips/report2_test_c_stripped.py b/docs/snips/report2_test_c_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..bdeaacea04f901b760bc377de5745add1a11baec --- /dev/null +++ b/docs/snips/report2_test_c_stripped.py @@ -0,0 +1,16 @@ +# autolab_example_py_upload/instructor/cs102_autolab/report2_test.py +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 diff --git a/docs/snips/report2_test_stripped.py b/docs/snips/report2_test_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..9c686bd25db47875c75bb330fa8d6667edba17cc --- /dev/null +++ b/docs/snips/report2_test_stripped.py @@ -0,0 +1,13 @@ +# autolab_example_py_upload/instructor/cs102_autolab/report2_test.py +from unitgrade import UTestCase, cache +import homework1 +import unittest + + +class Week1(UTestCase): + def test_add(self): + self.assertEqualC(add(2,2)) + self.assertEqualC(add(-100, 5)) + + def test_reverse(self): + self.assertEqualC(reverse_list([1, 2, 3])) \ No newline at end of file diff --git a/docs/snips/report3_complete_stripped.py b/docs/snips/report3_complete_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..69121d4b5b9ebbd9de4852ee2696d67d5cdcedf5 --- /dev/null +++ b/docs/snips/report3_complete_stripped.py @@ -0,0 +1,18 @@ +# example_docker/instructor/cs103/report3_complete.py +from unitgrade import UTestCase, Report +from unitgrade.utils import hide +from unitgrade import evaluate_report_student +import cs103 + +class AutomaticPass(UTestCase): + def test_automatic_pass(self): + self.assertEqual(2, 2) # For simplicity, this test will always pass + + @hide # The @hide-decorator tells unitgrade_v1 to hide the test for students. + def test_hidden_fail(self): + self.assertEqual(2, 3) # For simplicity, this test will always fail. + +class Report3(Report): + title = "CS 101 Report 3" + questions = [(AutomaticPass, 10)] # Include a single question for 10 credits. + pack_imports = [cs103] \ No newline at end of file diff --git a/docs/snips/report3_stripped.py b/docs/snips/report3_stripped.py new file mode 100644 index 0000000000000000000000000000000000000000..e7c3d78542627186dfae9596429ce78fc65621a0 --- /dev/null +++ b/docs/snips/report3_stripped.py @@ -0,0 +1,15 @@ +# example_docker/instructor/cs103/report3.py +from unitgrade import UTestCase, Report +from unitgrade.utils import hide +from unitgrade import evaluate_report_student +import cs103 + +class AutomaticPass(UTestCase): + def test_automatic_pass(self): + self.assertEqual(2, 2) # For simplicity, this test will always pass + + +class Report3(Report): + title = "CS 101 Report 3" + questions = [(AutomaticPass, 10)] # Include a single question for 10 credits. + pack_imports = [cs103] \ No newline at end of file diff --git a/examples/autolab_example_py_upload/instructor/cs102_autolab/homework1.py b/examples/autolab_example_py_upload/instructor/cs102_autolab/homework1.py index 839b6a5fa5eeef8f8093d7d8827bf0f552c6e0a4..7575516bdbfe80a016707765a06c332457cdb62d 100644 --- a/examples/autolab_example_py_upload/instructor/cs102_autolab/homework1.py +++ b/examples/autolab_example_py_upload/instructor/cs102_autolab/homework1.py @@ -1,4 +1,4 @@ -def reverse_list(mylist): #!f #!s;keeptags +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). @@ -12,4 +12,4 @@ def add(a,b): #!f if __name__ == "__main__": # Example usage: print(f"Your result of 2 + 2 = {add(2,2)}") - print(f"Reversing a small list", reverse_list([2,3,5,7])) #!s + print(f"Reversing a small list", reverse_list([2,3,5,7])) diff --git a/examples/example_framework/instructor/cs102/homework1.py b/examples/example_framework/instructor/cs102/homework1.py index 94004fc5d7ed38a9a3598d4b7ed9b0e08c6f6793..469f086e6168fc0ee00265a4bcb1daccd337cff2 100644 --- a/examples/example_framework/instructor/cs102/homework1.py +++ b/examples/example_framework/instructor/cs102/homework1.py @@ -1,11 +1,11 @@ -def reverse_list(mylist): #!f #!s;keeptags +def reverse_list(mylist): """ Given a list 'mylist' returns a list consisting of the same elements in reverse order. E.g. reverse_list([1,2,3]) should return [3,2,1] (as a list). """ return list(reversed(mylist)) -def add(a,b): #!f +def add(a,b): """ Given two numbers `a` and `b` this function should simply return their sum: > add(a,b) = a+b """ return a+b @@ -13,4 +13,4 @@ def add(a,b): #!f if __name__ == "__main__": # Example usage: print(f"Your result of 2 + 2 = {add(2,2)}") - print(f"Reversing a small list", reverse_list([2,3,5,7])) #!s + print(f"Reversing a small list", reverse_list([2,3,5,7])) diff --git a/examples/example_framework/instructor/cs102/report2.py b/examples/example_framework/instructor/cs102/report2.py index ae3366e7cacab9dd9e75f5d4b36353132626ed52..f0080c8f4421563d63480fc245f5602cc752efef 100644 --- a/examples/example_framework/instructor/cs102/report2.py +++ b/examples/example_framework/instructor/cs102/report2.py @@ -1,9 +1,7 @@ from unitgrade.framework import Report from unitgrade.evaluate import evaluate_report_student from cs102.homework1 import add, reverse_list -from unitgrade import UTestCase, cache # !s - - +from unitgrade import UTestCase, cache #!s class Week1(UTestCase): @classmethod @@ -14,61 +12,58 @@ class Week1(UTestCase): self.assertEqualC(add(2,2)) self.assertEqualC(add(-100, 5)) - # def test_reverse(self): - # self.assertEqualC(reverse_list([1, 2, 3])) #!s - # - # def test_output_capture(self): - # with self.capture() as out: - # print("hello world 42") # Genereate some output (i.e. in a homework script) - # self.assertEqual(out.numbers[0], 42) # out.numbers is a list of all numbers generated - # self.assertEqual(out.output, "hello world 42") # you can also access the raw output. + def test_reverse(self): + self.assertEqualC(reverse_list([1, 2, 3])) #!s + + def test_output_capture(self): + with self.capture() as out: + print("hello world 42") # Genereate some output (i.e. in a homework script) + self.assertEqual(out.numbers[0], 42) # out.numbers is a list of all numbers generated + self.assertEqual(out.output, "hello world 42") # you can also access the raw output. + +class Week1Titles(UTestCase): #!s=b + """ The same problem as before with nicer titles """ + def test_add(self): + """ Test the addition method add(a,b) """ + self.assertEqualC(add(2,2)) + print("output generated by test") + self.assertEqualC(add(-100, 5)) + + def test_reverse(self): + ls = [1, 2, 3] + reverse = reverse_list(ls) + self.assertEqualC(reverse) + # Although the title is set after the test potentially fails, it will *always* show correctly for the student. + self.title = f"Checking if reverse_list({ls}) = {reverse}" # Programmatically set the title #!s=b + + 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 Week1Titles(UTestCase): #!s=b -# """ The same problem as before with nicer titles """ -# def test_add(self): -# """ Test the addition method add(a,b) """ -# self.assertEqualC(add(2,2)) -# print("output generated by test") -# self.assertEqualC(add(-100, 5)) -# # self.assertEqual(2,3, msg="This test automatically fails.") -# -# def test_reverse(self): -# ls = [1, 2, 3] -# reverse = reverse_list(ls) -# self.assertEqualC(reverse) -# # Although the title is set after the test potentially fails, it will *always* show correctly for the student. -# self.title = f"Checking if reverse_list({ls}) = {reverse}" # Programmatically set the title #!s -# -# 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): #!s=c -# @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 #!s=c +class Question2(UTestCase): #!s=c + @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) -# w = Week1 + 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 #!s=c import cs102 class Report2(Report): title = "CS 102 Report 2" questions = [(Week1, 10), - # (Week1Titles, 6) + (Week1Titles, 6) ] pack_imports = [cs102] diff --git a/examples/example_simplest/instructor/cs101/report1.py b/examples/example_simplest/instructor/cs101/report1.py index ce58ec5d3c413d847bea79a81704683e913f35d5..68ba5666e1edbac12a3f3c959271cf0f466862b3 100644 --- a/examples/example_simplest/instructor/cs101/report1.py +++ b/examples/example_simplest/instructor/cs101/report1.py @@ -17,10 +17,4 @@ class Report1(Report): pack_imports = [cs101] # Include all .py files in this folder if __name__ == "__main__": - # from HtmlTestRunner import HTMLTestRunner - import HtmlTestRunner - unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(output='example_dir')) - - - # evaluate_report_student(Report1()) #!s=all - # unittest.main(verbosity=2) # Uncomment to run everything as a regular unittest + evaluate_report_student(Report1()) #!s=all diff --git a/examples/presentation/students/cpp_course/fragment.py b/examples/presentation/students/cpp_course/fragment.py index 0ea0ff6024d2b542ff17c3d3c86857289b8bacba..ca71abda8ccf7336d0cf948e897b4d2a237e4863 100644 --- a/examples/presentation/students/cpp_course/fragment.py +++ b/examples/presentation/students/cpp_course/fragment.py @@ -9,5 +9,3 @@ s = " 1 / 4 * 1 / 2" print("Result of", s, "is", from_string(s)) s = "5 / 2 div 10 / 3" print("Result of", s, "is", from_string(s)) -pass -#!i diff --git a/src/unitgrade_devel.egg-info/SOURCES.txt b/src/unitgrade_devel.egg-info/SOURCES.txt index 4540eb0b24ef94f90cb61d357f23ae86de0a6414..7844ac4231c4868c84940081a887626bff7e15ee 100644 --- a/src/unitgrade_devel.egg-info/SOURCES.txt +++ b/src/unitgrade_devel.egg-info/SOURCES.txt @@ -23,6 +23,7 @@ src/unitgrade_private/hidden_create_files.py src/unitgrade_private/hidden_gather_upload.py src/unitgrade_private/run.py src/unitgrade_private/token_loader.py +src/unitgrade_private/utils.py src/unitgrade_private/version.py src/unitgrade_private/autolab/__init__.py src/unitgrade_private/autolab/autolab.py diff --git a/src/unitgrade_private/utils.py b/src/unitgrade_private/utils.py index ae4bd62dfea4bd2909e97e7d3678810a7c2e46b0..b335a4b863ad44d2a7d6f800e16b2e617b957e68 100644 --- a/src/unitgrade_private/utils.py +++ b/src/unitgrade_private/utils.py @@ -24,12 +24,17 @@ def exit_after(s): ''' def outer(fn): def inner(*args, **kwargs): - timer = threading.Timer(s, quit_function, args=[fn.__name__]) - timer.start() + result = 0 try: - result = fn(*args, **kwargs) - finally: - timer.cancel() + timer = threading.Timer(s, quit_function, args=[fn.__name__]) + timer.start() + try: + result = fn(*args, **kwargs) + finally: + timer.cancel() + except KeyboardInterrupt as e: + print("The function took to long and is being killed.") + args[0].assertEqual(1,2, msg="Function took to long so I am killing it.") return result return inner return outer diff --git a/src/unitgrade_private/version.py b/src/unitgrade_private/version.py index aa5efd54228352e81ee9c582b7d83f061aa9c966..5c2098c4689bbe95e6e068ea2f6a6ac579a3416e 100644 --- a/src/unitgrade_private/version.py +++ b/src/unitgrade_private/version.py @@ -1 +1 @@ -__version__ = "0.1.60" +__version__ = "0.1.62"