1. Letting Python Think for You

In every automation task, especially those involving computer networks, making decisions is at the core of the process. Imagine you're monitoring hundreds of devices in a network, and your automation script needs to know whether a router is healthy, if an interface is down, or whether a link’s latency has exceeded acceptable thresholds. How does your code “decide” what to do next?

That’s where comparators and conditionals come in.

They give your Python code the ability to evaluate, choose, and react. These are the tools that enable scripts to branch off and make decisions dynamically, such as “If this interface is down, raise an alert” or “If packet loss exceeds 2%, log an incident.”

This article introduces you to:

  • Python comparators (also known as relational operators), which help you compare two values or states, like is X greater than Y? or does A equal B?

  • Conditionals, such as if, else, and elif, which lets your code take action based on those comparisons.

  • Logical operators, like and, or, and not, which allows combining multiple conditions for more complex logic.

These are core programming concepts, and when paired with your networking expertise, they become the foundation of powerful decision-making automation logic. Whether you’re building a topology validator, a telemetry parser, or a custom monitoring agent, understanding Python’s comparison and conditional structures is non-negotiable.

Why This Matters in Networking

In real-world network engineering, you are constantly evaluating things like:

  • Interface utilization: Is it over 80%? If so, alert.

  • BGP neighbor state: Is it “Established”? If not, log and notify.

  • Device inventory match: Does the current OS version match the golden config?

  • Reachability: Is the device responding to ICMP or SNMP? If not, retry. If still down, escalate.

You’ll see all these use cases, and more, brought to life in this article.

What You’ll Learn

By the end of this post, you will:

Understand all six Python comparators and how to use them with numbers, strings, and variables
Write clear, efficient conditional logic using if, elif, and else
Combine multiple comparisons into smart decisions using and, or, and not
Apply all of this to realistic network automation problems, with example code and step-by-step explanations
Run the exercises and experiment in your own IDE to develop deep familiarity

So open your Python editor or Jupyter Notebook, because you’re not just going to read about comparators: you’re going to test them, break them, and understand how they become part of your network engineer’s toolkit.

Let’s dive in.

2. Understanding Python Comparators

Comparators, also known as relational operators, allow Python to compare values and return a Boolean: either True or False.

This is where your script starts “thinking.”

Let’s walk through each comparator, provide realistic examples, and help you understand how to use them effectively, especially in network automation workflows.

What Are Python Comparators?

Here are the six comparators in Python:

Comparator

Symbol

Example

Description

Less than

<

latency < 100

True if the left value is strictly less than the right value

Less than or equal

<=

cpu_load <= 85

True if the left value is less than or equal to the right value

Equal to

==

ospf_state == "FULL"

True if both sides are equal

Greater than or equal

>=

routes >= 5000

True if left is greater than or equal to right

Greater than

>

flaps > 3

True if left is strictly greater than right

Not equal to

!=

bgp_state != "Idle"

True if both sides are not equal

Each of these operators returns a boolean result (True or False), which we then use inside conditional logic like if statements.

Examples in Network Engineering

Let’s say we’re writing a Python script to monitor various parameters from a device’s telemetry API or CLI command output.

Example 1: Check Interface Utilization

interface_utilization = 92  # percent

if interface_utilization > 90:
    print("⚠️ High interface utilization!")

Comparator used: >
Result: Since 92 is greater than 90, the condition is True and the alert is triggered.

Example 2: Confirm BGP Peer State

bgp_state = "Established"

if bgp_state == "Established":
    print("✅ BGP peer is up and stable.")

Comparator used: ==
We compare the current BGP session state against the string "Established". This is commonly retrieved via Netmiko, NAPALM, RESTCONF, or raw CLI scraping.

Example 3: Verify Config Drift

running_config_lines = 850
golden_config_lines = 850

if running_config_lines != golden_config_lines:
    print("⚠️ Config drift detected.")
else:
    print("✅ Configuration matches golden state.")

Comparator used: !=
Here we use != to detect if a device has deviated from its standard configuration template.

Example 4: Loop Latency Validation

latency_ms = 65

if latency_ms <= 100:
    print("✅ Latency is within acceptable range.")

Comparator used: <=
A typical example in WAN monitoring or overlay routing validation.

How to Think Like a Network Engineer

Before writing code with comparators, ask:

  1. What am I trying to verify? (e.g., CPU usage, session count, error rate)

  2. What’s the threshold or baseline? (numerical or categorical)

  3. What should happen if the condition is met or not met? (log it, alert, exit, retry, etc.)

