Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add lecture participation tracker using GitHub Actions (#2459) #2463

Merged
merged 12 commits into from
Sep 12, 2024

Conversation

bjornthiberg
Copy link
Contributor

@bjornthiberg bjornthiberg commented Sep 11, 2024

Description

This PR introduces a script and a GitHub Actions workflow to track lecture participation.

The structure of the script and workflow YAML file is based on the existing workflow for updating the Statistics of Student Registrations. It has a similar structure, can be run locally in the same way, and uses the same dependencies.

How it's supposed to work:

GitHub actions workflow

  • The workflow is triggered on new issue comments, and proceeds if the issue title is “Lecture participation tracker 2024”.
  • track_participation.py is run

Python script (track_participation.py):

  • Fetches all comments to the issue from the GitHub API
  • If the author is a collaborator, or the comment is outside the commenting window (5 hours from the start of each lecture), the comment is ignored.
  • Valid comments are stored in a dictionary, with keys for each student who has commented.
  • The script generates a markdown table, similar to the one for tracking tasks, which displays the lectures each student has attended.
  • The issue description is updated with this markdown table and a timestamp.

I have tested that (in a copy of the repo):

  • the workflow triggers correctly when a new comment is added to the tracker.
  • comments made by collaborators are ignored as expected.
  • comments made outside of the allowed window are not counted.
  • valid comments update the participation tracker issue description.
  • timezones work as expected (don't quote me on this)

I have not tested for more than two unique students/commenters, as would be the case in "production".

Updating for newer years should only require changing the lecture dates and start hours in the JSON config and the issue number in the YAML file.

Closes #2459

Copy link
Collaborator

@algomaster99 algomaster99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Thank you so much for the wonderful PR ❤️ Please see the changes that I have suggested.

  1. What is the default option in your script? --printPlain, --printMarkdown, --publish? Running it without output any options simply exits the script after 3 seconds with code 0.
  2. Do you agree to support maintenance of this script until the end of the course? :) I ask this because there could be a high chance that I merge this PR and then action breaks so I would need your help to fix it :D

@monperrus @Deee92 @javierron @sofiabobadilla example:

+-------+---------------------+-----------------------------+---------------------+
| Index |     Student Name    | Number of Lectures Attended | Lecture(s) attended |
+-------+---------------------+-----------------------------+---------------------+
|   1   |       RafDevX       |              2              |        L2 L3        |
|   2   |       Glassar       |              1              |          L2         |
|   3   |    diogotcorreia    |              2              |        L2 L3        |
|   4   |   MateusMarinheiro  |              2              |        L2 L3        |
|   5   |     bjornthiberg    |              1              |          L2         |
|   6   |       t-sorger      |              2              |        L2 L3        |
|   7   |      jackma-00      |              2              |        L2 L3        |
|   8   |    randomicecube    |              2              |        L2 L3        |
|   9   |        dvavd        |              2              |        L2 L3        |
|   10  |       Tian0602      |              2              |        L2 L3        |
|   11  |      Atheer2104     |              2              |        L2 L3        |
|   12  |      arejula27      |              2              |        L2 L3        |
|   13  |       d-melita      |              2              |        L2 L3        |
|   14  |        M1l0d        |              2              |        L2 L3        |
|   15  | CoordinatesNotFound |              2              |        L2 L3        |
|   16  |    marcocampione    |              2              |        L2 L3        |
|   17  |     Stellariser     |              2              |        L2 L3        |
|   18  |        NoelMT       |              2              |        L2 L3        |
|   19  |     pablo-freire    |              1              |          L2         |
|   20  |  GustavHenningsson  |              1              |          L2         |
|   21  |     Pesteves2002    |              2              |        L2 L3        |
|   22  |     muhammad1928    |              2              |        L2 L3        |
|   23  |       Uqqasha       |              2              |        L2 L3        |
|   24  |       Flopalot      |              1              |          L2         |
|   25  |      bepp-boop      |              1              |          L3         |
|   26  |   Alexanderliu2002  |              1              |          L3         |
|   27  |     laullaurado     |              1              |          L3         |
|   28  |       Jakebobs      |              1              |          L3         |
|   29  |     einbergisak     |              1              |          L3         |
|   30  |      Samkth123      |              1              |          L3         |
|   31  |        kthfre       |              1              |          L3         |
|   32  |      peremateu      |              1              |          L3         |
|   33  |        HexuL        |              1              |          L3         |
+-------+---------------------+-----------------------------+---------------------+

.github/workflows/lecture_participation.yml Outdated Show resolved Hide resolved
.github/workflows/lecture_participation.yml Outdated Show resolved Hide resolved
.github/workflows/lecture_participation.yml Outdated Show resolved Hide resolved
.github/workflows/lecture_participation.yml Outdated Show resolved Hide resolved
.github/workflows/lecture_participation.yml Outdated Show resolved Hide resolved
tools/track_participation.py Outdated Show resolved Hide resolved
tools/track_participation.py Outdated Show resolved Hide resolved
@bjornthiberg
Copy link
Contributor Author

Hi @algomaster99, thanks for the feedback!

I just did a force push to get the PR in line with the task structure, by changing the description and adding a task readme file (did not change the python script or YAML file).

I also added a short documentation to the /tools/README.md file, didn't see that earlier.

  1. No default option, it just does the fetching but prints an empty string. Doesn't make a lot of sense, I'll make it print plain text as default and remove it as an option instead.
  2. Of course!

I'll get on your other comments asap.

@bjornthiberg
Copy link
Contributor Author

@algomaster99

I have addressed all your comments now I think! Let me know if I missed something or anything else needs to be adjusted :)

