CSAI2026 labs: Lab-2..Lab-6 (Practical + Solution, data), Module-2..Module-6 notebooks and datasets
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "06f7188c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Module 2 — Lab 3: Data Structures and Raw Log Analysis\n",
|
||||
" \n",
|
||||
"**Topics:** list, tuple, dictionary, set, parsing\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": "67ad00e0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Input data\n",
|
||||
"\n",
|
||||
"Each log line contains four comma-separated fields: `timestamp,source_ip,username,status`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4b49fc55",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"raw_logs = [\n",
|
||||
" \"2026-09-01T08:00:00Z,203.0.113.55,alice,SUCCESS\",\n",
|
||||
" \"2026-09-01T08:01:00Z,198.51.100.14,admin,FAILED\",\n",
|
||||
" \"2026-09-01T08:01:20Z,198.51.100.14,root,FAILED\",\n",
|
||||
" \"2026-09-01T08:02:00Z,192.0.2.88,bob,SUCCESS\",\n",
|
||||
" \"2026-09-01T08:02:30Z,198.51.100.14,guest,FAILED\",\n",
|
||||
" \"2026-09-01T08:03:00Z,192.0.2.99,carol,FAILED\",\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"critical_fields = (\"timestamp\", \"source_ip\", \"username\", \"status\")\n",
|
||||
"blocked_ips = {\"198.51.100.14\", \"203.0.113.200\"}\n",
|
||||
"\n",
|
||||
"print(f\"Rows: {len(raw_logs)}\")\n",
|
||||
"print(\"Critical fields:\", critical_fields)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3f8fcb17",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"exercise"
|
||||
]
|
||||
},
|
||||
"source": [
|
||||
"## 1. Convert one log line into a dictionary\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "47d1eb8b",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"solution"
|
||||
]
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def parse_log_line(line):\n",
|
||||
" timestamp, source_ip, username, status = line.split(\",\")\n",
|
||||
" return {\n",
|
||||
" \"timestamp\": timestamp,\n",
|
||||
" \"source_ip\": source_ip,\n",
|
||||
" \"username\": username.lower(),\n",
|
||||
" \"status\": status.upper(),\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"sample_event = parse_log_line(raw_logs[0])\n",
|
||||
"print(sample_event)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "56f0258d",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"exercise"
|
||||
]
|
||||
},
|
||||
"source": [
|
||||
"## 2. Create an event list and a set of unique IP addresses\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a8c8af5e",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"solution"
|
||||
]
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"events = [parse_log_line(line) for line in raw_logs]\n",
|
||||
"unique_ips = {event[\"source_ip\"] for event in events}\n",
|
||||
"\n",
|
||||
"print(\"Unique IPs:\", sorted(unique_ips))\n",
|
||||
"print(\"Number of unique IPs:\", len(unique_ips))\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7651a31c",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"exercise"
|
||||
]
|
||||
},
|
||||
"source": [
|
||||
"## 3. Count failed logins with a dictionary\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0c0a3675",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"solution"
|
||||
]
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"failed_by_ip = {}\n",
|
||||
"\n",
|
||||
"for event in events:\n",
|
||||
" if event[\"status\"] != \"FAILED\":\n",
|
||||
" continue\n",
|
||||
" ip = event[\"source_ip\"]\n",
|
||||
" failed_by_ip[ip] = failed_by_ip.get(ip, 0) + 1\n",
|
||||
"\n",
|
||||
"print(failed_by_ip)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "21436c12",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"exercise"
|
||||
]
|
||||
},
|
||||
"source": [
|
||||
"## 4. Combine dictionaries and sets to create alerts\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "11954df9",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"solution"
|
||||
]
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"alerts = []\n",
|
||||
"\n",
|
||||
"for ip, count in failed_by_ip.items():\n",
|
||||
" if count >= 3 or ip in blocked_ips:\n",
|
||||
" alerts.append({\n",
|
||||
" \"source_ip\": ip,\n",
|
||||
" \"failed_attempts\": count,\n",
|
||||
" \"blocked\": ip in blocked_ips,\n",
|
||||
" })\n",
|
||||
"\n",
|
||||
"print(alerts)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b18d5731",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Self-check\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d30adfba",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert sample_event[\"username\"] == \"alice\"\n",
|
||||
"assert len(events) == 6\n",
|
||||
"assert unique_ips == {\"203.0.113.55\", \"198.51.100.14\", \"192.0.2.88\", \"192.0.2.99\"}\n",
|
||||
"assert failed_by_ip[\"198.51.100.14\"] == 3\n",
|
||||
"assert alerts == [{\"source_ip\": \"198.51.100.14\", \"failed_attempts\": 3, \"blocked\": True}]\n",
|
||||
"print(\"✓ Lab 3 completed\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "55d97609",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Reflection questions\n",
|
||||
"\n",
|
||||
"- Why is a `set` suitable for storing unique IP addresses or a blocklist?\n",
|
||||
"- Why is a `tuple` suitable for field names that should not change?\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