For instance:

  • "If the LLDP neighbor is not what I expect, exit the script."

  • "If packet loss is greater than 2%, log a warning."

  • "If the number of received prefixes equals the expected number, test passes."

Time to Practice

Try this exercise in your Python editor:

cpu = 72
memory = 60

print("High CPU?", cpu > 80)
print("Safe memory?", memory <= 70)
print("Is CPU exactly 72%?", cpu == 72)
print("Is CPU not at 100%?", cpu != 100)

Play around with the values. Change cpu to 85, memory to 75, or test a condition like cpu >= memory. See how the Boolean results change and think through why.

3. Conditional Logic in Python (if / elif / else)

In the previous section, you learned that comparators return Boolean values (True or False). Now we’ll see how to use those Booleans to make decisions in your Python code.

This is where Python becomes truly dynamic, where it starts reacting to changing states and outcomes. This is critical in network automation, where conditions are always in flux: links flap, routes change, devices reboot, peers fail.

Let’s break it down.

Why Do Network Engineers Need Conditionals?

In networking, we constantly face “if... then...” logic:

  • If a peer is not Established, then send an alert.

  • If an interface is up and bandwidth > 90%, then raise capacity warning.

  • If LLDP neighbor is missing, then stop configuration deployment.

Python’s if, elif, and else statements are the core building blocks to implement this logic.

Basic Syntax

if condition:
    # Do something
elif another_condition:
    # Do something else
else:
    # Fal
  • The block after each condition is indented; Python requires this to define scope.

  • Conditions must evaluate to a boolean: True or False.

  • Execution will stop at the first True condition.

Example 1: Routing Table Validation

bgp_received_routes = 4900

if bgp_received_routes > 5000:
    print("✅ Routes look healthy.")
elif bgp_received_routes >= 4000:
    print("⚠️ Slightly below expected route count.")
else:
    print("❌ Route count too low! Check upstream.")

In this script, we check route count thresholds and take different actions depending on the received value.

Example 2: Redundant Path Check

Let’s say you’re verifying link redundancy based on interface status.

uplink1 = "up"
uplink2 = "down"

if uplink1 == "up" and uplink2 == "up":
    print("✅ Both uplinks operational.")
elif uplink1 == "up" or uplink2 == "up":
    print("⚠️ Partial redundancy. Investigate secondary path.")
else:
    print("❌ Both uplinks are down. Major outage!")

Here, we combine conditions using and and or, two logical operators that evaluate multiple booleans.

Nested Conditionals

You can nest one if block inside another to perform deeper checks.

interface_status = "up"
utilization = 92

if interface_status == "up":
    print("✅ Interface is UP")
    if utilization > 90:
        print("⚠️ High utilization warning!")
    else:
        print("✅ Utilization is normal.")
else:
    print("❌ Interface is down.")

Example 3: Inventory-Based Conditional

You’re verifying if a device model is compatible with your automation tooling:

model = "NCS5501"

supported_models = ["NCS5501", "ASR9001", "MX960"]

if model in supported_models:
    print(model, "is supported ✅")
else:
    print(model, "is not supported ❌")

This is an elegant use of in with collections, a great trick for config drift checks, hardware eligibility, or access control.

Shorthand If-Else (Ternary Operator)

Sometimes, you want a single-line condition:

latency = 110
print("✅ Good") if latency < 100 else print("❌ Too high")

Or more complex:

print("A") if a > b else print("=") if a == b else print("B")

Use these sparingly. While compact, they’re harder to read for junior engineers.

Challenge Exercise

Create a script that:

  1. Accepts three input values from the user: ping_latency, interface_status, and device_role.

  2. Based on these inputs, prints:

    • Whether the device is reachable.

    • If the link status is healthy.

    • Whether the device is a core or edge node, and if it should raise alarms based on role.

Example inputs:

ping_latency = 150
interface_status = "up"
device_role = "core"

Then compare against thresholds (e.g. latency > 120 for core nodes should alarm, > 200 for edge).

Write it yourself, and in the next section, we’ll review a complete solution.

4. Boolean Logic: The Brains Behind Conditions

When writing conditionals, we often need to evaluate multiple conditions simultaneously. This is where Boolean logic operators, and, or, and not come in.

If comparators are your sensors, Boolean logic is your circuit board, deciding how the signals should be combined to produce a final decision.

Let’s break them down and teach you how to think with them.

and : All Conditions Must Be True

The and operator returns True only when both conditions are true.

cpu = 40
memory = 70

if cpu < 50 and memory < 80:
    print("System is healthy ✅")
