Skip to content
Snippets Groups Projects
Commit 4e6259c8 authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Updated all remaining steps to conform to new design

parent 1c4457ee
Branches main
No related tags found
No related merge requests found
import random
import subprocess
# from math import ceil, log10
from math import ceil, log10
from typing import Tuple
from api.canvas_classes import *
......@@ -24,6 +24,7 @@ def get_students() -> Set[CompositeUser]:
# TODO: assign_partners for arbitrarily-sized teams
# TODO: break this up into bite-sized chunks
def create_pairs(students: Set[CompositeUser], groupset_name: str = 'Unknown Assignment') -> \
List[Tuple[int, CompositeUser, CompositeUser, Optional[CompositeUser]]]:
students_with_blacklist: Set[CompositeUser] = sorted(list(filter(lambda s: s.has_blacklist(), students)),
......@@ -35,12 +36,31 @@ def create_pairs(students: Set[CompositeUser], groupset_name: str = 'Unknown Ass
if groupset_name in fields:
preassigned_students = set(filter(lambda s: len(s.graylist[groupset_name]) > 0, students))
unassigned_students: Set[CompositeUser] = set(students)
# handle student excusals
excused_students = set(filter(lambda s: s.graylist[groupset_name] == set('X'), preassigned_students))
# noinspection PyUnusedLocal
confirmation: str
# noinspection PyUnusedLocal
student: CompositeUser
for student in excused_students:
confirmation = input(f'\tExclude {student.readable_name} from student pairing ([Yes]/No/Abort)? ')
if confirmation == "" or confirmation.upper()[0] == 'Y':
print(f'Removing {student.readable_name} from pre-assigned students and from unassigned students.')
preassigned_students.remove(student)
unassigned_students.remove(student)
student.graylist[groupset_name] = set()
elif confirmation.upper()[0] == 'N':
print(f'Removing {student.readable_name} from pre-assigned students but leaving in unassigned students.')
preassigned_students.remove(student)
student.graylist[groupset_name] = set()
else:
print('Aborting.')
exit(0)
# handle truly-preassigned students
pair_number: int = 0
student_pairs: List[Tuple[int, CompositeUser, CompositeUser, Optional[CompositeUser]]] = []
# noinspection PyUnusedLocal
potential_pair: List[CompositeUser]
# noinspection PyUnusedLocal
confirmation: str
if preassigned_students:
print('First we shall confirm pre-assigned partners.')
else:
......@@ -52,7 +72,7 @@ def create_pairs(students: Set[CompositeUser], groupset_name: str = 'Unknown Ass
potential_pair = []
pair_number += 1
print(f'Preparing pair {pair_number}...')
student: CompositeUser = preassigned_students.pop()
student = preassigned_students.pop()
potential_pair.append(pair_number)
potential_pair.append(student)
potential_partners: Set[str] = student.graylist[groupset_name]
......@@ -120,9 +140,10 @@ def create_pairs(students: Set[CompositeUser], groupset_name: str = 'Unknown Ass
print('Very finally, we shall now assign the odd student to an existing partnership.')
match_found = False
while not match_found:
pair_number -= 1
potential_partners: Tuple[int, CompositeUser, CompositeUser, Optional[CompositeUser]] = \
student_pairs[--pair_number]
if potential_partners[2] is None and \
student_pairs[pair_number]
if potential_partners[3] is None and \
odd_student.is_graylist_compatible(potential_partners[1]) and \
odd_student.is_graylist_compatible(potential_partners[2]) and \
odd_student.is_blacklist_compatible(potential_partners[1]) and \
......@@ -134,6 +155,7 @@ def create_pairs(students: Set[CompositeUser], groupset_name: str = 'Unknown Ass
f'{potential_partners[1].readable_name} and {potential_partners[2].readable_name}')
else:
print('There is no odd student to add to an existing partnership.')
# update graylists
for pair in student_pairs:
usernames = set(map(lambda s: s.canvas_username if isinstance(s, CompositeUser) else None, pair)) - {None}
for student in pair[1:]:
......@@ -142,83 +164,81 @@ def create_pairs(students: Set[CompositeUser], groupset_name: str = 'Unknown Ass
return student_pairs
def save_student_roster(students: Set[CompositeUser]):
def save_student_roster(students: Set[CompositeUser]) -> None:
filename = input('Please provide the name of the new student roster file: ')
print(f'Writing {filename}.')
CompositeUser.write_student_csv(students, filename)
def create_contact_list(assignment_number, student_pairs):
filename = f'{assignment_number}-pairs.md'
def create_contact_list(groupset_name: str,
student_pairs: List[Tuple[int, CompositeUser, CompositeUser, Optional[CompositeUser]]]) -> None:
filename = f'{groupset_name}-partners.md'
print(f'Writing {filename}.')
zero_padding: int = ceil(log10(len(partners)))
with open(filename, mode='w') as pair_file:
pair_file.write(f'# PARTNERS FOR ASSIGNMENT {assignment_number}\n\n')
pair_file.write(f'# PARTNERS FOR ASSIGNMENT {groupset_name}\n\n')
for pair in student_pairs:
pair_file.write(f'- {assignment_number}pair {pair[0]}\n')
pair_file.write(f'- {groupset_name} {str(pair[0]).zfill(zero_padding)}\n')
pair_file.write(f' - {pair[1]}\n')
pair_file.write(f' - {pair[2]}\n')
if pair[3] is not None:
pair_file.write(f' - {pair[3]}\n')
def create_repositories(assignment_number, student_pairs, verbose):
if verbose:
print('Creating file for clone script.')
filename = f'{assignment_number}-clone.sh'
def create_repositories(groupset_name: str,
student_pairs: List[Tuple[int, CompositeUser, CompositeUser, Optional[CompositeUser]]]) -> None:
filename = f'{groupset_name}-clone.sh'
print(f'Creating file for clone script: {filename}. Creating repositories on Gitlab.')
zero_padding: int = ceil(log10(len(partners)))
with open(filename, mode='w') as clone_file:
clone_file.write('#!/bin/bash\n\n')
clone_file.write('# Auto-generated clone script.\n')
for pair in student_pairs:
if verbose:
print(f'Creating repo for pair number {pair[0]}')
print(f'\tCreating repo for pair number {str(pair[0]).zfill(zero_padding)}')
project = GitlabProject.create_project_in_group(Course.gitlab_namespace,
f'{assignment_number}pair{pair[0]}')
if verbose:
print(f'\tAdding {pair[1]}')
f'{groupset_name}{str(pair[0]).zfill(zero_padding)}')
print(f'\t\tAdding {pair[1]}')
project.add_user_as_maintainer(pair[1].get_gitlab_user())
if verbose:
print(f'\tAdding {pair[2]}')
print(f'\t\tAdding {pair[2]}')
project.add_user_as_maintainer(pair[2].get_gitlab_user())
if pair[3] is not None:
if verbose:
print(f'\tAdding {pair[3]}')
print(f'\t\tAdding {pair[3]}')
project.add_user_as_maintainer(pair[3].get_gitlab_user())
repo_url = project.get_cloning_url()
clone_file.write(f'git clone {repo_url}\n')
subprocess.call(['chmod', '+x', filename])
print('Repositories created')
def create_groups(assignment_number, student_pairs):
def create_groups(groupset_name: str,
student_pairs: List[Tuple[int, CompositeUser, CompositeUser, Optional[CompositeUser]]]) -> None:
print(f'Creating groupset {groupset_name} and student groups on Canvas.')
course = CanvasCourse(Course.canvas_course_id)
group_set = course.create_user_groupset(f'{assignment_number}pairs')
group_set = course.create_user_groupset(groupset_name)
zero_padding: int = ceil(log10(len(partners)))
for pair in student_pairs:
group = group_set.create_group(f'{assignment_number}pair {pair[0]}')
group = group_set.create_group(f'\t{groupset_name} {str(pair[0]).zfill(zero_padding)}')
group.add_student(pair[1].get_canvas_user())
group.add_student(pair[2].get_canvas_user())
if pair[3] is not None:
group.add_student(pair[3].get_canvas_user())
print('Canvas groups created')
if __name__ == '__main__':
groupset: str = input('Please provide the name of the student groupset: ')
student_set: Set[CompositeUser] = get_students()
# TODO: check for changes to course roster
# TODO: check for changes to gitlab usernames
partners: List[Tuple[int, CompositeUser, CompositeUser, Optional[CompositeUser]]] = create_pairs(student_set,
groupset)
print()
save_student_roster(student_set)
# zero_padding = ceil(log10(len(partners)))
# for partner in partners:
# print(f'{groupset} {str(partner[0]).zfill(zero_padding)}: {partner[1]}\t{partner[2]}\t{partner[3]}')
"""
assignment = '28'
pairs = create_pairs('2019-08.csv')
save_pairs(assignment, pairs)
print('Pairs created')
create_repositories(assignment, pairs, True)
print('Repositories created')
create_groups(assignment, pairs)
print('Canvas groups created')
create_contact_list(groupset, partners)
print()
create_repositories(groupset, partners)
print()
create_groups(groupset, partners)
print()
print('TODO:\tAdd issues')
print('\tCommit starter code')
print('\tUpdate graylists (also, please update the code to update the graylists)')
"""
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment