gruntfutuk

String to num list

Apr 1st, 2018
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.28 KB | None | 0 0
  1. ''' Beginner challenge.
  2.  
  3. Write a function that converts a string containing an ordered sequence of positive whole
  4. numbers and number ranges to an ordered list of those numbers.
  5.  
  6. Number are separated with commas (and optional spaces) and number ranges are marked with
  7. a - between two whole numbers (with optional spaces either side).
  8.  
  9. For bonus points, include validation, and handle out of order sequences and ranges.
  10.  
  11. State your assumptions (so interpret the challenge your way).
  12.  
  13. For example,
  14.  
  15. ‘1-5, 7, 9, 10-13’ should convert to [1, 2, 3, 4, 5, 7, 9, 10, 11, 12, 13]
  16. '''
  17.  
  18. # Stuart Moore's solution - no validation
  19. def str_to_numlst(sample):
  20.     ''' returns list of numbers from string of numbers and ranges of the format x-y
  21.    separated by commas '''
  22.     return [num for comma_sep in sample.split(',')
  23.             for before, _, after in [comma_sep.partition('-')]
  24.             for num in range(int(before), int(after or before) + 1)
  25.             ]
  26.  
  27. # Stuart Moore's solution - with validation
  28. def str_to_numlst_valid(sample):
  29.     ''' returns list of numbers from string of numbers and ranges of the format x-y
  30.    separated by commas, returns error message in ValueError if bad data given
  31.  
  32.    assumption: numbers returned should be unique '''
  33.     result = []
  34.     errmsg = ''
  35.     source = "".join(sample.split())
  36.     for comma_sep in source.split(','):
  37.         before, hyphen, after = comma_sep.partition('-')
  38.         if (not before or not before.isnumeric()) or \
  39.                 (hyphen and not after) or \
  40.                 (after and not after.isnumeric()):
  41.             errmsg += f'   ***>> {comma_sep} bad int/range'
  42.         else:
  43.             start = int(before)
  44.             fini = int(after) if after else start
  45.             if start > fini:
  46.                 start, fini = fini, start
  47.             for num in range(start, fini + 1):
  48.                 result.append(num)
  49.     if errmsg:
  50.         raise ValueError(errmsg)
  51.     return sorted(set(result))
  52.  
  53.  
  54. def Leo_Francisco_Simpao(data):
  55.     stripped_data = [x.strip() for x in data.split(",")]
  56.     ordered_list = []
  57.     for i in stripped_data:
  58.         if "-" in i:
  59.             ls = list(map(int, i.split("-")))
  60.             for x in range(ls[0], ls[-1] + 1):
  61.                 ordered_list.append(x)
  62.         else:
  63.             ordered_list.append(int(i))
  64.     return ordered_list
  65.  
  66.  
  67. def Ben_Cleary(data):
  68.     import re
  69.  
  70.     class InvalidDigit(Exception):
  71.         pass
  72.  
  73.     class OrderedSequenceGenerator:
  74.         processed = []
  75.         cleaned_payload = []
  76.  
  77.         def __init__(self, data):
  78.             self.safety_check_and_process(data)
  79.  
  80.         def sorted(self):
  81.             return sorted(self.processed)
  82.  
  83.         def safety_check_and_process(self, data):
  84.             pattern = re.compile("^[0-9]{1,}?(-[0-9]{1,})?$")
  85.             for item in list(map(lambda item: item.strip(), data.split(','))):
  86.                 if pattern.match(item):
  87.                     self.cleaned_payload.append(item)
  88.                 else:
  89.                     raise InvalidDigit(
  90.                         f"'{item}' is not in correct format, please use XXX-XXX // X, where X is a positive integer")
  91.  
  92.         def check_range_values(self, item):
  93.             if item[0] > item[1]:
  94.                 return [item[1], item[0]]
  95.             elif item[0] == item[1]:
  96.                 return [item[0]]
  97.             else:
  98.                 return [item[0], item[1]]
  99.  
  100.         def order(self):
  101.             for item in self.cleaned_payload:
  102.                 if "-" in item:
  103.                     r = self.check_range_values(
  104.                         list(map(int, item.split('-'))))
  105.                     if r.__len__() > 1:
  106.                         [self.processed.append(x)
  107.                          for x in range(r[0], r[1] + 1)]
  108.                     else:
  109.                         self.processed.append(r[0])
  110.                 else:
  111.                     self.processed.append(int(item))
  112.  
  113.     sequence = OrderedSequenceGenerator(data)
  114.     sequence.order()
  115.     return sequence.sorted()
  116.  
  117.  
  118. def Abhijit_Mukherjee(input_sequence):
  119.     list_of_num = []
  120.     for input in input_sequence.split(','):
  121.         if len(input) > 1:
  122.             for num in range(int(input.split('-')[0]), int(input.split('-')[1]) + 1):
  123.                 list_of_num.append(num)
  124.         else:
  125.             list_of_num.append(int(input))
  126.  
  127.     return list_of_num
  128.  
  129.  
  130. def Carlos_Guillermo_Durazo(lst):
  131.  
  132.     def valid_range(val):
  133.         import re
  134.         tmp = re.findall('\d+-\d+', val)
  135.         if len(tmp) == 1:
  136.             val = val.split('-')
  137.             tmp = tmp[0].split('-')
  138.             if val[0] == tmp[0] and val[1] == tmp[1]:
  139.                 return True
  140.         return False
  141.  
  142.     final_list = set()
  143.     for i in lst.split(','):
  144.         if len(i.split('-')) == 1:
  145.             if i.replace(' ', '').isdigit():
  146.                 final_list.add(int(i.replace(' ', '')))
  147.         else:
  148.             tmp = i.replace(' ', '')
  149.             if valid_range(tmp):
  150.                 tmp = tmp.split('-')
  151.                 for j in range(int(tmp[0]), int(tmp[-1]) + 1):
  152.                     final_list.add(int(j))
  153.     return list(final_list)
  154.  
  155.  
  156. def Umar_Khan(Input_String):
  157.   Output_list = []
  158.   for elements in Input_String.split(','):
  159.     Elements_contain_Number = False
  160.     for num in elements:
  161.       if num.isdigit():
  162.         Elements_contain_Number = True
  163.         break
  164.     if Elements_contain_Number == True:
  165.       new_element = elements.replace(" ", "")
  166.       if '-' not in new_element:
  167.         Sequence_Number = ''
  168.         for k in new_element:
  169.           if k.isdigit():
  170.             Sequence_Number = Sequence_Number + k
  171.         Output_list.append(int(Sequence_Number))
  172.       else:
  173.         Range_Number = []
  174.         for k in new_element.split('-'):
  175.           if k.isdigit():
  176.             Range_Number.append(int(k))
  177.         if len(Range_Number) >= 2:
  178.           if Range_Number[0] > Range_Number[1]:
  179.             Start = Range_Number[1]
  180.             End = Range_Number[0] + 1
  181.           else:
  182.             Start = Range_Number[0]
  183.             End = Range_Number[1] + 1
  184.           for i in range(Start, End):
  185.             Output_list.append(i)
  186.         else:
  187.           Output_list.append(Range_Number[0])
  188.   return sorted(list(set(Output_list)))
  189.  
  190. def Pierre_Chiggles(NumericString):
  191.   #print(NumericString)
  192.   Index = 0
  193.   Error = "Is not Integer"
  194.   NewArray = []
  195.   array = NumericString.split(",")
  196.   while Index <= len(array)-1:
  197.     Element = array[Index]
  198.     if "-" in Element:
  199.       Elements = Element.split("-")
  200.       Element_1 = Elements[0].strip()
  201.       Element_2 = Elements[1].strip()
  202.       try:
  203.         Element_1 = int(Element_1)
  204.         Element_2 = int(Element_2)
  205.       except:
  206.         return Error
  207.       Elements = []
  208.       Elements.append(Element_1)
  209.       Elements.append(Element_2)
  210.       Elements.sort()
  211.       Element = Elements[0]
  212.       while Element <= Elements[1]:
  213.         if Element not in NewArray:
  214.           NewArray.append(Element)
  215.         Element += 1
  216.     else:
  217.       Element = Element.strip()
  218.       try:
  219.         Element = int(Element)
  220.       except:
  221.         return Error
  222.       if Element not in NewArray:
  223.         NewArray.append(int(Element))
  224.     Index +=1
  225.     NewArray.sort()
  226.   return NewArray
  227.  
  228. def Andre_Müller(seq, constructor=set):
  229.     from contextlib import suppress
  230.  
  231.     def adv_range(seq):
  232.         for element in seq.split(','):
  233.             with suppress(ValueError):
  234.                 if '-' in element:
  235.                     start, _, stop = element.partition('-')
  236.                     start, stop = int(start), int(stop)
  237.                     direction = 1 if start <= stop else -1
  238.                     yield from range(start, stop + direction, direction)
  239.                 else:
  240.                     yield int(element)
  241.  
  242.     retval = constructor(adv_range(seq))
  243.     return sorted(retval)
  244.  
  245. def Zarren_Donovan_Spry(stringInput):
  246.     unsortedList = []
  247.     error = 0
  248.     rawList = stringInput.split(",")
  249.     for item in rawList:
  250.         if "-" in item:
  251.             num1,hyphen,num2 = item.partition("-")
  252.             num1 = num1.strip(" ")
  253.             num2 = num2.strip(" ")
  254.             if num1.isnumeric() and num2.isnumeric():
  255.                 num1 = int(num1)
  256.                 num2 = int(num2)
  257.                 if num1 < num2:
  258.                     for i in range(num1,num2 + 1):
  259.                         unsortedList.append(i)
  260.                 elif num1 > num2:
  261.                     for i in range(num2,num1 + 1):
  262.                         unsortedList.append(i)
  263.         removeNoise = item.strip(" ")
  264.         if removeNoise.isnumeric():
  265.             unsortedList.append(int(item))
  266.     return sorted(list(set(unsortedList)))
  267.  
  268.  
  269. def test_funcs(*funcs):
  270.     import traceback
  271.     tests = [('1-5,7,9,10-13', [1, 2, 3, 4, 5, 7, 9, 10, 11, 12, 13]),
  272.              ('5, 10-6, 4-8,3', [3, 4, 5, 6, 7, 8, 9, 10]),
  273.              ('1023,675,43, 23400-23395, 5-12', [5,6,7,8,9,10,11,12,43,675,1023,23395,23396,23397,23398,23399,23400]),
  274.              ('1, 3 -5, 6-, -, 7, -9 , 16 - 20,23',
  275.               [1, 3, 4, 5, 7, 16, 17, 18, 19, 20, 23]),
  276.              ('2, 4, num, ;5, a-b', [2, 4])
  277.              ]
  278.     for func in funcs:
  279.         print(f'\n\nTesting function: {func.__name__}\n')
  280.         print('-----------')
  281.         for test, assertion in tests:
  282.             print(f'Testing: {test}')
  283.             try:
  284.                 result = func(test)
  285.             except ValueError as errmsg:
  286.                 print(errmsg)
  287.             except Exception as e:
  288.                 print(f'ERROR: {traceback.format_exc()}')
  289.             else:
  290.                 try:
  291.                     assert sorted(set(result)) == assertion
  292.                 except AssertionError:
  293.                     print(
  294.                         f'*** ERROR -> for {test}\n\texpected {assertion},\n\treceived {result}')
  295.                 else:
  296.                     print(result, end='')
  297.                     if result != sorted(set(result)):
  298.                         print(' ** result not ordered/unique')
  299.                     else:
  300.                         print()
  301.             print('-----------')
  302.  
  303.  
  304. if __name__ == "__main__":
  305.     test_funcs(str_to_numlst, str_to_numlst_valid, Leo_Francisco_Simpao,
  306.                Ben_Cleary, Abhijit_Mukherjee, Carlos_Guillermo_Durazo,
  307.                Umar_Khan, Pierre_Chiggles, Andre_Müller, Zarren_Donovan_Spry)
Add Comment
Please, Sign In to add comment