Skip to main content

Python f-Strings Lab

· 2 min read

Lab 1: The Resource Alert (Beginner)​

Scenario: You need to notify the team about high CPU usage. Task: Use an f-string to combine a server name and a usage percentage.

Python

server = "Prod-Web-01"
cpu_usage = 94.5

# Task: Print "ALERT: Prod-Web-01 is at 94.5% capacity!"
message = f"ALERT: {server} is at {cpu_usage}% capacity!"
print(message)

Lab 2: The Security Audit Table (Intermediate)​

Scenario: You are printing a list of open ports. You want the output to be neatly aligned. Task: Use f-string padding to align text. (Hint: :<10 aligns left with 10 spaces).

Python

port_data = &#91;("SSH", 22), ("HTTP", 80), ("HTTPS", 443)]

print(f"{'SERVICE':<10} | {'PORT':<5}")
print("-" * 18)
for service, port in port_data:
print(f"{service:<10} | {port:<5}")

Lab 3: The Cost Calculator (Architect Level)​

Scenario: You have a list of microservice costs and you need to print a summary that includes a 10% tax. Task: Perform the math calculation directly inside the f-string.

Python

base_cost = 500.00
tax_rate = 0.10

# Task: Calculate total and format to 2 decimal places
print(f"Base: ${base_cost:.2f}")
print(f"Total (inc. tax): ${base_cost * (1 + tax_rate):.2f}")

Lab 1: The Cloud Cost Estimator (Beginner)​

Scenario: You have a daily server cost and need to estimate the yearly budget, formatted nicely. Task: Calculate the total and format it with commas and 2 decimal places.

Python

daily_cost = 45.50
days = 365

# Calculation inside the f-string
print(f"Estimated Yearly Budget: ${daily_cost * days:,.2f}")
# Output: Estimated Yearly Budget: $16,607.50

Lab 2: The Log Aligner (Intermediate)​

Scenario: You are printing a table of services and their statuses. You want the columns to line up perfectly for readability. Task: Use alignment syntax < (left) and > (right).

Python

services = &#91;("Nginx", "Running"), ("Docker", "Stopped"), ("K8s", "Running")]

print(f"{'SERVICE':<10} | {'STATUS':>10}")
print("-" * 23)

for name, status in services:
print(f"{name:<10} | {status:>10}")

Lab 3: The Dynamic JSON Builder (Architect Level)​

