# Buggy code
def add(
    self, config, cost, time, status, instance_id=None, seed=None, additional_info=None
):
    """
    adds a data of a new target algorithm (TA) run;
    it will update data if the same key values are used
    (config, instance_id, seed)

    Attributes
    ----------
        config : dict (or other type -- depending on config space module)
            parameter configuratoin
        cost: float
            cost of TA run (will be minimized)
        time: float
            runtime of TA run
        status: str
            status in {SUCCESS, TIMEOUT, CRASHED, ABORT, MEMOUT}
        instance_id: str
            str representing an instance (default: None)
        seed: int
            random seed used by TA (default: None)
        additional_info: dict
            additional run infos (could include further returned
            information from TA or fields such as start time and host_id)
    """

    # TODO: replace str casting of config when we have something hashable
    # as a config object
    # TODO JTS: We might have to execute one config multiple times
    #           since the results can be noisy and then we can't simply
    #           overwrite the old config result here!
    config_id = self.config_ids.get(config.__repr__())
    if config_id is None:
        self._n_id += 1
        self.config_ids[config.__repr__()] = self._n_id
        config_id = self.config_ids.get(config.__repr__())
        self.ids_config[self._n_id] = config

    k = self.RunKey(config_id, instance_id, seed)
    v = self.RunValue(cost, time, status, additional_info)

    self.data[k] = v


# Traceback (KeyError)
KeyError                                  Traceback (most recent call last)
<ipython-input-10-a9f6024df581> in <module>()
38 smbo = SMBO(scenario=scenario, rng=1, tae_runner=taf)
39 Stats.scenario = scenario
---> 40 smbo.run(max_iters=100)
41
42 print("Final Incumbent: %s" % (smbo.incumbent))

/home/feurerm/virtualenvs/ml2016/local/lib/python2.7/site-packages/smac/smbo/smbo.pyc in run(self, max_iters)
291                 run_history=self.runhistory,
292                 objective=self.objective,
--> 293                 time_bound=max(0.01, time_spend))
294
295             # TODO: Write run history into database

/home/feurerm/virtualenvs/ml2016/local/lib/python2.7/site-packages/smac/smbo/intensification.pyc in intensify(self, challengers, incumbent, run_history, objective, time_bound)
226                 chall_inst_seeds = set(map(lambda x: (
227                     x.instance, x.seed), run_history.get_runs_for_config(challenger)))
--> 228                 chal_perf = objective(challenger, run_history, chall_inst_seeds)
229                 run_history.update_cost(challenger, chal_perf)
230

/home/feurerm/virtualenvs/ml2016/local/lib/python2.7/site-packages/smac/smbo/objective.pyc in average_cost(config, run_history, instance_seed_pairs)
116     float
117     """
--> 118     return np.mean(_cost(config, run_history, instance_seed_pairs))
119
120 def sum_cost(config, run_history, instance_seed_pairs=None):

/home/feurerm/virtualenvs/ml2016/local/lib/python2.7/site-packages/smac/smbo/objective.pyc in _cost(config, run_history, instance_seed_pairs)
93     for i, r in instance_seed_pairs:
94         k = run_history.RunKey(id_, i, r)
---> 95         costs.append(run_history.data[k].cost)
96     return costs
97

KeyError: RunKey(config_id=36, instance_id='2', seed=931243971)

# Fixed code
def add(
    self, config, cost, time, status, instance_id=None, seed=None, additional_info=None
):
    """
    adds a data of a new target algorithm (TA) run;
    it will update data if the same key values are used
    (config, instance_id, seed)

    Attributes
    ----------
        config : dict (or other type -- depending on config space module)
            parameter configuratoin
        cost: float
            cost of TA run (will be minimized)
        time: float
            runtime of TA run
        status: str
            status in {SUCCESS, TIMEOUT, CRASHED, ABORT, MEMOUT}
        instance_id: str
            str representing an instance (default: None)
        seed: int
            random seed used by TA (default: None)
        additional_info: dict
            additional run infos (could include further returned
            information from TA or fields such as start time and host_id)
    """

    config_id = self.config_ids.get(config)
    if config_id is None:
        self._n_id += 1
        self.config_ids[config] = self._n_id
        config_id = self.config_ids.get(config)
        self.ids_config[self._n_id] = config

    k = self.RunKey(config_id, instance_id, seed)
    v = self.RunValue(cost, time, status, additional_info)

    self.data[k] = v