I want my code to understand a string
as a math expression
, then output me this string
with proper whitespaces.
operators = ("+", "-", "*", "/", "%", "**", "//") # Math operators the code is going to identify in the string
oper = "20 *25" # The operation string before being formatted ('oper' stands for 'operation')
new_oper = "" # This is going to be the new operation string (desired output)
it = iter(oper.replace(" ", "")) # Removed all whitespaces from the operation string and made it an iterable
next()
method once, just so he could understand this method (inside my loop) as the character that comes right after the character the loop is in.next(it)
operation string
(already with no whitespaces).for x in oper.replace(" ", ""):
try: # This try checks if I'm able to use the next() method. If I'm not, x is the last character in the string.
if x not in operators: # x is a number
if next(it) in operators:
new_oper += f"{x} " # If an operator comes right after a number, this number is printed with a whitespace, so they don't stay next to each other.
else:
new_oper += x
elif x in operators: # x is an operator
if x == "*":
if next(it) == "*":
new_oper += x # If another '*' comes after this '*', then it's a ** operator, so no whitespaces inserted (otherwise, they would be separated)
else:
new_oper += f"{x} "
elif x == "/":
if next(it) == "/":
new_oper += x # Same here: if there are 2 '/' next to each other, it's another operator ('//'), so no whitespaces inserted
else:
new_oper += f"{x} "
else:
new_oper += f"{x} "
except RuntimeError:
new_oper += x # x is the last character in the string, no needs to be formatted (it can't be an operator)
new_oper
).print(new_oper)
Check out these outputs (different values for oper
):
When
oper = "20 *2"
Output
Traceback (most recent call last):
File "filename", line 12, in <module>
if next(it) in operators:
^^^^^^^^
StopIteration
# Desired output: 20 * 2
When
oper = "20 +2"
Output
20 + 2 # Correct output (just changed the operator comparing to the last one)
When
oper = "10+ 3 *2"
Output
10 + 3*2
# Desired output: 10 + 3 * 2
I'd appreciate any approach for my problem. I'm not a python expert (far away from that), so I also would appreciate any suggestions or even fixes in my code that may not directly help my problem.
Firstly, you need to change the except RuntimeError:
to except StopIteration:
so that it is able to catch the StopIteration
exception that is thrown by the next()
when it reaches the end of the string.
You need to change the else
to make it like this:
else:
new_oper += f"{x} "
next(it)
Here, the next(it)
is so that the iterator is always in line with the value of x
. You call next(it)
once on all other path of the if
except this one.
With these 2 changes, it works on the examples given.
It might be easier to iterate over the string using enumerate
like this:
oper2 = oper.replace(" ", "")
for index, x in enumerate(oper2):
instead of trying to keep the iterator and the loop in sync. This way, you can refer to the next character as oper2[index+1]
(index
is the index of the current character) and for the current character, you can use x
.
For example, instead of next(it)
, you would write oper2[index+1]
. This has the added benefit of being able to look further ahead (but you would need to do except IndexError:
instead of except StopIteration:
)