{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `importnb` test specification\n",
    "\n",
    "this notebook is written to test many of the features of `importnb`.\n",
    "\n",
    "these features in this notebook test:\n",
    "* basic finding and loading\n",
    "* filtering magics, classes and functions\n",
    "* lazy loading\n",
    "* the command line interface"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## a sentinel for execution"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "the `slug` below is used to measure that a module has been executed,\n",
    "we specifically use this expression to measure the lazy importing system."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i was printed from  and my name is __main__\n"
     ]
    }
   ],
   "source": [
    "from importnb import get_ipython\n",
    "from pathlib import Path\n",
    "where = \"\"\n",
    "if \"__file__\" in locals():\n",
    "    where = Path(__file__).as_posix()\n",
    "\n",
    "slug = \"i was printed from {where} \\\n",
    "and my name is {__name__}\"\n",
    "print(slug.format(**locals()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## implicit markdown docstrings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "there is a strict separation of code and non-code in notebooks.\n",
    "to encourage more/better documentation `importnb` will use a markdown\n",
    "cell preceeding a function as a docstring. \n",
    "as a result, the `function_with_a_markdown` docstring will have this markdown cell for a value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def function_with_a_markdown_docstring():\n",
    "    return # function_with_a_markdown has a docstring defined by the preceeding markdown cell"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "the same convention holds for classes and async functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class class_with_a_markdown_docstring:\n",
    "    ... # my docstring is the cell above.        "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "this is not a docstring for `class_with_a_string` because it defines its own."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class class_with_a_python_docstring:\n",
    "    \"\"\"when a class defines its own docstring the preceeding cell is ignored.\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## cell magics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i'm only show when cell magics are active.\n"
     ]
    }
   ],
   "source": [
    "%%python\n",
    "print(\"i'm only show when cell magics are active.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "if get_ipython():\n",
    "    magic_slug = \"i'm only show when cell magics are active.\"\n",
    "    if __import__('sys').platform == \"win32\": magic_slug += \"\\n\"\n",
    "else:\n",
    "    magic_slug = f\"this was printed from the module named {__name__}\"\n",
    "    print(magic_slug)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## notebooks as scripts"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "the main block is a python convention we can apply in notebooks imported by importnb."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_parser():\n",
    "    from argparse import ArgumentParser, REMAINDER\n",
    "    parser =  ArgumentParser(\"test_parser\")\n",
    "    parser.add_argument(\"--\", nargs=REMAINDER, dest=\"args\")\n",
    "    return parser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def main(argv=None):\n",
    "    parser = get_parser()\n",
    "    print(\"the parser namespace is\", parser.parse_args(argv))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### notebooks as `doit` tasks\n",
    "\n",
    "[`doit`](https://pydoit.org/) is powerful alternative to makefiles for running development tasks.\n",
    "the `importnb` command line provides support for `doit` conventions, but does not provide the dependency;\n",
    "you the `doit` are responsible for that."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "this the docstring for the `echo` task that echos hello."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def task_echo():\n",
    "    return dict(actions=[\"echo hello\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "if __name__ == \"__main__\":\n",
    "    if \"__file__\" in locals():\n",
    "        # run this notebook like it is a cli\n",
    "        if \"pytest\" not in sys.modules:\n",
    "            if \"doit\" not in sys.modules:\n",
    "                main(sys.argv[1:])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## data loaders\n",
    "\n",
    "data loaders can import other file formats. we can hide loading logic underneath `import` statements."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": {
       "cells": [
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "# `importnb` test specification\n",
          "\n",
          "this notebook is written to test many of the features of `importnb`.\n",
          "\n",
          "these features in this notebook test:\n",
          "* basic finding and loading\n",
          "* filtering magics, classes and functions\n",
          "* lazy loading\n",
          "* the command line interface"
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "## a sentinel for execution"
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "the `slug` below is used to measure that a module has been executed,\n",
          "we specifically use this expression to measure the lazy importing system."
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 1,
         "metadata": {},
         "outputs": [
          {
           "name": "stdout",
           "output_type": "stream",
           "text": [
            "i was printed from  and my name is __main__\n"
           ]
          }
         ],
         "source": [
          "from importnb import get_ipython\n",
          "from pathlib import Path\n",
          "where = \"\"\n",
          "if \"__file__\" in locals():\n",
          "    where = Path(__file__).as_posix()\n",
          "\n",
          "slug = \"i was printed from {where} \\\n",
          "and my name is {__name__}\"\n",
          "print(slug.format(**locals()))"
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "## implicit markdown docstrings"
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "there is a strict separation of code and non-code in notebooks.\n",
          "to encourage more/better documentation `importnb` will use a markdown\n",
          "cell preceeding a function as a docstring. \n",
          "as a result, the `function_with_a_markdown` docstring will have this markdown cell for a value."
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 2,
         "metadata": {},
         "outputs": [],
         "source": [
          "def function_with_a_markdown_docstring():\n",
          "    return # function_with_a_markdown has a docstring defined by the preceeding markdown cell"
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "the same convention holds for classes and async functions."
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 3,
         "metadata": {},
         "outputs": [],
         "source": [
          "class class_with_a_markdown_docstring:\n",
          "    ... # my docstring is the cell above.        "
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "this is not a docstring for `class_with_a_string` because it defines its own."
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 4,
         "metadata": {},
         "outputs": [],
         "source": [
          "class class_with_a_python_docstring:\n",
          "    \"\"\"when a class defines its own docstring the preceeding cell is ignored.\"\"\""
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "## cell magics"
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 5,
         "metadata": {},
         "outputs": [
          {
           "name": "stdout",
           "output_type": "stream",
           "text": [
            "i'm only show when cell magics are active.\n"
           ]
          }
         ],
         "source": [
          "%%python\n",
          "print(\"i'm only show when cell magics are active.\")"
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 6,
         "metadata": {},
         "outputs": [],
         "source": [
          "if get_ipython():\n",
          "    magic_slug = \"i'm only show when cell magics are active.\"\n",
          "    if __import__('sys').platform == \"win32\": magic_slug += \"\\n\"\n",
          "else:\n",
          "    magic_slug = f\"this was printed from the module named {__name__}\"\n",
          "    print(magic_slug)"
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "## notebooks as scripts"
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "the main block is a python convention we can apply in notebooks imported by importnb."
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 7,
         "metadata": {},
         "outputs": [],
         "source": [
          "def get_parser():\n",
          "    from argparse import ArgumentParser, REMAINDER\n",
          "    parser =  ArgumentParser(\"test_parser\")\n",
          "    parser.add_argument(\"--\", nargs=REMAINDER, dest=\"args\")\n",
          "    return parser"
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 8,
         "metadata": {},
         "outputs": [],
         "source": [
          "def main(argv=None):\n",
          "    parser = get_parser()\n",
          "    print(\"the parser namespace is\", parser.parse_args(argv))"
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "### notebooks as `doit` tasks\n",
          "\n",
          "[`doit`](https://pydoit.org/) is powerful alternative to makefiles for running development tasks.\n",
          "the `importnb` command line provides support for `doit` conventions, but does not provide the dependency;\n",
          "you the `doit` are responsible for that."
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "this the docstring for the `echo` task that echos hello."
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 9,
         "metadata": {},
         "outputs": [],
         "source": [
          "def task_echo():\n",
          "    return dict(actions=[\"echo hello\"])"
         ]
        },
        {
         "cell_type": "code",
         "execution_count": 10,
         "metadata": {},
         "outputs": [],
         "source": [
          "import sys\n",
          "if __name__ == \"__main__\":\n",
          "    if \"__file__\" in locals():\n",
          "        # run this notebook like it is a cli\n",
          "        if \"pytest\" not in sys.modules:\n",
          "            if \"doit\" not in sys.modules:\n",
          "                main(sys.argv[1:])"
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "## data loaders\n",
          "\n",
          "data loaders can import other file formats. we can hide loading logic underneath `import` statements."
         ]
        },
        {
         "cell_type": "markdown",
         "metadata": {},
         "source": [
          "if get_ipython() and not where:\n",
          "    from importnb import loaders\n",
          "    display(loaders.Json.load_file(\"Untitled42.ipynb\"))"
         ]
        }
       ],
       "metadata": {
        "kernelspec": {
         "display_name": "Python [conda env:root] *",
         "language": "python",
         "name": "conda-root-py"
        },
        "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.9.13"
        },
        "vscode": {
         "interpreter": {
          "hash": "6624ee388a1c346f3d0811b591fe9e170807496b8a5fea1a5f5986a819dc2334"
         }
        }
       },
       "nbformat": 4,
       "nbformat_minor": 4
      },
      "text/plain": [
       "<module '__main__' from 'Untitled42.ipynb'>"
      ]
     },
     "metadata": {
      "application/json": {
       "expanded": false,
       "root": "<module '__main__' from 'Untitled42.ipynb'>"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "if get_ipython() and not where:\n",
    "    from importnb import loaders\n",
    "    display(loaders.Json.load_file(\"Untitled42.ipynb\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:root] *",
   "language": "python",
   "name": "conda-root-py"
  },
  "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.9.13"
  },
  "vscode": {
   "interpreter": {
    "hash": "6624ee388a1c346f3d0811b591fe9e170807496b8a5fea1a5f5986a819dc2334"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
