SeesSound
SeesSound

Reputation: 505

Implementing error message for code in Python

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

Answers (2)

jlengrand
jlengrand

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

Andrew Clark
Andrew Clark

Reputation: 208505

You can use regular expressions to do these checks:

  1. 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.

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

    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".

  3. 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

Related Questions