Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Problems with calculator
#1
Hi, I am trying to build a calculator, no parentheses required, supporting negative figures.
And I have written some codes and use visualize Python several times.
It seems my loop stop function once it has been executed.
Could anyone please kindly tell me why and how can i fix the bug?
Thank you very much.

=---------------------------------------
def Calculator(s):

    s=list(s.replace(" ",""))
    operator=["+", "-", "*", "/"]
    ### create series from 0~9
    num=map(str,(range(10)))
    
    ###calculate extra space number
    count= len([i for i in s if i in operator])
    if s[0]=='+' or s[0]=='-':
        count -= 1
    for i in range(len(s)):
        if (s[i] in operator)and(s[i+1] in operator) :
            count -= 1 

    ###seperate operators and figures with space  
    for i in range(1,len(s)+count*2):    
        if (s[i] in operator)and(s[i+1] in operator) :
            s.insert(i+1," ")
            s.insert(i," ")
        elif (s[i] in operator)and(s[i-1] in num):
            s.insert(i+1," ")
            s.insert(i," ")

  s= ''.join(s)
    s=s.split()
    
    ### * / first
    a=0
    for i in s:
        if i=="*" or i=="/":
            a+=1
    for i in range(a):
        for i in s:
            if i =="*":
                v=str(float(s[s.index(i)-1])*float(s[s.index(i)+1]))
                s.pop(s.index(i)+1)
                s.pop(s.index(i)-1)
                s.insert(s.index(i),v)
                s.pop(s.index(i)) 
                break
            elif i =="/":
                p=str(float(s[s.index(i)-1])/float(s[s.index(i)+1]))
                s.pop(s.index(i)+1)
                s.pop(s.index(i)-1)
                s.insert(s.index(i),p)
                s.pop(s.index(i)) 
                break
    ### then + -
    b=0
    for i in s:
        if i=="+" or i=="-":
            b+=1
    for i in range(b):
        for i in s:
            if i =="+":
                v=str(float(s[s.index(i)-1])+float(s[s.index(i)+1]))
                s.pop(s.index(i)+1)
                s.pop(s.index(i)-1)
                s.insert(s.index(i),v)
                s.pop(s.index(i)) 
                break
            elif i =="-":
                p=str(float(s[s.index(i)-1])-float(s[s.index(i)+1]))
                s.pop(s.index(i)+1)
                s.pop(s.index(i)-1)
                s.insert(s.index(i),p)
                s.pop(s.index(i)) 
                break
    your_ans=float(s[0])
    return your_ans   

    
s='-7.3 +-2 *   -8 /1.6'
Calculator(s)
Reply
#2
I think the problem might be that you keep removing the results after inserting them. Take lines 67 and 68. You insert the result of the subtraction, and then immediately remove that same position.

The first part of the program seems overly complicated. It looks like you want to make sure there are no spaces except there must be spaces around the operators (so the split works to make a list of numbers and operators). Wouldn't it be simpler to just use replace for each operator (replace('+', ' + '))?

Also, I think slice assignment would work better than all that popping and inserting: s[s.index(i)-1:s.index(i)+2] = [v].
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
(May-02-2019, 10:59 AM)ichabod801 Wrote:   ###seperate operators and figures with space 
    for i in range(1,len(s)+count*2):   
        if (s[i] in operator)and(s[i+1] in operator) :
            s.insert(i+1," ")
            s.insert(i," ")
        elif (s[i] in operator)and(s[i-1] in num):
            s.insert(i+1," ")
            s.insert(i," ")
 
(May-02-2019, 10:59 AM)ichabod801 Wrote: I think the problem might be that you keep removing the results after inserting them. Take lines 67 and 68. You insert the result of the subtraction, and then immediately remove that same position. The first part of the program seems overly complicated. It looks like you want to make sure there are no spaces except there must be spaces around the operators (so the split works to make a list of numbers and operators). Wouldn't it be simpler to just use replace for each operator (replace('+', ' + '))? Also, I think slice assignment would work better than all that popping and inserting: s[s.index(i)-1:s.index(i)+2] = [v].

Hi, Thank you for the suggestion!
I do agree replace is faster, but, in that case, how could i avoid negative figures turn into ' - - ' ?
Also, I am stucked in line 16-23 seem not workable:
the loop can not work (create space) once it has been executed once.

Thank you!
Reply
#4
You don't need to avoid negative figures turning into double operators. Let that happen, and then use replace on any double operators: text = text.replace(' - - ', ' - -'). But that may get tricky with double spaces cropping up.

I would normally approach this with regular expressions. Assuming this is homework and you can't use regular expressions, I would do one loop over the input string. For each character, if it's a number character, store it in a sub-string and build that sub-string character by character. When you get to an operator, append the number and then the operator into your list, and reset the sub-string. If you get an operator after an operator (or an operator at the beginning) you know that's a negative number, and you can put that in the sub string.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020