Skip to content

Instantly share code, notes, and snippets.

@peterfpeterson
Last active April 6, 2016 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peterfpeterson/0c4382bdae695c81325c973c7246a32d to your computer and use it in GitHub Desktop.
Save peterfpeterson/0c4382bdae695c81325c973c7246a32d to your computer and use it in GitHub Desktop.
Convert integers to condensed list of strings and back
#!/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