{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0de84a0a-f0bf-47fb-985b-1b6e0014a884",
   "metadata": {},
   "source": [
    "# Conditionals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e7777f4f-543c-4b79-a33c-3969f4cf9a89",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "from pathlib import Path\n",
    "\n",
    "# Find project root by looking for _config.yml\n",
    "current = Path.cwd()\n",
    "for parent in [current, *current.parents]:\n",
    "    if (parent / '_config.yml').exists():\n",
    "        project_root = parent  # ← Add project root, not chapters\n",
    "        break\n",
    "else:\n",
    "    # Fallback: go up 2 levels from notebook\n",
    "    project_root = Path.cwd().parent.parent\n",
    "\n",
    "# Add project root to path\n",
    "sys.path.insert(0, str(project_root))\n",
    "\n",
    "# Now import from project root\n",
    "from shared import thinkpython  # ← Direct import, not from shared"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c727861d",
   "metadata": {},
   "source": [
    "The main topic of conditionals is the `if` statement, which executes different code depending on the program's state. Some topics are essential to understand before you learn conditional statements: \n",
    "- boolean expressions for `True`/`False` decision, and \n",
    "- logical operators for combining Boolean expressions.\n",
    "\n",
    "There are five main kinds of conditional statements:\n",
    "1. Conditional Execution\n",
    "2. Alternative Execution\n",
    "3. Chained Conditional\n",
    "4. Nested Conditional\n",
    "5. The Match Statement (not covered in this section)\n",
    "\n",
    "We will start by looking at a use case of integer division and modulus operators to clarify the concept of `if`/`then` conditions."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce9f3fad",
   "metadata": {},
   "source": [
    "## Integer division and modulus\n",
    "\n",
    "Recall that the **integer division operator**, `//`, divides two numbers and rounds down to an integer. \n",
    "\n",
    "Integer division and modulus are often used together with conditional statements. Recall that for division we have: \n",
    "\n",
    "- **floating-point division** operator **`/`** calculates the precise mathematical quotient, including any fractional part, and always returns a **float** data type.\n",
    "- **integer division** (also called **floor division**) operator, **`//`**, performs division and then discards the fractional part, effectively rounding down to the nearest whole number (the \"floor\"); \n",
    "\n",
    "| Operator              | What it does          | Common conditional use                         |\n",
    "| --------------------- | --------------------- | ---------------------------------------------- |\n",
    "| `%` (modulus)         | Gets **remainder**        | Check **if** a number is even, multiple, cycle, etc. |\n",
    "| `//` (floor division) | Gets integer **quotient** | Check **if** a number is in a “group” or “range”   |\n",
    "\n",
    "\n",
    "For example, suppose the run time of a movie is 105 minutes. You might want to know how long that is in hours. Conventional division returns a floating-point number:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "65984e9c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.75"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "minutes = 105\n",
    "minutes / 60"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "efcd3992",
   "metadata": {},
   "source": [
    "But we don't normally write hours with decimal points.\n",
    "Integer division returns the integer number of hours, rounding down:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a936ed88",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "minutes = 105\n",
    "hours = minutes // 60\n",
    "hours"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cff1e105",
   "metadata": {},
   "source": [
    "To get the remainder, you could subtract off one hour in minutes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "14e002a2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "45"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "remainder = minutes - hours * 60\n",
    "remainder"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d7a26a7",
   "metadata": {},
   "source": [
    "Or you could use the **modulus operator**, `%`, which divides two numbers and returns the remainder."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "63b24da5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "45"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "remainder = minutes % 60\n",
    "remainder"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f35bf4f0",
   "metadata": {},
   "source": [
    "The modulus operator is more useful than it might seem.\n",
    "For example, it can check whether one number is divisible by another -- if `x % y` is zero, then `x` is divisible by `y`.\n",
    "\n",
    "Also, it can extract the right-most digit or digits from a number.\n",
    "For example, `x % 10` yields the right-most digit of `x` (in base 10).\n",
    "Similarly, `x % 100` yields the last two digits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "743ca769",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = 123\n",
    "x % 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9f1929f3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "23"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x % 100"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22321bf1",
   "metadata": {},
   "source": [
    "Finally, the modulus operator can do \"clock arithmetic\".\n",
    "For example, if an event starts at 11 AM and lasts three hours, we can use the modulus operator to figure out what time it ends."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "cb1092fd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "start = 11\n",
    "duration = 3\n",
    "end = (start + duration) % 12\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f64d800",
   "metadata": {},
   "source": [
    "The event would end at 2 PM."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "1559a43f-0c5b-4164-9ab9-cde0acd18ec0",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### Exercise: modulus & floor division\n",
    "### How many hours, minutes, and seconds are there in 12345 seconds? \n",
    "### (Convert an integer, n in seconds, into hours, minutes, and seconds.)\n",
    "### Use f-string to print\n",
    "### Your output should be the same as the cell below\n",
    "### Your code starts here\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "### Your code ends here"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "87d51c7a-0a0e-4093-a4dd-f882a2868959",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3 hours, 25 minutes, and 45 seconds.\n"
     ]
    }
   ],
   "source": [
    "seconds = 12345\n",
    "seconds = seconds % (24 * 3600)\n",
    "hours = seconds // 3600\n",
    "seconds %= 3600\n",
    "minutes = seconds // 60\n",
    "seconds %= 60\n",
    "\n",
    "print(f\"{hours} hours, {minutes} minutes, and {seconds} seconds.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d9041b0-39be-4a44-b799-88ddeb3ac46e",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "## `if` statements"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e0a27b6",
   "metadata": {},
   "source": [
    "`if` is a Python keyword.\n",
    "`if` statements have the same structure as function definitions: a\n",
    "**header** followed by an indented statement or sequence of statements called a **block**.\n",
    "\n",
    "The boolean expression after `if` is called the **condition**.\n",
    "If it is true, the statements in the indented block run. If not, they don't.\n",
    "\n",
    "There is no limit to the number of statements that can appear in the block, but there has to be at least one.\n",
    "Occasionally, it is useful to have a block that does nothing -- usually as a place keeper for code you haven't written yet.\n",
    "In that case, you can use the `pass` statement, which does nothing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "7f068c32",
   "metadata": {},
   "outputs": [],
   "source": [
    "if x < 0:\n",
    "    pass          # TODO: need to handle negative values!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61d52ad2",
   "metadata": {},
   "source": [
    "The word `TODO` in a comment is a conventional reminder that there’s something you need to do later. Modern IDE's would recognize it and act accordingly."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "035f615a-badb-48e9-893e-46051f825489",
   "metadata": {},
   "source": [
    "To write useful programs, we almost always need the ability to check conditions and adjust the program's behavior accordingly. Python uses if statements to handle conditional logic, offering several structures to control program flow: \n",
    "1. conditional execution (if),\n",
    "2. alternative execution (if/else),\n",
    "3. chained execution (if/elif/else),\n",
    "4. nested conditions, and\n",
    "5. match statement."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10c35ff7",
   "metadata": {},
   "source": [
    "### Conditional execution (`if`)\n",
    "Conditional gives us the ability to check the conditions and is the simplest form of the `if` statement:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "a1b42091",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is positive\n"
     ]
    }
   ],
   "source": [
    "if x > 0:\n",
    "    print('x is positive')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "a153b75e-b6f2-48cc-abfd-b80f35ee6b59",
   "metadata": {},
   "outputs": [],
   "source": [
    "if x < 0:\n",
    "    pass          # TODO: need to handle negative values!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6fcfeb8f-1856-4ba2-90ba-cea5bfdf9b71",
   "metadata": {},
   "source": [
    "The word `TODO` in a comment is a conventional reminder that there’s something you need to do later. Modern IDEs would recognize it and act accordingly.\n",
    "\n",
    "The `pass` statement in Python is a placeholder that does nothing when executed. It is used to keep code blocks valid where a statement is required, but no logic is needed yet. It is for creating empty functions, classes, loops, or conditional blocks."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9d8942d",
   "metadata": {},
   "source": [
    "### Alternative Execution (`else`)\n",
    "\n",
    "An `if` statement can have a second part, called an `else` clause. If the condition is true, the first indented statement runs; otherwise, the second indented statement runs. For example:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea7d5c3e",
   "metadata": {},
   "source": [
    "```python\n",
    "num = int(input(\"Please enter an integer: \"))\n",
    "\n",
    "if num % 2 == 0:                ### % modulus operator\n",
    "    print(\"num is even\")\n",
    "else:\n",
    "    print(\"num is odd\")\n",
    "```\n",
    "Output:\n",
    "```\n",
    "Please enter an integer:  5\n",
    "num is odd\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f736b465",
   "metadata": {},
   "source": [
    "In this example, if `num` is even, the remainder when `num` is divided by `2` is `0`, so the condition is `True` and the program displays `num is even`. If `num` is odd, the remainder is `1`, so the condition is false, and the program displays `num is odd`.\n",
    "\n",
    "Since the condition must be true or false, exactly **one** of the alternatives will run. The alternatives are called **branches**."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "93aede7a-f601-4a41-b7d6-d193d2e32b0f",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "### Chained Conditional (`elif`)\n",
    "Sometimes there are more than two possibilities, and we need more than two branches. One way to express a computation like that is a **chained conditional**, which includes an `elif` clause.\n",
    "\n",
    "`elif` is an abbreviation of \"else if\" and is used to add multiple conditions inside an `if` block. There is no limit on the number of `elif` clauses. \n",
    "\n",
    "If there is an `else` clause, it has to be at the end, but there doesn’t have to be one.\n",
    "\n",
    "Note that:\n",
    "- Each condition is checked in order.\n",
    "- If the first is false, the next is checked, and so on.\n",
    "- If one of them is true, the corresponding branch runs, and the `if` statement ends.\n",
    "- Even if more than one condition is true, only the first true branch runs."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c1de80ef-056c-4c08-8aa9-302401406dc7",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "source": [
    "A good example of a chained conditional statement is:\n",
    "\n",
    "```\n",
    "num = int(input(\"Please enter an integer: \"))\n",
    "\n",
    "if num > 0:\n",
    "    print(\"positive\")\n",
    "elif num == 0:\n",
    "    print(\"neither positive or negative\")\n",
    "elif num < 0:                               \n",
    "    print(\"negative\")\n",
    "else:\n",
    "    print(\"I don't know what you are talking about.\")\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "a4f6e982-d5cb-430d-bf51-25c04a44796a",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### Exercise:\n",
    "### Write a Python script that asks the user to input a numerical \n",
    "### score (0-100). Based on that score, the program should print a specific message.\n",
    "### Requirements:\n",
    "### If the score is 90 or above, print: \"Excellent! You got an A.\"\n",
    "### If the score is between 70 and 89, print: \"Good job! You passed.\"\n",
    "### If the score is below 70, print: \"Keep practicing! Try again.\"\n",
    "### Bonus: Add a check at the very beginning. If the user enters a \n",
    "### number greater than 100 or less than 0, print: \"Invalid score. Please enter a value between 0 and 100.\"\n",
    "### Your code starts here.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "### Your code ends here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "62bf42a6-7531-47fe-abe8-9fa0f696837c",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input",
     "thebe-interactive"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Excellent! You got an A.\n"
     ]
    }
   ],
   "source": [
    "# score = int(input(\"Enter a numerical score (0-100): \") or \"99\")\n",
    "score = 99   ### for testing; replace with input() for actual use\n",
    "\n",
    "if score > 100 or score < 0:\n",
    "    print(\"Invalid score. Please enter a value between 0 and 100.\")\n",
    "elif score >= 90:\n",
    "    print(\"Excellent! You got an A.\")\n",
    "elif score >= 70:\n",
    "    print(\"Good job! You passed.\")\n",
    "else:\n",
    "    print(\"Keep practicing! Try again.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9483fd70-36f7-4318-b980-9e86e9568a7a",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "### Nested Conditionals\n",
    "\n",
    "One conditional can also be nested within another. We could have written a conditional to compare two numbers:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "c213968f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x: 5; y: 10\n",
      "x is less than y\n"
     ]
    }
   ],
   "source": [
    "x = 5\n",
    "y = 10\n",
    "print(f\"x: {x}; y: {y}\")\n",
    "\n",
    "if x == y:\n",
    "    print('x and y are equal')\n",
    "else:\n",
    "    if x < y:\n",
    "        print('x is less than y')\n",
    "    else:\n",
    "        print('x is greater than y')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2db4a8d-2850-44ff-9eca-d3bae349703a",
   "metadata": {},
   "source": [
    "In this example, the outer `if` statement contains two branches:\n",
    "- The first branch contains a simple statement.\n",
    "- The second branch contains another `if` statement with two branches of its own.\n",
    "\n",
    "Those two branches are both simple `print` statements, although they could have been conditional statements as well.\n",
    "\n",
    "Although the indentation of the statements makes the structure apparent, **nested conditionals** can be difficult to read. I suggest you avoid them whenever possible.\n",
    "\n",
    "**Logical operators** often simplify nested conditional statements.\n",
    "Here's an example with a nested conditional."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "2d8dfd09-4b92-4d7a-af54-3326d6592c74",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is a positive single-digit number.\n"
     ]
    }
   ],
   "source": [
    "if 0 < x:\n",
    "    if x < 10:\n",
    "        print('x is a positive single-digit number.')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "012a7ba9",
   "metadata": {},
   "source": [
    "The `print` statement runs only if we make it past both conditionals, so we get the same effect with the `and` operator."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "c1f0861e",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is a positive single-digit number.\n"
     ]
    }
   ],
   "source": [
    "if 0 < x and x < 10:\n",
    "    print('x is a positive single-digit number.')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bbd454c9",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "For this kind of condition, Python provides a more concise option:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "6ebe98b1",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is a positive single-digit number.\n"
     ]
    }
   ],
   "source": [
    "if 0 < x < 10:\n",
    "    print('x is a positive single-digit number.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "dc172d43-c90c-4744-932e-cf77aece7420",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### Exercise: Nested Conditional\n",
    "### Create a simple login system that verifies a username and then a password. \n",
    "### For this exercise, set the \"correct\" credentials to:\n",
    "### Username: admin\n",
    "### Password: password123\n",
    "### Requirements:\n",
    "### Ask the user to input a username.\n",
    "### First Level (Username Check):\n",
    "### If the username is correct (\"admin\"), ask for a password.\n",
    "### If the username is incorrect, print: \"Access Denied: User not found.\"\n",
    "### Second Level (Password Check - Nested):\n",
    "### If the password is correct (\"password123\"), print: \"Welcome, Admin! Login successful.\"\n",
    "### If the password is incorrect, print: \"Access Denied: Incorrect password.\"\n",
    "### Your code starts here\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "### Your code ends here"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2915e098-205b-4516-a3ff-49918584b0b4",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "hide-input",
     "thebe-interactive"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Welcome, Admin! Login successful.\n"
     ]
    }
   ],
   "source": [
    "# username = input(\"Enter username: \")\n",
    "username = \"admin\"  ### for testing; replace with input() for actual use\n",
    "\n",
    "if username == \"admin\":\n",
    "    # password = input(\"Enter password: \")\n",
    "    password = \"password123\"  ### for testing; replace with input() for actual use\n",
    "    \n",
    "    if password == \"password123\":\n",
    "        print(\"Welcome, Admin! Login successful.\")\n",
    "    else:\n",
    "        print(\"Access Denied: Incorrect password.\")\n",
    "else:\n",
    "    print(\"Access Denied: User not found.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e263a502-8151-4862-96a3-bbec49ba2829",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "default_lexer": "ipython3"
  },
  "kernelspec": {
   "display_name": ".venv",
   "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.13.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
