code: def _generic_binary_op(self, other, op):
          
          output = {}
          if isinstance(other, TimeSeries):
              for key, value in self.items():
                  if key in other:
                      try:
                          result = op(value, other[key])
                          if result is NotImplemented:
                              other_type = type(other[key])
                              other_op = vars(other_type).get(op.__name__)
                              if other_op:
                                  output[key] = other_op(other_type(value), other[key])
                          else:
                              output[key] = result
                      except ZeroDivisionError:
                          continue
          else:
              for key, value in self.items():
                  try:
                      result = op(value, other)
                      if result is NotImplemented:
                          other_type = type(other)
                          other_op = vars(other_type).get(op.__name__)
                          if other_op:
                              output[key] = other_op(other_type(value), other)
                      else:
                          output[key] = result
                  except ZeroDivisionError:
                      continue
  
          if output:
              return TimeSeries(output)
          else:
              raise ValueError('TimeSeries data was empty or invalid.')
docs: Perform the method operation specified in the op parameter on the values
          within the instance's time series values and either another time series
          or a constant number value.
  
          :param other: Time series of values or a constant number to use in calculations with instance's time series.
          :param func op: The method to perform the calculation between the values.
          :return: :class:`TimeSeries` object.