Enfin des guides de packaging sur python.org

On peut chercher partout sur le Web, ça part toujours un peu dans tous les sens et beaucoup ont des solutions différentes.
C’est un peu comme les outils pour gérer le travail en équipe… ou la mise en production de Django : plein de solutions, et aucun n’est officiellement supportée.

Eh bien maintenant, c’est un petit pas pour Python, un grand pour les développeurs !
Il existe maintenant des guides de packaging sur python.org.

Cliquez ici pour tout savoir sur le packaging officiel dans Python :

Python Packaging User Guide

Edge : aussi mauvais qu’Internet Explorer ?

Ce qui suit est copié collé d’ici :

Microsoft fait une conférence pour promouvoir un de ses produits Azure.
Pendant la démonstration, Edge plante, plante et re-plante.
La personne en charge de la démonstration, lasse, télécharge puis installe Chrome, le navigateur de Google.
Tout cela sous les rires et les applaudissements de l’audience (un moment à retrouver vers 37:10 sur YouTube).

Python : liste : voir si tous les éléments sont identiques

Encore une petite idée prise ici : Astuces Python en anglais

>>> lst = ['a', 'a', 'a']

>>> len(set(lst)) == 1
True

>>> all(x == lst[0] for x in lst)
True

>>> lst.count(lst[0]) == len(lst)
True

Dans l’ordre, du plus « Pythonique » au moins « Pythonique »… mais paradoxalement, du moins efficace au plus efficace.
Utiliser count() est le plus rapide.

Mint et Ubuntu : une vitesse de clavier bien plus rapide que Windows

La vitesse de répétition du clavier est liée non pas au hardware (comme je l’ai cru pendant des années), mais au software, donc au système d’exploitation.

Mon ami Windows (« ami »… vous sentez l’ironie ?), qui est fait principalement pour les personnes qui pensent (à tort) qu’on est plus rapide avec une souris qu’avec un clavier, propose un délai avant de répéter les touches très long, même au minimum, et une vitesse de répétition plutôt lente, pour des personnes comme moi qui aiment aller vite.

Mon vrai ami Linux, lui, permet d’aller extrêmement vite, et c’est génial. Bon ok, il permet d’aller si vite qu’on peut faire des petites blagounettes à son camarade de classe. Alors Ubuntu a eu l’idée complètement débile (et je reste poli) de copier Windows et de limiter la vitesse de répétition, et le délai, à des temps très longs, qui se rapprochent de ceux de Windows.

Pourquoi brider tout cela ? Quel est l’intérêt de limiter sa voiture à 50km/h si elle peut aller à 200km/h (et que les autoroutes ne sont pas limitées !).

La solution : après avoir demandé ici sur stackoverflow, voici la réponse, je vous la mets en français : ouvrez un terminal et copiez-collez ce code :

Si vous êtes sur Linux en général

gsettings set org.gnome.settings-daemon.peripherals.keyboard repeat-interval 20

gsettings set org.gnome.settings-daemon.peripherals.keyboard delay 140

Si vous êtes sur Mint ou sur Ubuntu, autre solution

gsettings set org.cinnamon.settings-daemon.peripherals.keyboard repeat-interval 20

gsettings set org.cinnamon.settings-daemon.peripherals.keyboard delay 140

Et voilà. C’est le genre de choses, quand j’ai fini de coder toute la journée, et que je reviens sur Windows pour jouer un peu, qui fait que si je dois faire autre chose que jouer, je me mets à détester Windows et rebooter rien que pour écrire mes mails (au final je reste sur Mint parce que je ne vais pas re-rebooter pour rejouer…).

Dang Bader : dbader.org

Si vous souhaitez vous moderniser dans le monde Python et apprendre plein de petites astuces, je vous conseille de vous inscrire ici sur https://dbader.org/.

Voici quelques petites news que je résume et que je traduis en français :

Supprimer temporairement une exception

Il est possible de supprimer temporairement une exception en utilisant contextlib.suppress().

Exemple concret :
import contextlib
with contextlib.suppress(FileNotFoundError):
    os.remove('monfichier.tmp')

Voici l’équivalent du bon try/except des familles :

try:
    os.remove('monfichier.tmp')
except FileNotFoundError:
    pass

Méthodes de classe vs méthodes statiques

Le code parle de lui-même :

class MaClasse:
    def methode_normale(self):
        return 'instance method called', self

    @classmethod
    def methode_de_classe(cls):
        return 'class method called', cls

    @staticmethod
    def methode_statique():
        return 'static method called'

# Appels sur une instance :
# tout fonctionne :
>>> obj = MaClasse()
>>> obj.methode_normale()
('instance method called', )
>>> obj.methode_de_classe()
('class method called', )
>>> obj.staticmethod()
'static method called'

# Appels directs : voyez le résultat :
>>> MaClasse.methode_de_classe()
('class method called', )
>>> MaClasse.methode_statique()
'static method called'
>>> MaClasse.methode_normale()
TypeError:
    "unbound method methode_normale() must be called with MaClasse"
    "instance as first argument (got nothing instead)"

Désassembler un binaire Python

>>> def greet(name):
...     return 'Salut, ' + name + ' !'

>>> greet('Olivier')
'Salut, Olivier !'

>>> import dis
>>> dis.dis(greet)
2   0 LOAD_CONST     1 ('Salut, ')
    2 LOAD_FAST      0 (name)
    4 BINARY_ADD
    6 LOAD_CONST     2 ('!')
    8 BINARY_ADD
   10 RETURN_VALUE

100 livres Python pour tout le monde !

Pour toutes les personnes qui croient qu’on passe des jours entiers à écrire des bouquins pour les donner, changez d’endroit : oui ils sont payants… et c’est normal.

Bref, pour tous ceux qui veulent apprendre et payer pour avoir les meilleurs livres, écrits par les meilleurs, dans le domaine qui vous intéresse, vous avez tout ici : pythonbooks.org.

Sam Agnew bidouille le bon vieux Zelda à la PyCon 2017

Je vous laisse découvrir qui est Sam Agnew, mais dans la vidéo :

  • il fait un peu de LUA pour hacker et analyser le code de Zelda ;
  • il met en place le fait de discuter entre twitter et le code qui écrit en direct dans Zelda ;
  • cela écrit en direct dans Zelda pendant qu’on joue !

Enorme. Et en plus vous verrez du code sur comment lire les notifications twitter en quelques lignes de Python

Django / jQuery / Select2 / autocomplete

Voici un tutoriel sur quelque chose qui m’a pris plusieurs jours à réaliser « proprement » et encore, ça n’est pas si propre, mais c’est le mieux que je puisse faire actuellement, en termes de rapport « propreté / temps passé » raisonnable.

Voici l’idée : je veux qu’on puisse commencer à taper quelques lettres dans un champ, et que ce dernier aille demander en AJAX/JSON si jamais il y a des tags « connus ». Si c’est le cas, le retour renvoie une liste, qui s’ouvre, et l’utilisateur peut choisir dans cette liste en descendant avec les flèches. S’il n’y a aucun retour, l’utilisateur peut aller au bout, et envoyer son formulaire, et c’est là que la magie intervient : plus tard, s’il revient sur le formulaire, il pourra taper quelques lettres, et on lui proposera le champ en question ! Mieux ! Il peut séparer les champs par une virgule, et donc taper plusieurs choix. Exactement comme lorsqu’on commence à entrer le nom d’un destinataire sur gmail. La classe non ?

J’ai voulu faire cela pour plein de tags, mais le client pour lequel je faisais cela n’a pas réellement compris l’intérêt et m’a demandé de faire une liste de choix « fixes » que l’utilisateur peut cocher. Bref, no comment.

Donc voici comment j’ai procédé (je ne dis pas que c’est la meilleure façon, il y en a sûrement d’autres, mais vous pouvez vous en inspirer) :
– création d’un modèle Tag qui a la langue (selon les langues, pas le même Tag) :
– dériver un type de champ de base Django forms.TypedChoiceField afin de permettre une liste de choix, mais qui sera valide de deux manières : il faut surcharger les méthodes qui convertissent les valeurs de retour de ce champ, afin :
    – soit d’essayer de lire une liste d’entiers, séparés par des virgules, qui sont les ids des champs,
    – soit pour chaque champ qui ne peut pas être converti en entier, appeler une méthode « custom_tag« , qui va ajouter le tag en base de données puis renvoyer un entier = pk du tag ajouté
– créer un Widget custom dans lequel on passera une classe spéciale destinée au JavaScript qui recherchera cette classe
– en JavaScript (mon ami de toujours, qui fait que je passe 20% du temps sur Django à m’amuser et 80% du temps sur l’habillage Web à rager et/ou bidouiller), faire une routine qui va chercher les widgets définis au-dessus et y appliquer le select2 tel que défini dans la documentation
– faire une vue destinée de recherche qui prend un paramètre, et renvoie les résultats trouvés, c’est pour remplir les demandes d’AJAX de select2. Elle doit renvoyer un tableau « résultat » et une variable « total » qui est simplement le « length » de « résultat ».

