Last active
November 5, 2019 23:34
-
-
Save kellylougheed/5646b721fd6f682413c150372c54e678 to your computer and use it in GitHub Desktop.
Process CSV files of course requests to produce rosters
This file contains 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
import csv, operator, random | |
# Set enrollment limits per day | |
# Course-specific limits should be set inside the functions make_roster_tues and make_roster_thurs | |
TUES_LIMIT = 13 | |
THURS_LIMIT = 12 | |
''' | |
When generating rosters, manually double-check: | |
* Enrollment for PAWS, Math Cafe, Digital Literacy | |
* That Study Buddies participants have an endorsement | |
* That X-Block leaders are in the X-Block they're leading | |
* That Science Fair participants have a free on Thurs | |
* LEFTOVER STUDENTS -- Manually place if few, adjust limits if a lot | |
Files needed: | |
* signups-tues.csv | |
* signups-thurs.csv | |
(These files are identical and are used for tracking Tues and Thurs enrollment.) | |
* rosters-tues.csv | |
* rosters-thurs.csv | |
(Initially empty, to hold all the rosters.) | |
''' | |
''' | |
PART ONE: INVITATION ONLY & OTHER SPECIAL WORKSHOPS | |
''' | |
''' | |
These functions take in a workshop name and create a roster for that workshop. No functionality for limiting number of students in each X-Block. | |
Special cases are: Science Fair, PAWS, 6th Grade Math Cafe, 7th Grade Math Cafe, Digital Literacy, MS Play | |
STOP: Check if enrollment is low enough to include: So You Want To Lead an X-Block, Study Buddies | |
''' | |
def handle_special_case_tues(workshop): | |
remaining_students = [] | |
with open('signups-tues.csv', mode='r') as signups_file, open('rosters-tues.csv', mode='a') as rosters_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
rosters = csv.writer(rosters_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) | |
rosters.writerow([workshop]) | |
for row in signups: | |
if workshop in row[5]: | |
rosters.writerow(row) | |
else: | |
remaining_students.append(row) | |
signups_file.close() | |
rosters_file.close() | |
# Delete students now on roster from sign-ups | |
update_roster_tues(remaining_students) | |
# Give Science Fair students a free period on Thursday | |
if workshop == "Science Fair": | |
with open('signups-thurs.csv', mode='w') as signups_file: | |
signups = csv.writer(signups_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) | |
signups.writerows(remaining_students) | |
signups_file.close() | |
def handle_special_case_thurs(workshop): | |
remaining_students = [] | |
with open('signups-thurs.csv', mode='r+') as signups_file, open('rosters-thurs.csv', mode='a') as rosters_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
rosters = csv.writer(rosters_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) | |
rosters.writerow([workshop]) | |
for row in signups: | |
if workshop in row[6]: | |
rosters.writerow(row) | |
else: | |
remaining_students.append(row) | |
signups_file.close() | |
rosters_file.close() | |
# Delete students now on roster from sign-ups | |
update_roster_thurs(remaining_students) | |
def update_roster_tues(remaining_students): | |
with open('signups-tues.csv', mode='w') as signups_file: | |
signups = csv.writer(signups_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) | |
signups.writerows(remaining_students) | |
signups_file.close() | |
def update_roster_thurs(remaining_students): | |
with open('signups-thurs.csv', mode='w') as signups_file: | |
signups = csv.writer(signups_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) | |
signups.writerows(remaining_students) | |
signups_file.close() | |
''' | |
PART TWO: REGULAR WORKSHOPS | |
''' | |
# CHANGE EACH SERIES: keywords for regular workshops | |
workshops_tues = ["Wing", "Change", "Digital Crafts", "Dimension", "Robots", "Write", "Rotten", "Journal"] | |
workshops_thurs = ["Lead", "Baking", "Choreography", "Climate", "ProCRAFTination", "Spot", "Pup", "Gaming", "Knitting", "Seasonal", "Album", "Bullet", "Math"] | |
# Returns number of requests for a workshop on Tues | |
def count_requests_tues(workshop): | |
with open('signups-tues.csv', mode='r') as signups_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
requests = 0 | |
for row in signups: | |
if workshop in row[5]: | |
requests += 1 | |
signups_file.close() | |
return requests | |
# Returns number of requests for a workshop on Thurs | |
def count_requests_thurs(workshop): | |
with open('signups-thurs.csv', mode='r') as signups_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
requests = 0 | |
for row in signups: | |
if workshop in row[6]: | |
requests += 1 | |
signups_file.close() | |
return requests | |
# Arguments: list of workshops, string "T" for Tuesday or "TR" for Thursday | |
def get_counts(workshops, day): | |
counts = {} | |
for workshop in workshops: | |
if day == "T": | |
counts[workshop] = count_requests_tues(workshop) | |
elif day == "TR": | |
counts[workshop] = count_requests_thurs(workshop) | |
return counts | |
# Create dictionaries of counts | |
tues_counts = get_counts(workshops_tues, "T") | |
thurs_counts = get_counts(workshops_thurs, "TR") | |
# Convert dictionaries into list of ordered tuples | |
sorted_tues = sorted(tues_counts.items(), key=operator.itemgetter(1)) | |
sorted_thurs = sorted(thurs_counts.items(), key=operator.itemgetter(1)) | |
def make_roster_tues(workshop): | |
students_enrolled = [] | |
remaining_students = [] | |
with open('signups-tues.csv', mode='r+') as signups_file, open('rosters-tues.csv', mode='a') as rosters_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
rosters = csv.writer(rosters_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) | |
# Write workshop title | |
rosters.writerow([workshop]) | |
# Set limit | |
limit = TUES_LIMIT | |
if workshop == "Digital Crafts": | |
limit = 10 | |
if workshop == "Dimension": | |
limit = 12 | |
# Loop through to check for students who didn't request other workshops | |
for row in signups: | |
enroll = False | |
if workshop in row[5]: | |
enroll = True | |
for pair in sorted_tues: | |
if pair[0] in row[5]: | |
enroll = False | |
break | |
if enroll and len(students_enrolled) < limit: | |
rosters.writerow(row) | |
students_enrolled.append(row) | |
signups_file.close() | |
rosters_file.close() | |
# If still room, let students in randomly | |
for i in range(2): | |
with open('signups-tues.csv', mode='r+') as signups_file, open('rosters-tues.csv', mode='a') as rosters_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
rosters = csv.writer(rosters_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) | |
for row in signups: | |
if row not in students_enrolled and workshop in row[5]: | |
rand = random.randint(0, 1) | |
if rand == 0 and len(students_enrolled) < limit: | |
rosters.writerow(row) | |
students_enrolled.append(row) | |
signups_file.close() | |
rosters_file.close() | |
with open('signups-tues.csv', mode='r+') as signups_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
# Make list of remaining students to update sign-ups | |
for row in signups: | |
if row not in students_enrolled: | |
remaining_students.append(row) | |
signups_file.close() | |
# Delete students now on roster from sign-ups | |
update_roster_tues(remaining_students) | |
def make_roster_thurs(workshop): | |
students_enrolled = [] | |
remaining_students = [] | |
with open('signups-thurs.csv', mode='r+') as signups_file, open('rosters-thurs.csv', mode='a') as rosters_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
rosters = csv.writer(rosters_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) | |
# Write workshop title | |
rosters.writerow([workshop]) | |
# Set limit | |
limit = THURS_LIMIT | |
if workshop == "Climate": | |
limit = 8 | |
# Loop through to check for students who didn't request other workshops | |
# Thursday: Also check for X-Block leaders | |
for row in signups: | |
enroll = False | |
if workshop in row[6]: | |
enroll = True | |
for pair in sorted_tues: | |
if pair[0] in row[6]: | |
enroll = False | |
break | |
# Fast-track leaders to enrollment in their own X-Block | |
# Student-Led: "Baking", "Choreography", "Climate", "ProCRAFTination", "Spot", "Pup", "Gaming" | |
leader = False | |
if workshop == "Choreography" and "curry" in row[1]: | |
leader = True | |
elif workshop == "Baking" and ("wachler" in row[1] or "lundberg" in row[1] or "chu" in row[1]): | |
leader = True | |
elif workshop == "Climate" and "stephen" in row[1]: | |
leader = True | |
elif workshop == "ProCRAFTination" and ("morris" in row[1] or "keston" in row[1]): | |
leader = True | |
elif workshop == "Spot" and ("alvarez" in row[1] or "ritchie" in row[1]): | |
leader = True | |
elif workshop == "Pup" and ("entin" in row[1] or "frank" in row[1]): | |
leader = True | |
elif workshop == "Gaming" and ("arsan" in row[1] or "lazarus" in row[1]): | |
leader = True | |
if leader: | |
rosters.writerow(row) | |
students_enrolled.append(row) | |
elif enroll and len(students_enrolled) < limit: | |
rosters.writerow(row) | |
students_enrolled.append(row) | |
signups_file.close() | |
rosters_file.close() | |
# If still room, let students in randomly | |
for i in range(2): | |
with open('signups-thurs.csv', mode='r+') as signups_file, open('rosters-thurs.csv', mode='a') as rosters_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
rosters = csv.writer(rosters_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) | |
for row in signups: | |
if row not in students_enrolled and workshop in row[6]: | |
rand = random.randint(0, 1) | |
if rand == 0 and len(students_enrolled) < limit: | |
rosters.writerow(row) | |
students_enrolled.append(row) | |
signups_file.close() | |
rosters_file.close() | |
with open('signups-thurs.csv', mode='r+') as signups_file: | |
signups = csv.reader(signups_file, delimiter=',') | |
# Make list of remaining students to update sign-ups | |
for row in signups: | |
if row not in students_enrolled: | |
remaining_students.append(row) | |
signups_file.close() | |
# Delete students now on roster from sign-ups | |
update_roster_thurs(remaining_students) | |
special_cases = { | |
"Tues": ["Science Fair", "Digital Literacy", "PAWS", "7th Grade Math Cafe", "6th Grade Math Cafe", "Study Buddies"], | |
"Thurs": ["PAWS", "Play", "Lead"] | |
} | |
''' | |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
ROSTERS GENERATED HERE: COMMENT OUT IF NEEDED | |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
''' | |
for workshop in special_cases["Tues"]: | |
handle_special_case_tues(workshop) | |
for workshop in special_cases["Thurs"]: | |
handle_special_case_thurs(workshop) | |
# STOP: Cross-reference generated rosters with the official ones. Manually make corrections. | |
''' | |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
ROSTERS GENERATED HERE: COMMENT OUT IF NEEDED | |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
''' | |
# Feed each workshop name into roster-making function | |
# As you go, delete workshop tuples to remove them from consideration | |
# TUESDAY | |
for i in range(len(sorted_tues)): | |
make_roster_tues(sorted_tues[i][0]) | |
sorted_tues[i] = ('XXDONEXX', 'XXDONEXX') | |
# THURSDAY | |
for i in range(len(sorted_thurs)): | |
make_roster_thurs(sorted_thurs[i][0]) | |
sorted_thurs[i] = ('XXDONEXX', 'XXDONEXX') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment