Python Data Types Lab

Lab 1: The “Type Inspector” Check the types of various DevOps data points.

api_response = {"status": 200, "body": "OK"} # dict
server_list = ["10.0.0.1", "10.0.0.2"]       # list
is_secure = True                             # bool
max_retries = 5                              # int
latency = 0.45                               # float

print(f"API is {type(api_response)}")
print(f"Latency is {type(latency)}")

Lab 2: The “Strong Typing” Crash Try to add text and numbers.

port = 8080
msg = "Server running on port "

# print(msg + port) # CRASH: TypeError: can only concatenate str (not "int") to str

# Fix: Casting (converting)
print(msg + str(port)) # Works!

Lab 3: Sets for Uniqueness DevOps Scenario: You scanned logs and found duplicate IPs. Clean them up.

dirty_ips = ["192.168.1.1", "10.0.0.5", "192.168.1.1", "10.0.0.5"]
unique_ips = set(dirty_ips)

print(unique_ips) 
# Output: {'10.0.0.5', '192.168.1.1'} (Duplicates gone instantly!)

Lab 4: The “JSON Config” Challenge (Dictionaries)

Scenario: You are working with a JSON configuration file (represented as a Python Dictionary) for a Kubernetes Pod. You need to safely extract the “Image” name.

  • The Trap: Accessing a key that doesn’t exist crashes the script with a KeyError.
  • The Fix: Use the .get() method.
# A typical nested dictionary (like a JSON file)
k8s_pod = {
    "metadata": {
        "name": "nginx-pod",
        "namespace": "production"
    },
    "spec": {
        "containers": [
            {"name": "nginx", "image": "nginx:1.14.2"}
        ]
    }
}

# 1. The Risky Way (Direct Access)
# If 'status' key is missing, this line crashes the script!
# print(k8s_pod["status"]["phase"]) # Uncommenting this causes KeyError

# 2. The Safe Way (Using .get)
# Returns 'None' or a default value instead of crashing
pod_phase = k8s_pod.get("status", "Unknown") 
print(f"Pod Phase: {pod_phase}")

# 3. Accessing Nested Data
image_name = k8s_pod["spec"]["containers"][0]["image"]
print(f"Container Image: {image_name}")
  • Architect Insight: In automation pipelines, never assume a key exists. Always use .get() to prevent your entire pipeline from failing just because one optional field was missing.

Lab 5: The “Boolean Trap” (Type Casting Danger)

Scenario: You are reading Environment Variables to enable DEBUG mode.

  • The Problem: Environment variables are always Strings.
  • The Trap: bool("False") evaluates to True in Python! Why? Because any non-empty string is “Truthy”.
# Simulation of reading an Env Variable
env_debug_value = "False"  # This is what you get from os.environ

# BEGINNER MISTAKE:
is_debug_on = bool(env_debug_value)
print(f"Is Debug ON? {is_debug_on}") 
# Output: True (Wait, what?? We set it to False!)

# ARCHITECT FIX:
# Compare the string value directly
real_debug_status = env_debug_value.lower() == "true"
print(f"Is Debug ON (Fixed)? {real_debug_status}")
# Output: False (Correct)
  • Why this matters: I have seen production servers accidentally run in “Debug Mode” (exposing sensitive data) because of this specific misunderstanding of Python Data Types.

Lab 6: The “Log Parser” (String Splitting & Lists)

Scenario: You have a raw log line from a firewall. You need to extract the IP Address and the Error Code.

  • Concept: Strings are just sequences of characters. You can split them into a List.
raw_log = "2024-01-20 10:00:01 | ERROR | 192.168.1.50 | Connection Refused"

# Split the string by the separator " | "
log_parts = raw_log.split(" | ")

print(f"Parsed Data: {log_parts}")
print(f"Type of data: {type(log_parts)}")

# Extract specific fields using List Indexing
timestamp = log_parts[0]
severity = log_parts[1]
ip_address = log_parts[2]

print(f"Alert! Malicious traffic from {ip_address} with severity {severity}")

Output:

Parsed Data: ['2024-01-20 10:00:01', 'ERROR', '192.168.1.50', 'Connection Refused']
Alert! Malicious traffic from 192.168.1.50 with severity ERROR

Lab 7: The “Immutable Credentials” (Tuple vs List)

Scenario: You are storing database credentials in your script.

  • Goal: Ensure that no other part of the script can accidentally change the port number or password.
  • Solution: Use a Tuple.
# Tuple: (Host, Port, DB_Name)
db_config = ("db.prod.local", 5432, "users_db")

print(f"Connecting to {db_config[0]} on port {db_config[1]}...")

# Try to hack the port (Simulating a bug in code)
try:
    db_config[1] = 8080 # Trying to change 5432 to 8080
except TypeError as e:
    print(f"Security Blocked: {e}") 
    # Output: 'tuple' object does not support item assignment
  • Architect Insight: Using Tuples communicates “Intent”. It tells other developers (and the future you): “Do not touch this data, it is constant.”

Lab 8: Identifying Binary Data (Bytes)

Scenario: You are checking if a file is an image or a text file by looking at the header (magic bytes).

  • Concept: b"..." denotes a Byte Literal, distinct from a standard String.
# A standard string
text_header = "PNG" 

# A byte string (Machine readable data)
binary_header = b"PNG"

print(f"Type of text: {type(text_header)}")   # <class 'str'>
print(f"Type of binary: {type(binary_header)}") # <class 'bytes'>

# They are NOT equal
print(f"Are they equal? {text_header == binary_header}") # False

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top