tag:linuxfr.org,2005:/tags/design/publicLinuxFr.org : les contenus étiquetés avec « design »2024-02-05T23:13:09+01:00/favicon.pngtag:linuxfr.org,2005:Bookmark/78972024-02-05T23:13:09+01:002024-02-05T23:13:09+01:00Appel à contributions pluridisciplinaires - Privacy Research Day le 4 juin 2024 à Paris<a href="https://www.cnil.fr/fr/appel-contributions-pluridisciplinaires-informatique-sciences-sociales-design-et-droit-privacy">https://www.cnil.fr/fr/appel-contributions-pluridisciplinaires-informatique-sciences-sociales-design-et-droit-privacy</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/134826/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/dovik/liens/appel-a-contributions-pluridisciplinaires-privacy-research-day-le-4-juin-2024-a-paris#comments">ouvrir dans le navigateur</a>
</p>
dovikhttps://linuxfr.org/nodes/134826/comments.atomtag:linuxfr.org,2005:News/417582023-11-17T11:31:16+01:002023-11-18T08:08:22+01:00Comparaison critique de systèmes d'invite de commandeLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<div><p>Cet article a été écrit à l’occasion de <a href="https://github.com/liquidprompt/liquidprompt/releases/tag/v2.2.0-rc.1">l’imminence de la sortie de la version 2.2 de Liquid Prompt</a> et vous aurez l’occasion de pouvoir en discuter avec son auteur lors des journées <a href="https://capitoledulibre.org/">Toulouse Capitole du Libre</a>, qui proposera une conférence sur <a href="https://cfp.capitoledulibre.org/cdl-2023/talk/KYLR9C/">Liquid Prompt : repenser en profondeur le design du prompt shell</a>.</p>
<h2 id="toc-tldr-résumé">TL;DR: résumé</h2>
<p>Si vous utilisez la ligne de commande, vous gagneriez à utiliser un bon système d’invite de commande (« prompt ») au lieu de la configuration par défaut. Parmi les sept systèmes de prompt les plus connus, certains sont mieux conçus et d’autres prennent mieux en charge certaines fonctionnalités.</p>
<p>Mes principales conclusions sont les suivantes :</p>
<ul>
<li>Si vous recherchez le système qui offre la meilleure expérience globale à l’utilisateur, vous devriez probablement utiliser Liquid Prompt.</li>
<li>Si la faible latence est plus importante pour vous que les fonctionnalités, vous devriez miser sur PowerLevel10k.</li>
<li>Si vous êtes un développeur qui jongle en permanence avec plusieurs jeux d’outils, Starship semble être la meilleure option pour vous.</li>
</ul>
<p>Cet article est divisé en deux parties principales : la première introduit le sujet et présente les principales évaluations ; la deuxième partie entre dans les détails des designs et des fonctionnalités. Enfin, la conclusion donne des conseils sur le choix d’un prompt et propose quelques idées sur l’avenir des systèmes de prompts.</p>
</div><ul></ul><div><h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li>
<a href="#toc-introduction">Introduction</a><ul>
<li><a href="#toc-quest-ce-quun-prompt">Qu’est-ce qu’un prompt ?</a></li>
<li><a href="#toc-les-concurrents">Les concurrents</a></li>
<li><a href="#toc-ce-dont-vous-avez-besoin-cest-du-design-de-linformation">Ce dont vous avez besoin, c’est du design de l’information</a></li>
<li><a href="#toc-toutes-les-fonctionnalit%C3%A9s-ne-naissent-pas-%C3%A9gales">Toutes les fonctionnalités ne naissent pas égales</a></li>
</ul>
</li>
<li>
<a href="#toc-design">Design</a><ul>
<li><a href="#toc-si-vous-vous-sentez-sexy-vous-avez-lair-sexy">Si vous vous sentez sexy, vous avez l’air sexy</a></li>
<li><a href="#toc-un-segment-pour-les-gouverner-tous">Un segment pour les gouverner tous</a></li>
<li>
<a href="#toc-la-force-r%C3%A9side-dans-la-diversit%C3%A9-pas-dans-la-similitude">La force réside dans la diversité, pas dans la similitude</a><ul>
<li><a href="#toc-la-simplicit%C3%A9-ne-passe-pas-%C3%A0-l%C3%A9chelle">La simplicité ne passe pas à l’échelle</a></li>
<li><a href="#toc-d%C3%A9claration-contre-innovation">Déclaration contre Innovation</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#toc-fonctionnalit%C3%A9s">Fonctionnalités</a><ul>
<li><a href="#toc-les-fonctionnalit%C3%A9s-essentielles-sont-essentielles">Les fonctionnalités essentielles sont essentielles</a></li>
<li><a href="#toc-prendre-soin-de-lenvironnement">Prendre soin de l’environnement</a></li>
<li><a href="#toc-il-est-temps">Il est temps</a></li>
</ul>
</li>
<li>
<a href="#toc-conclusion">Conclusion</a><ul>
<li><a href="#toc-certains-sont-out">Certains sont <em>out</em></a></li>
<li><a href="#toc-certains-sont-in">Certains sont <em>in</em></a></li>
</ul>
</li>
<li><a href="#toc-vers-le-service-et-au-del%C3%A0">Vers le service et au-delà</a></li>
</ul>
<h2 id="toc-introduction">Introduction</h2>
<p>Avertissement : je suis l’auteur original de Liquid Prompt. Au début, j’ai fait cette étude approfondie pour savoir si je devais continuer à m’intéresser à Liquid Prompt ou passer à un autre système. Je vais essayer d’expliquer ici pourquoi je pense toujours que c’est l’un des meilleurs systèmes de prompt du marché.</p>
<p>Tous les systèmes de prompt comparés ici sont de bons logiciels libres, je me concentrerai donc ici sur l’utilité de leurs fonctionnalités, plutôt que de m’attarder sur la qualité du code ou la facilité d’installation.</p>
<h3 id="toc-quest-ce-quun-prompt">Qu’est-ce qu’un prompt ?</h3>
<p>Il existe deux types d’informaticien·ne·s : celleux qui utilisent la ligne de commande et celleux qui sont à la retraite. Même les développeurs qui adoptent des interfaces de développement très intégrées disposent d’une sorte de terminal dans certains panneaux de leur IDE. Qu’on le veuille ou non, l’interpréteur de commandes fait partie intégrante de la vie quotidienne de la plupart des personnes qui attendent de leur ordinateur qu’il travaille pour elles.</p>
<p>L’interpréteur de commandes (le « shell ») a accès à de nombreuses informations sur l’ordinateur. Et la plupart de ces informations concernent l’état actuel de l’environnement de travail, ce qui est du plus haut intérêt pour l’utilisateur. Cependant, par défaut, le shell n’affiche que très peu d’informations, à moins que vous ne les demandiez expressément. En outre, le seul endroit de l’écran disponible pour l’affichage permanent de quoi que ce soit est le prompt.</p>
<p>Le prompt est cette chaine de caractères affichée juste devant la ligne où vous tapez vos commandes. Dans la configuration par défaut la plus courante, elle n’affiche que trois informations : l’utilisateur, le nom d’hôte et le chemin d’accès <code>user@hostname:path $</code>.</p>
<p>Mais il peut en afficher davantage ! C’est l’objectif des systèmes de prompt. Ces prompts (pour faire court) ajoutent en fait beaucoup d’informations à cette partie de la ligne de commande. Par exemple, la fonctionnalité la plus courante est d’afficher l’état du dépôt Git dans lequel se trouve l’utilisateur.</p>
<h3 id="toc-les-concurrents">Les concurrents</h3>
<p>Comme c’est souvent le cas avec les logiciels destinés aux utilisateurs chevronnés, le marché est très fragmenté : il existe une tonne de prompts disponibles. Beaucoup de gens semblent aimer programmer leur prompt à partir de zéro et le déposer sur GitHub.</p>
<p>Dans le cadre de cet article, je n’ai pris en compte que sept prompts. Parmi les plus populaires, d’après le nombre d’articles de fans trouvés par Google et d’après les étoiles sur GitHub :</p>
<ul>
<li>
<a href="https://github.com/romkatv/powerlevel10k">PowerLevel10k</a>, le plus populaire,</li>
<li>
<a href="https://github.com/starship/starship">Starship</a>, celui programmé en Rust, et <a href="https://github.com/spaceship-prompt/spaceship-prompt">Spaceship</a>, son origine (dans ce qui suit, les deux sont considérés comme un seul système, étant donné leur similarité, mais vous voudrez probablement utiliser Starship de toute façon),</li>
<li>
<a href="https://github.com/powerline/powerline">Powerline</a>, qui fait des lignes de statut,</li>
<li>
<a href="https://github.com/sindresorhus/pure">Pure</a>, le système minimal au succès surprenant,</li>
<li>
<a href="https://ohmyposh.dev">Oh-My-Posh</a>, le système portable,</li>
<li>
<a href="https://github.com/nojhan/liquidprompt">Liquid Prompt</a>, le plus ancien (historiquement parlant).</li>
</ul>
<p>Il convient de noter que le nombre d’étoiles n’est pas nécessairement lié à l’âge du logiciel. Par exemple, Liquid Prompt a été lancé en 2010, tandis que Powerlevel* a été lancé en 2015 et Starship en 2019.</p>
<h3 id="toc-ce-dont-vous-avez-besoin-cest-du-design-de-linformation">Ce dont vous avez besoin, c’est du design de l’information</h3>
<p>La raison d’être d’un prompt c’est qu’il est utile d’avoir un accès immédiat à l’état actuel du système. Le fait de voir un changement d’état à l’endroit même où l’utilisateur regarde habituellement est un très bon retour d’information sur ses actions. Mais, bien entendu, ce retour d’information ne doit pas entraver le travail de l’utilisateur.</p>
<p>Les états doivent être choisis et affichés en fonction de leur importance pour le travail de l’utilisateur. Plus précisément, un bon prompt est un prompt qui est :</p>
<ul>
<li>
<strong>focus</strong> : il vise les états qui sont réellement utiles à l’utilisateur au cours d’une session de travail,</li>
<li>
<strong>transparent</strong> : il n’entraîne pas de friction avec le processus de travail de l’utilisateur,</li>
<li>
<strong>ciblé</strong> : il vise des états qui peuvent changer d’eux-mêmes ou être changés par l’utilisateur,</li>
<li>
<strong>mesuré</strong> : il tient compte du fait que certains états changent moins souvent que d’autres (et évite ainsi d’être une simple collection d’états qui ne changent que rarement),</li>
<li>
<strong>accentué</strong> : il rend plus visible le retour d’information concernant les changements d’état les plus importants, tout en ne polluant pas la visibilité des états stables/anecdotiques,</li>
<li>
<strong>configurable</strong> : il est facile d’adapter immédiatement l’affichage des informations, si nécessaire.</li>
</ul>
<p>En d’autres termes, un bon système d’alerte doit être bien conçu.</p>
<p>Mon évaluation de la conception générale des candidats est résumée dans le tableau suivant :</p>
<table>
<thead>
<tr>
<th>Prompt</th>
<th>Focus</th>
<th>Transparent</th>
<th>Ciblé</th>
<th>Mesuré</th>
<th>Accentué</th>
<th>Configurable</th>
</tr>
</thead>
<tbody>
<tr>
<td>Liquid Prompt</td>
<td>🌟🌟🌟</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>🌟🌟🌟</td>
<td>🌟🌟🌟</td>
<td>🌟🌟🌟</td>
</tr>
<tr>
<td>PowerLevel10k</td>
<td>⭐⭐</td>
<td>🌟🌟🌟</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
</tr>
<tr>
<td>Oh-My-Posh</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>⭐</td>
<td>⭐⭐</td>
</tr>
<tr>
<td>Pure</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>⭐</td>
<td>⭐⭐</td>
</tr>
<tr>
<td>*ship</td>
<td>⭐</td>
<td>⭐⭐</td>
<td>⭐</td>
<td>⭐</td>
<td>⭐</td>
<td>⭐⭐</td>
</tr>
<tr>
<td>Powerline</td>
<td>⭐</td>
<td>⭐⭐</td>
<td>⭐</td>
<td>⭐</td>
<td>⭐</td>
<td>⭐</td>
</tr>
</tbody>
</table>
<p>La section « design » de l’article (voir ci-dessous) explique plus en détail pourquoi.</p>
<h3 id="toc-toutes-les-fonctionnalités-ne-naissent-pas-égales">Toutes les fonctionnalités ne naissent pas égales</h3>
<p>Quels types de fonctionnalités nos six candidats proposent-ils ? On peut considérer six catégories (de la plus importante à la moins importante) :</p>
<ul>
<li>
<strong>l’essentiel du shell</strong> : les fonctionnalités que l’on trouve habituellement dans un prompt classique (chemin, utilisateur, codes de sortie…), qui sont utiles au quotidien (tâches, capteurs, intégration de multiplexeurs…), ou qui sont généralement considérées comme importantes (thèmes…).</li>
<li>la <strong>gestion de version</strong> : Git, Mercurial, etc.</li>
<li>
<strong>environnements</strong> : détection de configuration dynamique (virtual env, variables shell, conteneurs…).</li>
<li>
<strong>versions des outils</strong> : version actuelle d’outils spécifiques (langages de programmation, chaines de construction, outils…).</li>
<li>
<strong>fonctions diverses</strong> : fonctions liées au shell considérées comme moins importantes (réseau, titre du terminal, liens hypertextes…).</li>
<li>
<strong>services</strong> : services fonctionnant en permanence, en ligne ou sur la machine (musique, météo…).</li>
</ul>
<p>Ces catégories sont délimitées en fonction de l’utilisation principale du terminal :</p>
<ul>
<li>Les fonctionnalités de la catégorie « l’essentiel du shell » sont celles dont vous aurez le plus souvent besoin, quoi que vous fassiez dans votre terminal.</li>
<li>Si vous êtes programmeur, vous porterez une attention particulière aux catégories <em>gestion de version</em> et <em>environnements</em>.</li>
<li>Si vous êtes développeur, la catégorie <em>version des outils</em> vous intéressera également.</li>
<li>Si vous faites de l’administration système, la catégorie <em>divers</em> peut contenir des fonctionnalités marginalement intéressantes.</li>
<li>Si vous avez besoin de fonctionnalités dans la catégorie des services, vous avez probablement mal compris ce qu’est une interface de ligne de commande, ou vous recherchez une barre d’état (ce qu’un système de prompt peut être).</li>
</ul>
<p>Mon évaluation de la prise en charge globale de chaque ensemble de fonctionnalités est résumée dans le tableau suivant :</p>
<table>
<thead>
<tr>
<th>Prompt</th>
<th>Essentiels</th>
<th>Gestion de version</th>
<th>Environnements</th>
<th>Versions d’outils</th>
<th>Divers</th>
<th>Services</th>
</tr>
</thead>
<tbody>
<tr>
<td>Liquid Prompt</td>
<td>🌟🌟🌟</td>
<td>🌟🌟🌟</td>
<td>🌟🌟🌟</td>
<td>⭐</td>
<td>⭐⭐</td>
<td>_</td>
</tr>
<tr>
<td>*ship</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>🌟🌟🌟</td>
<td>🌟🌟🌟</td>
<td>⭐</td>
<td>_</td>
</tr>
<tr>
<td>PowerLevel10k</td>
<td>⭐⭐</td>
<td>⭐</td>
<td>🌟🌟🌟</td>
<td>⭐⭐</td>
<td>⭐⭐</td>
<td>⭐</td>
</tr>
<tr>
<td>Oh-My-Posh</td>
<td>⭐</td>
<td>⭐⭐</td>
<td>⭐</td>
<td>⭐⭐</td>
<td>⭐</td>
<td>⭐⭐</td>
</tr>
<tr>
<td>Powerline</td>
<td>⭐</td>
<td>⭐</td>
<td>⭐</td>
<td>_</td>
<td>⭐⭐</td>
<td>🌟🌟🌟</td>
</tr>
<tr>
<td>Pure</td>
<td>⭐</td>
<td>⭐</td>
<td>_</td>
<td>_</td>
<td>_</td>
<td>_</td>
</tr>
</tbody>
</table>
<p>La section « fonctionnalités » ci-dessous explique en détail comment certains prompts prennent en charge certaines de ces catégories.</p>
<h2 id="toc-design">Design</h2>
<p>Chaque système de prompt possède une culture sous-jacente, née de son histoire, qui transparait dans sa conception.</p>
<p>Par exemple, Powerline a eu un impact considérable sur l’adoption de caractères supplémentaires dans les polices « patchées ». Liquid Prompt a ciblé, dès le début, des caractéristiques proches du shell lui-même, tout en mettant l’accent sur le design. D’un autre côté, PowerLevel10k a été conçu pour être aussi rapide que possible. Étonnamment, Starship a également commencé avec la promesse d’être rapide, bien qu’il ne se rapproche même pas de PowerLevel10k (un bon exemple de la façon dont l’impact des langages est surestimé). Il rassemble cependant une grande communauté, qui à son tour fournit des tonnes d’outils de support. A titre de contre-exemple, Pure a démarré sur la promesse d’être ascétique en termes de fonctionnalités, et s’en est tenu à cette idée.</p>
<h3 id="toc-si-vous-vous-sentez-sexy-vous-avez-lair-sexy">Si vous vous sentez sexy, vous avez l’air sexy</h3>
<p>En ce qui concerne le design, les prompts candidats peuvent être répartis en trois catégories :</p>
<ul>
<li>ceux qui soutiennent que le plus simple est le mieux (Pure et *ship),</li>
<li>ceux qui aiment le look classique des « chevrons » (Powerline et Oh-My-Posh),</li>
<li>ceux qui accordent une attention particulière au design (Liquid Prompt et PowerLevel10k).</li>
</ul>
<p>L’équipe de Pure, par exemple, affirme très clairement qu’il est « joli et minimal ». Et par joli, elle entend « livré avec le parfait caractère de prompt » (sic, c’est « ❯ ») et utilise des couleurs pastel. Son aspect par défaut est assez clairement partagé avec Starship, même s’il permet de configurer certains thèmes en utilisant également le look chevrons. Dans la documentation de cette catégorie de design de prompts, il n’y a pas beaucoup d’explications sur la raison pour laquelle les choses sont affichées (ou non).</p>
<p>La deuxième catégorie suit plus ou moins la même philosophie, en pensant seulement que ce qui est joli, c’est d’avoir un arrière-plan coloré au lieu d’un avant-plan, d’utiliser une police de caractères patchée pour séparer joliment les segments, et d’utiliser des icônes partout.</p>
<p>Bien entendu, vous trouverez des systèmes permettant une certaine configuration des icônes ou des couleurs, afin de reproduire l’un ou l’autre style (Starship et Oh-My-Posh proposent des thèmes dans les deux styles, Liquid Prompt et PowerLevel10k ont des thèmes reproduisant les deux, fonctionnalités comprises).</p>
<p>La dernière catégorie, cependant, va plus loin dans les détails lorsqu’il s’agit d’expliquer pourquoi elle montre les choses de telle ou telle manière, et permet plus généralement un ensemble plus varié de thèmes.</p>
<p>PowerLevel10k va jusqu’à fournir un assistant de configuration pour construire le thème que vous préférez, en combinant plusieurs caractéristiques (nombre de lignes, caractère de séparation, etc.) Cependant, en dehors des capacités techniques impressionnantes, l’approche globale de la conception consiste à afficher ce qui doit être affiché sous forme de segments colorés flashy avec des icônes.</p>
<p>Liquid Prompt fournit des thèmes prêts à l’emploi et dispose de l’ensemble le plus diversifié. Certains de ses thèmes n’ont pas d’équivalent chez les autres systèmes, et changent beaucoup de la « série de segments » de tous les autres prompts.</p>
<h3 id="toc-un-segment-pour-les-gouverner-tous">Un segment pour les gouverner tous</h3>
<p>Un exemple intéressant de l’importance de l’approche de design est la façon dont Powerline et Liquid Prompt indiquent à l’utilisateur qu’il se trouve dans une session multiplexée (ce sont les deux seuls à disposer de cette fonctionnalité). Les multiplexeurs de terminaux sont des systèmes qui permettent d’avoir plusieurs sessions permanentes sur une machine, et de les détacher/attacher à volonté. Les plus connus sont screen et tmux.</p>
<p>Powerline affichera un segment coloré indiquant le nombre de clients tmux attachés à la session. Liquid Prompt a divisé son support en deux informations différentes : il affichera d’abord le nombre de sessions détachées, et colorera ensuite les crochets entourant le noyau de l’invite (nom d’utilisateur, hôte, chemin) s’il se trouve actuellement dans une session multiplexeur. L’indice visuel est subtil, mais si l’on y réfléchit, il est logique, car c’est « autour » de ce qui change avec la connexion. Il n’est pas nécessaire d’utiliser beaucoup d’espace pour rappeler à l’utilisateur cette information, qui sera constante au cours d’une session de travail.</p>
<p>Un autre exemple est la façon dont Starship et Liquid Prompt indiquent que sudo est actif. Starship affichera une icône (d’un assistant), tandis que Liquid Prompt changera la couleur de la marque d’invite, près de l’endroit où l’utilisateur tape des commandes, puisque les informations d’identification sudo peuvent avoir un impact considérable sur leur effet.</p>
<p>Le même type de différence se produit lors d’une connexion SSH : Starship affiche une autre icône, à côté du nom d’hôte. Liquid Prompt affiche le nom d’hôte avec sa propre couleur. Les deux peuvent être configurés pour n’afficher le nom d’hôte que lors d’une connexion via SSH. Oh-My-Posh affiche un segment avec une icône, et PowerLevel10k affiche à la fois le nom d’utilisateur et le nom d’hôte sous SSH, mais n’indique pas si l’utilisateur a été commuté localement, comme les autres.</p>
<p>La même approche s’applique à l’affichage des droits d’écriture ou du support X11 : Liquid Prompt change la couleur d’un caractère existant, tandis que les autres prompts ont tendance à ajouter un nouveau segment/une nouvelle icône.</p>
<p>Vous pouvez commencer à voir la tendance ici : la plupart des prompts ont été conçues avec l’idée qu’un état atomique doit être ajouté à la liste des états, ou non. En d’autres termes, ils ont tendance à ajouter un nouveau segment (et/ou une nouvelle icône) à la liste des segments. Liquid Prompt est peut-être le seul à avoir réfléchi à l’idée de maximiser la réutilisation des indices visuels et à les positionner avec précaution.</p>
<p>Essentiellement, la plupart des systèmes de prompts donnent la priorité à la question « saviez-vous que ? » (par exemple, « saviez-vous que vous avez la version 3.14 de Python ? ») tandis que Liquid Prompt donne la priorité à la question « vous devriez noter que » (par exemple, « vous devriez noter qu’il est temps de git pull »).</p>
<h3 id="toc-la-force-réside-dans-la-diversité-pas-dans-la-similitude">La force réside dans la diversité, pas dans la similitude</h3>
<p>Bien entendu, la plupart des systèmes de prompts ont en commun le fait que de nombreux éléments sont configurables. Un utilisateur peut réorganiser ce qui est affiché et changer complètement le <em>look and feel</em> de son message. C’est flagrant quand on regarde la diversité des thèmes compatibles.</p>
<p>Ici, Oh-My-Posh a fait beaucoup d’efforts pour promouvoir un très grand nombre de thèmes. En plus des prompts *ship, ils utilisent un langage de configuration déclaratif qui prétend être le moyen le plus simple d’assembler un nouveau thème.</p>
<p>Je vois deux problèmes à cette idée, qui semble être très répandue parmi les informaticiens, même loin de la configuration des invites (pensez aux systèmes de construction, par exemple) :</p>
<ol>
<li>la simplicité ne passe pas à l’échelle,</li>
<li>elle introduit trop de contraintes et limite l’innovation.</li>
</ol>
<h4 id="toc-la-simplicité-ne-passe-pas-à-léchelle">La simplicité ne passe pas à l’échelle</h4>
<p>Le premier problème est relativement évident si vous essayez d’interpréter une configuration de prompt complète, par exemple cette configuration aléatoire de <a href="https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/themes/atomicBit.omp.json">Oh-My-Posh/atomicBit</a> :</p>
<pre><code><#ffffff>[</>{{ .HEAD }}{{ if .Staging.Changed }}<#00AA00> \u25cf {{ .Staging.String }}</>{{ end }}{{ if .Working.Changed }}<#D75F00> \u25cf {{ .Working.String }}</>{{ end }}<#ffffff>]-</>"
</code></pre>
<p>Je ne fais même pas de sélection ; j’ai choisi celui-ci parce qu’il est en fait plus simple que le modèle par défaut. Que fait-elle en réalité ? Je ne suis pas sûr de vouloir faire les efforts nécessaires pour le comprendre. Par contre, je peux très bien voir l’intérêt de faire la même chose en script shell, avec des instructions if/then communément comprises, au lieu d’une soupe de parenthèses en notation polonaise inversée.</p>
<p>Je pense que, dans Liquid Prompt, cela ressemblerait à (non testé, juste ici pour donner une idée) :</p>
<pre><code> LP_COLOR_CHANGES=$GREEN
LP_COLOR_COMMITS=$MAGENTA
lp_git=""
if _lp_vcs_head_status; then
lp_git+="$lp_vcs_head_status"
fi
if _lp_vcs_unstaged_lines; then
lp_git+="$LP_COLOR_CHANGES ○+$lp_vcs_unstaged_i_lines/-$lp_vcs_unstaged_d_lines"
fi
if _lp_vcs_commits_off_remote; then
lp_git+="$LP_COLOR_COMMITS ○+$lp_vcs_commit_ahead$NO_COL/$LP_COLOR_COMMITS_BEHIND-$lp_vcs_commit_behind$NO_COL"
fi
</code></pre>
<p>Notez que la logique d’affichage (ou non) est découplée du schéma de coloration. Cela ne vous semble peut-être pas plus simple, mais au moins vous pouvez le lire sans avoir mal à la tête, et il me semble que vous pouvez l’adapter plus facilement à un plus grand nombre de cas d’utilisation, et qu’il a une granularité plus fine sur l’information qu’il peut afficher.</p>
<p>Maintenant, tout comme il est très difficile de concevoir de bons systèmes de <em>build</em> (qui sont un mélange de programmes déclaratifs et impératifs), c’est un problème notoirement difficile que de concevoir un système de configuration (pour les mêmes raisons). Ne soyez donc pas trop durs avec les développeurs, il n’y a pas de solution miracle.</p>
<h4 id="toc-déclaration-contre-innovation">Déclaration contre Innovation</h4>
<p>Le deuxième problème se manifeste dans la diversité des thèmes que les gens peuvent produire dans la pratique. La <a href="https://ohmyposh.dev/docs/themes">liste des thèmes disponibles pour Oh-My-Posh</a> est impressionnante. Il ne fait aucun doute que l’approche déclarative incite les gens à créer des thèmes. Toutefois, lorsque l’on parcourt la longue liste, il est évident qu’ils se ressemblent tous. Il ne faut pas s’attendre à des designs très différents avec ce prompt, ce ne sont que des listes de segments colorés.</p>
<p>Ici, Liquid Prompt présente une différence intéressante. Vous pouvez reconfigurer les thèmes avec l’approche classique <code>clé=valeur</code>, mais plus généralement, les thèmes sont de purs scripts shell qui <em>arrangent</em> les informations disponibles. Cela permet toutes sortes de subtilités, et plus généralement d’afficher n’importe quelle information sous n’importe quelle forme, pour n’importe quelle combinaison d’états, ce qui est totalement impossible à faire de manière efficace avec une approche déclarative.</p>
<p>Par ailleurs, l’approche utilisée par Liquid Prompt permet de combiner facilement des configurations (appelées <em>presets</em>). Ainsi, vous pouvez utiliser un thème, puis utiliser un <em>preset</em> pour modifier certaines de ses couleurs (par exemple si vous êtes daltonien).</p>
<p>L’impact de cette approche est visible dans la <a href="https://github.com/liquidprompt/liquidprompt/wiki/Themes">diversité des thèmes proposés par Liquid Prompt</a>. Il ne s’agit pas seulement de changer les couleurs et les icônes, mais de modifier l’ensemble de l’expérience utilisateur. Par exemple, le thème <a href="https://github.com/nojhan/lp-gitcrux">GitCrux</a> reprend le thème par défaut, mais ajoute des indications visuelles sur les commandes Git qui peuvent être utiles compte tenu de l’état du référentiel actuel. Pour ce thème, Liquid Prompt est plutôt un fournisseur de données, un* moteur de thème* qu’il utilise à ses propres fins.</p>
<p>On peut également voir une certaine innovation dans le <a href="https://github.com/nojhan/lp-dotmatrix">thème DotMatrix</a>, où certaines informations sont affichées non pas avec des icônes/segments, mais simplement avec des espaces orientés. Par exemple, dans Dotmatrix, lorsque vous êtes connecté via SSH, un espace entouré de flèches vers la gauche est inséré entre le type de terminal (c’est-à-dire une session purement textuelle ou graphique) et l’utilisateur. Il en va de même pour indiquer une session multiplexée : un espace est inséré entre l’utilisateur et le nom d’hôte. Le thème utilise la même idée pour le contrôle de version, et pour indiquer que des commits attendent d’être poussés (flèches espacées vers la gauche — là où se trouve le serveur) ou retirés (flèches espacées vers la droite — là où <em>vous</em> vous trouvez).</p>
<p>Ce type de conception nécessiterait une refonte complète du moteur de thème dans d’autres systèmes de prompt, mais ne requiert qu’un développeur motivé connaissant un peu de shell avec Liquid Prompt.</p>
<h2 id="toc-fonctionnalités">Fonctionnalités</h2>
<p>Le design, c’est bien, mais en fin de compte, les logiciels doivent avoir les fonctionnalités qui comptent. Vous savez, genre avoir quelque chose à afficher.</p>
<p>Pour entrer dans les détails des fonctionnalités, j’ai dressé la liste de toutes les fonctionnalités de chaque système d’invite, puis j’ai vérifié lesquels les prenaient également en charge. J’ai ensuite évalué la qualité de cette prise en charge :</p>
<ol>
<li>aucune prise en charge,</li>
<li>prise en charge et conception de base,</li>
<li>bon ensemble de fonctionnalités, mais ergonomie médiocre,</li>
<li>bonnes fonctionnalités et ergonomie.</li>
</ol>
<p>Les résultats sont présentés dans le tableau suivant, et les réflexions sur ce que cela signifie dans les sections suivantes.</p>
<p>Dans ce tableau, les nombres dans les cellules indiquent le niveau de qualité de la fonctionnalité. La popularité est la somme des niveaux de la ligne. Les lignes « support » correspondent à la somme des niveaux de la colonne, pour chaque catégorie. Les catégories sont triées de haut en bas en fonction de leur popularité moyenne. Les projets sont triés de gauche à droite, en fonction de leur score de support dans la section des essentiels du shell.</p>
<p>Les sections suivantes abordent certains des ensembles de fonctionnalités présentés dans ce tableau et les comparaisons entre les systèmes d’invite.</p>
<p><a href="https://camo.githubusercontent.com/a39022857261f072e32a7954f28c7c12e3be340ff38742d747034aba682e405a/68747470733a2f2f6c697175696470726f6d70742e72656164746865646f63732e696f2f656e2f6c61746573742f5f696d616765732f70726f6d7074735f636f6d70617269736f6e2e737667">Tableau de support des principaux systèmes de prompts</a></p>
<h3 id="toc-les-fonctionnalités-essentielles-sont-essentielles">Les fonctionnalités essentielles sont essentielles</h3>
<p>Le shell est un logiciel assez ancien. Vieux dans le bon sens du terme : il a été testé et mis à jour pour atteindre un niveau de qualité qui permet de travailler efficacement. De plus, il est fort probable que vous y passiez la plupart de votre temps à travailler sur quelques types de tâches : développeur, sysadmin, devops, analyste de données, ou n’importe quelle variante de ces familles. Quel que soit votre travail, il vous serait probablement utile de connaitre (et d’utiliser) un ensemble de fonctionnalités pour utilisateurs « chevronnés ». Si vous avez lu cet article jusqu’ici, il y a de fortes chances que vous soyez à l’aise avec le shell et que vous soyez un utilisateur expérimenté, ou que vous aspiriez à l’être.</p>
<p>La tâche principale du shell est d’afficher une sorte d’état lié à la machine, au shell/à l’environnement ou au répertoire courant. Les états les plus importants sont soit ceux fournis par le shell lui-même, soit ceux qui peuvent gêner votre travail (probablement l’état de l’ordinateur lui-même). Ces fonctionnalités sont essentielles, et elles devraient avoir une place de premier ordre dans l’invite.</p>
<p>Dans le tableau ci-dessus, j’ai séparé les fonctionnalités liées à la machine et au shell en deux catégories : les fonctionnalités essentielles et les fonctionnalités diverses. La catégorie « divers » contient les fonctionnalités liées au réseau, car elles sont notoirement criblées de toutes sortes d’écueils. J’ai également placé la fonction « dir stack » (les commandes <code>pushd</code> et <code>popd</code>) dans cette catégorie, car elle n’est pas fréquemment utilisée par les utilisateurs. C’est dommage, car il s’agit d’une fonctionnalité puissante. J’y ai également placé <a href="https://direnv.net/">direnv</a>. Bien qu’il ne s’agisse pas d’une fonctionnalité principale de l’interpréteur de commandes (il s’agit après tout d’un logiciel externe), elle est très proche d’une fonctionnalité principale de l’interpréteur de commandes et j’ai pensé qu’elle méritait plus que la catégorie « contexte de développement ».</p>
<p>Dans notre tableau, les prompts sont classés en fonction de leur capacité à prendre en charge ces fonctionnalités essentielles. Il devrait être évident en voyant le tableau que Liquid Prompt a de loin le meilleur support. Les autres prompts sont bien moins équipés, Starship a un bon support, bien qu’avec des choix ergonomiques discutables (comme nous l’avons vu dans la section <em>Design</em>), suivi par Oh-My-Posh et Powerlevel10k, tous deux avec un support moyen et une ergonomie générale moyenne. Pure a un support médiocre de par sa conception même, ce qui ne peut lui être reproché, mais si vous êtes un utilisateur expérimenté plutôt qu’un ascète, vous pourriez avoir une opinion peu amène quant à ce choix.</p>
<h3 id="toc-prendre-soin-de-lenvironnement">Prendre soin de l’environnement</h3>
<p>Pour les tâches du développeur, il est essentiel de connaitre le contexte logiciel dans lequel vous travaillez. Bien entendu, il faut diviser ce contexte en fonction de la prise en charge de tel ou tel logiciel. Il existe deux catégories générales à cet égard : les logiciels qui manipulent la configuration actuelle de votre session (<em>environnements virtuels</em> proprement dits) et la version actuelle de tout outil lié à la tâche en cours (<em>toolset</em>). Si vous jouez avec des conteneurs toute la journée, vous allez adorer ces fonctionnalités (une fois que vous aurez trouvé un moyen d’y installer un prompt).</p>
<p>En ce qui concerne la catégorie « environnements », le support est assez faible parmi les principaux concurrents (Liquid Prompt, *ship, et PowerLevel10k), Starship ayant le meilleur support global et la meilleure ergonomie. Oh-My-Posh est un peu en retrait, et Powerline presque nulle part. Pure, comme d’habitude, a décidé de ne pas supporter ce genre de choses.</p>
<p>Mais le vrai clivage est dans la catégorie <em>toolset</em>, avec Pure et Powerline qui ont décidé de ne pas supporter ce genre de fonctionnalités, Liquid Prompt qui ne supporte que deux outils, et *ship, Oh-My-Posh et PowerLevel10k qui misent à fond dessus. Parmi eux, Starship est le vainqueur incontesté, avec une liste impressionnante d’outils pris en charge.</p>
<p>Cependant, cette catégorie a tendance à avoir une expérience utilisateur très limitée, chaque fonctionnalité étant réduite à « afficher simplement l’icône & la version ». Pour la plupart d’entre elles (comme les langages de programmation), cela peut être facilement compris, puisqu’il n’y a pas grand-chose à signaler de toute façon. Pour d’autres (comme les systèmes de <em>build</em>), je pense que les prompts peuvent mieux faire.</p>
<p>Dans l’ensemble, je ne suis pas complètement convaincu que cette catégorie de fonctionnalités soit suffisamment importante pour remplir le prompt avec des icônes et des chiffres, mais puisque Starship semble le juger crucial, il y a surement des cas d’usage pour cela.</p>
<p>En passant, on peut voir que Starship se dit « minimal » sur sa page d’accueil, ce qui ne correspond pas tout à fait au niveau de support qu’il a pour ces <em>toolsets</em>… mais je m’éloigne du sujet.</p>
<h3 id="toc-il-est-temps">Il est temps</h3>
<p>La rapidité du prompt — c’est-à-dire le temps nécessaire pour l’afficher après l’exécution d’une commande — est une caractéristique qui fait l’objet de discussions constantes de la part des utilisateurs. </p>
<p>Vous pourriez penser qu’il s’agit d’une fonctionnalité très importante et qu’aucun compromis ne doit être fait à ce sujet. Mon point de vue est légèrement différent.</p>
<p>L’interpréteur de commandes est une interface de commande. C’est-à-dire que vous tapez, entrez, regardez le résultat de la commande, puis réfléchissez à la suivante. Il y a de fortes chances que vous ne tapiez jamais frénétiquement <em>Entrée</em> après une commande qui a été très rapide à produire son résultat. Vous tapez, vous réfléchissez, vous tapez la commande suivante. Vous n’avez pas besoin de la latence d’un jeu de tir à la première personne.</p>
<p>Bien sûr, il existe un seuil au-delà duquel la latence de l’affichage commence à produire des frictions. L’auteur de PowerLevel10k a <a href="https://github.com/romkatv/zsh-bench#how-fast-is-fast">discuté en détail de ce qui est impossible à distinguer d’une absence de latence</a>, ce qui vous donne une idée de la <em>plus petite</em> latence que vous pouvez remarquer, mais pas tout à fait celle que vous tolèreriez dans une session typique.</p>
<p>De ce point de vue, il y a un vainqueur incontestable : PowerLevel10k est incroyablement rapide. Il est allé très loin pour réduire sa latence, et a réussi quelques tours de force techniques très impressionnants, comme l’affichage asynchrone d’éléments lents, grâce à une « évaluation paresseuse ». Cela explique aussi en grande partie pourquoi il ne supporte que Zsh.</p>
<p>Je comprends l’intérêt de réduire les frictions liées à l’attente de la frappe ; mais je pense que l’on surestime souvent l’intérêt d’une latence ultra-faible, quand le prix à payer est que l’information intéressante peut ne pas être affichée au moment où l’on a besoin d’y penser.</p>
<p>Un fait intéressant concernant la latence est la curieuse affirmation de Starship à ce sujet. Sur sa page d’accueil, il affirme que Starship est « incroyablement rapide », <em>parce qu’il est programmé en Rust</em>, qui « apporte la meilleure vitesse, toutes catégories ». Cette affirmation ne tient pas vraiment la route face à la vraie vie. Non seulement Starship est beaucoup plus lent que PowerLevel10k, mais il est également plus lent que Liquid Prompt — tous deux écrits en pur script shell — dans la plupart des cas d’utilisation simple ! Oh-My-Posh — écrit en Go — ne se risque pas à faire le même genre d’affirmation, par exemple.</p>
<p><a href="https://github.com/romkatv/zsh-bench#prompt">Romkatv explique pourquoi dans son étude</a> :</p>
<blockquote>
<p>« Starship est implémenté en tant que binaire externe, il doit donc payer le prix d’au moins un fork+exec supplémentaire pour chaque commande par rapport aux prompts natifs de zsh. Un seul fork+exec ne peut pas expliquer le décalage élevé dont Starship fait preuve, alors qu’est-ce qui se passe ? Dans les conditions de référence, Starship clone 158 fois ! C’est coûteux. »</p>
</blockquote>
<p>C’est peut-être contre-intuitif pour la plupart des informaticiens peu expérimentés, mais le langage est loin d’être l’aspect le plus important de la programmation.</p>
<h2 id="toc-conclusion">Conclusion</h2>
<p>Si vous entrez suffisamment dans les détails, vous pourrez probablement toujours argumenter que tel ou tel système de prompt est le meilleur pour tel ou tel utilisation très spécifique. Grâce aux informations fournies dans cet article, j’espère que vous pourrez décider par vous-même. Maintenant, si vous préférez une évaluation globale, je pense qu’il est clair qu’il y a quelques systèmes qui conviennent mieux à certaines utilisations majeures.</p>
<h3 id="toc-certains-sont-out">Certains sont <em>out</em>
</h3>
<p>Tout d’abord, je pense que l’on peut affirmer sans risque de se tromper qu’il y a très peu d’intérêt à choisir Pure, si ce n’est pour signaler que vous vous positionnez comme étant aligné avec ses valeurs (c’est-à-dire que vous croyez au « one size does fit all », ou « je n’utilise pas vraiment le shell de toute façon »). La plupart des autres candidats ont des thèmes qui reproduisent son (absence) de fonctionnalité, et proposent même d’avoir le même style, mais en supportant plus de cas d’utilisation (d’autres systèmes de version, plus d’alertes sur l’état de l’ordinateur, etc.).</p>
<p>De même, Powerline n’est probablement pas très utile en dehors de son marché principal, qui est de produire des lignes d’état. Et même les autres prompts peuvent généralement fournir beaucoup plus d’informations pour ce faire, à l’exception de certains services en ligne spécifiques.</p>
<p>En outre, Spaceship peut également être mis de côté en toute sécurité, étant donné qu’il a été en pratique remplacé par Starship, qui prend en charge davantage de fonctionnalités (à moins que vous n’ayez besoin d’une identification très spécifique de l’ensemble d’outils, voir le tableau ci-dessus).</p>
<p>Après avoir longuement hésité, j’ai décidé de mettre également de côté Oh-My-Posh. Cela n’a pas été facile, étant donné qu’il est assez bon sur presque tous les critères d’évaluation que j’ai développés dans cet article, ce qui est déjà une belle réussite. Mais c’est là que réside son défaut : il n’est que moyen partout.</p>
<h3 id="toc-certains-sont-in">Certains sont <em>in</em>
</h3>
<p>Il nous reste donc Liquid Prompt, Starship et PowerLevel10k.</p>
<p>PowerLevel10k est le plus populaire (selon la métrique des étoiles de Github) et est le choix évident si vous vous souciez plus de la latence que des fonctionnalités. Il a un support plutôt moyen de chaque catégorie de fonctionnalités, mais a travaillé très dur pour fournir une latence ultra-faible entre deux commandes. Je ne suis pas sûr que cela vaille la peine de réduire les fonctionnalités et la portabilité, étant donné que je suis très rarement ennuyé par de grandes latences lorsqu’elles se produisent dans d’autres systèmes de prompts, mais votre appréciation peut différer (chacun ses fixettes). Il a néanmoins quelques choix de design très modernes et innovants, que j’aime beaucoup, même si j’ai l’impression qu’ils sont plus des paillettes techniques impressionnantes qu’un design vraiment utile ancré dans l’expérience de l’utilisateur.</p>
<p>Starship n’est pas loin derrière en termes d’étoiles, et brille évidemment par son soutien à l’identification des versions d’outils. L’utilité de ce système pour vous dépend de la fréquence à laquelle vous jonglez avec des tâches de développement complexes. En tant qu’ingénieur de recherche, je jongle constamment avec un ensemble de tâches très diverses, et je suis donc plus attiré par des systèmes qui couvrent bien les fonctionnalités de base du shell que par l’énumération des versions, mais je suppose que cela peut être débattu. Quoi qu’il en soit, si vous avez besoin de la portabilité vers PowerShell, Starship est un choix sûr. Gardez également à l’esprit que ses revendications en matière de latence sont exagérées.</p>
<p>Bien qu’il soit le plus ancien de tous, Liquid Prompt est aussi le moins connu. Cependant, il offre le meilleur support des fonctionnalités essentielles. Je dirais aussi qu’il a prêté plus d’attention à son design, permettant des prompts très denses, par exemple. Il est également très configurable, ce qui a permis de créer des thèmes très originaux en termes d’expérience utilisateur. C’est probablement le prompt qui servira le plus grand nombre de cas d’utilisation et d’utilisateurs, en particulier les personnes souhaitant apprendre le shell en expérimentant toutes ses fonctionnalités.</p>
<h2 id="toc-vers-le-service-et-au-delà">Vers le service et au-delà</h2>
<p>Cet article vous a donné quelques opinions basées sur une analyse à un moment donné d’un marché qui continue d’évoluer. En tant que tel, il ne constitue qu’un point dans le temps et peut très bien être rendu obsolète par un changement soudain dans l’activité de l’un ou l’autre projet.</p>
<p>Au cours de l’histoire des systèmes de prompts, tous ont découplé la collecte des données et leur affichage. Et la collecte des données est l’opération la plus couteuse, qui retient toute l’attention lorsque le temps d’exécution doit être optimisé. PowerLevel10k, par exemple, a complètement découplé les deux opérations, qui s’exécutent désormais dans des coroutines parallèles. Son auteur a même mis en place un <a href="https://github.com/romkatv/gitstatus">service de status pour Git</a> totalement précurseur, qui permet d’accélérer considérablement les prompts.</p>
<p>Une autre tendance intéressante consiste à découpler la collecte des données en éléments logiciels atomiques, comme les plugins. Starship n’aurait probablement pas eu son impressionnant support d’outils s’il n’y avait pas eu sa base de code propre et modulaire.</p>
<p>En même temps, Liquid Prompt a fait de gros efforts pour permettre aux thèmes de décider de ce qu’il faut afficher et (plus important) comment et quand l’afficher, allant plus loin que de considérer les thèmes comme de simples configurations.</p>
<p>Je pense que ces trois tendances convergent vers l’idée d’un <em>service</em> d’invite, où le <em>serveur</em> est responsable de la collecte et de la mise en cache des données, tandis que le <em>client</em> est responsable de l’articulation de ces informations d’une manière qui soit utile à l’utilisateur (et pas seulement en les affichant).</p>
<p>L’idée a été explorée ici et là, à ma connaissance surtout par les développeurs de Liquid Prompt, avec des projets tels que <a href="https://github.com/dolmen/angel-PS1">AngelPS1</a> de Dolmen et <a href="https://github.com/Rycieos/most">MOST</a> de Rycieos. Si vous aimez ça, le mainteneur de Liquid Prompt a lancé <a href="https://github.com/liquidprompt/liquidprompt/discussions/786">une conversation sur les « moteurs de thèmes »</a>, n’hésitez pas à la rejoindre et à participer à l’élaboration de l’avenir des systèmes de prompts !</p>
</div><div><a href="https://linuxfr.org/news/comparaison-critique-de-systemes-d-invite-de-commande.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/133912/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/comparaison-critique-de-systemes-d-invite-de-commande#comments">ouvrir dans le navigateur</a>
</p>
nojhanYsabeau 🧶 🧦gUIhttps://linuxfr.org/nodes/133912/comments.atomtag:linuxfr.org,2005:Bookmark/71462023-09-14T15:25:00+02:002023-09-15T07:44:49+02:00OpenMoji : Open source emojis for designers, developers and everyone else!<a href="https://openmoji.org/">https://openmoji.org/</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/133297/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/gilcot/liens/openmoji-open-source-emojis-for-designers-developers-and-everyone-else#comments">ouvrir dans le navigateur</a>
</p>
Gil Cot ✔https://linuxfr.org/nodes/133297/comments.atomtag:linuxfr.org,2005:Bookmark/46022022-04-26T21:57:36+02:002022-04-26T21:57:36+02:00“The REAL Ergonomic Keyboard Endgame!” - How To Design & Make A Totally Custom Keyboard<a href="https://invidious.snopyta.org/watch?v=UKfeJrRIcxw">https://invidious.snopyta.org/watch?v=UKfeJrRIcxw</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/127578/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/anonyme/liens/the-real-ergonomic-keyboard-endgame-how-to-design-make-a-totally-custom-keyboard#comments">ouvrir dans le navigateur</a>
</p>
Anonymehttps://linuxfr.org/nodes/127578/comments.atomtag:linuxfr.org,2005:Diary/402352022-04-17T03:14:11+02:002022-04-17T03:14:11+02:00Sunday Python Pattern : Une machine à état toute simpleLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li>
<ul>
<li><a href="#toc-une-impl%C3%A9mentation-toute-simple">Une implémentation toute simple</a></li>
<li><a href="#toc-un-premier-exemple-simple">Un premier exemple simple</a></li>
<li><a href="#toc-un-exemple-plus-concret">Un exemple plus concret</a></li>
<li><a href="#toc-conclusion">Conclusion</a></li>
</ul>
</li>
</ul>
<p>Bonjour Nal,</p>
<p>Il y a un "design pattern" que je réutilise souvent dans différent langages pour découper la logique métier en plusieurs petit bout de code bien séparés et facilement testable.</p>
<p>Ce design pattern s'apparente très fortement à une machine à état :</p>
<ul>
<li>on a la machine a état qui possède un contexte (des données qui seront manipulées et modifiées par l'exécution de l'algorithme)</li>
<li>chaque état va agir sur ce contexte et retourner l'état suivant à exécuter, ou <code>None</code> si on est arrivé au bout de l'algorithme</li>
</ul>
<p>Ici, les transitions d'un état vers un autre sont modelées par le code : l'état actuel retourne l'état suivant</p>
<p>Pour les tests c'est assez simple : étant donné un contexte, quel est le type de retour de mon état ?</p>
<h3 id="toc-une-implémentation-toute-simple">Une implémentation toute simple</h3>
<p>Allez, un peu de code Python pour imager la chose… Au passage, j'en ai fait une librairie disponible sur <a href="https://github.com/linkdd/easy_fsm">Github</a>.</p>
<p>Tout d'abord, on va définir le contexte :</p>
<pre><code class="python"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">TypeVar</span>
<span class="n">Context</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s2">"Context"</span><span class="p">)</span></code></pre>
<p>Le contexte peut être tout et n'importe quoi, mais on va explicitement le nommer pour la suite (comme ça, des outils tels que <strong><a href="http://mypy-lang.org/">mypy</a></strong> vont pouvoir vérifier que l'on fait correctement les choses).</p>
<p>Ensuite, on va définir ce qu'est un état :</p>
<pre><code class="python"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Protocol</span><span class="p">,</span> <span class="n">Generic</span><span class="p">,</span> <span class="n">Optional</span>
<span class="k">class</span> <span class="nc">State</span><span class="p">(</span><span class="n">Protocol</span><span class="p">,</span> <span class="n">Generic</span><span class="p">[</span><span class="n">Context</span><span class="p">]):</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">:</span> <span class="n">Context</span><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="s2">"State[Context]"</span><span class="p">]</span>
<span class="k">raise</span> <span class="ne">NotImplementedError</span></code></pre>
<p><strong>NB :</strong> Les guillemets sur le type de retour sont nécessaires, car <code>State</code> n'est pas encore complètement défini à cet endroit (cela ne pose aucun problème à mypy).</p>
<p>Ici, c'est l'équivalent Python d'une interface générique, en TypeScript cela donnerait :</p>
<pre><code class="typescript"><span class="kr">interface</span> <span class="nx">State</span><span class="o"><</span><span class="nx">Context</span><span class="o">></span> <span class="p">{</span>
<span class="nx">run</span><span class="p">(</span><span class="nx">context</span>: <span class="kt">Context</span><span class="p">)</span><span class="o">:</span> <span class="nx">State</span><span class="o"><</span><span class="nx">Context</span><span class="o">></span> <span class="o">|</span> <span class="kc">null</span>
<span class="p">}</span></code></pre>
<p>C'est ce que l'on va utiliser par la suite pour implémenter les différentes étapes de notre algorithme.</p>
<p>Enfin, on peut définir notre machine à état :</p>
<pre><code class="python"><span class="k">class</span> <span class="nc">StateMachine</span><span class="p">(</span><span class="n">Generic</span><span class="p">[</span><span class="n">Context</span><span class="p">]):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">:</span> <span class="n">Context</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="n">context</span>
<span class="k">def</span> <span class="nf">run_from</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">state</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">State</span><span class="p">[</span><span class="n">Context</span><span class="p">]]):</span>
<span class="k">while</span> <span class="n">state</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">state</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">)</span></code></pre>
<p>Et c'est tout. Tant que l'on a un état a exécuter, on continu. C'est l'état qui contrôle le déroulement de l'algorithme.</p>
<h3 id="toc-un-premier-exemple-simple">Un premier exemple simple</h3>
<p>Prenons un exemple tout simple, calculer une <a href="https://fr.wikipedia.org/wiki/Conjecture_de_Syracuse">suite de syracuse</a> :</p>
<pre><code class="python"><span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span><span class="p">,</span> <span class="n">field</span>
<span class="nd">@dataclass</span>
<span class="k">class</span> <span class="nc">Stats</span><span class="p">:</span>
<span class="n">altitude</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">fly_time</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">suite</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">list</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">ComputeNextNumber</span><span class="p">(</span><span class="n">State</span><span class="p">[</span><span class="n">Stats</span><span class="p">]):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">n</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">n</span> <span class="o">=</span> <span class="n">n</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">:</span> <span class="n">Stats</span><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="n">State</span><span class="p">[</span><span class="n">Stats</span><span class="p">]]:</span>
<span class="n">context</span><span class="o">.</span><span class="n">altitude</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">altitude</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">n</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">fly_time</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">context</span><span class="o">.</span><span class="n">suite</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">n</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">n</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">n</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="n">ComputeNextNumber</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">n</span> <span class="o">//</span> <span class="mi">2</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">ComputeNextNumber</span><span class="p">(</span><span class="mi">3</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Syracuse</span><span class="p">(</span><span class="n">StateMachine</span><span class="p">[</span><span class="n">Stats</span><span class="p">]):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">Stats</span><span class="p">())</span>
<span class="k">def</span> <span class="nf">compute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">n</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="bp">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">run_from</span><span class="p">(</span><span class="n">ComputeNextNumber</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
<span class="n">fsm</span> <span class="o">=</span> <span class="n">Syracuse</span><span class="p">()</span>
<span class="n">fsm</span><span class="o">.</span><span class="n">compute</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="k">assert</span> <span class="n">fsm</span><span class="o">.</span><span class="n">context</span><span class="o">.</span><span class="n">altitude</span> <span class="o">==</span> <span class="mi">16</span>
<span class="k">assert</span> <span class="n">fsm</span><span class="o">.</span><span class="n">context</span><span class="o">.</span><span class="n">fly_time</span> <span class="o">==</span> <span class="mi">6</span>
<span class="k">assert</span> <span class="n">fsm</span><span class="o">.</span><span class="n">context</span><span class="o">.</span><span class="n">suite</span> <span class="o">==</span> <span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span></code></pre>
<p>L'entièreté de l'algorithme réside dans la classe <code>ComputeNextNumber</code>.</p>
<p>Dans cet exemple, le type associé à <code>Context</code> est <code>Stats</code> (grâce à <code>State[Stats]</code> et <code>StateMachine[Stats]</code>), et mypy sera en mesure de le vérifier.</p>
<h3 id="toc-un-exemple-plus-concret">Un exemple plus concret</h3>
<p>Le second exemple représente un cas plus concret, si on essayait de parser une requête HTTP ?</p>
<p>Pour info, une requête HTTP est composée de :</p>
<ul>
<li>une ligne de requête (version du protocole, verbe HTTP, URL)</li>
<li>zéro ou plusieurs en-têtes</li>
<li>une ligne vide</li>
<li>le corps de la requête</li>
</ul>
<p>Par exemple :</p>
<pre><code>POST /hello HTTP/1.1
Host: example.com
world
</code></pre>
<p><strong>NB :</strong> Dans les exemples de code suivant, je vais omettre le détail de l'implémentation pour se focaliser sur l'utilisation de ce design pattern.</p>
<p>Je vois ici 3 étapes :</p>
<ol>
<li>lire la ligne de requête</li>
<li>lire une ligne d'en-tête</li>
<li>lire le corps de la requête</li>
</ol>
<p>En vérité, il y a une 4è étape qui peut intervenir à plusieurs endroits, pour la gestion d'erreur.</p>
<p>Lançons nous dans le code :</p>
<pre><code class="python"><span class="k">class</span> <span class="nc">HTTPContext</span><span class="p">:</span>
<span class="c1"># ...</span>
<span class="k">class</span> <span class="nc">ParseRequestLine</span><span class="p">(</span><span class="n">State</span><span class="p">[</span><span class="n">HTTPContext</span><span class="p">]):</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">:</span> <span class="n">HTTPContext</span><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="n">State</span><span class="p">[</span><span class="n">HTTPContext</span><span class="p">]]:</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span> <span class="c1"># EOF</span>
<span class="k">return</span> <span class="n">UnexpectedError</span><span class="p">(</span><span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"EOF"</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">verb</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parse_request_line</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ParseHeaderLine</span><span class="p">(</span><span class="n">verb</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">protocol</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="k">return</span> <span class="n">UnexpectedError</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_parse_request_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
<span class="c1"># ...</span>
<span class="k">class</span> <span class="nc">ParseHeaderLine</span><span class="p">(</span><span class="n">State</span><span class="p">[</span><span class="n">HTTPContext</span><span class="p">]):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">verb</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">url</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">protocol</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">headers</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">verb</span> <span class="o">=</span> <span class="n">verb</span>
<span class="bp">self</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="n">url</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span> <span class="o">=</span> <span class="n">protocol</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">:</span> <span class="n">HTTPContext</span><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="n">State</span><span class="p">[</span><span class="n">HTTPContext</span><span class="p">]]:</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span> <span class="c1"># EOF</span>
<span class="k">return</span> <span class="n">UnexpectedError</span><span class="p">(</span><span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"EOF"</span><span class="p">))</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="c1"># delete \r\n</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span>
<span class="k">return</span> <span class="n">ReadBody</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">verb</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">url</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">header_name</span><span class="p">,</span> <span class="n">header_val</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parse_header_line</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="k">return</span> <span class="n">UnexpectedError</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="n">header_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">header_val</span>
<span class="k">return</span> <span class="bp">self</span> <span class="c1"># MaximumDepthRecursion avoided!!!!</span>
<span class="k">def</span> <span class="nf">_parse_header_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
<span class="c1"># ...</span>
<span class="k">class</span> <span class="nc">ReadBody</span><span class="p">(</span><span class="n">State</span><span class="p">[</span><span class="n">HTTPContext</span><span class="p">]):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">verb</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">url</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">protocol</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">headers</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">verb</span> <span class="o">=</span> <span class="n">verb</span>
<span class="bp">self</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="n">url</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span> <span class="o">=</span> <span class="n">protocol</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">:</span> <span class="n">HTTPContext</span><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="n">State</span><span class="p">[</span><span class="n">HTTPContext</span><span class="p">]]:</span>
<span class="n">body</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">context</span><span class="o">.</span><span class="n">set_request_info</span><span class="p">(</span>
<span class="n">verb</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">verb</span><span class="p">,</span>
<span class="n">url</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">url</span><span class="p">,</span>
<span class="n">protocol</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="p">,</span>
<span class="n">body</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="k">class</span> <span class="nc">UnexpectedError</span><span class="p">(</span><span class="n">State</span><span class="p">[</span><span class="n">HTTPContext</span><span class="p">]):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> <span class="ne">Exception</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">err</span> <span class="o">=</span> <span class="n">err</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">:</span> <span class="n">HTTPContext</span><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="n">State</span><span class="p">[</span><span class="n">HTTPContext</span><span class="p">]]:</span>
<span class="n">context</span><span class="o">.</span><span class="n">set_error_info</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">None</span></code></pre>
<p>Dans cet exemple, on voit tout de suite les avantages :</p>
<ul>
<li>on a du code récursif sans limite de récursion, en effet, on quitte la fonction avant de re-rentrer dedans, donc la pile d'appel n'est pas surchargée</li>
<li>chaque étape de l'algorithme est bien séparée, on évite ainsi une fonction gigantesque</li>
<li>une gestion d'erreur plutôt simple et sans <code>goto</code>, en effet il suffit de retourner l'état qui va traiter l'erreur</li>
<li>facile à tester, on va pouvoir "mocker" le <code>HTTPContext</code> et vérifier le type de retour de la méthode <code>run()</code> de chaque étape</li>
</ul>
<h3 id="toc-conclusion">Conclusion</h3>
<p>Permettre à une fonction de retourner ce que l'appellant doit exécuter ensuite est un pattern très pratique, surtout quand il est question de changement de spec. Imaginons que la syntaxe de notre requête HTTP change, ici seul le code métier devra être revu, et en aucun cas le code qui l'appelle.</p>
<p>Le code qui appelle notre algorithme est entièrement piloté par notre algorithme au final (c'est nous qui lui disons quoi faire ensuite). J'ai simplifié pas mal de code métier dans différent projet en utilisant ce concept, que cela soit en Elixir, en Go, en Python, ou en TypeScript (je serais bien curieux de voir ce que cela donne en Rust).</p>
<p>Et toi Nal ? Tu en as des pattern sympa comme ça ?</p>
<ul>
<li>implémentation Python : <a href="https://github.com/linkdd/easy_fsm">easy_fsm</a>
</li>
</ul>
<div><a href="https://linuxfr.org/users/linkdd/journaux/sunday-python-pattern-une-machine-a-etat-toute-simple.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/127498/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/linkdd/journaux/sunday-python-pattern-une-machine-a-etat-toute-simple#comments">ouvrir dans le navigateur</a>
</p>
David Delassushttps://linuxfr.org/nodes/127498/comments.atomtag:linuxfr.org,2005:Diary/398012021-06-10T11:09:52+02:002021-06-10T11:09:52+02:00CPU Ex0166 Design graphique dans les pratiques de la scienceLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p><strong>Dans cette <em>release</em> de la série <a href="https://cpu.dascritch.net/serie/Bio%20is%20the%20new%20Black"><em>Bio is the new black</em></a></strong> : Des instruments scientifiques, une objectivité féministe, des images qui hantent la science, la science qui hante le design…<br>
Nous recevons <a href="http://koyre.ehess.fr/index.php?3041"><strong>Anne-Lyse Renon</strong>, enseignante-chercheuse en design</a>.</p>
<p><strong>Écoute libre</strong>, podcasts, liens documentaires et vos commentaires : <a href="https://cpu.pm/0166">https://cpu.pm/0166</a></p>
<p><strong>Chapitres :</strong><br>
- <a href="https://cpu.dascritch.net/post/2021/06/10/Paillasse-du-design-%3A-H%C3%A9riter-de-nos-images">Paillasse du design : Hériter de nos images</a><br>
- <a href="https://cpu.dascritch.net/post/2021/06/10/How-to-%3A-Repr%C3%A9senter-ce-que-l%E2%80%99on-regarde">How to : Représenter ce que l’on regarde</a><br>
- <a href="https://cpu.dascritch.net/post/2021/06/10/Anne-Lyse-Renon%2C-enseignante-chercheuse-en-design">Version longue de cette interview</a></p>
<p>Voilà un sujet étrangement dans la suite de nos 3 précédentes émissions, et la semaine prochaine aussi.</p>
<p>Tenez-vous prêts : un enregistrement sur Toulouse en public concernant la programmation est en cours de planification d'ici fin Juin. </p>
<div><a href="https://linuxfr.org/users/dascritch/journaux/cpu-ex0166-design-graphique-dans-les-pratiques-de-la-science.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/124556/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/dascritch/journaux/cpu-ex0166-design-graphique-dans-les-pratiques-de-la-science#comments">ouvrir dans le navigateur</a>
</p>
Da Scritchhttps://linuxfr.org/nodes/124556/comments.atomtag:linuxfr.org,2005:Bookmark/29532021-04-15T09:13:24+02:002021-04-15T09:13:24+02:00France : Système de Design de l'État, uniformisation graphique des sites administratifs<a href="https://systeme-de-design.gouv.fr/">https://systeme-de-design.gouv.fr/</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/123965/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/ysabeau/liens/france-systeme-de-design-de-l-etat-uniformisation-graphique-des-sites-administratifs#comments">ouvrir dans le navigateur</a>
</p>
Ysabeau 🧶 🧦https://linuxfr.org/nodes/123965/comments.atomtag:linuxfr.org,2005:Diary/394752020-12-03T11:10:02+01:002020-12-03T11:10:02+01:00CPU Ex0153 iGEM, International Genetically Engineered Machine competitionLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>Dans cette <em>release</em> : Des bactéries 🦠, des briques de codes ADN 🧬, un concours et du jus de moustiques 🦟 Nous recevons <strong><a href="https://arthurdonaldbouille.com/">Arthur-Donald Bouillé</a></strong>, <strong><a href="https://lisa-dehove.com/">Lisa Dehove</a></strong> et <strong><a href="https://xaviermontoy.net/">Xavier Montoy</a></strong>, designers au concours iGEM, dans <a href="https://cpu.dascritch.net/serie/Bio%20is%20the%20new%20Black">notre série <em>Bio is the new Black</em></a>.</p>
<p>Écoute, podcast, liens et réactions : <a href="http://cpu.pm/0153">http://cpu.pm/0153</a></p>
<p>Chroniques :</p>
<ul>
<li><a href="https://cpu.dascritch.net/post/2020/12/03/Paillasse-du-design-%3A-Programmation-du-vivant">Paillasse du design : Programmation du vivant</a></li>
<li><a href="https://cpu.dascritch.net/post/2020/12/03/How-to-%3A-%5BBiologie-de-synth%C3%A8se%2C%5D-responsabilit%C3%A9-ou-acceptabilit%C3%A9-sociale">How to : (Biologie de synthèse,) responsabilité ou acceptabilité sociale ?</a></li>
<li><a href="https://cpu.dascritch.net/post/2020/12/03/Arthur-Donald-Bouill%C3%A9%2C-Lisa-Dehove-et-Xavier-Montoy%2C-designers-au-concours-iGEM">Interview</a></li>
</ul>
<p>La semaine prochaine : Deuxième partie de la table ronde sur le regard de designers dans ce prestigieux concours de biologie.</p>
<div><a href="https://linuxfr.org/users/dascritch/journaux/cpu-ex0153-igem-international-genetically-engineered-machine-competition.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/122430/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/dascritch/journaux/cpu-ex0153-igem-international-genetically-engineered-machine-competition#comments">ouvrir dans le navigateur</a>
</p>
Da Scritchhttps://linuxfr.org/nodes/122430/comments.atomtag:linuxfr.org,2005:Bookmark/19962020-09-12T13:22:16+02:002020-09-12T13:22:16+02:00Dark Patterns: Past, Present, and Future<a href="https://cacm.acm.org/magazines/2020/9/246937-dark-patterns/fulltext">https://cacm.acm.org/magazines/2020/9/246937-dark-patterns/fulltext</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/121583/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/olivedeparis/liens/dark-patterns-past-present-and-future#comments">ouvrir dans le navigateur</a>
</p>
Big Petehttps://linuxfr.org/nodes/121583/comments.atomtag:linuxfr.org,2005:News/397522020-03-26T16:50:10+01:002020-03-26T16:50:10+01:00Atelier game design et création de jeu avec Godot anti‑confinementLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<div><p>Pour occuper nos jeunes confinés et leur permettre d’apprendre en s’amusant, <a href="https://activdesign.eu">Activdesign</a> met à disposition gratuitement son équipe de tuteurs en jeux vidéo dans le cadre d’ateliers ouverts gratuitement aux collégiens et lycéens.</p>
<p>Le principe est le suivant : <strong>apprendre à faire un jeu en utilisant des cadriciels Godot prêts à l’emploi</strong>.</p>
<p><strong>Ange</strong>, développeur d’un cadriciel simplifiant la création de plates‑formes 2D, et <strong>Cédric</strong>, membre de l’équipe d’<a href="https://github.com/flossmanualsfr/escoria"><em>Escoria in daiza</em></a> ayant écrit la <a href="https://fr.flossmanuals.net/creer-un-jeu-point-and-click-avec-escoria/">documentation sur le cadriciel Escoria</a>, se mettront à disposition des jeunes qui voudront tenter l’expérience d’utiliser ces outils. Leur disponibilité est assurée chaque jour du 30 mars au 3 avril 2020 de 15 h 30 à 17 h.</p>
</div><ul><li>lien nᵒ 1 : <a title="https://activdesign.eu/gamedesign" hreflang="fr" href="https://linuxfr.org/redirect/105961">S’inscrire à l’atelier game design Godot</a></li><li>lien nᵒ 2 : <a title="https://godotengine.org/download/" hreflang="fr" href="https://linuxfr.org/redirect/105962">Télécharger Godot</a></li><li>lien nᵒ 3 : <a title="https://github.com/flossmanualsfr/escoria" hreflang="fr" href="https://linuxfr.org/redirect/105963">Escoria in daiza</a></li></ul><div><h3 id="toc-comment-faire-pourparticiper">Comment faire pour participer ?</h3>
<ul>
<li>faire connaître son intention de participer en s’inscrivant sur <a href="https://activdesign.eu/gamedesign">https://activdesign.eu/gamedesign</a> en notant le code « COVID20 » ;</li>
<li>avoir un ordinateur à disposition avec une connexion Internet le temps des ateliers ;</li>
<li>avoir les logiciels installés, c’est‑à‑dire au moins <a href="https://godotengine.org/download/">Godot</a> (3.2 standard, si possible).</li>
</ul>
<p>Pour l’inscription, une adresse de courriel est demandée pour pouvoir informer d’éventuels changements. Cette adresse peut être créée pour l’occasion, mais il est préférable qu’elle reste active toute la durée de l’atelier, par précaution.</p>
<h3 id="toc-comment-cela-sepassera">Comment cela se passera ?</h3>
<p>Pour faciliter les échanges, le suivi se fera sur une plate‑forme en ligne spécifique disposant d’outils intégrés :</p>
<ul>
<li>une messagerie asynchrone ;</li>
<li>une messagerie instantanée Riot (inscrivez‑vous au préalable avec l’appli mobile) ou utilisez un client IRC sans inscription compatible, par exemple <a href="https://webchat.freenode.net/">https://webchat.freenode.net/</a>, mais qui ne permettra pas de faire de téléversement d’images ; le nom du salon sera notifié le moment venu ;</li>
<li>un client Jitsi, mais selon le nombre de personnes, la visioconférence pourrait s’avérer impraticable ;</li>
<li>un client FTP (par exemple FileZilla) pour s’envoyer des fichiers (Git n’est pas retenu pour des raisons de simplicité d’accès et d’uniformité de pratique) ; les identifiants seront aussi notifiés le moment venu ;</li>
<li>et quelques informations qui pourront être mises à jour au fur et à mesure des séances.</li>
</ul>
<p>Les identifiants fournis permettront d’accéder à la plate‑forme pour la durée de l’atelier.</p>
<p>Nous espérons que cette initiative permettra de mieux faire découvrir les logiciels de qualité d’autant plus merveilleux qu’ils sont libres, et contribuer à l’émergence de nouveaux contenus qui en découle.</p>
</div><div><a href="https://linuxfr.org/news/atelier-game-design-et-creation-de-jeu-avec-godot-anti-confinement.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/119775/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/atelier-game-design-et-creation-de-jeu-avec-godot-anti-confinement#comments">ouvrir dans le navigateur</a>
</p>
pygmeeDavy DefaudPierre Jarillonhttps://linuxfr.org/nodes/119775/comments.atomtag:linuxfr.org,2005:Diary/390002020-03-19T11:07:02+01:002020-03-19T11:07:02+01:00CPU Ex0132 Le designer-chercheur comme passeurLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>Dans cette <em>release</em> de <a href="https://cpu.dascritch.net/serie/Bio%20is%20the%20new%20Black">la série <em>Bio is the new black</em></a> : Un passeur, une discipline indisciplinée, de nouveaux organes perceptifs et des formats réinventés. <br>
Comment communiquer sur la recherche universitaire en design ? Une table ronde avec <strong>Xavier Guchet</strong>, philosophe des techniques et <strong>Anthony Masure</strong>, chercheur en design. Débat public mené par <a>Élise Rigot</a>, enregistré en Février au <a href="https://www.cri-paris.org/">Centre de Recherche Interdisciplinaire de Paris</a>.</p>
<p>Émission, podcast, et plein de liens sur le sujet : <a href="http://cpu.pm/0132">http://cpu.pm/0132</a></p>
<p><a href="http://eliserigot.com/content/Bio/#/">Une retranscription écrite de cette émission est disponible</a></p>
<p>Une <a href="https://cpu.dascritch.net/post/2020/03/19/Xavier-Guchet%2C-philosophe-des-techniques-et-Anthony-Masure%2C-chercheur-en-design">version longue de cette table ronde est disponible</a> avec l'intégralité des questions du public invité par <a href="http://designenrecherche.org/">l'association Design en Recherche</a>.</p>
<p>Restez chez vous en toute curiosité. On est bien en ligne avec <a href="http://radio-fmr.net">Radio FMR</a> ;) et n'oubliez pas d'applaudir le personnel soignant à 20h.</p>
<div><a href="https://linuxfr.org/users/dascritch/journaux/cpu-ex0132-le-designer-chercheur-comme-passeur.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/119695/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/dascritch/journaux/cpu-ex0132-le-designer-chercheur-comme-passeur#comments">ouvrir dans le navigateur</a>
</p>
Da Scritchhttps://linuxfr.org/nodes/119695/comments.atomtag:linuxfr.org,2005:News/397162020-02-29T22:44:35+01:002020-03-01T17:27:33+01:00Interview de Célia Margotteau, designeuse UX et UILicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<div><p>Les <a href="//linuxfr.org/forums/linux-general/posts/design-tshirt-tracim-lequel-preferez-vous">T‑shirts</a> avec les suricates, c’est elle, une partie des visuels du <a href="https://www.algoo.fr/fr/tracim">site Tracim</a>, c’est elle, lʼ<a href="//linuxfr.org/news/plus-d-excuse-pour-ne-plus-collaborer-avec-tracim-2-5#toc-travail-de-fond-sur-lergonomie-etledesign">interface Tracim</a>, c’est aussi elle en partie.</p>
<p>Pour tout dire, quand <em>LeBouquetin</em> a évoqué, dans une <a href="//linuxfr.org/news/plus-d-excuse-pour-ne-plus-collaborer-avec-tracim-2-5">dépêche plus générale</a>, le recrutement de Célia, j’ai pensé que ça pouvait être un bon sujet pour cette série d’entretiens. Le temps, ensuite, de jouer avec l’interface, de trouver des questions, nous voilà avec la première interview de cette année.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e616c676f6f2e66722f7374617469632f6d65646961732f696d6167652d346332356565333530306264316338393039633863386566366134643032373766663138376537312e6a7067/image-4c25ee3500bd1c8909c8c8ef6a4d0277ff187e71.jpg" alt="Dos du T‑shirt aux suricates" title="Source : https://www.algoo.fr/static/medias/image-4c25ee3500bd1c8909c8c8ef6a4d0277ff187e71.jpg"></p>
</div><ul><li>lien nᵒ 1 : <a title="https://www.algoo.fr/fr/tracim" hreflang="fr" href="https://linuxfr.org/redirect/105810">Tracim</a></li><li>lien nᵒ 2 : <a title="https://linuxfr.org/news/plus-d-excuse-pour-ne-plus-collaborer-avec-tracim-2-5" hreflang="fr" href="https://linuxfr.org/redirect/105811">Plus d’excuse pour ne plus collaborer (avec Tracim 2.5) !</a></li><li>lien nᵒ 3 : <a title="https://linuxfr.org/forums/linux-general/posts/design-tshirt-tracim-lequel-preferez-vous" hreflang="fr" href="https://linuxfr.org/redirect/105812">Design du T‑shirt, propositions</a></li><li>lien nᵒ 4 : <a title="https://fr.wikipedia.org/wiki/Exp%C3%A9rience_utilisateur" hreflang="fr" href="https://linuxfr.org/redirect/105813">Définition du concept expérience utilisateur</a></li></ul><div><p><strong> ― Comment devient‑on designeuse UX et UI ?</strong></p>
<p>Pour ma part, j’ai un parcours assez peu conventionnel guidé par la curiosité. De nature créative, j’ai toujours été intéressée par le design graphique et le Web, j’ai donc suivi une formation d’infographiste puis de communication visuelle et enfin sur les médias numériques. Mais ce qui a vraiment été déterminant, ça a été de me rendre compte que ce qui me parlait le plus, ce n’était pas seulement de faire du design ou des interfaces esthétiques, mais vraiment de créer des produits utiles et intuitifs, en comprenant les besoins des utilisateurs. Comprendre les utilisateurs, cela signifie se mettre à leur place, mais surtout observer et essayer de comprendre leurs problèmes sans avoir d’aprioris.</p>
<p><strong> ― En quoi cela consiste‑t‑il ? Outre les CSS, y a‑t‑il d’autres langages que tu doives connaître, voire maîtriser ?</strong></p>
<p>En fait, en tant qu’UX/UI designeuse, il faut surtout réussir à s’adapter à la fois aux utilisateurs (leur vocabulaire, leurs problématiques, leurs contraintes, leurs intérêts) mais aussi aux équipes de développement, qui ont une grande expertise de leur domaine et qui sont de précieux conseils. Il n’est pas forcément nécessaire de savoir développer pour être UX / UI designer. Personnellement, j’ai des bases en <em>front‑end</em>, et je comprends les grands principes du <em>back‑end</em>, ce qui me permet d’interagir avec les différentes équipes. Il ne faut pas avoir peur de poser des questions et d’apprendre plein de nouvelles choses !</p>
<p><strong> ― Quelles sont les spécificités de ces deux types de design UI (interface utilisateur) et UX (expérience utilisateur) ?</strong></p>
<p>Le design de l’interface utilisateur (UI) est une composante de l’expérience utilisateur (UX). Le Nielsen Norman Group définit l’expérience utilisateur comme : « englobant tous les aspects de l’interaction de l’utilisateur final avec l’entreprise, ses services et ses produits ». L’UX correspond donc à tout ce qu’un utilisateur peut expérimenter ou ressentir vis‑à‑vis d’un produit, d’un objet, d’une application, lors de son usage. Pour une application par exemple, cela va correspondre à l’enchaînement logique des écrans, la facilité de trouver les informations, et la facilité pour l’utilisateur d’atteindre son objectif. L’interface est importante parce qu’elle est directement au contact de l’utilisateur, c’est la partie visible de l’expérience.</p>
<p><strong> ― À ton avis quelles qualités faut‑il avoir pour exercer ce métier ?</strong></p>
<p>Pour moi, les principales qualités seraient : l’empathie, la curiosité et l’humilité. Je vois difficilement quelqu’un réussir dans son travail d’UX designer sans empathie. L’empathie est importante pour réussir à se mettre à la place des utilisateurs et à les comprendre. Rester curieux est aussi essentiel pour continuer à progresser dans le domaine et ne pas hésiter à remettre en question ses acquis. Et enfin l’humilité, car il faut être capable de mettre ses propres croyances et ses aprioris de côté, afin de vraiment s’intéresser aux usages et aux besoins des utilisateurs.</p>
<p><strong> ― Actuellement, à quel niveau interviens‑tu dans l’élaboration et la conception des interfaces ? Est‑ce que c’est le moment idéal ? Préfèrerais‑tu intervenir plus en amont, plus tard, au début, à la fin ?</strong></p>
<p>En tant qu’UX/UI designeuse, j’interviens de façon transversale dans un projet de création de nouvelle fonctionnalité ou de refonte de l’expérience. J’interviens ainsi tout au long du projet :</p>
<ul>
<li>
<em>en amont du développement</em>, les entretiens et les ateliers avec les utilisateurs permettent de comprendre leurs usages et leurs pratiques, afin d’imaginer des expériences adaptées ;</li>
<li>
<em>pendant le développement</em>, je participe à l’élaboration des spécifications et propose des maquettes présentant les nouvelles expériences et interfaces ;</li>
<li>
<em>après le développement</em>, en collaboration avec l’équipe de support et l’équipe commerciale, je récupère les retours des utilisateurs afin de continuer à améliorer l’expérience qu’on leur propose.</li>
</ul>
<p><strong> ― Quelles difficultés (ou pas, d’ailleurs) rencontres‑tu ou as‑tu pu rencontrer avec les équipes de développement dans le cadre de ton travail (en général, pas spécifiquement chez Algoo) ? Le cas échéant, comment y pallies‑tu ?</strong></p>
<p>Les équipes de développement expérimentées ont un vocabulaire technique qui peut être perturbant aux premiers abords. Cependant, j’ai toujours eu la chance de travailler avec des équipes très ouvertes et compréhensives, qui ont pris le temps de m’expliquer les contraintes de leurs métiers. J’ai beaucoup appris grâce à eux !</p>
<p><strong> ― As‑tu déjà (en général, pas forcément chez Algoo) été confrontée à des demandes de « dark patterns » (interface truquée d’après Wikipédia) ?</strong></p>
<p>Je n’ai jamais été confrontée à une demande de <em>dark patterns</em>, parce que j’ai eu la chance de pouvoir choisir les gens avec qui je travaillais. Les <em>darks patterns</em> correspondent à des expériences et des interfaces qui trompent sciemment les utilisateurs pour les empêcher de faire des actions qui ne sont pas profitables pour l’entreprise, comme, par exemple, désactiver les cookies (le plus fréquent) ou encore se désinscrire d’un service payant. C’est notre rôle en tant que designers de refuser de créer ou d’utiliser des <em>dark patterns</em>.</p>
<p><strong> ― Quels sont les soucis d’UX/UI que tu juges les plus fréquents ou notables dans les logiciels libres ?</strong></p>
<p>Un des soucis que l’on retrouve le plus fréquemment, dans tout type d’interfaces et d’expériences, pas seulement dans les logiciels libres, est de vouloir afficher trop d’informations, pensant que plus on affiche d’informations, plus c’est pertinent pour l’utilisateur. Cependant, afficher un grand nombre d’informations augmente la charge cognitive de l’utilisateur et rend sa navigation dans l’interface plus complexe. La <a href="https://fr.wikipedia.org/wiki/Loi_de_Hick">loi de Hick</a> est un modèle d’IHM (interaction homme‑machine) qui explique que le temps qu’il faut à un utilisateur pour prendre une décision augmente en fonction du nombre de choix à sa disposition. Concrètement, plus un utilisateur a de choix à sa disposition, plus la décision va être longue et complexe pour lui.</p>
<p><strong> ― Y a‑t‑il des différences et des spécificités en termes d’accessibilité entre une interface Web et celle d’un logiciel ?</strong></p>
<p>Je dirais que ça dépend beaucoup du contexte, mais globalement les règles d’accessibilité restent les mêmes.</p>
<p><strong> ― Comment testes‑tu l’accessibilité d’un projet ? Est‑ce que, par exemple, des personnes handicapées participent à ces tests ?</strong></p>
<p>Je teste les projets sur lesquels je travaille en suivant les recommandations des WCAG 2.1 (<em>Web Content Accessibility Guidelines</em>). Je n’ai pas encore eu la chance de pouvoir tester mes designs avec des personnes en situation de handicap mais c’est très clairement un objectif pour moi.</p>
<p><strong> ― Sur quels logiciels as‑tu été formée ?</strong></p>
<p>Dans mes études, j’ai été formée sur la suite Adobe, sur GIMP, LibreOffice, XMind, 3ds Max, SketchUp, AutoCAD, ou encore Inkscape.</p>
<p><strong> ― Penses‑tu que la formation que tu as reçue est bien adaptée à la réalité du métier ?</strong></p>
<p>Un élément qui est pour moi essentiel et dont ma formation n’a pas parlé est l’importance du travail en équipe et de la pédagogie à avoir lorsqu’on est designeuse. Je me suis vraiment rendu compte de l’aspect transversal de ce métier qu’une fois en entreprise, où j’ai dû collaborer et m’adapter à de nombreuses équipes et personnalités différentes. Personnellement, j’adore ça, parce que discuter avec les gens de différents métiers et apprendre tous les jours de nouvelles choses me passionne, mais ça a été une surprise. En réalité, faire une interface n’est pas très compliqué, mais faire une interface qui corresponde aux besoins des utilisateurs, aux possibilités techniques, à la philosophie du projet et qui suscite l’engouement des équipes est un challenge à relever.</p>
<p><strong> ― Est‑ce que c’est toi qui as dessiné les visuels (mascotte, T‑shirt, etc.) du site Tracim et l’interface des outils ?</strong></p>
<p>Quand je suis arrivée chez Algoo, je me suis inspirée de l’identité visuelle existante et je l’ai déclinée sur différents supports, dont les visuels du site <em>tracim.fr</em> ainsi que les T‑shirts d’Algoo. Je travaille sur Tracim depuis un an, et j’ai pu participer à l’élaboration de certaines fonctionnalités comme le partage de fichiers ou encore les onglets des applications (qui sont déjà disponibles dans Tracim), mais aussi sur des fonctionnalités qui sortiront bientôt comme une refonte du système de notifications ou une amélioration de l’historique des contenus. Nous avons aussi passé du temps à retravailler le site <em>tracim.fr</em> afin qu’il présente au mieux Tracim. J’ai aussi participé au lancement de l’instance publique <em>mon.tracim.fr</em>, qui permet aux particuliers et aux associations d’utiliser Tracim sans avoir besoin de compétences techniques spécifiques.</p>
<p><strong> ― Au niveau professionnel, quels logiciels libres utilises‑tu, sur quel système d’exploitation ?</strong></p>
<p>Au niveau professionnel, j’utilise Inkscape, LibreOffice, Mozilla Firefox, Thunderbird, les outils de Framasoft, <a href="https://fr.wikipedia.org/wiki/Mattermost">Mattermost</a> et Tracim bien sûr. Et je suis sous Debian GNU/Linux 9.9 (<em>Stretch</em>).</p>
<p><strong> ― Quelle est ta distribution GNU/Linux préférée et pourquoi, quels sont tes logiciels libres préférés ?</strong></p>
<p>Je suis assez classique, j’utilise Debian pour le travail et c’est la distribution qui me semble la plus claire pour une néophyte de Linux comme moi. ☺</p>
<p><strong> ― Quelle question aurais‑tu adoré qu’on te pose ? (évidemment, tu peux y répondre)<br>
Au niveau personnel, quels logiciels libres utilises‑tu ?</strong></p>
<p>J’utilise Krita pour les illustrations, Blender pour faire un peu de 3D, et <a href="https://www.aseprite.org/">Aseprite</a> pour faire du <em>pixel art</em> !</p>
<p><strong> ― Quelle question aurais‑tu détesté qu’on te pose (en espérant que je ne l’ai pas posée) ?</strong></p>
<p>Je n’en vois pas. ☺</p>
<p>Merci beaucoup pour ces questions !</p>
<p>Au plaisir de répondre aux questions des lecteurs. ☺</p>
<p><strong>Merci beaucoup Célia.</strong></p>
</div><div><a href="https://linuxfr.org/news/interview-de-celia-margotteau-designeuse-ux-et-ui.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/119528/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/interview-de-celia-margotteau-designeuse-ux-et-ui#comments">ouvrir dans le navigateur</a>
</p>
YsabeauDavy DefaudZeroHeuretedhttps://linuxfr.org/nodes/119528/comments.atomtag:linuxfr.org,2005:Diary/389032020-01-23T11:05:24+01:002020-01-23T11:24:51+01:00CPU Ex0126 : Un regard sur le vivantLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>Dans cette <em>release</em> de CPU : des fossiles qui dansent, des molécules syndicalisées, une cabaliste du vivant et un cancer standardisé. Deuxième émission de <a href="https://cpu.dascritch.net/serie/Bio%20is%20the%20new%20Black">la série <em>Bio is the new black</em></a>, notre invitée est <a href="https://twitter.com/MarieSarahA">Marie‑Sarah Adenis</a>, designer et biologiste de formation.</p>
<p>Podcast, liens documentaires et commentaires : <a href="http://cpu.pm/0126">http://cpu.pm/0126</a> et sur <a href="http://radio-fmr.net">Radio FMR</a> (maintenant et en rediffusion mardi à 9 h).</p>
<p>Sections de l’émission :</p>
<ul>
<li>
<a href="https://cpu.dascritch.net/post/2020/01/23/Paillasse-du-design-%3A-Une-science-en-culture">Paillasse du design : Une science en culture</a> ;</li>
<li>
<a href="https://cpu.dascritch.net/post/2020/01/23/Ex0126-Un-regard-sur-le-vivant">Standard : Henrietta Lacks, HeLa, elle l’a</a> ;</li>
<li>
<a href="https://cpu.dascritch.net/post/2020/01/23/Histoire-%3A-Berceau-de-mica">Histoire : Berceau de mica</a> ;</li>
<li>
<a href="https://cpu.dascritch.net/post/2020/01/23/Marie-Sarah-Adenis%2C-designer-et-biologiste-de-formation">Interview</a>.</li>
</ul>
<p>La semaine prochaine : Ex0127 Positionnement <em>in‑doors</em>.</p>
<div><a href="https://linuxfr.org/users/dascritch/journaux/cpu-ex0126-un-regard-sur-le-vivant.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/119223/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/dascritch/journaux/cpu-ex0126-un-regard-sur-le-vivant#comments">ouvrir dans le navigateur</a>
</p>
Da Scritchhttps://linuxfr.org/nodes/119223/comments.atomtag:linuxfr.org,2005:Post/406282019-11-05T14:30:18+01:002019-11-05T14:30:18+01:00Design tshirt tracim - lequel préférez vous ?<p>Bonjour à tous,</p>
<p>Comme vous le savez peut-être, <a href="https://www.algoo.fr/fr/actualites/article/retrouvez-les-nouveautes-de-la-version-2-4-de-tracim">tracim est sorti en version 2.4</a> (je prépare une dépêche) ; et comme vous le savez peut-être pas, nous serons présent au <a href="https://capitoledulibre.org/">Capitole du libre</a> dans 2 semaines à Toulouse.</p>
<p>Nous préparons de nouveaux tshirt et du coup comme le but est de faire des tshirt sympas on s'est dit qu'on allait demander l'avis de la communauté.</p>
<p>Voilà les 3 croquis à partir desquels on va partir (on doit passer commande demain, donc on est dans un mode "opération coup de poing") ; lequel préférez-vous ? (et pourquoi ?)</p>
<h3 id="toc-suricate-bouclier">Suricate bouclier</h3>
<p><img src="//img.linuxfr.org/img/687474703a2f2f7069782e746f696c652d6c696272652e6f72672f75706c6f61642f7468756d622f313537323936323536302e706e67/1572962560.png" alt="Bouclier" title="Source : http://pix.toile-libre.org/upload/thumb/1572962560.png"></p>
<p>En grand : <a href="http://pix.toile-libre.org/upload/original/1572962560.png">http://pix.toile-libre.org/upload/original/1572962560.png</a></p>
<h3 id="toc-suricate-évolution">Suricate évolution</h3>
<p><img src="//img.linuxfr.org/img/687474703a2f2f7069782e746f696c652d6c696272652e6f72672f75706c6f61642f7468756d622f313537323936323731342e706e67/1572962714.png" alt="Evolution" title="Source : http://pix.toile-libre.org/upload/thumb/1572962714.png"></p>
<p>En grand : <a href="http://pix.toile-libre.org/upload/original/1572962714.png">http://pix.toile-libre.org/upload/original/1572962714.png</a></p>
<h3 id="toc-suricate-bocal-scorpion">Suricate bocal scorpion</h3>
<p><img src="//img.linuxfr.org/img/687474703a2f2f7069782e746f696c652d6c696272652e6f72672f75706c6f61642f7468756d622f313537323936323734322e706e67/1572962742.png" alt="Bocal Scorpion" title="Source : http://pix.toile-libre.org/upload/thumb/1572962742.png"></p>
<p>En grand : <a href="http://pix.toile-libre.org/upload/original/1572962742.png">http://pix.toile-libre.org/upload/original/1572962742.png</a></p>
<p>Merci de vos retours.</p>
<p>Damien</p>
<div><a href="https://linuxfr.org/forums/linux-general/posts/design-tshirt-tracim-lequel-preferez-vous.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/118544/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/forums/linux-general/posts/design-tshirt-tracim-lequel-preferez-vous#comments">ouvrir dans le navigateur</a>
</p>
LeBouquetinhttps://linuxfr.org/nodes/118544/comments.atomtag:linuxfr.org,2005:Diary/385462019-06-08T17:42:13+02:002019-06-08T19:52:53+02:00Nouveau design pour l'espace de rédactionLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><a href="#toc-ajouter-des-images-den-t%C3%AAte-aux-d%C3%A9p%C3%AAches">Ajouter des images d'en-tête aux dépêches</a></li>
<li><a href="#toc-cr%C3%A9er-un-syst%C3%A8me-donglet-pour-afficher-la-tribune-les-d%C3%A9tails-et-les-informations">Créer un système d'onglet pour afficher la tribune, les détails et les informations</a></li>
<li><a href="#toc-rendre-le-design-utilisable-sur-les-t%C3%A9l%C3%A9phones-mobiles">Rendre le design utilisable sur les téléphones mobiles</a></li>
<li><a href="#toc-essayer-d%C3%AAtre-compatible-avec-ie">Essayer d'être compatible avec IE</a></li>
<li><a href="#toc-garder-lespace-de-mod%C3%A9ration-compatible-avec-laffichage-actuel-aux-utilisateurs">Garder l'espace de modération compatible avec l'affichage actuel aux utilisateurs</a></li>
<li><a href="#toc-diff%C3%A9rences-avec-le-design">Différences avec le design</a></li>
<li><a href="#toc-conclusion">Conclusion</a></li>
<li><a href="#toc-les-nimages">Les nimages</a></li>
</ul>
<p>Hello,</p>
<p>Sur github, j'ai proposé la <a href="https://github.com/linuxfrorg/linuxfr.org/pull/242">fusion des modifications de LinuxFr</a> qui permettent la mise en place du début du nouveau design proposé par mjourdan.</p>
<h2 id="toc-ajouter-des-images-den-tête-aux-dépêches">Ajouter des images d'en-tête aux dépêches</h2>
<p>Ici, l'idée semble assez simple à être mise en place, puisque LinuxFr utilise déjà CarrierWave et ImageMagick pour gérer l'envoi des avatars utilisateurs.</p>
<p>C'est donc le premier point que j'ai voulu traiter et, finalement, c'est celui qui m'a pris le plus de temps.</p>
<p>Tout d'abord, il m'a fallu me former aux concepts de Ruby on Rails (leur <a href="https://guides.rubyonrails.org/getting_started.html">tutoriel</a> est vraiment bien fait !).</p>
<p>Ensuite, j'ai débuté l'ajout de l'image aux dépêches, mais ça ne marchait pas. Pourtant, ce n'est pas bien compliqué, CarrierWave est vraiment simple à mettre en place !</p>
<p>J'ai donc repris le tutoriel, pas à pas, pour bien apprendre toutes les étapes de création de Model, Vues et Controlleurs et les formulaires pour la transmission des données.</p>
<p>Les tutoriels pour CarrierWave disponibles étaient assez simples aussi, mais je n'y arrivais toujours pas. J'ai donc recommencé de zéro un projet avec Ruby on Rails, suivi le tutoriel de démarrage pour mettre en place un petit projet. Ensuite, j'ai suivi un tutoriel pour ajouter des images avec CarrierWave et tout a fonctionné sans problème.</p>
<p>Je reprends le code de LinuxFr, je vérifie à nouveau que tout est bien fait comme dans l'autre projet. Mais aucune image n'arrive sur le serveur. J'étais prêt à baisser les bras, jusqu'à ce que je me rende compte que l'espace de rédaction utilise ajax pour envoyer les modifications au serveur. Je commence à lire le code CoffeeScript (c'est sympa, comme langage, je ne connaissais pas non plus !) et ce que je vois semble correct. Je regarde les requêtes réseaux et aucune image n'est transmise avec mon formulaire.</p>
<p>A force de chercher, je tombe sur des forums qui expliquent que JavaScript est incapable de lire les fichiers stockés sur disque. C'est bien dommage, parce qu'ajax est bien pratique dans l'espace de rédaction pour éditer les textes. Heureusement, je vois qu'ajax a eu des mises à jour avec HTML5 et qu'il est maintenant capable d'envoyer des fichiers avec l'API <a href="https://developer.mozilla.org/fr/docs/Web/API/FormData">FormData</a>. Je vérifie la <a href="https://caniuse.com/#search=formdata">compatiblité des navigateurs</a> et, heureusement, la plupart des navigateurs sont aujourd'hui compatibles.</p>
<h2 id="toc-créer-un-système-donglet-pour-afficher-la-tribune-les-détails-et-les-informations">Créer un système d'onglet pour afficher la tribune, les détails et les informations</h2>
<p>Maintenant que je comprends bien comment LinuxFr est construit, je m'attèle au deuxième challenge: ajouter un système d'onglet sur l'espace de rédaction pour éviter d'afficher trop d'informations en même temps aux rédacteurs.</p>
<p>Là, je remercie fortement le <a href="https://lehollandaisvolant.net/?mode=links&tag=css">Hollandais Volant</a> pour avoir écrit ses articles qui expliquent bien la puissance de CSS et comment bien l'utiliser avec JavaScript.</p>
<p>Après avoir fait ça, je me dis que c'est dommage que l'aide Markdown n'est plus affichée pour les premiers utilisateurs. Et là, je me rends compte que mjourdan avait déjà prévu ça dans son design :) L'idée est simple: quand l'utilisateur commence l'édition d'un paragraphe, on active l'onglet d'aide à l'édition. Ensuite, à la fin de l'édition, on affiche à nouveau la tribune.</p>
<p>Comme je m'étais déjà pris la tête avec les requêtes ajax, j'ai trouvé très rapidement comment appliquer ce comportement :)</p>
<h2 id="toc-rendre-le-design-utilisable-sur-les-téléphones-mobiles">Rendre le design utilisable sur les téléphones mobiles</h2>
<p>Le nouveau design utilise une structure à 3 colonnes. C'est sympa pour les grands écrans, mais ça ne marche pas bien pour les écrans plus petits comme ceux des tablettes ou les smartphones. Quand j'avais ajouté les icônes de téléchargement sur les boutons Markdown et Epub, j'ai appris qu'il ne fallait pas utiliser les CSS Grid, car la technologie est encore un peu trop récente.</p>
<p>Heureusement, CSS avait déjà une autre solution plus simple, c'est les FlexBox. J'ai suivi ce guide <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">assez complet</a> et les pages de Mozilla pour mettre en place tout ceci. Au début, je me suis trompé et j'ai utilisé Flex à l'ancienne, comme si j'avais à faire à des <code>div</code> avec l'affichage réglé par des <code>float</code>. Finalement, j'ai réussi à utiliser correctement Flex pour lui décrire ce que je voulais faire avec mes 3 colonnes et ça marche plutôt bien :)</p>
<p>Un autre point qui est intéressant pour les mobiles est de leur faire éviter de télécharger une image immense pour lui faire un rendu en petit. J'ai découvert que les navigateurs assez récents peuvent utiliser l'attribut <a href="https://developer.mozilla.org/fr/docs/Apprendre/HTML/Comment/Ajouter_des_images_adaptatives_%C3%A0_une_page_web"><code>srcset</code></a> pour choisir automatiquement quelle image est la plus intéressante à télécharger pour son écran. Ce qui est chouette, c'est que c'est un nouvel attribut, alors même si votre navigateur ne le connaît pas, il sera toujours capable d'afficher l'image disponible dans l'attribut <code>src</code>.</p>
<h2 id="toc-essayer-dêtre-compatible-avec-ie">Essayer d'être compatible avec IE</h2>
<p>Internet Explorer est encore présent et je voulais voir si c'était possible de garder l'espace de rédaction plus ou moins compatible avec lui. Heureusement pour moi, FormData et Flex sont plus ou moins disponibles dans IE :)</p>
<p>Mon système d'onglet avec CSS + JavaScript fonctionne sur les nouvelles dépêches, mais est inutilisable sur d'autres… bizarre. Je regarde la console JavaScript disponible sur IE et je me rends compte qu'il y a un bug sur la tribune quand un message est disponible !</p>
<p>IE 10 n'est en fait pas compatible avec la propriété <a href="https://developer.mozilla.org/fr/docs/Web/API/HTMLElement/dataset"><code>dataset</code></a> des éléments DOM et du coup, on ne peut pas utiliser JavaScript pour ajouter directement des données dans les éléments <code><time></code> de la tribune. Je n'avais pas vu que le problème était simplement ça, il y a peut-être un moyen d'écrire un code compatible avec IE10.</p>
<p>Pour l'instant, j'ai juste évité de faire bugger complètement JavaScript sous IE avec le contrôle <code>if(x.dataset)</code> avant de l'utiliser. Maintenant, IE n'a plus ce bug JavaScript et donc la rédaction fonctionne à nouveau correctement :)</p>
<h2 id="toc-garder-lespace-de-modération-compatible-avec-laffichage-actuel-aux-utilisateurs">Garder l'espace de modération compatible avec l'affichage actuel aux utilisateurs</h2>
<p>Pour l'espace de modération, j'ai essayé de faire converger les deux mondes: utiliser les nouveaux panneaux de l'espace de rédaction, mais garder le rendu de la dépêche tel qu'il sera fait après publication. Je me suis dit que ça aiderait les modérateurs.</p>
<h2 id="toc-différences-avec-le-design">Différences avec le design</h2>
<p>Je me suis arrêté là, ça faisait déjà pas mal de changements :) Il reste encore quelques différences avec le design:</p>
<ul>
<li>Par simplicité, j'ai mis les boutons de publications sur le panneau de gauche avec le sommaire et les liens</li>
<li>Dans la tribune, quand un message est posté, il est affiché sans avatars</li>
<li>L'historique dans les détails est complètement caché par défaut. Le design prévoyait d'afficher les 5 derniers et de mettre un bouton "tout afficher".</li>
<li>Dans l'onglet détail, on ne peut pas directement éditer le titre, la catégorie et la licence.</li>
<li>Dans l'onglet détail, on ne peut pas ajouter de Tags (ce n'était déjà pas disponible et je n'ai pas trouvé de moyen rapide de le faire).</li>
</ul>
<h2 id="toc-conclusion">Conclusion</h2>
<p>Tout n'est pas parfait, mais je pense que je suis arrivé à un point où c'est déjà utilisable pour la plupart des rédacteurs :-)</p>
<p>J'espère que cet article vous plaît et que vous serez motivé à également mettre à jour LinuxFr !</p>
<p>En plus des points ci-dessus, on a encore du <a href="//linuxfr.org/suivi/implementer-le-nouveau-design-de-linuxfr">pain sur la planche</a> :-)</p>
<h2 id="toc-les-nimages">Les nimages</h2>
<p>L'espace de rédaction d'une dépêche sans image d'entête:<br>
<img src="//img.linuxfr.org/img/68747470733a2f2f636c6f75642e61646f7273617a2e63682f696e6465782e7068702f732f4d5a63476e4137336a4859776b777a2f646f776e6c6f6164/download" alt="L'espace de rédaction d'une dépêche sans image d'entête" title="Source : https://cloud.adorsaz.ch/index.php/s/MZcGnA73jHYwkwz/download"></p>
<p>L'espace de rédaction d'une dépêche avec image d'entête:<br>
<img src="//img.linuxfr.org/img/68747470733a2f2f636c6f75642e61646f7273617a2e63682f696e6465782e7068702f732f486650747a675278617a77705a667a2f646f776e6c6f6164/download" alt="L'espace de rédaction d'une dépêche avec image d'entête" title="Source : https://cloud.adorsaz.ch/index.php/s/HfPtzgRxazwpZfz/download"></p>
<p>L'espace hybride de modération:<br>
<img src="//img.linuxfr.org/img/68747470733a2f2f636c6f75642e61646f7273617a2e63682f696e6465782e7068702f732f614a546f5373376a345157386f52442f646f776e6c6f6164/download" alt="L'espace hybride de modération sous IE" title="Source : https://cloud.adorsaz.ch/index.php/s/aJToSs7j4QW8oRD/download"></p>
<p>Les images dans l'accueil:<br>
<img src="//img.linuxfr.org/img/68747470733a2f2f636c6f75642e61646f7273617a2e63682f696e6465782e7068702f732f5850715266646533693869745867362f646f776e6c6f6164/download" alt="L'accueil avec des images" title="Source : https://cloud.adorsaz.ch/index.php/s/XPqRfde3i8itXg6/download"></p>
<div><a href="https://linuxfr.org/users/trim/journaux/nouveau-design-pour-l-espace-de-redaction.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/117425/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/trim/journaux/nouveau-design-pour-l-espace-de-redaction#comments">ouvrir dans le navigateur</a>
</p>
Adrien Dorsazhttps://linuxfr.org/nodes/117425/comments.atom