0
\$\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

\$\endgroup\$
1
  • \$\begingroup\$ There's no need for <pre> tags; you should just use indentation. I fixed the &quots as well. \$\endgroup\$
    – Jamal
    Oct 18 '18 at 2:53
0
\$\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 ;)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.