1

What I tried to do:

Create a calculator application. Write code that will take two numbers and an operator in the format: N1 OP N2, where N1 and N2 are floating point or integer values, and OP is one of the following: +, -, , /, %, *, representing addition, subtraction, multiplication, division, modulus/remainder, and exponentiation, respectively, and displays the result of carrying out that operation on the input operands.

What I was able to come up with:

def calculator(n1,op,n2):
    n1 = float(n1)
    n2 = float(n2)
    if op == "+":
        return (n1 + n2)
    elif op == "-":
        return (n1 - n2)
    elif op == "*":
        return (n1 * n2)
    elif op == "/":
        return (n1 / n2)
    elif op == "%":
        return (n1 % n2)
    elif op == "**":
        return (n1 ** n2)

It works. But there might be 2 potential improvements:

  1. right now one has to use double quotes("") when entering the operator, for example, calculator(3,"+",3). Otherwise the interpreter returns a SyntaxError pop-up. I tried to change if op == "+": into if op == +:, but then the interpreter returns a SyntaxError, highlighting the : after the +.

  2. right now the function converts all kinds of number input into float(), even if integer was taken as input. How to let the function itself determine whether the input is integer or floating point, and convert it accordingly?

I read the Documentation on Functions, but it only talked about several types of arguments, and none of them seem to help solving the current problems. I'm sure this is pretty basic stuff, but as a beginner I tried and wasn't able to figure it out.

6
  • 1
    How do you expect calculator to be called? calculator(1, +, 2)? You can't do that. Write a parser and just pass in a string: calculator('1 + 2'). Commented Jun 8, 2013 at 2:00
  • 1
    To fix 2. simply don't call float on n1 and n2... Commented Jun 8, 2013 at 2:08
  • @Blender Thanks! Sorry but I don't understand what a parser is or how to write one? "A Python program is read by a parser. Input to the parser is a stream of tokens, generated by the lexical analyzer. This chapter describes how the lexical analyzer breaks a file into tokens" This is what I was able to find, but I don't think I understand. Would you care to elaborate a bit? Thanks a lot! Total beginner :-( Commented Jun 8, 2013 at 2:13
  • @hakuna121: Not a Python parser, but just a parser in general. Commented Jun 8, 2013 at 2:13
  • @Blender :Not only a Python beginner, but a beginner in general (programming) :P Okay, so I'll go take a look on how to write a parser. Thanks a lot! Commented Jun 8, 2013 at 2:19

3 Answers 3

3

You can't use +,*,etc in your code as they are not valid identifiers, but you can use the operator module and a dictionary here to reduce your code:

from operator import mul,add,div,sub,pow,mod
dic = {'+':add, '-':sub, '*':mul, '**':pow, '%':mod, '/':div}
def calculator(n1,op,n2):
    n1 = n1
    n2 = n2
    try:
        return dic[op](n1,n2)
    except KeyError:
        return "Invalid Operator"

Demo:

>>> calculator(3,"**",3)
27
>>> calculator(3,"*",3)
9
>>> calculator(3,"+",3)
6
>>> calculator(3,"/",3)
1
>>> calculator(3,"&",3)  # & is not defined in your dict
'Invalid Operator'
Sign up to request clarification or add additional context in comments.

2 Comments

Using the operator module and dictionary is brilliant. Thanks! In your solution, is there a way to avoid using double quotes("") when calling the function?
@hakuna121 No you've to use quotes around those operators(as they're not valid variable names in python) otherwise python will raise some error.
1

Quoting the operator is the only way to pass a symbol. It's normal for the language. Python will also figure out the correct type of the result, so no need to convert to float.

Here's your program with slight modifications. Single quotes are more "normal" for Python, no need for () around return values, and throwing exceptions for bad input is standard practice as well:

def calculator(n1,op,n2):
    if op == '+':
        return n1 + n2
    elif op == '-':
        return n1 - n2
    elif op == '*':
        return n1 * n2
    elif op == '/':
        return n1 / n2
    elif op == '%':
        return n1 % n2
    elif op == '**':
        return n1 ** n2
    else:
        raise ValueError('invalid operator')

Output:

>>> calculator(1,'+',2)     # note result is int
3
>>> calculator(1,'/',2)     # Python 3.x returns float result for division
0.5
>>> calculator(2,'*',2.5)   # float result when mixed.
5.0
>>> calculator(2,'x',2.5)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "C:\Users\metolone\Desktop\x.py", line 15, in calculator
    raise ValueError('invalid operator')
ValueError: invalid operator

Also, building on @Ashwini answer, you can actually just pass the operator name as op instead of the symbol:

from operator import mul,add as plus,truediv as div,sub as minus,pow,mod

def calculator(n1,op,n2):
    return op(n1,n2)

Output:

>>> calculator(2,plus,4)
6
>>> calculator(2,div,4)
0.5

Comments

0

This converts a string into an integer if possible, otherwise it gives a float or throws an exception if a conversion is not possible:

In [573]: def make_number(number_string):
   .....:     try:
   .....:         return int(number_string)
   .....:     except ValueError:
   .....:         return float(number_string)
   .....:     


In [574]: make_number('1')
Out[574]: 1

In [575]: make_number('1.0')
Out[575]: 1.0

In [576]: make_number('a')
ValueError: could not convert string to float: 'a'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.