From 52087d40451e0a8a4426a511ff3ce7a190534d08 Mon Sep 17 00:00:00 2001 From: Jean-Luc Parouty <Jean-Luc.Parouty@grenoble-inp.fr> Date: Mon, 14 Dec 2020 18:29:47 +0100 Subject: [PATCH] Update README generator --- README.ipynb | 11 +- README.md | 2 +- READMEv2.ipynb | 119 ------- fidle/01 - Update_readme.ipynb | 255 +++++++++++++++ fidle/Template.ipynb | 2 +- fidle/Update_index.ipynb | 243 -------------- fidle/__init__.py | 2 - fidle/catalog_builder.py | 107 +++++++ fidle/config.py | 4 +- fidle/img/00-Datasets-tar.svg | 2 +- fidle/img/00-Fidle-pdf.svg | 2 +- fidle/img/00-Notebooks.svg | 2 +- fidle/log/catalog_nb.json | 226 +++++++++++++ fidle/pwk_ns.py | 562 --------------------------------- 14 files changed, 597 insertions(+), 942 deletions(-) delete mode 100644 READMEv2.ipynb create mode 100644 fidle/01 - Update_readme.ipynb delete mode 100644 fidle/Update_index.ipynb delete mode 100644 fidle/__init__.py create mode 100644 fidle/catalog_builder.py create mode 100644 fidle/log/catalog_nb.json delete mode 100644 fidle/pwk_ns.py diff --git a/README.ipynb b/README.ipynb index 303957e..1cd87bc 100644 --- a/README.ipynb +++ b/README.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": { "jupyter": { "source_hidden": true @@ -37,7 +37,7 @@ "For more information, you can contact us at : \n", "[<img width=\"200px\" style=\"vertical-align:middle\" src=\"fidle/img/00-Mail_contact.svg\"></img>](#top) \n", "Current Version : <!-- VERSION_BEGIN -->\n", - "0.6.0 DEV\n", + "0.6.1 DEV\n", "<!-- VERSION_END -->\n", "\n", "\n", @@ -120,13 +120,6 @@ "#\n", "# This README is visible under Jupiter LAb ! :-)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/README.md b/README.md index f67751a..e0382fe 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The objectives of this training are : For more information, you can contact us at : [<img width="200px" style="vertical-align:middle" src="fidle/img/00-Mail_contact.svg"></img>](#top) Current Version : <!-- VERSION_BEGIN --> -0.6.0 DEV +0.6.1 DEV <!-- VERSION_END --> diff --git a/READMEv2.ipynb b/READMEv2.ipynb deleted file mode 100644 index dc44792..0000000 --- a/READMEv2.ipynb +++ /dev/null @@ -1,119 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<a name=\"top\"></a>\n", - "\n", - "[<img width=\"600px\" src=\"fidle/img/00-Fidle-titre-01.svg\"></img>](#top)\n", - "\n", - "<!-- --------------------------------------------------- -->\n", - "<!-- To correctly view this README under Jupyter Lab -->\n", - "<!-- Open the notebook: README.ipynb! -->\n", - "<!-- --------------------------------------------------- -->\n", - "\n", - "\n", - "## A propos\n", - "\n", - "This repository contains all the documents and links of the **Fidle Training** . \n", - "Fidle (for Formation Introduction au Deep Learning) is a 2-day training session \n", - "co-organized by the Formation Permanente CNRS and the SARI and DEVLOG networks. \n", - "\n", - "The objectives of this training are :\n", - " - Understanding the **bases of Deep Learning** neural networks\n", - " - Develop a **first experience** through simple and representative examples\n", - " - Understanding **Tensorflow/Keras** and **Jupyter lab** technologies\n", - " - Apprehend the **academic computing environments** Tier-2 or Tier-1 with powerfull GPU\n", - "\n", - "For more information, you can contact us at : \n", - "[<img width=\"200px\" style=\"vertical-align:middle\" src=\"fidle/img/00-Mail_contact.svg\"></img>](#top) \n", - "Current Version : <!-- VERSION_BEGIN -->\n", - "0.6.0 DEV\n", - "<!-- VERSION_END -->\n", - "\n", - "\n", - "## Course materials\n", - "\n", - "| | | |\n", - "|:--:|:--:|:--:|\n", - "| **[<img width=\"50px\" src=\"fidle/img/00-Fidle-pdf.svg\"></img><br>Course slides](https://cloud.univ-grenoble-alpes.fr/index.php/s/wxCztjYBbQ6zwd6)**<br>The course in pdf format<br>(12 Mo)| **[<img width=\"50px\" src=\"fidle/img/00-Notebooks.svg\"></img><br>Notebooks](https://gricad-gitlab.univ-grenoble-alpes.fr/talks/fidle/-/archive/master/fidle-master.zip)**<br> Get a Zip or clone this repository <br>(10 Mo)| **[<img width=\"50px\" src=\"fidle/img/00-Datasets-tar.svg\"></img><br>Datasets](https://cloud.univ-grenoble-alpes.fr/index.php/s/wxCztjYBbQ6zwd6)**<br>All the needed datasets<br>(1.2 Go)|\n", - "\n", - "Have a look about **[How to get and install](https://gricad-gitlab.univ-grenoble-alpes.fr/talks/fidle/-/wikis/Install-Fidle)** these notebooks and datasets.\n", - "\n", - "\n", - "## Jupyter notebooks\n", - "\n", - "<!-- INDEX_BEGIN -->\n", - "| | |\n", - "|--|--|\n", - "|LINR1| [Linear regression with direct resolution](LinearReg/01-Linear-Regression.ipynb)<br>Direct determination of linear regression |\n", - "|GRAD1| [Linear regression with gradient descent](LinearReg/02-Gradient-descent.ipynb)<br>An example of gradient descent in the simple case of a linear regression.|\n", - "|POLR1| [Complexity Syndrome](LinearReg/03-Polynomial-Regression.ipynb)<br>Illustration of the problem of complexity with the polynomial regression|\n", - "|LOGR1| [Logistic regression, in pure Tensorflow](LinearReg/04-Logistic-Regression.ipynb)<br>Logistic Regression with Mini-Batch Gradient Descent using pure TensorFlow. |\n", - "|PER57| [Perceptron Model 1957](IRIS/01-Simple-Perceptron.ipynb)<br>A simple perceptron, with the IRIS dataset.|\n", - "|BHP1| [Regression with a Dense Network (DNN)](BHPD/01-DNN-Regression.ipynb)<br>A Simple regression with a Dense Neural Network (DNN) - BHPD dataset|\n", - "|BHP2| [Regression with a Dense Network (DNN) - Advanced code](BHPD/02-DNN-Regression-Premium.ipynb)<br>More advanced example of DNN network code - BHPD dataset|\n", - "|MNIST1| [Simple classification with DNN](MNIST/01-DNN-MNIST.ipynb)<br>Example of classification with a fully connected neural network|\n", - "|GTS1| [CNN with GTSRB dataset - Data analysis and preparation](GTSRB/01-Preparation-of-data.ipynb)<br>Episode 1 : Data analysis and creation of a usable dataset|\n", - "|GTS2| [CNN with GTSRB dataset - First convolutions](GTSRB/02-First-convolutions.ipynb)<br>Episode 2 : First convolutions and first results|\n", - "|GTS3| [CNN with GTSRB dataset - Monitoring ](GTSRB/03-Tracking-and-visualizing.ipynb)<br>Episode 3 : Monitoring and analysing training, managing checkpoints|\n", - "|GTS4| [CNN with GTSRB dataset - Data augmentation ](GTSRB/04-Data-augmentation.ipynb)<br>Episode 4 : Improving the results with data augmentation|\n", - "|GTS5| [CNN with GTSRB dataset - Full convolutions ](GTSRB/05-Full-convolutions.ipynb)<br>Episode 5 : A lot of models, a lot of datasets and a lot of results.|\n", - "|GTS6| [CNN with GTSRB dataset - Full convolutions as a batch](GTSRB/06-Notebook-as-a-batch.ipynb)<br>Episode 6 : Run Full convolution notebook as a batch|\n", - "|GTS7| [CNN with GTSRB dataset - Show reports](GTSRB/07-Show-report.ipynb)<br>Episode 7 : Displaying the reports of the different jobs|\n", - "|TSB1| [Tensorboard with/from Jupyter ](GTSRB/99-Scripts-Tensorboard.ipynb)<br>4 ways to use Tensorboard from the Jupyter environment|\n", - "|IMDB1| [Text embedding with IMDB](IMDB/01-Embedding-Keras.ipynb)<br>A very classical example of word embedding for text classification (sentiment analysis)|\n", - "|IMDB2| [Text embedding with IMDB - Reloaded](IMDB/02-Prediction.ipynb)<br>Example of reusing a previously saved model|\n", - "|IMDB3| [Text embedding/LSTM model with IMDB](IMDB/03-LSTM-Keras.ipynb)<br>Still the same problem, but with a network combining embedding and LSTM|\n", - "|SYNOP1| [Time series with RNN - Preparation of data](SYNOP/01-Preparation-of-data.ipynb)<br>Episode 1 : Data analysis and creation of a usable dataset|\n", - "|SYNOP2| [Time series with RNN - Try a prediction](SYNOP/02-First-predictions.ipynb)<br>Episode 2 : Training session and first predictions|\n", - "|SYNOP3| [Time series with RNN - 12h predictions](SYNOP/03-12h-predictions.ipynb)<br>Episode 3: Attempt to predict in the longer term |\n", - "|VAE1| [Variational AutoEncoder (VAE) with MNIST](VAE/01-VAE-with-MNIST.nbconvert.ipynb)<br>Episode 1 : Model construction and Training|\n", - "|VAE2| [Variational AutoEncoder (VAE) with MNIST - Analysis](VAE/02-VAE-with-MNIST-post.ipynb)<br>Episode 2 : Exploring our latent space|\n", - "|VAE3| [About the CelebA dataset](VAE/03-About-CelebA.ipynb)<br>Episode 3 : About the CelebA dataset, a more fun dataset ;-)|\n", - "|VAE4| [Preparation of the CelebA dataset](VAE/04-Prepare-CelebA-datasets.ipynb)<br>Episode 4 : Preparation of a clustered dataset, batchable|\n", - "|VAE5| [Checking the clustered CelebA dataset](VAE/05-Check-CelebA.ipynb)<br>Episode 5 :\tChecking the clustered dataset|\n", - "|VAE6| [Variational AutoEncoder (VAE) with CelebA (small)](VAE/06-VAE-with-CelebA-s.nbconvert.ipynb)<br>Episode 6 : Variational AutoEncoder (VAE) with CelebA (small res.)|\n", - "|VAE7| [Variational AutoEncoder (VAE) with CelebA (medium)](VAE/07-VAE-with-CelebA-m.nbconvert.ipynb)<br>Episode 7 : Variational AutoEncoder (VAE) with CelebA (medium res.)|\n", - "|VAE8| [Variational AutoEncoder (VAE) with CelebA - Analysis](VAE/08-VAE-withCelebA-post.ipynb)<br>Episode 8 : Exploring latent space of our trained models|\n", - "|ACTF1| [Activation functions](Misc/Activation-Functions.ipynb)<br>Some activation functions, with their derivatives.|\n", - "|NP1| [A short introduction to Numpy](Misc/Numpy.ipynb)<br>Numpy is an essential tool for the Scientific Python.|\n", - "<!-- INDEX_END -->\n", - "\n", - "\n", - "## Installation\n", - "\n", - "A procedure for **configuring** and **starting Jupyter** is available in the **[Wiki](https://gricad-gitlab.univ-grenoble-alpes.fr/talks/fidle/-/wikis/Install-Fidle)**.\n", - "\n", - "## Licence\n", - "\n", - "[<img width=\"100px\" src=\"fidle/img/00-fidle-CC BY-NC-SA.svg\"></img>](https://creativecommons.org/licenses/by-nc-sa/4.0/) \n", - "\\[en\\] Attribution - NonCommercial - ShareAlike 4.0 International (CC BY-NC-SA 4.0) \n", - "\\[Fr\\] Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International \n", - "See [License](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode). \n", - "See [Disclaimer](https://creativecommons.org/licenses/by-nc-sa/4.0/#). \n", - "\n", - "\n", - "----\n", - "[<img width=\"80px\" src=\"fidle/img/00-Fidle-logo-01.svg\"></img>](#top)\n" - ] - } - ], - "metadata": { - "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.7.7" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/fidle/01 - Update_readme.ipynb b/fidle/01 - Update_readme.ipynb new file mode 100644 index 0000000..c080807 --- /dev/null +++ b/fidle/01 - Update_readme.ipynb @@ -0,0 +1,255 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<img width=\"800px\" src=\"../fidle/img/00-Fidle-header-01.svg\"></img>\n", + "\n", + "\n", + "## Mise a jour du catalog des notebooks et des READMEs\n", + " - Génération du catalog des notebooks : `./log/catalog_nb.json`\n", + " - Génération automatique de la table des matières\n", + " - Mise à jour des `README.md` et `REAME.ipynb`\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 1 - Load modules" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import nbformat\n", + "from nbconvert.preprocessors import ExecutePreprocessor\n", + "\n", + "import re\n", + "import sys, os, glob\n", + "import json\n", + "from collections import OrderedDict\n", + "\n", + "sys.path.append('..')\n", + "import fidle.config as config\n", + "import fidle.catalog_builder as builder" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 2 - List of folders containing notebooks to be indexed :" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "directories_to_index = ['LinearReg', 'IRIS', 'BHPD', 'MNIST', 'GTSRB', 'IMDB', 'SYNOP', 'VAE', 'Misc']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3 - Catalog of notebooks" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Catalog saved as ../fidle/log/catalog_nb.json\n" + ] + } + ], + "source": [ + "\n", + "# ---- Get the notebook list\n", + "#\n", + "notebooks_list = builder.get_notebooks(directories_to_index)\n", + "\n", + "# ---- Get a detailled catalog for this list\n", + "#\n", + "catalog = builder.get_catalog(notebooks_list)\n", + "\n", + "with open(config.CATALOG_FILE,'wt') as fp:\n", + " json.dump(catalog,fp,indent=4)\n", + " print(f'Catalog saved as {config.CATALOG_FILE}') " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 4 - README.md" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "README.md is updated.\n" + ] + } + ], + "source": [ + "# ---- Create a markdown index\n", + "#\n", + "lines=['| | |','|--|--|']\n", + "tab=' '*5\n", + "for id, about in catalog.items():\n", + " id = about['id']\n", + " dirname = about['dirname']\n", + " basename = about['basename']\n", + " title = about['title']\n", + " description = about['description']\n", + " \n", + "# lines.append( f'[[{id}] - {title}]({dirname}/{basename}) ' )\n", + "# lines.append( f'{tab}{description} ')\n", + " lines.append( f'|{id}| [{title}]({dirname}/{basename})<br>{description}|')\n", + "\n", + "index = '\\n'.join(lines)\n", + " \n", + "# ---- Load README.md\n", + "#\n", + "with open('../README.md','r') as fp:\n", + " readme=fp.read()\n", + " \n", + "# ---- Update index, version\n", + "#\n", + "readme = builder.tag('INDEX', index, readme)\n", + "readme = builder.tag('VERSION', config.VERSION, readme)\n", + "\n", + "# ---- Save it\n", + "#\n", + "with open('../README.md','wt') as fp:\n", + " fp.write(readme)\n", + "\n", + "print('README.md is updated.')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 5 - README.ipynb\n", + "Just execute README.ipynb" + ] + }, + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "# ---- Load notebook\n", + "#\n", + "notebook = nbformat.read('../README.ipynb', nbformat.NO_CONVERT)\n", + "\n", + "# new_cell = nbformat.v4.new_markdown_cell(source=readme)\n", + "# notebook.cells.append(new_cell)\n", + "\n", + "# ---- Execute it\n", + "#\n", + "ep = ExecutePreprocessor(timeout=600, kernel_name=\"python3\")\n", + "ep.preprocess(notebook, {'metadata': {'path': '..'}})\n", + "\n", + "# ---- Save it\n", + "with open('../READMEv2.ipynb', mode=\"w\", encoding='utf-8') as fp:\n", + " nbformat.write(notebook)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 6 - More fun : Create and execute it !" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plus rigolo, on va fabriquer le README.ipynb et l'executer :-)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# ---- Create Notebook from scratch\n", + "#\n", + "notebook = nbformat.v4.new_notebook()\n", + "\n", + "# ---- Add a code cell\n", + "#\n", + "code = \"from IPython.display import display,Markdown\\n\"\n", + "code+= \"display(Markdown(open('README.md', 'r').read()))\\n\"\n", + "code+= \"#\\n\"\n", + "code+= \"# This README is visible under Jupiter LAb ! :-)\"\n", + "\n", + "new_cell = nbformat.v4.new_code_cell(source=code)\n", + "new_cell['metadata']= { \"jupyter\": { \"source_hidden\": True} }\n", + "notebook.cells.append(new_cell)\n", + "\n", + "# ---- Run it\n", + "#\n", + "ep = ExecutePreprocessor(timeout=600, kernel_name=\"python3\")\n", + "ep.preprocess(notebook, {'metadata': {'path': '..'}})\n", + "\n", + "# ---- Save it\n", + "#\n", + "with open('../README.ipynb', mode=\"w\", encoding='utf-8') as fp:\n", + " nbformat.write(notebook, fp)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "<img width=\"80px\" src=\"../fidle/img/00-Fidle-logo-01.svg\"></img>" + ] + } + ], + "metadata": { + "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.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/fidle/Template.ipynb b/fidle/Template.ipynb index c69dff7..56584b7 100644 --- a/fidle/Template.ipynb +++ b/fidle/Template.ipynb @@ -48,7 +48,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.6" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/fidle/Update_index.ipynb b/fidle/Update_index.ipynb deleted file mode 100644 index ec42e67..0000000 --- a/fidle/Update_index.ipynb +++ /dev/null @@ -1,243 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import nbformat\n", - "from nbconvert.preprocessors import ExecutePreprocessor\n", - "\n", - "import re\n", - "import sys, os, glob\n", - "import json\n", - "from collections import OrderedDict\n", - "\n", - "sys.path.append('..')\n", - "# import fidle.pwk as pwk\n", - "import fidle.config as config\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "directories_to_index = ['LinearReg', 'IRIS', 'BHPD', 'MNIST', 'GTSRB', 'IMDB', 'SYNOP', 'VAE', 'Misc']" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "def get_notebooks(directories, top_dir='..'):\n", - " '''\n", - " Return a list of notebooks from a given list of directories\n", - " args:\n", - " directories : list of directories\n", - " top_dir : location of theses directories\n", - " return:\n", - " notebooks : notebooks filename list (without top_dir prefix)\n", - " '''\n", - " notebooks = []\n", - " \n", - " for d in directories:\n", - " filenames = glob.glob( f'{top_dir}/{d}/*.ipynb')\n", - " filenames.sort()\n", - " notebooks.extend(filenames)\n", - "\n", - " notebooks = [ x.replace(f'{top_dir}/','') for x in notebooks]\n", - " return notebooks\n", - "\n", - "\n", - "def get_infos(filename, top_dir='..'):\n", - " '''\n", - " Extract informations from a fidle notebook.\n", - " Informations are dirname, basename, id, title, description and are extracted from comments tags in markdown.\n", - " args:\n", - " filename : Notebook filename\n", - " return:\n", - " dict : with infos.\n", - " '''\n", - "\n", - " about={}\n", - " about['dirname'] = os.path.dirname(filename)\n", - " about['basename'] = os.path.basename(filename)\n", - " about['id'] = '??'\n", - " about['title'] = '??'\n", - " about['description'] = '??'\n", - " \n", - " # ---- Read notebook\n", - " #\n", - " notebook = nbformat.read(f'{top_dir}/{filename}', nbformat.NO_CONVERT)\n", - " \n", - " # ---- Get id, title and desc tags\n", - " #\n", - " for cell in notebook.cells:\n", - "\n", - " if cell['cell_type'] == 'markdown':\n", - "\n", - " find = re.findall(r'<\\!-- TITLE -->\\s*\\[(.*)\\]\\s*-\\s*(.*)\\n',cell.source)\n", - " if find:\n", - " about['id'] = find[0][0]\n", - " about['title'] = find[0][1]\n", - "\n", - " find = re.findall(r'<\\!-- DESC -->\\s*(.*)\\n',cell.source)\n", - " if find:\n", - " about['description'] = find[0]\n", - "\n", - " return about\n", - " \n", - "\n", - "def get_catalog(notebooks_list, top_dir='..'):\n", - " '''\n", - " Return an OrderedDict of notebooks attributes.\n", - " Keys are notebooks id.\n", - " args:\n", - " notebooks_list : list of notebooks filenames\n", - " top_dir : Location of theses notebooks\n", - " return:\n", - " OrderedDict : {<notebook id> : { description} }\n", - " '''\n", - " \n", - " catalog = OrderedDict()\n", - "\n", - " for nb in notebooks_list:\n", - " about = get_infos(nb, top_dir='..')\n", - " id=about['id']\n", - " catalog[id] = about\n", - "\n", - " return catalog\n", - " \n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "README.md is updated.\n" - ] - } - ], - "source": [ - "\n", - "# ---- Get the notebook list\n", - "#\n", - "notebooks_list = get_notebooks(directories_to_index)\n", - "\n", - "# ---- Get a detailled catalog for this list\n", - "#\n", - "catalog = get_catalog(notebooks_list)\n", - "\n", - "with open(config.CATALOG_FILE,'wt') as fp:\n", - " json.dump(catalog,fp,indent=4)\n", - "\n", - "# ---- Create a markdown index\n", - "#\n", - "lines=['| | |','|--|--|']\n", - "tab=' '*5\n", - "for id, about in catalog.items():\n", - " id = about['id']\n", - " dirname = about['dirname']\n", - " basename = about['basename']\n", - " title = about['title']\n", - " description = about['description']\n", - " \n", - "# lines.append( f'[[{id}] - {title}]({dirname}/{basename}) ' )\n", - "# lines.append( f'{tab}{description} ')\n", - " lines.append( f'|{id}| [{title}]({dirname}/{basename})<br>{description}|')\n", - "\n", - "index = '\\n'.join(lines)\n", - " \n", - "# ---- Load README.md\n", - "#\n", - "with open('../README.md','r') as fp:\n", - " readme=fp.read()\n", - " \n", - "# ---- Update index\n", - "#\n", - "debut = '<!-- INDEX_BEGIN -->'\n", - "fin = '<!-- INDEX_END -->'\n", - "\n", - "readme = re.sub(f'{debut}.*{fin}',f'{debut}\\n{index}\\n{fin}',readme, flags=re.DOTALL)\n", - "\n", - "# ---- Update version\n", - "#\n", - "debut = '<!-- VERSION_BEGIN -->'\n", - "fin = '<!-- VERSION_END -->'\n", - "\n", - "readme = re.sub(f'{debut}.*{fin}',f'{debut}\\n{config.VERSION}\\n{fin}',readme, flags=re.DOTALL)\n", - "\n", - "# ---- Save it\n", - "#\n", - "with open('../README.md','wt') as fp:\n", - " fp.write(readme)\n", - "\n", - "print('README.md is updated.')" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# ---- Create Notebook\n", - "#\n", - "notebook = nbformat.v4.new_notebook()\n", - "new_cell = nbformat.v4.new_markdown_cell(source=readme)\n", - "notebook.cells.append(new_cell)\n", - "\n", - "# ---- Run it\n", - "#\n", - "ep = ExecutePreprocessor(timeout=600, kernel_name=\"python3\")\n", - "ep.preprocess(notebook)\n", - "\n", - "# ---- Save it\n", - "#\n", - "with open('../READMEv2.ipynb', mode=\"w\", encoding='utf-8') as fp:\n", - " nbformat.write(notebook, fp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "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.7.7" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/fidle/__init__.py b/fidle/__init__.py deleted file mode 100644 index 098c126..0000000 --- a/fidle/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - -VERSION='0.1a' \ No newline at end of file diff --git a/fidle/catalog_builder.py b/fidle/catalog_builder.py new file mode 100644 index 0000000..d8929e7 --- /dev/null +++ b/fidle/catalog_builder.py @@ -0,0 +1,107 @@ + +# ----------------------------------------------------------------------------- +# ____ _ _ ____ _ _ _ +# / ___|__ _| |_ __ _| | ___ __ _ | __ ) _ _(_) | __| | ___ _ __ +# | | / _` | __/ _` | |/ _ \ / _` | | _ \| | | | | |/ _` |/ _ \ '__| +# | |__| (_| | || (_| | | (_) | (_| | | |_) | |_| | | | (_| | __/ | +# \____\__,_|\__\__,_|_|\___/ \__, | |____/ \__,_|_|_|\__,_|\___|_| +# |___/ Module catalog_builder +# ----------------------------------------------------------------------------- +# +# A simple module to build the notebook catalog and update the README. + +import nbformat +from nbconvert.preprocessors import ExecutePreprocessor + +import re +import sys, os, glob +import json +from collections import OrderedDict + + +def get_notebooks(directories, top_dir='..'): + ''' + Return a list of notebooks from a given list of directories + args: + directories : list of directories + top_dir : location of theses directories + return: + notebooks : notebooks filename list (without top_dir prefix) + ''' + notebooks = [] + + for d in directories: + filenames = glob.glob( f'{top_dir}/{d}/*.ipynb') + filenames.sort() + notebooks.extend(filenames) + + notebooks = [ x.replace(f'{top_dir}/','') for x in notebooks] + return notebooks + + +def get_infos(filename, top_dir='..'): + ''' + Extract informations from a fidle notebook. + Informations are dirname, basename, id, title, description and are extracted from comments tags in markdown. + args: + filename : Notebook filename + return: + dict : with infos. + ''' + + about={} + about['dirname'] = os.path.dirname(filename) + about['basename'] = os.path.basename(filename) + about['id'] = '??' + about['title'] = '??' + about['description'] = '??' + + # ---- Read notebook + # + notebook = nbformat.read(f'{top_dir}/{filename}', nbformat.NO_CONVERT) + + # ---- Get id, title and desc tags + # + for cell in notebook.cells: + + if cell['cell_type'] == 'markdown': + + find = re.findall(r'<\!-- TITLE -->\s*\[(.*)\]\s*-\s*(.*)\n',cell.source) + if find: + about['id'] = find[0][0] + about['title'] = find[0][1] + + find = re.findall(r'<\!-- DESC -->\s*(.*)\n',cell.source) + if find: + about['description'] = find[0] + + return about + + +def get_catalog(notebooks_list, top_dir='..'): + ''' + Return an OrderedDict of notebooks attributes. + Keys are notebooks id. + args: + notebooks_list : list of notebooks filenames + top_dir : Location of theses notebooks + return: + OrderedDict : {<notebook id> : { description} } + ''' + + catalog = OrderedDict() + + for nb in notebooks_list: + about = get_infos(nb, top_dir='..') + id=about['id'] + catalog[id] = about + + return catalog + + +def tag(tag, text, document): + debut = f'<!-- {tag}_BEGIN -->' + fin = f'<!-- {tag}_END -->' + + output = re.sub(f'{debut}.*{fin}',f'{debut}\n{text}\n{fin}',document, flags=re.DOTALL) + return output \ No newline at end of file diff --git a/fidle/config.py b/fidle/config.py index 425ddf9..6f1ac38 100644 --- a/fidle/config.py +++ b/fidle/config.py @@ -14,7 +14,7 @@ # ---- Version ----------------------------------------------------- # -VERSION = '0.6.0 DEV' +VERSION = '0.6.1 DEV' # ---- Default notebook name --------------------------------------- # @@ -31,4 +31,4 @@ FINISHED_FILE = '../fidle/log/finished_file.json' # ---- Catalog file, a json description of all notebooks # -CATALOG_FILE = '../fidle/log/catalog_file.json' \ No newline at end of file +CATALOG_FILE = '../fidle/log/catalog_nb.json' \ No newline at end of file diff --git a/fidle/img/00-Datasets-tar.svg b/fidle/img/00-Datasets-tar.svg index 9cb96df..6186185 100644 --- a/fidle/img/00-Datasets-tar.svg +++ b/fidle/img/00-Datasets-tar.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36.8447 35.5347"><path d="M19.8818,8.3758V.9771H9.6714A3.2082,3.2082,0,0,0,6.4726,4.1759V27.6783a3.2081,3.2081,0,0,0,3.1988,3.1988H27.2329a3.2082,3.2082,0,0,0,3.1988-3.1988V11.5746H23.0806A3.2082,3.2082,0,0,1,19.8818,8.3758Z" style="fill:none;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><line x1="19.8818" y1="0.9771" x2="30.4555" y2="11.5508" style="fill:none;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><rect y="5.907" width="16.1948" height="17.0887" style="fill:#fff"/><path d="M20.3292,26.3928H24.002V18.63a1.1822,1.1822,0,0,1,1.1807-1.1807h6.208a1.1833,1.1833,0,0,1,1.1807,1.1753l.0351,7.7681h3.4029l-7.6367,8.5855Z" style="fill:#e12229"/><path d="M31.3905,17.8243a.8058.8058,0,0,1,.8058.8021l.0366,8.1415h2.9409l-6.8084,7.6544-7.171-7.6544h3.1827V18.63a.8057.8057,0,0,1,.8057-.8057h6.2077m0-.75H25.1828A1.5575,1.5575,0,0,0,23.6271,18.63v7.3879h-4.163l1.183,1.2628,7.171,7.6545.5617.5995.546-.6139,6.8084-7.6545,1.1105-1.2484H32.98l-.0333-7.3949a1.559,1.559,0,0,0-1.5558-1.5487Z" style="fill:#fff"/><path d="M14.901,9.12l0,.01c-.0174,1.0847-2.8156,1.9623-6.2648,1.9623S2.3887,10.2147,2.3712,9.13l0-.01c0-1.0894,2.8048-1.9725,6.2649-1.9725S14.901,8.03,14.901,9.12Z" style="fill:#e12229"/><path d="M14.9214,19.7408l0,.01c-.0174,1.0847-2.8156,1.9622-6.2648,1.9622s-6.2473-.8775-6.2648-1.9622l0-.01-.0041-2.779,0,.01c.0175,1.0847,2.8157,1.9622,6.2648,1.9622s6.2474-.8775,6.2648-1.9622l0-.01Z" style="fill:#e12229"/><path d="M14.9072,16.2168l0,.01c-.0175,1.0846-2.8157,1.9622-6.2648,1.9622s-6.2474-.8776-6.2648-1.9622l0-.01-.0041-2.779,0,.01C2.3908,14.5328,5.189,15.41,8.6382,15.41s6.2474-.8776,6.2648-1.9622l0-.01Z" style="fill:#e12229"/><path d="M14.9083,12.66l0,.01c-.0175,1.0847-2.8157,1.9622-6.2648,1.9622S2.396,13.7551,2.3786,12.67l0-.01-.0041-2.779,0,.01c.0174,1.0847,2.8156,1.9622,6.2648,1.9622s6.2473-.8775,6.2648-1.9622l0-.01Z" style="fill:#e12229"/></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 34.4736 35.5346"><path d="M17.5108,8.3758V.9771H7.3A3.2083,3.2083,0,0,0,4.1015,4.1759V27.6783A3.2082,3.2082,0,0,0,7.3,30.8771H24.8618a3.2081,3.2081,0,0,0,3.1988-3.1988V11.5746H20.71A3.2081,3.2081,0,0,1,17.5108,8.3758Z" style="fill:#fff;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><line x1="17.5108" y1="0.9771" x2="28.0844" y2="11.5508" style="fill:#fff;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><rect x="3.0246" y="6.2946" width="2.1612" height="16.2901" style="fill:#fff"/><path d="M17.9579,26.3927h3.6729V18.63a1.1822,1.1822,0,0,1,1.1811-1.1806h6.2075A1.1833,1.1833,0,0,1,30.2,18.6251l.0352,7.7676h3.4028l-7.6362,8.586Z" style="fill:#e12229"/><path d="M29.02,17.8244a.8057.8057,0,0,1,.8057.802l.0367,8.1414h2.9409l-6.8084,7.6545-7.171-7.6545H22.006V18.63a.8057.8057,0,0,1,.8057-.8056H29.02m0-.75H22.8117A1.5574,1.5574,0,0,0,21.256,18.63v7.3878H17.0931l1.183,1.2629,7.1709,7.6544.5617.5995.5461-.6139,6.8084-7.6544,1.11-1.2485H30.6085l-.0333-7.3949A1.5589,1.5589,0,0,0,29.02,17.0744Z" style="fill:#fff"/><path d="M12.53,9.12l0,.01c-.0175,1.0847-2.8157,1.9623-6.2648,1.9623S.0176,10.2147,0,9.13l0-.01C0,8.03,2.8049,7.1472,6.265,7.1472S12.53,8.03,12.53,9.12Z" style="fill:#e12229"/><path d="M12.55,19.7408l0,.01c-.0175,1.0847-2.8157,1.9622-6.2648,1.9622S.038,20.8358.0206,19.7511l0-.01-.0041-2.779,0,.01c.0174,1.0847,2.8156,1.9622,6.2648,1.9622s6.2473-.8775,6.2648-1.9622l0-.01Z" style="fill:#e12229"/><path d="M12.5362,16.2168l0,.01c-.0174,1.0846-2.8156,1.9622-6.2648,1.9622S.0239,17.3117.0064,16.2271l0-.01-.004-2.779,0,.01C.02,14.5328,2.818,15.41,6.2671,15.41s6.2474-.8776,6.2649-1.9622l0-.01Z" style="fill:#e12229"/><path d="M12.5373,12.66l0,.01c-.0174,1.0847-2.8156,1.9622-6.2648,1.9622S.025,13.7551.0075,12.67l0-.01L.0033,9.8811l0,.01c.0175,1.0847,2.8157,1.9622,6.2648,1.9622s6.2474-.8775,6.2648-1.9622l0-.01Z" style="fill:#e12229"/></svg> \ No newline at end of file diff --git a/fidle/img/00-Fidle-pdf.svg b/fidle/img/00-Fidle-pdf.svg index 82bb6da..327721e 100644 --- a/fidle/img/00-Fidle-pdf.svg +++ b/fidle/img/00-Fidle-pdf.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 6.6741 6.6889"><title>00-Fidle-pdf</title><g id="Calque_2" data-name="Calque 2"><g id="Contains_1" data-name="Contains #1"><path d="M3.4812,1.5766V.1839H1.5592A.604.604,0,0,0,.9571.7861V5.21a.6039.6039,0,0,0,.6021.6021H4.8649A.6038.6038,0,0,0,5.467,5.21V2.1787H4.0833A.6038.6038,0,0,1,3.4812,1.5766Z" style="fill:none;stroke:#000;stroke-linejoin:round;stroke-width:0.3678616155029277px"/><line x1="3.4812" y1="0.1839" x2="5.4715" y2="2.1742" style="fill:none;stroke:#000;stroke-linejoin:round;stroke-width:0.3678616155029277px"/><path d="M.3844,1.3505H2.8073a.3145.3145,0,0,1,.3145.3145V2.9521a.314.314,0,0,1-.314.314H.3844a.314.314,0,0,1-.314-.314V1.6645A.314.314,0,0,1,.3844,1.3505Z" style="fill:#e12229"/><path d="M2.8077,1.4216a.2439.2439,0,0,1,.2433.2431V2.9521a.2441.2441,0,0,1-.2433.2434H.3845a.2441.2441,0,0,1-.2433-.2434V1.6647a.2439.2439,0,0,1,.2433-.2431H2.8077m0-.1412H.3845A.3848.3848,0,0,0,0,1.6647V2.9521a.3849.3849,0,0,0,.3845.3845H2.8077a.3849.3849,0,0,0,.3846-.3845V1.6647A.3849.3849,0,0,0,2.8077,1.28Z" style="fill:#fff"/><path d="M.4142,1.78a1.5711,1.5711,0,0,1,.2851-.0225.4581.4581,0,0,1,.3067.0865.3187.3187,0,0,1,.105.2451.3526.3526,0,0,1-.0943.2583.4365.4365,0,0,1-.311.11.6411.6411,0,0,1-.0679-.0034v.3911H.4142Zm.2236.49a.24.24,0,0,0,.0645.0049.1658.1658,0,0,0,.185-.1748.15.15,0,0,0-.1679-.1616.303.303,0,0,0-.0816.0078Z" style="fill:#fff"/><path d="M1.2535,1.78a1.7814,1.7814,0,0,1,.2837-.0225.5689.5689,0,0,1,.3838.11.5091.5091,0,0,1,.1631.415.5735.5735,0,0,1-.1631.4439.6385.6385,0,0,1-.4316.13,1.5427,1.5427,0,0,1-.2359-.0162Zm.2251.8862a.3211.3211,0,0,0,.0679.0044c.1773.002.3-.1138.3-.3843.0015-.2226-.1045-.3462-.2817-.3462a.3427.3427,0,0,0-.0865.0084Z" style="fill:#fff"/><path d="M2.233,1.7655h.58v.1939H2.4581v.2583h.3311v.19H2.4581v.4375H2.233Z" style="fill:#fff"/><path d="M3.5651,4.9677h.7622L4.2565,3.5068a.2232.2232,0,0,1,.2226-.2227H5.6476a.2224.2224,0,0,1,.2222.2222L5.8771,5.038l.4824-.07h.1572L5.08,6.5839Z" style="fill:#e12229"/><path d="M5.6475,3.3551a.1516.1516,0,0,1,.1517.1509L5.806,5.0385H6.36L5.0781,6.4794l-1.35-1.4409h.5991V3.5068a.1517.1517,0,0,1,.1516-.1517H5.6475m0-.1411H4.479a.2931.2931,0,0,0-.2928.2928V4.8974H3.4026l.2226.2375,1.35,1.4409.1057.1131.1028-.1157,1.2815-1.441.209-.2348H5.9465L5.94,3.5053a.2932.2932,0,0,0-.2928-.2913Z" style="fill:#fff"/></g></g></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35.4564 35.5388"><path d="M29.0428,11.5771v16.11a3.2073,3.2073,0,0,1-3.2,3.19H8.2828a3.2073,3.2073,0,0,1-3.2-3.19V4.1771a3.2094,3.2094,0,0,1,3.2-3.2h10.21v7.4a3.2094,3.2094,0,0,0,3.2,3.2Z" style="fill:#fff"/><path d="M29.0428,11.5771h-7.35a3.2094,3.2094,0,0,1-3.2-3.2v-7.4H8.2828a3.2094,3.2094,0,0,0-3.2,3.2v23.51a3.2073,3.2073,0,0,0,3.2,3.19h17.56a3.2073,3.2073,0,0,0,3.2-3.19Z" style="fill:none;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><line x1="18.4928" y1="0.9771" x2="29.0628" y2="11.5571" style="fill:none;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><path d="M2.0421,7.1807h12.874a1.6675,1.6675,0,0,1,1.6675,1.6675v6.8394a1.6675,1.6675,0,0,1-1.6675,1.6675H2.0426A1.6675,1.6675,0,0,1,.3751,15.6876v-6.84A1.667,1.667,0,0,1,2.0421,7.1807Z" style="fill:#e12229"/><path d="M14.9161,7.5559a1.2961,1.2961,0,0,1,1.2923,1.2923v6.84A1.2962,1.2962,0,0,1,14.9161,16.98H2.0423A1.2961,1.2961,0,0,1,.75,15.6878v-6.84A1.2961,1.2961,0,0,1,2.0423,7.5559H14.9161m0-.75H2.0423A2.0446,2.0446,0,0,0,0,8.8482v6.84A2.0446,2.0446,0,0,0,2.0423,17.73H14.9161a2.0446,2.0446,0,0,0,2.0423-2.0423v-6.84a2.0446,2.0446,0,0,0-2.0423-2.0423Z" style="fill:#fff"/><path d="M2.2018,9.4488A8.3321,8.3321,0,0,1,3.7179,9.33a2.4056,2.4056,0,0,1,1.6386.46,1.6905,1.6905,0,0,1,.5489,1.3052,1.9307,1.9307,0,0,1-.4917,1.373,2.3388,2.3388,0,0,1-1.6631.5889,2.172,2.172,0,0,1-.3609-.0259v2.09H2.2018Zm1.1879,2.61a1.8559,1.8559,0,0,0,.3443.0253.8858.8858,0,0,0,.9834-.93.8009.8009,0,0,0-.8931-.8614,1.6415,1.6415,0,0,0-.4346.0425Z" style="fill:#fff"/><path d="M6.66,9.4488A9.4157,9.4157,0,0,1,8.1676,9.33a3.0234,3.0234,0,0,1,2.04.5883,2.6953,2.6953,0,0,1,.8687,2.209,3.0427,3.0427,0,0,1-.8687,2.3628,3.3479,3.3479,0,0,1-2.2861.6909A8.5047,8.5047,0,0,1,6.66,15.0958ZM7.856,14.1744a2.3257,2.3257,0,0,0,.36.0171c.9424.0083,1.5981-.6055,1.5981-2.0474,0-1.1855-.5571-1.8423-1.5-1.8423a1.9165,1.9165,0,0,0-.459.0425Z" style="fill:#fff"/><path d="M11.8634,9.3721h3.081v1.0323H13.06v1.373h1.7617v1.0152H13.06v2.3286H11.8634Z" style="fill:#fff"/><path d="M18.941,26.397h3.6729V18.6343a1.1821,1.1821,0,0,1,1.1806-1.1806H30.002a1.1835,1.1835,0,0,1,1.1812,1.1748l.0352,7.7685h3.4028l-7.6367,8.5855Z" style="fill:#e12229"/><path d="M30.0022,17.8286a.8057.8057,0,0,1,.8058.802l.0366,8.1414h2.941l-6.8085,7.6545L19.8062,26.772h3.1826V18.6342a.8056.8056,0,0,1,.8057-.8056h6.2077m0-.75H23.7945a1.5574,1.5574,0,0,0-1.5557,1.5556V26.022h-4.163l1.183,1.2629,7.171,7.6544.5617.5995.546-.6139,6.8084-7.6544,1.1105-1.2485H31.5913l-.0333-7.3949a1.559,1.559,0,0,0-1.5558-1.5485Z" style="fill:#fff"/></svg> \ No newline at end of file diff --git a/fidle/img/00-Notebooks.svg b/fidle/img/00-Notebooks.svg index 7befe03..93159a8 100644 --- a/fidle/img/00-Notebooks.svg +++ b/fidle/img/00-Notebooks.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36.8447 35.5346"><path d="M19.8818,8.3758V.9771H9.6714A3.2082,3.2082,0,0,0,6.4726,4.1759V27.6783a3.2081,3.2081,0,0,0,3.1988,3.1988H27.2329a3.2082,3.2082,0,0,0,3.1988-3.1988V11.5746H23.0806A3.2082,3.2082,0,0,1,19.8818,8.3758Z" style="fill:none;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><line x1="19.8818" y1="0.9771" x2="30.4555" y2="11.5508" style="fill:none;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><rect y="5.907" width="16.1948" height="17.0887" style="fill:#fff"/><path d="M20.3294,26.3927h3.6728V18.63a1.1821,1.1821,0,0,1,1.1807-1.1806H31.39a1.1834,1.1834,0,0,1,1.1807,1.1757l.0351,7.7676h3.4029l-7.6363,8.586Z" style="fill:#e12229"/><path d="M31.3905,17.8244a.8056.8056,0,0,1,.8057.802l.0367,8.1414h2.9409l-6.8084,7.6545-7.171-7.6545h3.1827V18.63a.8056.8056,0,0,1,.8057-.8056h6.2077m0-.75H25.1828A1.5574,1.5574,0,0,0,23.6271,18.63v7.3878h-4.163l1.183,1.2629,7.171,7.6544.5617.5995.546-.6139,6.8084-7.6544,1.1105-1.2485H32.98l-.0334-7.3949a1.5588,1.5588,0,0,0-1.5557-1.5485Z" style="fill:#fff"/><path d="M13.6929,12.4289C12.5982,6.1627,7.3243,6.71,7.3243,6.71l0,0a5.71,5.71,0,0,0-5.7108,5.7108A7.1617,7.1617,0,0,0,3.8012,17.62v4.5846h6.3847V19.8412h2.0285A1.2317,1.2317,0,0,0,13.4452,18.61v-2.05c.4531-.1023,1.5854-.5277,1.5415-.8977C14.9375,15.24,13.6929,12.4289,13.6929,12.4289Zm-2.7057.5477a1.104,1.104,0,0,1-1.552,0,1.1322,1.1322,0,0,1-.3064-.613H7.6953a.864.864,0,0,1-.3459.4251l.4745,1.7794a.6633.6633,0,0,1,.4448.178.6449.6449,0,0,1,0,.89.6291.6291,0,1,1-.7612-.9886l-.4646-1.74a.8835.8835,0,0,1-.7118-.1977l-1.0972.6327a1.0449,1.0449,0,0,1,.079.3954,1.0963,1.0963,0,1,1-.2372-.6723l1.0478-.603a.8683.8683,0,0,1-.0988-.346l-1.6015-.4251a.6291.6291,0,1,1-.9885-.7612.6451.6451,0,0,1,.89,0,.6737.6737,0,0,1,.1878.4449l1.5421.4152a.9791.9791,0,0,1,.3065-.4448l-.5239-.9095a1.0965,1.0965,0,1,1,.692-1.0182,1.0915,1.0915,0,0,1-.3164.771c-.1878.1879.3164.8008.4449,1.0182a.8586.8586,0,0,1,.85.2274l1.2159-1.1862a.642.642,0,0,1,.0989-.7612.6291.6291,0,0,1,.89.89.642.642,0,0,1-.7612.0988L7.7052,11.731a1.0517,1.0517,0,0,1,.0593.3064H9.1288a1.1674,1.1674,0,0,1,.3064-.6129,1.0975,1.0975,0,0,1,1.552,1.5521Z" style="fill:#e12229"/></svg> \ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35.8683 35.5346"><path d="M18.9054,8.3758V.9771H8.695A3.2082,3.2082,0,0,0,5.4962,4.1759V27.6783A3.2081,3.2081,0,0,0,8.695,30.8771H26.2565a3.2082,3.2082,0,0,0,3.1988-3.1988V11.5746H22.1042A3.2082,3.2082,0,0,1,18.9054,8.3758Z" style="fill:#fff;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><line x1="18.9054" y1="0.9771" x2="29.4791" y2="11.5508" style="fill:#fff;stroke:#000;stroke-linejoin:round;stroke-width:1.95428428707763px"/><path d="M19.353,26.3927h3.6728V18.63a1.1821,1.1821,0,0,1,1.1807-1.1806H30.414a1.1834,1.1834,0,0,1,1.1807,1.1757l.0351,7.7676h3.4029l-7.6363,8.586Z" style="fill:#e12229"/><path d="M30.4141,17.8244a.8056.8056,0,0,1,.8057.802l.0367,8.1414h2.9409L27.389,34.4223l-7.171-7.6545h3.1827V18.63a.8056.8056,0,0,1,.8057-.8056h6.2077m0-.75H24.2064A1.5574,1.5574,0,0,0,22.6507,18.63v7.3878h-4.163l1.183,1.2629,7.171,7.6544.5617.5995.546-.6139,6.8084-7.6544,1.11-1.2485H32.0032L31.97,18.6229a1.5588,1.5588,0,0,0-1.5557-1.5485Z" style="fill:#fff"/><path d="M6.6572,5.9063A6.1461,6.1461,0,0,0,.51,12.0537,7.71,7.71,0,0,0,2.8646,17.65v4.935H9.7374V20.0409H11.921a1.3259,1.3259,0,0,0,1.3249-1.3249V16.5093c.4877-.11,1.7066-.568,1.6594-.9663-.053-.4554-1.3928-3.4811-1.3928-3.4811C12.3342,5.3167,6.6571,5.9062,6.6571,5.9062Z" style="fill:#e12229;stroke:#fff;stroke-miterlimit:10"/><path d="M4.2366,12.7472l1.1279-.6491a.9361.9361,0,0,1-.1064-.3724l-1.7239-.4576A.6772.6772,0,1,1,2.47,10.4487a.6943.6943,0,0,1,.9577,0,.7247.7247,0,0,1,.2022.4789l1.66.4469a1.0535,1.0535,0,0,1,.33-.4788l-.564-.979a1.18,1.18,0,1,1,.7449-1.0961,1.1748,1.1748,0,0,1-.34.83c-.2022.2022.34.862.4789,1.0961a.9242.9242,0,0,1,.9151.2447L8.1632,9.7145A.6909.6909,0,0,1,8.27,8.8951a.6772.6772,0,0,1,.9577.9577.6909.6909,0,0,1-.8194.1064L7.0671,11.3107a1.1313,1.1313,0,0,1,.0639.33H8.6a1.2569,1.2569,0,0,1,.33-.66,1.1814,1.1814,0,1,1,0,1.6707,1.2192,1.2192,0,0,1-.33-.66H7.0565a.93.93,0,0,1-.3725.4576l.5108,1.9154a.7147.7147,0,0,1,.4789.1915.6944.6944,0,0,1,0,.9578A.6772.6772,0,1,1,6.8543,14.45l-.5-1.8728a.9507.9507,0,0,1-.7662-.2128l-1.1812.681a1.1251,1.1251,0,0,1,.0851.4256,1.18,1.18,0,1,1-.2553-.7236Z" style="fill:#fff"/></svg> \ No newline at end of file diff --git a/fidle/log/catalog_nb.json b/fidle/log/catalog_nb.json new file mode 100644 index 0000000..8a6b68e --- /dev/null +++ b/fidle/log/catalog_nb.json @@ -0,0 +1,226 @@ +{ + "LINR1": { + "dirname": "LinearReg", + "basename": "01-Linear-Regression.ipynb", + "id": "LINR1", + "title": "Linear regression with direct resolution", + "description": "Direct determination of linear regression " + }, + "GRAD1": { + "dirname": "LinearReg", + "basename": "02-Gradient-descent.ipynb", + "id": "GRAD1", + "title": "Linear regression with gradient descent", + "description": "An example of gradient descent in the simple case of a linear regression." + }, + "POLR1": { + "dirname": "LinearReg", + "basename": "03-Polynomial-Regression.ipynb", + "id": "POLR1", + "title": "Complexity Syndrome", + "description": "Illustration of the problem of complexity with the polynomial regression" + }, + "LOGR1": { + "dirname": "LinearReg", + "basename": "04-Logistic-Regression.ipynb", + "id": "LOGR1", + "title": "Logistic regression, in pure Tensorflow", + "description": "Logistic Regression with Mini-Batch Gradient Descent using pure TensorFlow. " + }, + "PER57": { + "dirname": "IRIS", + "basename": "01-Simple-Perceptron.ipynb", + "id": "PER57", + "title": "Perceptron Model 1957", + "description": "A simple perceptron, with the IRIS dataset." + }, + "BHP1": { + "dirname": "BHPD", + "basename": "01-DNN-Regression.ipynb", + "id": "BHP1", + "title": "Regression with a Dense Network (DNN)", + "description": "A Simple regression with a Dense Neural Network (DNN) - BHPD dataset" + }, + "BHP2": { + "dirname": "BHPD", + "basename": "02-DNN-Regression-Premium.ipynb", + "id": "BHP2", + "title": "Regression with a Dense Network (DNN) - Advanced code", + "description": "More advanced example of DNN network code - BHPD dataset" + }, + "MNIST1": { + "dirname": "MNIST", + "basename": "01-DNN-MNIST.ipynb", + "id": "MNIST1", + "title": "Simple classification with DNN", + "description": "Example of classification with a fully connected neural network" + }, + "GTS1": { + "dirname": "GTSRB", + "basename": "01-Preparation-of-data.ipynb", + "id": "GTS1", + "title": "CNN with GTSRB dataset - Data analysis and preparation", + "description": "Episode 1 : Data analysis and creation of a usable dataset" + }, + "GTS2": { + "dirname": "GTSRB", + "basename": "02-First-convolutions.ipynb", + "id": "GTS2", + "title": "CNN with GTSRB dataset - First convolutions", + "description": "Episode 2 : First convolutions and first results" + }, + "GTS3": { + "dirname": "GTSRB", + "basename": "03-Tracking-and-visualizing.ipynb", + "id": "GTS3", + "title": "CNN with GTSRB dataset - Monitoring ", + "description": "Episode 3 : Monitoring and analysing training, managing checkpoints" + }, + "GTS4": { + "dirname": "GTSRB", + "basename": "04-Data-augmentation.ipynb", + "id": "GTS4", + "title": "CNN with GTSRB dataset - Data augmentation ", + "description": "Episode 4 : Improving the results with data augmentation" + }, + "GTS5": { + "dirname": "GTSRB", + "basename": "05-Full-convolutions.ipynb", + "id": "GTS5", + "title": "CNN with GTSRB dataset - Full convolutions ", + "description": "Episode 5 : A lot of models, a lot of datasets and a lot of results." + }, + "GTS6": { + "dirname": "GTSRB", + "basename": "06-Notebook-as-a-batch.ipynb", + "id": "GTS6", + "title": "CNN with GTSRB dataset - Full convolutions as a batch", + "description": "Episode 6 : Run Full convolution notebook as a batch" + }, + "GTS7": { + "dirname": "GTSRB", + "basename": "07-Show-report.ipynb", + "id": "GTS7", + "title": "CNN with GTSRB dataset - Show reports", + "description": "Episode 7 : Displaying the reports of the different jobs" + }, + "TSB1": { + "dirname": "GTSRB", + "basename": "99-Scripts-Tensorboard.ipynb", + "id": "TSB1", + "title": "Tensorboard with/from Jupyter ", + "description": "4 ways to use Tensorboard from the Jupyter environment" + }, + "IMDB1": { + "dirname": "IMDB", + "basename": "01-Embedding-Keras.ipynb", + "id": "IMDB1", + "title": "Text embedding with IMDB", + "description": "A very classical example of word embedding for text classification (sentiment analysis)" + }, + "IMDB2": { + "dirname": "IMDB", + "basename": "02-Prediction.ipynb", + "id": "IMDB2", + "title": "Text embedding with IMDB - Reloaded", + "description": "Example of reusing a previously saved model" + }, + "IMDB3": { + "dirname": "IMDB", + "basename": "03-LSTM-Keras.ipynb", + "id": "IMDB3", + "title": "Text embedding/LSTM model with IMDB", + "description": "Still the same problem, but with a network combining embedding and LSTM" + }, + "SYNOP1": { + "dirname": "SYNOP", + "basename": "01-Preparation-of-data.ipynb", + "id": "SYNOP1", + "title": "Time series with RNN - Preparation of data", + "description": "Episode 1 : Data analysis and creation of a usable dataset" + }, + "SYNOP2": { + "dirname": "SYNOP", + "basename": "02-First-predictions.ipynb", + "id": "SYNOP2", + "title": "Time series with RNN - Try a prediction", + "description": "Episode 2 : Training session and first predictions" + }, + "SYNOP3": { + "dirname": "SYNOP", + "basename": "03-12h-predictions.ipynb", + "id": "SYNOP3", + "title": "Time series with RNN - 12h predictions", + "description": "Episode 3: Attempt to predict in the longer term " + }, + "VAE1": { + "dirname": "VAE", + "basename": "01-VAE-with-MNIST.nbconvert.ipynb", + "id": "VAE1", + "title": "Variational AutoEncoder (VAE) with MNIST", + "description": "Episode 1 : Model construction and Training" + }, + "VAE2": { + "dirname": "VAE", + "basename": "02-VAE-with-MNIST-post.ipynb", + "id": "VAE2", + "title": "Variational AutoEncoder (VAE) with MNIST - Analysis", + "description": "Episode 2 : Exploring our latent space" + }, + "VAE3": { + "dirname": "VAE", + "basename": "03-About-CelebA.ipynb", + "id": "VAE3", + "title": "About the CelebA dataset", + "description": "Episode 3\u00a0: About the CelebA dataset, a more fun dataset ;-)" + }, + "VAE4": { + "dirname": "VAE", + "basename": "04-Prepare-CelebA-datasets.ipynb", + "id": "VAE4", + "title": "Preparation of the CelebA dataset", + "description": "Episode 4\u00a0: Preparation of a clustered dataset, batchable" + }, + "VAE5": { + "dirname": "VAE", + "basename": "05-Check-CelebA.ipynb", + "id": "VAE5", + "title": "Checking the clustered CelebA dataset", + "description": "Episode 5\u00a0:\tChecking the clustered dataset" + }, + "VAE6": { + "dirname": "VAE", + "basename": "06-VAE-with-CelebA-s.nbconvert.ipynb", + "id": "VAE6", + "title": "Variational AutoEncoder (VAE) with CelebA (small)", + "description": "Episode 6\u00a0: Variational AutoEncoder (VAE) with CelebA (small res.)" + }, + "VAE7": { + "dirname": "VAE", + "basename": "07-VAE-with-CelebA-m.nbconvert.ipynb", + "id": "VAE7", + "title": "Variational AutoEncoder (VAE) with CelebA (medium)", + "description": "Episode 7\u00a0: Variational AutoEncoder (VAE) with CelebA (medium res.)" + }, + "VAE8": { + "dirname": "VAE", + "basename": "08-VAE-withCelebA-post.ipynb", + "id": "VAE8", + "title": "Variational AutoEncoder (VAE) with CelebA - Analysis", + "description": "Episode 8\u00a0: Exploring latent space of our trained models" + }, + "ACTF1": { + "dirname": "Misc", + "basename": "Activation-Functions.ipynb", + "id": "ACTF1", + "title": "Activation functions", + "description": "Some activation functions, with their derivatives." + }, + "NP1": { + "dirname": "Misc", + "basename": "Numpy.ipynb", + "id": "NP1", + "title": "A short introduction to Numpy", + "description": "Numpy is an essential tool for the Scientific Python." + } +} \ No newline at end of file diff --git a/fidle/pwk_ns.py b/fidle/pwk_ns.py deleted file mode 100644 index 22854e2..0000000 --- a/fidle/pwk_ns.py +++ /dev/null @@ -1,562 +0,0 @@ - -# ================================================================== -# ____ _ _ _ __ __ _ -# | _ \ _ __ __ _ ___| |_(_) ___ __ _| | \ \ / /__ _ __| | __ -# | |_) | '__/ _` |/ __| __| |/ __/ _` | | \ \ /\ / / _ \| '__| |/ / -# | __/| | | (_| | (__| |_| | (_| (_| | | \ V V / (_) | | | < -# |_| |_| \__,_|\___|\__|_|\___\__,_|_| \_/\_/ \___/|_| |_|\_\ -# module pwk -# ================================================================== -# A simple module to host some common functions for practical work -# Jean-Luc Parouty 2020 - -import os -import glob -import shutil -from datetime import datetime -import itertools -import datetime, time - -import math -import numpy as np -from collections.abc import Iterable - -import tensorflow as tf -from tensorflow import keras -from sklearn.metrics import confusion_matrix - -import pandas as pd -import matplotlib -import matplotlib.pyplot as plt -#import seaborn as sn #IDRIS : module en cours d'installation - -from IPython.display import display,Image,Markdown,HTML - -import fidle.config as config - -_save_figs = False -_figs_dir = './figs' -_figs_name = 'fig_' -_figs_id = 0 - -# ------------------------------------------------------------- -# init_all -# ------------------------------------------------------------- -# -def init( mplstyle='../fidle/mplstyles/custom.mplstyle', - cssfile='../fidle/css/custom.css', - places={ 'SOMEWHERE' : '/path/to/datasets'}): - - update_keras_cache=False - - # ---- Predifined places - # - predefined_places = config.locations - - # ---- Load matplotlib style and css - # - matplotlib.style.use(mplstyle) - load_cssfile(cssfile) - - # ---- Create subdirs - # - mkdir('./run') - - # ---- Try to find where we are - # - place_name, dataset_dir = where_we_are({**places, **predefined_places}) - - - # ---- If we are at IDRIS, we need to copy datasets/keras_cache to keras cache... - # - if place_name=='Fidle at IDRIS': - from_dir = f'{dataset_dir}/keras_cache/*.*' - to_dir = os.path.expanduser('~/.keras/datasets') - mkdir(to_dir) - for pathname in glob.glob(from_dir): - filename=os.path.basename(pathname) - destname=f'{to_dir}/{filename}' - if not os.path.isfile(destname): - shutil.copy(pathname, destname) - update_keras_cache=True - - # ---- Hello world - print('\nFIDLE 2020 - Practical Work Module') - print('Version :', config.VERSION) - print('Run time : {}'.format(time.strftime("%A %-d %B %Y, %H:%M:%S"))) - print('TensorFlow version :',tf.__version__) - print('Keras version :',tf.keras.__version__) - print('Current place :',place_name ) - print('Datasets dir :',dataset_dir) - if update_keras_cache: - print('Update keras cache : Done') - - return place_name, dataset_dir - -# ------------------------------------------------------------- -# Folder cooking -# ------------------------------------------------------------- -# -def tag_now(): - return datetime.datetime.now().strftime("%Y-%m-%d_%Hh%Mm%Ss") - -def mkdir(path): - os.makedirs(path, mode=0o750, exist_ok=True) - -def get_directory_size(path): - """ - Return the directory size, but only 1 level - args: - path : directory path - return: - size in Mo - """ - size=0 - for f in os.listdir(path): - if os.path.isfile(path+'/'+f): - size+=os.path.getsize(path+'/'+f) - return size/(1024*1024) - -# ------------------------------------------------------------------ -# Where we are ? -# ------------------------------------------------------------------ -# -def where_we_are(places): - - for place_name, place_dir in places.items(): - if os.path.isdir(place_dir): - return place_name,place_dir - - print('** ERROR ** : Le dossier datasets est introuvable\n') - print(' Vous devez :\n') - print(' 1/ Récupérer le dossier datasets') - print(' Une archive (datasets.tar) est disponible via le repo Fidle.\n') - print(" 2/ Préciser la localisation de ce dossier datasets") - print(" Soit dans le fichier fidle/config.py (préférable)") - print(" Soit via un paramètre à la fonction ooo.init()\n") - print(' Par exemple :') - print(" ooo.init( places={ 'Chez-moi':'/tmp/datasets', 'Sur-mon-cluster':'/tests/datasets'}')\n") - print(' Note : Vous pouvez également déposer le dossier datasets directement dans votre home : ~/datasets\n\n') - assert False, 'datasets folder not found : Abort all.' - - -# ------------------------------------------------------------- -# shuffle_dataset -# ------------------------------------------------------------- -# -def shuffle_np_dataset(x, y): - """ - Shuffle a dataset (x,y) - args: - x,y : dataset - return: - x,y mixed - """ - assert (len(x) == len(y)), "x and y must have same size" - p = np.random.permutation(len(x)) - return x[p], y[p] - - -def update_progress(what,i,imax, redraw=False): - """ - Display a text progress bar, as : - My progress bar : ############# 34% - args: - what : Progress bas name - i : Current progress - imax : Max value for i - return: - nothing - """ - bar_length = min(40,imax) - if (i%int(imax/bar_length))!=0 and i<imax and not redraw: - return - progress = float(i/imax) - block = int(round(bar_length * progress)) - endofline = '\r' if progress<1 else '\n' - text = "{:16s} [{}] {:>5.1f}% of {}".format( what, "#"*block+"-"*(bar_length-block), progress*100, imax) - print(text, end=endofline) - - -def rmax(l): - """ - Recursive max() for a given iterable of iterables - Should be np.array of np.array or list of list, etc. - args: - l : Iterable of iterables - return: - max value - """ - maxi = float('-inf') - for item in l: - if isinstance(item, Iterable): - t = rmax(item) - else: - t = item - if t > maxi: - maxi = t - return maxi - -def rmin(l): - """ - Recursive min() for a given iterable of iterables - Should be np.array of np.array or list of list, etc. - args: - l : Iterable of iterables - return: - min value - """ - mini = float('inf') - for item in l: - if isinstance(item, Iterable): - t = rmin(item) - else: - t = item - if t < mini: - mini = t - return mini - -# ------------------------------------------------------------- -# show_images -# ------------------------------------------------------------- -# -def plot_images(x,y=None, indices='all', columns=12, x_size=1, y_size=1, - colorbar=False, y_pred=None, cm='binary',y_padding=0.35, spines_alpha=1, - fontsize=20, save_as='auto'): - """ - Show some images in a grid, with legends - args: - x : images - Shapes must be (-1,lx,ly) (-1,lx,ly,1) or (-1,lx,ly,3) - y : real classes or labels or None (None) - indices : indices of images to show or None for all (None) - columns : number of columns (12) - x_size,y_size : figure size (1), (1) - colorbar : show colorbar (False) - y_pred : predicted classes (None) - cm : Matplotlib color map (binary) - y_padding : Padding / rows (0.35) - spines_alpha : Spines alpha (1.) - font_size : Font size in px (20) - save_as : Filename to use if save figs is enable ('auto') - returns: - nothing - """ - if indices=='all': indices=range(len(x)) - draw_labels = (y is not None) - draw_pred = (y_pred is not None) - rows = math.ceil(len(indices)/columns) - fig=plt.figure(figsize=(columns*x_size, rows*(y_size+y_padding))) - n=1 - for i in indices: - axs=fig.add_subplot(rows, columns, n) - n+=1 - # ---- Shape is (lx,ly) - if len(x[i].shape)==2: - xx=x[i] - # ---- Shape is (lx,ly,n) - if len(x[i].shape)==3: - (lx,ly,lz)=x[i].shape - if lz==1: - xx=x[i].reshape(lx,ly) - else: - xx=x[i] - img=axs.imshow(xx, cmap = cm, interpolation='lanczos') - axs.spines['right'].set_visible(True) - axs.spines['left'].set_visible(True) - axs.spines['top'].set_visible(True) - axs.spines['bottom'].set_visible(True) - axs.spines['right'].set_alpha(spines_alpha) - axs.spines['left'].set_alpha(spines_alpha) - axs.spines['top'].set_alpha(spines_alpha) - axs.spines['bottom'].set_alpha(spines_alpha) - axs.set_yticks([]) - axs.set_xticks([]) - if draw_labels and not draw_pred: - axs.set_xlabel(y[i],fontsize=fontsize) - if draw_labels and draw_pred: - if y[i]!=y_pred[i]: - axs.set_xlabel(f'{y_pred[i]} ({y[i]})',fontsize=fontsize) - axs.xaxis.label.set_color('red') - else: - axs.set_xlabel(y[i],fontsize=fontsize) - if colorbar: - fig.colorbar(img,orientation="vertical", shrink=0.65) - save_fig(save_as) - plt.show() - - -def plot_image(x,cm='binary', figsize=(4,4),save_as='auto'): - """ - Draw a single image. - Image shape can be (lx,ly), (lx,ly,1) or (lx,ly,n) - args: - x : image as np array - cm : color map ('binary') - figsize : fig size (4,4) - """ - # ---- Shape is (lx,ly) - if len(x.shape)==2: - xx=x - # ---- Shape is (lx,ly,n) - if len(x.shape)==3: - (lx,ly,lz)=x.shape - if lz==1: - xx=x.reshape(lx,ly) - else: - xx=x - # ---- Draw it - plt.figure(figsize=figsize) - plt.imshow(xx, cmap = cm, interpolation='lanczos') - save_fig(save_as) - plt.show() - - -# ------------------------------------------------------------- -# show_history -# ------------------------------------------------------------- -# -def plot_history(history, figsize=(8,6), - plot={"Accuracy":['accuracy','val_accuracy'], 'Loss':['loss', 'val_loss']}, - save_as='auto'): - """ - Show history - args: - history: history - figsize: fig size - plot: list of data to plot : {<title>:[<metrics>,...], ...} - """ - fig_id=0 - for title,curves in plot.items(): - plt.figure(figsize=figsize) - plt.title(title) - plt.ylabel(title) - plt.xlabel('Epoch') - for c in curves: - plt.plot(history.history[c]) - plt.legend(curves, loc='upper left') - if save_as=='auto': - figname='auto' - else: - figname=f'{save_as}_{fig_id}' - fig_id+=1 - save_fig(figname) - plt.show() - - - -# ------------------------------------------------------------- -# plot_confusion_matrix -# ------------------------------------------------------------- -# Bug in Matplotlib 3.1.1 -# -def plot_confusion_matrix(cm, - title='Confusion matrix', - figsize=(12,8), - cmap="gist_heat_r", - vmin=0, - vmax=1, - xticks=5,yticks=5, - annot=True, - save_as='auto'): - """ - given a sklearn confusion matrix (cm), make a nice plot - Note:bug in matplotlib 3.1.1 - - Args: - cm: confusion matrix from sklearn.metrics.confusion_matrix - title: the text to display at the top of the matrix - figsize: Figure size (12,8) - cmap: color map (gist_heat_r) - vmi,vmax: Min/max 0 and 1 - annot: Annotation or just colors (True) - - """ - - accuracy = np.trace(cm) / float(np.sum(cm)) - misclass = 1 - accuracy - - plt.figure(figsize=figsize) - sn.heatmap(cm, linewidths=1, linecolor="#ffffff",square=True, - cmap=cmap, xticklabels=xticks, yticklabels=yticks, - vmin=vmin,vmax=vmax,annot=annot) - plt.ylabel('True label') - plt.xlabel('Predicted label\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass)) - save_fig(save_as) - plt.show() - - - -def display_confusion_matrix(y_true,y_pred,labels=None,color='green', - font_size='12pt', title="#### Confusion matrix is :"): - """ - Show a confusion matrix for a predictions. - see : sklearn.metrics.confusion_matrix - - Args: - y_true Real classes - y_pred Predicted classes - labels List of classes to show in the cm - color: Color for the palette (green) - font_size: Values font size - title: the text to display at the top of the matrix - """ - assert (labels!=None),"Label must be set" - - if title != None : display(Markdown(title)) - - cm = confusion_matrix( y_true,y_pred, normalize="true", labels=labels) - df=pd.DataFrame(cm) - - cmap = sn.light_palette(color, as_cmap=True) - df.style.set_properties(**{'font-size': '20pt'}) - display(df.style.format('{:.2f}') \ - .background_gradient(cmap=cmap) - .set_properties(**{'font-size': font_size})) - - -def plot_donut(values, labels, colors=["lightsteelblue","coral"], figsize=(6,6), title=None, save_as='auto'): - """ - Draw a donut - args: - values : list of values - labels : list of labels - colors : list of color (["lightsteelblue","coral"]) - figsize : size of figure ( (6,6) ) - return: - nothing - """ - # ---- Title or not - if title != None : display(Markdown(title)) - # ---- Donut - plt.figure(figsize=figsize) - # ---- Draw a pie chart.. - plt.pie(values, labels=labels, - colors = colors, autopct='%1.1f%%', startangle=70, pctdistance=0.85, - textprops={'fontsize': 18}, - wedgeprops={"edgecolor":"w",'linewidth': 5, 'linestyle': 'solid', 'antialiased': True}) - # ---- ..with a white circle - circle = plt.Circle((0,0),0.70,fc='white') - ax = plt.gca() - ax.add_artist(circle) - # Equal aspect ratio ensures that pie is drawn as a circle - plt.axis('equal') - plt.tight_layout() - save_fig(save_as) - plt.show() - - - -def plot_multivariate_serie(sequence, labels=None, predictions=None, only_features=None, - columns=3, width=5,height=4,wspace=0.3,hspace=0.2, - save_as='auto', time_dt=1): - - sequence_len = len(sequence) - features_len = sequence.shape[1] - if only_features is None : only_features=range(features_len) - if labels is None : labels=range(features_len) - - t = np.arange(sequence_len) - if predictions is None: - dt = 0 - else: - dt = len(predictions) - sequence_with_pred = sequence.copy() - sequence_with_pred[-dt:]=predictions - - rows = math.ceil(features_len/columns) - fig = plt.figure(figsize=(columns*width, rows*height)) - fig.subplots_adjust(wspace=0.3,hspace=0.2) - n=1 - for i in only_features: - ax=fig.add_subplot(rows, columns, n) - ax.plot(t[:-dt], sequence[:-dt,i], '-', linewidth=1, color='steelblue', label=labels[i]) - ax.plot(t[:-dt], sequence[:-dt,i], 'o', markersize=4, color='steelblue') - ax.plot(t[-dt-1:], sequence[-dt-1:,i],'--o', linewidth=1, fillstyle='none', markersize=6, color='steelblue') - if predictions is not None: - ax.plot(t[-dt-1:], sequence_with_pred[-dt-1:,i], '--', linewidth=1, fillstyle='full', markersize=6, color='red') - ax.plot(t[-dt:], predictions[:,i], 'o', linewidth=1, fillstyle='full', markersize=6, color='red') - - ax.legend(loc="upper left") - n+=1 - save_fig(save_as) - plt.show() - - - - - -def set_save_fig(save=True, figs_dir='./figs', figs_name='fig_', figs_id=0): - """ - Set save_fig parameters - Default figs name is <figs_name><figs_id>.{png|svg} - args: - save : Boolean, True to save figs (True) - figs_dir : Path to save figs (./figs) - figs_name : Default basename for figs (figs_) - figs_id : Start id for figs name (0) - """ - global _save_figs, _figs_dir, _figs_name, _figs_id - _save_figs = save - _figs_dir = figs_dir - _figs_name = figs_name - _figs_id = figs_id - print(f'Save figs : {_save_figs}') - print(f'Path figs : {_figs_dir}') - - -def save_fig(filename='auto', png=True, svg=False): - """ - Save current figure - args: - filename : Image filename ('auto') - png : Boolean. Save as png if True (True) - svg : Boolean. Save as svg if True (False) - """ - global _save_figs, _figs_dir, _figs_name, _figs_id - if not _save_figs : return - mkdir(_figs_dir) - if filename=='auto': - path=f'{_figs_dir}/{_figs_name}{_figs_id:02d}' - else: - path=f'{_figs_dir}/{filename}' - if png : plt.savefig( f'{path}.png') - if svg : plt.savefig( f'{path}.png') - if filename=='auto': _figs_id+=1 - - -def subtitle(t): - display(Markdown(f'<br>**{t}**')) - -def display_md(md_text): - display(Markdown(md_text)) - -def display_img(img): - display(Image(img)) - -def hdelay(sec): - return str(datetime.timedelta(seconds=int(sec))) - -def hsize(num, suffix='o'): - for unit in ['','K','M','G','T','P','E','Z']: - if abs(num) < 1024.0: - return f'{num:3.1f} {unit}{suffix}' - num /= 1024.0 - return f'{num:.1f} Y{suffix}' - -def load_cssfile(cssfile): - if cssfile is None: return - styles = open(cssfile, "r").read() - display(HTML(styles)) - - - -def np_print(*args, format={'float': '{:6.3f}'.format}): - with np.printoptions(formatter=format): - for a in args: - print(a) - - - - - - -- GitLab