Records

Records used in flows can be any types; however, steps may often only work with a specific subset of types. It is therefore useful to define base classes, such that steps will work with any type that implements the base class.

Base Classes

class records.spreadsheet_record.SpreadsheetRecord

A specific record type that can be represented in a spreadsheet.

To achieve this, the object must be able to be expressed from and as a list of strings.

Child classes must accordingly identify the headers that should be used in a spreadsheet that contains them:

abstract property headers: list[str]

The headers to use for the given object.

These should be sufficient to represent all data in an object instance, and be of the same order as the data in the string representation.

Additionally, child classes must implement the following two methods to enable translation to and from a spreadsheet representation:

abstractmethod to_strings() list[str]

Represent itself as a list of strings.

The list should be the same length as its headers, with each element representing the data for the corresponding header.

Returns:

A representation of the instance as strings

Return type:

list[str]

abstractmethod classmethod from_strings(header_mapping: dict[str, str]) SpreadsheetRecord

Construct itself from a mapping of strings.

Parameters:

header_mapping (dict[str, str]) – A mapping of headers to the data under the header. Some headers may not be present, and the class must determine whether it can still be constructed.

Returns:

An instance of the class constructed

from the provided data

Return type:

SpreadsheetRecord

Implementations

Currently, the following two classes are used by the majority of implemented steps to achieve the necessary functionality:

class records.student_record.StudentRecord(first_name: str, last_name: str, netid: str, cuid: str, enrolled: bool = True, github_username: str | None = None, github_valid: bool | None = None, last_no_username_ping: datetime | None = None, last_valid_ping: datetime | None = None, sent_invite: bool = False, invite_date: datetime | None = None, github_accepted: bool | None = None, last_accepted_ping: datetime | None = None, personal_repo_name: str | None = None, added_to_personal: bool = False, last_group_ping: datetime | None = None, group_num: int | None = None, group_repo_name: str | None = None, added_to_group: bool = False)

Bases: SpreadsheetRecord

A record indicating a student’s status in the class.

This includes metadata about the student, as well as attributes reflecting whether specific activities have been completed.

- first_name

The student’s first name

Type:

str

- last_name

The student’s last name

Type:

str

- netid

The student’s NetID

Type:

str

- cuid

The student’s CUID

Type:

str

- enrolled

Whether the student is still enrolled or not

Type:

bool

- github_username

The student’s GitHub username, if known

Type:

Optional[str]

- github_valid

Whether their GitHub username is valid

Type:

Optional[bool]

- last_no_username_ping

When they were last pinged about not submitting a GitHub username

Type:

Optional[datetime.datetime]

- last_valid_ping

When they were last pinged about their invalid GitHub username, if at all

Type:

Optional[datetime.datetime]

- sent_invite

Whether they’ve been sent a GitHub invitation

Type:

bool

- invite_date

When they were sent a GitHub invitation

Type:

Optional[datetime.datetime]

- github_accepted

Whether they’ve accepted their GitHub invite

Type:

bool

- last_accepted_ping

When they were last pinged to accept the GitHub invite, if at all

Type:

Optional[datetime.datetime]

- personal_repo_name

The name of their personal GitHub repository

Type:

Optional[str]

- added_to_personal

Whether they’ve been added to their personal GitHub repository

Type:

bool

- group_num

The number of their lab group on Canvas

Type:

Optional[str]

- group_repo_name

The name of their lab group’s repo on GitHub

Type:

Optional[str]

- added_to_group

Whether they’ve been added to their lab group’s repo on GitHub

Type:

bool

headers = ['First Name', 'Last Name', 'NetID', 'CUID', 'Enrolled?', 'GithubUsername', 'ValidUsername?', 'LastUsernamePing', 'LastValidPing', 'SentInvite?', 'InviteDate', 'GithubAccepted?', 'LastAcceptedPing', 'PersonalRepoName', 'AddedToPersonal?', 'LastGroupPing', 'GroupNum', 'GroupRepoName', 'AddedToGroup?']
to_strings() list[str]

Represent the record as a list of strings.

This is used to store the record in a spreadsheet.

Returns:

The strings that represent the record

Return type:

list[str]

classmethod from_strings(header_mapping: dict[str, str]) StudentRecordChild

Form a StudentRecord from the data found under headers.

This is used to obtain a record from a spreadsheet entry.

Parameters:

header_mapping (dict[str, str]) – The mapping of headers to row data

Raises:

Exception – Raised if a mandatory header is missing

Returns:

The corresponding record with the desired data

Return type:

StudentRecord

class records.tag_record.TagRecords(repo_name: str, repo_type: Literal['personal', 'group'])

Bases: SpreadsheetRecord

A collection of TagRecords for a specific repository.

Using TagRecords

TagRecords are meant to be inherited from in order to use; this is to allow flexibility with how many submissions/labs they represent, while maintaining string typing. When creating a child class, users must:

  • Override the labs class attribute to represent all necessary labs to tag

  • Override the headers attribute to accurately reflect the new headers needed to represent the class in a spreadsheet

An example is provided below, where the resulting MyTagRecords represents tags for two lab submissions (using get_tag_headers() to get the headers for the particular set of labs):

class MyTagRecords(TagRecords):
    """A custom TagRecords class"""

    labs = [
        "lab1",
        "lab2"
    ]
    headers = get_tag_headers(labs)

Instances of the resulting class will have the attributes lab1 and lab2, each of which contain a TagRecord. If a lab is provided such that the name cannot be accessed as an object attribute using the dot syntax, users should use getattr and setattr appropriately to access the attributes.

to_strings() list[str]

Represent the record as a list of strings.

This is used to store the record in a spreadsheet.

Returns:

The string representation

Return type:

list[str]

classmethod from_strings(header_mapping: dict[str, str]) TagRecords

Form a TagRecords from the data found under headers.

This is used to obtain a record from a spreadsheet entry.

Parameters:

header_mapping (dict[str, str]) – The mapping of headers to row data

Raises:

Exception – Raised if a mandatory header is missing

Returns:

The corresponding record with the desired data

Return type:

TagRecords