
1) Les environnements virtuels python venv et virtualenv
Un des modules intégré à Python 3 est venv. Il permet de créer facilement et rapidement un environnement virtuel dans lequel on peut installer et exécuter des programmes Python.
Il imite une installation système complète de Python et de tous les modules souhaités sans interférer avec aucun système sur lequel l'application pourrait fonctionner.
Voyons comment créer un environnement virtuel et comment ajouter un module python.
pi@raspberrypi2:~/Documents $ pwd /home/pi/Documents # On cree un repertoire qui sera notre environnement virtuel pi@raspberrypi2:~/Documents $ mkdir PM pi@raspberrypi2:~/Documents $ ls -l total 4 drwxr-xr-x 2 pi pi 4096 sept. 27 17:49 PM pi@raspberrypi2:~/Documents $ python3 --version Python 3.5.3 # On cree l'environnement virtuel pi@raspberrypi2:~/Documents $ python3 -m venv /home/pi/Documents/PM # On regarde simplement ce qui a ete cree pi@raspberrypi2:~/Documents $ ls -l PM/ total 20 drwxr-xr-x 2 pi pi 4096 sept. 27 17:50 bin drwxr-xr-x 2 pi pi 4096 sept. 27 17:50 include drwxr-xr-x 3 pi pi 4096 sept. 27 17:50 lib -rw-r--r-- 1 pi pi 69 sept. 27 17:50 pyvenv.cfg drwxr-xr-x 3 pi pi 4096 sept. 27 17:50 share pi@raspberrypi2:~/Documents $ ls -l PM/bin/ total 32 -rw-r--r-- 1 pi pi 2133 sept. 27 17:50 activate -rw-r--r-- 1 pi pi 1249 sept. 27 17:50 activate.csh -rw-r--r-- 1 pi pi 2413 sept. 27 17:50 activate.fish -rwxr-xr-x 1 pi pi 251 sept. 27 17:50 easy_install -rwxr-xr-x 1 pi pi 251 sept. 27 17:50 easy_install-3.5 -rwxr-xr-x 1 pi pi 223 sept. 27 17:50 pip -rwxr-xr-x 1 pi pi 223 sept. 27 17:50 pip3 -rwxr-xr-x 1 pi pi 223 sept. 27 17:50 pip3.5 lrwxrwxrwx 1 pi pi 7 sept. 27 17:50 python -> python3 lrwxrwxrwx 1 pi pi 16 sept. 27 17:50 python3 -> /usr/bin/python3 # On active l'environnement pi@raspberrypi2:~/Documents $ source /home/pi/Documents/PM/bin/activate # On constate deja que le prompt a change (PM) pi@raspberrypi2:~/Documents $ # On regarde les versions des outils installes (PM) pi@raspberrypi2:~/Documents $ cd PM/ (PM) pi@raspberrypi2:~/Documents/PM $ which pip /home/pi/Documents/PM/bin/pip (PM) pi@raspberrypi2:~/Documents/PM $ pip --version pip 9.0.1 from /home/pi/Documents/PM/lib/python3.5/site-packages (python 3.5) (PM) pi@raspberrypi2:~/Documents/PM $ pip3 --version pip 9.0.1 from /home/pi/Documents/PM/lib/python3.5/site-packages (python 3.5) # On utilise pip pour installer un module python (PM) pi@raspberrypi2:~/Documents/PM $ pip install snakeviz Collecting snakeviz Downloading https://files.pythonhosted.org/packages/91/c1/79a997be084ea26d269244800db4be8c457816ca777b4b134c72514079b3/snakeviz-2.0.1-py2.py3-none-any.whl (281kB) 100% |████████████████████████████████| 286kB 507kB/s Collecting tornado>=2.0 (from snakeviz) Downloading https://www.piwheels.org/simple/tornado/tornado-6.0.3-cp35-cp35m-linux_armv7l.whl (425kB) 100% |████████████████████████████████| 430kB 176kB/s Installing collected packages: tornado, snakeviz Successfully installed snakeviz-2.0.1 tornado-6.0.3 # On liste les modules python installes (PM) pi@raspberrypi2:~/Documents/PM $ pip list DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning. pip (9.0.1) pkg-resources (0.0.0) setuptools (33.1.1) snakeviz (2.0.1) tornado (6.0.3) # On quitte (exit) l'environnement virtuel (PM) pi@raspberrypi2:~/Documents/PM $ deactivate pi@raspberrypi2:~/Documents/PM $
Il est aussi possible de créer un environnement virtuel avec Python 2:
pi@raspberrypi2:~/Documents $ python --version Python 2.7.13 pi@raspberrypi2:~/Documents $ which python /usr/bin/python # On crée le répertoire qui contiendra l'environnement virtuel pi@raspberrypi2:~/Documents $ mkdir PM # S'il n'existe pas, on installe virtualenv pi@raspberrypi2:~/Documents $ pip install virtualenv Collecting virtualenv Downloading https://files.pythonhosted.org/packages/62/77/6a86ef945ad39aae34aed4cc1ae4a2f941b9870917a974ed7c5b6f137188/virtualenv-16.7.8-py2.py3-none-any.whl (3.4MB) 100% |████████████████████████████████| 3.4MB 48kB/s Installing collected packages: virtualenv Successfully installed virtualenv-16.7.8 # On crée l'environnement virtuel pi@raspberrypi2:~/Documents $ python -m virtualenv /home/pi/Documents/PM New python executable in /home/pi/Documents/PM/bin/python Installing setuptools, pip, wheel... done. pi@raspberrypi2:~/Documents $ ls -ltr PM total 16 drwxr-xr-x 3 pi pi 4096 déc. 15 17:42 lib drwxr-xr-x 2 pi pi 4096 déc. 15 17:42 include drwxr-xr-x 2 pi pi 4096 déc. 15 17:42 local drwxr-xr-x 2 pi pi 4096 déc. 15 17:42 bin pi@raspberrypi2:~/Documents $ # On se place dans l'environnement virtuel (activation) pi@raspberrypi2:~/Documents $ cd PM pi@raspberrypi2:~/Documents/PM $ source bin/activate (PM) pi@raspberrypi2:~/Documents/PM $
2) Un premier script pour débuter en python
Voici un petit script en python3 qui permet de déterminer si un nombre est premier ou non. L'image ci-dessous montre également quelques exécutions sur Kubuntu 19.04:
prabou@prabou-VPCZ23C5E:~/Téléchargements$ cat is_prime.py #!/usr/bin/env python3 #File: is_prime.py #Author: Prabou MOUTTOU #Description: checks if nombre is prime #Version: 29 April 2019 import sys, math nombre = int(sys.argv[1]) if (nombre%2 == 0): print(nombre,"est pair, il n'est donc pas premier") else: #calcul de la partie entiere de la racine carree du nombre partie_entiere = int(math.sqrt(nombre)) if (partie_entiere%2 == 0): partie_entiere = partie_entiere - 1 #calcul du reste de l'operation nombre/3,5,7...$partie_entiere i = 3 while ((nombre%i != 0) & (i <= partie_entiere)) : i = i+2 if ((i-2) != partie_entiere): print(nombre,"n'est pas premier!", nombre,"est divisible par", i) else: print(nombre,"est premier!") prabou@prabou-VPCZ23C5E:~/Téléchargements$ ./is_prime.py 37 37 est premier! prabou@prabou-VPCZ23C5E:~/Téléchargements$ ./is_prime.py 39 39 n'est pas premier! 39 est divisible par 3 prabou@prabou-VPCZ23C5E:~/Téléchargements$ ./is_prime.py 391 391 n'est pas premier! 391 est divisible par 17 prabou@prabou-VPCZ23C5E:~/Téléchargements$ ./is_prime.py 396 396 est pair, il n'est donc pas premier prabou@prabou-VPCZ23C5E:~/Téléchargements$
3) Un deuxième script
Un script python qui répond au Problème 1 (Multiples of 3 and 5) du Project Euler.L'image ci-dessous montre le problème, suivi de quelques exécutions du script:

