Skip to content
Happy Programming Guide
Start learning
Programming Projects

Python Project: Build a Calculator

A menu-driven Python calculator built with functions and a dictionary. Full code with error handling for division by zero and invalid input.

A calculator is the classic second project. It looks trivial and quietly teaches you functions, dictionaries, validation and program structure.

What you will build#

Output
Simple Calculator
  +  add        -  subtract
  *  multiply   /  divide
  q  quit

Operation: *
First number: 7
Second number: 6
7.0 * 6.0 = 42.0

Step 1: one operation per function#

Python
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def multiply(a, b):
    return a * b

def divide(a, b):
    if b == 0:
        return None          # signal "not possible"
    return a / b

Each function does one thing and returns a value rather than printing. That separation is what makes them reusable — see Python functions explained.

Step 2: a dictionary instead of a long if chain#

Python
OPERATIONS = {
    "+": add,
    "-": subtract,
    "*": multiply,
    "/": divide,
}

symbol = "+"
result = OPERATIONS[symbol](3, 4)     # 7

Functions are values in Python, so you can store them in a dictionary and look one up. Adding a new operation later becomes a one-line change instead of another elif.

Step 3: read numbers safely#

Python
def ask_number(prompt):
    while True:
        raw = input(prompt)
        try:
            return float(raw)
        except ValueError:
            print("Please enter a number.")

The loop keeps asking until it gets something usable. float rather than int so decimals work.

The finished program#

Python
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def multiply(a, b):
    return a * b

def divide(a, b):
    if b == 0:
        return None
    return a / b

OPERATIONS = {
    "+": add,
    "-": subtract,
    "*": multiply,
    "/": divide,
}

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

def show_menu():
    print()
    print("Simple Calculator")
    print("  +  add        -  subtract")
    print("  *  multiply   /  divide")
    print("  q  quit")

def main():
    while True:
        show_menu()
        symbol = input("Operation: ").strip()

        if symbol == "q":
            print("Goodbye.")
            break

        if symbol not in OPERATIONS:
            print("Unknown operation. Try +, -, * or /.")
            continue

        a = ask_number("First number: ")
        b = ask_number("Second number: ")

        result = OPERATIONS[symbol](a, b)

        if result is None:
            print("Cannot divide by zero.")
        else:
            print(f"{a} {symbol} {b} = {round(result, 4)}")

main()

How the code works#

  • main() holds the loop; every other function does one small job.
  • .strip() removes stray spaces so ” + ” still works.
  • if symbol not in OPERATIONS validates before doing any work.
  • divide returns None rather than printing, so the display logic stays in one place.
  • round(result, 4) hides floating-point noise like 0.30000000000000004.

Questions people ask#

Should I use eval() to evaluate expressions?

No. eval runs whatever text it is given, which is a serious security problem if that text ever comes from someone else. Parse it yourself, or use a library built for the job.

Why float instead of int?

So decimals work. If you want whole numbers only, use int() and tell the user.

How do I turn this into a GUI app?

Keep these functions exactly as they are and add a tkinter interface that calls them. That is the payoff of separating logic from input and output.

Where to go next#

Next projectBuild a Python to-do list

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *