def _gen_grades(): filedir = os.path.dirname(os.path.abspath(__file__)) if common.DEBUG: studentdir = './test/students' else: studentdir = '../../../students' studentdir = os.path.abspath(os.path.join(filedir, studentdir)) assignmentsfile = os.path.join(studentdir, 'assignments.gen.py') scandir = os.path.join(studentdir, 'scans') # ......................................................................... name2cwid = { v['github'].lower(): k for k, v in students.students.items() if 'github' in v } grades = { cwid: OrderedDict([ ('extra credit', 0), ('overall', None), ('predictions', OrderedDict()), ] + [(( g, s, ), OrderedDict()) for g, ss in standards.groups.items() for s in ss]) for cwid in students.students } # ......................................................................... # from github github = github3.GitHub() try: for r in sorted([r.name for r in github.iter_user_repos(common.org)]): if r in ('course-materials', ): continue assignment = 'a' + r[-2:] for cwid in students.students: grades[cwid][('assignment completion', '')][assignment] = None for pr in github.iter_repo_issues(common.org, r, state='all'): name = pr.user.login if name not in name2cwid: continue grades[name2cwid[name]] \ [('assignment completion', '')] \ [assignment] = True with open(assignmentsfile, 'w') as f: f.write( repr({ cwid: grades[cwid][('assignment completion', '')] for cwid in grades })) except (requests.exceptions.ConnectionError, github3.models.GitHubError): assignments = eval(open(assignmentsfile).read()) none = OrderedDict([(a, None) for a in assignments[list(assignments.keys())[0]]]) for cwid in grades: if cwid in assignments: grades[cwid][('assignment completion', '')] = assignments[cwid] else: grades[cwid][('assignment completion', '')] = none # ......................................................................... # from scans for d in sorted(os.listdir(scandir)): if d.startswith('.'): continue i = Namespace() (i.date, i.assessment, i.standards) = d.split(',', maxsplit=2) i.standards = [standards.lookup(s) for s in i.standards.split(',')] for cwid in students.students: for sta in i.standards: grades[cwid][sta][i.assessment] = None for f in os.listdir(os.path.join(scandir, d)): if f.startswith('.'): continue (i.name, i.scores) = \ f.split('.',maxsplit=1)[0].split(',', maxsplit=1) i.scores = i.scores.split(',') if '' in i.scores: raise Error('WARNING: empty score in' + ' "' + os.path.join(d, f) + '"') if len(i.scores) != len(i.standards): raise Error('WARNING: mismatch in number of scores for' + ' "' + os.path.join(d, f) + '"') i.scores = [ None if s == 'x' else 3.5 if s == '5' else 3.75 if s == '7' else int(s) for s in i.scores ] for sta, sco in zip(i.standards, i.scores): grades[students.lookup(i.name)][sta][i.assessment] = sco # ......................................................................... # from file private = common.importfile(os.path.join(studentdir, 'grades.py')) for cwid in private.grades: if cwid in grades: grades[cwid].update(private.grades[cwid]) else: grades[cwid] = private.grades[cwid] # ......................................................................... for cwid in grades: overall = 0 maximum = 0 for sta, assessments in grades[cwid].items(): if isinstance(sta, str): continue scos = [sco for sco in assessments.values() if sco is not None] if sta == ('assignment completion', ''): sco = len(scos) / len(assessments) if len( assessments) > 0 else 0 assessments['overall'] = sco overall += sco * standards.multipliers[sta] maximum += standards.multipliers[sta] continue if len(scos) == 0: assessments['overall'] = None else: if len(scos) == 1 or scos[-1] >= scos[-2]: sco = scos[-1] else: # scos[-1] < scos[-2] sco = [ sco for sco in [1, 2, 3, 3.5, 3.75, 4] if (scos[-1] + scos[-2]) / 2 <= sco ][0] assessments['overall'] = sco if sco >= 3: overall += sco / 4 * standards.multipliers[sta] maximum += standards.multipliers[sta] ec = grades[cwid]['extra credit'] * 0.002 if grades[cwid]['overall'] is None: grades[cwid]['overall'] = overall + ec grades[cwid]['predictions']['current grade'] = grades[cwid]['overall'] if maximum == 0: grades[cwid]['predictions']['average'] = None grades[cwid]['predictions']['maximum without reassessing'] = None else: grades[cwid]['predictions']['average'] = overall / maximum grades[cwid]['predictions']['maximum without reassessing'] = \ 1 - maximum + overall + ec # ......................................................................... return grades
def _gen_students(): filedir = os.path.dirname(os.path.abspath(__file__)) if common.DEBUG: studentdir = './test/students' else: studentdir = '../../../students' studentdir = os.path.abspath(os.path.join(filedir, studentdir)) titandir = os.path.join(studentdir, 'titan-online') # ......................................................................... # - for data copied and pasted from Titan Online into TextEdit, and saved # as HTML student = re.compile( r'<tr>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?>(?P<cwid>\d{9})<.*?</td>' + r'.*?<td.*?<a href="mailto:(?P<email>[^"]+)">(?P<name>[^<]+)<.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?</tr>*?', re.DOTALL, ) students = {} # ......................................................................... for entry in os.scandir(titandir): if entry.name.startswith('.') or not entry.is_file(): continue path = os.path.join(titandir, entry.name) for m in student.finditer(open(path).read()): section = entry.name.split('.')[0] cwid = m.group('cwid') email = m.group('email') name = ' '.join(reversed(m.group('name').split(',', maxsplit=1))) alias = name.split() if len(alias) == 1: alias = alias[0] elif alias[-1] in ( 'I', 'II', 'III', 'IV', ) and len(alias) > 2: alias = ' '.join([alias[0], alias[-2]]) else: alias = ' '.join([alias[0], alias[-1]]) students[cwid] = { 'section': section, 'email': email, 'name': name, 'alias': alias, } # ......................................................................... private = common.importfile(os.path.join(studentdir, 'students.py')) for cwid in private.students: if cwid in students: students[cwid].update(private.students[cwid]) else: students[cwid] = private.students[cwid] # ......................................................................... return students
# Project located at <https://github.com/benblazak/text-processing-utilities> # ----------------------------------------------------------------------------- """A script to print out some subset of student names and emails, in a format suitable for the `openEmail` function in `open-email.applescript`. """ import os.path import sys import common # ............................................................................. filedir = os.path.dirname(os.path.abspath(__file__)) students = common.importfile(os.path.join(filedir, '../students.py')) # ----------------------------------------------------------------------------- if len(sys.argv) == 1: arg = 'all' elif len(sys.argv) == 2: arg = sys.argv[1] else: print('ERROR: too many arguments') sys.exit(1) # ............................................................................. vs = students.students.values()
"""A script to print out some subset of student names and emails, in a format suitable for the `openEmail` function in `open-email.applescript`. """ import os import os.path import subprocess import sys import textwrap import time import common filedir = os.path.dirname(os.path.abspath(__file__)) students = common.importfile( os.path.join(filedir, '../students.py') ) # ----------------------------------------------------------------------------- if len(sys.argv) == 1: arg = 'all' elif len(sys.argv) == 2: arg = sys.argv[1] else: print('ERROR: too many arguments') sys.exit(1) # ............................................................................. cwids = []
def _gen_students(): filedir = os.path.dirname(os.path.abspath(__file__)) if common.DEBUG: studentdir = './test/students' else: studentdir = '../../../students' studentdir = os.path.abspath(os.path.join(filedir, studentdir)) titandir = os.path.join(studentdir, 'titan-online') # ......................................................................... # - for data copied and pasted from Titan Online into TextEdit, and saved # as HTML student = re.compile( r'<tr>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?>(?P<cwid>\d{9})<.*?</td>' + r'.*?<td.*?<a href="mailto:(?P<email>[^"]+)">(?P<name>[^<]+)<.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?<td.*?</td>' + r'.*?</tr>*?', re.DOTALL, ) students = {} # ......................................................................... for entry in os.scandir(titandir): if entry.name.startswith('.') or not entry.is_file(): continue path = os.path.join(titandir, entry.name) for m in student.finditer(open(path).read()): section = entry.name.split('.')[0] cwid = m.group('cwid') email = m.group('email') name = ' '.join(reversed( m.group('name').split(',', maxsplit=1) )) alias = name.split() if len(alias) == 1: alias = alias[0] elif alias[-1].lower() in ( 'i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'jr' ) and len(alias) > 2: alias = ' '.join([ alias[0], alias[-2] ]) else: alias = ' '.join([ alias[0], alias[-1] ]) students[cwid] = { 'section': section, 'email': email, 'name': name, 'alias': alias, } # ......................................................................... private = common.importfile(os.path.join(studentdir, 'students.py')) for cwid in private.students: if cwid in students: students[cwid].update(private.students[cwid]) else: students[cwid] = private.students[cwid] # ......................................................................... return students
def _gen_grades(): filedir = os.path.dirname(os.path.abspath(__file__)) if common.DEBUG: studentdir = './test/students' else: studentdir = '../../../students' studentdir = os.path.abspath(os.path.join(filedir, studentdir)) assignmentsfile = os.path.join(studentdir, 'assignments.gen.py') scandir = os.path.join(studentdir, 'scans') # ......................................................................... name2cwid = { v['github'].lower():k for k,v in students.students.items() if 'github' in v } grades = { cwid: OrderedDict( [ ('extra credit', 0), ('overall', None), ('predictions', OrderedDict()), ] + [ ((g,s,),OrderedDict()) for g,ss in standards.groups.items() for s in ss ] ) for cwid in students.students } # ......................................................................... # from github github = github3.GitHub() try: for r in sorted([ r.name for r in github.iter_user_repos(common.org) ]): if r in ( 'course-materials', ): continue assignment = 'a' + r[-2:] for cwid in students.students: grades[cwid][('assignment completion', '')][assignment] = None for pr in github.iter_repo_issues(common.org, r, state='all'): name = pr.user.login.lower() if name not in name2cwid: continue grades[name2cwid[name]] \ [('assignment completion', '')] \ [assignment] = True with open(assignmentsfile, 'w') as f: f.write(repr({ cwid: grades[cwid][('assignment completion', '')] for cwid in grades })) except (requests.exceptions.ConnectionError, github3.models.GitHubError): assignments = eval(open(assignmentsfile).read()) none = OrderedDict([ (a, None) for a in assignments[list(assignments.keys())[0]] ]) for cwid in grades: if cwid in assignments: grades[cwid][('assignment completion', '')] = assignments[cwid] else: grades[cwid][('assignment completion', '')] = none # ......................................................................... # from scans for d in sorted(os.listdir(scandir)): if d.startswith('.'): continue i = Namespace() (i.date, i.assessment, i.standards) = d.split(',', maxsplit=2) i.standards = [ standards.lookup(s) for s in i.standards.split(',') ] for cwid in students.students: for sta in i.standards: grades[cwid][sta][i.assessment] = None for f in os.listdir(os.path.join(scandir, d)): if f.startswith('.'): continue (i.name, i.scores) = \ f.split('.',maxsplit=1)[0].split(',', maxsplit=1) i.scores = i.scores.split(',') if '' in i.scores: raise Error( 'WARNING: empty score in' + ' "' + os.path.join(d, f) + '"' ) if len(i.scores) != len(i.standards): raise Error( 'WARNING: mismatch in number of scores for' + ' "' + os.path.join(d, f) + '"' ) i.scores = [ None if s == 'x' else 3.5 if s == '5' else 3.75 if s == '7' else int(s) for s in i.scores ] for sta,sco in zip(i.standards,i.scores): grades[students.lookup(i.name)][sta][i.assessment] = sco # ......................................................................... # from file private = common.importfile(os.path.join(studentdir, 'grades.py')) for cwid in private.grades: if cwid in grades: grades[cwid].update(private.grades[cwid]) else: grades[cwid] = private.grades[cwid] # ......................................................................... for cwid in grades: overall = 0 maximum = 0 for sta,assessments in grades[cwid].items(): if isinstance(sta, str): continue scos = [ sco for sco in assessments.values() if sco is not None ] if sta == ('assignment completion', ''): sco = len(scos)/len(assessments) if len(assessments) > 0 else 0 assessments['overall'] = sco overall += sco * standards.multipliers[sta] maximum += standards.multipliers[sta] continue if len(scos) == 0: assessments['overall'] = None else: if len(scos) == 1 or scos[-1] >= scos[-2]: sco = scos[-1] else: # scos[-1] < scos[-2] sco = [ sco for sco in [1, 2, 3, 3.5, 3.75, 4] if (scos[-1]+scos[-2])/2 <= sco ][0] assessments['overall'] = sco if sco >= 3: overall += sco / 4 * standards.multipliers[sta] maximum += standards.multipliers[sta] ec = grades[cwid]['extra credit'] * 0.002 if grades[cwid]['overall'] is None: grades[cwid]['overall'] = overall + ec grades[cwid]['predictions']['current grade'] = grades[cwid]['overall'] if maximum == 0: grades[cwid]['predictions']['average'] = None grades[cwid]['predictions']['maximum without reassessing'] = None else: grades[cwid]['predictions']['average'] = overall / maximum grades[cwid]['predictions']['maximum without reassessing'] = \ 1 - maximum + overall + ec # ......................................................................... return grades