DEV Community

Cover image for Your Code Is Always Asking Questions — Here's the Rulebook It Uses
Ebenezer
Ebenezer

Posted on

Your Code Is Always Asking Questions — Here's the Rulebook It Uses

Hey guys!

Today, I’m starting a new series on Python.

A few days ago, a special Python session started at our institute, and that’s what inspired me to begin this series. From now on, we’ll be discussing many interesting concepts, programs, and practical topics together — not only in future blogs, but starting from today itself.

Honestly, the session began three days ago, but I didn’t even attempt to write a blog about it. Still, it’s better to start late than never. From now on, I’ll try my best to publish the blog the very next day after each session, so keep your fingers crossed.

On the very first day, the topic was Conditional Statements. As we already know, conditional statements are a subset of control flow statements and play a major role in decision-making within programming.

In this blog, I’ve explained the concepts in a simple and beginner-friendly way. I’ve also included the important points, discussions, and insights that I noted during the session

When you write your first few lines of code, it looks like giving instructions. You tell the machine to do something, and it does it. Simple enough.

But the more you write, the more you realize something strange. Code doesn't just run — it constantly evaluates. Every line is a small judgment. Every condition is a question waiting to be answered. And underneath all of that, there are rules your program follows without ever telling you.

This post is about three of those rules. They come from three different directions — control flow, type systems, and boolean evaluation — but they're all part of the same conversation. Once you understand how they connect, the way you read code changes. Not just syntactically. Conceptually.

Let's build that understanding from the ground up.


Part 1 — The Road That Forks: Conditionals and Control Flow

What actually happens when code runs

By default, a program reads top to bottom. Line 1 executes, then line 2, then line 3. Every beginner's first program works exactly like this — and for a few days, that feels like enough.

Then you hit a problem that requires a decision. "If the user is logged in, show the dashboard. Otherwise, show the login page." Suddenly, a straight line doesn't work anymore. You need a fork in the road. That's exactly what control flow gives you.

Control flow is the set of rules that determines which lines of code actually execute, and in what order. Without it, every program would be a list of instructions that always runs the same way — regardless of input or situation. That's not a program. That's a script.

How conditionals create a choice at every crossroad

The if statement is the most fundamental decision-making tool in programming. It evaluates a condition, and if that condition is true, it runs a block of code. If it's false, it skips it — or runs an alternate block through else.

score = 85

if score >= 90:
    print("Grade: A")
elif score >= 75:
    print("Grade: B")
else:
    print("Grade: C")
Enter fullscreen mode Exit fullscreen mode

Here's where most beginners get confused. They use multiple separate if statements when they should be using elif. The difference isn't cosmetic — it changes the logic entirely.

When you chain elif, only the first true condition executes. The rest are skipped. When you write multiple standalone if statements, each one runs independently. If more than one condition is true, multiple blocks execute — and that can create bugs that are painful to track down because the code looks correct.

Python doesn't have a traditional switch statement — but from Python 3.10 onwards, match fills that role cleanly.

day = "Monday"

match day:
    case "Monday":
        print("Start of the week")
    case "Friday":
        print("Almost there")
    case _:
        print("Just another day")
Enter fullscreen mode Exit fullscreen mode

Loops — when the road circles back

Conditionals handle choices. Loops handle repetition. A for loop in Python runs over a sequence. A while loop runs as long as a condition stays true. If that condition never becomes false, the loop never stops — that's an infinite loop, one of the most common beginner mistakes.

for i in range(5):
    print("Iteration:", i)

# Output: 0, 1, 2, 3, 4
Enter fullscreen mode Exit fullscreen mode

Control flow isn't just a feature of a language. It's the core mechanism that makes programs dynamic. Without it, software couldn't respond to users, handle different inputs, or make decisions at scale.

What's the actual difference between if/elif and match?

Use if/elif when your conditions involve ranges, multiple variables, or complex expressions. Use match when you're comparing a single variable against a fixed list of values. One isn't better — they solve slightly different problems. Choosing the right one makes your code easier to read, which matters more than most beginners expect.


Part 2 — The Language's Promise: Static vs. Dynamic Typing

What does "type" even mean in a program?

Every piece of data in a program has a type. A number is not the same as a word. A true/false value is not the same as a decimal. Type is how the language categorizes what a value is, so it knows what operations are valid on it.

You can't divide a name by 2. You can't add two booleans and get a meaningful number. Types are the boundaries that keep these situations from silently breaking your program.

Dynamic typing — Python's way of figuring it out as you go

Python is a dynamically typed language. You don't declare the type of a variable — Python figures it out at runtime based on what you assign to it. And you can reassign it to a completely different type later without any complaint.

value = 42           # Python sees: int
value = "forty-two"  # now it's str — no error
value = True         # now it's bool — still no error

print(type(value))   # <class 'bool'>
Enter fullscreen mode Exit fullscreen mode

This flexibility makes Python fast to write in, especially when prototyping. But type-related bugs in dynamic languages don't surface until the code actually runs — sometimes in production, when a user hits a path you didn't test.

Static typing — when Python asks you to commit upfront

