Skip to content

Commit f080a6c

Browse files
authored
Merge pull request #6 from JMU-CS/gui-and-tidy
Gui and tidy
2 parents 2d936ea + bdfde78 commit f080a6c

46 files changed

Lines changed: 1154 additions & 174 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 116 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,142 @@ Features include:
1111
* provides a `@required` annotation that makes a test required, so
1212
that subsequent tests will automatically fail if it fails.
1313
* provide several additional assertion methods, including an
14-
`assertScriptOutputEqual` method that makes it possible to specify
14+
`assertOutputEqual` method that makes it possible to specify
1515
stdin input and check for correct stdout output for a Python
1616
script.
1717
* Some additional utility functions for checking PEP 8 compliance
1818
and applying regex searches to submitted source files.
1919
* A script that makes it possible to test the autograder logic
2020
locally before uploading to the Gradescope server:
2121
`test_autograder.py`
22+
* A graphical tool for testing autograders and building autograder zip
23+
files.
2224

23-
Documentation can be found here: <https://jmu-cs.github.io/jmu_python_gradescope_utils/>
25+
API Documentation can be found here: <https://jmu-cs.github.io/jmu_python_gradescope_utils/>
2426

2527
## Installation
2628

2729
```
30+
pip3 install wheel
2831
pip3 install git+https://github.com/JMU-CS/jmu_python_gradescope_utils.git
2932
```
3033

31-
## Instructions
34+
On Linux, this will probably add the GUI script to your PATH so that it can be executed as:
3235

33-
See `examples/hello_world_autograder/` for a sample autograder.
36+
```
37+
$ jmu_gradescope_builder.py
38+
```
39+
40+
If that doesn't work, you may need to execute the script using the Python interpreter:
41+
42+
```
43+
python3 wherever/on/your/system/bin/jmu_gradescope_builder.py
44+
```
45+
46+
Note that the GUI uses tk, which should be available in Windows, Linux
47+
and OSX. Unfortunately, the tk library distributed with some versions
48+
of OSX is broken, resulting in a blank black window. There are some
49+
reports that upgrading Python to 3.10 resolves the issue.
50+
51+
## Autograder Format
52+
53+
See `examples/hello_world/` and `hello_world_w_coverage` for a sample autograders.
54+
55+
Autograder folders are organized as follows:
3456

35-
To perform a test run:
57+
```
58+
hello_world/
59+
60+
├── config.ini
61+
62+
├── configurations/
63+
│ ├── flake8.cfg
64+
│ ├── docstring.cfg
65+
│ └── requirements.txt
66+
67+
├── sample/
68+
│ └── hello_world.py
69+
70+
└── scaffolding/
71+
72+
└── tests/
73+
└── test_hello.py
74+
```
75+
76+
77+
### `config.ini`
78+
79+
This specifies the files that must be submitted by the student:
3680

