1
\$\begingroup\$

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:

enter image description here

Ludisposed
11.8k2 gold badges41 silver badges91 bronze badges
asked Oct 17, 2018 at 0:59
\$\endgroup\$
1
  • \$\begingroup\$ There's no need for <pre> tags; you should just use indentation. I fixed the &quots as well. \$\endgroup\$ Commented Oct 18, 2018 at 2:53

1 Answer 1

1
\$\begingroup\$

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 ;)

answered Oct 19, 2018 at 19:22
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.