Skip to content

Simple Calculator

A calculator is the perfect second project. It is small enough to finish in one sitting and large enough to teach you the four pillars of procedural Python: functions, control flow, user input, and error handling. In this tutorial you will build a command-line calculator that performs the four basic operations plus square root and exponentiation, runs in a loop until the user chooses to exit, and handles invalid input gracefully.

By the end you will have practiced:

  • Defining and calling functions with parameters and return values.
  • Using the math module from Python’s standard library.
  • Branching with if/elif/else.
  • Looping with while True plus break.
  • Converting strings from input() into numbers using float().
  • Catching errors with try/except.
  • Python 3.6 or above.
  • A text editor or IDE (VS Code recommended).
  • Familiarity with running a Python file from the terminal (see Hello World).
ConceptWhat it is
FunctionA reusable named block of code. Defined with def.
ParameterA variable a function expects when called.
Return valueThe result a function hands back with return.
math moduleStandard-library module providing sqrt, pow, pi, log, etc.
Type conversionTurning a string like "3.14" into a float with float().
ExceptionAn error object Python raises when something goes wrong, such as dividing by zero.
  1. Make a folder named simple-calculator.
  2. Inside it, create a file named calculator.py.
  3. Open the folder in your code editor.

Paste the following into calculator.py:

Simple Calculator pch.viewSource
Simple Calculator
# Calculator Program

# Importing Modules
import math

# Defining Functions
def add(x, y):
    return x + y

def sub(x, y):
    return x - y

def mul(x, y):
    return  x * y

def div(x, y):
    return x / y

def sqrt(x):
    return math.sqrt(x)

def power(x, y):
    return math.pow(x, y)


# Main Program
print("Select Operation.")
print("1. Addition")
print("2. Subtraction")
print("3. Multiplication")
print("4. Division")
print("5. Square Root")
print("6. Power")
print("E. Exit")
print("R. Restart")

while True:
    choice = input("Enter Choice (1/2/3/4/5/6/E/R): ")

    if choice in ('1', '2', '3', '4', '5', '6'):
        num1 = float(input("Enter First Number: "))
        num2 = float(input("Enter Second Number: "))

        if choice == '1':
            print(num1, "+", num2, "=", add(num1, num2))

        elif choice == '2':
            print(num1, "-", num2, "=", sub(num1, num2))

        elif choice == '3':
            print(num1, "*", num2, "=", mul(num1, num2))

        elif choice == '4':
            print(num1, "/", num2, "=", div(num1, num2))

        elif choice == '5':
            print("Square Root of", num1, "=", sqrt(num1))
            print("Square Root of", num2, "=", sqrt(num2))

        elif choice == '6':
            print(num1, "to the power of", num2, "=", power(num1, num2))

    elif choice.upper() == 'E':
        confirm = input("Are you sure you want to exit? (Y/N): ")
        if confirm.upper() == 'Y':
            print("Exiting...")
            break
        elif confirm.upper() == 'N':
            print("Select Operation.")
            print("1. Addition")
            print("2. Subtraction")
            print("3. Multiplication")
            print("4. Division")
            print("5. Square Root")
            print("6. Power")
            print("E. Exit")
            print("R. Restart")
        else:
            print("Invalid Input")

    elif choice.upper() == 'R':
        print("Restarting...")
        print("Select Operation.")
        print("1. Addition")
        print("2. Subtraction")
        print("3. Multiplication")
        print("4. Division")
        print("5. Square Root")
        print("6. Power")
        print("E. Exit")
        print("R. Restart")

    else:
        print("Invalid Input")

Save the file. Open the terminal, cd to the folder, and run:

command
C:\Users\username\Documents\simple-calculator> python calculator.py
Select Operation.
1. Addition
2. Subtraction
3. Multiplication
4. Division
5. Square Root
6. Power
E. Exit
R. Restart
Enter Choice (1/2/3/4/5/6/E/R): 1
Enter First Number: 2
Enter Second Number: 4
2.0 + 4.0 = 6.0
Enter Choice (1/2/3/4/5/6/E/R): E
Are you sure you want to exit? (Y/N): Y
Exiting...

Read from the top: this is what runs when you execute the file, and which function calls which. It is generated from the code, so it cannot drift from it.

diagram Diagram mermaid
calculator.py
import math

The math module gives you mathematical helpers you would otherwise have to write yourself. We use math.sqrt(x) for square roots and math.pow(x, y) for exponentiation. (Python also has the ** operator for powers, but using math.pow keeps the code consistent and explicit.)

calculator.py
def add(x, y):
    return x + y
 
def subtract(x, y):
    return x - y
 
def multiply(x, y):
    return x * y
 
def divide(x, y):
    return x / y

Each function takes two numbers, performs one operation, and returns the result. This is separation of concerns — every piece does exactly one thing. It is easier to test, easier to read, and easier to extend.

