EZ LearnEZ Learn
Courses
EZ Board
Dashboard
All articles
python-for-cyber-securitypythonloopsfunctions

Conditions, Loops and Functions

Indentation is how Python reads your intent. Walk the watchman's rounds with loops, write a recipe card of a function, and meet is_port_open(), the first cell of a port scanner.

Ashish Revar17 October 202614 min read
1 video lesson 5:19 total
Sign in to track your progress

Video lesson

A script that cannot decide, repeat or reuse anything is just a calculator. This article gives you the three ideas that turn a few lines into a tool: conditions (decide), loops (repeat) and functions (reuse). By the end you will have written the first working piece of a port scanner.

Conditions: choosing a path

Python decides which lines belong to an if by their indentation, not by braces. A missing or uneven indent is the single most common error a beginner meets, and is worth checking first whenever a script refuses to run.

conditions.py

port = 443
if port == 443:
    print("Likely HTTPS")
elif port == 80:
    print("Likely HTTP")
else:
    print("Unrecognised common port")

Sample output

Likely HTTPS

Python checks the conditions from the top and runs the first block whose condition is true, then skips the rest. The else at the bottom catches everything nothing above it claimed.

port = 443if port == 443 ?yes"Likely HTTPS"noelif port == 80 ?yes"Likely HTTP"noelse: "Unrecognised common port"
Figure 5.1. An if / elif / else chain tests each condition in turn and runs only the first block that matches.

Caution: The error you will meet on day one

Forget to indent the line under if, and Python refuses to run the script at all:

  File "conditions.py", line 3
    print("Likely HTTPS")
    ^^^^^
IndentationError: expected an indented block after 'if' statement on line 2

Read the line number, look at the line above it, and check the indentation. Four spaces per level is the convention. Never mix tabs and spaces in the same file.

Loops: the night watchman's rounds

Analogy: The night watchman's rounds

A for loop is a watchman walking a fixed set of doors, one after another, until every door on the list has been checked. A while loop is a watchman told to keep walking until a condition changes, useful when you do not know in advance how many rounds are needed, such as reading from a socket until the other side stops sending.

loops.py

# for: a known, fixed set of doors to check
for port in [21, 22, 23, 25, 80, 443]:
    print(f"Would check port {port}")

# while: keep reading from a socket until no more data arrives
data = sock.recv(1024)
while data:
    process(data)
    data = sock.recv(1024)

The second half of that listing is a pattern, not a program to run yet: sock is a network socket you will create in the sockets article, and process stands for whatever your script does with each chunk of data. The shape is what matters. It reads once to start, then keeps going while the last read returned something, and stops the moment the other side has nothing more to send.

for: a known list of doors212280443visit each one, then stopyou know the number of rounds in advancewhile: until something changesdata = recv()read a chunkprocess(data)do the workstill got data? go round againyou do not know how many rounds
Figure 5.2. A for loop visits every item of a list once. A while loop keeps going for as long as a condition stays true.

range(start, stop) produces the integers from start up to, but not including, stop, and is the usual way to sweep a block of port numbers:

range_demo.py

for port in range(1, 1025):     # ports 1 through 1024
    pass                         # a scanner checks each one here

print(list(range(1, 6)))         # [1, 2, 3, 4, 5]
print(list(range(10, 0, -3)))    # a third number is the step: [10, 7, 4, 1]

Functions: the recipe card

Analogy: The recipe card

A function is a recipe card. Once written, it can be followed again whenever the dish is needed, without copying out every step each time. Keeping each function focused on one task, one dish, also makes a script easier to test and to reuse in a later unit.

Inputshostporttimeout = 1.0timeout has a defaultis_port_open()connect, thencheck the resultReturn valueTrueorFalse
Figure 5.3. A function takes inputs, does one job, and hands back an answer. is_port_open() takes a host, a port and a timeout, and returns True or False.

is_port_open.py

def is_port_open(host, port, timeout=1.0):
    """Return True if a TCP connection to host:port succeeds."""
    import socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(timeout)
    result = sock.connect_ex((host, port))
    sock.close()
    return result == 0

if is_port_open("10.0.0.5", 22):
    print("SSH port appears open")
LineWhat it does
def is_port_open(host, port, timeout=1.0):Starts the recipe card. Three inputs; timeout has a default of 1.0, so it is optional
"""Return True if ..."""A docstring: one sentence saying what the function does, for the next person to read
import socketBrings in Python's networking module (you will meet it fully in the sockets article)
socket.socket(AF_INET, SOCK_STREAM)Creates a TCP socket, a handle on one end of a connection
sock.settimeout(timeout)Gives up waiting after this many seconds instead of hanging forever
sock.connect_ex((host, port))Tries to connect and returns a number instead of raising an error. 0 means success
sock.close()Hangs up, whatever the outcome
return result == 0Answers True when the connection succeeded, False otherwise

The timeout=1.0 parameter carries a default value, so the function can be called as is_port_open("10.0.0.5", 22) without a timeout, or as is_port_open("10.0.0.5", 22, timeout=3.0) when a slow network needs more patience. You will meet this exact function again, grown into a full scanner, at the start of Unit 2.

Try it on your own machine

You do not need a lab server to watch this function work. Python can open a real port for you with a one-line web server. In one terminal, start it:

terminal 1

