def py_students(source='tasks.txt'): results = [] for name, info in py_tasks(source).items(): for tid in ['1', '2', '3', 'projektukas', 'testukas', 'iskaita']: info.setdefault(tid, Cache( taskid=tid, description=None, full=None, chosen=False, status=None, done=False, should_choose=False, )) any_of_the_three_chosen = False all_done = True for tid in ['1', '2', '3']: any_of_the_three_chosen = any_of_the_three_chosen or info[tid]['chosen'] info[tid]['should_choose'] = not info['projektukas']['chosen'] all_done = all_done and info[tid]['done'] all_done = all_done or info['projektukas']['done'] info['all_done'] = all_done info['projektukas']['should_choose'] = not any_of_the_three_chosen info['iskaita']['done'] = info['testukas']['done'] and all_done info['uzd'] = [info[taskid] for taskid in ['1', '2', '3', 'projektukas', 'testukas', 'iskaita']] name, surname = (name.split() + ['???', '???'])[:2] results.append((surname, name, info)) results.sort() return [row[-1] for row in results]
def cna_tasks(gr=None, pogr=None, source='taskdata'): taken = {} exacttaken = {} if gr: for row in cna_parse_students(gr=gr, pogr=pogr): task = row['task'] exacttaken[task] = exacttaken.get(task, 0) + 1 if task: task = task.split()[0] taken[task] = taken.get(task, 0) + 1 cur_template = bf.template_context.template_name task_file = os.path.join(os.path.dirname(cur_template), source) data = open(task_file).read() rows = data.strip().splitlines()[1:] result = [] for row in rows: cells = row.split(None, 1) task = cells[0] title = cells[1] shorttitle = title if len(shorttitle) > 30: shorttitle = ' '.join(title.split()[:5]) + "..." en = exacttaken.get(task, 0) n = taken.get(task, 0) if en > 1: cls = 'conflict' elif n: cls = 'taken' else: cls = '' result.append(Cache( task=task.decode('UTF-8'), title=title.decode('UTF-8'), shorttitle=shorttitle.decode('UTF-8'), class_=cls, )) return result
def py_tasks(source='tasks.txt', strict=False): cur_template = bf.template_context.template_name data_file = os.path.join(os.path.dirname(cur_template), source) errors = [] people = {} for line in open(data_file).read().splitlines(): line = line.decode('UTF-8') if line.startswith('#'): continue if ':' not in line: continue name, what = line.split(':', 1) name = fullinfo = name.strip() if '(' in name: name = name.split('(', 1)[0].strip() persondata = people.setdefault(name, Cache( name=name, fullinfo=fullinfo)) what = what.strip() if '[' not in what: if strict: errors.append('no "[" in line %s' % line) continue description, status = what.split('[', 1) description = description.strip() taskandstatus = status[:-1].strip() taskid = 'unknown' status = taskandstatus for tid in ['1', '2', '3', 'projektukas', 'testukas']: if taskandstatus.startswith(tid): taskid = tid status = taskandstatus[len(tid):] break if strict and taskid in persondata: errors.append('duplicate entry: %s' % line) persondata[taskid] = Cache( taskid=taskid, description=what.split('[')[0].strip(), full=what, chosen=True, status=status, done='+' in status) if errors: raise Exception('\n'.join(errors)) return people
def py_student_totals(source='tasks.txt'): n_students = 0 n_all_done = 0 n_passed = 0 for row in py_students(source): n_students += 1 if row['all_done']: n_all_done += 1 if row['iskaita']['done']: n_passed += 1 return Cache( students=n_students, done_all=n_all_done, passed=n_passed)
def py_taken(taskid, source='tasks.txt'): tasks = [] for persondata in py_tasks(source).values(): task = persondata.get(taskid, {}).get('description') done = persondata.get(taskid, {}).get('done') if task: tasks.append((task, persondata['name'], done)) tasks.sort() return [ Cache( task=task, student=name, done=done, done_suffix=(done and ' [+]' or ''), ) for task, name, done in tasks ]
def py_students_by_group(source='../tasks.txt'): groups = {} for row in py_students(source): try: group = row['fullinfo'].split('(', 1)[1].split(')')[0] group = group.replace('informatika', u'kompiuterių mokslas') except IndexError: group = '???' groups.setdefault(group, []).append(row) results = groups.items() results.sort() return [ Cache( title=title, students=students, count=len(students), count_done=sum([1 for s in students if s['iskaita']['done']]), ) for title, students in results ]
def cna_parse_students(gr, pogr=None, source='data${gr}gr.csv'): cur_template = bf.template_context.template_name csv_file = os.path.join(os.path.dirname(cur_template), source.replace('${gr}', gr)) result = [] for cells in list(csv.reader(open(csv_file)))[1:]: # 0: eil nr, 1: stud paz, 2: vardas, 3: username, 4: uzduotis, 5: pogrupis, 6: 1uzd, 7: data, 8: pastabos, 9: 2uzd, 10:, 11:, 12: 3uzd, ... cells = [s.strip() for s in cells] while len(cells) <= 12: cells.append('') if pogr and str(pogr) != cells[5]: continue uzd1 = cells[6] and '+' or '' uzd2 = cells[9] and '+' or '' uzd3 = cells[12] and '+' or '' result.append(Cache( name=cells[2].strip().decode('UTF-8'), task=cells[4].strip().decode('UTF-8'), uzd=[uzd1, uzd2, uzd3], )) return result
def cna_results(gr=None, pogr=None, deadlines=(), source='../data${gr}gr.csv', holiday_week=None, date_prefix_sanity_check='2005-0'): for deadline in deadlines: assert deadline.startswith(date_prefix_sanity_check) taskmap = {} for row in cna_tasks(source='../taskdata'): taskmap[row['task']] = row['shorttitle'] def parse_score(score): """Pvz., '1.5+0.2-0.3' => [1.5, 0.2, -0.3]""" score = score.replace(' ', '') score = score.replace('+', ' +') score = score.replace('-', ' -') return map(float, score.split()) def week_of(date): week = datetime.datetime.strptime(date, '%Y-%m-%d').isocalendar()[1] if holiday_week is not None: assert week != holiday_week if week < holiday_week: week += 1 return week def penalty(date, deadline): w_of_d = week_of(date) diff = week_of(deadline) - w_of_d if diff > 3: diff = 3 return diff * 0.1 cur_template = bf.template_context.template_name csv_file = os.path.join(os.path.dirname(cur_template), source.replace('${gr}', gr)) result = [] for cells in list(csv.reader(open(csv_file)))[1:]: # 0: eil nr, 1: stud paz, 2: vardas, 3: username, 4: uzduotis, 5: pogrupis, 6: 1uzd, 7: data, 8: pastabos, 9: 2uzd, 10:, 11:, 12: 3uzd, ... cells = [s.strip() for s in cells] while len(cells) <= 15: cells.append('') if pogr and str(pogr) != cells[5]: continue uzd = [] total = total_no_delay = 0 left = {1.5: 2, 1: 1} kurios = {} for n in range(3): score = cells[6+3*n].strip() parts = parse_score(score) total += sum(parts) total_no_delay += sum(parts) if len(parts) > 1 and parts[1] < 0: total_no_delay -= parts[1] date = cells[7+3*n].strip() comments = cells[8+3*n].strip() plus = score and '+' or '' uncertainity = False if ('C++/Java' in comments or 'C/Java' in comments or 'Java/C++' in comments or 'C++ su Java' in comments): if 'C++/Java' in kurios: comments = "kartojasi!!!\n" + comments else: kurios['C++/Java'] = 1 elif 'C' in comments: if 'C' in kurios: comments = "kartojasi!!!\n" + comments else: kurios['C'] = 1 elif 'Java' in comments: if 'Java' in kurios: comments = "kartojasi!!!\n" + comments else: kurios['Java'] = 1 if date and not date.startswith(date_prefix_sanity_check): uncertainity = True comments = "data!!!\n" + comments if date and parts: pen = penalty(date, deadlines[n]) if pen == 0: parts.insert(1, 0.0) elif parts: if len(parts) < 2: parts.append(0.0) if abs(parts[1] - pen) > 0.001: uncertainity = True if pen < 0: comments = "(vėlavo %s)!!!\n" % pen + comments else: comments = "(skubėjo %s)!!!\n" % pen + comments if parts: if left.get(parts[0], 0) < 1: comments = "!!!\n" + comments else: left[parts[0]] = left[parts[0]] - 1 if 'nežinau už ką' in comments: uncertainity = True score = ''.join(['%+.1f' % x for x in parts]) if score.startswith('+'): score = score[1:] score = score.replace('-', u'−') # hyphen -> U+2212 MINUS SIGN uzd.append(Cache( plus=plus, date=date, score=score, comments=comments.decode('UTF-8'), uncertainity=uncertainity, )) task = cells[4].strip().decode('UTF-8') taskhint = taskmap.get(task, "") result.append(Cache( name=cells[2].strip().decode('UTF-8'), taskhint=taskhint, task=task, uzd=uzd, total=total, total_no_delay=total_no_delay, studnr=cells[1].strip().decode('UTF-8'), )) return result