else:
    print("Check system load ❌")

In networking, you might check if BGP is established AND latency is under the threshold.

bgp_status = "Established"
latency = 90

if bgp_status == "Established" and latency < 100:
    print("✅ Peer is stable and performing well.")

or : At Least One Must Be True

The or operator returns True if any one of the conditions is true.

is_ospf_enabled = False
is_bgp_enabled = True

if is_ospf_enabled or is_bgp_enabled:
    print("✅ At least one routing protocol is active.")
else:
    print("❌ No routing protocols are active!")

You’ll use this in networking when you have multiple acceptable states or fallback paths.

not : Inverts the Result

The not operator flips True to False and vice versa.

link_status = "down"

if not link_status == "up":
    print("❌ Link is not up!")

You can also write it more naturally:

if link_status != "up":
    print("❌ Link is not up!")

Use not when you want to act on the absence or negation of a condition.

Thinking in Boolean Logic

Here’s a networking problem: You’re checking if a redundant link can be used.

link_a = "down"
link_b = "up"

if link_a == "up" or link_b == "up":
    print("✅ At least one uplink is available.")
else:
    print("❌ No uplinks available.")

If both are down:

if not (link_a == "up" or link_b == "up"):
    print("🚨 Failover failure detected!")

This nested thinking, utilizing parentheses to group evaluations, becomes particularly powerful when dealing with complex logic.

Use Case: BGP Peer Health Check

Here’s an example that mixes all three operators.

bgp_state = "Established"
prefix_count = 4500
max_latency = 100

if bgp_state == "Established" and prefix_count > 4000 and not max_latency > 120:
    print("✅ BGP peer is healthy.")
else:
    print("❌ BGP peer health check failed.")

This is a perfect example of chaining conditions and using not for negation of a threshold.

Use the Right Operator

Use Case

Operator

Require multiple conditions

and

Accept any condition

or

Reverse a condition

not

Try This Challenge

Build a script that:

  • Takes input for ospf_status, interface_status, and jitter.

  • If OSPF is up, the interface is up, and jitter < 30, print “ Path stable”.

  • If any one of the conditions fails, print “⚠️ Path may be unstable”.

Test it in your Python environment, then compare it to the sample solution we’ll provide later.

5. Writing Cleaner Code with Shorthand If/Else

Sometimes, your logic is so simple that writing a full-blown if...else block feels unnecessarily verbose. That’s when Python’s shorthand conditional comes into play, great for inline decisions, especially in network scripts where space and clarity matter.

Let’s walk through how this works.

Basic Shorthand if

Instead of:

if link_state == "up":
    print("Link is operational.")

You can write:

if link_state == "up": print("Link is operational.")

This one-liner is handy when you're just triggering a log or simple action.

Shorthand if ... else

Let’s say you want to assign a label based on a latency threshold:

latency = 85
status = "Good" if latency < 100 else "Poor"
print(status)

Output:

Good

Here, you’re assigning a value based on a condition; no need for multiline blocks. Perfect for:

  • Tagging interfaces with "healthy" or "congested"

  • Setting alert levels

  • Choosing between backup paths

Nested Ternary Expressions

You can even nest shorthand expressions. While readability should always be a priority, there are cases where it’s elegant to do so.

latency = 120
label = "Excellent" if latency < 80 else "Acceptable" if latency < 100 else "Degraded"
print(label)

Output:

Degraded

Use this with care. It's helpful in dashboards or alerts where compact classification logic is needed.

Network Engineering Example

Let’s classify link performance with shorthand expressions:

latency = 90
jitter = 25

quality = (
    "Excellent"
    if latency < 50 and jitter < 10
    else "Good"
    if latency < 100 and jitter < 30
    else "Poor"
)

print("Link Quality:", quality)

Output:

Link Quality: Good

This is particularly useful when calculating health scores or link labels in automation scripts, such as when sending data to a monitoring API.

⚠️ When Not to Use It

Shorthand expressions are great, but don’t sacrifice readability for compactness. Avoid nesting ternaries too deeply, especially if you're performing actions rather than just assigning values.

Good:

label = "Active" if is_up else "Inactive"

Avoid:

label = "Fast" if speed > 1000 else "Moderate" if speed > 500 else "Slow" if speed > 100 else "Dead"

In that case, better to use a function or if/elif/else chain for clarity.

Shorthand in Action: Network State Labeling

Let’s try a script together. This will label interfaces based on both status and errors.

interface_status = "up"
error_count = 0

