Files
labs/Lab-2/Lab-2-Practical/04_NumPy_Security_Metrics_Lab.ipynb

4.8 KiB

Module 2 — Lab 4: NumPy for Security Metrics

Topics: array, vectorization, statistics, boolean mask

Instructions: Run the cells in order. Complete every TODO, then run the Self-check cell. Do not open the Solution notebook before attempting the tasks yourself.

Scenario

A network sensor reports packet sizes, latency, and failed authentication attempts for each time window. We use NumPy to calculate efficiently across the entire array.

In [ ]:
import numpy as np

packet_sizes = np.array([64, 128, 1500, 512, 1514, 256, 1400, 80])
latency_ms = np.array([12.5, 18.0, 250.0, 33.5, 180.0, 25.0, 95.0, 10.0])
failed_attempts = np.array([0, 1, 8, 2, 10, 1, 6, 0])

print(packet_sizes.shape, packet_sizes.dtype)

1. Unit conversion and descriptive statistics

In [ ]:
# TODO 1: convert packet_sizes from bytes to KB with a vectorized operation
packet_kb = None

# TODO 2: calculate the mean and 95th percentile of latency_ms
mean_latency = None
p95_latency = None

print("Packet sizes (KB):", packet_kb)
print("Mean latency:", mean_latency)
print("P95 latency:", p95_latency)

2. Filter with a Boolean mask

In [ ]:
# TODO 3: True when size > 1400 OR latency > 150 OR failures >= 8
suspicious_mask = None

# TODO 4: obtain the indices matching the mask with np.where
suspicious_indices = None

print("Mask:", suspicious_mask)
print("Suspicious indices:", suspicious_indices)

3. Normalize values and create a risk score

In [ ]:
def min_max(values):
    values = np.asarray(values, dtype=float)
    # TODO 5: return a zero array when max == min; otherwise apply min-max normalization
    pass


latency_score = min_max(latency_ms)
failure_score = min_max(failed_attempts)

# TODO 6: calculate 40% latency_score + 60% failure_score
risk_score = None

print("Risk scores:", risk_score)
print("Highest-risk index:", None if risk_score is None else int(np.argmax(risk_score)))

Self-check

In [ ]:
assert packet_sizes.shape == (8,)
assert np.isclose(mean_latency, 78.0)
assert suspicious_indices.tolist() == [2, 4]
assert int(np.argmax(risk_score)) == 4
assert np.all((risk_score >= 0) & (risk_score <= 1))
print("✓ Lab 4 completed")

Extension challenge

Change the weights assigned to latency and failed attempts. Observe whether the highest-risk element changes and explain why.