docs: def eval_conditions(conditions=None, data={}):
      '''
      Evaluates conditions and returns Boolean value.
  
      Args:
          conditions (tuple) for the format of the tuple, see below
          data (dict) the keys of which can be used in conditions
      Returns:
          (boolea)
      Raises:
          ValueError if an invalid operator value is specified
          TypeError if: 
                  conditions are not a 3-item tuple
                  the arguments of the condition don't have the same type
                      e.g. ('abc', 'eq', 3)
                  if a boolean operator does not get boolean arguments
                      e.g. (True, 'and', 15)
  
      The format of the condition tuple is:
          (arg1, op, arg2)
      where:
          arg1, arg2 can be numerical values, strings or condition tuples
          op is a valid operator from the operator module
      If arg is a string, and the string is a key in <data> it is treated as
      a variable with value data[arg].
  
      Notes:
          * If no conditions are specified True is returned.
          * empty or 0 values do *not* evaluate to booleans
      '''
  #CONSIDER: implementing addition/subtraction/multiplication/division
      if not conditions:
          return True
      if isinstance(conditions, str) or isinstance(conditions, unicode):
          conditions = str2tuple(conditions)
      if not isinstance(conditions, tuple) or not len(conditions) == 3:
          raise TypeError('conditions must be a tuple with 3 items.')
      arg1 = conditions[0]
      op = conditions[1]
      arg2 = conditions[2]
      if arg1 in data:
          arg1 = data[arg1]
      elif isinstance(arg1, tuple):
          arg1 = eval_conditions(arg1, data)
      if arg2 in data:
          arg2 = data[arg2]
      elif isinstance(arg2, tuple):
          arg2 = eval_conditions(arg2, data)
      if op in ('lt', 'le', 'eq', 'ne', 'ge', 'gt'):
          if not (type(arg1) in (float, int) and type(arg2) in (float,int)) and \
                  type(arg1) != type(arg2):
              raise TypeError('both arguments must have the same type {}, {}'.\
                      format(arg1, arg2))
      elif op in ('and', 'or'):
          if not isinstance(arg1, bool) or not isinstance(arg2, bool):
              raise TypeError('boolean operator {} needs boolean arguments {},'\
                      ' {}'.format(op, arg1, arg2))
          op += '_'
      else:
          raise ValueError('operator {} not supported', op)
      return getattr(operator, op)(arg1, arg2)