PROJET AUTOBLOG


Sam et Max

source: Sam et Max

⇐ retour index

Mettez des fonctions dans vos structures de données

samedi 15 février 2014 à 10:50

En Python les fonctions sont des objets de premier ordre. On peut les manipuler, copier les références, les supprimer…

Exemple :

# On definit une fonction.
# Jusqu'ici tout va bien...
def pizza():
    return "miam"
 
 
print(pizza())
## miam
 
# On peut assigner la référence de
# la fonction à une variable.
delice = pizza
 
# Et utiliser la fonction depuis la variable
print(delice())
## miam
 
# On peut même supprimer la variable
# originale.
del pizza
print(delice())
## miam
 
pizza()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-3-dc0f1f08233f> in <module>()
----> 1 pizza()
 
NameError: name 'pizza' is not defined

La fonction est un objet ordinaire qui peut donc se mettre dans une variable, mais aussi se passer en paramètre, se retourner comme valeur, etc. J’ai déjà expliqué ça dans le tuto sur les décorateurs plus en détail, mais un rappel ne fait pas de mal.

Cela veut dire que l’on peut mettre la référence d’une fonction dans une structure de données.

Par exemple dans une liste :

def pizza():
    return "miam"
 
def epinard():
    return "miam aussi"
 
def arepas():
    return "decidement tout est miam"
 
# On met les fonctions dans la liste :
liste_de_fonctions = [pizza, epinard, arepas]
 
# Et du coup on peut boucler sur les fonctions
for func in liste_de_fonctions:
    print(func())
 
## miam
## miam aussi
## decidement tout est miam
 
# Le monde des listes s'ouvre à vous
 
print(liste_de_fonctions[-1]())
## decidement tout est miam
 
f1, f2 = liste_de_fonctions[:2]
print(f2())
## miam aussi

Mais aussi dans un dictionnaire :

dico_de_fonction = {
    "choix1": pizza,
    "choix2": epinard,
    "choix3": arepas
}
 
print(dico_de_fonction["choix2"]())
## miam aussi
 
for key, func in dico_de_fonction.items():
    print("%s: %s" % (key, func()))
 
## choix1: miam
## choix3: decidement tout est miam
## choix2: miam aussi

En fait, ça marche avec tout (les fonctions sont hashables) : les sets, les tuples, les deques

On peut même faire un générateur qui yield des fonctions :

import random
 
def fonctions_aleatoires(nombre, fonctions=liste_de_fonctions):
    for x in range(nombre):
        yield random.choice(liste_de_fonctions)
 
for func in fonctions_aleatoires(5):
    print(func())
 
## miam aussi
## miam
## decidement tout est miam
## miam
## miam aussi

Python n’a certes pas les capacités de Lisp ou même Javascript pour faire de la programmation fonctionnelle, mais les fonctions restent des objets très puissants dans ce langage.

D’ailleurs, cet article est valable aussi pour les classes et les modules :)

flattr this!

Et pour quelques astuces de plus

vendredi 14 février 2014 à 18:00

Sublime Text n’en fini pas d’être sublime.

Depuis le dernier article, j’ai découvert d’autres trucs super géniaux.

Echanger deux selections

Ctrl + T.

Selection en colonne

Shift + Clic droit.

Selection similaires

Ctrl + D

Attention, ça ne marche pas quand le champ “recherche” est activé.

Déplacer une ligne

Shift + Ctrl + Flèche haut ou bas.

Supprimer une ligne

Ctrl + k deux fois pour supprimer la ligne après le curseur. On rajoute shift pour supprimer la ligne complete.

Je suppose que sous Mac plein de raccourcis sont différents avec des touches commandes à la place du shift et autre…

flattr this!

Le namedtuple, la structure mal aimée

jeudi 13 février 2014 à 17:29

Figurez-vous qu’on a un chat IRC. Si, si ! freenode#sametmax administré par foxmask, qui est aussi le seul participant du chan.

Bon j’exagère, d’ailleurs tout à l’heure un lien de JEDI_BC m’a donné l’idée de cet article : qu’est-ce qu’un namedtuple et à quoi ça sert.

Les tuples, vous connaissez : c’est une séquence ordonnées non modifiable d’éléments hétérogènes.

Pardon, je recommence. C’est comme une liste, mais plus rapide, et pas modifiable. Ca se créer avec l’opérateur “,” :

