mirror of
https://github.com/Code-For-Groningen/temmies.git
synced 2025-03-15 15:10:15 +01:00
272 lines
7.3 KiB
Markdown
272 lines
7.3 KiB
Markdown
# Classes
|
|
---
|
|
|
|
## `Themis`
|
|
Creates the initial connection to Themis.
|
|
|
|
### Usage
|
|
```python
|
|
from temmies.themis import Themis
|
|
|
|
themis = Themis("s-number", "password")
|
|
```
|
|
|
|
### Methods
|
|
#### `login()`
|
|
Logs in to Themis. Runs automatically when the class is initialized.
|
|
|
|
#### `get_year(start, end)`
|
|
Returns an instance of a [`Year`](#year) (academic year) between `start` and `end`.
|
|
|
|
```python
|
|
year = themis.get_year(2023, 2024)
|
|
```
|
|
|
|
#### `all_years()`
|
|
Returns a list of `Year` instances corresponding to all years visible to the user.
|
|
|
|
```python
|
|
years = themis.all_years()
|
|
```
|
|
<sub> I don't see why you would need this, but it's here. </sub>
|
|
----
|
|
|
|
## `Year`
|
|
|
|
### Usage
|
|
```python
|
|
year = themis.get_year(2023, 2024)
|
|
```
|
|
|
|
### Methods
|
|
#### `get_course(name)`
|
|
Returns an instance of a [`Course`](#course) with the name `name`.
|
|
|
|
```python
|
|
pf = year.get_course("Programming Fundamentals (for CS)")
|
|
```
|
|
|
|
#### `all_courses()`
|
|
Returns a list of `Course` instances corresponding to all courses visible to the user in a given `Year`.
|
|
|
|
```python
|
|
courses = year.all_courses()
|
|
```
|
|
|
|
----
|
|
|
|
## `Course`
|
|
### Usage
|
|
```python
|
|
pf = year.get_course("Programming Fundamentals (for CS)")
|
|
assignments = pf.get_groups()
|
|
```
|
|
|
|
### Methods
|
|
#### `get_groups(full=False)`
|
|
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.
|
|
|
|
When you have fully traversed the course, you can access everything via indices and the `exercises` and `folders` attributes of the `ExerciseGroup` instances:
|
|
|
|
```python
|
|
ai_group = ai_course.get_groups(full=True)
|
|
exercise = ai_group[7].exercises[1] # Week 11 -> Suitcase packing
|
|
exercise.submit(["suitcase.py"], silent=False)
|
|
```
|
|
|
|
This is equivalent to the case in which we don't traverse the whole course using `get_group` like so:
|
|
|
|
```python
|
|
ai_group = ai_course.get_group("Week 11")
|
|
exercise = ai_group.get_group("Suitcase packing")
|
|
exercise.submit(["suitcase.py"], silent=False)
|
|
```
|
|
|
|
#### `get_group(name, full=False)`
|
|
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
|
|
week1 = pf.get_group("Week 1")
|
|
```
|
|
|
|
----
|
|
|
|
## `ExerciseGroup`
|
|
Setting the `full` flag to `True` will traverse the whole group.
|
|
|
|
- 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
|
|
Let's say we have a folder structure like this:
|
|
```
|
|
- Course Name
|
|
- Week 1
|
|
- Exercise 1
|
|
- Exercise 2
|
|
- Part 1
|
|
- Part 2
|
|
- Week 2
|
|
- Exercise 1
|
|
- Exercise 2
|
|
```
|
|
And we want to get to `Part 2` of `Week 1`'s `Exercise 2`. We would do this:
|
|
|
|
```python
|
|
pf = year.get_course("Programming Fundamentals (for CS)")
|
|
assignments = pf.get_groups()
|
|
week1 = assignments[0] # Week 1
|
|
exercise2 = week1.folders[1] # Exercise 2
|
|
part2 = exercise2.exercises[1] # Part 2
|
|
|
|
# Or, if you don't want to traverse the whole course:
|
|
week1 = pf.get_group("Week 1")
|
|
exercise2 = week1.get_group("Exercise 2")
|
|
part2 = exercise2.get_group("Part 2")
|
|
```
|
|
|
|
### Methods
|
|
#### `download_files(path=".")`
|
|
Downloads all files in the exercise group to a directory `path`. Defaults to the current directory.
|
|
|
|
```python
|
|
assignment.download_files()
|
|
```
|
|
|
|
#### `download_tcs(path=".")`
|
|
Downloads all test cases in the exercise group to a directory `path`. Defaults to the current directory.
|
|
|
|
```python
|
|
assignment.download_tcs()
|
|
```
|
|
|
|
#### `get_group(name, full=False)`
|
|
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
|
|
# Week 1 -> Exercise 2 -> Part 2
|
|
week1 = pf.get_group("Week 1")
|
|
exercise2 = week1.get_group("Exercise 2")
|
|
part2 = exercise2.get_group("Part 2")
|
|
|
|
# This is equivalent to (but faster than):
|
|
week1 = pf.get_groups(full=True)[0]
|
|
exercise2 = week1.folders[1]
|
|
part2 = exercise2.exercises[1]
|
|
```
|
|
|
|
#### `submit(files, judge=True, wait=True, silent=True)`
|
|
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.
|
|
|
|
```python
|
|
suitcase = ai_course.get_group("Week 11").get_group("Suitcase packing")
|
|
suitcase.submit(["suitcase.py"], silent=False)
|
|
|
|
# Output:
|
|
# Submitting to Suitcase packing
|
|
# • suitcase.py
|
|
# 1: ✅
|
|
# 2: ✅
|
|
# 3: ✅
|
|
# ...
|
|
```
|
|
|
|
#### `get_status(text=False)`
|
|
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.
|
|
|
|
```python
|
|
pf = year.get_course("Programming Fundamentals (for CS)")
|
|
exercise = pf.get_group("Lab Session 2").get_group("Recurrence")
|
|
|
|
# Get status
|
|
status = exercise.get_status()
|
|
print(status)
|
|
|
|
# Output:
|
|
{
|
|
'assignment': 'Recurrence',
|
|
'group': 'Y.N. Here',
|
|
'status': 'passed: Passed all test cases',
|
|
'grade': '2.00',
|
|
'total': '2',
|
|
'output limit': '1',
|
|
'passed': '1',
|
|
'leading': <temmies.submission.Submission object at 0x...>,
|
|
'best': <temmies.submission.Submission object at 0x...>,
|
|
'latest': <temmies.submission.Submission object at 0x...>,
|
|
'first_pass': <temmies.submission.Submission object at 0x...>,
|
|
'last_pass': <temmies.submission.Submission object at 0x...>,
|
|
'visible': 'Yes'
|
|
}
|
|
```
|
|
|
|
To access submission details:
|
|
|
|
```python
|
|
leading_submission = status["leading"]
|
|
print(leading_submission.get_files())
|
|
```
|
|
|
|
----
|
|
|
|
## `Submission`
|
|
### Usage
|
|
```python
|
|
submission = pf.get_group("Week 1").get_group("Exercise 1").get_group("Part 1").get_status()["leading"]
|
|
```
|
|
|
|
### Methods
|
|
#### `get_test_cases()`
|
|
Returns a dictionary of test cases and their statuses.
|
|
|
|
```python
|
|
test_cases = submission.get_test_cases()
|
|
print(test_cases)
|
|
|
|
# Output:
|
|
{'1': 'passed', '2': 'passed', '3': 'passed', '4': 'passed', '5': 'passed', '6': 'passed', '7': 'passed', '8': 'passed', '9': 'passed', '10': 'passed'}
|
|
```
|
|
|
|
#### `get_info()`
|
|
Returns a dictionary of information about the submission.
|
|
|
|
```python
|
|
info = submission.get_info()
|
|
print(info)
|
|
|
|
# Output:
|
|
{
|
|
'assignment': 'Part 1',
|
|
'group': 'Y.N. Here',
|
|
'uploaded_by': 'Y.N. Here s1234567',
|
|
'created_on': 'Wed Sep 13 2023 12:51:37 GMT+0200',
|
|
'submitted_on': 'Wed Sep 13 2023 12:51:37 GMT+0200',
|
|
'status': 'passed: Passed all test cases',
|
|
'files': [
|
|
('recurrence.c', '/file/.../recurrence.c'),
|
|
('compile.log', '/file/.../compile.log')
|
|
],
|
|
'language': 'c'
|
|
}
|
|
```
|
|
|
|
#### `get_files()`
|
|
Returns a list of uploaded files in the format `(name, URL)`.
|
|
|
|
```python
|
|
files = submission.get_files()
|
|
print(files)
|
|
|
|
# Output:
|
|
[
|
|
('recurrence.c', '/file/.../recurrence.c'),
|
|
('compile.log', '/file/.../compile.log')
|
|
]
|
|
```
|
|
|
|
----
|