def __init__(self, options_configurator):
     super().__init__(
         lambda: self._bind(options_configurator),
         lambda: self._update_model(options_configurator),
         lambda: self._update_gui(options_configurator),
         lambda: self._init_gui(options_configurator)
     )
     self.serializer = BasicJsonizer([
         AddingRulesConfiguration,
         CrowdingConfiguration,
         ElitismConfiguration,
         AlgorithmConfiguration,
         RuleConfiguration,
         Symbol,
         EvolutionConfiguration,
         EvolutionOperatorConfiguration,
         EvolutionOperatorsConfiguration,
         EvolutionSelectorConfiguration,
         CoverageConfiguration,
         CoverageOperatorConfiguration,
         CoverageOperatorsConfiguration,
         CykConfiguration,
         GrammarCorrection,
         ClassicalStatisticsConfiguration,
         EvolutionRandomSelectorConfiguration,
         EvolutionTournamentSelectorConfiguration,
         EvolutionRouletteSelectorConfiguration
     ])
    def __init__(self):
        self.configuration_serializer = BasicJsonizer([
            AddingRulesConfiguration,
            CrowdingConfiguration,
            ElitismConfiguration,
            AlgorithmConfiguration,
            RuleConfiguration,
            Symbol,
            EvolutionConfiguration,
            EvolutionOperatorConfiguration,
            EvolutionOperatorsConfiguration,
            EvolutionSelectorConfiguration,
            CoverageConfiguration,
            CoverageOperatorConfiguration,
            CoverageOperatorsConfiguration,
            CykConfiguration,
            GrammarCorrection,
            ClassicalStatisticsConfiguration,
            PasiekaStatisticsConfiguration,
            EvolutionRandomSelectorConfiguration,
            EvolutionTournamentSelectorConfiguration,
            EvolutionRouletteSelectorConfiguration
        ])
        self.population_serializer = RulePopulationJsonizer(
            RulePopulationJsonizer.make_binding_map(
                [
                    RulePopulation,
                    StochasticRulePopulation
                ]
            )
        )

        self.diagram_painter = [
            GrammarCriteriaPainter('missrate'),
            GrammarCriteriaPainter('fallout'),
            GrammarCriteriaPainter('sensitivity'),
            GrammarCriteriaPainter('specificity'),
            GrammarCriteriaPainter('accuracy'),
            GrammarCriteriaPainter('precision'),
            GrammarCriteriaPainter('falseomission'),
            GrammarCriteriaPainter('falsediscovery'),
            GrammarCriteriaPainter('negpredictive')
        ]

        self.randomizer = Randomizer(Random())
class MainBoxAutoUpdater(AutoUpdater):
    def __init__(self, options_configurator):
        super().__init__(
            lambda: self._bind(options_configurator),
            lambda: self._update_model(options_configurator),
            lambda: self._update_gui(options_configurator),
            lambda: self._init_gui(options_configurator)
        )
        self.serializer = BasicJsonizer([
            AddingRulesConfiguration,
            CrowdingConfiguration,
            ElitismConfiguration,
            AlgorithmConfiguration,
            RuleConfiguration,
            Symbol,
            EvolutionConfiguration,
            EvolutionOperatorConfiguration,
            EvolutionOperatorsConfiguration,
            EvolutionSelectorConfiguration,
            CoverageConfiguration,
            CoverageOperatorConfiguration,
            CoverageOperatorsConfiguration,
            CykConfiguration,
            GrammarCorrection,
            ClassicalStatisticsConfiguration,
            EvolutionRandomSelectorConfiguration,
            EvolutionTournamentSelectorConfiguration,
            EvolutionRouletteSelectorConfiguration
        ])

    @staticmethod
    def _init_gui(options_configurator):
        pass

    def _bind(self, options_configurator):
        options_configurator.ui.buttonBox.button(QtGui.QDialogButtonBox.Reset).clicked.connect(
            lambda: self.on_reset_clicked(options_configurator))
        options_configurator.ui.buttonBox.button(QtGui.QDialogButtonBox.Save).clicked.connect(
            lambda: self.on_save_clicked(options_configurator))
        options_configurator.ui.buttonBox.button(QtGui.QDialogButtonBox.Open).clicked.connect(
            lambda: self.on_open_clicked(options_configurator))

    @staticmethod
    def on_reset_clicked(options_configurator):
        options_configurator.on_variant_changed(options_configurator.current_variant.name)

    def on_save_clicked(self, options_configurator):
        selected_filename = QtGui.QFileDialog.getSaveFileName(
            options_configurator.widget, 'Save configuration as...',
            options_configurator.last_directory, "*.parconf")

        if selected_filename:
            options_configurator.last_directory = os.path.dirname(selected_filename)
            with open(selected_filename, 'w+') as f:
                json.dump(self.serializer.to_json(options_configurator.configuration), f,
                          sort_keys=True, indent=4)

    def on_open_clicked(self, options_configurator):
        selected_filename = QtGui.QFileDialog.getOpenFileName(
            options_configurator.widget, 'Load configuration...',
            options_configurator.last_directory, "*.parconf")

        if selected_filename:
            options_configurator.last_directory = os.path.dirname(selected_filename)
            with open(selected_filename) as f:
                configuration = self.serializer.from_json(json.load(f))
            options_configurator.on_variant_changed(configuration.algorithm_variant)
            options_configurator.configuration = configuration
            options_configurator.variant_changed__reset_gui()

    @staticmethod
    def _update_model(options_configurator):
        pass

    @staticmethod
    def _update_gui(options_configurator):
        pass
