Last active
August 29, 2015 14:27
-
-
Save brettvitaz/70b74b16fbc3b17aa79b to your computer and use it in GitHub Desktop.
MultiRange will make complex range sequences from a formatted string.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MultiRange: | |
def __init__(self, range_str, **kwargs): | |
""" | |
MultiRange return a complex number sequence from a formatted string. | |
Range formats: | |
'Start[:Stop[:Step]]' - Start number (or single number), stop number (optional), step value (optional) | |
Groups are separated by ','. | |
For example, `MultiRange('1:3,5,7:9')` will result in (1,2,3,5,7,8,9). | |
Text substitution can be specified by adding a keyword argument of the same name. | |
For example, `MultiRange('1:max', max=10)` will result in (1,2,3,4,5,6,7,8,9,10) | |
Sequences are returned in the order specified in the range_str, and can contain duplicates if written as such. | |
Use `sorted(set(range_maker(...)))` to sort and eliminate duplicates if desired. | |
:type range_str: str | |
:rtype : MultiRange | |
""" | |
self.range_str = range_str | |
# Substitute strings that match kwargs keys | |
for k, v in kwargs.items(): | |
self.range_str = self.range_str.replace(k, str(v)) | |
self._range_items = self.range_str.split(',') | |
def _parse(self, range_item): | |
# Make a list of each int value in the range. | |
item_data = [int(item) for item in range_item.split(':', 2)] | |
if len(item_data) == 1: | |
return item_data | |
else: | |
# Get the range parameters | |
start, stop = item_data[:2] | |
stop_off = int(start <= stop or -1) | |
# If no step value, use the stop offset | |
step = item_data[2] if len(item_data) == 3 else stop_off | |
return range(start, stop + stop_off, step) | |
def __contains__(self, item): | |
for range_item in self._range_items: | |
if item in self._parse(range_item): | |
return True | |
return False | |
def __iter__(self): | |
result = [] | |
for range_items in self._range_items: | |
result.extend(self._parse(range_items)) | |
return iter(result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment