|
| 1 | +--- |
| 2 | +celltoolbar: Slideshow |
| 3 | +jupytext: |
| 4 | + encoding: '# -*- coding: utf-8 -*-' |
| 5 | + text_representation: |
| 6 | + extension: .md |
| 7 | + format_name: myst |
| 8 | +kernelspec: |
| 9 | + display_name: Python 3 (ipykernel) |
| 10 | + language: python |
| 11 | + name: python3 |
| 12 | +language_info: |
| 13 | + name: python |
| 14 | + nbconvert_exporter: python |
| 15 | + pygments_lexer: ipython3 |
| 16 | +nbhosting: |
| 17 | + title: formatage et impressions |
| 18 | +--- |
| 19 | + |
| 20 | ++++ {"cell_style": "center"} |
| 21 | + |
| 22 | +Licence CC BY-NC-ND, Thierry Parmentelat & Arnaud Legout |
| 23 | + |
| 24 | +```{code-cell} ipython3 |
| 25 | +:lines_to_next_cell: 2 |
| 26 | +
|
| 27 | +from IPython.display import HTML |
| 28 | +HTML(filename="_static/style.html") |
| 29 | +``` |
| 30 | + |
| 31 | +# formatage et impressions |
| 32 | + |
| 33 | ++++ {"slideshow": {"slide_type": "slide"}} |
| 34 | + |
| 35 | +## formatage des chaînes : f-strings |
| 36 | + |
| 37 | ++++ {"tags": []} |
| 38 | + |
| 39 | +pour le formatage des chaines: utilisez les ***f-strings***, qui évitent les répétitions fastidieuses |
| 40 | +l'idée consiste à |
| 41 | + |
| 42 | +* faire précéder la chaine par un `f` |
| 43 | +* et embarquer directement dans la chaine des `{}` |
| 44 | +* qui peut contenir une expression Python (un nom de variable, ou plus élaboré) |
| 45 | +* et toute la partie dans le `{}` sera remplacé par le résultat de l'expression |
| 46 | + |
| 47 | +```{code-cell} ipython3 |
| 48 | +:tags: [gridwidth-1-2] |
| 49 | +
|
| 50 | +import math |
| 51 | +``` |
| 52 | + |
| 53 | +```{code-cell} ipython3 |
| 54 | +:tags: [gridwidth-1-2] |
| 55 | +
|
| 56 | +nom, age = "Pierre", 42 |
| 57 | +``` |
| 58 | + |
| 59 | +```{code-cell} ipython3 |
| 60 | +:tags: [gridwidth-1-2] |
| 61 | +
|
| 62 | +f"{nom} a {age} ans" |
| 63 | +``` |
| 64 | + |
| 65 | +```{code-cell} ipython3 |
| 66 | +:tags: [gridwidth-1-2] |
| 67 | +
|
| 68 | +f"360° = {2*math.pi} radians" |
| 69 | +``` |
| 70 | + |
| 71 | +````{admonition} n'importe quelle expression entre {} |
| 72 | +:class: info |
| 73 | +
|
| 74 | +notez qu'entre les `{}`, on peut mettre un **nom de variable** mais aussi, plus généralement, écrire **une expression** (faire un calcul) |
| 75 | +```` |
| 76 | + |
| 77 | ++++ {"slideshow": {"slide_type": ""}} |
| 78 | + |
| 79 | +### *f-string* : expression et format |
| 80 | + |
| 81 | +```{image} media/f-string.svg |
| 82 | +:align: center |
| 83 | +``` |
| 84 | + |
| 85 | +```{code-cell} ipython3 |
| 86 | +print(f"ᴨ arrondi à deux décimales = {math.pi:.2f}") |
| 87 | +``` |
| 88 | + |
| 89 | +### `=` dans une f-string |
| 90 | + |
| 91 | +grâce au `=` optionnel, on peut obtenir en une seule fois un double affichage: |
| 92 | + |
| 93 | +* le code de l'expression |
| 94 | +* et la valeur de l'expression |
| 95 | + |
| 96 | +```{code-cell} ipython3 |
| 97 | +# et c'est très pratique pour le debugging |
| 98 | +def add(x, y): |
| 99 | + return x+y |
| 100 | +
|
| 101 | +a, b = 10, 30 |
| 102 | +
|
| 103 | +# c'est ici: ⬇ |
| 104 | +print(f"{add(a, b)=}") |
| 105 | +``` |
| 106 | + |
| 107 | +### formats - scientifiques |
| 108 | + |
| 109 | +formats scientifiques usuels: `e` `f` et `g`, cf. `printf` |
| 110 | + |
| 111 | +```{code-cell} ipython3 |
| 112 | +x = 23451.23423536563 |
| 113 | +f'{x:e} | {x:f} | {x:g} | {x:010.1f} | {x:.2f}' |
| 114 | +``` |
| 115 | + |
| 116 | +```{code-cell} ipython3 |
| 117 | +y = 769876.11434 |
| 118 | +f'{x:e} | {y:f} | {x:g} | {y:010.2f} | {x:.2f}' |
| 119 | +``` |
| 120 | + |
| 121 | +Voir aussi pour plus de détails: |
| 122 | +<https://mkaz.blog/code/python-string-format-cookbook/> |
| 123 | + |
| 124 | ++++ |
| 125 | + |
| 126 | +### justification |
| 127 | + |
| 128 | +pour faire de la justification, on dispose des formats `<` `ˆ` et `>` |
| 129 | + |
| 130 | +```{code-cell} ipython3 |
| 131 | +f"|{nom:<12}|{nom:^12}|{nom:>12}|" |
| 132 | +``` |
| 133 | + |
| 134 | +```{code-cell} ipython3 |
| 135 | +# on peut aussi préciser avec quel caractère remplir |
| 136 | +num = 123 |
| 137 | +f"|{num:<12}|{num:-^12}|{num:0>12}|" |
| 138 | +``` |
| 139 | + |
| 140 | ++++ {"slideshow": {"slide_type": ""}, "tags": []} |
| 141 | + |
| 142 | +### expression dans le format |
| 143 | + |
| 144 | +un peu plus avancé, mais notez qu'on peut également utiliser des expressions dans le format |
| 145 | + |
| 146 | +```{code-cell} ipython3 |
| 147 | +:tags: [gridwidth-1-2] |
| 148 | +
|
| 149 | +from decimal import Decimal |
| 150 | +value = Decimal('12.34567') |
| 151 | +``` |
| 152 | + |
| 153 | +```{code-cell} ipython3 |
| 154 | +:tags: [gridwidth-1-2] |
| 155 | +
|
| 156 | +# ici la précision de 4 |
| 157 | +# signifie 4 chiffres |
| 158 | +# significatifs en tout |
| 159 | +
|
| 160 | +f"value = >{value:10.4}<" |
| 161 | +``` |
| 162 | + |
| 163 | +```{code-cell} ipython3 |
| 164 | +:tags: [gridwidth-1-2] |
| 165 | +
|
| 166 | +# si nécessaire la précision |
| 167 | +# peut aussi être un paramètre ! |
| 168 | +
|
| 169 | +width = 10 |
| 170 | +precision = 4 |
| 171 | +f"value = >{value:{width}.{precision}}<" |
| 172 | +``` |
| 173 | + |
| 174 | +## affichage avec `print()` |
| 175 | + |
| 176 | +```python |
| 177 | +print(obj1, .., objn, sep=' ', end='\n', |
| 178 | + file=sys.stdout, flush=False) |
| 179 | +``` |
| 180 | + |
| 181 | +* affiche les objets *obj* convertis en chaînes de caractères |
| 182 | +* séparés par `sep` (un espace par défaut) |
| 183 | +* dans le fichier `file` (`sys.stdout` par défaut) |
| 184 | +* la ligne se termine par `end` (un retour chariot par défaut) |
| 185 | + |
| 186 | ++++ |
| 187 | + |
| 188 | +#### enlever le *newline* |
| 189 | + |
| 190 | +* suppression du retour à la ligne automatique |
| 191 | + |
| 192 | +```{code-cell} ipython3 |
| 193 | +for i in range(10): |
| 194 | + print(i, end='') |
| 195 | +``` |
| 196 | + |
| 197 | +#### redirection dans un fichier |
| 198 | + |
| 199 | +* pour que `print()` écrive sur le disque dur plutôt que dans le terminal |
| 200 | + |
| 201 | +```{code-cell} ipython3 |
| 202 | +:tags: [gridwidth-1-2] |
| 203 | +
|
| 204 | +with open('test.txt', 'w') as channel: |
| 205 | + L = list(range(10)) |
| 206 | + for item in L: |
| 207 | + print(item, file=channel, end=' + ') |
| 208 | + print("\n", file=channel) |
| 209 | +``` |
| 210 | + |
| 211 | +```{code-cell} ipython3 |
| 212 | +:tags: [gridwidth-1-2] |
| 213 | +
|
| 214 | +!cat test.txt |
| 215 | +``` |
| 216 | + |
| 217 | ++++ {"slideshow": {"slide_type": "slide"}} |
| 218 | + |
| 219 | +#### plusieurs paramètres |
| 220 | + |
| 221 | +```{code-cell} ipython3 |
| 222 | +:tags: [gridwidth-1-2] |
| 223 | +
|
| 224 | +print(1, 'x', True) |
| 225 | +``` |
| 226 | + |
| 227 | +```{code-cell} ipython3 |
| 228 | +:tags: [gridwidth-1-2] |
| 229 | +
|
| 230 | +print(1, 'x', True, sep='_') |
| 231 | +``` |
| 232 | + |
| 233 | +```{code-cell} ipython3 |
| 234 | +# dans un notebook ce n'est pas très parlant |
| 235 | +# mais ici on n'obtiendrait PAS de retour à la ligne |
| 236 | +print(1, 'x', True, sep='_', end='FIN') |
| 237 | +``` |
| 238 | + |
| 239 | +```{code-cell} ipython3 |
| 240 | +# et ici on en obtiendrait deux (soit une ligne blanche) |
| 241 | +print(1, 'x', True, sep='_', end='\n\n') |
| 242 | +``` |
| 243 | + |
| 244 | +### module logging (avancé) |
| 245 | + |
| 246 | +* pour le logging plus évolué qu’un simple print redirigé dans un fichier, on peut utiliser le module de la librairie standard `logging` |
| 247 | +* documentation du module |
| 248 | + * https://docs.python.org/3/library/logging.html |
| 249 | +* tutorial |
| 250 | + * https://docs.python.org/3/howto/logging.html#logging-basic-tutorial |
| 251 | + |
| 252 | +c'est **la bonne façon** de conserver des traces d'exécutionpour un programme en production |
| 253 | + |
| 254 | ++++ |
| 255 | + |
| 256 | +## formatage : méthodes *old-school* |
| 257 | + |
| 258 | +* avant Python-3.6, il y a eu deux autres méthodes pour formatter |
| 259 | + * `str.format()` |
| 260 | + * l'opérateur `%` |
| 261 | +* il est **recommandé** d'utiliser les f-strings |
| 262 | +* mais les deux autres formes existent encore, a minima savoir les lire |
| 263 | + |
| 264 | ++++ {"slideshow": {"slide_type": "slide"}} |
| 265 | + |
| 266 | +### formatage avec `str.format()` (*old-school*) |
| 267 | + |
| 268 | +```{code-cell} ipython3 |
| 269 | +# anonyme (dans l'ordre) |
| 270 | +print('We are the {} who say "{}!"'.format('knights', 'Ni')) |
| 271 | +``` |
| 272 | + |
| 273 | +```{code-cell} ipython3 |
| 274 | +# par index |
| 275 | +print('{1} and {0} {0}'.format('spam', 'eggs')) |
| 276 | +``` |
| 277 | + |
| 278 | +```{code-cell} ipython3 |
| 279 | +# par nom |
| 280 | +print('This {food} is {adjective}' |
| 281 | + .format(food='spam', adjective='absolutely horrible')) |
| 282 | +``` |
| 283 | + |
| 284 | +### formatage avec `%` (*very old-school*) |
| 285 | + |
| 286 | +* encore plus ancienne méthode |
| 287 | + |
| 288 | +```{code-cell} ipython3 |
| 289 | +nom = "Alice" |
| 290 | +"%s dit bonjour" % nom |
| 291 | +``` |
| 292 | + |
| 293 | +```{code-cell} ipython3 |
| 294 | +d = 3 |
| 295 | +"%i + %i = %i" % (d, d, d + d) |
| 296 | +``` |
| 297 | + |
| 298 | +```{code-cell} ipython3 |
| 299 | +"%(food)s is %(adjective)s" % {'food' : 'bacon', |
| 300 | + 'adjective' : 'delicious' } |
| 301 | +``` |
| 302 | + |
| 303 | +### attention avec `+` |
| 304 | + |
| 305 | ++++ {"slideshow": {"slide_type": "slide"}, "tags": []} |
| 306 | + |
| 307 | +* on peut être parfois tenté d’utiliser la concaténation `+` |
| 308 | + |
| 309 | +```{code-cell} ipython3 |
| 310 | +:tags: [] |
| 311 | +
|
| 312 | +'abc' + 'def' |
| 313 | +``` |
| 314 | + |
| 315 | ++++ {"tags": []} |
| 316 | + |
| 317 | +* par contre **attention**, on ne peut concaténer que des `str`, il faut convertir explicitement avec `str()` |
| 318 | + |
| 319 | +```{code-cell} ipython3 |
| 320 | +:tags: [] |
| 321 | +
|
| 322 | +age = 35 |
| 323 | +try: 'alice a ' + age + ' ans' |
| 324 | +except Exception as e: print ("OOPS", e) |
| 325 | +``` |
| 326 | + |
| 327 | +```{code-cell} ipython3 |
| 328 | +:tags: [] |
| 329 | +
|
| 330 | +'alice a ' + str(age) + ' ans' |
| 331 | +``` |
0 commit comments