prabou@prabou-VPCZ23C5E:~/Téléchargements$ cat projecteuler_pb1.py #!/usr/bin/python #File: projecteuler_pb1.py #Author: Prabou MOUTTOU #Description: find the sum of all the multiples of 3 or 5 below 1000 (https://projecteuler.net/archives) #Version: 20 december 2015 import sys, math nombre = int(sys.argv[1]) sum = 0 for i in range(1,nombre): if (i%3 == 0) or (i%5 == 0): # si i est multiple de 3 ou de 5 on actualise sum sum = sum + i print "la somme vaut %d" %sum prabou@prabou-VPCZ23C5E:~/Téléchargements$ ./projecteuler_pb1.py 10 la somme vaut 23 prabou@prabou-VPCZ23C5E:~/Téléchargements$ ./projecteuler_pb1.py 1000 la somme vaut 233168 prabou@prabou-VPCZ23C5E:~/Téléchargements$
4) Pylint, Pycodestyle et Black
Un script python qui répond au Problème 10 (Summation of primes) du Project Euler.
L'image ci-dessous montre le problème, suivi de l'exécution du script, et enfin l'amélioration de la qualité du code avec pylint, pycodestyle et black:

prabou@prabou-VPCZ23C5E:~/Documents/DEV$ cat projecteuler_pb10.py #!/usr/bin/env python3 """File: projecteuler_pb10.py Author: Prabou MOUTTOU Description: resolution of projecteuler_pb10 Version: 15 May 2020""" import sys import math MYNUMBER = int(sys.argv[1]) def isprime(nombre): """Checks if nombre is prime""" # If nombre is Even, then it is not prime if nombre%2 == 0: return False else: # calcul de la partie entiere de la racine carree du nombre partie_entiere = int(math.sqrt(nombre)) if partie_entiere%2 == 0: partie_entiere = partie_entiere - 1 # calcul du reste de l'operation nombre/3,5,7...$partie_entiere i = 3 while (nombre%i != 0) & (i <= partie_entiere): i = i+2 if (i-2) != partie_entiere: return False return True def main(): """If j is prime then add total = total + j""" total = 2 for j in range(3, MYNUMBER+1): if isprime(j): total = total+j print("TOTAL=", total) if __name__ == '__main__': main() prabou@prabou-VPCZ23C5E:~/Documents/DEV$ ./projecteuler_pb10.py 10 TOTAL= 17 prabou@prabou-VPCZ23C5E:~/Documents/DEV$ ./projecteuler_pb10.py 2000000 TOTAL= 142913828922 # pylint installation prabou@prabou-VPCZ23C5E:~/Documents/DEV$ sudo apt install pylint # Code analysis prabou@prabou-VPCZ23C5E:~/Documents/DEV$ pylint projecteuler_pb10.py ************* Module projecteuler_pb10 projecteuler_pb10.py:15:4: R1705: Unnecessary "else" after "return" (no-else-return) ------------------------------------------------------------------ Your code has been rated at 9.57/10 (previous run: 9.57/10, +0.00) # pycodestyle installation prabou@prabou-VPCZ23C5E:~/Documents/DEV$ pip3 install pycodestyle Collecting pycodestyle Downloading pycodestyle-2.6.0-py2.py3-none-any.whl (41 kB) |████████████████████████████████| 41 kB 115 kB/s Installing collected packages: pycodestyle Successfully installed pycodestyle-2.6.0 # style conventions check with pycodestyle prabou@prabou-VPCZ23C5E:~/Documents/DEV$ pycodestyle projecteuler_pb10.py projecteuler_pb10.py:12:1: E302 expected 2 blank lines, found 1 projecteuler_pb10.py:15:14: E228 missing whitespace around modulo operator projecteuler_pb10.py:20:26: E228 missing whitespace around modulo operator projecteuler_pb10.py:25:22: E228 missing whitespace around modulo operator projecteuler_pb10.py:32:1: E302 expected 2 blank lines, found 1 projecteuler_pb10.py:40:1: E305 expected 2 blank lines after class or function definition, found 1 # black installation prabou@prabou-VPCZ23C5E:~/Documents/DEV$ pip3 install black Collecting black Downloading black-20.8b1.tar.gz (1.1 MB) |████████████████████████████████| 1.1 MB 234 kB/s Installing build dependencies ... done Getting requirements to build wheel ... done Preparing wheel metadata ... done Collecting typed-ast>=1.4.0 Downloading typed_ast-1.4.2-cp38-cp38-manylinux1_x86_64.whl (774 kB) |████████████████████████████████| 774 kB 26 kB/s Collecting click>=7.1.2 Downloading click-7.1.2-py2.py3-none-any.whl (82 kB) |████████████████████████████████| 82 kB 189 kB/s Collecting mypy-extensions>=0.4.3 Downloading mypy_extensions-0.4.3-py2.py3-none-any.whl (4.5 kB) Collecting regex>=2020.1.8 Downloading regex-2021.4.4-cp38-cp38-manylinux2014_x86_64.whl (733 kB) |████████████████████████████████| 733 kB 117 kB/s Collecting pathspec<1,>=0.6 Downloading pathspec-0.8.1-py2.py3-none-any.whl (28 kB) Collecting typing-extensions>=3.7.4 Downloading typing_extensions-3.7.4.3-py3-none-any.whl (22 kB) Collecting appdirs Downloading appdirs-1.4.4-py2.py3-none-any.whl (9.6 kB) Collecting toml>=0.10.1 Downloading toml-0.10.2-py2.py3-none-any.whl (16 kB) Building wheels for collected packages: black Building wheel for black (PEP 517) ... done Created wheel for black: filename=black-20.8b1-py3-none-any.whl size=124184 sha256=0e66ef978971465b51b933354196cf311524ec6c287a5e84de87714b2a954f50 Stored in directory: /home/prabou/.cache/pip/wheels/95/a4/59/10cd5378d52f92cdb45025f040e4686e10ae5217961c25fd66 Successfully built black Installing collected packages: typed-ast, click, mypy-extensions, regex, pathspec, typing-extensions, appdirs, toml, black Successfully installed appdirs-1.4.4 black-20.8b1 click-7.1.2 mypy-extensions-0.4.3 pathspec-0.8.1 regex-2021.4.4 toml-0.10.2 typed-ast-1.4.2 typing-extensions-3.7.4.3 # python code formatter prabou@prabou-VPCZ23C5E:~/Documents/DEV$ black projecteuler_pb10.py reformatted projecteuler_pb10.py All done! ✨ 🍰 ✨ 1 file reformatted. prabou@prabou-VPCZ23C5E:~/Documents/DEV$
Si vous souhaitez aller plus loin et faire du "Profiling", on peut installer Snakeviz.
Remarque: Le profiling est utilisé pour mesurer le temps que passe un programme dans chaque fonction.# On installe pip3 (càd pip pour Python3) prabou@prabou-VPCZ23C5E:~/Téléchargements$ sudo apt install python3-pip # On installe Snakeviz prabou@prabou-VPCZ23C5E:~/Téléchargements$ pip3 install snakeviz # Lister les packages avec pip3 prabou@prabou-VPCZ23C5E:~/Téléchargements$ pip3 list Package Version ---------------------- ----------- apt-xapian-index 0.47 asn1crypto 0.24.0 certifi 2018.8.24 chardet 3.0.4 command-not-found 0.3 cryptography 2.3 cson 0.7 cupshelpers 1.0 defer 1.0.6 distro-info 0.21ubuntu2 entrypoints 0.3 httplib2 0.11.3 idna 2.6 keyring 17.1.1 keyrings.alt 3.1.1 language-selector 0.1 netifaces 0.10.4 numpy 1.16.2 olefile 0.46 pexpect 4.6.0 Pillow 5.4.1 pip 18.1 pycairo 1.16.2 pycrypto 2.6.1 pycups 1.9.73 PyGObject 3.32.0 pymacaroons 0.13.0 PyNaCl 1.3.0 PyQt5 5.12.1 python-apt 1.8.4 python-debian 0.1.34 pyxdg 0.25 PyYAML 3.13 reportlab 3.5.18 requests 2.21.0 requests-unixsocket 0.1.5 SecretStorage 2.3.1 setuptools 40.8.0 six 1.12.0 snakeviz 2.0.0 speg 0.3 systemd-python 234 tornado 6.0.2 ubuntu-advantage-tools 19.2 ubuntu-drivers-common 0.0.0 ufw 0.36 unattended-upgrades 0.1 urllib3 1.24.1 wheel 0.32.3 xkit 0.0.0 prabou@prabou-VPCZ23C5E:~$ # On peut directement lancer le profilage avec le module cProfile prabou@prabou-VPCZ23C5E:~/Documents/DEV$ python3 -m cProfile -s time projecteuler_pb10.py 2000000 TOTAL= 142913828922 3000056 function calls in 9.625 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 1999998 9.187 0.000 9.307 0.000 projecteuler_pb10.py:12(isprime) 1 0.317 0.317 9.625 9.625 projecteuler_pb10.py:32(main) 999999 0.121 0.000 0.121 0.000 {built-in method math.sqrt} 1 0.000 0.000 0.000 0.000 {built-in method builtins.print} 1 0.000 0.000 0.000 0.000 {built-in method _imp.create_builtin} 1 0.000 0.000 0.000 0.000La dernière commande ci-dessus ouvrira Firefox avec un résultat qui ressemblera à ceci::986(_find_and_load) 1 0.000 0.000 9.625 9.625 projecteuler_pb10.py:2( ) 1 0.000 0.000 0.000 0.000 :157(_get_module_lock) 1 0.000 0.000 0.000 0.000 :650(_load_unlocked) 1 0.000 0.000 0.000 0.000 :406(spec_from_loader) 1 0.000 0.000 0.000 0.000 :477(_init_module_attrs) 1 0.000 0.000 0.000 0.000 :890(_find_spec) 1 0.000 0.000 0.000 0.000 :78(acquire) 1 0.000 0.000 0.000 0.000 :956(_find_and_load_unlocked) 2 0.000 0.000 0.000 0.000 :211(_call_with_frames_removed) 1 0.000 0.000 0.000 0.000 :103(release) 4 0.000 0.000 0.000 0.000 {built-in method builtins.getattr} 1 0.000 0.000 0.000 0.000 :58(__init__) 1 0.000 0.000 0.000 0.000 :725(find_spec) 1 0.000 0.000 0.000 0.000 :549(module_from_spec) 1 0.000 0.000 9.625 9.625 {built-in method builtins.exec} 1 0.000 0.000 0.000 0.000 :746(create_module) 4 0.000 0.000 0.000 0.000 {built-in method builtins.hasattr} 1 0.000 0.000 0.000 0.000 :232(_requires_builtin_wrapper) 1 0.000 0.000 0.000 0.000 :176(cb) 1 0.000 0.000 0.000 0.000 :147(__enter__) 1 0.000 0.000 0.000 0.000 :389(parent) 1 0.000 0.000 0.000 0.000 :754(exec_module) 1 0.000 0.000 0.000 0.000 :342(__init__) 1 0.000 0.000 0.000 0.000 :867(__exit__) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 1 0.000 0.000 0.000 0.000 :151(__exit__) 1 0.000 0.000 0.000 0.000 :143(__init__) 1 0.000 0.000 0.000 0.000 :863(__enter__) 3 0.000 0.000 0.000 0.000 {built-in method _imp.acquire_lock} 3 0.000 0.000 0.000 0.000 {built-in method _imp.release_lock} 2 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 1 0.000 0.000 0.000 0.000 :222(_verbose_message) 2 0.000 0.000 0.000 0.000 {built-in method _thread.get_ident} 2 0.000 0.000 0.000 0.000 {method 'rpartition' of 'str' objects} 2 0.000 0.000 0.000 0.000 {built-in method _thread.allocate_lock} 1 0.000 0.000 0.000 0.000 {built-in method _imp.is_builtin} 1 0.000 0.000 0.000 0.000 {built-in method _imp.exec_builtin} 1 0.000 0.000 0.000 0.000 {method 'pop' of 'dict' objects} 1 0.000 0.000 0.000 0.000 :397(has_location) 1 0.000 0.000 0.000 0.000 :771(is_package) prabou@prabou-VPCZ23C5E:~/Documents/DEV$ # On peut aussi générer un fichier profile (*.prof) prabou@prabou-VPCZ23C5E:~/Documents/DEV$ python3 -m cProfile -o projecteuler_pb10.prof projecteuler_pb10.py 2000000 TOTAL= 142913828922 prabou@prabou-VPCZ23C5E:~/Documents/DEV$ ls -lrt | grep -i ".prof" -rw-rw-r-- 1 prabou prabou 5244 mai 21 17:37 projecteuler_pb10.prof prabou@prabou-VPCZ23C5E:~/Documents/DEV$ # Maintenant qu'on a le fichier projecteuler_pb10.prof, il faut l'ouvrir. # Pour trouver le path où est installé snakeviz, on utilise les commandes suivantes: prabou@prabou-VPCZ23C5E:~/Documents/DEV$ pip3 show snakeviz Name: snakeviz Version: 2.1.0 Summary: A web-based viewer for Python profiler output Home-page: https://github.com/jiffyclub/snakeviz Author: Matt Davis Author-email: jiffyclub@gmail.com License: UNKNOWN Location: /usr/local/lib/python3.8/dist-packages Requires: tornado Required-by: prabou@prabou-VPCZ23C5E:~/Documents/DEV$ ls -ltr /usr/local/lib/python3.8/dist-packages total 16 drwxr-sr-x 5 root staff 4096 mai 21 17:15 tornado drwxr-sr-x 2 root staff 4096 mai 21 17:15 tornado-6.0.4.dist-info drwxr-sr-x 2 root staff 4096 mai 21 17:15 snakeviz-2.1.0.dist-info drwxr-sr-x 5 root staff 4096 mai 21 17:15 snakeviz prabou@prabou-VPCZ23C5E:~/Documents/DEV$ which snakeviz /usr/local/bin/snakeviz prabou@prabou-VPCZ23C5E:~/Documents/DEV$ /usr/local/bin/snakeviz projecteuler_pb10.prof snakeviz web server started on 127.0.0.1:8080; enter Ctrl-C to exit http://127.0.0.1:8080/snakeviz/%2Fhome%2Fprabou%2FDocuments%2FDEV%2Fprojecteuler_pb10.prof # Une autre méthode plus simple est d'utiliser la commande: prabou@prabou-VPCZ23C5E:~/Documents/DEV$ python3 -m snakeviz projecteuler_pb10.prof

