Revue de presse Inno #9

Spécial PyCon Canada 2017 (Suite !)

Que retenir de la dernière PyCon Canada ? Quelques éléments de réponse avec les développeurs de l’équipe Innovation de Savoir-faire Linux !

Conférence ‘Double Click: Continue Building Better CLIs’

Par Kévin Barralon

Cette conférence donnée lors de la PyCon Canada visait à présenter Click, un package Python permettant de créer des CLIs (Commande Line Interface) en peu de lignes de code.

L’utilisation est simple et intuitive : la configuration d’une commande passe essentiellement par l’ajout de décorateurs à votre fonction.

Par exemple, voici une fonction simple chargée de répéter un nom passé en argument :

# hello.py
import click

@click.command()
@click.option('--count', default=1, type=int, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    for _ in range(count):
        click.echo(f'Hello {name}!') # Syntaxe de Python 3.6 !

if __name__ == '__main__':
    hello()

En quelques lignes de codes, vous avez créé une commande qui :

  • prend une option --count avec une valeur par défaut de 1 et dont le type exigé est un integer.
  • prend une option --name qui permet grâce à l’argument prompt passé dans votre décorateur de proposer à l’utilisateur de renseigner son nom.

Ces valeurs sont transmises directement aux paramètres count et name de la fonction décorée. Ci-dessous le code pour lancer la commande dans votre terminal :

python3 test.py --count=3

Your name: Casimir
Hello Casimir!
Hello Casimir!
Hello Casimir!

L’autre point intéressant (et pratique également !) est que si vous passez l’option --help à l’appel de votre fichier, vous obtenez l’affichage de la Docstring de votre fonction, ainsi que les informations pour chaque option fournies grâce à l’argument help passé dans vos décorateurs :

python3 hello.py --help

Usage: test.py [OPTIONS]

Simple program that greets NAME for a total of COUNT times.

Options:
--count INTEGER Number of greetings.
--name TEXT The person to greet.
--help Show this message and exit.

Plutôt que de passer des options à votre commande, vous pouvez également définir des arguments. Pour l’exemple :

@click.command()
@click.argument('filename')
def touch(filename):
    click.echo(filename)

Puis :

python3 touch.py foo.txt
foo.txt # Résultat

Comme vous pouvez le constater, les possibilités de Click sont vraiment nombreuses. Quelques unes en supplément pour l’occasion :

  • possibilité d’ajouter l’argument multiple=True dans votre décorateur @click.option qui vous renverra un tuple des options passées à l’appel de votre commande.
  • ajouter un callback en argument du @click.option qui changera le comportement de votre commande (par exemple pour définir des règles de validations sur-mesures).
  • de passer des variables d’environnement à votre décorateur (ex: envar="USERNAME").
  • définir un nombre limité ou illimité d’arguments qui retourneront un tuple.
  • ajouter une méthode File en guise de type dans votre décorateur (par exemple : @click.argument('input', type=click.File('rb'))) qui se chargera également d’ouvrir votre fichier et de le fermer automatiquement.

La liste de toutes les possibilités offertes par le package est disponible dans la documentation, très bien faite par ailleurs.

Bonus !

La conférence sur f-strings a vraiment motivé les troupes ! Voici un article de Maxime qui fait écho à celui de Sébastien la semaine dernière :

Les f-strings, qu’est-ce que ça mange en hiver?

Par Maxime Dupuis

Les chaînes de caractères-f, ou f-strings, sont une nouvelle façon de faire de l’interpolation en Python. Elles se définissent en mettant un f (ou F) en amont de la déclaration d’une chaîne de caractères : f'Ma chaîne f'.

Elles sont très semblable en comportement aux chaînes patrons (template strings) en JavaScript qui, elles, sont définies en utilisant le caractère `.

L’utilité des f-strings vient du fait qu’elles peuvent contenir des variables qui seront automatiquement interpolées avec les valeurs des variables locales définies du même nom :

>>> age = 42
>>> prenom = 'Maxime'
>>> f"Je m'appelle {prenom} et j'ai {age} ans"
"Je m'appelle Maxime et j'ai 42 ans"
>>> # L'utilisation d'une variable non-définie nous donnera une erreur de type NameError :
>>> f"{nondefini}"
Traceback (most recent call last):
File "", line 1, in
NameError: name 'nondefini' is not defined

Là où l’utilisation de chaînes de caractères-f devient intéressante est notamment du fait que ce type de chaînes est très rapide ! Si on les compare aux autres façons de créer des chaînes en Python, on a :

python3.6 -m timeit -c 'age=42; prenom="Maxime"; f"Mon nom est {prenom} et mon age est {age} ans"'
10000000 loops, best of 3: 0.172 usec per loop
python3.6 -m timeit -c 'age=42; prenom="Maxime"; "Mon nom est {prenom} et mon age est {age} ans".format(prenom=prenom, age=age)'
1000000 loops, best of 3: 0.714 usec per loop
python3.6 -m timeit -c 'age=42; prenom="Maxime"; "Mon nom est %s et mon age est %s ans" % (prenom, age)'
1000000 loops, best of 3: 0.283 usec per loop
python3.6 -m timeit -c 'age=42; prenom="Maxime"; "Mon nom est " + prenom + " et mon age est " + str(age) + " ans"'
1000000 loops, best of 3: 0.449 usec per loop
python3.6 -m timeit -c 'from string import Template; age=42; prenom="Maxime"; Template("Mon nom est $prenom et mon age est $age").substitute(prenom=prenom, age=age)'
100000 loops, best of 3: 8.75 usec per loop

Mais l’utilité des f-strings ne réside pas uniquement dans sa rapidité : Il est également possible d’appeler des fonctions, faire du traitement, et toutes autres choses :

>>> total = 10.0
>>> taxes = 1.15
>>> f'Total: {total + taxes}'
'Total: 11.15'
>>> prenom = 'Maxime'
>>> f'Mon nom est {prenom.upper()}'
'Mon nom est MAXIME'

Si cela vous intéresse et que vous n’avez pas encore découvert toutes les nouveautés que Python 3.6 peut vous offrir, consultez les notes de version : «What’s New In Python 3.6».

Mobilité

SwiftGen

Par Thibault Wittemberg

Lorsque nous développons une application iOS, nous avons régulièrement besoin d’accéder à des ressources. La façon traditionnelle pour les utiliser dans le code est de les instancier avec leurs identifiants (chaînes de caractères) :

let avatar = UIImage(named: ‘darthVader’) // gets the ‘darthVader’ image from the assets folder
let name = NSLocalizedString (‘darthVader’, comment: ‘’) // gets the localized string with the key ‘darthVader’ from the Localizable.strings file

Il en va de même pour les fonts, les storyboards et les couleurs.

Pour rappel, Swift se veut un langage assez strict sur la gestion des types et favorise la détection d’erreurs lors de la phase de compilation plutôt que lors de la phase d’exécution. Ceci étant, que se passe-t-il si l’une des ressources que l’on souhaite instancier n’est pas trouvée à l’exécution ? Puisque cette instantiation se base sur une chaine de caractères, elle est soumise à des erreurs (fautes de frappe par exemple).

La solution ? L’outil Swiftgen, qui nous permet de sécuriser cette manipulation :

  • Il évite les erreurs de frappes,
  • Il permet la complétion syntaxique,
  • Il assure que la ressource existe au moment de la compilation.

Son principe de fonctionnement est le suivant :

  • L’exécutable « Swiftgen » est installé sur le poste de développement (soit via Homebrew soit via CocoaPods),
  • Une phase de build custom lance cet exécutable lors de chaque compilation,
  • Swiftgen parcours les ressources du projet et génère le code Swift les représentant de façon « type safe ».

Les identifiants des ressources seront ainsi transformés en « enum » dont l’utilisation est bien plus sécurisée et facile. Notre exemple deviendrait :

let avatar = Asset.darthVader.image
let name = L10n.darthVader

Il est même possible de customiser les templates qui serviront à la génération du code si l’on souhaite appliquer un coding style différent de celui offert par défaut.

Lorsqu’il est combiné au framework « Reusable » (du même auteur), nous disposons d’outils quasiment indispensables (et que nous mettons en place systématiquement chez Savoir-faire Linux) et dont on souhaiterait disposer par défaut dans l’environnement de développement d’Apple.

Swiftgen est pensé pour être intégré à l’environnement d’intégration continue d’un projet (l’exécutable peut être embarqué dans une dépendance CocoaPods, évitant ainsi de l’installer sur la machine de build).

Contribution

Nouvelle version de savoirfairelinux/num2words 0.5.6

Par Ernesto Ortiz

Cinq mois depuis la version précédente de num2words v0.5.5, cinq mois vraiment actifs.

Beaucoup de nouveaux contributeurs ont apporté de grandes améliorations et ont ajouté un support pour de nouvelles langues !
Voici quelques-uns des nouveaux changements avec des « remerciements spéciaux » aux contributeurs !

  • Num2words a changé les conventions de codage pour suivre PEP8,
    La couverture du code a beaucoup augmenté et nous avons besoin de votre aide pour continuer à améliorer cela, alors regardez les problèmes,
  • Maintenant, nous pouvons utiliser d’autres convertisseurs to_currency, to_year, to_ordinal_num,
  • Merci à Tufan Kaynak d’avoir apporté son soutien à la localisation turque,
  • Merci à Jesús Leganés-Combarro d’avoir soutenu la localisation franco-algérienne,
  • Merci à Armin Oliya pour son soutien à la localisation néerlandaise,
  • Merci à Sergio Zholudov pour son soutien à la localisation ukrainienne,
  • Remerciements à Blaž Bregar pour son soutien à la localisation slovène,
  • Merci à Mārtiņš Šulcs d’avoir apporté de nombreuses améliorations au code de base, aux fonctionnalités de to_currency et plus encore !

Un merci spécial à tous ceux qui ont pris le temps de signaler de nouveaux problèmes, de faire une pull request et de partager leur temps dans ce projet !

Vous pouvez vérifier la nouvelle version dans :