Skip to content
Snippets Groups Projects

Vylepšení výsledkové listiny

Merged Martin Mareš requested to merge mj/vysledky-p into devel
1 file
+ 158
0
Compare changes
  • Side-by-side
  • Inline
bin/p-score 0 → 100755
+ 158
0
#!/usr/bin/env python3
# Generátor výsledkové listiny pro MO-P
import argparse
from sqlalchemy.orm import joinedload
import mo.db as db
from mo.score import Score
from mo.util import die, init_standalone
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}' % (round.score_winner_limit,) + "\n")
out.write(r'\def\HraniceUspesnychResitelu{%s}' % (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(s.points)
else:
cols.append('--')
cols.append(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(s.points)
else:
cols.append('')
cols.append(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).one()
print(f"Kolo {round.round_code()}")
tasks = sess.query(db.Task).filter_by(round=round).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: c.place.get_code())
results = get_results(round, contests)
write_tex(round, tasks, contests, results)
write_html(round, tasks, contests, results)
Loading