diff --git a/README.md b/README.md index 3cf5e30..61622a8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # latexify + [![Python](https://img.shields.io/pypi/pyversions/latexify-py.svg)](https://pypi.org/project/latexify-py/) [![PyPI Latest Release](https://img.shields.io/pypi/v/latexify-py.svg)](https://pypi.org/project/latexify-py/) [![License](https://img.shields.io/pypi/l/latexify-py.svg)](https://github.com/google/latexify_py/blob/main/LICENSE) @@ -6,7 +7,6 @@ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/) - `latexify` is a Python package to compile a fragment of Python source code to a corresponding $\LaTeX$ expression: @@ -17,7 +17,6 @@ corresponding $\LaTeX$ expression: * Libraries to compile Python source code or AST to $\LaTeX$. * IPython classes to pretty-print compiled functions. - ## FAQs 1. *Which Python versions are supported?* @@ -33,12 +32,13 @@ corresponding $\LaTeX$ expression: `latexify` is based on traditional parsing techniques. If the "AI" meant some techniques around machine learning, the answer is no. - ## Getting started -We prepared a -[Google Colaboratory notebook](https://colab.research.google.com/drive/1MuiawKpVIZ12MWwyYuzZHmbKThdM5wNJ?usp=sharing) -that provides several examples to use this package. +See the [example notebook](examples/latexify_examples.ipynb), which provides several +use-cases of this library. + +You can also try the above notebook on +[Google Colaboratory](https://colab.research.google.com/github/google/latexify_py/blob/main/examples/latexify_examples.ipynb). See also the official [documentation](docs/index.md) for more details. @@ -47,18 +47,16 @@ See also the official [documentation](docs/index.md) for more details. To contribute to this project, please refer [CONTRIBUTING.md](https://github.com/google/latexify_py/blob/develop/CONTRIBUTING.md). - ## Disclaimer -This software is currently hosted on https://github.com/google, but not officially +This software is currently hosted on , but not officially supported by Google. If you have any issues and/or questions about this software, please visit the [issue tracker](https://github.com/google/latexify_py/issues) or contact the [main maintainer](https://github.com/odashi). - -## License +## License This software adopts the [Apache License 2.0](https://github.com/google/latexify_py/blob/develop/LICENSE). diff --git a/examples/examples.ipynb b/examples/examples.ipynb deleted file mode 100644 index 86a71d7..0000000 --- a/examples/examples.ipynb +++ /dev/null @@ -1,206 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "import latexify" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-1.0\n", - "\\mathrm{solve}(a, b, c) = \\frac{-b + \\sqrt{b^{{2}} - {4}ac}}{{2}a}\n" - ] - }, - { - "data": { - "text/latex": [ - "$$ \\displaystyle \\mathrm{solve}(a, b, c) = \\frac{-b + \\sqrt{b^{{2}} - {4}ac}}{{2}a} $$" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "@latexify.function\n", - "def solve(a, b, c):\n", - " return (-b + math.sqrt(b**2 - 4*a*c)) / (2*a)\n", - "\n", - "print(solve(1, 4, 3))\n", - "print(solve)\n", - "solve" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$$ \\displaystyle \\mathrm{sinc}(x) = \\left\\{ \\begin{array}{ll} {1}, & \\mathrm{if} \\ {x = {0}} \\\\ \\frac{\\sin{\\left({x}\\right)}}{x}, & \\mathrm{otherwise} \\end{array} \\right. $$" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "@latexify.function\n", - "def sinc(x):\n", - " if x == 0:\n", - " return 1\n", - " else:\n", - " return math.sin(x) / x\n", - "\n", - "sinc" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$$ \\displaystyle \\mathrm{fib}(x) = \\left\\{ \\begin{array}{ll} {0}, & \\mathrm{if} \\ {x = {0}} \\\\ {1}, & \\mathrm{if} \\ {x = {1}} \\\\ \\mathrm{fib}\\left(x - {1}\\right) + \\mathrm{fib}\\left(x - {2}\\right), & \\mathrm{otherwise} \\end{array} \\right. $$" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Elif or nested else-if are unrolled.\n", - "@latexify.function\n", - "def fib(x):\n", - " if x == 0:\n", - " return 0\n", - " elif x == 1:\n", - " return 1\n", - " else:\n", - " return fib(x-1) + fib(x-2)\n", - "\n", - "fib" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$$ \\displaystyle \\mathrm{greek}({\\alpha}, {\\beta}, {\\gamma}, {\\Omega}) = {\\alpha}{\\beta} + \\Gamma\\left({{\\gamma}}\\right) + {\\Omega} $$" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Some math symbols are converted automatically.\n", - "@latexify.function(use_math_symbols=True)\n", - "def greek(alpha, beta, gamma, Omega):\n", - " return alpha * beta + math.gamma(gamma) + Omega\n", - "\n", - "greek" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$$ \\displaystyle \\frac{-b + \\sqrt{b^{{2}} - {4}ac}}{{2}a} $$" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# latexify.expression works similarly, but the result does not contain the signature.\n", - "@latexify.expression\n", - "def solve(a, b, c):\n", - " return (-b + math.sqrt(b**2 - 4*a*c)) / (2*a)\n", - "\n", - "solve" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "$$ \\displaystyle \\frac{-b + \\sqrt{b^{{2}} - {4}ac}}{{2}a} $$" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# We can also print the output to a .tex file\n", - "@latexify.expression\n", - "def solve1(a, b, c):\n", - " return (-b + math.sqrt(b**2 - 4*a*c)) / (2*a)\n", - "\n", - "with open('latexifyExample.tex', 'w') as fp: \n", - " print(solve1, file = fp) \n" - ] - } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/latexify_examples.ipynb b/examples/latexify_examples.ipynb new file mode 100644 index 0000000..e177657 --- /dev/null +++ b/examples/latexify_examples.ipynb @@ -0,0 +1,540 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "W5mNJI3Bnl6n" + }, + "source": [ + "# `latexify` examples\n", + "\n", + "This notebook provides several examples to use `latexify`.\n", + "\n", + "See also the\n", + "[official documentation](https://github.com/google/latexify_py/blob/documentation/docs/index.md)\n", + "for more details.\n", + "\n", + "If you have any questions, please ask it in the\n", + "[issue tracker](https://github.com/google/latexify_py/issues)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fWCVgcRHoLd8" + }, + "source": [ + "## Install `latexify`" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "4IPGyu2dFH6T", + "outputId": "471cab8d-3069-4a27-f3ff-67ba177ec58d" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting latexify-py\n", + " Downloading latexify_py-0.4.2-py3-none-any.whl (38 kB)\n", + "Collecting dill>=0.3.2 (from latexify-py)\n", + " Downloading dill-0.3.7-py3-none-any.whl (115 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m115.3/115.3 kB\u001b[0m \u001b[31m5.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hInstalling collected packages: dill, latexify-py\n", + "Successfully installed dill-0.3.7 latexify-py-0.4.2\n" + ] + } + ], + "source": [ + "# Restart the runtime before running the examples below.\n", + "%pip install latexify-py\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-Mzq4_dNoSmc" + }, + "source": [ + "## Import `latexify` into your code" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "id": "hViDMhyMFNCO", + "outputId": "b46edb25-5952-4cff-da1e-d65e7e3caad0" + }, + "outputs": [ + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'0.4.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import math # Optional\n", + "import numpy as np # Optional\n", + "import latexify\n", + "\n", + "latexify.__version__\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4QJ6I2s7odX1" + }, + "source": [ + "## Examples" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "NvbEYSwXFaeE", + "outputId": "5d0ca2a4-a285-4053-9cc4-3776746443be" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-1.0\n", + "\\mathrm{solve}(a, b, c) = \\frac{-b + \\sqrt{ b^{2} - 4 a c }}{2 a}\n" + ] + } + ], + "source": [ + "@latexify.function\n", + "def solve(a, b, c):\n", + " return (-b + math.sqrt(b**2 - 4*a*c)) / (2*a)\n", + "\n", + "print(solve(1, 4, 3)) # Invoking the function works as expected.\n", + "print(solve) # Printing the function shows the underlying LaTeX source.\n", + "solve # Displays the expression.\n", + "\n", + "# Writes the underlying LaTeX source into a file.\n", + "with open(\"compiled.tex\", \"w\") as fp:\n", + " print(solve, file=fp)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 56 + }, + "id": "wS7BhtPgjSak", + "outputId": "76a8547c-e6b5-458d-aeb2-f9df2f35f7c7" + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$$ \\displaystyle \\frac{-b + \\sqrt{ b^{2} - 4 a c }}{2 a} $$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# latexify.expression works similarly, but does not output the signature.\n", + "@latexify.expression\n", + "def solve(a, b, c):\n", + " return (-b + math.sqrt(b**2 - 4*a*c)) / (2*a)\n", + "\n", + "solve\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "id": "G73dnoqqjg4A", + "outputId": "b9f53cf8-4a34-452c-8d9b-946ddd0998df" + }, + "outputs": [ + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'\\\\mathrm{solve}(a, b, c) = \\\\frac{-b + \\\\sqrt{ b^{2} - 4 a c }}{2 a}'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# latexify.get_latex obtains the underlying LaTeX expression directly.\n", + "def solve(a, b, c):\n", + " return (-b + math.sqrt(b**2 - 4*a*c)) / (2*a)\n", + "\n", + "latexify.get_latex(solve)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 58 + }, + "id": "8bYSWIngGF8E", + "outputId": "669e070d-2718-49cb-a2fe-0defe0286b27" + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$$ \\displaystyle \\mathrm{sinc}(x) = \\left\\{ \\begin{array}{ll} 1, & \\mathrm{if} \\ x = 0 \\\\ \\frac{\\sin x}{x}, & \\mathrm{otherwise} \\end{array} \\right. $$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@latexify.function\n", + "def sinc(x):\n", + " if x == 0:\n", + " return 1\n", + " else:\n", + " return math.sin(x) / x\n", + "\n", + "sinc\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 78 + }, + "id": "h1i4BjdgHjxl", + "outputId": "e448ff37-4753-4090-b2b1-1ef21b279b34" + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$$ \\displaystyle \\mathrm{fib}(x) = \\left\\{ \\begin{array}{ll} 0, & \\mathrm{if} \\ x = 0 \\\\ 1, & \\mathrm{if} \\ x = 1 \\\\ \\mathrm{fib} \\mathopen{}\\left( x - 1 \\mathclose{}\\right) + \\mathrm{fib} \\mathopen{}\\left( x - 2 \\mathclose{}\\right), & \\mathrm{otherwise} \\end{array} \\right. $$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Elif or nested else-if are unrolled.\n", + "@latexify.function\n", + "def fib(x):\n", + " if x == 0:\n", + " return 0\n", + " elif x == 1:\n", + " return 1\n", + " else:\n", + " return fib(x-1) + fib(x-2)\n", + "\n", + "fib\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 39 + }, + "id": "-JhJMAXM7j-X", + "outputId": "a47dcd59-2ff9-4aa1-935d-7c789b39057e" + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$$ \\displaystyle \\mathrm{greek}(\\alpha, \\beta, \\gamma, \\Omega) = \\alpha \\beta + \\Gamma \\mathopen{}\\left( \\gamma \\mathclose{}\\right) + \\Omega $$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Some math symbols are converted automatically.\n", + "@latexify.function(use_math_symbols=True)\n", + "def greek(alpha, beta, gamma, Omega):\n", + " return alpha * beta + math.gamma(gamma) + Omega\n", + "\n", + "greek\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 39 + }, + "id": "ySyNPS0y4tzu", + "outputId": "2d95b5ce-a9b8-42b1-eb55-dc8bd0097d69" + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$$ \\displaystyle f(x) = g \\mathopen{}\\left( x \\mathclose{}\\right) $$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Function names, arguments, variables can be replaced.\n", + "identifiers = {\n", + " \"my_function\": \"f\",\n", + " \"my_inner_function\": \"g\",\n", + " \"my_argument\": \"x\",\n", + "}\n", + "\n", + "@latexify.function(identifiers=identifiers)\n", + "def my_function(my_argument):\n", + " return my_inner_function(my_argument)\n", + "\n", + "my_function\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 56 + }, + "id": "TyacQaDM4Ei7", + "outputId": "8e971bbd-2c74-45d2-d0fa-7f46569b10a6" + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$$ \\displaystyle f(a, b, c) = \\frac{-b + \\sqrt{ b^{2} - 4 a c }}{2 a} $$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Assignments can be reduced into one expression.\n", + "@latexify.function(reduce_assignments=True)\n", + "def f(a, b, c):\n", + " discriminant = b**2 - 4 * a * c\n", + " numerator = -b + math.sqrt(discriminant)\n", + " denominator = 2 * a\n", + " return numerator / denominator\n", + "\n", + "f\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 78 + }, + "id": "oD8MFS2WE-2U", + "outputId": "f9fad1bd-b7eb-41cc-8743-ec0d80cca8bc" + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$$ \\displaystyle \\mathrm{transform}(x, y, a, b, \\theta, s, t) = \\begin{bmatrix} 1 & 0 & s \\\\ 0 & 1 & t \\\\ 0 & 0 & 1 \\end{bmatrix} \\cdot \\begin{bmatrix} \\cos \\theta & -\\sin \\theta & 0 \\\\ \\sin \\theta & \\cos \\theta & 0 \\\\ 0 & 0 & 1 \\end{bmatrix} \\cdot \\begin{bmatrix} a & 0 & 0 \\\\ 0 & b & 0 \\\\ 0 & 0 & 1 \\end{bmatrix} \\cdot \\begin{bmatrix} x \\\\ y \\\\ 1 \\end{bmatrix} $$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Matrix support.\n", + "@latexify.function(reduce_assignments=True, use_math_symbols=True)\n", + "def transform(x, y, a, b, theta, s, t):\n", + " cos_t = math.cos(theta)\n", + " sin_t = math.sin(theta)\n", + " scale = np.array([[a, 0, 0], [0, b, 0], [0, 0, 1]])\n", + " rotate = np.array([[cos_t, -sin_t, 0], [sin_t, cos_t, 0], [0, 0, 1]])\n", + " move = np.array([[1, 0, s], [0, 1, t], [0, 0, 1]])\n", + " return move @ rotate @ scale @ np.array([[x], [y], [1]])\n", + "\n", + "transform\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 241 + }, + "id": "81OlPVWyGfWN", + "outputId": "48660400-a812-41e2-91ea-23e49ea20c7f" + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$ \\begin{array}{l} \\mathbf{function} \\ \\mathrm{fib}(x) \\\\ \\hspace{1em} \\mathbf{if} \\ x = 0 \\\\ \\hspace{2em} \\mathbf{return} \\ 0 \\\\ \\hspace{1em} \\mathbf{else} \\\\ \\hspace{2em} \\mathbf{if} \\ x = 1 \\\\ \\hspace{3em} \\mathbf{return} \\ 1 \\\\ \\hspace{2em} \\mathbf{else} \\\\ \\hspace{3em} \\mathbf{return} \\ \\mathrm{fib} \\mathopen{}\\left( x - 1 \\mathclose{}\\right) + \\mathrm{fib} \\mathopen{}\\left( x - 2 \\mathclose{}\\right) \\\\ \\hspace{2em} \\mathbf{end \\ if} \\\\ \\hspace{1em} \\mathbf{end \\ if} \\\\ \\mathbf{end \\ function} \\end{array} $" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# latexify.algorithmic generates an algorithmic environment instead of an equation.\n", + "@latexify.algorithmic\n", + "def fib(x):\n", + " if x == 0:\n", + " return 0\n", + " elif x == 1:\n", + " return 1\n", + " else:\n", + " return fib(x-1) + fib(x-2)\n", + "\n", + "fib\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 261 + }, + "id": "kbw_1txkGfnX", + "outputId": "fdc58207-1c06-4d88-e249-b0b011bd98c0" + }, + "outputs": [ + { + "data": { + "text/latex": [ + "$ \\begin{array}{l} \\mathbf{function} \\ \\mathrm{collatz}(x) \\\\ \\hspace{1em} n \\gets 0 \\\\ \\hspace{1em} \\mathbf{while} \\ x > 1 \\\\ \\hspace{2em} n \\gets n + 1 \\\\ \\hspace{2em} \\mathbf{if} \\ x \\mathbin{\\%} 2 = 0 \\\\ \\hspace{3em} x \\gets \\left\\lfloor\\frac{x}{2}\\right\\rfloor \\\\ \\hspace{2em} \\mathbf{else} \\\\ \\hspace{3em} x \\gets 3 x + 1 \\\\ \\hspace{2em} \\mathbf{end \\ if} \\\\ \\hspace{1em} \\mathbf{end \\ while} \\\\ \\hspace{1em} \\mathbf{return} \\ n \\\\ \\mathbf{end \\ function} \\end{array} $" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Another example: latexify.algorithmic supports usual control flows.\n", + "@latexify.algorithmic\n", + "def collatz(x):\n", + " n = 0\n", + " while x > 1:\n", + " n = n + 1\n", + " if x % 2 == 0:\n", + " x = x // 2\n", + " else:\n", + " x = 3 * x + 1\n", + " return n\n", + "\n", + "collatz\n" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}