diff --git a/scripts/validate_groups b/scripts/validate_groups index d2931ee..b10faf2 100755 --- a/scripts/validate_groups +++ b/scripts/validate_groups @@ -1,272 +1,268 @@ #!/usr/bin/env python3 import os import subprocess import mailer import argparse import getpass import random import Slides.class_helper as ch config = ch.get_class_config() parser = argparse.ArgumentParser( description='Validate groups for homeworks') parser.add_argument('-n', '--homework', type=str, help='specify the homework label', required=True) parser.add_argument('-t', '--target', type=str, help='Specify the name of a mail box' ' to send test messages,' 'default : guillaume.anciaux@epfl.ch', default=config['teachers'][0]) parser.add_argument('-u', '--username', type=str, help='Username to log to the SMTP server', default=None) args = parser.parse_args() students_list = config['students'] homework = config['homeworks'][args.homework] group_list = homework['groups'] +group_list.rename(columns={"Student #1 EPFL email": "email1", + "Student #2 EPFL email": "email2"}, + inplace=True) + +group_list.applymap(lambda x: x.strip() if isinstance(x, str) else x) target = args.target username = args.username password = None if username: print('login:', username) password = getpass.getpass() -students_registered_in_group = set() +# ############################################################### +# generate group keys +students_registered_in_group = list() -def make_group_keys(group): - email1 = group['Student #1 EPFL email'].strip() - email2 = group['Student #2 EPFL email'].strip() +def make_group_keys(group): - emails = set() - emails.add(email1) - emails.add(email2) + emails = [group.email1, group.email2] + emails.sort() if len(emails) < 2: raise RuntimeError( 'invalid group: ' + str(emails)) print(emails) - emails = list(emails) - emails.sort() key = '_'.join(emails) - students_registered_in_group.add(email1) - students_registered_in_group.add(email2) + students_registered_in_group.extend(emails) return key group_keys = group_list.apply(make_group_keys, axis=1) group_list['group_key'] = group_keys group_list.set_index('group_key', inplace=True) +students_registered_in_group = set(students_registered_in_group) # ############################################################### # prepare to clone try: os.mkdir('homeworks') except Exception: pass # ############################################################### def run_command(cmd, on_failure=None, on_success=None): process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output = process.communicate() output = [i.decode().strip() for i in output if i.decode().strip() != ''] output = '\n'.join(output) ret = process.returncode if ret != 0: print('Failed: group ' + key) print(cmd) print(output) if on_failure is not None: on_failure() else: if on_success is not None: on_success() return ret # ############################################################### # search for failing to clone groups groups_failing_to_clone = set() for key, group in group_list.iterrows(): dirname = os.path.join( 'homeworks', args.homework, key) if os.path.isdir(dirname): print('Success: group ' + key) continue cmd = group['Homeworks repository'] + ' ' + dirname ret = run_command(cmd, on_failure=lambda: groups_failing_to_clone.add(key), on_success=lambda: print('Success: group ' + key) ) if ret == 0: continue - email1 = group['Student #1 EPFL email'].strip() - email2 = group['Student #2 EPFL email'].strip() - - group_emails = [email1, email2] + group_emails = [group.email1, group.email2] repo = group[5] if username: mailer.mail( username=username, password=password, sender_email=target, subject='SP4E homeworks: error in cloning your project', copy_mail=config['teachers']+config['assistants'], message=f""" Dear Students, Apparently we cannot clone your repository: {repo} Please fix the permissions. Best regards, The teaching team. """, target_emails=group_emails ) # ############################################################### # search for unregistered students student_list = config["students"] students = set() for k, student in student_list.iterrows(): students.add(student['e-Mail'].strip()) illegally_registered_student = ( students_registered_in_group - students_registered_in_group.intersection(students)) ################################################################ # construct invalid groups invalid_groups = set() for key, group in group_list.iterrows(): - email1 = group['Student #1 EPFL email'].strip() - email2 = group['Student #2 EPFL email'].strip() - group_emails = set([email1, email2]) + group_emails = set([group.email1, group.email2]) - if (email1 in illegally_registered_student or - email2 in illegally_registered_student): + if (group.email1 in illegally_registered_student or + group.email2 in illegally_registered_student): students_registered_in_group -= group_emails invalid_groups.add(key) else: continue if username: mailer.mail( username=username, password=password, sender_email=target, subject=f'{config["class"]["acronym"]} homeworks: invalid group', message=""" Dear Students, Your group is composed with at least a student not officially registered for the class. Therefore I have to ask you to change the composition of the group. You have to understand that the grading of so many projects is a lot of work. Therefore we will do it only for the registered students. With my best regards, The teaching team. """, copy_mail=config['teachers']+config['assistants'], target_emails=group_emails ) unregistered_list = students - students_registered_in_group ################################################################ # send email to unregistered people unregistered_list = list(unregistered_list) -# print(unregistered_list) random.shuffle(unregistered_list) -# print(unregistered_list) if len(unregistered_list): - print('aa', unregistered_list) if len(unregistered_list) % 2 == 0: random_groups = [e for e in zip( unregistered_list[::2], unregistered_list[1::2])] else: random_groups = [e for e in zip( unregistered_list[:-1:2], unregistered_list[1:-1:2])] random_groups[-1] = random_groups[-1][0], random_groups[-1][1], unregistered_list[-1] random_groups = [" - {0}".format(", ".join(b)) for b in random_groups] - print('bb', random_groups) + + random_groups = '\n'.join(random_groups) + if username and len(unregistered_list) > 0: mailer.mail( username=username, password=password, sender_email=target, subject=f'{config["class"]["acronym"]} homeworks: not registered in a group', - message=""" + message=f""" Dear Students, Apparently you did not registered yet to any group. Several reasons might explain this. -If it happens that you need to find a pair, please find below the +If it happens that you need to find a pair, please find below the automatically created groups. -{0} +{random_groups} If the situation does not suit you, please inform us as quickly as possible. -You still have to create a repository to store your homework. Please -inform us of your repository URI, for instance by filling the -[form](https://docs.google.com/forms/d/e/1FAIpQLSfymokpXgx4rhYY8msKLKXpY2sAbcv5n6cBiv1Ngx3Lu0Ob1A/viewform?vc=0&c=0&w=1&flr=0&usp=mail_form_link) +You still have to create a repository to store your homework. +Please inform us of your repository URI, for instance by filling the +[form]({homework["group_form"]}) With my best regards, The teaching team. -""".format('\n'.join(random_groups)), +""", copy_mail=config['teachers']+config['assistants'], target_emails=unregistered_list, markdown=True ) ################################################################ # output info print('total students:', len(students)) print('registered students:', len(students_registered_in_group)) print('unregistered students:', len(unregistered_list)) print('illegally registered students:', len(illegally_registered_student)) print('invalid groups:', len(invalid_groups))