label = (
    "Healthy"
    if interface_status == "up" and error_count == 0
    else "Warning"
    if interface_status == "up" and error_count > 0
    else "Down"
)

print(f"Interface State: {label}")

Try changing the error_count and interface_status and observe how the label adjusts. This pattern is commonly found in dashboards, CLI reports, or small REST API implementations.

Summary

Need

Use

Simple one-line conditional

if inline

Assign values based on condition

x = a if condition else b

Chain multiple evaluations

Nested ternary (with caution!)

Coming up next: Max, Min, and Comparison in Action, where I'll show you how to compare more than two values efficiently using Python’s built-in functions and tie that directly into network use cases.

6: Comparing Multiple Values with max() and min()

In network engineering, you often need to determine:

  • The interface with the highest bandwidth usage

  • The site with the lowest latency

  • The BGP peer with the highest number of received prefixes

Rather than writing long chains of if/elif comparisons, Python gives us a built-in way to handle this efficiently and readably.

Basic Usage of max() and min()

These functions return the maximum or minimum value from an iterable or multiple arguments.

max_value = max(10, 20, 30)
print(max_value)  # Output: 30

Likewise:

min_value = min(10, 20, 30)
print(min_value)  # Output: 10

That’s just the beginning. Let’s go deeper.

Network Engineering Use Case

Let’s say you have bandwidth utilization data across three interfaces:

intf_bandwidth = {
    "Gig0/0": 450,
    "Gig0/1": 875,
    "Gig0/2": 320
}

You want to find out which interface has the highest usage.

Using max() with a custom key:

most_utilized = max(intf_bandwidth, key=intf_bandwidth.get)
print(f"The busiest interface is {most_utilized} with {intf_bandwidth[most_utilized]} Mbps.")

Output:

The busiest interface is Gig0/1 with 875 Mbps.

This is clean, Pythonic, and very useful in automation dashboards, alerting systems, or configuration generation logic.

Finding the Interface with the Least Errors

You can do the opposite using min():

intf_errors = {
    "Gig0/0": 10,
    "Gig0/1": 2,
    "Gig0/2": 5
}

cleanest_intf = min(intf_errors, key=intf_errors.get)
print(f"The interface with the fewest errors is {cleanest_intf}.")

Output:

The interface with the fewest errors is Gig0/1.

This kind of snippet is perfect for daily health check scripts or dynamic reporting tools.

Using max() with Lists of Tuples

You can combine data into tuples and extract based on specific values.

prefix_data = [("192.0.2.0/24", 120), ("198.51.100.0/24", 300), ("203.0.113.0/24", 180)]
most_received = max(prefix_data, key=lambda x: x[1])
print(f"Prefix {most_received[0]} received {most_received[1]} routes.")

Output:

Prefix 198.51.100.0/24 received 300 routes.

This style helps when processing parsed outputs from APIs, netmiko/napalm facts, or structured logs.

Comparison vs Conditional Chains

Let’s pause and compare. Which one is easier to maintain?

Option A: if/elif chain

if latency1 > latency2 and latency1 > latency3:
    best = latency1
elif latency2 > latency3:
    best = latency2
else:
    best = latency3

Option B: max()

best = max(latency1, latency2, latency3)

Use max() and min() when you need a single value out of multiple options, it is more readable and less error-prone.

Practice Exercise

Try this in your IDE:

# Sample interface error rates
interface_errors = {
    "eth0": 8,
    "eth1": 0,
    "eth2": 3,
    "eth3": 0
}

# Find most and least problematic interfaces
most_errors = max(interface_errors, key=interface_errors.get)
least_errors = min(interface_errors, key=interface_errors.get)

print(f"Most errors: {most_errors} ({interface_errors[most_errors]} errors)")
print(f"Least errors: {least_errors} ({interface_errors[least_errors]} errors)")

Now modify the dictionary, run again, and observe how dynamic and reliable your logic becomes.

When Should You Use This?

Situation

Use max() / min()?

Why

Selecting highest/lowest from multiple values

Yes

Clean and readable

Comparing across dictionary values

Yes

One-liner with .get

Conditional logic based on "biggest/smallest"

Yes

Avoid nested if/elif

Complex multi-condition decisions

No

Use if chains instead

7. Logical Operators (and, or, not) in Automation Decisions

In real-world network automation, we often make decisions based on multiple conditions. For example:

  • Is a device reachable and is the interface status up?

  • Is a BGP session down or is the prefix count abnormal?

  • Should I trigger a config push only if certain features are not active?

