2024-04-06 16:16:23 +02:00
# Classes
---
2024-11-17 19:50:05 +01:00
2024-04-06 16:16:23 +02:00
## `Themis`
Creates the initial connection to Themis.
### Usage
```python
2024-04-21 20:37:07 +02:00
from temmies.themis import Themis
2024-04-06 16:16:23 +02:00
themis = Themis("s-number", "password")
```
### Methods
#### `login()`
Logs in to Themis. Runs automatically when the class is initialized.
2024-04-10 18:48:21 +02:00
#### `get_year(start, end)`
2024-11-17 19:50:05 +01:00
Returns an instance of a [`Year` ](#year ) (academic year) between `start` and `end` .
2024-04-06 16:16:23 +02:00
```python
2024-04-10 18:48:21 +02:00
year = themis.get_year(2023, 2024)
2024-04-06 16:16:23 +02:00
```
2024-04-10 18:48:21 +02:00
#### `all_years()`
2024-04-06 16:16:23 +02:00
Returns a list of `Year` instances corresponding to all years visible to the user.
```python
2024-04-10 18:48:21 +02:00
years = themis.all_years()
2024-04-06 16:16:23 +02:00
```
< sub > I don't see why you would need this, but it's here. < / sub >
----
## `Year`
### Usage
```python
2024-04-10 18:48:21 +02:00
year = themis.get_year(2023, 2024)
2024-04-06 16:16:23 +02:00
```
### Methods
2024-04-10 18:48:21 +02:00
#### `get_course(name)`
Returns an instance of a [`Course` ](#course ) with the name `name` .
2024-04-06 16:16:23 +02:00
```python
2024-04-10 18:48:21 +02:00
pf = year.get_course("Programming Fundamentals (for CS)")
2024-04-06 16:16:23 +02:00
```
2024-04-10 18:48:21 +02:00
#### `all_courses()`
2024-04-06 16:16:23 +02:00
Returns a list of `Course` instances corresponding to all courses visible to the user in a given `Year` .
```python
2024-04-10 18:48:21 +02:00
courses = year.all_courses()
2024-04-06 16:16:23 +02:00
```
----
## `Course`
### Usage
```python
2024-04-10 18:48:21 +02:00
pf = year.get_course("Programming Fundamentals (for CS)")
assignments = pf.get_groups()
2024-04-06 16:16:23 +02:00
```
### Methods
2024-04-10 18:48:21 +02:00
#### `get_groups(full=False)`
2024-11-17 19:50:05 +01:00
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.
2024-04-09 16:18:54 +02:00
2024-11-17 19:50:05 +01:00
You can traverse the course in both cases, although in different ways.
2024-04-09 16:18:54 +02:00
When you have fully traversed the course, you can access everything via indices and the `exercises` and `folders` attributes of the `ExerciseGroup` instances:
2024-04-06 16:16:23 +02:00
```python
2024-11-17 19:50:05 +01:00
ai_group = ai_course.get_groups(full=True)
exercise = ai_group[7].exercises[1] # Week 11 -> Suitcase packing
exercise.submit(["suitcase.py"], silent=False)
2024-04-09 16:18:54 +02:00
```
2024-11-17 19:50:05 +01:00
This is equivalent to the case in which we don't traverse the whole course using `get_group` like so:
2024-04-09 16:18:54 +02:00
```python
2024-04-10 18:48:21 +02:00
ai_group = ai_course.get_group("Week 11")
exercise = ai_group.get_group("Suitcase packing")
2024-11-17 19:50:05 +01:00
exercise.submit(["suitcase.py"], silent=False)
2024-04-09 16:18:54 +02:00
```
2024-11-17 19:50:05 +01:00
#### `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.
2024-04-09 16:18:54 +02:00
```python
2024-04-10 18:48:21 +02:00
week1 = pf.get_group("Week 1")
2024-04-06 16:16:23 +02:00
```
2024-11-17 19:50:05 +01:00
----
2024-04-06 16:16:23 +02:00
2024-11-17 19:50:05 +01:00
## `ExerciseGroup`
Setting the `full` flag to `True` will traverse the whole group.
2024-04-06 16:16:23 +02:00
2024-11-17 19:50:05 +01:00
- 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.
2024-04-06 16:16:23 +02:00
### 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
2024-04-10 18:48:21 +02:00
pf = year.get_course("Programming Fundamentals (for CS)")
assignments = pf.get_groups()
2024-11-17 19:50:05 +01:00
week1 = assignments[0] # Week 1
exercise2 = week1.folders[1] # Exercise 2
part2 = exercise2.exercises[1] # Part 2
2024-04-09 16:18:54 +02:00
2024-11-17 19:50:05 +01:00
# Or, if you don't want to traverse the whole course:
2024-04-10 18:48:21 +02:00
week1 = pf.get_group("Week 1")
exercise2 = week1.get_group("Exercise 2")
part2 = exercise2.get_group("Part 2")
2024-04-06 16:16:23 +02:00
```
### Methods
2024-04-10 18:48:21 +02:00
#### `download_files(path=".")`
2024-04-06 16:16:23 +02:00
Downloads all files in the exercise group to a directory `path` . Defaults to the current directory.
```python
2024-11-17 19:50:05 +01:00
assignment.download_files()
2024-04-06 16:16:23 +02:00
```
2024-04-10 18:48:21 +02:00
#### `download_tcs(path=".")`
2024-04-06 16:16:23 +02:00
Downloads all test cases in the exercise group to a directory `path` . Defaults to the current directory.
```python
2024-11-17 19:50:05 +01:00
assignment.download_tcs()
2024-04-06 16:16:23 +02:00
```
2024-11-17 19:50:05 +01:00
#### `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.
2024-04-09 16:18:54 +02:00
```python
2024-11-17 19:50:05 +01:00
# Week 1 -> Exercise 2 -> Part 2
week1 = pf.get_group("Week 1")
exercise2 = week1.get_group("Exercise 2")
part2 = exercise2.get_group("Part 2")
2024-04-09 16:18:54 +02:00
2024-11-17 19:50:05 +01:00
# This is equivalent to (but faster than):
week1 = pf.get_groups(full=True)[0]
exercise2 = week1.folders[1]
part2 = exercise2.exercises[1]
```
2024-04-09 16:18:54 +02:00
2024-11-17 19:50:05 +01:00
#### `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.
2024-04-06 16:16:23 +02:00
```python
2024-11-17 19:50:05 +01:00
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: ✅
# ...
2024-04-06 16:16:23 +02:00
```
2024-04-08 22:28:01 +02:00
2024-11-17 19:50:05 +01:00
#### `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.
2024-04-20 21:35:09 +02:00
```python
2024-11-17 19:50:05 +01:00
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'
}
```
2024-04-20 21:35:09 +02:00
2024-11-17 19:50:05 +01:00
To access submission details:
2024-04-20 21:35:09 +02:00
2024-11-17 19:50:05 +01:00
```python
leading_submission = status["leading"]
print(leading_submission.get_files())
2024-04-20 21:35:09 +02:00
```
2024-11-17 19:50:05 +01:00
----
2024-04-20 21:35:09 +02:00
## `Submission`
### Usage
```python
2024-11-17 19:50:05 +01:00
submission = pf.get_group("Week 1").get_group("Exercise 1").get_group("Part 1").get_status()["leading"]
2024-04-20 21:35:09 +02:00
```
### Methods
2024-11-17 19:50:05 +01:00
#### `get_test_cases()`
Returns a dictionary of test cases and their statuses.
2024-04-20 21:35:09 +02:00
```python
2024-11-17 19:50:05 +01:00
test_cases = submission.get_test_cases()
print(test_cases)
2024-04-21 00:29:49 +02:00
2024-11-17 19:50:05 +01:00
# Output:
{'1': 'passed', '2': 'passed', '3': 'passed', '4': 'passed', '5': 'passed', '6': 'passed', '7': 'passed', '8': 'passed', '9': 'passed', '10': 'passed'}
2024-04-20 21:35:09 +02:00
```
2024-11-17 19:50:05 +01:00
#### `get_info()`
2024-04-20 21:35:09 +02:00
Returns a dictionary of information about the submission.
```python
2024-11-17 19:50:05 +01:00
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'
}
2024-04-20 21:35:09 +02:00
```
2024-11-17 19:50:05 +01:00
#### `get_files()`
Returns a list of uploaded files in the format `(name, URL)` .
2024-04-20 21:35:09 +02:00
```python
2024-11-17 19:50:05 +01:00
files = submission.get_files()
print(files)
# Output:
[
('recurrence.c', '/file/.../recurrence.c'),
('compile.log', '/file/.../compile.log')
]
2024-04-20 21:35:09 +02:00
```
2024-04-09 16:18:54 +02:00
2024-11-17 19:50:05 +01:00
----