Si vous souhaitez faire en plus de la couverture de code, on peut installer Coverage:
# Installation de Coverage prabou@prabou-VPCZ23C5E:~/Téléchargements$ pip3 install coverage Collecting coverage Downloading https://files.pythonhosted.org/packages/b4/6a/8e2918c56682739cf177a7358929fed427d3982cc649e859b7a2d5c7daea/coverage-4.5.3-cp37-cp37m-manylinux1_x86_64.whl (204kB) 100% |████████████████████████████████| 215kB 1.6MB/s Installing collected packages: coverage Successfully installed coverage-4.5.3 # Mesure/test de couverture du code, il génère un fichier .coverage prabou@prabou-VPCZ23C5E:~/Téléchargements$ coverage run projecteuler_pb10.py 2000 TOTAL= 277050 prabou@prabou-VPCZ23C5E:~/Téléchargements$ ls -lart | grep -i "coverage" -rw-rw-r-- 1 prabou prabou 198 mai 22 21:18 .coverage # La commande "coverage erase" permet de supprimer le fichier .coverage (càd supprimer le résultat de la dernière analyse) prabou@prabou-VPCZ23C5E:~/Téléchargements$ coverage erase prabou@prabou-VPCZ23C5E:~/Téléchargements$ ls -lart | grep -i "coverage" prabou@prabou-VPCZ23C5E:~/Téléchargements$ # Comme on vient de supprimer la dernière mesure, on recommence le test prabou@prabou-VPCZ23C5E:~/Téléchargements$ coverage run projecteuler_pb10.py 7 TOTAL= 17 prabou@prabou-VPCZ23C5E:~/Téléchargements$ # On choisit d'afficher le résultat directement dans le terminal prabou@prabou-VPCZ23C5E:~/Téléchargements$ coverage report -m Name Stmts Miss Cover Missing ---------------------------------------------------- projecteuler_pb10.py 21 2 90% 27, 30 prabou@prabou-VPCZ23C5E:~/Téléchargements$ # On choisit de générer un beau rapport html (création du répertoire htmlcov) prabou@prabou-VPCZ23C5E:~/Téléchargements$ coverage html prabou@prabou-VPCZ23C5E:~/Téléchargements$ ls -lart | grep -i "cov" -rw-rw-r-- 1 prabou prabou 192 mai 22 21:34 .coverage drwxrwxr-x 2 prabou prabou 4096 mai 22 21:35 htmlcov prabou@prabou-VPCZ23C5E:~/Téléchargements$
Dans ce répertoire htmlcov, on retrouve notamment un fichier index.html qui ressemble à ceci:

