class_docstr: Abstract class :class:`Reporter` for result visualisation.
docstr: Helper function to convert the history entry from tuple to
  :class:`HistoryPoint` and then log it using the overridden method
  :method:`_log_history_point`.
docstr_tok: ["Helper","function","to","convert","the","history","entry","from","tuple","to",":","class",":","`","HistoryPoint","`","and","then","log","it","using","the","overridden","method",":","method",":","`","_log_history_point","`","."]
code: def _log_tuple(self, entry: Tuple, **kwargs):
      """Helper function to convert the history entry from tuple to
      :class:`HistoryPoint` and then log it using the overridden method
      :method:`_log_history_point`.
      """
      if not (
          len(entry) == 2
          and isinstance(entry[0], Sample)
          and isinstance(entry[1], (Dict, EvaluationScore, float))
      ):
          raise ValueError(f"Malformed history entry tuple: {entry}.")
      sample, metrics_obj = entry
      if isinstance(metrics_obj, (float, EvaluationScore)):
          # use default name for score column
          metrics_obj = {self.primary_metric: metrics_obj}
      metrics = {}
      # create a properly formatted metrics dict of type Dict[str, EvaluationScore]
      for name, val in metrics_obj.items():
          if name in metrics:
              continue
          if name.endswith("_var"):
              metric_name = name.rstrip("_var")
              if metric_name not in metrics_obj or not isinstance(
                  metrics_obj[metric_name], float
              ):
                  raise ValueError(
                      f"Metrics dict does not contain a proper value "
                      f"for metric {metric_name}."
                  )
              metrics[metric_name] = EvaluationScore(
                  value=metrics_obj[metric_name], variance=val
              )
          elif isinstance(val, EvaluationScore):
              metrics[name] = val
          elif isinstance(val, float):
              metrics[name] = EvaluationScore(
                  value=val,
                  variance=metrics_obj.get(f"{name}_var", 0.0),
              )
      entry = HistoryPoint(sample=sample, metrics=metrics)
      self._add_to_db(entry, kwargs.pop("meta", None))
      self._log_history_point(entry, **kwargs)
  
imports: import abc
  import datetime
  import os
  from typing import Any, Callable, Dict, List, Optional, Tuple, Union
  import tinydb
  from hypertunity.domain import Domain, Sample
  from hypertunity.optimisation.base import EvaluationScore, HistoryPoint
label_desc: Use image node_id 5 for calling the Reporter obj's underlying member method code with example usage: obj._log_tuple(entry) without return types