DEV Community

Enayet Rashid
Enayet Rashid

Posted on

From if Statements to Classes: How Refactoring Taught Me Testable Code

From Inline Code to OOP: What Building a Python Calculator Taught Me About Testability

I am a self-taught learner. So when I decided to build a Python calculator, I didn't start with classes or design patterns. I started with the messiest, most beginner thing possible — everything crammed into one script. And honestly? That was the right decision.

This article is about how I evolved that calculator through three versions, and what each step taught me about writing code that's actually testable — which matters a lot when you're learning QA automation like I am.

👉 GitHub: https://github.com/enayetrashid/python-calculator-evolution


Version 1: The "Just Make It Work" Phase

My first version was pure chaos by design. No functions, no classes; just raw logic from top to bottom.

a = float(input("Enter first number: "))
b = float(input("Enter second number: "))
operation = input("Enter operation (+, -, *, /): ")

if operation == "+":
    print(a + b)
elif operation == "-":
    print(a - b)
elif operation == "*":
    print(a * b)
elif operation == "/":
    print(a / b)
Enter fullscreen mode Exit fullscreen mode

It worked. But the moment I asked myself "how do I test this?" I had no answer. You can't test code that demands user input just to run. This was my first real lesson:

If input and logic live together, testing becomes nearly impossible.


Version 2 — Introducing Functions

I pulled the calculation logic out into separate functions. A small change — but it changed everything.

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

def subtract(a, b):
    return a - b
Enter fullscreen mode Exit fullscreen mode

Now I could write an actual test:

def test_add():
    assert add(2, 3) == 5
Enter fullscreen mode Exit fullscreen mode

No input prompts. No manual interaction. Just pure logic I could verify instantly. This felt like a superpower.

The lesson: Functions are the foundation of testable code. If you can't call it in isolation, you can't test it properly.


Version 3 — Moving to OOP

Finally I wrapped everything in a class and added proper error handling:

class Calculator:
    def add(self, a, b):
        return a + b

    def divide(self, a, b):
        if b == 0:
            raise ZeroDivisionError("Division by zero")
        return a / b
Enter fullscreen mode Exit fullscreen mode

The divide method was a turning point for me. Adding that guard clause meant I could now test failure scenarios too — not just the happy path.

def test_divide_by_zero():
    calc = Calculator()
    with pytest.raises(ZeroDivisionError):
        calc.divide(10, 0)
Enter fullscreen mode Exit fullscreen mode

The lesson: OOP isn't just about organisation — it's about making your code extensible and testable at scale.


Why This Matters Beyond the Calculator

I'm learning QA automation, and this little project taught me something that no tutorial explained clearly:

The structure of code directly affects how easy it is to test.

In real automation work with tools like Pytest or Playwright, you never test everything in one place. You separate test logic, business logic, and test data. This calculator evolved through exactly that same pattern:

Version Structure Testability
Version 1 Everything inline Nearly impossible to test
Version 2 Functions Testable in isolation
Version 3 OOP Scalable and extensible

Key Takeaways

  • Start simple — but don't stay simple
  • Refactoring is a skill, not just a task
  • Testability should guide your design decisions from the beginning
  • Even the smallest projects can teach big engineering concepts

Final Thought

This wasn't really about building a calculator. It was about learning to think like someone who cares about quality — not just getting something to run, but building it so it can be verified.

What's the simplest project that taught you something fundamental? I'd love to hear it in the comments.


I'm a self-taught QA learner from Bangladesh documenting my journey into software testing and automation. If you're on a similar path, feel free to connect!

Top comments (0)