import re

class Interval:
    def __init__(self, interval):
        """Initialize an Interval object from a string representation of an interval
           e.g: Interval('(3,4]')"""
        if isinstance(interval, Interval):
        	self.begin, self.end = interval.begin, interval.end
        	self.begin_included = interval.begin_included
        	self.end_included = interval.end_included
        	return
        number_re = '-?[0-9]+(?:.[0-9]+)?'
        interval_re = ('^\s*'
        	           +'(\[|\()'  # opeing brecket
                       + '\s*'
                       + '(' + number_re + ')'  # beginning of the interval
                       + '\s*,\s*'
                       + '(' + number_re + ')'  # end of the interval
                       + '\s*'
                       + '(\]|\))'  # closing brecket
                       + '\s*$'
                      )
        match = re.search(interval_re, interval)
        if match is None:
        	raise ValueError('Got an incorrect string representation of an interval: {!r}'. format(interval))
        opening_brecket, begin, end, closing_brecket = match.groups()
        self.begin, self.end = float(begin), float(end)
        if self.begin >= self.end:
        	raise ValueError("Interval's begin shoud be smaller than it's end")
        self.begin_included = opening_brecket == '['
        self.end_included = closing_brecket == ']'
        # It might have been batter to use number_re = '.*' and catch exeptions float() raises instead
        
    def __repr__(self):
        return 'Interval({!r})'.format(str(self))
        
    def __str__(self):
    	opening_breacket = '[' if self.begin_included else '('
    	closing_breacket = ']' if self.end_included else ')'
    	return '{}{}, {}{}'.format(opening_breacket, self.begin, self.end, closing_breacket)
    	
    def __contains__(self, number):
    	if self.begin < number < self.end:
    		return True
    	if number == self.begin:
    		return self.begin_included
    	if number == self.end:
    		return self.end_included
    	
            
for interval in ('(4,5]', '[-10,4)', '', 'foo', '(foo', '(10]', '()', '(4.0, 5.7]', '[5,-5]'):
    print('Interval(', repr(interval), ') = ')
    try:
        print(repr(Interval(interval)))
    except BaseException as e:
        print(repr(e))
    	
for interval in ('(-5, 8)', '[5, 8]', '(5, 8]', '[-3, 5]', '[-3, 5)'):
    interval = Interval(interval)
    print(5, 'in', interval, '=', 5 in interval)
    
   
def foo(interval, bar, baz):
	interval = Interval(interval)
	print(repr(interval))
	
foo('[-1, 5)', 42, True)
foo(Interval('[-1,5)'), 42, True)