To access material, start machines and answer questions login.
In the Python: Simple Demo room, we built a "Guess the Number" game and learned three foundational programming concepts: variables, conditional statements, and while loops. Those three concepts alone let us create a working, interactive program. Now it is time to go deeper.
Consider the following scenario. You are a junior penetration tester, and your team lead hands you a text file containing 10,000 usernames harvested during reconnaissance. Your job is to check each username against a list of known default passwords, flag weak credentials, and write the results to a report file. Doing this by hand would take days. A short Python script can finish it in seconds.
To write that script, you need more than variables and if statements. You need to know how to work with strings, store data in lists and dictionaries, use a richer set of operators, and master a second type of loop: the for loop. That is exactly what this room covers.
This room and its companion, Python: Building Scripts, together form a two-part series. In this first room, you will learn how Python handles data and control flow. In the second room, you will use that foundation to write functions, handle errors, work with files, import libraries, and build a complete Password Strength Checker from scratch.
Learning Objectives
By the end of this room, you will be able to:
- Review Python variables, conditional statements, and loops (covered in Simple Demo)
- Work with Python data types and perform type conversions
- Use formatted strings (f-strings) and augmented assignment operators
- Manipulate strings using built-in methods
- Store and retrieve data with lists and dictionaries
- Use comparison, logical, arithmetic, and membership operators
- Iterate over data using
forloops,whileloops, andrange() - Control loop flow with
breakandcontinue
Prerequisites
It is best if you tackle this room after finishing:
Machine Access
You can follow along by clicking the Start Machine button below to launch the Target machine (VM). Visual Studio Code (VS Code) should open automatically with a modern Python installation ready for you. All example scripts discussed in this room are saved in the /home/ubuntu/Core-Concepts/ directory. We strongly encourage you to run, modify, and experiment with every code snippet on the as you progress through the tasks.
Set up your virtual environment
Let's master Python's core concepts!
Note: If you have completed the Python: Simple Demo room, the first three subsections below will be familiar ground. Feel free to skim through them as a refresher and jump directly to the "What's New" subsection and the questions at the end. If this is your first encounter with Python, take your time with each subsection before moving on.
Hello World
The simplest Python program outputs text to the screen using the print() function. In the Python: Simple Demo room, we used print() to tell the user that the computer had picked a secret number. Let's revisit the basics.
# This is a comment. Python ignores lines starting with #.
print("Hello World")
When you run this, the text Hello World appears on the screen. A few things to note:
- Lines starting with
#are comments. The computer ignores them; they exist to help humans understand the code. - The
print()function outputs whatever is placed between its parentheses. - Text (called a string) must be enclosed in quotation marks, either
"double"or'single'.
Open the file hello.py in VS Code on the attached VM, run it, and confirm you see Hello World in the terminal.
Variables and Data Types
Variables let you store and update data. As we saw in Simple Demo, we stored the secret number in a variable called secret and the user's input in guess:
food = "ice cream" # a string (text)
money = 2000 # an integer (whole number)
In the example above, the variable food stores the string "ice cream", while money stores the integer 2000. Variables are powerful because you can change their values throughout your program:
age = 30
age = age + 1
print(age) # 31
Every value in Python has a data type. The core types you need to know are:
| Type | Name | Example | Description |
|---|---|---|---|
str |
String | "hello" |
Text, characters, symbols |
int |
Integer | 42 |
Whole numbers |
float |
Float | 3.14 |
Numbers with decimal points |
bool |
Boolean | True / False |
Logical on/off, yes/no values |
list |
List | [1, 2, 3] |
Ordered collection of items |
You can check a value's type using type():
username = "admin"
port = 8080
print(type(username)) # <class 'str'>
print(type(port)) # <class 'int'>
Open types_demo.py on the VM and run it. Observe the output and try changing the variable values to see how type() responds.
Conditional Statements and Logical Operators
In Simple Demo, we used if, elif, and else to compare the user's guess to the secret number. Let's recap the structure:
age = 18
if age < 17:
print("You are NOT old enough to drive")
else:
print("You are old enough to drive")
The key components are:
- The
ifkeyword followed by a condition and a colon: - An indented code block that runs only when the condition is
True - An optional
else:block that runs when the condition isFalse - One or more
elif CONDITION:blocks for additional checks (as we used in our guessing game)
Comparison operators let you build conditions:
| Operator | Meaning | Example |
|---|---|---|
== |
Equal to | x == 5 |
!= |
Not equal to | x != 5 |
< |
Less than | x < 5 |
> |
Greater than | x > 5 |
<= |
Less than or equal to | x <= 5 |
>= |
Greater than or equal to | x >= 5 |
Logical operators combine multiple conditions:
| Operator | Meaning | Example |
|---|---|---|
and |
True only if both sides are true | x > 0 and x < 100 |
or |
True if at least one side is true | x == 1 or x == 10 |
not |
Inverts the boolean value | not is_locked |
Consider the following example:
name = "bob"
hungry = True
if name == "bob" and hungry == True:
print("Bob is hungry")
elif name == "bob" and not hungry:
print("Bob is not hungry")
else:
print("Not sure who this is or if they are hungry")
A critical distinction worth repeating: = is the assignment operator (it stores a value in a variable), while == is the equality operator (it compares two values). Confusing the two is one of the most common beginner mistakes.
What's New: Type Conversion and f-strings
If you completed Simple Demo, the material above should feel like familiar territory. The rest of this room introduces concepts that go well beyond what we covered in the guessing game. Let's start with two improvements to how we work with variables.
Type Conversion
As we saw in Simple Demo, input() always returns a string. When the user typed 10 at the prompt, Python stored it as the text "10", not the number 10. We used int() to convert it. Python provides several built-in conversion functions:
| Function | Converts To | Example |
|---|---|---|
int() |
Integer | int("42") gives 42 |
float() |
Float | float("3.14") gives 3.14 |
str() |
String | str(42) gives "42" |
bool() |
Boolean | bool(0) gives False |
Consider the following example:
text = input("Enter a port number: ") # user types 443
print(type(text)) # <class 'str'>
port = int(text) # convert to integer
print(type(port)) # <class 'int'>
print(port + 1) # 444
Without the int() conversion, text + 1 would cause an error because Python does not know how to add a number to a piece of text.
Formatted Strings (f-strings)
In Simple Demo, we used commas inside print() to display variables alongside text, like print("You got it in", tries, "tries!"). This approach works, but modern Python offers a cleaner alternative called f-strings (formatted string literals). An f-string starts with the letter f before the opening quotation mark and lets you embed variables directly inside curly braces:
username = "admin"
port = 443
# Old approach (comma-separated, as used in Simple Demo)
print("User", username, "is on port", port)
# Modern approach (f-string)
print(f"User {username} is on port {port}")
Both lines produce the same output: User admin is on port 443. The f-string version is easier to read and gives you precise control over spacing and formatting. We will use f-strings throughout the rest of this room.
Augmented Assignment Operators
In Simple Demo, we wrote tries = tries + 1 to increment a counter. Python provides a shorthand for this pattern called augmented assignment:
count = 0
count += 1 # same as count = count + 1
count -= 1 # same as count = count - 1
count *= 2 # same as count = count * 2
count /= 4 # same as count = count / 4
These shortcuts make code shorter and reduce the chance of typos. You will see += used frequently in loops and counters.
Open fstrings_demo.py on the attached , run it, and observe how f-strings and augmented assignment operators work in practice.
What built-in function reveals the data type of a value?
If a user types 3.14 at an input() prompt, what data type does Python store it as before any conversion?
On the attached VM, open and run fstrings_demo.py. What is the last line printed to the terminal?
Have you ever filled out an online form and received an error saying "password must contain at least one uppercase letter"? Behind that message is a piece of code that inspects your password character by character. In Python, that inspection is powered by string methods, and mastering them is essential for any script that processes text. In security, that means nearly every script you will ever write.
A string is a sequence of characters enclosed in quotes. You can use single quotes ('hello'), double quotes ("hello"), or triple quotes ("""hello""") for multi-line text. Python treats them all as the same data type.
String Length
The len() function returns how many characters a string contains. This is a fundamental check in many security scripts: is the password long enough? Is the input within expected bounds?
password = "Tr0ub4dor"
length = len(password)
print(f"Password length: {length}") # Password length: 9
String Indexing and Slicing
Each character in a string occupies a numbered position called an index. Python indexes start at 0, not 1. Consider the string "Python":
| Index | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| Character | P | y | t | h | o | n |
word = "Python"
print(word[0]) # P (first character)
print(word[5]) # n (last character)
print(word[-1]) # n (negative index counts from the end)
Slicing lets you extract a portion of a string using the syntax string[start:end]. The start index is included; the end index is excluded.
word = "Python"
print(word[0:3]) # Pyt (characters at index 0, 1, 2)
print(word[2:]) # thon (from index 2 to the end)
print(word[:4]) # Pyth (from the start to index 3)
Useful String Methods
Python strings come with dozens of built-in methods. Here are the ones you will reach for most often:
| Method | What It Does | Example | Result |
|---|---|---|---|
.upper() |
Converts to uppercase | "hello".upper() |
"HELLO" |
.lower() |
Converts to lowercase | "HELLO".lower() |
"hello" |
.strip() |
Removes leading/trailing whitespace | " hi ".strip() |
"hi" |
.replace(a, b) |
Replaces all occurrences of a with b |
"cat".replace("c", "b") |
"bat" |
.split(sep) |
Splits into a list at each sep |
"a,b,c".split(",") |
["a", "b", "c"] |
.startswith(x) |
Checks if string begins with x |
"http://".startswith("http") |
True |
.endswith(x) |
Checks if string ends with x |
"file.txt".endswith(".txt") |
True |
.count(x) |
Counts occurrences of x |
"banana".count("a") |
3 |
Character Checks
For tasks like password validation, we need to know whether a character is a digit, an uppercase letter, or something else. Python provides methods for exactly this:
char = "A"
print(char.isupper()) # True
print(char.islower()) # False
print(char.isdigit()) # False
print(char.isalpha()) # True (is it a letter?)
print(char.isalnum()) # True (is it a letter or digit?)
These methods return a boolean (True or False), which makes them perfect for use inside if statements. We will combine them with loops later in this room to scan every character in a string.
The in Operator
Python's in operator checks whether a substring exists within a larger string. It returns True or False:
url = "https://tryhackme.com/room/pythoncoreconcepts"
print("tryhackme" in url) # True
print("hackthebox" in url) # False
print("https" in url) # True
The in operator is one of the most versatile tools in Python; we will see it again with lists and dictionaries in the next task.
Open strings_demo.py on the VM. The script contains several string operations. Run it and study its output. Then modify the test_string variable at the top to your own name and rerun to see how the output changes.
What function returns the number of characters in a string?
Given word = "TryHackMe", what does word[3:7] return?
What string method converts "ADMIN" to "admin"?
Imagine you are responsible for monitoring a network. You have a list of IP addresses to scan, a collection of open ports for each host, and a mapping of port numbers to service names (port 22 is , port 80 is , and so on). Storing each of these in a separate variable would be impractical. Python gives us two powerful data structures to handle collections of data: lists and dictionaries.
Lists
A list is an ordered collection of items enclosed in square brackets. Items can be of any data type, and the list preserves their order.
ports = [22, 80, 443, 8080]
usernames = ["admin", "root", "guest"]
mixed = ["server1", 443, True]
Accessing and Modifying List Elements
Lists use the same indexing system as strings. The first element is at index 0:
ports = [22, 80, 443, 8080]
print(ports[0]) # 22
print(ports[-1]) # 8080 (last element)
print(ports[1:3]) # [80, 443] (slicing works on lists too)
You can change an element by assigning a new value to its index:
ports[0] = 2222
print(ports) # [2222, 80, 443, 8080]
Common List Methods
| Method | What It Does | Example |
|---|---|---|
.append(x) |
Adds x to the end |
ports.append(3306) |
.remove(x) |
Removes the first occurrence of x |
ports.remove(80) |
.pop(i) |
Removes and returns the item at index i |
ports.pop(0) |
.sort() |
Sorts the list in ascending order | ports.sort() |
.reverse() |
Reverses the list order | ports.reverse() |
len(list) |
Returns the number of items | len(ports) |
The in operator, which we introduced with strings, works on lists as well:
common_passwords = ["123456", "password", "admin", "letmein"]
if "password" in common_passwords:
print("This password is in the common list.")
Dictionaries
A dictionary stores data as key-value pairs enclosed in curly braces. One analogy would be a physical dictionary: you look up a word (the key) to find its definition (the value). In technical terms, a dictionary lets you associate one piece of data with another for quick retrieval.
services = {
22: "SSH",
80: "HTTP",
443: "HTTPS",
3306: "MySQL"
}
Accessing Dictionary Values
You retrieve a value by passing its key inside square brackets:
print(services[22]) # SSH
print(services[443]) # HTTPS
Adding, Updating, and Removing Entries
# Add a new entry
services[8080] = "HTTP-Alt"
# Update an existing entry
services[22] = "OpenSSH"
# Remove an entry
del services[3306]
print(services)
# {22: 'OpenSSH', 80: 'HTTP', 443: 'HTTPS', 8080: 'HTTP-Alt'}
Checking for Keys
if 22 in services:
print(f"Port 22 runs {services[22]}")
Useful Dictionary Methods
| Method | Returns |
|---|---|
.keys() |
All keys in the dictionary |
.values() |
All values in the dictionary |
.items() |
All key-value pairs as tuples |
.get(key, default) |
Value for key, or default if the key does not exist |
The .get() method is particularly useful because accessing a nonexistent key with square brackets causes an error, while .get() lets you supply a safe fallback:
result = services.get(9999, "Unknown")
print(result) # Unknown
Looking Ahead
In the companion room, Python: Building Scripts, we will build a Password Strength Checker that stores a list of common weak passwords loaded from a file and uses a dictionary to map each strength level to a descriptive label. Both data structures will become essential tools in your security scripting toolkit.
Open lists_dicts_demo.py on the VM and run it. The script demonstrates lists and dictionaries using the examples above. After running it, add a new port-service pair to the services dictionary inside the script and rerun it to confirm your change appears in the output.
What method adds an element to the end of a list?
Given services = {22: "SSH", 80: "HTTP"}, what does services[80] return?
What dictionary method lets you retrieve a value with a safe fallback if the key does not exist?
In Simple Demo, we used comparison operators like < and > to compare the user's guess to the secret number. In this task, we expand our operator toolkit with new arithmetic operators and a closer look at how Python evaluates compound conditions.
New Arithmetic Operators
You already know addition (+), subtraction (-), multiplication (*), and division (/). Let's add three more to the set:
| Operator | Name | Example | Result |
|---|---|---|---|
** |
Exponent | 2 ** 8 |
256 |
// |
Floor Division | 7 // 2 |
3 |
% |
Modulus (remainder) | 7 % 2 |
1 |
The modulus operator (%) returns the remainder after division. It is commonly used to check whether a number is even or odd: if number % 2 == 0, the number is even.
Floor division (//) divides and then rounds down to the nearest whole number. Regular division (/) always returns a float: 7 / 2 gives 3.5, while 7 // 2 gives 3.
The exponent operator (**) raises the left number to the power of the right number. For example, 2 ** 8 calculates 2 raised to the 8th power, which is 256. In security, you will often see this when discussing key sizes: a 128-bit key has 2 ** 128 possible combinations.
The Membership Operator: in
We introduced in with strings and lists in previous tasks. It deserves dedicated attention because it works with almost every collection type in Python and will play a central role in many security scripts.
# Checking if a password is in a list of common passwords
common = ["123456", "password", "qwerty", "letmein"]
user_password = "qwerty"
if user_password in common:
print("This password is too common.")
You can negate it with not in:
if user_password not in common:
print("Good. This password is not in the common list.")
Combining Operators in Practice
Consider a practical example. A password might be considered moderate if it is at least 8 characters long and contains at least one digit:
password = "Tr0ubador"
length = len(password)
has_digit = any(char.isdigit() for char in password)
if length >= 8 and has_digit:
print("Moderate strength")
elif length >= 8 or has_digit:
print("Weak, but has some merit")
else:
print("Very weak")
Don't worry if the any() line looks unfamiliar; we will revisit it in the companion room when we cover functions. For now, focus on how and requires both conditions to be true, while or requires only one.
Open operators_demo.py on the attached . The script walks you through each operator with printed examples. Run it and observe the output.
What operator returns the remainder of a division?
What does 10 // 3 evaluate to?
What does 2 ** 10 evaluate to?
In Simple Demo, we used a while loop to keep asking the user for guesses until they found the secret number. The while loop repeats as long as a condition is true; it is perfect when the number of iterations depends on some runtime condition. Python offers a second type of loop, the for loop, which is designed for iterating over a sequence of items. Let's explore both.
Quick Recap: while Loops
A while loop runs as long as its condition evaluates to True:
attempts = 0
max_attempts = 3
while attempts < max_attempts:
password = input("Enter password: ")
attempts += 1
print(f"Attempt {attempts} of {max_attempts}")
This loop asks for a password up to 3 times. Once attempts reaches 3, the condition attempts < max_attempts becomes False, and the loop stops.
The for Loop
Consider the case where you have a list of IP addresses and you want to process each one. You know exactly how many items there are, and you want to visit each one in order. This is the sweet spot for a for loop.
targets = ["192.168.1.1", "192.168.1.2", "192.168.1.3"]
for ip in targets:
print(f"Scanning {ip}...")
# The output would be:
Scanning 192.168.1.1...
Scanning 192.168.1.2...
Scanning 192.168.1.3...
Let's break this down. The variable ip takes on the value of each element in the targets list, one at a time. On the first iteration, ip is "192.168.1.1"; on the second, it is "192.168.1.2"; and so on. The loop ends when every element has been visited.
Iterating Over Strings
A string is also a sequence, so you can loop through it character by character. This is exactly what we need for tasks like password validation:
password = "S3cure!"
for char in password:
if char.isdigit():
print(f"Found digit: {char}")
elif char.isupper():
print(f"Found uppercase: {char}")
# The output would be:
Found uppercase: S
Found digit: 3
The range() Function
Sometimes you need a loop that runs a specific number of times without a predefined list. The range() function generates a sequence of numbers:
# range(stop): 0 to stop-1
for i in range(5):
print(i) # prints 0, 1, 2, 3, 4
# range(start, stop): start to stop-1
for i in range(1, 6):
print(i) # prints 1, 2, 3, 4, 5
# range(start, stop, step): with custom increment
for i in range(0, 20, 5):
print(i) # prints 0, 5, 10, 15
In programming, counting often starts from 0. Consequently, range(5) produces five numbers: 0, 1, 2, 3, and 4.
Iterating Over Dictionaries
As we mentioned in Task 4, dictionaries have .keys(), .values(), and .items() methods. These become especially powerful inside for loops:
services = {22: "SSH", 80: "HTTP", 443: "HTTPS"}
# Loop through both keys and values
for port, name in services.items():
print(f"Port {port} = {name}")
# The output would be:
Port 22 = SSH
Port 80 = HTTP
Port 443 = HTTPS
break and continue
Two keywords give you fine-grained control inside a loop:
breakimmediately exits the loop entirely.continueskips the rest of the current iteration and moves to the next one.
# Stop scanning as soon as we find port 443
for port in [22, 80, 443, 8080]:
if port == 443:
print(f"Port {port} found. Stopping scan.")
break
print(f"Checked port {port}")
# The output would be:
Checked port 22
Checked port 80
Port 443 found. Stopping scan.
Notice that 8080 was never checked because break terminated the loop as soon as we found 443.
# Skip blank lines when processing a file
lines = ["admin", "", "root", "", "guest"]
for line in lines:
if line == "":
continue # skip empty strings
print(f"Processing: {line}")
# The output would be:
Processing: admin
Processing: root
Processing: guest
Choosing Between for and while
A general rule of thumb: use a for loop when you know the number of iterations in advance (a list to process, a range of numbers, a string to scan). Use a while loop when the number of iterations depends on a condition that changes during execution (e.g., waiting for correct input or retrying until a connection succeeds).
On the VM, open loops_demo.py and run it. The script demonstrates for loops, while loops, range(), break, and continue in sequence. Study the output and try adding a new loop that prints every even number from 0 to 20 using range() with a step of 2.
What type of loop is best suited for iterating over each item in a list?
What does range(3) produce?
What keyword immediately exits a loop?
In this room, we covered the data and control flow foundations of Python:
- Data types and type conversion: understanding
str,int,float,booland converting between them withint(),str(),float(), andbool() - Formatted strings: f-strings for clean, readable output
- Strings: indexing, slicing, and powerful built-in methods like
.split(),.strip(),.lower(),.isdigit(), and.isupper() - Lists and dictionaries: storing collections of data and retrieving them efficiently with indexing,
.append(),.get(), and theinoperator - Operators: arithmetic (
+,-,*,/,//,%,**), comparison (==,!=,<,>), logical (and,or,not), and the membership operatorin - Loops:
forloops for sequences and ranges,whileloops for condition-based repetition, plusbreakandcontinue
You now have the vocabulary and mechanics to read, understand, and modify Python programs. The next step is to learn how to structure those programs into something reusable, resilient, and practical. It is time to join the Python: Building Scripts room, where you will define functions, handle errors, read and write files, import libraries, and build a complete Password Strength Checker from scratch.
I have successfully completed the room!
Ready to learn Cyber Security?
TryHackMe provides free online cyber security training to secure jobs & upskill through a fun, interactive learning environment.
Already have an account? Log in