1

This is a small program that works as a arithmetic calculator. I have read previous questions here, but there is still a doubt. In my code, I have used 'is' and not == in my while loop, but my loop does not stop. That is kind of unexpected because the variable ask is getting assigned by a new object if the user presses 'n' when asked for input. I'd be grateful if someone can have a look on the code and help.

def Add(x,y):
    add = x+y
    print("Answer:",add)

def Sub(x,y):
    sub = x-y
    print("Answer:",sub)

def Mult(x,y):
    product = float(x*y)
    print("Answer:",product)

def Div(x,y):
    if y!=0:
        div=float(x/y)
        print("Answer:",div)
    else:
        print("Invalid input!")


ask='y'
while(ask is 'y' or 'Y'):

    x=float(input("\nEnter x:"))
    y=float(input("Enter y:"))

    print("\nCALCULATOR:")
    print("\nPlease select any of the following options:")
    print("1.Add")
    print("2.Subtract")
    print("3.Multiplication")
    print("4.Division")
    opt=int(input("\nYour option:"))


    if(opt is 1):
        Add(x,y)

    elif(opt is 2):
        Sub(x,y)

    elif(opt is 3):
        Mult(x,y)

    elif(opt is 4):
        Div(x,y)

    else:
        print("Invalid option!")
    ask=input("\nDo you want to continue?(y/n or Y/N)")
Aamir Khan
  • 324
  • 2
  • 10
  • The while loop does not stop because `anything or 'y'` is always `True`. See here: http://stackoverflow.com/q/15112125/1639625 – tobias_k Jun 05 '16 at 17:14
  • I believe `while( ask in ['y','Y'])` is what your are looking for. I believe the way your current statement is evaluated is `(ask is 'y') or 'Y'` which is always `True`, per @tobias_k – michael_j_ward Jun 05 '16 at 17:17

2 Answers2

5

is compares object identity. But there are many different string objects, that have the value 'y'. So always compare with == if you want to compare values.

Besides or is a boolean operation on two expressions and not lexical or.

So the condition have to be:

while ask == 'y' or ask == 'Y':
    ...

or more compact:

while ask in ['y', 'Y']:
    ...

or with the help of lower method:

while ask.lower() == 'y':
    ...
Daniel
  • 42,087
  • 4
  • 55
  • 81
  • This is correct, but just to clarify a little: in Python, a non-empty string converted to boolean evaluates to `True`. So your while condition is equivalent to `while (ask is 'y') or (True):`. – bjudson Jun 05 '16 at 17:25
  • @bjudson: wrong, `ask is 'y' or 'Y'` evaluates to `True` (if `ask` is equal to `'y'`) or to `'Y'` otherwise. Now, the `while`-condition is evaluated to a boolean, so `True` stays true or `'Y'` finally becomes `True`. – Daniel Jun 05 '16 at 17:27
  • Edited comment to clarify I was referring to string to boolean conversion – bjudson Jun 05 '16 at 17:31
1

As Daniel mentions in his excellent answer, in Python, the is for identity, not equality. In case you don't know what that means, I will offer a brief explaination.

is compares if two variables are referencing the same object in memory, not if they are equal. For example

im_a_list = [1,2,3]
im_a_similar_list = [1,2,3]

now,

im_a_list is im_a_similar_list

will be False, whilst

im_a_list == im_a_similar_list

is True. on the otherhand, if you have

im_a_list = im_seriously_the_same_list = [1,2,3]

then

im_a_list is im_seriously_the_same_list 

will evaluate to True

JustDanyul
  • 13,813
  • 7
  • 53
  • 71