3

I'm new to Python and I'm trying to create some kind of a calculator that reads expressions as strings and calculates them (without eval). In order to do so I'm working with a list after converting the string to a list separated by parentheses, operators and values. I have a list that contains the operators too, I just don't know how to use it in the regex split so up until now I've done that manually.

I have 3 issues with my code:

  1. The code doesn't split correctly negative numbers.
  2. The code doesn't allow to add operators (in example - if I'd like to add _ as a new operator in the future, the code won't know to split according to it).
  3. The code brings back numbers as strings, which I then convert to integers in an outside function.
    # Removing any unwanted white spaces, tabs, or new lines from the equation string:
    equation = re.sub(r"[\n\t\s]*", "", equation)
    # Creating a list based on the equation string:
    result_list = re.split(r'([-+*/^~%!@$&()])|\s+', equation)
    # Filtering the list - Removing all the unwanted "spaces" from the list:
    result_list = [value for value in result_list if value not in ['', ' ', '\t']]

For example: 5--5 -> I'd like to get: [5, '-', -5] -> I currently get: ['5', '-', '-', '5']

Another example : ((500-4)*-3) -> I'd like to get: ['(', '(', 500, '-', '4', ')', *', '-3', ')']

5
  • I think, you should set some rules for your calculator Commented Dec 21, 2019 at 11:10
  • The main idea in the calculator is that it will be easy for the next programmer to change and add operators, therefore I'm trying to create it as "clean" as possible Commented Dec 21, 2019 at 11:12
  • Try at first to create a more strict and then make it more easy and versatile) Commented Dec 21, 2019 at 11:13
  • I've done that and the rest of the functions of the calculator works perfectly fine, all I have left now is to find a way to separate the string into a list correctly. Commented Dec 21, 2019 at 11:17
  • You can deal with operators (e.g. +, -) by only splitting when they are preceded by a digit i.e. use a positive lookbehind (?<=\d) to qualify the split Commented Dec 21, 2019 at 12:06

1 Answer 1

2

Here is a way to go:

import re

arr = [
    '5--5',
    '((500-4)*-3)',
]

for s in arr:
    res = re.findall(r'\b-\b|-?\d+|\D', s)
    print res

Output:

['5', '-', '-5']
['(', '(', '500', '-', '4', ')', '*', '-3', ')']

Demo & explanation

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much, it works well. Is there a way to treat + as well in this regex? (to receive +5 as '5' for example)
@RnadomG: It should work with + without modifications. If you can't make it working, edit your question and add more test cases.

Your Answer

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.