{ "cells": [ { "cell_type": "markdown", "id": "db19a07f", "metadata": {}, "source": [ "# Module 2 — Lab 2: Control Flow and Functions\n", " \n", "**Topics:** if/elif/else, for, while, break, continue, function\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": "0d178b19", "metadata": {}, "source": [ "## Scenario\n", "\n", "You need to build small rules that classify login alerts and automatically review a list of IP addresses. All activity is simulated with local data; this notebook does not connect to or scan any real system.\n" ] }, { "cell_type": "markdown", "id": "56bc45d4", "metadata": { "tags": [ "exercise" ] }, "source": [ "## 1. Classify failed login attempts\n" ] }, { "cell_type": "code", "execution_count": null, "id": "dac7be01", "metadata": { "tags": [ "solution" ] }, "outputs": [], "source": [ "failed_attempts = 7\n", "\n", "if failed_attempts >= 10:\n", " severity = \"CRITICAL\"\n", "elif failed_attempts >= 5:\n", " severity = \"HIGH\"\n", "elif failed_attempts >= 1:\n", " severity = \"MEDIUM\"\n", "else:\n", " severity = \"LOW\"\n", "\n", "print(severity)\n" ] }, { "cell_type": "markdown", "id": "63b6d1a8", "metadata": { "tags": [ "exercise" ] }, "source": [ "## 2. Review IP addresses with `for`, `continue`, and `break`\n" ] }, { "cell_type": "code", "execution_count": null, "id": "3820130f", "metadata": { "tags": [ "solution" ] }, "outputs": [], "source": [ "blocked_ips = {\"10.0.0.5\", \"10.0.0.12\"}\n", "targets = [f\"10.0.0.{i}\" for i in range(1, 16)]\n", "reviewed = []\n", "\n", "for ip in targets:\n", " last_octet = int(ip.split(\".\")[-1])\n", "\n", " if last_octet % 2 != 0:\n", " continue\n", "\n", " reviewed.append(ip)\n", " print(f\"Reviewing: {ip}\")\n", "\n", " if ip in blocked_ips:\n", " print(f\"Alert: blocked IP found: {ip}\")\n", " break\n", "\n", "print(\"Reviewed:\", reviewed)\n" ] }, { "cell_type": "markdown", "id": "61f09e15", "metadata": { "tags": [ "exercise" ] }, "source": [ "## 3. Limit retry attempts with `while`\n" ] }, { "cell_type": "code", "execution_count": null, "id": "0ec1dc95", "metadata": { "tags": [ "solution" ] }, "outputs": [], "source": [ "attempt = 0\n", "max_attempts = 3\n", "service_responded = False\n", "\n", "while attempt < max_attempts and not service_responded:\n", " attempt += 1\n", " print(f\"Health check attempt {attempt}\")\n", " service_responded = attempt == 2\n", "\n", "print(f\"Service responded: {service_responded}\")\n" ] }, { "cell_type": "markdown", "id": "b849e734", "metadata": { "tags": [ "exercise" ] }, "source": [ "## 4. Package a rule in a function\n" ] }, { "cell_type": "code", "execution_count": null, "id": "a34324a1", "metadata": { "tags": [ "solution" ] }, "outputs": [], "source": [ "def classify_login_risk(failed_attempts, is_admin=False, is_off_hours=False):\n", " # Return LOW, MEDIUM, HIGH, or CRITICAL for a login event.\n", " score = failed_attempts * 10\n", " if is_admin:\n", " score += 25\n", " if is_off_hours:\n", " score += 15\n", "\n", " if score >= 100:\n", " return \"CRITICAL\"\n", " if score >= 60:\n", " return \"HIGH\"\n", " if score >= 30:\n", " return \"MEDIUM\"\n", " return \"LOW\"\n", "\n", "\n", "print(classify_login_risk(2))\n", "print(classify_login_risk(7, is_off_hours=True))\n", "print(classify_login_risk(8, is_admin=True))\n" ] }, { "cell_type": "markdown", "id": "aba3b1a8", "metadata": {}, "source": [ "## Self-check\n" ] }, { "cell_type": "code", "execution_count": null, "id": "de52830d", "metadata": {}, "outputs": [], "source": [ "assert severity == \"HIGH\"\n", "assert reviewed == [\"10.0.0.2\", \"10.0.0.4\", \"10.0.0.6\", \"10.0.0.8\", \"10.0.0.10\", \"10.0.0.12\"]\n", "assert attempt == 2 and service_responded is True\n", "assert classify_login_risk(2) == \"LOW\"\n", "assert classify_login_risk(7, is_off_hours=True) == \"HIGH\"\n", "assert classify_login_risk(8, is_admin=True) == \"CRITICAL\"\n", "print(\"✓ Lab 2 completed\")\n" ] }, { "cell_type": "markdown", "id": "c97e0f71", "metadata": {}, "source": [ "## Extension challenge\n", "\n", "Modify the function to add 20 points when `source_ip` belongs to a set of blocked IP addresses. Write at least two `assert` statements for the new rule.\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 }