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:
1 Answer 1
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
StringController()
seems overly complexBasically 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
The extraction of numbers can be greatly simplified
You could use
re.findall(r'(\d+)', input)
to find the digits in a neater wayAnd 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 ;)
<pre>
tags; you should just use indentation. I fixed the"
s as well. \$\endgroup\$