For these types of compound logic flows, Python provides three fundamental logical operators:

Operator

Description

Example

and

True if both operands are true

if is_up and has_ip:

or

True if at least one operand is true

if bgp_down or prefix_abnormal:

not

Inverts the result

if not is_compliant:

Let’s break this down into network-related examples.

Using and: Multiple Conditions Must Be Met

Let’s imagine a device monitoring scenario where we only want to send an alert if the interface is administratively up and has traffic above a threshold.

interface_status = "up"
traffic_rate = 750  # Mbps

if interface_status == "up" and traffic_rate > 700:
    print("⚠️ High traffic alert on active interface!")

Output:

⚠️ High traffic alert on active interface!

The alert only triggers if both conditions are true.

Using or: Trigger Action if One of Many Is True

In this case, let’s say we’re auditing compliance and want to trigger an action if either the router is not running the latest firmware or the configuration is not validated.

firmware_up_to_date = False
config_valid = True

if not firmware_up_to_date or not config_valid:
    print("⚠️ Device requires attention: audit failed.")

Output:

⚠️ Device requires attention: audit failed.

Using not: Reversing a Condition

Let’s imagine a condition where we want to skip a device only if it is already compliant:

is_compliant = True

if not is_compliant:
    print("🚨 Push remediation!")
else:
    print("✅ Device is compliant, no action needed.")

Output:

✅ Device is compliant, no action needed.

Chaining Logical Conditions

You can chain multiple conditions together to build richer logic:

is_up = True
bgp_established = False
load = 65

if is_up and not bgp_established and load > 50:
    print("⚠️ Interface is up but BGP down and load high — investigate!")

Output:

⚠️ Interface is up but BGP down and load high — investigate!

Network Use Case

Let’s simulate a condition where a device:

  • Must be in production

  • Must not have failed its health check

  • Must not be under a maintenance window

Only then should we trigger a config deployment.

in_production = True
health_check_passed = True
under_maintenance = False

if in_production and health_check_passed and not under_maintenance:
    print("🚀 Safe to deploy configuration!")
else:
    print("🛑 Deployment blocked due to failed checks.")

This is the kind of logic you’d use in CI/CD pipelines, orchestration systems, or custom automation scripts.

Practice Exercise

Try this in your IDE:

is_reachable = True
cpu_usage = 95
is_bgp_up = False

if is_reachable and cpu_usage < 90 and is_bgp_up:
    print("All systems nominal")
else:
    print("⚠️ Potential problem detected")

Now change each variable one at a time and rerun. Observe how a single condition change alters the entire result.

Comparison Table: and vs or vs not

Use Case

Use and

Use or

Use not

All conditions must be true

(negate false cases)

One condition is enough

Filter non-compliant devices

Debugging / validation

Complex compound checks

Summary: When to Use Logical Operators

  • Use and when all conditions must be true (e.g., pre-deployment checks).

  • Use or when any condition can trigger an action (e.g., alerting).

  • Use not to exclude or invert a condition (e.g., skipping compliant nodes).

Wrap-Up: Thinking in Conditions and Comparisons

In this article, we’ve gone far beyond the simple notion of “greater than” or “equal to.” You’ve seen how comparators (==, !=, >, <, >=, <=) are the foundation for logic and decision-making in Python, and how they’re the building blocks for automated reasoning in scripts that need to respond to real-world data and events.

You’ve also explored how control flow structures, such as if, elif, and else, let you orchestrate how Python reacts under specific conditions. Whether you're checking the status of an interface, evaluating latency thresholds, or applying different provisioning logic based on device role, these tools are absolutely essential.

As a network engineer, you’ll frequently:

  • Check if devices are reachable or configs are compliant.

  • Compare values from APIs, SNMP, telemetry, or CLI output.

  • Evaluate whether one metric breaches a threshold.

  • Branch your logic based on platform, vendor, or intent.

When those decisions need to be embedded into automated tools, monitoring scripts, remediation pipelines, or simply daily validation scripts, Python’s comparators and conditionals are how you encode that reasoning.

What You Should Take Away:

  • Comparators return Boolean values, and are often embedded inside if, while, and even list comprehensions.

  • You can combine conditions using and, or, and not for more sophisticated logic.

  • Python encourages readable, expressive branching logic using indentation, elif, and else.

  • You now understand short-hand expressions and nested logic, and how to structure them properly.

  • These tools are indispensable in writing maintainable, testable network automation code.

This has been a pretty long post, so let's pause here and pick it up in the next chapter. See you there!

Leonardo Furtado

Keep Reading