Last active
April 6, 2016 17:30
-
-
Save peterfpeterson/0c4382bdae695c81325c973c7246a32d to your computer and use it in GitHub Desktop.
Convert integers to condensed list of strings and back
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
#!/usr/bin/env python | |
def getMachine(): | |
"""Determine the name of the machine this process is running on.""" | |
from socket import gethostname | |
return gethostname() | |
def splitArgs(optArgs, sysArgs, options=None): | |
try: | |
index = sysArgs.index("--") | |
comArgs = sysArgs[index+1:] | |
except ValueError: | |
index = -1 | |
comArgs = [] | |
runArgs = optArgs | |
if index > 0: | |
runArgs = optArgs[:-1*len(comArgs)] | |
temp = " " | |
comArgs = temp.join(comArgs) | |
else: | |
comArgs = "" | |
runs = generateList(runArgs, options) | |
if options is not None: | |
if options.verbose is True or int(options.verbose) > 0: | |
print "RUNS:", runs | |
print "COM :", comArgs | |
return (runs, comArgs) | |
def getConcurrentIndices(runs, startIndex=0): | |
"""Compress a collection of consecutive integers into a single string | |
with a dash in the middle""" | |
start = startIndex | |
stop = start | |
for i in range(startIndex, len(runs)-1): | |
if runs[i]+1 == runs[i+1]: | |
stop = i+1 | |
else: | |
return (start, stop) | |
return (start, stop) | |
def condenseList(runs): | |
"""Turn a list of integers into a condensed string version of the list""" | |
result = [] | |
(start, stop) = (0, 0) | |
length = len(runs) | |
while stop < length: | |
(start, stop) = getConcurrentIndices(runs, start) | |
if stop >= length: | |
break | |
if start < stop: | |
result.append("%s-%s" % (runs[start], runs[stop])) | |
else: | |
result.append(runs[start]) | |
start = stop+1 | |
# convert the remaining runs into strings | |
result = map(lambda x: str(x), result) | |
return ",".join(result) | |
def generateList(args, options=None): | |
"""Convert a string list into a list of integers | |
args = single string or list of strings in the form | |
'\d+(-\d+)?(,\d+(-\d+)?)*' | |
For example: '12-15,30-33' | |
options = If options.verbose exists and is True, then this function | |
will send a warning message to stdout when it cannot | |
understand a portion of args. | |
Returns a list of all the integers indicated by args. The example | |
above would return the list [12, 13, 14, 15, 30, 31, 32, 33]. | |
Returned integers will be sorted least to greatest with no | |
duplicates. | |
""" | |
optargs = getattr(options, 'run', None) | |
if args is None: | |
args = [] | |
if optargs is not None: | |
args.append(optargs) | |
if len(args) <= 0: | |
raise RuntimeError("Cannot generate list from empty") | |
verbose = getattr(options, 'verbose', False) | |
# normalize args to always be a list | |
if (not isinstance(args, list)): | |
args = [args] | |
# args should be a list of strings like this: | |
# ['1-5,10', '12,15-21']. | |
# force all elements to be strings and split on commas | |
args = [str(a).split(',') for a in args] | |
# args should now be a list of lists like this: | |
# [['1-5', '10'], ['12', '15-21']] | |
# flatten the list back out again | |
from operator import add # function equivalent of + | |
args = reduce(add, args) | |
# args should now be a list of strings again like this: | |
# ['1-5', '10', '12', '15-21'] | |
# use a set instead of a list so overlapping ranges won't create | |
# duplicate integers in the output | |
result = set() | |
for a in args: | |
# watch for badly formatted input ranges | |
# Mainly I expect the int() cast below to fail for bad input. | |
try: | |
ends = [int(x) for x in a.split('-')] | |
if (len(ends) > 2): | |
raise ValueError("too many dashes") | |
# reverse any backwards ranges | |
ends.sort() | |
result |= set(xrange(ends[0], ends[-1] + 1)) | |
except: | |
if verbose: | |
print "WARN: Skipping range \"%s\"" % a | |
return sorted(result) | |
###################################################################### | |
# MAIN FUNCTION FOR TESTING | |
###################################################################### | |
if __name__ == "__main__": | |
print "getMachine():", getMachine() | |
print "condenseList([1,2,3,7])", condenseList([1, 2, 3, 7]) | |
print "generateList('1-3,8')", generateList("1-3,8") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment