def simulate_submissions(self, submissions): """ Submissions is a list of tuples: (ctask, date, action, expected_score_triple), Action can be: True -> sending a correct solution False -> sending an incorrect solution int x -> ID of the solution (assume 1-based). """ team = self.team for index, test_case in enumerate(submissions): try: ctask, date, action, expected_score_triple = test_case if isinstance(action, bool): is_correct = action result = "42" if is_correct else "0" submission = Submission.objects.create(ctask=ctask, team=team, date=date, result=result, cache_is_correct=is_correct) update_score_on_ctask_action(self.competition, team, self.chain, ctask, submission, False) else: # Raise an exception if not found. submission = Submission.objects.get(id=action) submission.delete() update_score_on_ctask_action(self.competition, team, self.chain, ctask, None, True) score_triple = (team.cache_score_before_freeze, team.cache_score, team.cache_max_score_after_freeze) refresh_teams_cache_score([team]) score_triple = (team.cache_score_before_freeze, team.cache_score, team.cache_max_score_after_freeze) self.assertEqual(score_triple, expected_score_triple) except: print "Test case #{}: {}".format(index, test_case) raise
def task_detail(request, competition, data, ctask_id): is_admin = data['is_admin'] extra = ['task__author'] if is_admin else [] ctask = get_object_or_404( CompetitionTask.objects.select_related('chain', 'task', 'task__content', *extra), competition=competition, id=ctask_id) ctask_id = int(ctask_id) team = data['team'] if not is_admin: if (not team and not data['has_finished']) or not data['has_started'] \ or ctask.chain.unlock_minutes > data['minutes_passed']: raise Http404 if ctask.score > 1: ctask.t_score_text = ungettext( "This task is worth %d point.", "This task is worth %d points.", ctask.score) % ctask.score evaluator = get_evaluator(competition.evaluator_version) variables = safe_parse_descriptor(evaluator, ctask.descriptor) if team: ctasks, chain_submissions = preprocess_chain( competition, ctask.chain, team, preloaded_ctask=ctask) submissions = [x for x in chain_submissions if x.ctask_id == ctask_id] submissions.sort(key=lambda x: x.date) if data['has_finished']: ctask.t_is_locked = False if ctask.t_is_locked and not is_admin: raise Http404 if request.method == 'POST' and (not data['has_finished'] or is_admin): solution_form = CompetitionSolutionForm(request.POST, descriptor=ctask.descriptor, evaluator=evaluator) submission = None delete = False if is_admin and 'delete-submission' in request.POST: try: submission = Submission.objects.get( id=request.POST['delete-submission']) chain_submissions = \ [x for x in chain_submissions if x != submission] submissions = [x for x in submissions if x != submission] submission.delete() delete = True except Submission.DoesNotExist: pass elif solution_form.is_valid(): # TODO: Ignore submission if already correctly solved. if len(submissions) < ctask.max_submissions: result = solution_form.cleaned_data['result'] is_correct = evaluator.check_result( ctask.descriptor, result) submission = Submission(ctask=ctask, team=team, result=result, cache_is_correct=is_correct) submission.save() chain_submissions.append(submission) submissions.append(submission) if delete or submission: if is_admin and team.is_admin_private(): update_ctask_cache_admin_solved_count( competition, ctask, ctask.chain) update_score_on_ctask_action(competition, team, ctask.chain, ctask, submission, delete, chain_ctask_ids=[x.id for x in ctasks], chain_submissions=chain_submissions) # Prevent form resubmission. return (ctask.get_absolute_url(), ) else: solution_form = CompetitionSolutionForm( descriptor=ctask.descriptor, evaluator=evaluator) data['is_solved'] = any(x.cache_is_correct for x in submissions) data['solution_form'] = solution_form data['submissions'] = submissions data['submissions_left'] = ctask.max_submissions - len(submissions) if is_admin: data['all_ctask_submissions'] = list(Submission.objects \ .filter(ctask_id=ctask_id) \ .select_related('team') \ .order_by('id')) for submission in data['all_ctask_submissions']: submission.team.competition = competition data['help_text'] = get_solution_help_text(variables) data['chain'] = ctask.chain data['ctask'] = ctask if competition.show_solutions and data['has_finished'] \ and not data.get('is_solved', False): data['sample_solution'] = get_sample_solution(variables) return data