# Path: marathoner/contest/base.py
# class BaseContest(object):
#     '''BaseContest is an abstract class for contest-specific modifications to
#     Marathoner.
#     '''
#     def __init__(self, project):
#         self.project = project
#         self.maximize = project.maximize
# 
#     def extract_score(self, visualizer_stdout, solution_stderr):
#         '''Extract raw score and return it.
# 
#         @param visualizer_stdout: output received from visualizer's stdout
#         @type visualizer_stdout: list of lines
# 
#         @param solution_stderr: output received from solution's stderr
#         @type solution_stderr: list of lines
#         '''
#         raise NotImplementedError()
# 
#     # single-test callbacks
#     def single_test_starting(self, seed):
#         '''Called before running the single test.'''
#         raise NotImplementedError()
# 
#     def single_test_ending(self, seed, visualizer_stdout, solution_stderr,
#                            best_score, current_score):
#         '''Called after the single test *successfully* finished.
# 
#         @param best_score: best score for the current test. Updated with the
#                            `current_score` already.
#         @type best_score: Score
# 
#         @param current_score: score for the current test
#         @type current_score: Score
#         '''
#         raise NotImplementedError()
# 
#     # multi-test callbacks
#     def multiple_tests_starting(self, num_tests):
#         '''Called before running the batch of tests.
# 
#         @param num_tests: number of tests to be run.
#         '''
#         raise NotImplementedError()
# 
#     def one_test_starting(self, seed):
#         '''Called before running the test from the batch.'''
#         raise NotImplementedError()
# 
#     def one_test_ending(self, seed, visualizer_stdout, solution_stderr,
#                         best_score, current_score):
#         '''Called after the test from the batch *successfully* finished.'''
#         raise NotImplementedError()
# 
#     def multiple_tests_ending(self, num_tests):
#         '''Called after running the batch of tests.
# 
#         @param num_tests: number of tests that actually ran. Can be lower
#                           than number of tests sent to `multiple_tests_starting()`,
#                           if user kills execution.
#                           Basically it is number of times `one_test_ending()`
#                           was called.
#         '''
#         raise NotImplementedError()
# 
# Path: marathoner/scores.py
# class Score(object):
#     '''Encapsulates score and run-time of the single test.'''
#     def __init__(self, seed, score, run_time=None):
#         self.seed = int(seed)
#         self.score = float(score)
#         self.run_time = float(run_time or 0.0)
# 
#     def __str__(self):
#         return '<Test-%s Score: %s Run time: %s>' % (self.seed, self.score, self.time)
# 
#     @classmethod
#     def better(cls, maximize, score1, score2):
#         '''Return better of the two scores.'''
#         # zero score is always bad
#         if not score1.score:
#             return score2
#         if not score2.score:
#             return score1
# 
#         # for the same score, compare run times
#         if score1.score == score2.score:
#             if not score1.run_time:
#                 return score2
#             if not score2.run_time:
#                 return score1
#             return score1 if score1.run_time < score2.run_time else score2
# 
#         if maximize == (score1.score > score2.score):
#             return score1
#         else:
#             return score2
# 
#     @classmethod
#     def relative_score(cls, maximize, current_score, best_score):
#         if not current_score.score:
#             return 0.0
#         if maximize:
#             return current_score.score / max(best_score.score, best_score.score)
#         else:
#             return min(best_score.score, current_score.score) / current_score.score


from itertools import chain
from six import print_
from marathoner.contest.base import BaseContest
from marathoner.scores import Score
import re
        print_('\tNew score: %.2f' % current_score.score)
        if seed:
            if self.old_best_score and best_score.score != self.old_best_score:
                print_('\tBest score: %.2f (old: %.2f)' % (best_score.score, self.old_best_score))
            else:
                print_('\tBest score: %.2f' % best_score.score)
            print_('\tRelative score: %.5f' % Score.relative_score(self.maximize, current_score, best_score))


    def multiple_tests_starting(self, num_tests):
        tag = self.project.current_tag
        if tag:
            print_('Running %s tests with tag "%s"...' % (num_tests, tag.name))
        else:
            print_('Running %s tests...' % num_tests)
        log_filename = self.project.data_path('multiple_tests.log')
        self.log_file = open(log_filename, 'w')
        self.score_sum = 0.0
        self.zero_seeds = []

        self._write_line(self.hline)
        self._write_line(self.row_format % self.header)
        self._write_line(self.hline)

    def one_test_starting(self, seed):
        pass

    def one_test_ending(self, seed, visualizer_stdout, solution_stderr, best_score, current_score):
        if not current_score.score:
            self.zero_seeds.append(seed)