Python introduced optional type hints to bring some of the safety of static typing into a dynamic world. Tools like mypy can catch type mismatches before you run the code.

def add_score(score: int, bonus: int) -> int:
    return score + bonus

add_score(85, 10)       # ✓ correct
add_score(85, "ten")    # mypy flags this — types don't match
Enter fullscreen mode Exit fullscreen mode

The hints don't change how Python runs the code. But they tell other developers — and static analysis tools — what types are expected. It's Python giving you a choice: stay flexible, or opt into safety where it matters.

Which is better — dynamic or static typing for a beginner?

Dynamic typing lets you start writing logic immediately — which is why Python is one of the best first languages. But as your programs grow, type hints become valuable. They catch bugs earlier, make your code easier to read, and prepare you for statically typed languages like Java or Go.

The real insight: static typing is safety traded for flexibility. Dynamic typing is flexibility traded for safety. Python gives you both options — which is rare, and worth understanding.


Part 3 — The Liars in Your Conditions: Truthy and Falsy

Why every value has a secret boolean identity

In Python, every single value has an implicit boolean identity. When it's placed inside a condition, Python converts it to either True or False automatically. This behavior is called type coercion, and it's the engine behind truthy and falsy values.

name = "Ebenezer"

if name:
    print("Name exists")  # runs — non-empty string is truthy
Enter fullscreen mode Exit fullscreen mode

The if block runs because "Ebenezer" is a non-empty string — and non-empty strings are truthy. You didn't check name == True. You didn't compare it to anything. Python evaluated the value in a boolean context and decided it was truthy. That decision follows a specific set of rules.

The exclusive falsy club

In Python, only a specific set of values evaluate to False in a boolean context. Everything else is truthy.

False        # boolean false
0            # integer zero
0.0          # float zero
0j           # complex zero
""           # empty string
[]           # empty list
{}           # empty dict
()           # empty tuple
None         # absence of value
Enter fullscreen mode Exit fullscreen mode

None represents the absence of a value. An empty string has no content. An empty list has no elements. And 0 is numerically zero. Python treats all of these as "nothing meaningful is here" — which maps to False.

The classic 0 bug — and why it silently breaks real programs

Let's say you're building a form that asks for a price, and the user enters 0 — a valid input, meaning the item is free.

price = 0

if price:
    print("Price:", price)
else:
    print("No price entered")  # ← this runs. oops.
Enter fullscreen mode Exit fullscreen mode

This prints "No price entered" — even though the user clearly typed something. The number 0 is falsy, so the condition fails silently. This is a real bug that appears in production code more often than it should.

The fix is to be explicit about what "missing" actually means.

price = 0

if price is not None:
    print("Price:", price)   # ✓ now runs correctly

# Or with a default fallback using conditional expression
final_price = price if price is not None else "No price entered"
print(final_price)  # 0
Enter fullscreen mode Exit fullscreen mode

Why does Python treat 0 as False when it's a valid value?

Because truthy/falsy was designed for convenience, not precision. It lets you write shorter conditions for common cases. For most situations, coercion works exactly the way you'd expect. The problem is that 0 sits at an edge — numerically nothing, but semantically real.

You can always check how any value behaves using the built-in bool() function.

print(bool(0))      # False
print(bool(""))     # False
print(bool([]))     # False
print(bool(1))      # True
print(bool("hi"))   # True
print(bool([1,2]))  # True
Enter fullscreen mode Exit fullscreen mode

The Bigger Picture

These three ideas — control flow, typing systems, and truthy/falsy evaluation — aren't isolated features you learn once and file away. They interact constantly.

Your if statement depends on control flow. The condition inside it may be affected by truthy/falsy coercion. Whether that coercion causes problems depends on how carefully you handle types. Pull one thread and you find it's connected to the others.

Every program, at its core, is a logic machine. It receives information, evaluates it, makes a decision, and moves forward. The rules that govern how values are interpreted, how types are inferred, and how execution branches — those are the rules underneath everything.

Once you see that, code stops looking like a list of commands. It starts looking like a structured conversation between you and the machine. And that conversation has a very specific grammar.


References & Resources

  1. Python Docs — Control Flow Tools
    https://docs.python.org/3/tutorial/controlflow.html

  2. Real Python — Conditional Statements in Python
    https://realpython.com/python-conditional-statements/

  3. GeeksforGeeks — Control Flow in Programming
    https://www.geeksforgeeks.org/computer-science-fundamentals/control-flow-statements-in-programming/

  4. Orient Software — Dynamic Typing vs Static Typing
    https://www.orientsoftware.com/blog/dynamic-typing-vs-static-typing/

  5. TechTarget — Static vs Dynamic Typing: The Details and Differences
    https://www.techtarget.com/searchapparchitecture/tip/Static-vs-dynamic-typing-The-details-and-differences

  6. Python Docs — Built-in Types: Truth Value Testing
    https://docs.python.org/3/library/stdtypes.html#truth-value-testing

  7. Real Python — Python Type Checking (mypy Guide)
    https://realpython.com/python-type-checking/

Top comments (0)