>>> un_tuple = 1, 2, 3
>>> print(un_tuple)
(1, 2, 3)
>>> type(un_tuple)
<type 'tuple'>
>>> un_tuple[0]
1
>>> un_tuple[:-1]
(1, 2)
>>> autre_tuple = ("pomme", 1, True)

Les parenthèses sont optionnelles mais permettent d’éviter les ambiguïtés.

Bref, les tuples, c’est top : on peut les slicer, les indexer, et en plus c’est très très rapide car non modifiable :

>>> autre_tuple[0] = "banane"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Le tuple est donc une bonne alternative aux listes si on sait que le contenu ne bougera pas. Ca prend moins de mémoire, c’est plus rapide, c’est tout aussi flexible, et comme c’est un itérable on peut le plugger un peu partout.

Un gros défaut du tuple, néanmoins, c’est l’absence d’attributs nommés. Il faut connaitre les indices des valeurs, et c’est pas évident à lire si le tuple est gros.

Pour cette raison, la lib standard vient avec le namedtuple, qui est simplement un tuple dont les valeurs sont nommées.

Ca s’utilise en deux étapes. D’abord, définir un nouveau type de namedtuple avec la liste des attributs qu’il va contenir. Un peu comme définir une classe :

>>> from collections import namedtuple
>>> Joueur = namedtuple('Joueur', ['nom', 'age', 'signe_particulier'])

À partir de là nous avons une nouvelle “classe” de namedtuple appelée Joueur qui peut créer des namedtuples avec 3 attributs : ‘nom’, ‘age’ et ‘signe_particulier’.

Et ça s’utilise comme un tuple :

>>> jdg = Joueur('M. Grenier', 31, 'Un langage fleuri')
>>> jdg[0]
'M. Grenier'
>>> nom, age, signe = jdg
>>> nom
'M. Grenier'

Mais aussi comme un objet en read-only :

>>> jdg.nom
'M. Grenier'
>>> sam = Joueur(nom="Sam", age="Tu sauras pas", signe_particulier="Est parfaitement impartial")
>>> sam.age
'Tu sauras pas'

flattr this!

A quoi sert Ellipsis en Python ?

mercredi 12 février 2014 à 15:56

A rien.
































































Nan mais revenez, je déconnais.

Mais, sérieusement, Ellipsis, à la base, ne sert à rien.

Il existe, c’est tout.

En Python 2:

>>> Ellipsis
Ellipsis
>>> ... # pas de forme abrégée 
  File "<stdin>", line 1
    ...
    ^
SyntaxError: invalid syntax
>>> range(10)[...] # mais ceci n'est pas une syntaxe error
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: range indices must be integers or slices, not ellipsis
>>> str(Ellipsis)
'Ellipsis'
>>> Ellipsis() # ce truc ne sert à rien
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'ellipsis' object is not callable
>>> Ellipsis + Ellipsis # a rien je vous dis
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'ellipsis' and 'ellipsis'
>>> Ellipsis is Ellipsis # c'est un singleton
True
>>> bool(Ellipsis) # c'est comme None, mais en True
True

En Python 3:

>>> ...
Ellipsis

Comme je vous le disais, ça ne sert à rien.

Du coup on peut en faire ce qu’on veut ! It’s toasted !

Les libs comme NumPy s’en servent pour faire du slicing étendu. Elles ré-implementent __getitem__ et quand elles voient Ellipsis, elles interprètent ça comme un “:pour toutes les dimensions non spécifiées.

Il y a des gens qui l’utilisent en lieu et place de pass pour dire “j’écrirai ce truc plus tard”:

def fonction_optionelle():
    ...

Bien entendu, ça ne marche qu’en Python 3.

Personnellement je m’en sers comme valeur quand j’ai besoin d’un truc neutre qui ne soit pas None si None peut être une valeur attendue. Au final quand on veut faire propre, il vaut mieux faire un objet dédié qui s’appelle NotAValue ou autre, mais le quick and dirty a la vie dure.

Attention, les références récursives sont signalées par le shell Python comme ..., mais ça n’a rien à avoir avec la choucroute :

>>> l = []
>>> l.append(l)
>>> l
[[...]]

flattr this!

La quête de la contraception masculine

mardi 11 février 2014 à 18:49

Aller contre la nature, c’est toujours très contraignant.

Par exemple, imbriquer deux organes sexuels avec une faible probabilité d’obtenir une grossesse alors qu’ils sont faits pour ça, c’est un vrai challenge.