, et un fichier projecteuler_pb10_py.html qui peut être affiché depuis index.html en cliquant sur le nom du fichier; et qui ressemble à ceci (affichage du code):

5) gspread
gspread est une API python pour Google Sheets. Elle permet d'automatiser la création/suppression d'une feuille de calcul dans un dossier spécifique de Google Drive.
Grâce à cette API, on peut lire le contenu d'une feuille, y écrire, et mettre en forme les données.
La vidéo suivante montre les différentes étapes de configuration, ainsi qu'un exemple d'utilisation.
6) Quelques modules python
Voici les modules matplotlib et numpy. Matplotlib permet de tracer et visualiser des données sous formes de graphiques.
Ci-dessous la fonction 1 + sin(2πt), pour t ∈ [0; 2]
import matplotlib.pyplot as plt import numpy as np t = np.arange(0.0, 2.0, 0.01) s = 1 + np.sin(2*np.pi*t) plt.plot(t, s) plt.xlabel('time (s)') plt.ylabel('voltage (mV)') plt.title('About as simple as it gets, folks') plt.grid(True) plt.savefig("matplot_1.png") plt.show()Voici le résultat obtenu:

Ci-dessous une courbe obtenue simplement à partir de 4 points:
import matplotlib.pyplot as plt plt.plot([1, 2, 3, 4], [1, 4, 9, 16]) plt.ylabel('some numbers') plt.grid(True) plt.show()

Ou si on souhaite afficher uniquement des points:
import matplotlib.pyplot as plt import numpy as np # evenly sampled time at 200ms intervals t = np.arange(0., 5., 0.2) # red dashes, blue squares, green triangles, fuchsia diamond... plt.plot(t, t, 'r--') plt.plot(t, t**2, 'bs') plt.plot(t, t**3, 'g^') plt.plot(t, t**4, color = '#FF00FF', linestyle = '', marker = 'D') plt.plot(t, 80*t, color = '#FFA500', linestyle = 'dotted', marker = 'x') plt.plot(t, 20*t, 'yo') plt.plot(t, 3*np.exp(t), 'k*') plt.show()
