Skip to content
Snippets Groups Projects
Select Git revision
  • 3813f3da74d37b4ed8cafcad43e7b7097871c046
  • master default protected
2 results

splay_operation.h

Blame
  • p-score NaN GiB
    #!/usr/bin/env python3
    # Generátor výsledkové listiny pro MO-P
    
    import argparse
    import locale
    from sqlalchemy.orm import joinedload
    
    import mo.db as db
    from mo.score import Score
    from mo.util import die, init_standalone
    from mo.util_format import format_decimal
    
    parser = argparse.ArgumentParser(description='Vygeneruje výsledkovou listinu MO-P')
    parser.add_argument('year', type=int)
    parser.add_argument('seq', type=int)
    
    args = parser.parse_args()
    init_standalone()
    sess = db.get_session()
    
    
    def get_results(round, contests):
        results = {}
        for contest in contests:
            place_code = contest.place.get_code()
            print(f"Počítám oblast {place_code}")
    
            score = Score(round, contest)
            results[place_code] = score.get_sorted_results()
    
            for msg in score.get_messages():
                if msg[0] != 'info':
                    print(f'\t{msg[0].upper()}: {msg[1]}')
    
        return results
    
    
    def write_tex(round, tasks, contests, results):
        with open('final.tex', 'w') as out:
            out.write(r'\def\HranicePostupu{%s}' % (format_decimal(round.score_winner_limit,)) + "\n")
            out.write(r'\def\HraniceUspesnychResitelu{%s}' % (format_decimal(round.score_successful_limit),) + "\n")
            out.write('\n')
            for c in contests:
                res = results[c.place.get_code()]
                if round.seq <= 2:
                    out.write(r'\kraj{%s}' % c.place.name + '\n')
                    if not res:
                        out.write(r'\nobody' + '\n')
                        out.write(r'\endkraj' + '\n\n')
                        continue
    
                out.write(r'\begintable' + '\n')
                prev_typ = ""
    
                for r in res:
                    if r.winner:
                        typ = 'v'
                    elif r.successful:
                        typ = 'u'
                    else:
                        typ = 'n'
                    if typ != prev_typ:
                        if prev_typ:
                            out.write(r'\sep%s' % typ)
                        prev_typ = typ
                    out.write(r'\%s' % typ)
    
                    cols = []
                    o = r.order
                    if not r.successful or o.continuation:
                        cols.append("")
                    elif o.span > 1:
                        cols.append(f'{o.place}.--{o.place + o.span - 1}.')
                    else:
                        cols.append(f'{o.place}.')
    
                    cols.append(r.user.full_name())
                    cols.append(r.pant.school_place.name)
                    cols.append(r.pant.grade)
    
                    sol_map = r.get_sols_map()
                    for t in tasks:
                        s = sol_map.get(t.task_id)
                        if s is not None:
                            cols.append(format_decimal(s.points))
                        else:
                            cols.append('--')
    
                    cols.append(format_decimal(r.get_total_points()))
    
                    out.write("".join(['{' + str(col) + '}' for col in cols]) + '\n')
    
                out.write(r'\endtable' + '\n')
                if round.seq <= 2:
                    out.write(r'\endkraj' + '\n\n')
    
    
    def write_html(round, tasks, contests, results):
        num_cols = 4 + len(tasks) + 1
        with open('final.html', 'w') as out:
            for c in contests:
                out.write(f'<tr><th colspan={num_cols}>{c.place.name}\n')
    
                res = results[c.place.get_code()]
                if not res:
                    out.write(f'<tr class=nobody><td colspan={num_cols}>Nikdo se nezúčastnil.\n')
                    out.write(f'<tr><td colspan={num_cols}>\n\n')
                    continue
    
                for r in res:
                    if r.winner:
                        out.write('<tr class=marked>')
                    elif r.successful:
                        out.write('<tr class=success>')
                    else:
                        out.write('<tr>')
    
                    cols = []
                    o = r.order
                    if not r.successful or o.continuation:
                        cols.append("")
                    elif o.span > 1:
                        cols.append(f'{o.place}.–{o.place + o.span - 1}.')
                    else:
                        cols.append(f'{o.place}.')
    
                    cols.append(r.user.full_name())
                    cols.append(r.pant.school_place.name)
                    cols.append(r.pant.grade)
    
                    sol_map = r.get_sols_map()
                    for t in tasks:
                        s = sol_map.get(t.task_id)
                        if s is not None:
                            cols.append(format_decimal(s.points))
                        else:
                            cols.append('')
    
                    cols.append(format_decimal(r.get_total_points()))
    
                    out.write("".join(['<td>' + str(col) for col in cols]) + '\n')
    
                out.write(f'<tr><td colspan={num_cols}>\n\n')
    
    
    round = sess.query(db.Round).filter_by(year=args.year, category='P', seq=args.seq).filter(db.Round.master_round_id == db.Round.round_id).one()
    print(f"Kolo {round.round_code()}")
    
    round_group_subq = sess.query(db.Round.round_id).filter_by(master_round_id=round.round_id)
    tasks = sess.query(db.Task).filter(db.Task.round_id.in_(round_group_subq)).order_by(db.Task.code).all()
    
    contests = (sess.query(db.Contest)
                .filter_by(round=round)
                .options(joinedload(db.Contest.place))
                .all())
    assert contests
    contests.sort(key=lambda c: locale.strxfrm(c.place.name))
    
    results = get_results(round, contests)
    write_tex(round, tasks, contests, results)
    write_html(round, tasks, contests, results)