class SimulationExecutor(object):
    POPULATION_EXT = ".pop"
    GRAMMAR_ESTIMATOR_EXT = ".grest"
    RUN_SUMMARY_EXT = ".txt"

    def __init__(self):
        self.configuration_serializer = BasicJsonizer([
            AddingRulesConfiguration,
            CrowdingConfiguration,
            ElitismConfiguration,
            AlgorithmConfiguration,
            RuleConfiguration,
            Symbol,
            EvolutionConfiguration,
            EvolutionOperatorConfiguration,
            EvolutionOperatorsConfiguration,
            EvolutionSelectorConfiguration,
            CoverageConfiguration,
            CoverageOperatorConfiguration,
            CoverageOperatorsConfiguration,
            CykConfiguration,
            GrammarCorrection,
            ClassicalStatisticsConfiguration,
            PasiekaStatisticsConfiguration,
            EvolutionRandomSelectorConfiguration,
            EvolutionTournamentSelectorConfiguration,
            EvolutionRouletteSelectorConfiguration
        ])
        self.population_serializer = RulePopulationJsonizer(
            RulePopulationJsonizer.make_binding_map(
                [
                    RulePopulation,
                    StochasticRulePopulation
                ]
            )
        )

        self.diagram_painter = [
            GrammarCriteriaPainter('missrate'),
            GrammarCriteriaPainter('fallout'),
            GrammarCriteriaPainter('sensitivity'),
            GrammarCriteriaPainter('specificity'),
            GrammarCriteriaPainter('accuracy'),
            GrammarCriteriaPainter('precision'),
            GrammarCriteriaPainter('falseomission'),
            GrammarCriteriaPainter('falsediscovery'),
            GrammarCriteriaPainter('negpredictive')
        ]

        self.randomizer = Randomizer(Random())

    def prepare_simulation(self, runner, task_no, data_path, config_path, population_path=None):
        with open(config_path) as f:
            configuration = self.configuration_serializer.from_json(json.load(f))

        is_stochastic = configuration.algorithm_variant == AlgorithmVariant.sgcs
        algorithm_variant = CykServiceVariationManager(is_stochastic)
        learning_set_path, testing_set_path = self.load_input_config(data_path)

        learning_set = SymbolTranslator.create(learning_set_path)
        learning_set.negative_allowed = configuration.statistics.negative_sentence_learning

        testing_set = SymbolTranslator.create(testing_set_path)
        testing_set.negative_allowed = True

        return (lambda conf: self._perform_simulation(
            algorithm_variant, learning_set, testing_set, conf, runner, task_no, population_path),
            configuration,
            self._mk_population_printer(learning_set)
        )

    @staticmethod
    def _mk_population_printer(translator):
        return lambda x: translator.rule_population_to_string(x)

    def _perform_simulation(self, algorithm_variant, learning_set, testing_set, configuration,
                            runner, task_no, population_path=None):
        algorithm_simulator = PyQtAwareAsyncGcsSimulator(self.randomizer, algorithm_variant,
                                                         task_no, runner.input_queue)
        if population_path is not None:
            pop_path = os.path.dirname(population_path)
            pop_name = os.path.basename(population_path).split('.')[0]
            starting_pop = self.load_population(pop_path, pop_name, starting_symbol=Symbol(1))
            starting_rules = list(starting_pop.get_all_non_terminal_rules())
            starting_rules += starting_pop.get_terminal_rules()
        else:
            starting_rules = []

        result, ngen, gener_grammar_estimator, population, grammar_estimator = \
            algorithm_simulator.perform_simulation(learning_set, testing_set, configuration,
                                                   starting_rules=starting_rules)

        return result, ngen, grammar_estimator, population, gener_grammar_estimator

    @staticmethod
    def _artifact_file(path, name, extension, mode='r'):
        return open(os.path.join(path, name + extension), mode)

    def save_population(self, rule_population, population_printer, path, name):
        self.save_population_data(rule_population, path, name)
        with self._artifact_file(path, name + '_view', self.RUN_SUMMARY_EXT, 'w+') as pop_view_file:
            pop_view_file.write('{0}\n'.format(population_printer(rule_population)))

    def save_population_data(self, rule_population, path, name):
        serialized_population = self.population_serializer.to_json(rule_population)
        with self._artifact_file(path, name, self.POPULATION_EXT, 'w+') as pop_file:
            json.dump(serialized_population, pop_file, sort_keys=True, indent=4)

    def load_population(self, path, name, *pop_args, **pop_kwargs):
        with self._artifact_file(path, name, self.POPULATION_EXT) as pop_file:
            serialized_population = json.load(pop_file)
            return self.population_serializer.from_json(serialized_population,
                                                        self.randomizer, *pop_args, **pop_kwargs)

    def save_grammar_estimator(self, grammar_estimator, path, name):
        serialized_grammar_estimator = grammar_estimator.json_coder()
        with self._artifact_file(path, name, self.GRAMMAR_ESTIMATOR_EXT, 'w+') as est_file:
            json.dump(serialized_grammar_estimator, est_file, sort_keys=True, indent=4)

    @staticmethod
    def load_input_config(config_path):
        with open(config_path) as file:
            deserialized = json.loads('\n'.join(file.readlines()))

            return deserialized['learning'], deserialized['testing']

    def save_execution_summary(self, run_estimator, ngen, generalisation_data, path, name):
        with self._artifact_file(path, name, self.RUN_SUMMARY_EXT, 'w+') as summary_f:
            summary_f.write('{0}\n'.format(run_estimator))
            summary_f.write('Ngen: {0}\n'.format(ngen))

            for criteria, value in generalisation_data.criterias.items():
                summary_f.write('{0}: {1}\n'.format(criteria, value.get(0)))

    def generate_grammar_estimation_diagrams(self, grammar_estimator, path, configuration):
        for painter in self.diagram_painter:
            painter.paint(grammar_estimator, path, configuration)