# Path: marathoner/contest/base.py
# class BaseContest(object):
#     '''BaseContest is an abstract class for contest-specific modifications to
#     Marathoner.
#     '''
#     def __init__(self, project):
#         self.project = project
#         self.maximize = project.maximize
# 
#     def extract_score(self, visualizer_stdout, solution_stderr):
#         '''Extract raw score and return it.
# 
#         @param visualizer_stdout: output received from visualizer's stdout
#         @type visualizer_stdout: list of lines
# 
#         @param solution_stderr: output received from solution's stderr
#         @type solution_stderr: list of lines
#         '''
#         raise NotImplementedError()
# 
#     # single-test callbacks
#     def single_test_starting(self, seed):
#         '''Called before running the single test.'''
#         raise NotImplementedError()
# 
#     def single_test_ending(self, seed, visualizer_stdout, solution_stderr,
#                            best_score, current_score):
#         '''Called after the single test *successfully* finished.
# 
#         @param best_score: best score for the current test. Updated with the
#                            `current_score` already.
#         @type best_score: Score
# 
#         @param current_score: score for the current test
#         @type current_score: Score
#         '''
#         raise NotImplementedError()
# 
#     # multi-test callbacks
#     def multiple_tests_starting(self, num_tests):
#         '''Called before running the batch of tests.
# 
#         @param num_tests: number of tests to be run.
#         '''
#         raise NotImplementedError()
# 
#     def one_test_starting(self, seed):
#         '''Called before running the test from the batch.'''
#         raise NotImplementedError()
# 
#     def one_test_ending(self, seed, visualizer_stdout, solution_stderr,
#                         best_score, current_score):
#         '''Called after the test from the batch *successfully* finished.'''
#         raise NotImplementedError()
# 
#     def multiple_tests_ending(self, num_tests):
#         '''Called after running the batch of tests.
# 
#         @param num_tests: number of tests that actually ran. Can be lower
#                           than number of tests sent to `multiple_tests_starting()`,
#                           if user kills execution.
#                           Basically it is number of times `one_test_ending()`
#                           was called.
#         '''
#         raise NotImplementedError()
# 
# Path: marathoner/scores.py
# class Score(object):
#     '''Encapsulates score and run-time of the single test.'''
#     def __init__(self, seed, score, run_time=None):
#         self.seed = int(seed)
#         self.score = float(score)
#         self.run_time = float(run_time or 0.0)
# 
#     def __str__(self):
#         return '<Test-%s Score: %s Run time: %s>' % (self.seed, self.score, self.time)
# 
#     @classmethod
#     def better(cls, maximize, score1, score2):
#         '''Return better of the two scores.'''
#         # zero score is always bad
#         if not score1.score:
#             return score2
#         if not score2.score:
#             return score1
# 
#         # for the same score, compare run times
#         if score1.score == score2.score:
#             if not score1.run_time:
#                 return score2
#             if not score2.run_time:
#                 return score1
#             return score1 if score1.run_time < score2.run_time else score2
# 
#         if maximize == (score1.score > score2.score):
#             return score1
#         else:
#             return score2
# 
#     @classmethod
#     def relative_score(cls, maximize, current_score, best_score):
#         if not current_score.score:
#             return 0.0
#         if maximize:
#             return current_score.score / max(best_score.score, best_score.score)
#         else:
#             return min(best_score.score, current_score.score) / current_score.score


# Path: marathoner/contest/simple.py
from itertools import chain
from six import print_
from marathoner.contest.base import BaseContest
from marathoner.scores import Score
import re

        print_('\tNew score: %.2f' % current_score.score)
        if seed:
            if self.old_best_score and best_score.score != self.old_best_score:
                print_('\tBest score: %.2f (old: %.2f)' % (best_score.score, self.old_best_score))
            else:
                print_('\tBest score: %.2f' % best_score.score)
            print_('\tRelative score: %.5f' % Score.relative_score(self.maximize, current_score, best_score))


    def multiple_tests_starting(self, num_tests):
        tag = self.project.current_tag
        if tag:
            print_('Running %s tests with tag "%s"...' % (num_tests, tag.name))
        else:
            print_('Running %s tests...' % num_tests)
        log_filename = self.project.data_path('multiple_tests.log')
        self.log_file = open(log_filename, 'w')
        self.score_sum = 0.0
        self.zero_seeds = []

        self._write_line(self.hline)
        self._write_line(self.row_format % self.header)
        self._write_line(self.hline)

    def one_test_starting(self, seed):
        pass

    def one_test_ending(self, seed, visualizer_stdout, solution_stderr, best_score, current_score):
        if not current_score.score:
            self.zero_seeds.append(seed)

        relative = Score.relative_score(self.maximize, current_score, best_score)