fork download
  1. import re
  2.  
  3. class Interval:
  4. def __init__(self, interval):
  5. """Initialize an Interval object from a string representation of an interval
  6. e.g: Interval('(3,4]')"""
  7. if isinstance(interval, Interval):
  8. self.begin, self.end = interval.begin, interval.end
  9. self.begin_included = interval.begin_included
  10. self.end_included = interval.end_included
  11. return
  12. number_re = '-?[0-9]+(?:.[0-9]+)?'
  13. interval_re = ('^\s*'
  14. +'(\[|\()' # opeing brecket
  15. + '\s*'
  16. + '(' + number_re + ')' # beginning of the interval
  17. + '\s*,\s*'
  18. + '(' + number_re + ')' # end of the interval
  19. + '\s*'
  20. + '(\]|\))' # closing brecket
  21. + '\s*$'
  22. )
  23. match = re.search(interval_re, interval)
  24. if match is None:
  25. raise ValueError('Got an incorrect string representation of an interval: {!r}'. format(interval))
  26. opening_brecket, begin, end, closing_brecket = match.groups()
  27. self.begin, self.end = float(begin), float(end)
  28. if self.begin >= self.end:
  29. raise ValueError("Interval's begin shoud be smaller than it's end")
  30. self.begin_included = opening_brecket == '['
  31. self.end_included = closing_brecket == ']'
  32. # It might have been batter to use number_re = '.*' and catch exeptions float() raises instead
  33.  
  34. def __repr__(self):
  35. return 'Interval({!r})'.format(str(self))
  36.  
  37. def __str__(self):
  38. opening_breacket = '[' if self.begin_included else '('
  39. closing_breacket = ']' if self.end_included else ')'
  40. return '{}{}, {}{}'.format(opening_breacket, self.begin, self.end, closing_breacket)
  41.  
  42. def __contains__(self, number):
  43. if self.begin < number < self.end:
  44. return True
  45. if number == self.begin:
  46. return self.begin_included
  47. if number == self.end:
  48. return self.end_included
  49.  
  50.  
  51. for interval in ('(4,5]', '[-10,4)', '', 'foo', '(foo', '(10]', '()', '(4.0, 5.7]', '[5,-5]'):
  52. print('Interval(', repr(interval), ') = ')
  53. try:
  54. print(repr(Interval(interval)))
  55. except BaseException as e:
  56. print(repr(e))
  57.  
  58. for interval in ('(-5, 8)', '[5, 8]', '(5, 8]', '[-3, 5]', '[-3, 5)'):
  59. interval = Interval(interval)
  60. print(5, 'in', interval, '=', 5 in interval)
  61.  
  62.  
  63. def foo(interval, bar, baz):
  64. interval = Interval(interval)
  65. print(repr(interval))
  66.  
  67. foo('[-1, 5)', 42, True)
  68. foo(Interval('[-1,5)'), 42, True)
Success #stdin #stdout 0.01s 9992KB
stdin
Standard input is empty
stdout
Interval( '(4,5]' ) = 
Interval('(4.0, 5.0]')
Interval( '[-10,4)' ) = 
Interval('[-10.0, 4.0)')
Interval( '' ) = 
ValueError("Got an incorrect string representation of an interval: ''",)
Interval( 'foo' ) = 
ValueError("Got an incorrect string representation of an interval: 'foo'",)
Interval( '(foo' ) = 
ValueError("Got an incorrect string representation of an interval: '(foo'",)
Interval( '(10]' ) = 
ValueError("Got an incorrect string representation of an interval: '(10]'",)
Interval( '()' ) = 
ValueError("Got an incorrect string representation of an interval: '()'",)
Interval( '(4.0, 5.7]' ) = 
Interval('(4.0, 5.7]')
Interval( '[5,-5]' ) = 
ValueError("Interval's begin shoud be smaller than it's end",)
5 in (-5.0, 8.0) = True
5 in [5.0, 8.0] = True
5 in (5.0, 8.0] = False
5 in [-3.0, 5.0] = True
5 in [-3.0, 5.0) = False
Interval('[-1.0, 5.0)')
Interval('[-1.0, 5.0)')