HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMajor

My first calculator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
firstcalculatorstackoverflow

Problem

I've just wrote my first code, which is basically a calculator. Please rate it and suggest improvements (keeping in mind that I'm a beginner).

import math

#Returns the sum of num1 and num2
def add(num1, num2):
    return num1 + num2

import math

#Returns the difference between num1 and num2
def sub(num1, num2):
    return num1 - num2

#Returns product of num1 and num2
def mul(num1, num2):
    return num1 * num2

#Returns the quotient of num1 and num2
def div(num1, num2):
    return num1 / num2

#Returns the result of num1 to the power of num2    
def exp(num1, num2):
    return num1 ** num2

#Returns the square of num1
def sqrt(num1):
    return num1**2

#Returns the value of pi
def pi():
    pi = 3.14159265
    return pi

#Returns the value of num1 multiplied with pi
def mulpi(num1):
    pi = 3.14159265
    return num1*pi

def main():
    operation = input("What do you want to do? (+,-,*,/,exp,pi,_pi,sqrt)")
    if(operation != '+' and operation != '-' and operation != '*' and operation != '/' and operation != 'exp' and operation != '_pi' and operation != 'sqrt' and operation != 'pi'):
        #Invalid Operation
        print("YOU MUST ENTER A VALID OPERATION")
    elif(operation == 'pi'):
        print(pi()) 
    elif(operation == '_pi' or 'sqrt'):
        var1 = int(input("enter number: "))
        if(operation == '_pi'):
            print(mulpi(var1))
        elif(operation == 'sqrt'):
            print(sqrt(var1))
    else:
        var1 = int(input("enter num1: "))
        var2 = int(input("enter num2: "))
        if(operation == '+'):
            print (add(var1, var2))
        elif(operation == '*'):
            print(mul(var1, var2))
        elif(operation == '-'):
            print(sub(var1, var2))
        elif(operation == 'exp'):
            print(exp(var1, var2))
        else:
            print(div(var1, var2))

main()

Solution

Input validation

You do absolutely no input validation when the user enters an integer. If the user enters a non-integer value, like foo, or bar, your code will crash with a ValueError. The correct way to obtain user input is to use a try/except block, like this:

try:
    var1 = int(input( ... ))
    var2 = int(input( ... ))

    ...
except ValueError:
    print("Invalid input!")
    ...


By doing this, you can be sure that your program won't crash on invalid input.

Input mappings

Right now, you're chaining if/elif/else statements to check user input. This is not an optimal way to do this. Rather, you can create a dictionary mapping, like the below, for possible inputs:

OPERATIONS = {
    "+": add,
    "-": sub,
    ...
}


Then, all you have to do to get, and run user input is something like this:

operation = input( ... )
if operation in OPERATIONS:
    OPERATIONS[operation](var1, var2)
else:
    print("Invalid operation!")


This makes your code much clearer, and easier to read, rather than a chain of if/elif/else statements.

Use math and operator

There is absolutely no reason to define your own mathematical functions, just so you can use them in a dictionary mapping, you should be using the math and operator modules instead. These all provide built-in functions, like add, and sub, or values, like \$\pi\$ or \$e\$.

General nitpicks

-
There's no need for parentheses around if/elif/else statements. They can be written like this:

if condition:
    ...


-
You should be using an if __name__ == "__main__" guard. This ensures that if your code is imported to another file, certain code will not be run. This means that this function call right here:

main()


Should become this:

if __name__ == "__main__":
    main()


-
There's no need to import math twice. Once it's imported, it's functions and variables already populate the file's namespace.

-
Finally, if you're going to write comments for your functions (in this case your comments are fairly useless), you should be using docstrings instead. A typical docstring looks something like this:

def my_func( ... ):
    """Brief description.

    More detailed description.

    Keyword arguments:
    argument -- Argument description.
    """
    ...


Keep in mind though, if your code is self-commenting, and clearly written, the comments probably aren't needed.

Code Snippets

try:
    var1 = int(input( ... ))
    var2 = int(input( ... ))

    ...
except ValueError:
    print("Invalid input!")
    ...
OPERATIONS = {
    "+": add,
    "-": sub,
    ...
}
operation = input( ... )
if operation in OPERATIONS:
    OPERATIONS[operation](var1, var2)
else:
    print("Invalid operation!")
if condition:
    ...
if __name__ == "__main__":
    main()

Context

StackExchange Code Review Q#104593, answer score: 24

Revisions (0)

No revisions yet.