Updated docs ot include changelog and reflect upon recent changes

This commit is contained in:
Boyan 2024-11-17 19:50:05 +01:00
parent 135420d488
commit 019e2c181e
3 changed files with 125 additions and 124 deletions

View File

@ -1,5 +1,6 @@
# Classes # Classes
--- ---
## `Themis` ## `Themis`
Creates the initial connection to Themis. Creates the initial connection to Themis.
@ -28,7 +29,6 @@ Returns a list of `Year` instances corresponding to all years visible to the use
years = themis.all_years() years = themis.all_years()
``` ```
<sub> I don't see why you would need this, but it's here. </sub> <sub> I don't see why you would need this, but it's here. </sub>
---- ----
## `Year` ## `Year`
@ -59,13 +59,12 @@ courses = year.all_courses()
### Usage ### Usage
```python ```python
pf = year.get_course("Programming Fundamentals (for CS)") pf = year.get_course("Programming Fundamentals (for CS)")
print(pf.info) # <- course info attribute
assignments = pf.get_groups() assignments = pf.get_groups()
``` ```
### Methods ### Methods
#### `get_groups(full=False)` #### `get_groups(full=False)`
Returns a list of `ExerciseGroup` instances corresponding to all exercise groups visible to the user in a given `Course`. Default argument is `full=False`, which will only return the (name, link) of each exercise and folder in the group. If `full=True`, it will traverse the whole course. Returns a list of `ExerciseGroup` instances corresponding to all exercise groups visible to the user in a given `Course`. The default argument is `full=False`, which will only return the top-level (name, link) of each exercise and folder in the group. If `full=True`, it will traverse the whole course.
You can traverse the course in both cases, although in different ways. You can traverse the course in both cases, although in different ways.
@ -74,33 +73,33 @@ When you have fully traversed the course, you can access everything via indices
```python ```python
ai_group = ai_course.get_groups(full=True) ai_group = ai_course.get_groups(full=True)
exercise = ai_group[7].exercises[1] # Week 11 -> Suitcase packing exercise = ai_group[7].exercises[1] # Week 11 -> Suitcase packing
exercise.submit("suitcase.py", silent=False)``` exercise.submit(["suitcase.py"], silent=False)
``` ```
This is equivalent to the case in which we don't traverse the full course using `get_group` like so: This is equivalent to the case in which we don't traverse the whole course using `get_group` like so:
```python ```python
ai_group = ai_course.get_group("Week 11") ai_group = ai_course.get_group("Week 11")
exercise = ai_group.get_group("Suitcase packing") exercise = ai_group.get_group("Suitcase packing")
exercise.submit("suitcase.py", silent=False) exercise.submit(["suitcase.py"], silent=False)
``` ```
### `get_group(name, full=False)` #### `get_group(name, full=False)`
Returns an instance of an `ExerciseGroup` with the name `name`. Default argument is `full=False`, which will only return the (name, link) of each exercise and folder in the group. If `full=True`, it will traverse the whole group. Returns an instance of an `ExerciseGroup` with the name `name`. The default argument is `full=False`, which will only return the (name, link) of each exercise and folder in the group. If `full=True`, it will traverse the whole group.
```python ```python
week1 = pf.get_group("Week 1") week1 = pf.get_group("Week 1")
``` ```
----
## `ExerciseGroup` ## `ExerciseGroup`
Setting the `full` flag to `True` will traverse the whole course. Setting the `full` flag to `True` will traverse the whole group.
You can traverse the course in both cases
* Both folders and exercises are represented as `ExerciseGroup` instances.
* Folders will have the `am_exercise` attribute set to `False`.
* Folders can have the `download_files` method called on them.
* Exercises can have the `submit`, `download_files` and `download_tcs` method called on them.
- Both folders and exercises are represented as `ExerciseGroup` instances.
- Folders will have the `am_exercise` attribute set to `False`.
- Folders can have the `download_files` method called on them.
- Exercises can have the `submit`, `download_files`, and `download_tcs` methods called on them.
### Example of folder traversal ### Example of folder traversal
Let's say we have a folder structure like this: Let's say we have a folder structure like this:
@ -124,13 +123,12 @@ week1 = assignments[0] # Week 1
exercise2 = week1.folders[1] # Exercise 2 exercise2 = week1.folders[1] # Exercise 2
part2 = exercise2.exercises[1] # Part 2 part2 = exercise2.exercises[1] # Part 2
# Or, if you dont want to traverse the whole course: # Or, if you don't want to traverse the whole course:
week1 = pf.get_group("Week 1") week1 = pf.get_group("Week 1")
exercise2 = week1.get_group("Exercise 2") exercise2 = week1.get_group("Exercise 2")
part2 = exercise2.get_group("Part 2") part2 = exercise2.get_group("Part 2")
``` ```
### Methods ### Methods
#### `download_files(path=".")` #### `download_files(path=".")`
Downloads all files in the exercise group to a directory `path`. Defaults to the current directory. Downloads all files in the exercise group to a directory `path`. Defaults to the current directory.
@ -146,140 +144,128 @@ Downloads all test cases in the exercise group to a directory `path`. Defaults t
assignment.download_tcs() assignment.download_tcs()
``` ```
#### get_group(name, full=False) #### `get_group(name, full=False)`
This is used when you want to traverse the course dynamically(not recurse through the whole thing). Of course, you can use it even if you've traversed the whole course, but that would overcomplicate things. This is used when you want to traverse the course dynamically (not recurse through the whole thing). You can use it even if you've traversed the whole course.
```python ```python
# Week 1 -> Exercise 2 -> Part 2 # Week 1 -> Exercise 2 -> Part 2
week1 = pf.get_groups("Week 1") week1 = pf.get_group("Week 1")
exercise2 = week1.get_group("Exercise 2") exercise2 = week1.get_group("Exercise 2")
part2 = exercise2.get_group("Part 2") part2 = exercise2.get_group("Part 2")
# This is equivalent to (but faster than): # This is equivalent to (but faster than):
week1 = pf.get_groups("Week 1", full=True) week1 = pf.get_groups(full=True)[0]
exercise2 = week1[1] exercise2 = week1.folders[1]
part2 = exercise2[1] part2 = exercise2.exercises[1]
``` ```
#### `submit(files, judge=True, wait=True, silent=True)`
#### `submit(files)` Submits the files to the exercise. The default arguments are `judge=True`, `wait=True`, and `silent=True`. Setting `judge=False` will not judge the submission immediately. Setting `wait=False` will not wait for the submission to finish. Turning off `silent` will print the submission status dynamically.
Submits the files to the exercise group. Default arguments are `judge=True`, `wait=True` and `silent=True`. `judge` will judge the submission instantly, and `wait` will wait for the submission to finish. Turning off `silent` will print the submission status dynamically.
```python ```python
suitcase = ai.get_group("Week 11") suitcase = ai_course.get_group("Week 11").get_group("Suitcase packing")
suitcase[7].exercises[1].submit("suitcase.py", silent=False) suitcase.submit(["suitcase.py"], silent=False)
# Or
ai.get_group("Week 11").get_group("Suitcase packing").submit("suitcase.py", silent=False)
>>> 1: ✅
>>> 2: ✅
>>> 3: ✅
>>> 4: ✅
>>> 5: ✅
>>> 6: ✅
>>> 7: ✅
>>> 8: ✅
>>> 9: ✅
>>> 10: ✅
# Output:
# Submitting to Suitcase packing
# • suitcase.py
# 1: ✅
# 2: ✅
# 3: ✅
# ...
``` ```
#### `get_status(section=None, text=False)` #### `get_status(text=False)`
Parses the status of the exercise group(from a given section). If `section` is not `None`, it will return the status of the section. Don't set `section` if you don't know what you're doing. Retrieves the status of the exercise group. When `text` is set to `True`, it will return the status as a dictionary of strings. Otherwise, it will return a dictionary where keys map to either strings or `Submission` objects. Common keys include `'leading'`, `'best'`, `'latest'`, etc.
When `text` is set to `True`, it will return the status as a dictionary of strings. Otherwise, it will return a tuple in the form `(dict(str:str), dict(str:Submission))`. Refer to the [Submission](#submission) class for more information.
```python ```python
pf = year.get_course("Programming Fundamentals (for CS)") pf = year.get_course("Programming Fundamentals (for CS)")
pf_as = pf.get_group("Lab Session 2") exercise = pf.get_group("Lab Session 2").get_group("Recurrence")
# Get exercise
exercise = pf_as.get_group("Recurrence")
# Get status # Get status
status = exercise.get_status() status = exercise.get_status()
print(status) print(status)
>>> ( # Output:
>>> { # Information [0] {
>>> 'assignment': 'Recurrence' 'assignment': 'Recurrence',
>>> 'group': 'Y.N. Here' 'group': 'Y.N. Here',
>>> 'status': 'passed: Passed all test cases' 'status': 'passed: Passed all test cases',
>>> 'grade': '2.00' 'grade': '2.00',
>>> 'total': '2' 'total': '2',
>>> 'output limit': '1' 'output limit': '1',
>>> 'passed': '1' 'passed': '1',
>>> 'leading': '/submission/2023-2024/progfun/lab2/recurrence/@submissions/s1234567/s1234567-1' 'leading': <temmies.submission.Submission object at 0x...>,
>>> 'best': '/submission/2023-2024/progfun/lab2/recurrence/@submissions/s1234567/s1234567-1' 'best': <temmies.submission.Submission object at 0x...>,
>>> 'latest': '/submission/2023-2024/progfun/lab2/recurrence/@submissions/s1234567/s1234567-1' 'latest': <temmies.submission.Submission object at 0x...>,
>>> 'first pass': '/submission/2023-2024/progfun/lab2/recurrence/@submissions/s1234567/s1234567-1' 'first_pass': <temmies.submission.Submission object at 0x...>,
>>> 'last pass': '/submission/2023-2024/progfun/lab2/recurrence/@submissions/s1234567/s1234567-1' 'last_pass': <temmies.submission.Submission object at 0x...>,
>>> 'visible': 'Yes' 'visible': 'Yes'
>>> } }
>>> { # Submission instances [1]
>>> 'leading': <submission.Submission object at 0x774ea7a48cd0>
>>> 'best': <submission.Submission object at 0x774ea79af910>
>>> 'latest': <submission.Submission object at 0x774eaa7d3c10>
>>> 'first_pass': <submission.Submission object at 0x774ea77ee810>
>>> 'last_pass': <submission.Submission object at 0x774ea755de10>
>>> }
>>>)
``` ```
#### `get_all_statuses(text=False) To access submission details:
Does the same as `get_status`, but for all visible status sections.
```python
leading_submission = status["leading"]
print(leading_submission.get_files())
```
----
## `Submission` ## `Submission`
### Usage ### Usage
```python ```python
submission = pf.get_group("Week 1").get_group("Exercise 1").get_group("Part 1").get_status()[1]["leading"] # Week 1 -> Exercise 1 -> Part 1 -> Leading submission submission = pf.get_group("Week 1").get_group("Exercise 1").get_group("Part 1").get_status()["leading"]
``` ```
### Methods ### Methods
#### `test_cases()` #### `get_test_cases()`
Returns a list of `TestCase` instances corresponding to all test cases in the submission. Returns a dictionary of test cases and their statuses.
```python ```python
submission = pf.get_group("Week 1").get_group("Exercise 1").get_group("Part 1").get_status()[1]["leading"] test_cases = submission.get_test_cases()
submission.test_cases() print(test_cases)
>>> {'1': 'passed', '2': 'passed', '3': 'passed', '4': 'passed', '5': 'passed', '6': 'passed', '7': 'passed', '8': 'passed', '9': 'passed', '10': 'passed'}
# Output:
{'1': 'passed', '2': 'passed', '3': 'passed', '4': 'passed', '5': 'passed', '6': 'passed', '7': 'passed', '8': 'passed', '9': 'passed', '10': 'passed'}
``` ```
#### `info()` #### `get_info()`
Returns a dictionary of information about the submission. Returns a dictionary of information about the submission.
```python ```python
submission = pf.get_group("Week 1").get_group("Exercise 1").get_group("Part 1").get_status()[1]["leading"] info = submission.get_info()
submission.info() print(info)
>>> { # Output:
>>>'assignment': 'Part 1', {
>>>'group': 'Y.N. Here', 'assignment': 'Part 1',
>>>'uploaded_by': 'Y.N. Here s1234567', 'group': 'Y.N. Here',
>>>'created_on': 'Wed Sep 13 2023 12:51:37 GMT+02002023-09-13T10:51:37.338Z', 'uploaded_by': 'Y.N. Here s1234567',
>>>'submitted_on': 'Wed Sep 13 2023 12:51:37 GMT+02002023-09-13T10:51:37.344Z', 'created_on': 'Wed Sep 13 2023 12:51:37 GMT+0200',
>>>'status': 'passed: Passed all test cases', 'submitted_on': 'Wed Sep 13 2023 12:51:37 GMT+0200',
>>>'files': [('recurrence.c', 'status': 'passed: Passed all test cases',
>>>'/file/2023-2024/progfun/lab2/recurrence/%40submissions/s1234567/s1234567-1/source/recurrence.c'), 'files': [
>>>('compile.log', ('recurrence.c', '/file/.../recurrence.c'),
>>>'/file/2023-2024/progfun/lab2/recurrence/%40submissions/s1234567/s1234567-1/output/compile.log')], ('compile.log', '/file/.../compile.log')
>>>'language': 'c' ],
>>> } 'language': 'c'
}
``` ```
#### `files()` #### `get_files()`
Returns a list of files in the form `(name, link)`. Returns a list of uploaded files in the format `(name, URL)`.
```python ```python
submission = pf.get_group("Week 1").get_group("Exercise 1").get_group("Part 1").get_status()[1]["leading"] files = submission.get_files()
submission.files() print(files)
>>> [('recurrence.c', '/file/2023-2024/progfun/lab2/recurrence/%40submissions/s1234567/s1234567-1/source/recurrence.c'), ('compile.log', '/file/2023-2024/progfun/lab2/recurrence/%40submissions/s1234567/s1234567-1/output/compile.log')] # Output:
[
('recurrence.c', '/file/.../recurrence.c'),
('compile.log', '/file/.../compile.log')
]
``` ```
----

14
docs/changelog.md Normal file
View File

@ -0,0 +1,14 @@
## **Changelog**
### **Version 1.1.0**
#### **Documentation**
- Fixed method signatures to align with actual functionality.
- Updated `get_status` to properly handle `Submission` instances.
- Ensured all class and method examples are consistent with the codebase.
#### **Codebase**
- Prepended `get_` to all methods in `Submission`
- Created base `Group` from which `Course` and `ExerciseGroup` inherit.
-

View File

@ -3,4 +3,5 @@ nav:
- Temmies: index.md - Temmies: index.md
- API Reference: api.md - API Reference: api.md
- About: about.md - About: about.md
- Change Log: changelog.md
theme: readthedocs theme: readthedocs