Exemple #1
0
def getSubmissions(params, user):
    submissions = []

    cont = Contest.getCurrent()
    if not cont:
        return ""

    Submission.forEach(lambda x: submissions.append(x) if x.user.id == user.id
                       and cont.start <= x.timestamp <= cont.end else None)
    if len(submissions) == 0:
        return Page(h2("No Submissions Yet", cls="page-title"), )
    return Page(h2("Your Submissions", cls="page-title"),
                *map(SubmissionDisplay, submissions))
def getSubmissions(params, user):
    submissions = []
    
    cont = Contest.getCurrent()
    if not cont:
        return ""
    
    Submission.forEach(lambda x: submissions.append(x) if x.user.id == user.id and cont.start <= x.timestamp <= cont.end else None)
    if len(submissions) == 0:
        return Page(
            h2("No Submissions Yet", cls="page-title"),
        )
    return Page(
        h2("Your Submissions", cls="page-title"),
        *map(SubmissionDisplay, submissions)
    )
Exemple #3
0
 def __init__(self, submission: Submission):
     subTime = submission.timestamp
     probName = submission.problem.title
     cls = "gray" if submission.status == "Review" else "red" if submission.result != "ok" else ""
     self.html = div(
         cls="modal-content",
         contents=[
             div(cls=f"modal-header {cls}",
                 contents=[
                     h.h5(
                         f"Submission to {probName} at ",
                         h.span(subTime,
                                cls="time-format",
                                data_timestamp=subTime)), """
             <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                 <span aria-hidden="true">&times;</span>
             </button>"""
                 ]),
             div(cls="modal-body",
                 contents=[
                     h.strong(
                         "Language: <span class='language-format'>{}</span>"
                         .format(submission.language)),
                     h.br(),
                     h.strong("Result: "),
                     verdict_name[submission.getContestantResult()],
                     h.br(),
                     h.br(),
                     h.strong("Code:"),
                     h.code(submission.code.replace("\n", "<br/>").replace(
                         " ", "&nbsp;"),
                            cls="code"),
                 ])
         ])
Exemple #4
0
def rejudge(params, setHeader, user):
    id = params["id"]
    submission = Submission.get(id)
    if os.path.exists(f"/tmp/{id}"):
        shutil.rmtree(f"/tmp/{id}")
    runCode(submission)
    return submission.result
def rejudge(params, setHeader, user):
    id = params["id"]
    submission = Submission.get(id)
    if os.path.exists(f"/tmp/{id}"):
        shutil.rmtree(f"/tmp/{id}")
    runCode(submission)
    return submission.result
def correctLog(params, user):
    contest = Contest.getCurrent() or Contest.getPast()
    if not contest:
        return Page(h1("&nbsp;"), h1("No Contest Available", cls="center"))
    elif contest.scoreboardOff <= time.time() * 1000 and not user.isAdmin():
        return Page(h1("&nbsp;"), h1("Scoreboard is off.", cls="center"))

    start = contest.start
    end = contest.end

    subs = {}
    for sub in Submission.all():
        if start <= sub.timestamp <= end and not sub.user.isAdmin():
            subs[sub.user.id] = subs.get(sub.user.id) or []
            subs[sub.user.id].append(sub)

    log = createLog(subs)

    logDisplay = []
    for (tmstmp, usr, ttl, id) in log:
        logDisplay.append(
            h.tr(
                h.td(tmstmp, cls='time-format', data_timestamp=tmstmp),
                h.td(usr),
                h.td(ttl, cls="center"),
            ))

    return Page(
        h2("Correct Log", cls="page-title"),
        h.table(
            h.thead(
                h.tr(h.th("Date/Time", cls="center"), h.th("Contestant"),
                     h.th("Problem", cls="center"))), h.tbody(*logDisplay)))
Exemple #7
0
def changeResult(params, setHeader, user):
    id = params["id"]
    sub = Submission.get(id)
    if not sub:
        return "Error: incorrect id"
    sub.result = params["result"]
    sub.save()
    return "ok"
def download(params, setHeader, user):
    id = params["id"]
    submission = Submission.get(id)
    files = [(f"submission.{exts[submission.language]}", submission.code)]
    for i in range(len(submission.inputs)):
        files.append((f"test{i}.txt", submission.inputs[i]))
    # send the json data
    return json.dumps(files)
def changeResult(params, setHeader, user):
    id = params["id"]
    sub = Submission.get(id)
    if not sub:
        return "Error: incorrect id"
    sub.result = params["result"]
    sub.save()
    return "ok"
Exemple #10
0
 def __init__(self, contest):
     subs = filter(
         lambda sub: sub.user.type != "admin" and contest.start <= sub.
         timestamp <= contest.end, Submission.all())
     self.html = h.table(
         h.thead(
             h.tr(h.th("Name"), h.th("Problem"), h.th("Time"),
                  h.th("Language"), h.th("Result"))),
         h.tbody(*map(lambda sub: SubmissionRow(sub), subs)),
         id="submissions")
Exemple #11
0
 def __init__(self,
              title,
              contents,
              link=None,
              cls=None,
              delete=None,
              reply=None,
              user=None,
              problemId=None):
     if cls == None:
         cls = "card"
     else:
         cls += " card"
     deleteLink = ""
     if delete:
         deleteLink = div(h.i("clear", cls="material-icons"),
                          cls="delete-link",
                          onclick=delete)
     elif reply:
         deleteLink = div("Reply", cls="delete-link", onclick=reply)
     result = ''
     if user != None and problemId != None:
         icon = ''
         tmstmp = 0
         result = ''
         for i in Submission.all():
             if user.isAdmin():
                 break
             if i.problem != None:
                 if i.problem.id == problemId and i.user.id == user.id and "ok" == i.result:
                     icon = "check"
                     tmstmp = i.timestamp
                     break
                 elif i.problem.id == problemId and i.user.id == user.id and "pending" != i.result:
                     icon = "times"
                     tmstmp = i.timestamp
         if icon != '':
             result = f'<i class="fa fa-{icon}"></i> '
     self.html = h.div(cls=cls,
                       contents=[
                           div(cls="card-header",
                               contents=[
                                   h2(contents=[result, title],
                                      cls="card-title"), deleteLink
                               ]),
                           div(cls="card-contents", contents=contents)
                       ])
     if link != None:
         self.html = div(a(href=link, cls="card-link"),
                         self.html,
                         cls="card-link-box")
Exemple #12
0
def getSubmissions(params, user):
    submissions = []

    cont = Contest.getCurrent()
    if not cont:
        return ""

    Submission.forEach(lambda x: submissions.append(x) if x.user.id == user.id
                       and cont.start <= x.timestamp <= cont.end else None)
    if len(submissions) == 0:
        return Page(h2("No Submissions Yet", cls="page-title"), )
    return Page(
        h2("Your Submissions", cls="page-title"),
        SubmissionTable(
            sorted(submissions,
                   key=lambda sub: (sub.problem.title, -sub.timestamp))),
        div(cls="modal",
            tabindex="-1",
            role="dialog",
            contents=[
                div(cls="modal-dialog",
                    role="document",
                    contents=[div(id="modal-content")])
            ]))
def rejudgeAll(params, setHeader, user):
    probId = params["probId"]
    # curTime = params["curTime"]
    curTime = time.time() * 1000
    count = 0
    for contestant in filter(lambda c: not c.isAdmin(), User.all()):
        for sub in filter(
                lambda s: s.user.id == contestant.id and s.problem.id == probId
                and s.timestamp < curTime and s.result != "reject" and s.type
                != "test", Submission.all()):
            if os.path.exists(f"/tmp/{id}"):
                shutil.rmtree(f"/tmp/{id}")
            runCode(sub)
            count += 1
    return {"name": Problem.get(probId).title, "count": count}
Exemple #14
0
def leaderboard(params, user):
    contest = Contest.getCurrent() or Contest.getPast()
    if not contest:
        return Page(h1("&nbsp;"), h1("No Contest Available", cls="center"))
    elif contest.scoreboardOff <= time.time() * 1000 and not user.isAdmin():
        return Page(h1("&nbsp;"), h1("Scoreboard is off.", cls="center"))

    start = contest.start
    end = contest.end

    subs = {}
    for sub in Submission.all():
        if start <= sub.timestamp <= end and not sub.user.isAdmin():
            subs[sub.user.id] = subs.get(sub.user.id) or []
            subs[sub.user.id].append(sub)

    scores = []
    for user in subs:
        scor = score(subs[user], start)
        scores.append((User.get(user).username, scor[0], scor[1], scor[2]))
    scores = sorted(scores,
                    key=lambda score: score[1] * 1000000000 + score[2] *
                    10000000 - score[3],
                    reverse=True)

    ranks = [i + 1 for i in range(len(scores))]
    for i in range(1, len(scores)):
        u1 = scores[i]
        u2 = scores[i - 1]
        if (u1[1], u1[2], u1[3]) == (u2[1], u2[2], u2[3]):
            ranks[i] = ranks[i - 1]

    scoresDisplay = []
    for (name, solved, samples, points), rank in zip(scores, ranks):
        scoresDisplay.append(
            h.tr(h.td(name), h.td(solved, cls="center"),
                 h.td(samples, cls="center"), h.td(points, cls="center"),
                 h.td(rank, cls="center")))

    return Page(
        h2("Leaderboard", cls="page-title"),
        h.table(
            h.thead(
                h.tr(h.th("User"), h.th("Problems Solved", cls="center"),
                     h.th("Sample Cases Solved", cls="center"),
                     h.th("Penalty Points", cls="center"),
                     h.th("Rank", cls="center"))), h.tbody(*scoresDisplay)))
