# Control the input of the user according to a sample string and get some info from it

I made this Python code that prints a sample string and ensures that the input of the user agrees with the sample, and then do an action with this inputted string, in this case a multiplication table.

I've made this code to practice some Python concepts, and I do not know if I did everything correctly and "in a pythonic way". I'd like to know if there's anything in this code that can be improved and things I could have done otherwise.

import re
from time import sleep

class StringController(object):
def __init__(self, *args, **kwargs):
self.regexp = re.compile('(?i)^show me the multiplication table of [0-9]* from [0-9]* to [0-9]*$') def __enter__(self, *args, **kwargs): print('Example string: show me the multiplication table of 10 from 5 to 20') self.inputedstring = input('Input: ') print('-'*50) sleep(1) return self def __exit__(self, exc_type, exc_val, exc_tb): if exc_type: print('{}: {}'.format(exc_type.__name__, 'You must use the provided string')) else: print('-'*50) del self.inputedstring if __name__ == '__main__': myobject = StringController() while True: try: with myobject as strcon: multiplication_table = list(range(int(myobject.inputedstring.split(' ')[8]), int(myobject.inputedstring.split(' ')[10])+1)) results = list(map(lambda x : x*int(myobject.inputedstring.split(' ')[6]), multiplication_table)) if myobject.regexp.match(myobject.inputedstring): print('\n'.join(str(results) for results in results)) else: raise UserWarning('You must use the provided string') except (ValueError, IndexError) as WrongInput: print("\n") del WrongInput finally: del strcon  Output: • There's no need for <pre> tags; you should just use indentation. I fixed the &quots as well. – Jamal Oct 18 '18 at 2:53 ## 1 Answer # Bug The regex is flawed, consider this: >>> print(re.match(pat, 'show me the multiplication table of from to ')) >>> <re.Match object; span=(0, 46), match='show me the multiplication table of from to '>  That is because [0-9]* matches the digit zero, or more times I suggest to change them with + which will match the digit 1, or more times pattern = re.compile('(?i)^show me the multiplication table of \d+ from \d+ to \d+$')


# Codestyle

1. StringController() seems overly complex

Basically the same can be achieved with re.match(pattern, input_string)

It adds a layer of complexity what is not needed, I would just remove the entire class

2. The extraction of numbers can be greatly simplified

You could use re.findall(r'(\d+)', input) to find the digits in a neater way

And you could map(int, iterable) to convert them to integers

# Alternative

INPUT_REGEX = re.compile('(?i)^show me the multiplication table of \d+ from \d+ to \d+\$')

def make_table(user_input):
step, min_range, max_range = map(int, re.findall('(\d+)', user_input))
return "\n".join(str(step * t) for t in range(min_range, max_range))

def main():
while True:
user_input = input('Example string: show me the multiplication table of 8 from 3 to 8\nInput: ')
print('-'*50)
if user_input.lower() in ('q', 'quit', 'exit'):
exit()
elif re.match(INPUT_REGEX, user_input):
print(make_table(user_input))
else:
print('Use the provided string')

if __name__ == '__main__':
main()


Note I added a quit, might be nice for your user to let them exit in a clean way ;)