C’est tout… enfin tout… on se comprend !

Mais en pratique, une fois que tout est mis en place, il suffit de déclarer dans n’importe quel formulaire un champ ainsi, et on aura un champ entièrement dynamique, qui s’auto-alimentera avec le temps. Extrêmement pratique :


    a = _("Emails:")
    emails = TagTypedChoiceField(
        label=a, required=False,
        custom_tag=add_tag_to_languages,
        widget=Select2Widget(attrs={
            'title': a,
            'placeholder': _("type an email"),
            'multiple': 'multiple',
            'data-select2-json': reverse_lazy(
                'co_branding_json_tags_emails',
                kwargs={'company': 'ubisoft'}),
            'class': 'form-control form-control select2'}),
        error_messages=e,
        choices=self.get_list_tags(Tag.TYPE_EMAIL))

Python : on n’arrête jamais d’apprendre….

J’avais rendu compatible Python 3 + dernière version de Django authomatic, un outil qui gère la connexion avec plein d’API, sachant que les plus importantes sont google et facebook.

J’avais fait ce code :

    @property
    def params(self):
        # (!) Olivier Pons ! REQUEST removed
        a = QueryDict('', mutable=True)
        a.update(self.request.GET)
        a.update(self.request.POST)
        retour = {}
        for key, value in a.iterlists():
            if len(value) > 1:
                retour[key] = value
            else:
                retour[key] = value[0]
        return retour

J’étais tout content et tout fier de le partager. Ils ont écrit « problème corrigé ».
Et leur solution :

    @property
    def params(self):
        params = {}
        params.update(self.request.GET.dict())
        params.update(self.request.POST.dict())
        return params

J’ai encore plein de choses à apprendre en Python on dirait…

Tiens tiens… Python vs Php…

Depuis plus de quinze ans, j’essaie d’expliquer que des fontes grosses, claires et visibles sont plus efficaces que tout le reste et le Web est allé dans ce sens il y a à peine quinze ans…

Depuis plus de dix ans, je prédis que la domotique va devenir extrêmement importante et omniprésente, et on commence à peine à parler d’objets connectés…

Il y a quinze ans j’ai eu un pressentiment très fort avec Php et j’ai écrit énormément de choses avec jusqu’à acquérir un bon niveau… car je savais que Php était l’avenir !

…jusqu’à il y a cinq ans où j’ai bien senti que tout ralentissait… Je me suis penché sur Python / Django, et j’ai eu le même enthousiasme qu’avec Php il y a quinze ans. C’est pas tous les jours qu’on a ça ! Bref. Tout ça pour dire que :

Python dépasse pour la première fois Php en nombre total de questions sur Stackoverflow.

J’avais eu un entretien de prestation pour Symfony chez… je ne cite pas, mais ils se reconnaîtront pour la description que je fais ensuite : j’avais eu le malheur de leur expliquer que non seulement Symfony c’est une usine à gaz, mais en plus qu’il était dépassé et que Django plus Python était mieux à tous les niveaux. Que n’avais-je pas dit, quel sacrilège ! Mais bon, les deux CTOs ne connaissaient même pas LoL alors que là aussi je prédis depuis plus de cinq ans qu’il y a de plus en plus d’argent à se faire dans le monde des claviers / et du gaming…

J’aimerais bien revoir ces deux CTOs… pour voir s’ils me riraient encore au nez comme ils l’avaient fait… comme si j’étais le dernier des crétins… mais la nature humaine étant ce qu’elle est, il est toujours très difficile – voire impossible pour certains – de dire humblement : « j’avoue, je m’étais trompé »… peut-être qu’ils en seraient capables, je ne les connais pas assez pour m’avancer.

Bref : j’ai toujours prédit les bonnes tendances : Delphi à l’époque, puis Php, puis des concepts comme les commandes de repas en lignes, et maintenant Python et je ne me suis jamais trompé en 25 ans… et hop, une de plus !

J’ai encore une autre grosse tendance pour laquelle je suis sûr que c’est l’avenir, et je n’en parle pas car je suis en train de développer une application dessus… il y a bien sûr une interaction avec un site développé en Python / Django, bien sûr !

Bonne journée à tous 🙂