{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.8 \u2014 Debugging Basics\n",
    "\n",
    "Every programmer, at every level, spends serious time fixing code that doesn't work. That's not a sign something's gone wrong with *you* \u2014 it's just what programming actually is. Today's about doing it efficiently: reading error messages properly, and tracing through code by hand when the bug isn't obvious."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The Idea\n",
    "\n",
    "Python's error messages (**tracebacks**) tell you three things: what kind of error it is, what line it happened on, and often a description of exactly what went wrong. Read them **bottom to top** \u2014 the last line names the error type and gives the clearest description; the lines above show you how the program got there.\n",
    "\n",
    "Common error types you've already met:\n",
    "- **`NameError`** \u2014 you used a variable that doesn't exist (often a typo, or forgetting to define it first)\n",
    "- **`TypeError`** \u2014 you tried to combine or use values in a way their types don't support (like `\"5\" + 5`)\n",
    "- **`IndexError`** \u2014 you asked for a list or string index that doesn't exist\n",
    "\n",
    "When the bug isn't obvious from the error alone, add temporary `print()` statements to show what a variable actually contains at each step \u2014 this is called **print-statement debugging**, and it's the single most useful debugging skill you can build right now."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A worked example \u2014 reading a traceback and fixing the bug\n",
    "\n",
    "# Buggy version (this cell will error on purpose):\n",
    "# print(character_nam)\n",
    "\n",
    "# The traceback would end with:\n",
    "# NameError: name 'character_nam' is not defined\n",
    "\n",
    "# Fixed version:\n",
    "character_name = \"Zara\"\n",
    "print(character_name)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Guided Practice 1\n",
    "\n",
    "This code has a typo bug. Run it once to see the traceback, read the last line carefully, then fix the typo and re-run."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Fix the typo below, then re-run\n",
    "\n",
    "hp = 100\n",
    "print(f\"Current health: {hp}\")\n",
    "print(f\"Health after hit: {hp - 20}\")\n",
    "print(f\"Health after two hits: {hpp - 40}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Guided Practice 2\n",
    "\n",
    "This loop has an off-by-one bug \u2014 it's supposed to print rounds 1 through 5, but doesn't quite. Add a `print()` inside the loop to trace what `round_number` actually holds on each pass, then fix the bug."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Add a print() to trace round_number, find the bug, then fix it\n",
    "\n",
    "total_rounds = 5\n",
    "\n",
    "for round_number in range(1, total_rounds):\n",
    "    print(f\"Round {round_number}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Independent Practice 1\n",
    "\n",
    "The code below raises an `IndexError`. Read the traceback, figure out why, and fix it.\n",
    "\n",
    "**Hint (only if stuck):** count how many items are actually in the list, then compare that to the index being requested."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Find and fix the IndexError\n",
    "\n",
    "party = [\"Zara\", \"Old Finn\"]\n",
    "print(party[2])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Independent Practice 2\n",
    "\n",
    "No hint this time. The code below runs without error, but prints the wrong thing \u2014 it's supposed to say the monster is defeated only when its health drops to 0 or below, but it's saying so too early. Hand-trace through it and fix the logic bug."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Find and fix the logic bug \u2014 it runs, but the output is wrong\n",
    "\n",
    "monster_health = 40\n",
    "damage_per_hit = 15\n",
    "\n",
    "monster_health = monster_health - damage_per_hit\n",
    "if monster_health < 30:\n",
    "    print(\"Monster defeated!\")\n",
    "else:\n",
    "    print(f\"Monster health remaining: {monster_health}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Want More? (Optional)\n",
    "\n",
    "The code below combines a loop and a conditional, with a bug hiding in the interaction between them. Find and fix it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Optional stretch \u2014 find and fix the bug\n",
    "\n",
    "inventory = [\"sword\", \"shield\", \"potion\"]\n",
    "\n",
    "for i in range(len(inventory)):\n",
    "    if inventory[i] = \"potion\":\n",
    "        print(\"Found the potion!\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Check Your Understanding\n",
    "\n",
    "In one sentence: what's the actual difference between a syntax error and a logic error?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Your answer:** *(double-click to edit this cell)*"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
