Python Arithmetic Operators – Stop Calculating Pizza Slices
Right, so you’ve got scientific notation working and data types sorted haven’t you. Numbers, strings, converting between them, that whole bit. Now we’re getting to something that catches loads of people out when they start doing actual calculations with network data – python arithmetic operators.
Python for Network Engineers Blog 13: Scientific Notation
Now here’s where most Python courses completely cock it up again. They’ll have you calculating how many pizza slices everyone gets at a party or working out your shopping bill or figuring out compound interest on your savings account. I’m sitting there thinking, that’s lovely mate but I’ve got bandwidth calculations to do, subnet sizes to work out, and VLAN ranges to manage. How’s pizza mathematics going to help me calculate link utilisation then?
Thing is, I made this exact mistake when I started. Few years back, was trying to write a script to work out how many /24 subnets I could fit in a /16 network. Had to do loads of maths with powers of 2, division, that sort of thing. Kept getting the calculations wrong because I didn’t understand which arithmetic operator to use when. Spent ages manually working it out with a calculator. Complete waste of time.
Few months later, needed to calculate bandwidth utilisation across multiple interfaces on our core switches. Thought there’s got to be a better way than doing all this maths manually every time.
Found someone who explained python arithmetic operators properly, this one actually used networking examples. Made much more sense straight away. Instead of calculating pizza portions, I’m working out subnet sizes with 2 ** 24 and bandwidth percentages with division operators.
So anyway, let’s do python arithmetic operators properly using network stuff that matters.
What Python Arithmetic Operators Actually Are
Right so python arithmetic operators are just symbols that tell Python to do maths calculations. Addition, subtraction, multiplication, division, that sort of thing. But there’s a few more that are dead useful for networking calculations.
Python gives you seven arithmetic operators to work with:
# Basic arithmetic operators for networking calculations
vlan_count = 10 + 20 # Addition: 30 VLANs total
remaining_ips = 254 - 50 # Subtraction: 204 IPs left
total_ports = 24 * 3 # Multiplication: 72 ports across 3 switches
bandwidth_per_user = 1000 / 25 # Division: 40 Mbps per user
# More advanced operators for network maths
subnet_size = 2 ** 8 # Exponentiation: 256 addresses in /24
networks_in_supernet = 65536 // 256 # Floor division: 256 networks
host_portion = 192 % 256 # Modulo: remainder for subnet calculations
print(f"VLAN count: {vlan_count}")
print(f"Remaining IPs: {remaining_ips}")
print(f"Total ports: {total_ports}")
print(f"Bandwidth per user: {bandwidth_per_user}")
print(f"Subnet size: {subnet_size}")
print(f"Networks in supernet: {networks_in_supernet}")
print(f"Host portion: {host_portion}")
See? Network calculations that actually matter. Not working out how to split restaurant bills.
Now here’s something quite clever about python arithmetic operators that I didn’t know when I started. The order they get calculated matters massively. Just like in normal maths, multiplication happens before addition. But there’s some networking-specific gotchas you need to watch out for.
Had this come up last month actually. Was calculating total bandwidth across multiple link types. Had something like 4 * 1000 + 2 * 100. Python calculated it as (4 * 1000) + (2 * 100) = 4200 Mbps, not 4 * (1000 + 2) * 100 which would be mental. Operator precedence saved me from a proper cock-up.
Why This Matters for Network Engineers
Look, networking’s absolutely stuffed with calculations, isn’t it? Subnet sizes, bandwidth calculations, port counts, utilisation percentages. Everything needs maths to work properly.
Understanding python arithmetic operators properly means you can automate all these calculations instead of doing them manually. Makes your scripts much more reliable when you’re working out network capacity or planning IP addressing schemes.
# Real network capacity calculations
switch_ports = 48
switches = 3
users_per_port = 1
oversubscription_ratio = 20 # 20:1 oversubscription
# Calculate total user capacity
total_ports = switch_ports * switches
total_users = total_ports * users_per_port
backplane_bandwidth = 1000 # 1 Gbps uplink
# Work out actual bandwidth per user with oversubscription
theoretical_bandwidth = backplane_bandwidth / total_users
actual_bandwidth = theoretical_bandwidth / oversubscription_ratio
print(f"Total ports: {total_ports}")
print(f"Total users: {total_users}")
print(f"Theoretical bandwidth per user: {theoretical_bandwidth:.2f} Mbps")
print(f"Actual bandwidth per user: {actual_bandwidth:.2f} Mbps")
But here’s where people get confused. When do you use which operator for different types of network calculations?
Basic Arithmetic Operators
This catches people out constantly. Which operator do you use for different networking calculations?
Simple rule I use. Addition and subtraction for counts and ranges. Multiplication for scaling up. Division for working out averages and utilisation.
# Addition - combining counts
sales_vlans = 10
engineering_vlans = 15
guest_vlans = 5
total_vlans = sales_vlans + engineering_vlans + guest_vlans # 30 VLANs
# Subtraction - finding available capacity
total_ip_addresses = 254
used_ip_addresses = 87
available_ips = total_ip_addresses - used_ip_addresses # 167 available
# Multiplication - scaling configurations
ports_per_switch = 24
number_of_switches = 5
total_access_ports = ports_per_switch * number_of_switches # 120 ports
# Division - calculating averages and ratios
total_bandwidth = 10000 # 10 Gbps
active_users = 250
bandwidth_per_user = total_bandwidth / active_users # 40 Mbps per user
print(f"Total VLANs: {total_vlans}")
print(f"Available IPs: {available_ips}")
print(f"Total ports: {total_access_ports}")
print(f"Bandwidth per user: {bandwidth_per_user} Mbps")
There we go. Basic operators that handle most of your day-to-day network calculations.

Got caught out by this early on actually. Had a script that was trying to calculate VLAN ranges using addition. Kept getting weird results because I was adding VLAN IDs instead of counting how many VLANs were in each range. Spent ages debugging before I realised I needed subtraction to find the range size. Proper embarrassing that was.
Advanced Arithmetic Operators
Right so here’s something that confused the hell out of me when I started. Python has three more arithmetic operators that are absolutely brilliant for networking calculations but most people don’t know about them.
Exponentiation Operator (**)
The double asterisk is for powers. Dead useful for subnet calculations:
# Subnet size calculations using powers of 2
prefix_length = 24
host_bits = 32 - prefix_length # 8 host bits
subnet_size = 2 ** host_bits # 2^8 = 256 addresses
print(f"/{prefix_length} subnet has {subnet_size} addresses")
# Calculate how many subnets you can fit
network_size = 16 # /16 network
host_bits_needed = 8 # Want /24 subnets
number_of_subnets = 2 ** (prefix_length - network_size)
print(f"Can fit {number_of_subnets} /24 subnets in a /{network_size}")
# VLAN ID ranges using powers
max_vlan_bits = 12 # 802.1Q standard
max_vlans = 2 ** max_vlan_bits
usable_vlans = max_vlans - 2 # Subtract reserved VLANs 0 and 4095
print(f"Maximum usable VLANs: {usable_vlans}")
Brilliant. Much easier than trying to remember that 2^8 is 256 every time.
Floor Division Operator (//)
Double slash gives you whole numbers only. Perfect for working out how many complete things you can fit:
# How many complete /24 networks fit in larger subnets
total_addresses = 65536 # /16 network has 65536 addresses
subnet_size = 256 # /24 network has 256 addresses
complete_subnets = total_addresses // subnet_size # 256 complete /24s
print(f"Complete /24 subnets in /16: {complete_subnets}")
# Port allocation calculations
users_needing_ports = 150
ports_per_switch = 48
switches_needed = users_needing_ports // ports_per_switch # 3 complete switches
print(f"Switches needed: {switches_needed}")
print(f"This provides {switches_needed * ports_per_switch} ports")
# Bandwidth allocation
available_bandwidth = 1000 # 1 Gbps
required_per_user = 30 # 30 Mbps per user
max_users = available_bandwidth // required_per_user # 33 users maximum
print(f"Maximum users: {max_users}")
Perfect for capacity planning where you need whole numbers of things.
Modulo Operator (%)
The percent sign gives you the remainder after division. Useful for working out what’s left over:
# Find out how many ports are left over
total_users = 150
ports_per_switch = 48
leftover_ports = total_users % ports_per_switch # 6 users need individual ports
print(f"Users needing individual ports: {leftover_ports}")
# IP address calculations
ip_address = 192
network_boundary = 256
host_portion = ip_address % network_boundary # 192
print(f"Host portion of address: {host_portion}")
# VLAN wrapping calculations
starting_vlan = 100
vlan_increment = 250
vlans_to_assign = [starting_vlan + (i * vlan_increment) for i in range(5)]
wrapped_vlans = [vlan % 4096 for vlan in vlans_to_assign] # Wrap at VLAN limit
print(f"Original VLANs: {vlans_to_assign}")
print(f"Wrapped VLANs: {wrapped_vlans}")
Great stuff. Modulo is dead handy for working out remainders and boundaries.
Common Python Arithmetic Operators Cock-ups
Let me tell you about cock-ups I see network engineers make when learning python arithmetic operators. Made most of these myself at some point.
Mixing up division operators is a massive one:
# Wrong - using normal division for counting things
available_bandwidth = 1000 # 1 Gbps
user_requirement = 30 # 30 Mbps per user
users = available_bandwidth / user_requirement # Gives 33.333333... users
# Right - using floor division for whole users
users = available_bandwidth // user_requirement # Gives 33 complete users
print(f"Wrong calculation: {available_bandwidth / user_requirement} users")
print(f"Right calculation: {users} users")
You can’t have 0.33 of a user. Always use floor division when counting discrete things like users, switches, ports.
Forgetting operator precedence bit me badly once:
# Wrong - precedence gives unexpected results
bandwidth_total = 4 * 1000 + 2 * 100 # Gets calculated as (4*1000) + (2*100) = 4200
print(f"Confusing result: {bandwidth_total}")
# Right - use brackets to be explicit
uplink_bandwidth = 4 * 1000 # 4 Gbps uplinks
access_bandwidth = 2 * 100 # 2 x 100 Mbps access
total_bandwidth = uplink_bandwidth + access_bandwidth # 4200 Mbps total
print(f"Clear calculation: {total_bandwidth}")
# Even better - break it down properly
uplinks = 4
uplink_speed = 1000
access_links = 2
access_speed = 100
total = (uplinks * uplink_speed) + (access_links * access_speed)
print(f"Explicit calculation: {total}")
Always use brackets when you’re not sure about precedence. Makes the code much clearer.
Not understanding integer division catches people out constantly:
# This can give unexpected results
total_ports = 100
switches = 3
ports_per_switch = total_ports / switches # Gives 33.333333...
print(f"Ports per switch: {ports_per_switch}")
# But you probably want whole numbers
ports_per_switch_floor = total_ports // switches # Gives 33
leftover_ports = total_ports % switches # Gives 1
print(f"Complete ports per switch: {ports_per_switch_floor}")
print(f"Leftover ports: {leftover_ports}")
Think about whether you need exact division or whole number division.

Actually Useful Applications
Thing is, once you get python arithmetic operators sorted, loads of networking tasks become much easier. Let me show you some practical applications.
Subnet calculations become dead simple:
# Complete subnet calculator using arithmetic operators
def calculate_subnet_info(network_ip, prefix_length):
host_bits = 32 - prefix_length
subnet_size = 2 ** host_bits
usable_hosts = subnet_size - 2 # Subtract network and broadcast
network_address = network_ip - (network_ip % subnet_size)
broadcast_address = network_address + subnet_size - 1
first_host = network_address + 1
last_host = broadcast_address - 1
return {
"network": network_address,
"broadcast": broadcast_address,
"first_host": first_host,
"last_host": last_host,
"usable_hosts": usable_hosts,
"subnet_size": subnet_size
}
# Calculate subnet info for 192.168.1.100/24
ip = 192 * 256**3 + 168 * 256**2 + 1 * 256 + 100 # Convert to integer
subnet_info = calculate_subnet_info(ip, 24)
print(f"Network: {subnet_info['network']}")
print(f"Usable hosts: {subnet_info['usable_hosts']}")
print(f"Subnet size: {subnet_info['subnet_size']}")
Brilliant. All the subnet maths done with arithmetic operators.
Bandwidth calculations for capacity planning:
# Bandwidth utilisation calculator
def calculate_bandwidth_stats(interfaces_data):
total_capacity = 0
total_utilisation = 0
for interface in interfaces_data:
capacity = interface["speed_mbps"]
current_usage = interface["input_mbps"] + interface["output_mbps"]
utilisation_percent = (current_usage / capacity) * 100
total_capacity += capacity
total_utilisation += current_usage
print(f"{interface['name']}: {utilisation_percent:.1f}% utilised")
overall_utilisation = (total_utilisation / total_capacity) * 100
return overall_utilisation
# Example interface data
interfaces = [
{"name": "Gi0/1", "speed_mbps": 1000, "input_mbps": 250, "output_mbps": 180},
{"name": "Gi0/2", "speed_mbps": 1000, "input_mbps": 120, "output_mbps": 90},
{"name": "Gi0/3", "speed_mbps": 1000, "input_mbps": 300, "output_mbps": 220}
]
overall = calculate_bandwidth_stats(interfaces)
print(f"Overall utilisation: {overall:.1f}%")
Much easier to work with arithmetic operators than doing all the maths manually.
VLAN management with arithmetic operators:
# VLAN range calculator
def calculate_vlan_ranges(start_vlan, departments, vlans_per_dept):
vlan_assignments = {}
current_vlan = start_vlan
for dept in departments:
dept_vlans = []
for i in range(vlans_per_dept):
if current_vlan > 4094: # VLAN limit
current_vlan = current_vlan % 4094 + 1 # Wrap around
dept_vlans.append(current_vlan)
current_vlan += 1
vlan_assignments[dept] = dept_vlans
return vlan_assignments
# Assign VLANs to departments
departments = ["Sales", "Engineering", "Marketing", "HR"]
vlan_plan = calculate_vlan_ranges(100, departments, 5)
for dept, vlans in vlan_plan.items():
print(f"{dept}: VLANs {vlans}")
Fantastic. Arithmetic operators make VLAN planning much more systematic.
Real Network Examples
Let me show you actual scenarios where python arithmetic operators matter.
Network capacity planning for a new office:
# New office capacity planning
office_requirements = {
"employees": 85,
"growth_factor": 1.2, # 20% growth allowance
"ports_per_employee": 1.5, # Some need multiple ports
"bandwidth_per_employee": 50 # 50 Mbps per employee
}
# Calculate port requirements
base_ports = office_requirements["employees"] * office_requirements["ports_per_employee"]
total_ports_needed = int(base_ports * office_requirements["growth_factor"])
# Work out switch requirements
ports_per_switch = 48
switches_needed = total_ports_needed // ports_per_switch
if total_ports_needed % ports_per_switch > 0:
switches_needed += 1 # Need one more switch for remainder
# Calculate bandwidth requirements
base_bandwidth = office_requirements["employees"] * office_requirements["bandwidth_per_employee"]
total_bandwidth_needed = int(base_bandwidth * office_requirements["growth_factor"])
print(f"Employees: {office_requirements['employees']}")
print(f"Ports needed: {total_ports_needed}")
print(f"Switches required: {switches_needed}")
print(f"Total bandwidth needed: {total_bandwidth_needed} Mbps")
print(f"Uplink recommendation: {total_bandwidth_needed // 1000 + 1} Gbps")
Brilliant. All the capacity planning maths sorted with arithmetic operators.
IP addressing scheme calculator:
# IP addressing calculator for multiple sites
def calculate_ip_scheme(base_network, sites_info):
# Base network is 10.0.0.0/16, giving us 256 /24 subnets
current_subnet = 1 # Start from 10.0.1.0/24
ip_assignments = {}
for site, info in sites_info.items():
hosts_needed = info["devices"] + info["users"]
growth_allowance = int(hosts_needed * 0.3) # 30% growth
total_hosts = hosts_needed + growth_allowance
# Calculate subnet size needed (power of 2)
host_bits_needed = 0
subnet_size = 1
while subnet_size < (total_hosts + 2): # +2 for network and broadcast
host_bits_needed += 1
subnet_size = 2 ** host_bits_needed
prefix_length = 32 - host_bits_needed
# Assign subnet
network_third_octet = current_subnet
network_address = f"10.0.{network_third_octet}.0/{prefix_length}"
ip_assignments[site] = {
"network": network_address,
"hosts_available": subnet_size - 2,
"hosts_needed": total_hosts,
"utilisation": f"{(total_hosts / (subnet_size - 2)) * 100:.1f}%"
}
# Move to next available subnet
subnets_used = 2 ** (24 - prefix_length) # How many /24s this uses
current_subnet += subnets_used
return ip_assignments
# Site requirements
sites = {
"London": {"devices": 20, "users": 150},
"Manchester": {"devices": 15, "users": 80},
"Birmingham": {"devices": 10, "users": 45}
}
ip_plan = calculate_ip_scheme("10.0.0.0/16", sites)
for site, details in ip_plan.items():
print(f"{site}: {details['network']}")
print(f" Hosts available: {details['hosts_available']}")
print(f" Hosts needed: {details['hosts_needed']}")
print(f" Utilisation: {details['utilisation']}")
Great stuff. Complex IP planning made simple with arithmetic operators.
Operator Precedence
Now here’s something that catches people out when they start doing more complex network calculations.
Python follows standard mathematical precedence rules:
# Order of operations: PEMDAS (Parentheses, Exponents, Multiplication/Division, Addition/Subtraction)
calculation = 2 + 3 * 4 ** 2 # Calculated as: 2 + (3 * (4 ** 2)) = 2 + (3 * 16) = 2 + 48 = 50
print(f"Without brackets: {calculation}")
# Use brackets to make your intentions clear
bandwidth_calc = (2 + 3) * (4 ** 2) # (5) * (16) = 80
print(f"With brackets: {bandwidth_calc}")
# Real networking example
uplink_speed = 10 # Gbps
access_ports = 48
oversubscription = 20
user_bandwidth = uplink_speed * 1000 / access_ports / oversubscription # 10.416... Mbps
# Much clearer with brackets
user_bandwidth_clear = (uplink_speed * 1000) / (access_ports * oversubscription)
print(f"User bandwidth: {user_bandwidth_clear:.2f} Mbps")
Always use brackets when you’re doing complex calculations. Makes your code much easier to understand.

Had this come up recently actually. Was calculating aggregate bandwidth across multiple link types. Had something like 4 * 1000 + 8 * 100 + 24 * 10. Python calculated it correctly as (41000) + (8100) + (24*10) = 5040 Mbps. But I spent ages checking it because I wasn’t sure about the precedence. Should have just used brackets to be explicit.
PCEP Requirements for Arithmetic Operators
The PCEP exam covers specific aspects of python arithmetic operators that you need to understand properly.
You need to know all seven arithmetic operators and what they do:
# All arithmetic operators with networking examples
a = 1000 # 1 Gbps in Mbps
b = 8 # 8 ports
addition = a + b # 1008
subtraction = a - b # 992
multiplication = a * b # 8000
division = a / b # 125.0 (always returns float)
floor_division = a // b # 125 (returns integer)
modulo = a % b # 0 (remainder)
exponentiation = b ** 2 # 64
print(f"Addition: {addition}")
print(f"Subtraction: {subtraction}")
print(f"Multiplication: {multiplication}")
print(f"Division: {division}")
print(f"Floor division: {floor_division}")
print(f"Modulo: {modulo}")
print(f"Exponentiation: {exponentiation}")
All these operators are essential for network calculations.
Understanding operator precedence is crucial for the PCEP exam:
# Precedence examples the exam might test
result1 = 2 + 3 * 4 # 14 (not 20)
result2 = 2 ** 3 ** 2 # 512 (not 64) - exponentiation is right-associative
result3 = 10 / 2 * 3 # 15.0 (left-to-right for same precedence)
result4 = 10 // 3 / 2 # 1.5 (floor division first, then regular division)
print(f"2 + 3 * 4 = {result1}")
print(f"2 ** 3 ** 2 = {result2}")
print(f"10 / 2 * 3 = {result3}")
print(f"10 // 3 / 2 = {result4}")
The exam will test these precedence rules, so make sure you understand them.
Mixing integer and float arithmetic:
# Type coercion with arithmetic operators
int_value = 1000 # Integer
float_value = 1.5 # Float
# Any operation with a float returns a float
result1 = int_value + float_value # 1001.5 (float)
result2 = int_value * 2 # 2000 (integer)
result3 = int_value / 2 # 500.0 (float - division always returns float)
result4 = int_value // 2 # 500 (integer)
print(f"Int + Float: {result1} ({type(result1)})")
print(f"Int * Int: {result2} ({type(result2)})")
print(f"Int / Int: {result3} ({type(result3)})")
print(f"Int // Int: {result4} ({type(result4)})")
Understanding type behaviour is important for the exam.
Why This All Actually Matters
Look, understanding python arithmetic operators properly is fundamental to everything else you’ll do with network calculations. Without them, you’ll struggle with subnet planning, capacity calculations, bandwidth utilisation.
Get python arithmetic operators wrong and you’ll spend ages doing manual calculations, getting wrong results because of precedence issues, or using the wrong division operator for counting discrete things. Get them right and you can automate all your network maths.
The key thing is using python arithmetic operators for actual network calculations. Subnet sizes, bandwidth allocation, port counting, utilisation percentages. Not calculating pizza slices or shopping bills that have nothing to do with networking.
Understanding arithmetic operators means your network scripts can handle all the maths properly. From simple addition for counting VLANs to complex exponentiation for subnet calculations. Makes you much more effective at network planning and capacity management.
That’s python arithmetic operators sorted properly. You understand all seven operators, when to use each one, and how to avoid precedence cock-ups. Much better than generic examples that teach you nothing useful for actual networking work.
External Link: Python Operator Precedence Documentation – official Python documentation for operator precedence rules
Pingback: Python for Network Engineers Blog 15: Python Comparison Operators - RichardKilleen