$ python3 -m http.server 9999 --bind 127.0.0.1
Serving HTTP on 127.0.0.1 port 9999 (http://127.0.0.1:9999/) ...

In a second terminal, sweep a block of ports on your own machine using the for loop, range and your function together:

sweep_demo.py

import socket

def is_port_open(host, port, timeout=1.0):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(timeout)
    result = sock.connect_ex((host, port))
    sock.close()
    return result == 0

for port in range(9996, 10001):
    state = "open" if is_port_open("127.0.0.1", port) else "closed"
    print(f"127.0.0.1:{port:<5} {state}")

Sample output

127.0.0.1:9996  closed
127.0.0.1:9997  closed
127.0.0.1:9998  closed
127.0.0.1:9999  open
127.0.0.1:10000 closed

You have just written the heart of a port scanner: a loop that visits each door, a function that knocks, and a condition that reports. Everything else a scanner does is polish on those three ideas.

Combining all three: wait for a service, then sweep

Real scripts mix while, for, functions and conditions freely. This one waits patiently for a service to come up, then lists which ports in a block are open. Start it first, then launch the web server from the previous step a couple of seconds later and watch the loop notice.

wait_and_sweep.py

import socket
import time

def is_port_open(host, port, timeout=1.0):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(timeout)
    result = sock.connect_ex((host, port))
    sock.close()
    return result == 0

def wait_for_port(host, port, max_tries=6, pause=1.0):
    attempt = 1
    while attempt <= max_tries:                 # while: we do not know how many rounds
        if is_port_open(host, port):
            print(f"Attempt {attempt}: {host}:{port} is open")
            return True
        print(f"Attempt {attempt}: {host}:{port} not up yet")
        time.sleep(pause)
        attempt += 1
    return False

def sweep(host, ports):
    open_ports = []
    for port in ports:                           # for: a known list of doors
        if is_port_open(host, port, timeout=0.5):
            open_ports.append(port)
    return open_ports

print(wait_for_port("127.0.0.1", 9999))
print("Open ports:", sweep("127.0.0.1", range(9990, 10000)))

Sample output

Attempt 1: 127.0.0.1:9999 not up yet
Attempt 2: 127.0.0.1:9999 not up yet
Attempt 3: 127.0.0.1:9999 is open
True
Open ports: [9999]

Real incident: Mirai, 2016: a loop and a short list

In the autumn of 2016, a botnet named Mirai infected hundreds of thousands of internet-connected cameras, routers and video recorders by trying a short, fixed list of around sixty factory-default username and password pairs, admin and admin among them, over Telnet. No exploit was needed; the devices had simply never had their defaults changed. On 21 October 2016, Mirai directed its captured devices to flood Dyn, a company providing DNS for a large share of the internet, taking Twitter, Netflix, Reddit and many other sites offline for hours across the United States.

What this teaches: the idea behind Mirai is the idea in this article. It is a for loop over a short list, repeated across an enormous number of doors. Mirai reached a scale no single attacker could by hand only because so many devices shared one unchanged default. You will build the harmless, lab-only version of that loop in Unit 2, and by then you will understand exactly why changing a default credential before a device goes into service remains one of the cheapest and most effective defences in all of security.

Check your understanding

Question 1: When would you choose a while loop over a for loop?

Choose for when you have a known, fixed set of items to visit, such as a list of ports. Choose while when you do not know in advance how many rounds you need, such as reading from a socket until the other side stops sending, or retrying until a service comes up.

Question 2: What does range(1, 1025) produce, and what is the last port it includes?

It produces the integers 1 through 1024. The stop value is not included, so 1025 never appears. The last port is 1024.

Question 3: In is_port_open(host, port, timeout=1.0), what does the "= 1.0" mean, and how do you override it?

It gives timeout a default value. If the caller leaves it out, 1.0 seconds is used. To override it, pass a value: is_port_open("10.0.0.5", 22, timeout=3.0).

Key takeaway: Key takeaway

Conditions decide, loops repeat and functions reuse. Indentation is syntax, for suits a known list and while suits an unknown number of rounds, and a small function like is_port_open() is the seed of a whole scanner.

Assessments

Unit Assessment

Python and Networking Foundations

20 questions30 minPass: 60%

Start exam →

Comprehensive Assessment

Python for Cyber Security: Complete Assessment

100 questions120 minPass: 60%

Start final exam →

Related to this topic

Continue learning

Reference material

Cheatsheet

Python for Cyber Security — Cheatsheet

v1.0

Open resource

MCQ Bank

Python for Cyber Security — MCQ Bank

v1.0

Open resource

Question Bank

Python for Cyber Security — Question Bank

v1.0

Open resource

eBook

Python for Cyber Security — eBook

v1.0

Open resource

Discussion

Loading comments…
More articlesTest your knowledge
EZ MentorAI · Free

Conditions, Loops and Functions

Hi! I'm EZ Mentor

Your AI tutor for
Conditions, Loops and Functions

Sign in to ask, it's free.

EZ Mentor is AI-powered · Answers may not be perfect · 10 free questions / day

EZ LearnEZ Learn

Structured learning across Reverse Engineering, Cloud Security, and Research Methodology, plus games and practice tools in EZ Arena. Free, and open to anyone.

EZ Learn

  • Courses
  • EZ Articles
  • EZ Watch
  • EZ Talks
  • EZ Bytes
  • Cyber Hygiene

EZ Library

  • All Resources
  • eBooks & PDFs
  • Question Banks
  • MCQ Banks
  • Cheatsheets

EZ Exams

  • All Exams
  • REMA
  • Cloud Security
  • Research Methodology
  • Python for Cyber Security
  • Cyber Law & IPR
  • Community
  • EZ Board

EZ Arena

  • EZ Games
  • Live Quiz
  • ML Challenges
  • दिशा - Hygiene
  • सजग - Awareness
  • अभ्यास - Practice

Platform

  • About
  • Contact
  • Terms of Use
  • Disclaimer
  • Verify Certificate
  • Events

© 2026 EZ Learn by EpochZero. Educational content for learning purposes.

Platform Lead: Ashish Revar