I have tested the code again, and the CI job on my test repo.

Copy link
Collaborator

@algomaster99 algomaster99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did a force push to get the PR in line with the task structure, by changing the description and adding a task readme file

Always create a PR from a different branch. You can avoid rebasing in this way.

Of course!

Thank you!

I think we are almost there! Just a few more changes.

contributions/open-source/bthiberg/README.md Outdated Show resolved Hide resolved
@@ -58,3 +58,32 @@ This script is used to grade each student according to the number of task comple

### Usage
...


## track_participation.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I almost forgot about suggesting this change, but I am happy you noticed! Could you please also add a heading about the prerequisites that should be updated every year?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 71c9c9f

REPO_FULLNAME = os.getenv("REPO_FULLNAME")
ISSUE_NUMBER = os.getenv("TRACKER_ISSUE_NUMBER")

config = json.load(open("tools/track_participation_config.json"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
config = json.load(open("tools/track_participation_config.json"))
config = json.load(open("track_participation_config.json"))

I think this should be sufficient?

Copy link
Contributor Author

@bjornthiberg bjornthiberg Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will work when running locally from the tools folder, but the workflow will not find the file as it runs Python in the repo's root dir.

See this failed run in the test repo.

Could change that in the workflow file, but I thought this was cleaner.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could change that in the workflow file, but I thought this was cleaner.

I think otherwise because the this path is only true with respect to the CI job so it should be in workflow file only.

Comment on lines +2 to +3
# -*- coding: utf-8 -*-
# Filename: track_participation.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I ask what these headers are for? Is it required for some plugin that you use? I am curious.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just something I saw in the other python scripts in the repo. I believe the first line is for encoding, but is generally a remnant from python 2 as 3+ uses utf-8 by default. Second line is just for readability I suppose.

lecture_start_hour = LECTURE_DATES_TO_START_TIME[lecture_date_str]

allowed_period_start = comment_time.replace(hour=lecture_start_hour, minute=0, second=0, microsecond=0)
allowed_period_end = allowed_period_start + timedelta(hours=COMMENTING_DURATION_HOURS)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if I being too nitpicky here, but I would request you to have two variables here instead of one COMMENT_DURATION_HOURS. One which is the actual duration and the other which is the leeway. This would be my personal opinion in terms of code readability/understandability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed! addressed in ef44d53

@bjornthiberg
Copy link
Contributor Author

Always create a PR from a different branch. You can avoid rebasing in this way.

Damnit, didn't think about this since it's a fork. Could change now but probably more trouble than it is worth since rebasing will not be very complicated.

I think we are almost there! Just a few more changes.

On it!

@bjornthiberg
Copy link
Contributor Author

@algomaster99 I've addressed the requested changes. Let me know if there’s anything else needed or if you spot any issues! :)

I suppose my commits should be squashed and rebased onto the current 2024 branch. Lmk if I should do that and force push to this PR, to make merging easier.

Copy link
Collaborator

@algomaster99 algomaster99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final change and I will merge it once you resolve it :)

REPO_FULLNAME = os.getenv("REPO_FULLNAME")
ISSUE_NUMBER = os.getenv("TRACKER_ISSUE_NUMBER")

config = json.load(open("tools/track_participation_config.json"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could change that in the workflow file, but I thought this was cleaner.

I think otherwise because the this path is only true with respect to the CI job so it should be in workflow file only.

@algomaster99
Copy link
Collaborator

Thanks for the quick fix! Let's give it a run, shall we? I am looking forward to it.

@bjornthiberg
Copy link
Contributor Author

bjornthiberg commented Sep 12, 2024

I squeezed in another quick fix! The timestamp ended up being incorrect with the timezone change, should be fixed now in 5c90115

@algomaster99
Copy link
Collaborator

The timestamp ended up being incorrect with the timezone change, should be fixed now in 5c90115

Awesome! I did not notice it. Thanks!

@algomaster99
Copy link
Collaborator

Are we ready to merge? 😄

@algomaster99
Copy link
Collaborator

Merging! Let's hope nothing breaks :D

@algomaster99 algomaster99 merged commit 7ca38a7 into KTH:2024 Sep 12, 2024
1 check passed
@algomaster99
Copy link
Collaborator

Great work! One cool thing I immediately realised was that the table could be sorted by the number of lectures attended. Could you also propose a PR for that? I hope it is not too much effort.

@bjornthiberg
Copy link
Contributor Author

Should be easy! Will do next week

@algomaster99
Copy link
Collaborator

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CI job for live counting active participation
2 participants