A ma droite, côté nana, le choix est entre plusieurs “solutions” :

À ma gauche, du côté des mecs, on a :

Bref, l’humanité peut envoyer des gens sur la lune, bientôt sur Mars, et c’est toujours la merde pour tromper sa femme sans faire de bâtard.

Personnellement, j’ai mis une de mes partenaires enceinte, malgré l’usage du préservatif. 4% de chance que ça passe au travers. Je répète, 1 chance sur 25 les gars…

Ayant bien compris que je ne serai pas vraiment un père enthousiaste, la miss a opté pour l’IVG. Et franchement, elle a hésité. J’aime autant vous dire que c’est pas marrant du tout. Mais alors pas du tout. Déjà, elle en chie à mort car psychologiquement c’est dur, mais en plus les médocs qu’ils vous filent, à côté les laxatifs c’est des skittles.

Je suis très bonbons dans cet article.

Mais en plus vous faites plusieurs passages à l’hosto, avec tous les deux la culpabilité pour diverses raisons. La meuf, super flippée évidement, ressort de là lessivée. Et le mec garde un super souvenir de ses attentes dans les couloirs des sections “spécial gonzesse only” de l’hopital où on te mate comme le yeti. Il doit pas y avoir beaucoup d’hommes qui accompagnent leur copine durant la procédure. En tout cas on peut pas participer aux entretiens, on sait pas ce qu’il se dit, c’est long, elle peut changer d’avis durant la longue semaine de réflexion qu’on lui laisse. Et ça peut rater aussi, faut le savoir.

Bien, ces bases posées, vous voyez que le plaisir de fritouiller, qu’on aime bien montrer comme simple et naturel, a quand même quelques problématiques cotons. Je n’aborderais même pas les MST, je laisse ça à Max, c’est lui l’expert :)

Du coup, j’ai choisis l’option vasectomie. Après deux années de réflexion, je me décide, j’en parle à tout le monde, et tout le monde me bassine pendant des heures que c’est une mauvaise idée, que je suis irresponsable, et si ? et si ? et si ?

Toujours les mêmes arguments. Jamais une once d’esprit critique. Beaucoup de stéréotype et de formatage culturel.

C’est lassant.

Je me pointe chez le bitologue, et je lui annonce. Il me dit répond : “M. Saaaam…”

Il m’appelle “M. Saaaam…” en trainant sur les syllabes, sur sa chaise, légèrement surélevée pour pouvoir regarder de haut ses patients.

“M. Saaaam…” donc, “à votre age. Vous n’avez pas d’enfaaaaaaaants… J’ai exactement les mêmes arguments que tous vos amiiiis et votre famille sur lesquelles vous avez réfléchi pendant 2 ans et moi 5 minutes car personne n’est jamais venu se présenter avec cette requête. Bla bla bla. Cot cot cot cot.”

“Bref, vous n’avez pas les bonnes chaussures. Ça va pas être possible. 75 euros s’il vous plait.”

Je déprime un peu.

Depuis quelques années, je suis le projet RISUG, un truc indien encore expérimental qui consiste à injecter un polymère dans le spermiducte (ça s’appelle comme ça, juré !). Pour le moment, on a un ratio de 1 grossesse sur 250 mecs, et au max ça a tenu 10 ans. C’est réversible.

Ça ne protège pas des maladies (quoi que des tests sont en cours pour vérifier si ça n’arrête pas la transmission du VIH mâle => femelle), évidement, mais il n’y a pas d’effets secondaires constatés, pas de bidule à faire avant, pendant ou après l’acte, pas d’hormone à prendre pour qui que ce soit.

Comment ça marche ? Ça fonctionne comme un taser chimique, envoyant une charge électriques aux nageurs, annulant la leur et les rendant inertes. Imaginez Cartman à la sortie de vos couilles en train de crier “respectez mon autorité” en grillant tous les têtards qui passent.

Une bonne nouvelle donc, si on se sent l’âme d’un aventurier volontaire pour proposer ses bijoux de famille comme cobayes. Non je ne ferai pas de blague raciste sur le curry.

J’ai bien envie de me laisser tenter. Un voyage en Inde, 1000 balles. Si je me lance, je ferai un article ici pour détailler le moment où mes testicules vont devenir vertes, pourrir et se détacher. Promis.

flattr this!