def GetDistToWrappedLimits(value, start_limit, end_limit,
                           wrap_left, wrap_right):
  """Returns value for min distance from value to limits on wrapped scale.

  Arguments:
    value: Value to be evaluated. Can be list-like or single value. Values must
      be between wrap_left and wrap_right.
    start_limit: The beginning of a range on wrapped scale.
    end_limit: The end of a range on wrapped scale.
    wrap_left: Minimum value for wrapping scale.
    wrap_right: Maximum value for wrapping scale.
  Returns:
    Minimum distance that value is from range limits.
    Positive values indicate value is between range specified by start_limit
    and end_limit. Negative values indicate value is outside of range.
  """
  wrap_range = wrap_right - wrap_left

  if not hasattr(value, '__iter__'):
    value = [value]

  # Unwrap end limit if needed so limits are in order.
  if end_limit < start_limit:
    end_limit_ordered = end_limit + wrap_range
  else:
    end_limit_ordered = end_limit

  for ii, v in enumerate(value):
    assert v >= wrap_left and v <= wrap_right, (
        'Values must be between wrap_left and wrap_right.')

    if end_limit < start_limit and v < end_limit:
      # If limits go around wrap and value was in limits before wrap,
      # unwrap value.
      v += wrap_range

    if v > start_limit and v < end_limit_ordered:
      # If inside the bad range, give positive value
      value[ii] = min(abs(v - start_limit),
                      abs(v - end_limit_ordered))
    else:
      # If outside bad range, give negative value.
      value[ii] = -min(abs(v - start_limit),
                       abs(v - end_limit_ordered),
                       # Also check wrapped values to limits.
                       abs(v + wrap_range - end_limit_ordered),
                       abs(v - wrap_range - start_limit))

  if len(value) == 1:
    return value[0]
  else:
    return value