#!/usr/bin/env python # coding: utf-8 # In[1]: implementations = ['cpython', 'pypy', 'jython', 'ironpython'] for implementation in implementations: print(implementation) # # #

La philosophie de l'itération

# # # # #

# #



kevin@formationspython.com # #

# # # Un design pattern : iterator # Eviter de boucler à la main: # # ```c # const char *relatedTopics[] = { # "++", # "jerome", # "pas ma faute", # NULL # }; # # for (int i=0; relatedTopics[i]; ++i) { # const char *ch = relatedTopics[i]; # while(*ch) { # putchar(*ch++); # putchar('\n'); # } # putchar('\n'); # } # # ``` # # # # Visitor # # Methode `forEach` des arrays en JS: # # ```javascript # var nope = ["==", "with", "eval"]; # nope.forEach((e) => { # console.log(e) # }); # ``` # # "L'iterator" `each` de Ruby: # # ```Ruby # popularProjects = ["RoR", "rails", "Ruby on Rails"]; # popularProjects.each do |i| # puts i # end # }); # ``` # # # Comment Python fait marcher tout ça # In[2]: cris = ['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'] # cris = set(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo']) # cris = tuple(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo']) # cris = dict.fromkeys(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo']) print(f"{type(cris)} de cris :") for cri in cris: print(cri, '!') # In[3]: cris = ['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'] #cris = set(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo']) #cris = tuple(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo']) #cris = dict.fromkeys(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo']) # In[4]: sauce_magique = iter(cris) # In[5]: type(sauce_magique) # In[6]: next(sauce_magique) # In[7]: next(sauce_magique) # In[8]: next(sauce_magique) # In[10]: next(sauce_magique) # # Iterator, l'interface universelle # In[11]: for i in range(1, 4): print(i) # In[12]: for lettre in "abc": print(lettre) # In[13]: for ligne in open('answers.txt'): print(ligne) # In[14]: list(open('answers.txt')) # In[15]: tuple(range(1, 4)) # In[16]: set('abc') # In[17]: sum([1, 2, 3]) # In[18]: sum(set([1, 2, 3])) # In[19]: sum(range(1, 4)) # In[20]: sum(map(int, "123")) # In[21]: sorted(set(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'])) # In[22]: list(filter(bool, (True, False, None, 1, 0))) # In[23]: "/////////////".join(open('answers.txt')) # In[24]: for i, ligne in enumerate('abc', 1): print(i, ligne) # In[79]: import collections # amis des itérables collections.Counter('dkjflchldkfhjdlskqfvdkfdhqkj') # collections.deque # collections.defaultdict # collections.OrderedDict # collections.namedtuple # In[36]: # Prend n'importe quel itérable print(any([True, True, False, True, False])) print(all([True, True, False, True, False])) print(max([5, 10, 4, 1])) # min # reduce # Retourne des itérables: # # - bytes # - csv.reader # - os.walk # - multiprocessing.Pool.map # - sqlite3.cursor # - xml.etree.ElementTree # # # Et même les libs externes: # # - Querysets des ORMs (Django, SQLAlchemy, Peewee...); # - Body des réponses de WSGI # ## Un module juste pour les itérables # # # # ```python # import itertools # # itertools.accumulate # itertools.chain # itertools.combinations # itertools.combinations_with_replacement # itertools.compress # itertools.count # itertools.cycle # itertools.dropwhile # itertools.filterfalse # itertools.groupby # itertools.islice # itertools.permutations # itertools.product # itertools.repeat # itertools.starmap # itertools.takewhile # itertools.tee # itertools.zip_longest # ``` # In[39]: import itertools for x in itertools.chain('abc', range(3)): print(x) # In[40]: list(itertools.product('abc', range(3))) # In[41]: histoire_de_la_vie = iter(itertools.cycle('abc')) print(next(histoire_de_la_vie)) print(next(histoire_de_la_vie)) print(next(histoire_de_la_vie)) print(next(histoire_de_la_vie)) # ## L'unpacking # In[25]: x, y = (1, 2) print(x) # In[26]: def point(): return 1, 2 x, y = point() print(y) # In[27]: a, b, c = ["Aligator", "Behemot", "Claude"] print(f'a = {a}') print(f'b = {b}') print(f'c = {c}') # In[28]: a, b, c = open('answers.txt') print(f'a = {a}') print(f'b = {b}') print(f'c = {c}') # In[29]: a, *b, d = range(100) print(f'a = {a}') print(f'b = {b}') print(f'd = {d}') # In[30]: print(*'abc', sep="#") # équivaut à print("a", "b", "c", sep="#") # In[31]: [*range(3), *open('answers.txt'), *set(cris)] # marche aussi pour merger des dictionnaires avec ** :) # In[15]: pixels = ["rouge", "vert", "bleu", "rouge", "vert", "bleu", "rouge", "vert", "bleu"] # In[16]: pixels[::3], pixels[2::3] = pixels[2::3], pixels[::3] # In[17]: pixels # # Le flux de données # In[42]: import subprocess res = subprocess.check_output(["ifconfig"], encoding="utf8") # devinez ce qu'attend "call" en paramètre ? print(res) # In[43]: import re, subprocess res = subprocess.check_output(["ifconfig"], encoding="utf8") reg = re.compile(r'(\S+).*\n.*adr:(\S+)') # In[44]: interfaces = {} for block in res.split('\n\n'): if 'adr' in block: interface, ip = reg.match(block).groups() interfaces[interface] = ip print(interfaces) # In[45]: interfaces = [reg.match(block).groups() for block in res.split('\n\n') if 'adr' in block] dict(interfaces) # ## Les intensions # In[46]: [x * x for x in range(10)] # In[47]: {x: x * x for x in range(10)} # In[48]: {x * x for x in range(10)} # ## Les expressions génératrices # In[49]: # NOPE ! # res = [x * x for x in range(10000000000000)] # In[50]: res = (x * x for x in range(10000000000000)) # In[51]: res # In[52]: next(res) # In[53]: next(res) # In[54]: print(next(res)) print(next(res)) print(next(res)) # In[55]: import sqlite3 def get_results(n=10, profile="/home/pycon/.mozilla/firefox/l92ue2kx.default/places.sqlite"): return sqlite3.connect(profile).execute(""" SELECT sites.rev_host as host, count(*) as visits FROM moz_historyvisits as visits, moz_places as sites WHERE visits.place_id == sites.id GROUP BY host ORDER BY visits DESC """) # In[56]: sites = ((dom[-2::-1], vis) for dom, vis in get_results()) # In[57]: MOTEURS = set(['duckduckgo', 'google', 'bing', 'qwant']) sites = ((dom, vis) for dom, vis in sites if not any(m in dom for m in MOTEURS)) # In[58]: import itertools sites = itertools.islice(sites, 0, 5) # In[59]: sites # In[60]: next(sites) # In[61]: next(sites) # In[62]: for s in sites: print(s) # ## Yield # In[63]: def fonction_normale(): print('Avant le premier return') return 1 print('Apres le premier return') return 2 print("Apres le second return") return 3 print('Tout à la fin') res = fonction_normale() print(res) # In[64]: def fabriquer_un_generateur(): print('Avant le premier yield') yield 1 print('Apres le premier yield') yield 2 print("Apres le second yield") yield 3 print('Tout à la fin') res = fabriquer_un_generateur() print(res) # In[65]: next(res) # In[66]: next(res) # In[67]: for x in res: print(x) # In[68]: import secrets def secret_key_generator(n): for i in range(n): yield secrets.token_hex() gen = secret_key_generator(10) # In[69]: next(gen) # In[70]: next(gen) # In[71]: import itertools class MachineAtuer: def __iter__(self): while True: yield "Miaou !" for x in itertools.islice(MachineAtuer(), 10): print(x) # ## Tous les tuyaux mis bouts à bouts # In[72]: import string from pathlib import Path def lister_mots_cles(dossier, ext): for chemin in Path(dossier).glob(f'./**/*.{ext}'): # iterable try: with open(chemin) as f: for ligne in f: # iterable for mot in ligne.split(): # iterable # expression generatrice sur un itérable passée à join... qui attend un itérable mot = "".join(l for l in mot if l not in string.punctuation).strip() if mot: # génération de données yield mot except Exception: pass # In[73]: from collections import Counter # Counter accepte un itérable en a paramètre for mot, score in Counter(lister_mots_cles('/etc', 'conf')).most_common(5): # itérable print(f'- {mot}: {score}') # In[18]: get_ipython().run_cell_magic('HTML', '', '\n') # # # In[74]: import numpy as np # ou scipy, pandas, etc import matplotlib.pyplot as plt x = np.arange(0, 3 * np.pi, 0.1) y = np.sin(x) plt.plot(x, y) plt.show() # In[75]: import math x = np.arange(0, 3 * np.pi, 0.1) get_ipython().run_line_magic('timeit', '[math.sin(i) for i in x]') get_ipython().run_line_magic('timeit', 'np.sin(x)') # # Il y a un "one more thing" pour ça # In[76]: def crieur(): while True: res = yield print(res.upper(), '!') gen = crieur() next(gen) # In[77]: interdits = [ 'les interdictions', 'les listes', 'les interdictions', 'les repetitions', 'les mets', 'les blagues faciles' ] for x in interdits: gen.send(x) # #

Télécharger les slides

# # #

# https://huit.re/philo-iteration-fr #

# # #

# #

kevin@formationspython.com

#