Scenario: You need to generate a JSON payload string to send to a security tool API. Task: Insert variables into a string that looks like JSON. Note: Double the curly braces {{ to print literal braces.

Python

user = "dev_admin"
role = "read-write"

# We use {{ to escape the braces so they appear in the final string
json_payload = f'{{"username": "{user}", "permissions": "{role}"}}'

print(f"Sending payload: {json_payload}")
# Output: Sending payload: {"username": "dev_admin", "permissions": "read-write"}

Python Indexing & Slicing Lab

· 2 min read

Lab 1: The Timestamp Extractor (Beginner)​

Scenario: Standard ISO logs start with a timestamp like 2026-01-29T14:30:05Z. You only need the Year and the Time.

Task: Use slicing to extract the first 4 characters and characters from index 11 to 19.

Python

log_entry = "2026-01-29T14:30:05Z"

# 1. Extract Year (Start to index 4)
year = log_entry&#91;:4]

# 2. Extract Time (From 11 to 19)
time = log_entry&#91;11:19]

print(f"Audit Date: {year}, Audit Time: {time}")

Lab 2: The Extension Auditor (Intermediate)​

Scenario: You are writing a security scanner for uploaded files. You need to identify the file extension, regardless of how long the filename is.

Task: Use negative indexing to grab the last 3 characters of a filename.

Python

filename = "system_vulnerability_report_final_v1.pdf"

# Use negative slicing to get the last 3 chars
extension = filename&#91;-3:]

if extension == "pdf":
print("Document analysis triggered...")
elif extension == "exe":
print("ALERT: Executable detected!")

Lab 3: The "Sanity Check" (Intermediate)​

Scenario: A developer accidentally sent a list of sensitive IPs with a "header" and a "footer" string that shouldn't be there. data = ["HEADER", "192.168.1.1", "10.0.0.5", "172.16.0.2", "FOOTER"]

Task: Use slicing to remove the first and last elements in a single "Symmetrical Slice".

Python

data = &#91;"HEADER", "192.168.1.1", "10.0.0.5", "172.16.0.2", "FOOTER"]

# Symmetrical slice to 'trim' the ends
clean_ips = data&#91;1:-1]

print(f"Cleaned IP List: {clean_ips}")

Lab 4: The Dynamic Image Parser (Architect Level)​

Scenario: You have a Docker image string: registry.hub.docker.com/library/python:3.10-slim. You need to extract the Tag (everything after the colon) dynamically.

Task: Find the index of the colon and slice the string from that point to the end.

Python

image_path = "ghcr.io/devsecops/web-app:v2.4.1-beta"

# 1. Find the position of the colon
colon_pos = image_path.find(":")

# 2. Slice from colon_pos + 1 to the end
tag = image_path&#91;colon_pos + 1:]

print(f"Deploying Version: {tag}")

Lab 5: The Reversed Audit Log (Pro Level)​

Scenario: A buffer stores the last 5 security events, but they are in "Oldest First" order. For your dashboard, you need them in "Newest First" (Reversed).

Task: Use the step parameter to reverse the list.

Python

events = &#91;"Login", "File_Edit", "File_Delete", "Logout", "Admin_Access"]

# The "Pythonic" reversal trick
reversed_events = events&#91;::-1]

print(f"Latest activity first: {reversed_events}")

Python Indexing & Slicing Quiz

· One min read

Slicer

Score: 0/20

🔪 Master Quiz: Indexing & Slicing

Master the art of extracting data with GPS precision using the [start:stop:step] formula.

🎉 Extraction Complete!​

Your Accuracy:

0/20 Novice

  • **↺ Slice Again**

Python String Methods Lab

· 3 min read

Lab: The Log Scrubber​

Try this in your Python terminal to see the power of chaining:

# Raw, messy log entry from a server
raw_log = " ERROR: Connection failed from IP 192.168.1.1 \n"

# 1. Clean whitespace
clean_log = raw_log.strip()

# 2. Check if it's an error
is_error = clean_log.startswith("ERROR")

# 3. Extract the IP (The Architect way)
log_parts = clean_log.split(" ")
ip_address = log_parts&#91;-1]

print(f"Status: {is_error}, IP: {ip_address}")

Lab 1: The Config File Sanitizer (Beginner)​

Scenario: You have a configuration file where users often add accidental spaces or use inconsistent casing. You need to "normalize" these keys to ensure your script reads them correctly.

Task: Clean the following list of raw configuration keys so they are all lowercase, have no leading/trailing spaces, and replace internal spaces with underscores.

raw_configs = &#91;" Max_Connections ", "timeout ", " RETRY_COUNT", "Buffer Size "]

# Your Code Here:
for config in raw_configs:
# 1. Strip spaces
# 2. Convert to lowercase
# 3. Replace spaces with underscores
clean_config = config.strip().lower().replace(" ", "_")
print(f"Validated: '{clean_config}'")

Lab 2: The Secret Masker (Intermediate)​

Scenario: For security reasons, you must never print a full API Key in your logs. You need to write a script that "masks" a key, showing only the first 4 and last 4 characters, with asterisks in the middle.

Task: Take an API key string and return the masked version.

api_key = "prod_9283746551029384756"

# Logic:
# 1. Get the first 4 chars
# 2. Get the last 4 chars
# 3. Use .count() to see how many chars to mask (optional) or use string slicing
# 4. Join them with "********"

prefix = api_key&#91;:4]
suffix = api_key&#91;-4:]
masked_key = prefix + "*" * 10 + suffix

print(f"Logging Access for Key: {masked_key}")

Lab 3: The Automated SQLi Filter (Architect Level)​

Scenario: You are building a basic security middleware. You need to detect if a user input string contains common SQL Injection keywords or suspicious characters.

Task: Create a function that checks if a string is "safe." A string is unsafe if it contains symbols like ', ;, or -- or keywords like DROP or DELETE.

def is_input_safe(user_input):
# Normalize input for checking
check_val = user_input.upper()

# Check for keywords
if "DROP" in check_val or "DELETE" in check_val:
return False

# Check for suspicious symbols
if ";" in user_input or "--" in user_input:
return False

return True

# Test cases
print(is_input_safe("admin' --")) # Should be False
print(is_input_safe("john_doe_2026")) # Should be True

Lab 4: CSV Data Extractor (Architect Level)​

Scenario: You receive a comma-separated string representing a user's permissions: Username,Role,Region,Department. You need to extract the Role and Department to verify access.

Task: Use .split() and indexing to extract specific data.

access_log = "amit_sharma,Security_Admin,Mumbai,Infrastructure"

# 1. Split by comma
data = access_log.split(",")

# 2. Assign variables via indexing
username = data&#91;0]
role = data&#91;1]
dept = data&#91;-1]

print(f"User {username} from {dept} is requesting {role} access.")

Lab 5: The File Extension Auditor​

Scenario: You are scanning a directory for malware. You only want to analyze files that end in .sh, .py, or .exe.

Task: Write a loop that filters a list of filenames based on their extension.

files = &#91;"backup.zip", "install.sh", "script.py", "virus.exe", "notes.txt"]
dangerous_files = &#91;]

for file in files:
if file.endswith((".sh", ".py", ".exe")):
dangerous_files.append(file)

print(f"Files to audit: {dangerous_files}")

Challenge Lab: The "Clean URL" Generator​

Combine multiple methods to turn a blog title into a URL slug.

  • Input: "How to Secure your Docker Containers in 2026!"

  • Output: "how-to-secure-your-docker-containers-in-2026"

Hint: Use .lower(), .strip(), .replace(), and remember to remove the "!" punctuation!

Python String Methods Quiz

· One min read

Toolbox

Score: 0/20

🛠️ Master Quiz: String Methods

Open the toolkit: Test your skills with Sandpaper (.strip), Saws (.split), and Glue (.join).

🎉 Construction Complete!​

Your Craftsmanship:

0/20 Novice

  • **↺ Re-Open Toolkit**

Python Creating Strings Lab

· 4 min read

Lab: The "Config Generator"​

Scenario: You need to create a configuration string for a database connection. The database password has special characters, and the directory path is on Windows.

Task: Create the connection string correctly without errors.

# Inputs
db_host = "192.168.1.50"
db_port = 5432
# Note: Raw string used here because of backslashes in path
db_path = r"D:\Data\Systems\db_vol"
# Note: Standard string used, but we must be careful if it had quotes
db_pass = "Secure#Pass123"

# Creating the Connection String using f-string (The best way)
connection_string = f"""
&#91;Database Config]
Host: {db_host}
Port: {db_port}
Path: {db_path}
Password: {db_pass}
Status: Active
"""

print(connection_string)

Output:

&#91;Database Config]
Host: 192.168.1.50
Port: 5432
Path: D:\Data\Systems\db_vol
Password: Secure#Pass123
Status: Active

Lab: The "Smart" Registration Form (Beginner)​

Concept: Input handling, cleaning whitespace, and standardizing text case. Scenario: Users often enter data messily (e.g., " jOhn ", "INDIA "). Your script must clean this up before saving it to a database.

Task:

  • Accept a username and country from the user.

  • Remove extra spaces from the start/end.

  • Format the name to "Title Case" (e.g., John).

  • Format the country to "Upper Case" (e.g., INDIA).

  • Generate a welcome message using an f-string.

# 1. Take dirty input (simulating user typing)
raw_name = " raHul "
raw_country = " india "

print(f"Raw Input: '{raw_name}' and '{raw_country}'")

# 2. Clean and Format
# strip() removes spaces, title() fixes capitalization
clean_name = raw_name.strip().title()

# strip() removes spaces, upper() capitalizes everything (standard for country codes)
clean_country = raw_country.strip().upper()

# 3. Generate Output
welcome_msg = f"Welcome, {clean_name}! Registration for {clean_country} is complete."

print(welcome_msg)
# Expected Output: Welcome, Rahul! Registration for INDIA is complete.

Lab 2: The Log Analyzer (Intermediate)​

Concept: String slicing, finding indices, and parsing unstructured text. Scenario: You have a long server log string. You need to extract the specific Transaction ID hidden inside it to debug an error.

Data: INFO 2026-01-25 [Server-1] TransactionID:TXN-998877 completed successfully.

Task: Locate where the ID starts and ends, extract it, and verify it starts with "TXN".

log_line = "INFO 2026-01-25 &#91;Server-1] TransactionID:TXN-998877 completed successfully."

# 1. Find the starting position
# We look for the label "TransactionID:"
start_marker = "TransactionID:"
start_index = log_line.find(start_marker)

# 2. Calculate the exact start of the value
# We add the length of the marker so we start reading AFTER the colon
value_start = start_index + len(start_marker)

# 3. Find the ending position
# The ID ends where the next space begins
end_index = log_line.find(" ", value_start)

# 4. Slice the string
txn_id = log_line&#91;value_start:end_index]

print(f"Extracted ID: {txn_id}")

# 5. Validation Check
if txn_id.startswith("TXN"):
print("Valid Transaction format.")
else:
print("Invalid format!")

Lab: The SQL Injection Blocker (DevSecOps Focus)​

Concept: String replacement (.replace()) and security sanitization. Scenario: A hacker tries to input a username with a single quote ' to break your database query (SQL Injection). As a DevSecOps engineer, you must neutralize this threat.

Input: admin' OR '1'='1 Task: Detect the dangerous character (') and remove it before processing.

# Dangerous input mimicking a hacker
user_input = "admin' OR '1'='1"

print(f"Malicious Input: {user_input}")

# 1. Detect Threat
# logic: if a single quote exists, it is risky
if "'" in user_input:
print("WARNING: SQL Injection attempt detected!")

# 2. Sanitize (Neutralize the threat)
# We replace the single quote with an empty string (delete it)
safe_input = user_input.replace("'", "")

print(f"Sanitized Input: {safe_input}")

else:
print(f"Input is safe: {user_input}")

# Result: The script processes "admin OR 1=1", which effectively breaks the attack logic.

Lab: The Dynamic Kubernetes Config Generator (Architect Level)​

Concept: Multi-line strings ("""), formatting, and automation. Scenario: You need to deploy 50 microservices. Writing 50 YAML files manually is impossible. You need a Python script to generate the Kubernetes configuration string dynamically based on the App Name and Port.

Task: Create a template using a multi-line f-string and fill it with variables.

# Configuration Variables
app_name = "payment-service"
image_version = "v2.5.0"
container_port = 8080
env_type = "Production"

# Creating the YAML Manifest
# We use triple quotes (""") to keep the indentation (crucial for YAML)
k8s_manifest = f"""
apiVersion: apps/v1
kind: Deployment
metadata:
name: {app_name}
labels:
env: {env_type}
spec:
replicas: 3
template:
spec:
containers:
- name: {app_name}
image: myrepo/{app_name}:{image_version}
ports:
- containerPort: {container_port}
"""

print("--- Generated Kubernetes Manifest ---")
print(k8s_manifest)

# Note: In a real script, you would write this string to a file like 'deployment.yaml'

Python Creating Strings Quiz

· One min read

String Theory

Score: 0/20

📜 Master Quiz: Python Strings

Test your knowledge on Immutability, f-strings, and Escaping.

🎉 Text Processing Complete!​

Your Proficiency:

0/20 Novice

  • **↺ Parse Again**

Python String Characteristics Lab

· 5 min read

Lab: The "Immutable" Log Fixer​

Scenario: You have received a server log where the server name was recorded incorrectly as "server-production". Due to a policy change, all servers must start with "SRV-". Since you cannot change the string in place, you must reconstruct it.

Task:

  • Check if the string starts with "server".

  • Create a new string that replaces "server" with "SRV".

  • Verify the new string is actually a new object in memory.

# Lab Code

# 1. Old String
old_log = "server-production-01"
print(f"Original: {old_log} | ID: {id(old_log)}")

# 2. Transformation (Since we can't do old_log&#91;0:6] = "SRV")
# We use slicing to keep everything AFTER index 6 ("-production-01")
remaining_part = old_log&#91;6:]

# Construct New String
new_log = "SRV" + remaining_part

# 3. Verification
print(f"Fixed: {new_log} | ID: {id(new_log)}")

# Logic Check
if id(old_log) != id(new_log):
print("Success: A new immutable string object was created.")
else:
print("Error: IDs match.")

Lab 1: Visualizing Immutability (Memory Lab)​

Task: Prove that modifying a string changes its memory location.

# Lab 1: The Identity Check
user_role = "admin"
print(f"Original Role: {user_role} | Memory Address: {id(user_role)}")

# Attempt to 'modify' (concatenation)
user_role = user_role + "_sys"
print(f"New Role: {user_role} | Memory Address: {id(user_role)}")

# Observation: The memory addresses are totally different.
# Proof: The original "admin" string was NOT changed; a new "admin_sys" was created.

Lab 2: Iteration for Security (Password Strength)​

Task: Use the Iterable nature of strings to count digits in a password.

# Lab 2: The Strength Checker
password = "SecurePass123!"
digit_count = 0

# Iterating through the string character by character
for char in password:
# Check if the character is a number
if char.isdigit():
digit_count += 1

print(f"Password '{password}' contains {digit_count} numbers.")
# Output: Password 'SecurePass123!' contains 3 numbers.

Lab 3: Ordered Slicing (Log Extraction)​

Task: Use the Ordered nature to extract specific data from a structured string.

# Lab 3: The Order Extractor
# Standard Format: &#91;Date] &#91;Level] Message
log_entry = "&#91;2026-01-28] &#91;ERROR] DB Connection Failed"

# Because strings are ordered, we know exactly where the Date is relative to brackets
date_part = log_entry&#91;1:11]
print(f"Date of Incident: {date_part}")
# Output: 2026-01-28

Lab 1: The "Secret Key" Masker (Immutability & Ordering)​

Concept: Since strings are Immutable, you cannot just overwrite the middle characters of a password to hide them. You must use Slicing (Order) to cut the head and tail, and create a new string with stars in the middle.

Scenario: You are building a logging system. When an API Key is printed to the logs, it must be masked so that only the first 4 and last 4 characters are visible.

Input: API_KEY = "SK_live_51Mz9AaT7bCq8Zp2"

Task:

  • Extract the first 4 characters.

  • Extract the last 4 characters.

  • Calculate how many hidden characters are in the middle.

  • Create a new masked string.

# Lab 1 Solution

api_key = "SK_live_51Mz9AaT7bCq8Zp2"

# 1. Slice the Start (Indices 0 to 3)
prefix = api_key&#91;0:4]

# 2. Slice the End (Last 4 characters)
suffix = api_key&#91;-4:]

# 3. Calculate masking length
# Total length - (length of prefix + length of suffix)
mask_length = len(api_key) - (len(prefix) + len(suffix))

# 4. Construct the NEW string (Concatenation)
masked_key = prefix + ("*" * mask_length) + suffix

print(f"Original: {api_key}")
print(f"Masked: {masked_key}")

# Verification of Immutability:
# api_key is still the same. 'masked_key' is a new object.
print(f"Original is untouched: {api_key}")

Lab 2: The Permission Analyzer (Iterable)​

Concept: Strings are Iterable. You can loop through them to check every single character.

Scenario: In Linux, file permissions are often shown as strings like rwxr-xr-x (Read, Write, Execute). You need to write a script that iterates through this string and raises a "Security Alert" if the Write ('w') permission is found more than once (meaning it's too open).

Input: permissions = "rwxrwxrwx" (777 - Very Dangerous!)

Task:

  • Loop through the string character by character.

  • Count how many times 'w' appears.

  • If count > 1, print a red alert.

# Lab 2 Solution

permissions = "rwxrwxrwx"
write_count = 0

# 1. Iterate through the string
for char in permissions:
# 2. Check condition
if char == 'w':
write_count = write_count + 1

# 3. Decision Logic
print(f"Analyzing permissions: {permissions}")

if write_count > 1:
print(f"SECURITY ALERT: Write permission found {write_count} times! Too dangerous.")
else:
print("Permissions look safe.")

Lab 3: The Version Extractor (Ordered)​

Concept: Strings are Ordered. We rely on specific positions (indexes) to extract meaningful data.

Scenario: You have a list of backup files named backup_2026_v1.tar.gz. You need to extract just the Year (2026) to organize them into folders. You know the format is always backup_YEAR_....

Task: Use slicing with specific indices to extract the year.

# Lab 3 Solution

filename = "backup_2026_v1.tar.gz"

# We know the format:
# b a c k u p _ 2 0 2 6 ...
# 0 1 2 3 4 5 6 7 8 9 10

# The year starts at index 7 and ends at index 11 (exclusive)
year = filename&#91;7:11]

print(f"Processing File: {filename}")
print(f"Extracted Year: {year}")

# Advanced Architect Tip:
# If the filename length changes, slicing by hard numbers is risky.
# Better to use .split('_') if the separator is consistent.
parts = filename.split('_') # &#91;'backup', '2026', 'v1.tar.gz']
print(f"Safer Extraction: {parts&#91;1]}")

Lab 4: The "Reverse" Encryption (Ordered)​

Concept: Python's unique slicing capability [::-1] allows you to reverse the Order of a string instantly.

Scenario: You need to send a simple obfuscated message over a network so it isn't readable by a casual glance. You decide to reverse the string.

Task:

  • Take a message string.

  • Create a reversed version.

  • Reverse it back to prove it works.

# Lab 4 Solution

message = "DevSecOps"

# 1. Reverse the string using negative step slicing
# Syntax: &#91;start : end : step]
# Step -1 means "walk backwards"
encrypted = message&#91;::-1]

print(f"Original: {message}")
print(f"Encrypted: {encrypted}")

# 2. Decrypt (Reverse the reversed string)
decrypted = encrypted&#91;::-1]

print(f"Decrypted: {decrypted}")

# Validation
if message == decrypted:
print("Integrity Check Passed.")

Python String Characteristics Quiz

· One min read

String Logic

Score: 0/20

🔒 Master Quiz: String Characteristics

Deep dive into Immutability, Ordering, and Memory Efficiency.

🎉 Analysis Complete!​

Your Status:

0/20 Novice

  • **↺ Re-Run Tests**