{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before you turn this problem in, make sure everything runs as expected. First, **restart the kernel** (in the menubar, select Kernel$\\rightarrow$Restart) and then **run all cells** (in the menubar, select Cell$\\rightarrow$Run All).\n",
    "\n",
    "Make sure you fill in any place that says `YOUR CODE HERE` or \"YOUR ANSWER HERE\", as well as your name and collaborators below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "NAME = \"Alyssa P. Hacker\"\n",
    "COLLABORATORS = \"Ben Bitdiddle\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "535c21960d4663d5edac398cb445d087",
     "grade": false,
     "grade_id": "jupyter",
     "locked": true,
     "schema_version": 2,
     "solution": false
    }
   },
   "source": [
    "For this problem set, we'll be using the Jupyter notebook:\n",
    "\n",
    "![](jupyter.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## Part A (2 points)\n",
    "\n",
    "Write a function that returns a list of numbers, such that $x_i=i^2$, for $1\\leq i \\leq n$. Make sure it handles the case where $n<1$ by raising a `ValueError`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "8f1eab8d02a9520920aa06f8a86a2492",
     "grade": false,
     "grade_id": "squares",
     "locked": false,
     "schema_version": 2,
     "solution": true
    }
   },
   "outputs": [],
   "source": [
    "def squares(n):\n",
    "    \"\"\"Compute the squares of numbers from 1 to n, such that the \n",
    "    ith element of the returned list equals i^2.\n",
    "    \n",
    "    \"\"\"\n",
    "    if n < 1:\n",
    "        raise ValueError\n",
    "    return [i ** 2 for i in range(1, n + 1)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Your function should print `[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]` for $n=10$. Check that it does:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "8e029652317e6c6a37a72710dc8d2429",
     "grade": true,
     "grade_id": "correct_squares",
     "locked": false,
     "points": 1.0,
     "schema_version": 2,
     "solution": false
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"Check that squares returns the correct output for several inputs\"\"\"\n",
    "assert squares(1) == [1]\n",
    "assert squares(2) == [1, 4]\n",
    "assert squares(10) == [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n",
    "assert squares(11) == [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "c6ff383fa27ce1c2eb97789816c93069",
     "grade": true,
     "grade_id": "squares_invalid_input",
     "locked": false,
     "points": 1.0,
     "schema_version": 2,
     "solution": false
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"Check that squares raises an error for invalid inputs\"\"\"\n",
    "try:\n",
    "    squares(0)\n",
    "except ValueError:\n",
    "    pass\n",
    "else:\n",
    "    raise AssertionError(\"did not raise\")\n",
    "\n",
    "try:\n",
    "    squares(-4)\n",
    "except ValueError:\n",
    "    pass\n",
    "else:\n",
    "    raise AssertionError(\"did not raise\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Part B (1 point)\n",
    "\n",
    "Using your `squares` function, write a function that computes the sum of the squares of the numbers from 1 to $n$. Your function should call the `squares` function -- it should NOT reimplement its functionality."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "166e1abc6621f93f8084ec312c49f757",
     "grade": false,
     "grade_id": "sum_of_squares",
     "locked": false,
     "schema_version": 2,
     "solution": true
    }
   },
   "outputs": [],
   "source": [
    "def sum_of_squares(n):\n",
    "    \"\"\"Compute the sum of the squares of numbers from 1 to n.\"\"\"\n",
    "    return sum(squares(n))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The sum of squares from 1 to 10 should be 385. Verify that this is the answer you get:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sum_of_squares(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "8cd2b086064694cb2352074a421b8964",
     "grade": true,
     "grade_id": "correct_sum_of_squares",
     "locked": false,
     "points": 0.5,
     "schema_version": 2,
     "solution": false
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"Check that sum_of_squares returns the correct answer for various inputs.\"\"\"\n",
    "assert sum_of_squares(1) == 1\n",
    "assert sum_of_squares(2) == 5\n",
    "assert sum_of_squares(10) == 385\n",
    "assert sum_of_squares(11) == 506"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "b1e1ec376ddc63d803b109befacde06a",
     "grade": true,
     "grade_id": "sum_of_squares_uses_squares",
     "locked": false,
     "points": 0.5,
     "schema_version": 2,
     "solution": false
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"Check that sum_of_squares relies on squares.\"\"\"\n",
    "orig_squares = squares\n",
    "del squares\n",
    "try:\n",
    "    sum_of_squares(1)\n",
    "except NameError:\n",
    "    pass\n",
    "else:\n",
    "    raise AssertionError(\"sum_of_squares does not use squares\")\n",
    "finally:\n",
    "    squares = orig_squares"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## Part C (1 point)\n",
    "\n",
    "Using LaTeX math notation, write out the equation that is implemented by your `sum_of_squares` function."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "f3cc38a3e522c0be10852ebbe2a638b7",
     "grade": true,
     "grade_id": "sum_of_squares_equation",
     "locked": false,
     "points": 1.0,
     "schema_version": 2,
     "solution": true
    }
   },
   "source": [
    "$\\sum_{i=1}^n i^2$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## Part D (2 points)\n",
    "\n",
    "Find a usecase for your `sum_of_squares` function and implement that usecase in the cell below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "5a96910dbc324f5565edf92f5c98af1b",
     "grade": true,
     "grade_id": "sum_of_squares_application",
     "locked": false,
     "points": 2.0,
     "schema_version": 2,
     "solution": true
    }
   },
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "def hypotenuse(n):\n",
    "    \"\"\"Finds the hypotenuse of a right triangle with one side of length n and\n",
    "    the other side of length n-1.\"\"\"\n",
    "    # find (n-1)**2 + n**2\n",
    "    if (n < 2):\n",
    "        raise ValueError(\"n must be >= 2\")\n",
    "    elif n == 2:\n",
    "        sum1 = 5\n",
    "        sum2 = 0\n",
    "    else:\n",
    "        sum1 = sum_of_squares(n)\n",
    "        sum2 = sum_of_squares(n-2)\n",
    "    return math.sqrt(sum1 - sum2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(hypotenuse(2))\n",
    "print(math.sqrt(2**2 + 1**2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(hypotenuse(10))\n",
    "print(math.sqrt(10**2 + 9**2))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python",
   "language": "python",
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
