{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "source": [
    "# Timer\n",
    "\n",
    "The code in this notebook helps with measuring time."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "source": [
    "**Prerequisites**\n",
    "\n",
    "* This notebook needs some understanding on advanced concepts in Python, notably \n",
    "    * classes\n",
    "    * the Python `with` statement\n",
    "    * measuring time"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Synopsis\n",
    "\n",
    "<!-- Automatically generated. Do not edit. -->\n",
    "\n",
    "\n",
    "\n",
    "The `Timer` class allows you to measure elapsed real time.  Its typical usage is in conjunction with a `with` clause:\n",
    "\n",
    "```python\n",
    "with Timer() as t:\n",
    "    some_long_running_function()\n",
    "t.elapsed_time()\n",
    "```\n",
    "```python\n",
    "=> 0.042843673028983176\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "source": [
    "## Measuring Time\n",
    "\n",
    "The class `Timer` allows measuring the elapsed time during some code execution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    },
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [],
   "source": [
    "import bookutils.setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [],
   "source": [
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ignore\n",
    "from typing import Type, Any"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [],
   "source": [
    "def clock() -> float:\n",
    "    \"\"\"\n",
    "    Return the number of fractional seconds elapsed since some point of reference.\n",
    "    \"\"\"\n",
    "    return time.perf_counter()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from types import TracebackType"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [],
   "source": [
    "class Timer:\n",
    "    def __init__(self) -> None:\n",
    "        \"\"\"Constructor\"\"\"\n",
    "        self.start_time = clock()\n",
    "        self.end_time = None\n",
    "\n",
    "    def __enter__(self) -> Any:\n",
    "        \"\"\"Begin of `with` block\"\"\"\n",
    "        self.start_time = clock()\n",
    "        self.end_time = None\n",
    "        return self\n",
    "\n",
    "    def __exit__(self, exc_type: Type, exc_value: BaseException,\n",
    "                 tb: TracebackType) -> None:\n",
    "        \"\"\"End of `with` block\"\"\"\n",
    "        self.end_time = clock()  # type: ignore\n",
    "\n",
    "    def elapsed_time(self) -> float:\n",
    "        \"\"\"Return elapsed time in seconds\"\"\"\n",
    "        if self.end_time is None:\n",
    "            # still running\n",
    "            return clock() - self.start_time\n",
    "        else:\n",
    "            return self.end_time - self.start_time  # type: ignore"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "source": [
    "Here's an example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [],
   "source": [
    "def some_long_running_function() -> None:\n",
    "    i = 1000000\n",
    "    while i > 0:\n",
    "        i -= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [],
   "source": [
    "print(\"Stopping total time:\")\n",
    "with Timer() as t:\n",
    "    some_long_running_function()\n",
    "print(t.elapsed_time())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [],
   "source": [
    "print(\"Stopping time in between:\")\n",
    "with Timer() as t:\n",
    "    for i in range(10):\n",
    "        some_long_running_function()\n",
    "        print(t.elapsed_time())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "button": false,
    "new_sheet": false,
    "run_control": {
     "read_only": false
    }
   },
   "source": [
    "That's it, folks – enjoy!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Synopsis\n",
    "\n",
    "The `Timer` class allows you to measure elapsed real time (in fractional seconds).  Its typical usage is in conjunction with a `with` clause:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "with Timer() as t:\n",
    "    some_long_running_function()\n",
    "t.elapsed_time()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "button": false,
    "new_sheet": true,
    "run_control": {
     "read_only": false
    }
   },
   "source": [
    "## Lessons Learned\n",
    "\n",
    "* With the `Timer` class, it is very easy to measure elapsed time."
   ]
  }
 ],
 "metadata": {
  "ipub": {
   "bibliography": "fuzzingbook.bib",
   "toc": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "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.6.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "toc-autonumbering": false
 },
 "nbformat": 4,
 "nbformat_minor": 4
}