{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.6 \u2014 Functions\n",
    "\n",
    "You've been writing the same *kind* of code over and over \u2014 reading input, calculating damage, printing a message. Functions let you package that up once, give it a name, and reuse it \u2014 the first real step toward organizing a program instead of just writing it top to bottom."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The Idea\n",
    "\n",
    "`def` creates a function. Anything in parentheses is a **parameter** \u2014 a value the function needs from whoever calls it. `return` sends a value back out; a function with no `return` gives back `None`.\n",
    "\n",
    "```python\n",
    "def calculate_damage(attack, defense):\n",
    "    return attack - defense\n",
    "\n",
    "result = calculate_damage(18, 5)   # result is now 13\n",
    "```\n",
    "\n",
    "A variable created *inside* a function only exists inside that function \u2014 that's called **scope**. If you need a value to exist outside the function, `return` it and assign it to a variable in the outer code, like `result` above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A worked example \u2014 a reusable damage calculator\n",
    "\n",
    "def calculate_damage(attack, defense):\n",
    "    return attack - defense\n",
    "\n",
    "zara_damage = calculate_damage(18, 5)\n",
    "finn_damage = calculate_damage(12, 3)\n",
    "\n",
    "print(f\"Zara deals {zara_damage} damage.\")\n",
    "print(f\"Old Finn deals {finn_damage} damage.\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Watch out for:* `print()`-ing inside a function shows something on screen, but doesn't give the calling code anything to work with afterward. If you need to use the result later (store it, compare it, pass it to something else), you need `return`, not just `print()`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Guided Practice 1\n",
    "\n",
    "A function that greets whichever character you pass in. Run the cell as-is, then call it again with a different name."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Change the name passed in below, or add another call, and re-run\n",
    "\n",
    "def greet_character(name):\n",
    "    print(f\"Welcome, {name}!\")\n",
    "\n",
    "greet_character(\"Zara\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Guided Practice 2\n",
    "\n",
    "The function itself is already written and correct \u2014 read it carefully, then fill in the two blanks where it's *called*, further down."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The function below is complete \u2014 fill in the two blank arguments where it's called\n",
    "\n",
    "def remaining_health(current_health, damage_taken):\n",
    "    return current_health - damage_taken\n",
    "\n",
    "health_left = remaining_health(____, ____)   # try 50 and 15\n",
    "print(f\"Health remaining: {health_left}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Independent Practice 1\n",
    "\n",
    "Write a function `can_afford(gold, price)` that returns `True` if `gold` is greater than or equal to `price`, `False` otherwise. Call it at least twice with different values and print the results.\n",
    "\n",
    "**Hint (only if stuck):** the whole function body can be one line: `return gold >= price` \u2014 no `if` statement needed, since the comparison already gives you a `bool`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Your code here \u2014 write and call can_afford(gold, price)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Independent Practice 2\n",
    "\n",
    "No hint this time. Write a function `describe_room(name, danger_level)` that returns a formatted sentence describing the room (use an f-string inside the function). Call it with at least two different rooms and print each result."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Your code here \u2014 write and call describe_room(name, danger_level)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Want More? (Optional)\n",
    "\n",
    "Give one of your functions a **default parameter value** \u2014 for example, a `heal(current_health, amount=10)` function that heals by 10 unless you specify a different amount. Call it once with no second argument, and once specifying a different amount."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Optional stretch \u2014 a function with a default parameter value\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Check Your Understanding\n",
    "\n",
    "In one sentence: what's the actual difference between a function that `print()`s something and a function that `return`s something?"
   ]
  },
  {
   "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
}
