Reputation: 505
def parse(expression):
operators= set("*/+-")
numbers= set("0123456789")#not used anywhere as of now
opExtrapolate= []
numExtrapolate= []
buff=[]
for i in expression:
if i in operators:
if len(buff) >0: #prevents buff if multiple operators
numExtrapolate.append(''.join(buff))
buff= []
opExtrapolate.append(i)
opExtrapolation=opExtrapolate
else:
buff.append(i)
numExtrapolate.append(''.join(buff))
numExtrapolation=numExtrapolate
print(numExtrapolation)
print("z:", len(opExtrapolation))
return numExtrapolation, opExtrapolation
def errors():
numExtrapolation,opExtrapolation=parse(expression)
#Error for muliple operators
if (len(numExtrapolation) ==3) and (len(opExtrapolation) !=2):
print("Bad1")
if (len(numExtrapolation) ==2) and (len(opExtrapolation) !=1):
print("Bad2")
#
I posted similar code in an older question however the premise for questions is different in this post.
The code above takes a mathematical input entered in a variable expression by the user and it splits it into operands and operators. The errors function will later print errors if the input is incorrect.
Input would look something like this , where the operators can only be in the set("*/+-") and operands are real numbers. so an example input would be 45/23+233
With the help of an SO user I was able to get one of the errors to work(error for multiple operators), but I am having trouble implementing a few more error messages.
1)If the input contains items that are not numbers or not the allowed operators then an error message is displayed
2)If a user enters a number such as .23 or something like 554. where there is no number before the decimal place or after the decimal place then a different error is displayed.(note that a number like 0.23 is fine).
3)If the user attempts to divide by zero an error is displayed.
::What I have tried:
In the else statement of parse(), I tried to put conditions on buff.append(i) so that it would only run that code if buff.isdigit()==true but I got errors saying that there were no digits in buff. I also tried creating a set called "numbers"(in code below) and limiting buff.append(i) to that set through a for statement similar to the initial for statement. But unfortunately nothing worked. Any and all help would be appreciated.
Please don't introduce large amounts of code more advanced than the code below. I am trying to fix a problem, not completely change my code. Thanks for all your help.
Upvotes: 0
Views: 297
Reputation: 12827
I will give you some indications, but not solve it for you :). If you need more, ask a precise question and I'll answer it.
The answers I give you are NOT directly related with your code.
You can test if a string variable can be an integer by trying to cast it :
try:
var2 = int(var)
I let you see what Error it gives
For a version that doesn't use try, you can look at the isdigit method
You can see if a string variable if one of your operator by checking it
if (var in ["+", "-", "/", "*"])
to check even more, you can look at the variable's length first
if len(var) != and ... see above
To check if a user inputs something like .543 and refuse it, and can look at the first element of your string variable :
if myvar[0] is ".":
To check if your user wants to divide by 0, you can simply check whether the last number is equals to 0
if int(myvar) == 0:
All these expect you to be able to get operators and numbers first though.
The other solution would be to use regular expressions to perform these checks before parsing your numbers and operators. It seems quite complex compared to the exercise you are trying to achieve though as it is homework. Might be a good idea to look at them anyway.
Upvotes: 1
Reputation: 208505
You can use regular expressions to do these checks:
If the input contains items that are not numbers or not the allowed operators then an error message is displayed
if not re.match(r'[\d.*/+\- ]+$', expression):
print("Bad3") # Characters exist that are not allowed
Explanation: [\d.*/+\- ]
will only match digits, your operators, and spaces, the +
means to allow one or more of those characters, and the $
matches at the very end of the string. re.match()
starts at the beginning of the string so this means that only those characters are allowed.
If a user enters a number such as .23 or something like 554. where there is no number before the decimal place or after the decimal place then a different error is displayed.(note that a number like 0.23 is fine).
if re.search(r'(?<!\d)\.|\.(?!\d)', expression):
print("Bad4") # There is a '.' without a digit before or after it
Explanation: \.
in a regex matches a literal '.' character. The |
in the middle is an alternation, so the regex will match if the expression on either side of it matches. (?<!\d)
means that the previous character is not a number, and (?!\d)
means that the next character is not a number, so this regex means "match a '.' that is not preceeded by a digit OR match a '.' that is not followed by a digit".
If the user attempts to divide by zero an error is displayed.
if re.search(r'/ *[0.]+(?![.\d])', expression):
print("Bad5") # Division by 0
Explanation: This matches /
followed by any number of spaces, then one or more 0
or .
characters, so this will match if anywhere in expression
you have something like / 0
, / 0.0
, or / 0.00
. The (?![.\d])
means that the next character can't be a digit or .
, which will prevent you from matching something like / 0.4
.
Upvotes: 2