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)
aW1wb3J0IHJlCgpjbGFzcyBJbnRlcnZhbDoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBpbnRlcnZhbCk6CiAgICAgICAgIiIiSW5pdGlhbGl6ZSBhbiBJbnRlcnZhbCBvYmplY3QgZnJvbSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhbiBpbnRlcnZhbAogICAgICAgICAgIGUuZzogSW50ZXJ2YWwoJygzLDRdJykiIiIKICAgICAgICBpZiBpc2luc3RhbmNlKGludGVydmFsLCBJbnRlcnZhbCk6CiAgICAgICAgCXNlbGYuYmVnaW4sIHNlbGYuZW5kID0gaW50ZXJ2YWwuYmVnaW4sIGludGVydmFsLmVuZAogICAgICAgIAlzZWxmLmJlZ2luX2luY2x1ZGVkID0gaW50ZXJ2YWwuYmVnaW5faW5jbHVkZWQKICAgICAgICAJc2VsZi5lbmRfaW5jbHVkZWQgPSBpbnRlcnZhbC5lbmRfaW5jbHVkZWQKICAgICAgICAJcmV0dXJuCiAgICAgICAgbnVtYmVyX3JlID0gJy0/WzAtOV0rKD86LlswLTldKyk/JwogICAgICAgIGludGVydmFsX3JlID0gKCdeXHMqJwogICAgICAgIAkgICAgICAgICAgICsnKFxbfFwoKScgICMgb3BlaW5nIGJyZWNrZXQKICAgICAgICAgICAgICAgICAgICAgICArICdccyonCiAgICAgICAgICAgICAgICAgICAgICAgKyAnKCcgKyBudW1iZXJfcmUgKyAnKScgICMgYmVnaW5uaW5nIG9mIHRoZSBpbnRlcnZhbAogICAgICAgICAgICAgICAgICAgICAgICsgJ1xzKixccyonCiAgICAgICAgICAgICAgICAgICAgICAgKyAnKCcgKyBudW1iZXJfcmUgKyAnKScgICMgZW5kIG9mIHRoZSBpbnRlcnZhbAogICAgICAgICAgICAgICAgICAgICAgICsgJ1xzKicKICAgICAgICAgICAgICAgICAgICAgICArICcoXF18XCkpJyAgIyBjbG9zaW5nIGJyZWNrZXQKICAgICAgICAgICAgICAgICAgICAgICArICdccyokJwogICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgIG1hdGNoID0gcmUuc2VhcmNoKGludGVydmFsX3JlLCBpbnRlcnZhbCkKICAgICAgICBpZiBtYXRjaCBpcyBOb25lOgogICAgICAgIAlyYWlzZSBWYWx1ZUVycm9yKCdHb3QgYW4gaW5jb3JyZWN0IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhbiBpbnRlcnZhbDogeyFyfScuIGZvcm1hdChpbnRlcnZhbCkpCiAgICAgICAgb3BlbmluZ19icmVja2V0LCBiZWdpbiwgZW5kLCBjbG9zaW5nX2JyZWNrZXQgPSBtYXRjaC5ncm91cHMoKQogICAgICAgIHNlbGYuYmVnaW4sIHNlbGYuZW5kID0gZmxvYXQoYmVnaW4pLCBmbG9hdChlbmQpCiAgICAgICAgaWYgc2VsZi5iZWdpbiA+PSBzZWxmLmVuZDoKICAgICAgICAJcmFpc2UgVmFsdWVFcnJvcigiSW50ZXJ2YWwncyBiZWdpbiBzaG91ZCBiZSBzbWFsbGVyIHRoYW4gaXQncyBlbmQiKQogICAgICAgIHNlbGYuYmVnaW5faW5jbHVkZWQgPSBvcGVuaW5nX2JyZWNrZXQgPT0gJ1snCiAgICAgICAgc2VsZi5lbmRfaW5jbHVkZWQgPSBjbG9zaW5nX2JyZWNrZXQgPT0gJ10nCiAgICAgICAgIyBJdCBtaWdodCBoYXZlIGJlZW4gYmF0dGVyIHRvIHVzZSBudW1iZXJfcmUgPSAnLionIGFuZCBjYXRjaCBleGVwdGlvbnMgZmxvYXQoKSByYWlzZXMgaW5zdGVhZAogICAgICAgIAogICAgZGVmIF9fcmVwcl9fKHNlbGYpOgogICAgICAgIHJldHVybiAnSW50ZXJ2YWwoeyFyfSknLmZvcm1hdChzdHIoc2VsZikpCiAgICAgICAgCiAgICBkZWYgX19zdHJfXyhzZWxmKToKICAgIAlvcGVuaW5nX2JyZWFja2V0ID0gJ1snIGlmIHNlbGYuYmVnaW5faW5jbHVkZWQgZWxzZSAnKCcKICAgIAljbG9zaW5nX2JyZWFja2V0ID0gJ10nIGlmIHNlbGYuZW5kX2luY2x1ZGVkIGVsc2UgJyknCiAgICAJcmV0dXJuICd7fXt9LCB7fXt9Jy5mb3JtYXQob3BlbmluZ19icmVhY2tldCwgc2VsZi5iZWdpbiwgc2VsZi5lbmQsIGNsb3NpbmdfYnJlYWNrZXQpCiAgICAJCiAgICBkZWYgX19jb250YWluc19fKHNlbGYsIG51bWJlcik6CiAgICAJaWYgc2VsZi5iZWdpbiA8IG51bWJlciA8IHNlbGYuZW5kOgogICAgCQlyZXR1cm4gVHJ1ZQogICAgCWlmIG51bWJlciA9PSBzZWxmLmJlZ2luOgogICAgCQlyZXR1cm4gc2VsZi5iZWdpbl9pbmNsdWRlZAogICAgCWlmIG51bWJlciA9PSBzZWxmLmVuZDoKICAgIAkJcmV0dXJuIHNlbGYuZW5kX2luY2x1ZGVkCiAgICAJCiAgICAgICAgICAgIApmb3IgaW50ZXJ2YWwgaW4gKCcoNCw1XScsICdbLTEwLDQpJywgJycsICdmb28nLCAnKGZvbycsICcoMTBdJywgJygpJywgJyg0LjAsIDUuN10nLCAnWzUsLTVdJyk6CiAgICBwcmludCgnSW50ZXJ2YWwoJywgcmVwcihpbnRlcnZhbCksICcpID0gJykKICAgIHRyeToKICAgICAgICBwcmludChyZXByKEludGVydmFsKGludGVydmFsKSkpCiAgICBleGNlcHQgQmFzZUV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KHJlcHIoZSkpCiAgICAJCmZvciBpbnRlcnZhbCBpbiAoJygtNSwgOCknLCAnWzUsIDhdJywgJyg1LCA4XScsICdbLTMsIDVdJywgJ1stMywgNSknKToKICAgIGludGVydmFsID0gSW50ZXJ2YWwoaW50ZXJ2YWwpCiAgICBwcmludCg1LCAnaW4nLCBpbnRlcnZhbCwgJz0nLCA1IGluIGludGVydmFsKQogICAgCiAgIApkZWYgZm9vKGludGVydmFsLCBiYXIsIGJheik6CglpbnRlcnZhbCA9IEludGVydmFsKGludGVydmFsKQoJcHJpbnQocmVwcihpbnRlcnZhbCkpCgkKZm9vKCdbLTEsIDUpJywgNDIsIFRydWUpCmZvbyhJbnRlcnZhbCgnWy0xLDUpJyksIDQyLCBUcnVlKQ==