コード例 #1
0
def schedule_ai_games(exam_id):
    time = timezone.now()
    exam = Exam.objects.get(pk=exam_id)
    comps = exam.competitors.all()
    for p in exam.problems.all():
        subs = []
        for c in comps:
            lastsub = c.submissions.filter(
                problem=p,
                submit_time__lte=time).order_by("-submit_time").first()
            if lastsub is not None:
                subs.append(lastsub)

        n = len(subs)
        ai_prob = p.aiproblem.first()
        np = ai_prob.numplayers
        if n < max(np, 2):
            log(not_enough_players=n, problem=p.problem_name)
            continue  # not enough people to play matches against
        random.shuffle(subs)
        if np == 0:
            g = AIGame(status=-1,
                       time=time,
                       numplayers=n,
                       aiproblem=ai_prob,
                       miniround=-1)
            g.save()
            for i in range(n):
                s = AISubmission(game=g,
                                 seat=i + 1,
                                 competitor=subs[i].competitor,
                                 submission=subs[i])
                s.save()
            g.status = 0  # add to queue after submissions are made
            g.save()
        else:
            roundup = np * ((n + np - 1) // np)
            for i in range(roundup - n):
                subs.append(subs[i])
            for i in range(roundup // np):
                g = AIGame(status=-1,
                           time=time,
                           numplayers=np,
                           aiproblem=ai_prob,
                           miniround=-1)
                g.save()
                for j in range(np):
                    idx = np * i + j
                    s = AISubmission(game=g,
                                     seat=j + 1,
                                     competitor=subs[idx].competitor,
                                     submission=subs[idx])
                    s.save()
                g.status = 0  # add to queue after submissions are made
                g.save()
コード例 #2
0
def check_finished_games_real():
    from website.models import MatchResult
    # log(check_finished_games_real='started')
    games = AIGame.objects.defer("history").filter(status=2)
    for g in games:
        g.status = -1
        g.save()
    for g in games:
        try:
            prob = g.aiproblem.problem
            exam = prob.exam
            subs = []
            ratings = []
            scores = []
            aisubs = []
            for aisub in g.aisubmissions.all():
                sub = aisub.submission
                subs.append(sub)
                ratings.append((sub.rating, ))
                scores.append(-aisub.score)
                aisubs.append(aisub)
            new_ratings = trueskill.rate(ratings, ranks=scores)
            for i in range(len(subs)):
                s = subs[i]
                prev_rating = s.public_rating
                s.mu = new_ratings[i][0].mu
                s.sigma = new_ratings[i][0].sigma
                s.save()
                s.update_score_from_rating()
                score = Score.objects.get(problem=prob,
                                          competitor=s.competitor)
                mr = MatchResult(score=score,
                                 aisubmission=aisubs[i],
                                 time_played=g.time,
                                 prev_rating=prev_rating,
                                 new_rating=s.public_rating)
                mr.save()
            g.status = 4
            g.save()
        except Exception as e:
            log(error=str(e), at='check_finished_games_real', game_id=g.id)
コード例 #3
0
ファイル: leaderboard.py プロジェクト: CMU-Math/cmimc-online
def contest_leaderboard(request, contest_id):
    try:
        user = request.user
        contest = get_object_or_404(Contest, pk=contest_id)
        teams = contest.teams.all()
        exams = list(contest.exams.all())
        max_scores = [0] * len(exams)
        for i in range(len(exams)):
            for t in teams:
                try:
                    c = Competitor.objects.get(exam=exams[i],
                                               team=t,
                                               mathlete=None)
                    max_scores[i] = max(max_scores[i], c.total_score)
                except Exception as e:
                    log(error=str(e),
                        during='contest_leaderboard view',
                        team=t.team_name,
                        exam=exams[i].name)

        rows = []
        for t in teams:
            scores = []
            for i in range(len(exams)):
                try:
                    c = Competitor.objects.get(exam=exams[i],
                                               team=t,
                                               mathlete=None)
                    if max_scores[i] > 0:
                        norm_score = c.total_score / max_scores[i] * 300
                    else:
                        norm_score = 0
                    scores.append(norm_score)
                except:
                    log(error='Competitor not found',
                        exam=exams[i].name,
                        team=t.team_name,
                        contest=contest.name)
            rows.append({
                'scores': scores,
                'name': t.team_name,
                'total': sum(scores)
            })
        rows = sorted(rows, key=lambda d: d['total'], reverse=True)

        rows[0]['rank'] = 1
        for i in range(1, len(rows)):
            if rows[i]['total'] == rows[i - 1]['total']:
                rows[i]['rank'] = rows[i - 1]['rank']
            else:
                rows[i]['rank'] = i + 1

        context = {
            'contest': contest,
            'exams': exams,
            'rows': rows,
        }
        return render(request, 'contest_leaderboard.html', context)
    except Exception as e:
        log(error=str(e), during='contest_leaderboard view')
コード例 #4
0
def schedule_burst(submission):
    p = submission.problem
    exam = p.exam
    if exam.is_ai:
        # schedule a burst of matches
        time = timezone.now()
        comps = exam.competitors.all()
        subs = []
        othersubs = []
        for c in comps:
            lastsub = c.submissions.filter(
                problem=p,
                submit_time__lte=time).order_by("-submit_time").first()
            if lastsub is not None:
                subs.append(lastsub)
                if c != submission.competitor:
                    othersubs.append(lastsub)

        n = len(subs)
        ai_prob = p.aiproblem.first()
        np = ai_prob.numplayers
        if n < max(np, 2):
            log(not_enough_players=n, problem=p.problem_name)
            return  # not enough people to play matches against
        if np == 0:
            for _ in range(ai_prob.burst_matches):
                random.shuffle(subs)
                g = AIGame(status=-1,
                           time=time,
                           numplayers=n,
                           aiproblem=ai_prob,
                           miniround=-1)
                g.save()
                for i in range(n):
                    s = AISubmission(game=g,
                                     seat=i + 1,
                                     competitor=subs[i].competitor,
                                     submission=subs[i])
                    s.save()
                g.status = 0  # add to queue after submissions are made
                g.save()
        else:
            seats = [i + 1 for i in range(np)]
            for i in range(ai_prob.burst_matches):
                random.shuffle(othersubs)
                subs = [submission] + othersubs
                random.shuffle(seats)
                g = AIGame(status=-1,
                           time=time,
                           numplayers=np,
                           aiproblem=ai_prob,
                           miniround=-1)
                g.save()
                for j in range(np):
                    s = AISubmission(game=g,
                                     seat=seats[j],
                                     competitor=subs[j].competitor,
                                     submission=subs[j])
                    s.save()
                g.status = 0  # add to queue after submissions are made
                g.save()
コード例 #5
0
def final_ai_grading(exam):
    log(grade_ai_final='started')
    try:
        comps = exam.competitors.all()
        time = timezone.now()
        for p in exam.problems.all():
            log(problem=p.name)
            subs = []
            for c in comps:
                lastsub = c.submissions.filter(
                    problem=p,
                    submit_time__lte=time).order_by("-submit_time").first()
                if lastsub is not None:
                    subs.append(lastsub)

            n = len(subs)
            ai_prob = p.aiproblem.first()
            np = ai_prob.numplayers
            if n < max(np, 2):
                log(not_enough_players=n, problem=p.problem_name)
                continue  # not enough people to play matches against

            # reset all ratings
            for sub in subs:
                sub.mu = None
                sub.sigma = None
                sub.save()

            if np == 2:
                # 1 iteration = n games in total
                c = 12 * (n - 1)  # 12 round robins
                random.shuffle(subs)
                for i in range(c):
                    shift = i % (n - 1) + 1
                    for j1 in range(n):
                        j2 = (j1 + shift) % n
                        g = AIGame(status=-1,
                                   time=time,
                                   numplayers=np,
                                   aiproblem=ai_prob,
                                   miniround=i)
                        g.save()
                        s1 = AISubmission(game=g,
                                          seat=1,
                                          competitor=subs[j1].competitor,
                                          submission=subs[j1])
                        s1.save()
                        s2 = AISubmission(game=g,
                                          seat=2,
                                          competitor=subs[j2].competitor,
                                          submission=subs[j2])
                        s2.save()
                        g.status = 0  # add to queue after submissions are made
                        g.save()
            elif ai_prob.numplayers == 3:
                # 1 iteration = n games in total
                c = 334
                random.shuffle(subs)
                for i in range(c):
                    x = i % (n - 2) + 1
                    y = n - 1 - i % (n - 1)
                    if x >= y:
                        x += 1
                    # guaranteed that 1 <= x,y <= n and x =/= y
                    # loops over grid diagonally from top-left to bottom-right (x shifted by 1)
                    # this ensures that you don't get matched with the same opponent
                    # at most twice in one iteration (unless n is small or c is large)
                    for j1 in range(n):
                        j2 = (j1 + x) % n
                        j3 = (j1 + y) % n
                        g = AIGame(status=-1,
                                   time=time,
                                   numplayers=np,
                                   aiproblem=ai_prob,
                                   miniround=i)
                        g.save()
                        s1 = AISubmission(game=g,
                                          seat=1,
                                          competitor=subs[j1].competitor,
                                          submission=subs[j1])
                        s1.save()
                        s2 = AISubmission(game=g,
                                          seat=2,
                                          competitor=subs[j2].competitor,
                                          submission=subs[j2])
                        s2.save()
                        s3 = AISubmission(game=g,
                                          seat=3,
                                          competitor=subs[j3].competitor,
                                          submission=subs[j3])
                        s3.save()
                        g.status = 0  # add to queue after submissions are made
                        g.save()
            elif ai_prob.numplayers == 0:
                c = 1000
                for i in range(c):
                    random.shuffle(subs)
                    g = AIGame(status=-1,
                               time=time,
                               numplayers=n,
                               aiproblem=ai_prob,
                               miniround=i)
                    g.save()
                    for j in range(n):
                        s = AISubmission(game=g,
                                         seat=j + 1,
                                         competitor=subs[j].competitor,
                                         submission=subs[j])
                        s.save()
                    g.status = 0  # add to queue after submissions are made
                    g.save()
        log(grade_ai_final='ended')
    except Exception as e:
        log(error=str(e))
コード例 #6
0
def contest_list(request):

    if request.method == 'POST':
        if 'update_contest' in request.POST:
            contest = Contest.objects.get(pk=request.POST['update_contest'])
            update_contest(contest)
        elif 'reset_contest' in request.POST:
            contest = Contest.objects.get(pk=request.POST['reset_contest'])
            reset_contest(contest)
        elif 'reset_exam' in request.POST:
            exam = Exam.objects.get(pk=request.POST['reset_exam'])
            reset_exam(exam)
        elif 'reset_problem' in request.POST:
            problem = Problem.objects.get(pk=request.POST['reset_problem'])
            reset_problem(problem)
        elif 'init_all_tasks' in request.POST:
            init_all_tasks()
        elif 'regrade_games' in request.POST:
            regrade_games()
        elif 'recheck_games' in request.POST:
            recheck_games()
        elif 'score_file' in request.FILES:
            text = request.FILES['score_file'].read().decode('utf-8')
            scores_from_csv(text)
        elif 'recompute_leaderboard' in request.POST:
            exam = Exam.objects.get(pk=request.POST['recompute_leaderboard'])
            recompute_leaderboard(exam)
        elif 'final_ai_grading' in request.POST:
            exam = Exam.objects.get(pk=request.POST['final_ai_grading'])
            final_ai_grading(exam)
        elif 'check_finished_games' in request.POST:
            check_finished_games_real()
        elif 'delete_team' in request.POST:
            team = Team.objects.get(pk=request.POST['delete_team'])
            log(deleting_team=team.team_name)
            team.delete()
            log(deleted_team='')

    user = request.user
    all_contests = Contest.objects.all()
    if not user.is_tester:
        all_contests = all_contests.filter(
            is_private=False)  # hide private contests

    tuples = []
    for contest in all_contests:
        if user.is_mathlete:
            if user.has_team(contest):
                team = user.mathlete.get_team(contest)
                tuples.append({
                    'contest': contest,
                    'has_team': True,
                    'team': team,
                    'exams': contest.reg_exams(user.mathlete),
                    'canjoin': contest.started
                })
            else:
                tuples.append({
                    'contest': contest,
                    'has_team': False,
                    'team': None,
                    'exams': contest.reg_exams(user.mathlete),
                    'canjoin': False
                })
        else:
            tuples.append({
                'contest': contest,
                'has_team': user.has_team(contest),
                'team': None,
                'exams': contest.exams.all(),
                'canjoin': contest.started
            })

    # Categorize the contests in the tuples
    ongoing_contests = []
    for t in tuples:
        if t['contest'].ongoing:
            ongoing_contests.append(t)
    upcoming_contests = []
    for t in tuples:
        if not t['contest'].started:
            upcoming_contests.append(t)
    past_contests = []
    for t in tuples:
        if t['contest'].ended:
            past_contests.append(t)

    # Get all exams
    all_exams = Exam.objects.all()
    all_emails = []
    prog_emails = []
    small_teams = []
    member_count = [0] * 10
    member_count2 = [0] * 10

    if user.is_staff:

        # Temporary email list (only visible to staff)
        all_users = User.objects.all()
        for user in all_users:
            all_emails.append(user.email)

        c = Contest.objects.get(pk=1)  # programming contest
        teams = Team.objects.filter(contest=c)
        for team in teams:
            member_count[min(team.mathletes.all().count(), 9)] += 1
            for m in team.mathletes.all():
                prog_emails.append(m.user.email)
            if team.coach:
                prog_emails.append(team.coach.email)
            if team.mathletes.all().count() < 3:
                for m in team.mathletes.all():
                    small_teams.append(m.user.email)

        c = Contest.objects.get(pk=2)  # programming contest
        teams = Team.objects.filter(contest=c)
        for team in teams:
            member_count2[min(team.mathletes.all().count(), 9)] += 1

    context = {
        'exams': all_exams,
        'ongoing': ongoing_contests,
        'upcoming': upcoming_contests,
        'past': past_contests,
        # staff only
        'emaillist': ', '.join(all_emails),
        'prog_emails': ', '.join(prog_emails),
        'small_teams': ', '.join(small_teams),
        'member_count': member_count,
        'member_count2': member_count2,
    }
    return render(request, 'contest_list.html', context)
コード例 #7
0
ファイル: exam.py プロジェクト: CMU-Math/cmimc-online
def all_problems_math(request, user, exam):
    try:
        problems = exam.problem_list
        if user.is_mathlete:
            competitor = Competitor.objects.getCompetitor(exam, user.mathlete)

        if request.method == "POST":
            if not user.can_submit(exam):
                raise PermissionDenied(
                    "You are not allowed to submit to this problem")
            if 'save' in request.POST:
                num = request.POST['save']
                p = problems.get(problem_number=num)
                latex = request.POST[f'input-{num}']
                '''
                print('latex: ', latex)
                expr = parse_latex(latex)
                print('sympy expr: ', expr)
                print('ans latex: ', p.answer)
                ans_expr = parse_latex(p.answer)
                print('ans expr: ', ans_expr)
                '''
                '''
                signal.signal(signal.SIGALRM, handler)
                signal.alarm(5)
                try:
                    print(expr.equals(ans_expr))
                except:
                    print("timeout!")
                signal.alarm(0)
                '''

                sub = Submission(problem=p, competitor=competitor, text=latex)
                sub.save()
                score = Score.objects.get(problem=p, competitor=competitor)
                score.latest_sub = sub
                score.save()
                return redirect('all_problems', exam_id=exam.id)
            elif 'password' in request.POST:
                competitor.password = request.POST['password']
                competitor.save()
                return redirect('all_problems', exam_id=exam.id)

        prob_info = []
        for p in problems:
            score = Score.objects.get(problem=p, competitor=competitor)
            if score.latest_sub:
                text = score.latest_sub.text
            else:
                text = None
            prob_info.append({
                'p': p,
                'n': p.problem_number,
                'latest_sub': text,
            })

        context = {
            'exam':
            exam,
            'prob_info':
            prob_info,
            'can_submit':
            user.is_mathlete and competitor.password == exam.password,
            'can_enter_password':
            user.is_mathlete and exam.password != ''
            and competitor.password != exam.password,
        }
        return render(request, 'exam/all_problems_math.html', context)
    except Exception as e:
        log(ERROR=str(e), during='all_problems_math')