New deploy script.

This commit is contained in:
Julien Palard 2023-05-27 09:28:28 +02:00
parent 20260058ae
commit 263586f061
Signed by: mdk
GPG Key ID: 0EFC1AC1006886F8
5 changed files with 169 additions and 182 deletions

BIN
background.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

29
deploy.sh Executable file
View File

@ -0,0 +1,29 @@
#!/bin/sh
if ! which cutycapt >/dev/null
then
echo Please apt install cutycapt
exit 1
fi
if ! which pytest >/dev/null
then
echo Please pip install -r requirements.txt
exit 1
fi
set -e # So a breaking test stops the deploy.
export QT_QPA_PLATFORM=offscreen
for makefile in */Makefile
do
dir="$(dirname "$makefile")"
figlet -C utf8 -t "$dir"
(
cd "$dir"
make test
make rsync
)
done

View File

@ -359,26 +359,6 @@ En initiation on dit "ça ne vous servira pas". En avancé on dit
Notes:
```python
class M(type):
def __new__(cls, *args, **kwargs):
print(f"meta.__new__(*{args}, **{kwargs})")
return super().__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
print(f"meta.__init__(*{args}, **{kwargs})")
super().__init__(*args, **kwargs)
class MyCls(metaclass=M):
def __new__(cls, *args, **kwargs):
print(f"cls.__new__(*{args}, **{kwargs})")
return super().__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
print(f"cls.__init__(*{args}, **{kwargs})")
super().__init__(*args, **kwargs)
```
Vous pouvez aussi utiliser un décorateur pour personaliser une classe.
@ -906,7 +886,7 @@ Dans l'attribut `value`.
## await
```
```text
async def two():
return 2
@ -963,8 +943,11 @@ def coro_manager(coro):
coro.send(None)
except StopIteration as stop:
return stop.value
```
print(coro_manager(four()))
```pycon
>>> print(coro_manager(four()))
4
```
@ -981,7 +964,7 @@ async def wont_terminate_here():
print("Terminated")
return 42
print(coro_manager(wont_terminate_here()))
coro_manager(wont_terminate_here())
```
## Gérer ses coroutines
@ -1016,14 +999,14 @@ def frenetic_coros_manager(*coros):
## Gérer ses coroutines
```python
```text
async def tum():
for _ in range(10): # ou : while True:
while True:
await Awaitable()
print("Tum")
async def pak():
for _ in range(10): # ou : while True:
while True:
await Awaitable()
print("Pak")

View File