def changeResult(params, setHeader, user):
    version = int(params["version"])
    id = params["id"]
    sub = Submission.get(id)
    contestDict = sub.problem.contests[Contest.getCurrent().id]

    scoreChange = -1 if params["result"] != "ok" else 1
    if (sub.user.id in contestDict["completed"] and scoreChange == -1) or (
            sub.user.id not in contestDict["completed"] and scoreChange == 1):
        if scoreChange == -1:
            contestDict["completed"].remove(sub.user.id)
        else:
            contestDict["completed"].append(sub.user.id)

        if sub.language == 'c':
            contestDict['c'] += scoreChange
        elif sub.language == 'cpp':
            contestDict['cpp'] += scoreChange
        elif sub.language == 'cs':
            contestDict['cs'] += scoreChange
        elif sub.language == 'java':
            contestDict['java'] += scoreChange
        elif sub.language == 'python2':
            contestDict['python2'] += scoreChange
        elif sub.language == 'python3':
            contestDict['python3'] += scoreChange
        elif sub.language == 'ruby':
            contestDict['ruby'] += scoreChange
        elif sub.language == 'vb':
            contestDict['vb'] += scoreChange
    if not sub:
        return "Error: incorrect id"
    elif sub.version != version:
        return "The submission has been changed by another judge since you loaded it. Please reload the sumbission to modify it."
    sub.result = params["result"]
    sub.status = params["status"]
    sub.version += 1
    sub.checkout = None
    sub.save()
    return "ok"
def addSubmission(probId, lang, code, user, type):
    sub = Submission()
    sub.problem = Problem.get(probId)
    sub.language = lang
    sub.code = code
    sub.result = "pending"
    sub.user = user
    sub.timestamp = time.time() * 1000
    sub.type = type
    if type == "submit":
        sub.save()
    else:
        sub.id = str(uuid4())
    return sub
Exemple #17
0
def judge_submission(params, user):
    return SubmissionCard(Submission.get(params[0]))
Exemple #18
0
def addSubmission(probId, lang, code, user, type):
    sub = Submission()
    sub.problem = Problem.get(probId)
    sub.language = lang
    sub.code = code
    sub.result = "pending"
    sub.user = user
    sub.timestamp = time.time() * 1000
    sub.type = type
    if type == "submit":
        sub.save()
    else:
        sub.id = str(uuid4())
    return sub
Exemple #19
0
def detailedReport(params, user):
    contest = Contest.getCurrent() or Contest.getPast()
    if not contest:
        return Page(h1("&nbsp;"), h1("No Contest Available", cls="center"))
    elif contest.scoreboardOff <= time.time() * 1000 and not user.isAdmin():
        return Page(h1("&nbsp;"), h1("Scoreboard is off.", cls="center"))

    start = contest.start
    end = contest.end

    subs = {}
    for sub in Submission.all():
        if start <= sub.timestamp <= end and not sub.user.isAdmin():
            subs[sub.user.id] = subs.get(sub.user.id) or []
            subs[sub.user.id].append(sub)

    problemSummary = {}
    for prob in contest.problems:
        problemSummary[prob.id] = [0, 0]

    scores = []
    for user in subs:
        usersubs = subs[user]
        scor = score(usersubs, start, problemSummary)
        atempts = []
        for i in getDetails(usersubs, contest):
            atempts.append(i)
        scores.append((User.get(user).username, User.get(user).id, scor[0],
                       scor[1], scor[2], atempts))
    scores = sorted(scores,
                    key=lambda score: score[2] * 1000000000 + score[3] *
                    10000000 - score[4],
                    reverse=True)

    ranks = [i + 1 for i in range(len(scores))]
    for i in range(1, len(scores)):
        u1 = scores[i]
        u2 = scores[i - 1]
        if (u1[1], u1[2], u1[3]) == (u2[1], u2[2], u2[3]):
            ranks[i] = ranks[i - 1]

    scoresDisplay = []
    for (name, usrID, solved, samples, points,
         atempts), rank in zip(scores, ranks):
        atmpts = []
        for atmpt in atempts:
            atmpts.append(h.td(atmpt, cls="center"))
        scoresDisplay.append(
            h.tr(h.td(rank, cls="center"),
                 h.td(name) if contest.end <= time.time() * 1000 else '',
                 h.td(usrID, cls="center"), h.td(solved, cls="center"),
                 h.td(points, cls="center"), *atmpts))
    problemSummaryDisplay = []
    languageSummaryDisplay = []
    cnt = 1
    for problem in contest.problems:
        contestDict = problem.contests[contest.id]
        problemSummaryDisplay.append(
            h.tr(h.td(cnt), h.td(problem.title),
                 h.td(problemSummary[problem.id][0], cls="center"),
                 h.td(problemSummary[problem.id][1], cls="center")))
        languageSummaryDisplay.append(
            h.tr(h.td(cnt), h.td(problem.title),
                 h.td(contestDict["c"], cls="center"),
                 h.td(contestDict["cpp"], cls="center"),
                 h.td(contestDict["cs"], cls="center"),
                 h.td(contestDict["java"], cls="center"),
                 h.td(contestDict["python2"], cls="center"),
                 h.td(contestDict["python3"], cls="center"),
                 h.td(contestDict["ruby"], cls="center"),
                 h.td(contestDict["vb"], cls="center")))
        cnt += 1

    prblmHeader = []
    cnt = 1
    for num in contest.problems:
        prblmHeader.append(h.th(cnt, cls="center"))
        cnt += 1

    return Page(
        h2("Detailed Report", cls="page-title"),
        h.table(
            h.thead(
                h.tr(
                    h.th("Rank", cls="center"),
                    h.th("Contestant")
                    if contest.end <= time.time() * 1000 else '',
                    h.th("ContestantID", cls="center"),
                    h.th("Correct", cls="center"), h.th("Penalty",
                                                        cls="center"),
                    *prblmHeader)), h.tbody(*scoresDisplay)),
        h2("Problem Summary", cls="page-title"),
        h.table(
            h.thead(
                h.tr(
                    h.th("#"),
                    h.th("Title"),
                    h.th("Attempts", cls="center"),
                    h.th("Correct", cls="center"),
                )), h.tbody(*problemSummaryDisplay)),
        h2("Problem Summary", cls="page-title"),
        h.table(
            h.thead(
                h.tr(h.th("#"), h.th("Title"), h.th("c", cls="center"),
                     h.th("cpp", cls="center"), h.th("cs", cls="center"),
                     h.th("java", cls="center"), h.th("python2", cls="center"),
                     h.th("python3", cls="center"), h.th("ruby", cls="center"),
                     h.th("vb", cls="center"))),
            h.tbody(*languageSummaryDisplay)))
Exemple #20
0
def leaderboard(params, user):
    contest = Contest.getCurrent() or Contest.getPast()
    if not contest:
        return Page(h1("&nbsp;"), h1("No Contest Available", cls="center"))
    elif contest.scoreboardOff <= time.time() * 1000 and not user.isAdmin():
        return Page(h1("&nbsp;"), h1("Scoreboard is off.", cls="center"))

    start = contest.start
    end = contest.end

    subs = {}
    for sub in Submission.all():
        if start <= sub.timestamp <= end and not sub.user.isAdmin():
            subs[sub.user.id] = subs.get(sub.user.id) or []
            subs[sub.user.id].append(sub)

    problemSummary = {}
    for prob in contest.problems:
        problemSummary[prob.id] = [0, 0]

    scores = []
    for user in subs:
        usersubs = subs[user]
        scor = score(usersubs, start, problemSummary)

        scores.append((User.get(user).username, scor[0], scor[1], scor[2],
                       len(usersubs)))
    scores = sorted(scores,
                    key=lambda score: score[1] * 1000000000 + score[2] *
                    10000000 - score[3],
                    reverse=True)

    ranks = [i + 1 for i in range(len(scores))]
    for i in range(1, len(scores)):
        u1 = scores[i]
        u2 = scores[i - 1]
        if (u1[1], u1[2], u1[3]) == (u2[1], u2[2], u2[3]):
            ranks[i] = ranks[i - 1]

    scoresDisplay = []
    for (name, solved, samples, points, attempts), rank in zip(scores, ranks):

        scoresDisplay.append(
            h.tr(h.td(rank, cls="center"), h.td(name),
                 h.td(attempts, cls="center"), h.td(solved, cls="center"),
                 h.td(samples, cls="center"), h.td(points, cls="center")))

    problemSummaryDisplay = []
    for problem in contest.problems:
        problemSummaryDisplay.append(
            h.tr(h.td(problem.title),
                 h.td(problemSummary[problem.id][0], cls="center"),
                 h.td(problemSummary[problem.id][1], cls="center")))

    return Page(
        h2("Leaderboard", cls="page-title"),
        h.table(
            h.thead(
                h.tr(h.th("Rank", cls="center"), h.th("User"),
                     h.th("Attempts", cls="center"),
                     h.th("Problems Solved", cls="center"),
                     h.th("Sample Cases Solved", cls="center"),
                     h.th("Penalty Points", cls="center"))),
            h.tbody(*scoresDisplay)), h2("Problem Summary", cls="page-title"),
        h.table(
            h.thead(
                h.tr(
                    h.th("Problem", cls="center"),
                    h.th("Attempts", cls="center"),
                    h.th("Solved", cls="center"),
                )), h.tbody(*problemSummaryDisplay)), h.br(), h.br(), h.br(),
        div(cls="actions",
            contents=[
                h.button("Detailed Report",
                         cls="button correct-log",
                         onclick="window.location='/detailedReport'"),
                h.button("Correct Log",
                         cls="button correct-log",
                         onclick="window.location='/correctLog'")
            ]))
Exemple #21
0
def contestant_submission(params, user):
    return SubmissionCard(Submission.get(params[0]))
Exemple #22
0
def judge_submission_close(params, setHeader, user):
    submission = Submission.get(params["id"])
    if submission.version == int(params["version"]):
        submission.checkout = None
        submission.save()
    return "ok"
Exemple #23
0
def judge_submission(params, user):
    submission = Submission.get(params[0])
    force = params[1] == "force"
    if submission.checkout is not None and not force:
        return f"CONFLICT:{User.get(submission.checkout).username}"
    return SubmissionCard(submission, user, force)
Exemple #24
0
 def __init__(self, x, cont):
     num, prob = x
     subs = filter(
         lambda sub: sub.problem == prob and cont.start <= sub.timestamp <=
         cont.end, Submission.all())
     self.html = div(*map(SubmissionCard, subs), id=f"tabs-{num}")
 def __init__(self, x, cont):
     num, prob = x
     subs = filter(lambda sub: sub.problem == prob and cont.start <= sub.timestamp <= cont.end, Submission.all())
     self.html = div(*map(SubmissionCard, subs), id=f"tabs-{num}")
 def __init__(self, contest):
     subs = filter(lambda sub: sub.user.type != "admin" and contest.start <= sub.timestamp <= contest.end, Submission.all())
     self.html = h.table(
         h.thead(
             h.tr(
                 h.th("Name"),
                 h.th("Problem"),
                 h.th("Time"),
                 h.th("Language"),
                 h.th("Result")
             )
         ),
         h.tbody(
             *map(lambda sub: SubmissionRow(sub), subs)
         ),
         id="submissions"
     )
def judge_submission(params, user):
    return SubmissionCard(Submission.get(params[0]))
