Last active
March 24, 2025 21:42
-
-
Save benmarwick/c9179fdc13596a66598218ac301f09f3 to your computer and use it in GitHub Desktop.
Final grade calculations from a Canvas gradebook that uses an additive grading policy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Introduction | |
# This code will take grades on the Canvas gradebook, and add up the individual | |
# assignments to get a final grade, according to the policy for the class, in this | |
# case, here https://docs.google.com/spreadsheets/d/1-6f7mpgStojP4Gb3mk2PSwupGY2MiSrnIDD_KlxxEzk/edit?gid=874302185#gid=874302185 | |
## Get the Canvas gradebook | |
# Go to the Canvas course page, go to the gradebook for that | |
# course, click 'Actions' then 'Export'. That will download a CSV file to | |
# your computer. Move that file into the same folder as this R script file. | |
# Make sure that the assignment that we are updating is 'published' so | |
# we get the column in the exported gradebook | |
library(tidyverse) | |
# update the Canvas gradebook file name here (assuming we are starting in grading.Rproj) | |
canvas_gradebook <- "2025-03-24T1409_Grades-ARCHY_488_A.csv" | |
# check structure of the data | |
str(read_csv(canvas_gradebook)) | |
# sum up the assignments in each group, and assign to totals | |
canvas_gradebook_totals_update <- | |
read_csv(canvas_gradebook) %>% | |
filter(!is.na(`SIS Login ID`)) %>% | |
select(-contains(c("Current Points", | |
"Final Points", | |
"Current Score", | |
"Unposted Current Score", | |
"Final Score", | |
"Unposted Final Score"))) %>% | |
mutate(across(c(6:ncol(.) & where(is.character)), | |
parse_number)) %>% | |
dplyr::rowwise() %>% | |
# now do the additive grade calculations, create new columns to hold the | |
# totals, 1:10 for ten weeks | |
mutate(`Total Labs` = sum(c_across(contains(str_c("Week ", 1:10, ": "))), | |
na.rm = TRUE)) %>% | |
mutate(`Total Final Project` = sum(c_across(contains(str_c("Step ", 1:10, ": "))), | |
na.rm = TRUE)) %>% | |
# deal with the max allowed from each category, indicated here: | |
# https://docs.google.com/spreadsheets/d/1-6f7mpgStojP4Gb3mk2PSwupGY2MiSrnIDD_KlxxEzk/edit?gid=874302185#gid=874302185 | |
mutate(`Total Labs` = if_else(`Total Labs` > 3, | |
3, `Total Labs` )) %>% | |
mutate(`Total Final Project` = if_else(`Total Final Project` > 1, | |
1, `Total Final Project` )) %>% | |
select(Student, | |
ID, | |
`SIS User ID`, | |
`SIS Login ID`, | |
Section, | |
`Total Labs`, | |
`Total Final Project` | |
) | |
# take a look before we upload to Canvas, does it look ok? | |
view(canvas_gradebook_totals_update) | |
# See how their grade out of 4.0 is looking | |
canvas_gradebook_totals_update_out_of_four <- | |
canvas_gradebook_totals_update %>% | |
rowwise() %>% | |
mutate(total_out_of_4.0 = rowSums(across(starts_with("Total")), | |
na.rm = TRUE) ) %>% | |
mutate(total_out_of_4.0 = ifelse(total_out_of_4.0 > 4, | |
4, | |
total_out_of_4.0)) %>% | |
# round up, https://stackoverflow.com/a/12688836/1036500 | |
mutate(total_out_of_4.0_rounded = janitor::round_half_up(total_out_of_4.0, 1)) | |
# take a look | |
view(canvas_gradebook_totals_update_out_of_four) | |
canvas_gradebook_totals_update_out_of_four %>% | |
select(Student, total_out_of_4.0_rounded) %>% View | |
ggplot(canvas_gradebook_totals_update_out_of_four) + | |
aes(total_out_of_4.0_rounded) + | |
geom_histogram() + | |
ggtitle("ARCHY 488 SP23 Distribution of final grades") + | |
theme_minimal(base_size = 14) + | |
xlab("Final grade submitted to the registrar")+ | |
xlim(2, 4.1) | |
# ---- export to CSV, and import this file to Canvas gradebook | |
write_csv(canvas_gradebook_totals_update, | |
"update_totals_upload_to_canvas_gradebook.csv") | |
# ---- export to CSV, and import this file to UW GradePage | |
canvas_gradebook_totals_update_out_of_four %>% | |
select(`SIS User ID`, | |
ImportGrade = total_out_of_4.0_rounded) %>% | |
write_csv("update_totals_upload_to_gradepage.csv") | |
# Go to canvas an import, then come back here and continue... | |
# delete all the CSV files in this directory so we have a clean slate ready for next week | |
map(fs::dir_ls( glob = "*.csv"), fs::file_delete) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Introduction | |
# This code will take grades on the Canvas gradebook, and add up the individual | |
# assignments to get a final grade, according to the policy for the class, in this | |
# case, here https://docs.google.com/spreadsheets/d/1-6f7mpgStojP4Gb3mk2PSwupGY2MiSrnIDD_KlxxEzk/edit?gid=874302185#gid=874302185 | |
## Get the Canvas gradebook | |
# Go to the Canvas course page, go to the gradebook for that | |
# course, click 'Actions' then 'Export'. That will download a CSV file to | |
# your computer. Move that file into the same folder as this R script file. | |
# Make sure that the assignment that we are updating is 'published' so | |
# we get the column in the exported gradebook | |
library(tidyverse) | |
# update the Canvas gradebook file name here (assuming we are starting in grading.Rproj) | |
canvas_gradebook <- "2025-03-24T0948_Grades-ARCHY_483_A.csv" | |
# check structure of the data | |
str(read_csv(canvas_gradebook)) | |
# sum up the assignments in each group, and assign to totals | |
canvas_gradebook_totals_update <- | |
read_csv(canvas_gradebook) %>% | |
filter(!is.na(`SIS Login ID`)) %>% | |
select(-contains(c("Current Points", | |
"Final Points", | |
"Current Score", | |
"Unposted Current Score", | |
"Final Score", | |
"Unposted Final Score"))) %>% | |
mutate(across(c(6:ncol(.) & where(is.character)), | |
parse_number)) %>% | |
dplyr::rowwise() %>% | |
# now do the additive grade calculations, create new columns to hold the | |
# totals, 1:10 for ten weeks | |
mutate(`Total Seminar notes` = sum(c_across(contains(str_c("Seminar ", 1:10, ": "))), | |
na.rm = TRUE)) %>% | |
mutate(`Total Participation` = sum(c_across(contains(str_c("Lecture ", 1:10, " participation "))), | |
na.rm = TRUE)) %>% | |
mutate(`Total Quizzes` = sum(c_across(contains(c(str_c("Lecture ", 1:10, " quiz "), | |
"Syllabus Quiz"))), | |
na.rm = TRUE))%>% | |
mutate(`Total Final paper` = round(sum(c_across(starts_with("Final paper step")), | |
na.rm = TRUE), 1) ) %>% | |
# deal with the max allowed from each category, indicated here: | |
# https://docs.google.com/spreadsheets/d/1-6f7mpgStojP4Gb3mk2PSwupGY2MiSrnIDD_KlxxEzk/edit?gid=874302185#gid=874302185 | |
# max is 1 for all assignment categories, so we count 1 as the max towards the final grade | |
mutate(`Total Seminar notes` = if_else(`Total Seminar notes` > 1, | |
1, `Total Seminar notes` )) %>% | |
mutate(`Total Participation` = if_else(`Total Participation` > 1, | |
1, `Total Participation` )) %>% | |
mutate(`Total Quizzes` = if_else(`Total Quizzes` > 1, | |
1, `Total Quizzes` )) %>% | |
mutate(`Total Final paper` = if_else(`Total Final paper` > 1, | |
1, `Total Final paper` )) %>% | |
select(Student, | |
ID, | |
`SIS User ID`, | |
`SIS Login ID`, | |
Section, | |
`Total Seminar notes`, | |
`Total Participation`, | |
`Total Quizzes`, | |
`Total Final paper` | |
) | |
# take a look before we upload to Canvas, does it look ok? | |
view(canvas_gradebook_totals_update) | |
# See how their grade out of 4.0 is looking | |
canvas_gradebook_totals_update_out_of_four <- | |
canvas_gradebook_totals_update %>% | |
rowwise() %>% | |
mutate(total_out_of_4.0 = rowSums(across(starts_with("Total")), | |
na.rm = TRUE) ) %>% | |
mutate(total_out_of_4.0 = ifelse(total_out_of_4.0 > 4, | |
4, | |
total_out_of_4.0)) %>% | |
# round up, https://stackoverflow.com/a/12688836/1036500 | |
mutate(total_out_of_4.0_rounded = janitor::round_half_up(total_out_of_4.0, 1)) | |
# take a look | |
view(canvas_gradebook_totals_update_out_of_four) | |
canvas_gradebook_totals_update_out_of_four %>% | |
select(Student, total_out_of_4.0_rounded) %>% View | |
ggplot(canvas_gradebook_totals_update_out_of_four) + | |
aes(total_out_of_4.0_rounded) + | |
geom_histogram() + | |
ggtitle("ARCHY 483 SP23 Distribution of final grades") + | |
theme_minimal(base_size = 14) + | |
xlab("Final grade submitted to the registrar")+ | |
xlim(2, 4.1) | |
# ---- export to CSV, and import this file to Canvas gradebook | |
write_csv(canvas_gradebook_totals_update, | |
"update_totals_upload_to_canvas_gradebook.csv") | |
# ---- export to CSV, and import this file to UW GradePage | |
canvas_gradebook_totals_update_out_of_four %>% | |
select(`SIS User ID`, | |
ImportGrade = total_out_of_4.0_rounded) %>% | |
write_csv("update_totals_upload_to_gradepage.csv") | |
# Go to canvas an import, then come back here and continue... | |
# delete all the CSV files in this directory so we have a clean slate ready for next week | |
map(fs::dir_ls( glob = "*.csv"), fs::file_delete) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment