CSAI2026 labs: Lab-2..Lab-6 (Practical + Solution, data), Module-2..Module-6 notebooks and datasets
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "03d77301",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Module 2 — Lab 4: NumPy for Security Metrics\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"**Topics:** array, vectorization, statistics, boolean mask\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"> **Solution version:** This notebook contains the complete solution. Run the cells in order and compare the results with your Lab notebook.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "33cb0ba1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Scenario\n",
|
||||
"\n",
|
||||
"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.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d7d3de72",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"packet_sizes = np.array([64, 128, 1500, 512, 1514, 256, 1400, 80])\n",
|
||||
"latency_ms = np.array([12.5, 18.0, 250.0, 33.5, 180.0, 25.0, 95.0, 10.0])\n",
|
||||
"failed_attempts = np.array([0, 1, 8, 2, 10, 1, 6, 0])\n",
|
||||
"\n",
|
||||
"print(packet_sizes.shape, packet_sizes.dtype)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5d225bd1",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"exercise"
|
||||
]
|
||||
},
|
||||
"source": [
|
||||
"## 1. Unit conversion and descriptive statistics\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3da57f45",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"solution"
|
||||
]
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"packet_kb = packet_sizes / 1024\n",
|
||||
"mean_latency = latency_ms.mean()\n",
|
||||
"p95_latency = np.percentile(latency_ms, 95)\n",
|
||||
"\n",
|
||||
"print(\"Packet sizes (KB):\", np.round(packet_kb, 3))\n",
|
||||
"print(f\"Mean latency: {mean_latency:.2f} ms\")\n",
|
||||
"print(f\"P95 latency: {p95_latency:.2f} ms\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "dddbd812",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"exercise"
|
||||
]
|
||||
},
|
||||
"source": [
|
||||
"## 2. Filter with a Boolean mask\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d24785c0",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"solution"
|
||||
]
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"suspicious_mask = (packet_sizes > 1400) | (latency_ms > 150) | (failed_attempts >= 8)\n",
|
||||
"suspicious_indices = np.where(suspicious_mask)[0]\n",
|
||||
"\n",
|
||||
"print(\"Mask:\", suspicious_mask)\n",
|
||||
"print(\"Suspicious indices:\", suspicious_indices)\n",
|
||||
"print(\"Suspicious packet sizes:\", packet_sizes[suspicious_mask])\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ce903e91",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"exercise"
|
||||
]
|
||||
},
|
||||
"source": [
|
||||
"## 3. Normalize values and create a risk score\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "dcece1eb",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"solution"
|
||||
]
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def min_max(values):\n",
|
||||
" values = np.asarray(values, dtype=float)\n",
|
||||
" value_range = values.max() - values.min()\n",
|
||||
" if value_range == 0:\n",
|
||||
" return np.zeros_like(values)\n",
|
||||
" return (values - values.min()) / value_range\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"latency_score = min_max(latency_ms)\n",
|
||||
"failure_score = min_max(failed_attempts)\n",
|
||||
"risk_score = 0.4 * latency_score + 0.6 * failure_score\n",
|
||||
"\n",
|
||||
"print(\"Risk scores:\", np.round(risk_score, 3))\n",
|
||||
"print(\"Highest-risk index:\", int(np.argmax(risk_score)))\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "65a088f0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Self-check\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a730cc89",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert packet_sizes.shape == (8,)\n",
|
||||
"assert np.isclose(mean_latency, 78.0)\n",
|
||||
"assert suspicious_indices.tolist() == [2, 4]\n",
|
||||
"assert int(np.argmax(risk_score)) == 4\n",
|
||||
"assert np.all((risk_score >= 0) & (risk_score <= 1))\n",
|
||||
"print(\"✓ Lab 4 completed\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2c85c6e5",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Extension challenge\n",
|
||||
"\n",
|
||||
"Change the weights assigned to latency and failed attempts. Observe whether the highest-risk element changes and explain why.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user