calculator.py
while True:
    print("Select Operation.")
    print("1. Addition")
    # …
    choice = input("Enter Choice (1/2/3/4/5/6/E/R): ")

while True keeps the menu visible until the user explicitly exits. Without the loop, the program would run once and quit — frustrating for anyone doing several calculations in a row.

calculator.py
if choice == "1":
    num1 = float(input("Enter First Number: "))
    num2 = float(input("Enter Second Number: "))
    print(num1, "+", num2, "=", add(num1, num2))
elif choice == "2":
    # …
  • input() always returns a string. float() converts it to a floating-point number so arithmetic works.
  • The chain of if/elif/else picks the right function based on the menu choice.
  • An else at the bottom handles unknown inputs.
calculator.py
elif choice.upper() == "E":
    confirm = input("Are you sure you want to exit? (Y/N): ")
    if confirm.upper() == "Y":
        print("Exiting...")
        break

Using .upper() makes the check case-insensitive — e, E, y, and Y all work.

The version above crashes if a user types abc when asked for a number. Add a try/except block to handle it:

safer_input.py
def get_number(prompt):
    while True:
        try:
            return float(input(prompt))
        except ValueError:
            print("Please enter a valid number.")

Replace each float(input(...)) call with get_number("..."). Now a typo no longer crashes the program — it asks again.

Likewise, division by zero should be friendly, not fatal:

safe_divide.py
def divide(x, y):
    if y == 0:
        return "undefined (cannot divide by zero)"
    return x / y
ProblemWhat happenedFix
TypeError: can only concatenate strYou tried "=" + add(...) instead of using , in printUse commas in print or an f-string
ValueError: could not convert string to floatUser typed lettersWrap float(input(...)) in try/except
Loop never exitsbreak is indented wrong, or condition is always falseConfirm break is inside the if, not after it
Decimal results everywhereUsed float even for whole numbersDisplay with int(result) when you know it is whole, or format with f"{result:.2f}"
more_ops.py
def modulo(x, y):     return x % y
def floor_div(x, y):  return x // y
def factorial(n):     return math.factorial(int(n))
def log(x):           return math.log(x)

A growing if/elif chain becomes unwieldy. Replace it with a dictionary that maps choices to functions:

dispatch.py
OPERATIONS = {
    "1": ("Addition", add),
    "2": ("Subtraction", subtract),
    "3": ("Multiplication", multiply),
    "4": ("Division", divide),
}
 
choice = input("Choice: ")
if choice in OPERATIONS:
    name, func = OPERATIONS[choice]
    a, b = get_number("a: "), get_number("b: ")
    print(f"{name}: {func(a, b)}")

Adding a new operation is now one line.

Instead of menu-driven input, parse a typed expression like 2 + 3 * 4:

expr.py
import ast, operator as op
 
OPS = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, ast.Div: op.truediv}
 
def evaluate(node):
    if isinstance(node, ast.Constant):
        return node.value
    if isinstance(node, ast.BinOp):
        return OPS[type(node.op)](evaluate(node.left), evaluate(node.right))
    raise ValueError("unsupported")
 
tree = ast.parse("2 + 3 * 4", mode="eval")
print(evaluate(tree.body))   # 14

This safely evaluates math expressions without using the dangerous built-in eval().

Use Tkinter to build buttons in a grid. See the Calculator GUI project on Python Central Hub for a full walkthrough.

Keep a list of past results and let the user reuse the previous answer with ans:

history.py
history = []
# after each successful calc:
history.append(result)
# allow input "ans" to mean history[-1]
  • One function, one job. Each operation is its own function.
  • Use the standard library. math is already there — do not roll your own square root.
  • Validate at the boundary. Convert and check input the moment it enters the program.
  • Handle errors close to where they happen. Division by zero is a divide() problem, not a whole program problem.
  • Interactive shells for scientific work (think mini-REPL).
  • Form back-ends that compute totals from user input.
  • Bot commands (!calc 2+2) in Discord/Slack integrations.
  • Foundations for spreadsheet engines and expression evaluators.

Extend the calculator with any of these:

  • Trigonometry: math.sin, math.cos, math.tan (remember to convert degrees with math.radians).
  • Memory keys: M+, M-, MR, MC like a real desktop calculator.
  • Calculation history file: persist results to history.txt so they survive restarts.
  • Unit conversion mode: kilometers ↔ miles, kilograms ↔ pounds, etc.
  • Graphing mode: pair with matplotlib to plot a function the user types.

A calculator looks simple, but it is one of the most honest beginner projects: every feature you add forces you to write better code. You used Python’s built-in math module, separated each operation into its own function, looped a menu, and converted user input safely. Find more progressive beginner projects on Python Central Hub. The full source is on GitHub.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading