Numbers, Files, and Lists

Do real math on network values, read whole config files off disk instead of single lines, and use lists — Python's workhorse container — to slice and organize everything you parse.

In this lesson you will:
  • Use integer and float math for subnet sizing and utilization numbers
  • Convert parsed text to numbers (and dodge the string-math trap)
  • Read and write files safely with the with statement
  • Index, slice, and grow lists of interfaces, VLANs, and config lines
  • Know when sorted() and .sort() behave differently — and why it bites

Numbers: subnet math without a calculator tab

Python has two numeric types you’ll use constantly: integers (int) for things you count — ports, VLANs, prefix lengths — and floats (float) for things you measure — utilization, error rates. The operators are mostly what you’d expect, plus three that matter more in networking than anywhere else:

>>> 2 ** (32 - 24) - 2     # ** is exponent: usable hosts in a /24
254
>>> 48 // 12               # // is integer division (no remainder)
4
>>> 530 % 48               # % is modulo: the remainder
2

That first line is the one to tattoo somewhere: a /26 has 2 ** (32 - 26) - 2 = 62 usable addresses, and now you never count on your fingers during a design review again. Division with / always returns a float, which pairs with round() for human-readable reporting:

>>> used, total = 87, 254
>>> round(used / total * 100, 1)
34.3

Files: configs live on disk, not in single lines

Lesson 1 parsed one line at a time. Real work starts with whole files — saved configs, inventory exports, show output you redirected last night. The professional pattern is the with statement:

with open("den-acc-sw03.cfg") as f:
    config = f.read()

lines = config.splitlines()

with guarantees the file gets closed when the block ends — including when your code crashes halfway through. The bare f = open(...) form you’ll see in old scripts leaks file handles when things go wrong; just don’t.

Two reading styles cover nearly everything:

  • f.read() — the whole file as one string. Pair with .splitlines() to get a clean list of lines with no trailing \n characters.
  • f.readlines() — a list of lines with their newlines still attached. Usually the wrong choice for exactly that reason.

Writing is the same shape with a mode argument:

with open("pre-check-den-acc-sw03.txt", "w") as f:
    f.write(version_output)

Lists: the container you’ll use every single day

A list is an ordered, changeable collection — and almost everything in network automation arrives as one: lines of a config, interfaces on a switch, devices in a site.

>>> uplinks = ["Gi1/0/1", "Gi1/0/2", "Te1/1/1", "Te1/1/2"]
>>> len(uplinks)
4
>>> uplinks[0]          # indexing starts at ZERO
'Gi1/0/1'
>>> uplinks[-1]         # negatives count from the end
'Te1/1/2'

Slicing pulls out sub-lists with [start:stop] — start included, stop excluded:

>>> uplinks[0:2]
['Gi1/0/1', 'Gi1/0/2']
>>> uplinks[-2:]        # everything from the second-to-last on: the tens
['Te1/1/1', 'Te1/1/2']

Omitting an endpoint means “from the beginning” or “to the end” — so lines[:10] is the first ten lines of a config and lines[-5:] is the last five. Lists grow and reorganize in place:

>>> vlans = [10, 30, 20]
>>> vlans.append(40)        # add one item to the end
>>> vlans
[10, 30, 20, 40]
>>> sorted(vlans)           # returns a NEW sorted list
[10, 20, 30, 40]
>>> vlans                   # the original is untouched
[10, 30, 20, 40]

And because a config is just a list of strings once you .splitlines() it, everything from Lesson 1 composes with everything above:

🖥 Subnet math and slicing config lines
▶ Try it yourself (Python runs in your browser)
Output appears here. First run downloads the Python runtime (~10 MB), so give it a few seconds.

Exercises (graded)

cd labs/python-foundations/lesson02
pytest -q

Five functions in exercises.py:

  1. usable_hosts(prefix_len) — usable host count for a prefix length
  2. utilization_pct(used, total) — percentage utilization, one decimal place
  3. read_config_lines(path) — a file’s lines as a clean list (no newlines)
  4. get_uplinks(interfaces) — the last two interfaces in a list
  5. add_vlan(vlans, vlan_id) — a new sorted list with the VLAN added

Reference solutions in solutions/ — after an honest attempt.

✅ Check your understanding

A /26 subnet — how many usable host addresses, and which expression computes it?

1 / 3

Summary

Integer math (**, //, %) handles subnet sizing — 2 ** (32 - prefix) - 2 — and floats with round() handle utilization reporting, but only after you int() whatever you parsed, because parsed text is always strings. The with open(...) statement is the only file-reading pattern worth learning, and .read().splitlines() hands you a config as a clean list. Lists index from zero, slice with [start:stop], grow with .append(), and hide one classic trap: in-place methods like .sort() return None. Next lesson: conditionals and loops — where your scripts finally start making decisions about every line in that config, not just the ones you point at.