37-
```bash
38-
$ cd /your/autograder
39-
$ test_autograder.py /path/to/sample/submission/folder
4081
```
82+
[SUBMIT]
83+
code: hello_world.py
84+
tests:
85+
```
86+
87+
The `test` field should contain the names of student test files for assignments that require student-submitted unit tests.
88+
89+
### `flake8.cfg`
90+
91+
This is the `flake8` configuration file that will be used by
92+
[assertPassesPep8](https://jmu-cs.github.io/jmu_python_gradescope_utils/jmu_test_case.html#jmu_gradescope_utils.jmu_test_case._JmuTestCase.assertPassesPep8).
93+
94+
The [flake8](https://flake8.pycqa.org/en/latest/index.html) tool is
95+
used by our library for Python style checking. The possible error
96+
codes are listed in the following locations:
4197

42-
The output of the test will be stored in a file named
43-
`test_results.json`.
98+
* [pycodestyle error codes](https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes)
99+
* [flake8 error codes](https://flake8.pycqa.org/en/latest/user/error-codes.html)
44100

45-
Once everything is working correctly, just zip the contents of the
46-
autograder folder and upload to Gradescope:
47101

48-
```bash
49-
$ cd /your/autograder
50-
$ zip -r autograder.zip .
102+
The current default looks like this:
51103
```
104+
[flake8]
105+
select = E, F, C90
106+
ignore = W, E226, E123, W504, N818, E704, E24, E121, E126
107+
max-line-length = 100
108+
```
109+
110+
### `docstring.cfg`
111+
This is the `flake8` configuration file that will be used by [assertDocstringsCorrect](https://jmu-cs.github.io/jmu_python_gradescope_utils/jmu_test_case.html#jmu_gradescope_utils.jmu_test_case._JmuTestCase.assertDocstringsCorrect). The current default looks like this:
112+
113+
```
114+
[flake8]
115+
select = D,DAR
116+
ignore = D401
117+
118+
[pydocstyle]
119+
convention=google
120+
121+
[darglint]
122+
docstring_style=google
123+
```
124+
125+
The available error codes for the two plugins can be found here:
126+
127+
* `pydocstyle`: <http://www.pydocstyle.org/en/stable/error_codes.html>
128+
* `darglint`: <https://github.com/terrencepreilly/darglint#error-codes>
129+
130+
131+
### `requirements.txt`
132+
133+
This file should list any python packages that are required for this
134+
assignment. They will be pip installed on the server by the autograder
135+
script.
136+
137+
### sample/
138+
139+
This folder should contain a reference solution. This isn't strictly
140+
necessary, but the autograder testing utility will expect to find a
141+
solution at this location.
142+
143+
### scaffolding/
144+
145+
Any files in this folder will be copied into the same folder as the
146+
student submission before testing. This could be data files or Python
147+
modules.
148+
149+
### tests/
150+
151+
Instructor unit tests.
152+

doc/jmu_test_case.rst

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,3 @@ JmuTestCase
1414
:members:
1515
:private-members:
1616
:undoc-members:
17-
18-
.. automodule:: jmu_gradescope_utils.utils
19-
:members:
20-
:private-members:
21-
:undoc-members:
22-
23-
.. automodule:: jmu_gradescope_utils.coverage_utils
24-
:members:
25-
:private-members:
26-
:undoc-members:

examples/hello_world/config.ini

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[SUBMIT]
2+
# Student submitted code files, comma separated
3+
code: hello_world.py
4+
5+
# Student submitted test files, comma separated
6+
tests:
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[flake8]
2+
select = D,DAR
3+
ignore = D401
4+
5+
[pydocstyle]
6+
convention=google
7+
8+
[darglint]
9+
docstring_style=google
10+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[flake8]
2+
select = E, F, C90
3+
ignore = W, E226, E123, W504, N818, E704, E24, E121, E126
4+
max-line-length = 100
File renamed without changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print("Hello World!")

examples/hello_world/scaffolding/.gitignore

Whitespace-only changes.
Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,28 @@
11
import unittest
22
from gradescope_utils.autograder_utils.decorators import weight, number
3-
from jmu_gradescope_utils import JmuTestCase, required, check_submitted_files
3+
from jmu_gradescope_utils import JmuTestCase, required
44
import jmu_gradescope_utils
55

6+
FILENAME = 'hello_world.py'
67

78
class TestHelloWorld(JmuTestCase):
89

9-
FILENAME = 'hello_world.py'
10-
1110
@required()
1211
@weight(0)
1312
def test_submitted_files(self):
1413
"""Check submitted files"""
15-
self.assertRequiredFilesPresent([self.FILENAME])
14+
self.assertRequiredFilesPresent([FILENAME])
1615

17-
1816
@weight(2)
1917
def test_pep8(self):
2018
"""PEP 8 checks. """
21-
self.assertPassesPep8(self.FILENAME)
22-
19+
self.assertPassesPep8(FILENAME)
20+
2321
@weight(8)
24-
def test_output(self):
25-
"""hello_world.py output checks. """
22+
def test_functionality(self):
23+
"""Test for correct output."""
24+
2625
string_in = ""
2726
expected = "Hello World!\n"
28-
self.assertOutputCorrect(self.FILENAME, string_in, expected)
29-
30-
31-
27+
self.assertOutputEqual('hello_world.py', string_in, expected)
28+
print('Correct output:\n' + expected)
-3.27 KB
Binary file not shown.

0 commit comments

Comments
 (0)