Exemple #28
0
 def __init__(self, submission: Submission, user, force):
     subTime = submission.timestamp
     probName = submission.problem.title
     cls = "gray" if submission.status == "Review" else "red" if submission.result != "ok" else ""
     submission.checkout = user.id
     self.html = div(
         cls="modal-content",
         contents=[
             div(cls=f"modal-header {cls}",
                 contents=[
                     h.h5(
                         f"Submission to {probName} at ",
                         h.span(subTime,
                                cls="time-format",
                                data_timestamp=subTime)), """
             <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                 <span aria-hidden="true">&times;</span>
             </button>"""
                 ]),
             div(cls="modal-body",
                 contents=[
                     h.input(type="hidden",
                             id="version",
                             value=f"{submission.version}"),
                     h.strong(
                         "Language: <span class='language-format'>{}</span>"
                         .format(submission.language)),
                     h.br(),
                     h.strong(
                         "Result: ",
                         h.select(
                             cls=f"result-choice {submission.id}",
                             contents=[*resultOptions(submission.result)])),
                     h.strong(
                         "&emsp;Status: ",
                         h.select(
                             cls=f"status-choice {submission.id}",
                             contents=[*statusOptions(submission.status)])),
                     h.span("&emsp;"),
                     h.button(
                         "Save",
                         type="button",
                         onclick=
                         f"changeSubmissionResult('{submission.id}', '{submission.version}')",
                         cls="btn btn-primary"),
                     h.br(),
                     h.br(),
                     h.button("Rejudge",
                              type="button",
                              onclick=f"rejudge('{submission.id}')",
                              cls="btn btn-primary rejudge"),
                     h.br(),
                     h.br(),
                     h.strong("Code:"),
                     h.code(submission.code.replace("\n", "<br/>").replace(
                         " ", "&nbsp;"),
                            cls="code"),
                     h.br(),
                     h.button("Download",
                              type="button",
                              onclick=f"download('{submission.id}')",
                              cls="btn btn-primary download"),
                     h.br(),
                     h.br(),
                     div(cls="result-tabs",
                         id="result-tabs",
                         contents=[
                             h.ul(*map(lambda x: TestCaseTab(x, submission),
                                       enumerate(submission.results))),
                             *map(
                                 lambda x: TestCaseData(x, submission),
                                 zip(range(submission.problem.tests),
                                     submission.inputs, submission.outputs,
                                     submission.errors, submission.answers))
                         ])
                 ])
         ])
def leaderboard(params, user):
    contest = Contest.getCurrent() or Contest.getPast()
    if not contest:
        return Page(
            h1("&nbsp;"),
            h1("No Contest Available", cls="center")
        )
    elif contest.scoreboardOff <= time.time() * 1000 and not user.isAdmin():
        return Page(
            h1("&nbsp;"),
            h1("Scoreboard is off.", cls="center")
        )

    start = contest.start
    end = contest.end

    
    subs = {}
    for sub in Submission.all():
        if start <= sub.timestamp <= end and not sub.user.isAdmin():
            subs[sub.user.id] = subs.get(sub.user.id) or []
            subs[sub.user.id].append(sub)            
    
    problemSummary = {}
    for prob in contest.problems:
        problemSummary[prob.id] = [0, 0]

    scores = []
    for user in subs:
        usersubs = subs[user]
        scor = score(usersubs, start, problemSummary)
        scores.append((
            User.get(user).username,
            scor[0],
            scor[1],
            scor[2],
            len(usersubs)
        ))
    scores = sorted(scores, key=lambda score: score[1] * 1000000000 + score[2] * 10000000 - score[3], reverse=True)
    
    ranks = [i + 1 for i in range(len(scores))]
    for i in range(1, len(scores)):
        u1 = scores[i]
        u2 = scores[i - 1]
        if (u1[1], u1[2], u1[3]) == (u2[1], u2[2], u2[3]):
            ranks[i] = ranks[i - 1]
    
    scoresDisplay = []
    for (name, solved, samples, points, attempts), rank in zip(scores, ranks):
        scoresDisplay.append(h.tr(
            h.td(rank, cls="center"),
            h.td(name),
            h.td(attempts, cls="center"),
            h.td(solved, cls="center"),
            h.td(samples, cls="center"),
            h.td(points, cls="center")
        ))

    problemSummaryDisplay = []
    for problem in contest.problems:
        problemSummaryDisplay.append(h.tr(
            h.td(problem.title),
            h.td(problemSummary[problem.id][0], cls="center"),
            h.td(problemSummary[problem.id][1], cls="center")
        ))

    return Page(
        h2("Leaderboard", cls="page-title"),
        h.table(
            h.thead(
                h.tr(
                    h.th("Rank", cls="center"),
                    h.th("User"),
                    h.th("Attempts", cls="center"),
                    h.th("Problems Solved", cls="center"),
                    h.th("Sample Cases Solved", cls="center"),
                    h.th("Penalty Points", cls="center")
                )
            ),
            h.tbody(
                *scoresDisplay
            )
        ),
        h2("Problem Summary", cls="page-title"),
        h.table(
            h.thead(
                h.tr(
                    h.th("Problem", cls="center"),
                    h.th("Attempts", cls="center"),
                    h.th("Solved", cls="center"),
                )
            ),
            h.tbody(
                *problemSummaryDisplay
            )

        )
    )