@ -135,7 +135,7 @@ In [1]:
## Testons l'interpréteur
```python
```pycon
>>> 10
10
```
@ -150,7 +150,7 @@ pour qu'on puisse le lire.
## C'est votre nouvelle calculatrice
```python
```pycon
>>> 60 * 60 * 4
14400
```
@ -158,7 +158,7 @@ pour qu'on puisse le lire.
## Les exceptions
```python
```pycon
>>> 5 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
@ -174,7 +174,7 @@ Lisez *TOUJOURS* la dernière ligne en premier !
## Booléens
```python
```pycon
>>> True
True
>>> False
@ -185,7 +185,7 @@ False
## Nombres
```python
```pycon
>>> 42
42
```
@ -193,7 +193,7 @@ False
## Nombres
```python
```pycon
>>> 18446744073709551616
18446744073709551616
```
@ -201,7 +201,7 @@ False
## Nombres
```python
```pycon
>>> 3.1415
3.1415
```
@ -209,7 +209,7 @@ False
## Chaînes de caractères
```python
```pycon
>>> "Beurre ou huile d'olive ?"
"Beurre ou huile d'olive ?"
```
@ -222,7 +222,7 @@ dans un cours de C89.
## Chaînes de caractères
```python
```pycon
>>> 'Cuisson "au beurre" !!'
'Cuisson "au beurre" !!'
```
@ -234,7 +234,7 @@ Les triples quotes apparaissent jour 2.
## Listes
```python
```pycon
>>> ["1 kg de farine", "12 œufs", "130 g de beurre"]
['1 kg de farine', '12 œufs', '130 g de beurre']
```
@ -246,7 +246,7 @@ La représentation est souvent du Python valide.
## Listes
```python
```pycon
>>> ["farine", 1000]
['farine', 1000]
```
@ -258,7 +258,7 @@ Attention à ne pas abuser du mélange autorisé des types.
## *n*-uplets, *tuple*
```python
```pycon
>>> ("œufs", 12)
('œufs', 12)
>>> ("sucre", 130)
@ -275,7 +275,7 @@ liste, par exemple des coordonnées : (x, y).
## Listes et tuples
```python
```pycon
>>> [("farine", 1000), ("œufs", 12), ("sucre", 130)]
[('farine', 1000), ('œufs', 12), ('sucre', 130)]
```
@ -316,7 +316,7 @@ pas les clefs à l'avance, sinon c'est une classe.
## Les opérateurs mathématiques
```python
```pycon
>>> 10 + 10
20
>>> 10.5 + 2
@ -326,14 +326,14 @@ pas les clefs à l'avance, sinon c'est une classe.
## Les opérateurs mathématiques
```python
```pycon
>>> (4 * 10**1) + (2 * 10**0)
42
```
## Les opérateurs mathématiques
```python
```pycon
>>> 10 / 2
5.0
```
@ -341,7 +341,7 @@ pas les clefs à l'avance, sinon c'est une classe.
## Les opérateurs
```python
```pycon
>>> "Bri" + "oche"
'Brioche'
```
@ -353,7 +353,7 @@ It's called concatenation of strings.
## Les opérateurs
```python
```pycon
>>> "mur" * 2
'murmur'
```
@ -365,7 +365,7 @@ Tant qu'il n'y a pas d'ambiguité, c'est implémenté.
## Les opérateurs
```python
```pycon
>>> ["farine", "œufs"] + ["sucre", "sel"]
['farine', 'œufs', 'sucre', 'sel']
```
@ -374,7 +374,7 @@ Tant qu'il n'y a pas d'ambiguité, c'est implémenté.
## Les Comparisons
```python
```pycon
>>> 10 < 1
False
>>> 10 == 10
@ -391,7 +391,7 @@ quand l'utiliser.
## Logique
```python
```pycon
>>> True or False
True
>>> True and False
@ -407,7 +407,7 @@ On utilisera ça plus tard, avec les structures de contrôle.
## Test d'appartenance
```python
```pycon
>>> "chocolat" in "pain au chocolat"
True
```
@ -415,7 +415,7 @@ True
## Test d'appartenance
```python
```pycon
>>> "sel" in {"farine", "œuf", "sucre", "sel", "levure"}
True
```
@ -423,7 +423,7 @@ True
## Travailler avec les ensembles
```python
```pycon
>>> {"farine", "sel"} | {"œuf", "sel"} == {"sel", "farine", "œuf"}
True
```
@ -435,7 +435,7 @@ C'est une union.
## Travailler avec les ensembles
```python
```pycon
>>> {"farine", "levure", "sel"} & {"œuf", "sel", "sucre"}
{'sel'}
```
@ -447,7 +447,7 @@ Une intersection.
## Mais en cas d'ambiguité…
```python
```pycon
>>> "farine" * "sucre"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
@ -457,7 +457,7 @@ TypeError: can't multiply sequence by non-int of type 'str'
## Mais en cas d'ambiguité…
```python
```pycon
>>> {"farine", "levure"} + {"sel", "œuf"}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
@ -469,7 +469,7 @@ TypeError: unsupported operand type(s) for +: 'set' and 'set'
## Affectation
```python
```pycon
>>> preparation = 20
>>> cuisson = 30
>>> preparation + cuisson
@ -483,7 +483,7 @@ JAMAIS dire : On met 20 dans « preparation ».
## Affectation multiple
```python
```pycon
>>> preparation, cuisson = 20, 30
>>> preparation
20
@ -494,7 +494,7 @@ JAMAIS dire : On met 20 dans « preparation ».
## Accès par indice
```python
```pycon
>>> etapes = ["preparation", "cuisson", "dégustation"]
>>> etapes[0]
'preparation'
@ -513,7 +513,7 @@ Bien prendre le temps d'expliquer la syntaxe ici.
## Accès par clé
```python
```pycon
>>> definitions = {
... "un verre": "25 cl",
... "un petit verre": "12 cl",
@ -529,7 +529,7 @@ Bien prendre le temps d'expliquer la syntaxe ici.
## print
```python
```pycon
>>> print("Brioche")
Brioche
```
@ -541,7 +541,7 @@ C'est leur première fonction, s'attarder sur la syntaxe !
## print
```python
```pycon
>>> print("La moitié de 130 g :", 130 // 2, "g")
La moitié de 130 g : 65 g
```
@ -560,14 +560,14 @@ Exercices:
## str, list, int, ...
```python
```pycon
>>> str(130)
'130'
```
## str, list, int, ...
```python
```pycon
>>> int("130")
130
```
@ -575,7 +575,7 @@ Exercices:
## len
```python
```pycon
>>> len(["farine", "œufs", "sucre"])
3
>>> len("farine")
@ -589,7 +589,7 @@ Exercise: Character counting
## range
```python
```pycon
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(5, 10))
@ -614,14 +614,14 @@ chaînes.
## sorted
```python
```pycon
>>> sorted({"sel", "farine", "sucre"})
['farine', 'sel', 'sucre']
```
## Les importer des modules
```python
```pycon
>>> from random import choice
>>> print(choice(["Pain au chocolat", "Chocolatine"]))
Pain au chocolat
@ -636,7 +636,7 @@ Exercice : Import.
## if
```python
```pycon
>>> if "sucre" in ingredients and "œuf" in ingredients:
... print("Commencer par blanchir les œufs.")
Commencer par blanchir les œufs.
@ -656,7 +656,7 @@ whole number can be written as a _unique_ product of primes ».
Après un bloc `if`, on peut ajouter un bloc `else` :
```python
```pycon
>>> if "sucre" in ingredients and "œuf" in ingredients:
... print("Commencer par blanchir les œufs.")
... else:
@ -669,7 +669,7 @@ Commencer par blanchir les œufs.
Après un `if`, on peut ajouter un ou des bloc `elif` :
```python
```pycon
>>> grams = 1250
>>> if grams == 0:
... print("Ne pas en mettre")
@ -689,7 +689,7 @@ Parler de `pass` et de `...`.
## for
```python
```pycon
>>> for ingredient in ingredients:
... print(ingredient)
...
@ -701,7 +701,7 @@ beurre
œuf
```
```python
```pycon
>>> ingredient = ingredients[0]
>>> print(ingredient)
sel
@ -716,7 +716,7 @@ sucre
## for
```python
```pycon
>>> for lettre in "Œuf":
... print(lettre)
...
@ -729,7 +729,7 @@ f
## for
```python
```pycon
>>> for i in range(5):
... print(i)
0
@ -755,7 +755,7 @@ cependant dans quelques cas:
## L'instruction `while`
```python
```pycon
>>> while il_reste_de_la_pâte:
... faire_une_crêpe()
...
@ -766,7 +766,7 @@ cependant dans quelques cas:
## Sur les chaînes
```python
```pycon
>>> s = "Pâte à crêpe"
>>> s.count("e")
2
@ -783,7 +783,7 @@ Exercise : Counting Words.
## Sur les chaînes
```python
```pycon
>>> s = "Durée : {} minutes."
>>> s.format(3600 // 60)
'Durée : 60 minutes.'
@ -792,7 +792,7 @@ Exercise : Counting Words.
## Sur les listes
```python
```pycon
>>> ingredients = ["1 kg de farine", "12 œufs"]
>>> ingredients.append("130 g de beurre")
>>> ingredients
@ -802,7 +802,7 @@ Exercise : Counting Words.
## Sur les dictionnaires
```python
```pycon
>>> definitions = {
... "un verre": "25 cl",
... "un petit verre": "12 cl",
@ -894,7 +894,7 @@ modifier).
En Python, ce qui est vide est faux, `0` est faux, `None` est faux,
`False` est faux. Le reste est vrai :
```python
```pycon
>>> bool("Non vide")
True
>>> bool([]) # Une liste vide
@ -930,7 +930,7 @@ Passer du temps sur la syntaxe et le vocabulaire
## Exemple
```python
```pycon
>>> def temps_total(temps_de_preparation, temps_de_cuisson):
... return temps_de_preparation + temps_de_cuisson
...
@ -950,7 +950,7 @@ def fahrenheit_to_celsius(fahrenheit):
## Arguments
On peut donc lui donner des arguments :
```python
```pycon
>>> fahrenheit_to_celsius(320)
160.0
>>> fahrenheit_to_celsius(390)
@ -966,7 +966,7 @@ Exercices: First function, Print even numbers, ...
# Les chaînes
```python
```pycon
>>> """Elle préfère "l'huile d'olive"."""
'Elle préfère "l\'huile d\'olive".'
```
@ -989,7 +989,7 @@ def une_fonction():
## Les opérateurs mathématiques
```python
```pycon
>>> 0.1 + 0.1
0.2
```
@ -997,7 +997,7 @@ def une_fonction():
## Les opérateurs mathématiques
```python
```pycon
>>> 0.1 + 0.2
0.30000000000000004
```
@ -1017,7 +1017,7 @@ l'élément suivant. Qu'on soit dans un `for` ou dans un `while`.
## `break`
```python
```pycon
>>> while True:
... if not il_reste_de_la_pâte:
... break
@ -1028,7 +1028,7 @@ l'élément suivant. Qu'on soit dans un `for` ou dans un `while`.
## `continue`
```python-repl
```pycon-repl
>>> for recette in recettes:
... if "sésame" in recette["ingredients"]:
... continue
@ -1043,7 +1043,7 @@ Houmous
## Les exceptions : `try`
```python
```pycon
>>> try:
... int("2 kg")
... except ValueError:
@ -1056,7 +1056,7 @@ Raté
C'est transformer ça :
```python
```pycon
>>> durées = []
>>> for recette in recettes:
... durées.append(recette["durée"])
@ -1069,7 +1069,7 @@ C'est transformer ça :
en :
```python
```pycon
>>> [recette["durée"] for recette in recettes]
[35, 20, 13]
```
@ -1114,20 +1114,20 @@ Elle devrait s'écrire sur une seule ligne, mais, vidéoprojecteur...
*slices* en anglais
notes:
On pourrait traduire par « tranches » et filer la métaphore culinaire…
Notes:
['incontestable', 'contestable', 'testable', 'stable']
```python
seq = 'incontestable'
# ['incontestable', 'contestable', 'testable', 'stable']
```
## Les *slices*
```python
>>> seq
'incontestable'
```pycon
>>> seq = 'incontestable'
>>> seq[0]
'i'
```
@ -1135,65 +1135,79 @@ seq = 'incontestable'
## Les *slices*
```python
```text
11
0123456789 |
incontestable—12
|
10
```
```pycon
>>> seq[5:9]
'test'
>>> seq[5:13]
'testable'
>>> seq[7:13]
'stable'
```
## Les *slices*
```pycon
>>> seq[:2]
'in'
>>> seq[2:]
'contestable'
```
## Les *slices*
```python
>>> seq[3:6]
['D', 'E', 'F']
```
## Les *slices*
```python
>>> seq[:]
['A', 'B', 'C', 'D', 'E', 'F']
```
## Les *slices*
```python
>>> seq[1:]
['B', 'C', 'D', 'E', 'F']
```
## Les *slices*
```python
```pycon
>>> seq[-1]
'F'
'e'
```
## Les *slices*
```python
>>> seq[:-2]
['A', 'B', 'C', 'D']
```pycon
>>> seq[-6:]
'stable'
```
## Les *slices*
```python
>>> seq[0:5:2]
['A', 'C', 'E']
```pycon
>>> "perso"[::2]
'pro'
```
## Les *slices*
notes:
```python
>>> seq[::-1]
['F', 'E', 'D', 'C', 'B', 'A']
dict = ['ados', 'assit', 'engager', 'éroder', 'épater', 'ivres', 'soda', 'tissa', 'regagne', 'erodé', 'retapé', 'servi']
```
## Les *slices*
```pycon
>>> for word in dict:
... if word[::-1] in dict:
... print(word, word[::-1])
ados soda
assit tissa
engager regagne
épater retapé
ivres servi
soda ados
tissa assit
regagne engager
retapé épater
servi ivres
```
@ -1251,7 +1265,7 @@ Notes: On connaît les attributs.
## Exemple
```python
```pycon
>>> ISIN = {
... "GLE": "FR0000130809",
... "PARRO": "FR0004038263",
@ -1296,7 +1310,7 @@ BiaisedDice(Dice) est un bon exemple d'héritage.
## Utilisation
```python
```pycon
>>> dice = Dice()
>>> dice.throw()
>>> dice.value
@ -1306,7 +1320,7 @@ BiaisedDice(Dice) est un bon exemple d'héritage.
## Utilisation
```python
```pycon
>>> cup = DiceCup(
... [Dice() for _ in range(10)]
... )
@ -1517,7 +1531,7 @@ Notes: Voir mon bashrc :] Surtout "viable" depuis la 3.8.
Signifie « plusieurs », comme dans une liste ou un *n*-uplet.
```python
```pycon
>>> begin, *rest = range(5)
>>> begin
0
@ -1538,7 +1552,7 @@ begin, rest = seq[0], seq[1:]
## `*`
```python
```pycon
>>> def sum(*args):
... print(args)
...
@ -1549,7 +1563,7 @@ begin, rest = seq[0], seq[1:]
## `*`
```python
```pycon
>>> [0, 0, 0, *range(3)]
[0, 0, 0, 0, 1, 2]
```
@ -1557,7 +1571,7 @@ begin, rest = seq[0], seq[1:]
## `*`
```python
```pycon
>>> print(*range(5))
0 1 2 3 4
```
@ -1568,7 +1582,7 @@ begin, rest = seq[0], seq[1:]
Signifie « plusieurs, nommés », comme dans un dictionnaire.
```python
```pycon
>>> def p(**kwargs):
... for key, value in kwargs.items():
... print(key, "→", value)
@ -1581,7 +1595,7 @@ y → 12
## `**`
```python
```pycon
>>> defaults = {"path": "./",
... "pattern": "*.txt"}
>>> {**defaults, "pattern": "*.md"}
@ -1591,7 +1605,7 @@ y → 12
## `**`
```python
```pycon
>>> def p(x, y):
... print(f"x → {x}")
... print(f"y → {y}")
@ -1610,7 +1624,7 @@ y → 12
C'est transformer une chaîne en octets, pour son transport ou stockage :
```python
```pycon
>>> "L'été".encode()
b"L'\xc3\xa9t\xc3\xa9"
>>> list("L'été".encode())
@ -1622,7 +1636,7 @@ b"L'\xc3\xa9t\xc3\xa9"
C'est le contraire ...
```python
```pycon
>>> bytes([76, 39, 195, 169, 116, 195, 169]).decode()
"L'été"
```

View File

@ -1,40 +0,0 @@
#!/usr/bin/env python3
import argparse
from string import ascii_letters, digits
import re
import doctest
from tempfile import NamedTemporaryFile
import importlib.util
parser = argparse.ArgumentParser()
parser.add_argument("file", nargs="+")
parser.add_argument("-v", "--verbose", action="store_true")
parser.add_argument("-d", "--debug", action="store_true")
args = parser.parse_args()
for file_to_test in args.file:
with open(file_to_test) as f:
source = f.read()
with NamedTemporaryFile(mode="w", suffix=".py") as f:
for example_match in re.finditer("```python.*?```", source, re.S):
example = example_match.group()
example = "\n".join(example.split("\n")[1:-1])
lineno = source[:example_match.start()].count("\n") + 1
function_name = ''.join(letter if letter in ascii_letters + digits else '_' for letter in file_to_test[:-3]) + "_line_" + str(lineno)
if example.startswith(">>> "):
if '"""' in example:
f.write(f"""def _{function_name}():\n r'''""" + example + """\n'''\n\n""")
else:
f.write(f'''def _{function_name}():\n r"""''' + example + '''\n"""\n\n''')
else:
f.write(example + "\n\n")
f.flush()
if args.debug:
with open(f.name) as py_source:
print(py_source.read())
spec = importlib.util.spec_from_file_location("to_test", f.name)
to_test = importlib.util.module_from_spec(spec)
spec.loader.exec_module(to_test)
doctest.testmod(to_test, verbose=args.verbose)

1
python-initiation/test.py Symbolic link
View File

@ -0,0 +1 @@
../python-avancé/test.py