Ceci est un post invité de 01ivier posté sous licence creative common 3.0 unported.
Bonsjours à toutes et à tous,
Dans un sursaut de patriotisme, je me suis dit qu’il me fallait, moi aussi, participer à l’effort national et promouvoir le savoir-faire technologique français. Partant du constat que, de nos jours, proposer quelque chose de nouveau semble suffisant pour être innovant, j’ai fait comme tout bon startupeur, je ne me suis pas embarrassé à concevoir quelque chose d’utile. À vrai dire, ce n’est même pas nouveau. Mais je suis français et j’ai un compte Twitter, je crois que c’est amplement suffisant pour prétendre au label #CitizenOfTheFrenchTechNation.
Où le bus l’innovation va tout droit.
Parce que je suis bien conscient de l’influence que cet article va avoir dans le monde du jeu vidéo, je vais détailler les différentes étapes de la réalisation de ce projet bouleversant.
Tout d’abord, j’ai fait en sorte que le bus de l’innovation aille tout droit sur un chemin de la croissance qui est tout droit.
#-*- coding: utf-8 -*- # On importe de quoi dormir from time import sleep # On définit le graphisme en accord avec l'équipe de designers chemin = " " arbre = "A" bus = "B" # On définit la qualité de l'image après avoir consulté les experts en GPU du Digital-Agile-Open-Tech-Lab-Responsive.IO largeur_ecran = 70 # On définit l'état initial conjointement avec la team level design. # (elle-même ayant sollicité au préalable le narrative designer, bien entendu) largeur_chemin = 15 position_chemin = 28 position_bus = 35 while 1: # On place la première portion d'arbres dans le paysage paysage = arbre * position_chemin # On place le chemin paysage += chemin * largeur_chemin # On remplit le reste du paysage par la deuxième portion d'arbres paysage += arbre * (largeur_ecran - len(paysage)) # On place le bus sur notre paysage paysage = paysage[:position_bus] + bus + paysage[position_bus:] # On affiche le tout print(paysage) # On dort un peu sleep(0.2) |
Oui. Il est effectivement possible d’arriver plus simplement au même résultat, mais, mes qualifications ne m’offrent pas le loisir d’être incompétent. J’anticipe donc les futurs mouvements du bus de l’innovation ainsi que les inéluctables virages du chemin de la croissance.
Ce doit être un peu déroutant pour vous, j’en conviens, mais c’est l’expérience qui parle.
Faites-moi confiance.
Où le bus l’innovation va tout droit mais en bien plus beau.
Parce que l’on n’est jamais assez exigent sur l’apparence d’un produit de luxe, j’ai voulu changer le rendu des arbres en remplaçant le “A” par un “█” bien plus raffiné. Voici le résultat que j’ai obtenu :
Diable comme le succès est semé d’embûches !
En effet, un petit…
>>> len("█") 3 |
… m’a appris que le “█” comptait pour trois caractères, faussant mon ingénieuse gestion des positions.
Mon talent m’avait permis d’anticiper les mouvements et autres virages mais pas ça. Damned. Qu’allais-je faire ?
Un petit replace()
bien placé et le tour était joué. Sans compter que je pouvais désormais me permettre de mettre de la couleur.
La classe internationale.
#-*- coding: utf-8 -*- from time import sleep chemin = " " arbre = "A" #On définit un arbre classe et vert en utilisant les codes ANSI arbre_classe_et_vert = "\33[32m█\033[0m" bus = "B" largeur_ecran = 70 largeur_chemin = 15 position_chemin = 28 position_bus = 35 while 1: paysage = arbre * position_chemin paysage += chemin* largeur_chemin paysage += arbre * (largeur_ecran - len(paysage)) paysage = paysage[:position_bus] + bus + paysage[position_bus:] # PAF ! On remplace l'arbre ridicule par un arbre classe et vert après avoir géré la position des différents éléments. paysage = paysage.replace(arbre, arbre_classe_et_vert) print(paysage) sleep(0.5) |
BIM !
Où le bus de l’innovation va tout droit mais sur un chemin de la croissance qui tourne.
Pour faire tourner le chemin de la croissance je fais un petit +2/-2 sur sa position avec un randint()
, et zou.
Par contre, pour forcer le chemin de la croissance à rester dans l’écran, j’ai été surpris de ne pas trouver de fonction prête à l’emploi pour contraindre un nombre dans un intervalle donné. Je suis donc passé par une “astuce” pécho sur Stack Overflow que j’ai trouvée élégante. On classe par ordre croissant le nombre donné avec les bornes de l’interval et on récupère le deuxième élément.
position = sorted(position_min, position, position_max)[1] |
Si vous avez mieux, ça m’intéresse.
#-*- coding: utf-8 -*- # On importe de quoi choisir des nombres au hasard from random import randint from time import sleep chemin = " " arbre = "A" arbre_classe_et_vert = "\33[32m█\033[0m" bus = "B" largeur_ecran = 70 largeur_chemin = 15 position_chemin = 28 position_bus = 35 # On définit une position maximale pour le chemin de la croissance position_max_chemin = largeur_ecran - largeur_chemin while 1: # On calcule la nouvelle position du chemin de la croissance # Un peu plus à droite, un peu plus à gauche ou un peu plus tout droit... position_chemin += randint(-2, 2) # En s'assurant qu'il ne déborde pas de la largeur de l'écran position_chemin = sorted([1, position_chemin, position_max_chemin])[1] paysage = arbre * position_chemin paysage += chemin * largeur_chemin paysage += arbre * (largeur_ecran - len(paysage)) paysage = paysage[:position_bus] + bus + paysage[position_bus:] paysage = paysage.replace(arbre, arbre_classe_et_vert) print(paysage) sleep(0.5) |
Où le bus de l’innovation crache des flammes.
Avant de me pencher sur les mouvements du bus de l’innovation, j’ai pris le temps de le tuner un peu.
Déjà, direct, je l’ai peint en rouge, rapport au fait que le bus de l’innovation, c’est un peu la Ferrari de l’entrepreneuriat.
Et puis, je me suis dit qu’il fallait qu’il n’y ai vraiment absolument aucun doute sur le fait que c’était bel et bien le bus de l’innovation. Je lui ai donc fait écrire “LE BUS DE L’INNOVATION” sur la route. Je m’en remets à vous pour me dire s’il reste une ambiguïté.
Accessoirement, le “A” utilisé pour placer les arbres est devenu un “a“, pour ne pas être confondus avec le “A” présent dans “INNOVATION”. C’est un détail, mais les générations d’ingénieurs qui liront ça dans deux cent ans seront bien contents de trouver cette explication.
#-*- coding: utf-8 -*- from random import randint from time import sleep chemin = " " arbre = "a" arbre_classe_et_vert = "\33[32m█\033[0m" largeur_ecran = 70 largeur_chemin = 15 position_chemin = 28 position_bus = 35 # On définit le texte écrit par le bus de l'innovation texte_du_bus = "LE BUS DE L'INNOVATION " # On récupère le nombre de caractères dans le texte écrit par le bus de l'innovation nb_caractere = len(texte_du_bus) # On initialise un compteur pour gérer la succession des caractères compteur = 0 position_max_chemin = largeur_ecran - largeur_chemin while 1: position_chemin += randint(-2, 2) position_chemin = sorted([1, position_chemin, position_max_chemin])[1] paysage = arbre * position_chemin paysage += chemin * largeur_chemin paysage += arbre * (largeur_ecran - len(paysage)) # Dans le texte écrit par le bus de l'innovation, on prend le caractère # indiqué par le compteur modulo le nombre de caractères possibles caractere = texte_du_bus[compteur%nb_caractere] # On peint le caractère en rouge Ferrari bus = "\33[31m{0}\033[0m".format(caractere) # On incrémente le compteur pour avoir le caractère suivant au prochain tour compteur += 1 paysage = paysage[:position_bus] + bus + paysage[position_bus:] paysage = paysage.replace(arbre, arbre_classe_et_vert) print(paysage) sleep(0.5) |
Magnifique.
Où l’on cherche à faire tourner le bus de l’innovation.
Je ne vais pas vous mentir, la course du bus de l’innovation sur le chemin de la croissance n’est pas vraiment une nouveauté vidéoludique. Nous, c’est à dire La Labomedia, l’avons déjà présentée à Toulouse lors du THSF 2014 ainsi qu’au PSESHSF 2016 de Choisy-le-Roi dont il existe même une vidéo de la Master Class.
Sur cette photo spectaculaire, vous pouvez découvrir la pertinence de notre ingénieuse interface biologique imputrescible nourrie aux anti-biotiques NF.
Mais, non seulement j’avais perdu totalement le code initial mais en plus l’installation s’appuyait sur l’excessivement chère MakeyMakey qui, par ailleurs, telle qu’elle est vendue, impose à l’utilisateur d’être relié à une masse.
Pour sa résurrection, je lui ai donc préférée la Capacitive Touch HAT pour RaspberryPi conçue par Adafruit et qui fonctionne direct au simple touché.
(Il va de soit que les natural chicken flavor interfaces n’ont, elles, pas été remises en question.)
Voici le code minimal pour utiliser le Capacitive Touch HAT une fois la librairie d’Adafruit installée :
import Adafruit_MPR121.MPR121 from time import sleep interface = Adafruit_MPR121.MPR121.MPR121() interface.begin() while 1: # Si la patine numéro 0 est touchée if interface.is_touched(0): print("GAUCHE !") # Si la patine numéro 10 est touchée if interface.is_touched(10): print("DROITE !") sleep(0.1) |
Qui devient ceci quand on instaure un seuil de détection pour tenir compte de la conductivité des pattes de poulet.
import Adafruit_MPR121.MPR121 from time import sleep interface = Adafruit_MPR121.MPR121.MPR121() interface.begin() seuil = 100 while 1: # Si la patte de poulet reliée à la patine numéro 0 est touchée if interface.filtered_data(0) < seuil: print("GAUCHE !") # Si la patte de poulet reliée à la patine numéro 0 est touchée if interface.filtered_data(10) < seuil: print("DROITE !") sleep(0.1) |
On ne peut pas dire que ce soit très compliqué. À noter tout de même la nécessité d’activer l’I2C et de lancer le script en root. Une formalité pour celles et ceux qui ont de l’ambition dans la Vie.
Une fois intégré dans notre formidable simulation de sport mécanique extrême, le script ressemble alors à ça :
#-*- coding: utf-8 -*- # On importe la librairie d'Adafruit import Adafruit_MPR121.MPR121 as MPR121 from random import randint from time import sleep # On instancie l'interface... interface = MPR121.MPR121() # ... et on la démarre. interface.begin() chemin = " " arbre = "a" arbre_classe_et_vert = "\33[32m█\033[0m" largeur_ecran = 70 largeur_chemin = 15 position_chemin = 28 position_bus = 35 texte_du_bus = "LE BUS DE L'INNOVATION " nb_caractere = len(texte_du_bus) compteur = 0 position_max_chemin = largeur_ecran - largeur_chemin seuil = 100 while 1: # En fonction des patines touchées, # on déplace le bus de l'innovation vers la droite... if interface.filtered_data(0) < seuil: position_bus += 1 # ... ou vers la gauche. if interface.filtered_data(10) < seuil: position_bus -= 1 position_chemin += randint(-2, 2) position_chemin = sorted([1, position_chemin, position_max_chemin])[1] paysage = arbre * position_chemin paysage += chemin * largeur_chemin paysage += arbre * (largeur_ecran - len(paysage)) caractere = texte_du_bus[compteur%nb_caractere] bus = "\33[31m{0}\033[0m".format(caractere) compteur += 1 paysage = paysage[:position_bus] + bus + paysage[position_bus:] paysage = paysage.replace(arbre, arbre_classe_et_vert) print(paysage) sleep(0.5) |
Où le bus de l’innovation est tenu de rester sur le chemin de la croissance.
Écoutez, que les choses soient bien claires, moi aussi je trouve cet article beaucoup trop long, mais c’est du rayonnement de la France dont il est question. Dois-je vous le rappeler ?
Voici donc comment j’ai tenu compte des sorties du chemin de la croissance par notre bus de l’innovation :
#-*- coding: utf-8 -*- import Adafruit_MPR121.MPR121 as MPR121 from random import randint from time import sleep interface = MPR121.MPR121() interface.begin() chemin = " " arbre = "a" arbre_classe_et_vert = "\33[32m█\033[0m" largeur_ecran = 70 largeur_chemin = 15 position_chemin = 28 position_bus = 35 texte_du_bus = "LE BUS DE L'INNOVATION " nb_caractere = len(texte_du_bus) compteur = 0 position_max_chemin = largeur_ecran - largeur_chemin # On définit un booléen qui rendra compte de l'état du bus de l'innovation le_bus_roule = True seuil = 100 while 1: if interface.filtered_data(0) < seuil: position_bus += 1 if interface.filtered_data(10) < seuil: position_bus -= 1 # Si le bus roule... if le_bus_roule: position_chemin += randint(-2, 2) position_chemin = sorted([1, position_chemin, position_max_chemin])[1] paysage = arbre * position_chemin paysage += chemin * largeur_chemin paysage += arbre * (largeur_ecran - len(paysage)) # Si le bus sort de la route, à gauche ou à droite... if position_bus <= position_chemin or position_bus >= position_chemin + largeur_chemin: # On change l'apparence du bus (qui devient une croix verte) bus = "\33[32mX\033[0m" # On change l'état du bus de l'innovation le_bus_roule = False # Sinon, on affiche le bus comme précédement défini else: caractere = texte_du_bus[compteur%nb_caractere] bus = "\33[31m{0}\033[0m".format(caractere) compteur += 1 paysage = paysage[:position_bus] + bus + paysage[position_bus:] paysage = paysage.replace(arbre, arbre_classe_et_vert) print(paysage) # Si, entre temps, le bus de l'innovation s'est arrêté de rouler if not le_bus_roule: # On affiche un message sympathique après avoir sauté une ligne print("\nIl n'est pas exclu que le bus de l'innovation se soit pris un arbre...") sleep(0.5) |
Où la course du bus de l’innovation sur le chemin de la croissance va pouvoir enfin commencer.
Afin que le public intègre bien le défi collectif que représente la relance de l’économie par le financement et le développement d’innovants nouveaux projets novateurs avec de la technologie à la pointe de la technologie, j’ai fait en sorte d’afficher la croissance totale que l’ensemble des joueurs auront fait parcourir au bus de l’innovation.
Ainsi, n’y a-t-il jamais un individu qui perd, mais toujours un collectif qui gagne.
Quelque chose entre la victoire éternelle et le succès permanent.
Une véritable leçon de Vie.
#-*- coding: utf-8 -*- import Adafruit_MPR121.MPR121 as MPR121 from random import randint from time import sleep interface = MPR121.MPR121() interface.begin() chemin = " " arbre = "a" arbre_classe_et_vert = "\33[32m█\033[0m" largeur_ecran = 70 largeur_chemin = 15 # On met en place un système d'initialisation des positions # du chemin de l'innovation et du bus de la croissance init_position_chemin = 28 init_position_bus = 35 position_chemin = init_position_chemin position_bus = init_position_bus texte_du_bus = "LE BUS DE L'INNOVATION " nb_caractere = len(texte_du_bus) compteur = 0 position_max_chemin = largeur_ecran - largeur_chemin seuil = 100 le_bus_roule = True # On déclare des variables qui vont nous permettre de rendre compte # des quantités de croissance parcourue par le bus de l'innovation croissance_parcourue_totale = 0 croissance_parcourue = 0 # On définit un petit texte à formater pour présenter les quantités en question texte_crash =''' Bravo ! Tu t'es pris un arbre mais tu as parcouru {0} mètres de croissance ! Pour ton information, le Bus de l'Innovation a parcouru {1} mètres de croissance depuis son départ. Pour le faire redémarrer, appuie sur la cuisse de poulet du milieu. La France compte sur toi ! ''' while 1: if interface.filtered_data(0) < seuil: position_bus += 1 if interface.filtered_data(10) < seuil: position_bus -= 1 # On met en place un moyen de reprendre le chemin de la croissance # si le bus de l'innovation s'est pris un arbre if if interface.filtered_data(5) < seuil and not le_bus_roule: le_bus_roule = True croissance_parcourue = 0 position_chemin = init_position_chemin position_bus = init_position_bus compteur = 0 if le_bus_roule: position_chemin += randint(-2, 2) position_chemin = sorted([1, position_chemin, position_max_chemin])[1] paysage = arbre * position_chemin paysage += chemin * largeur_chemin paysage += arbre * (largeur_ecran - len(paysage)) if position_bus <= position_chemin or position_bus >= position_chemin + largeur_chemin: bus = "\33[32mX\033[0m" le_bus_roule = False else: caractere = texte_du_bus[compteur%nb_caractere] bus = "\33[31m{0}\033[0m".format(caractere) compteur += 1 # On incrémente la croissance parcourue à chaque tour croissance_parcourue += 5 paysage = paysage[:position_bus] + bus + paysage[position_bus:] paysage = paysage.replace(arbre, arbre_classe_et_vert) print(paysage) if not le_bus_roule: # On calcule la croissance totale parcourue croissance_parcourue_totale += croissance_parcourue # On formate notre petit texte pour informer le joueur de sa # performance individuelle et collective. print(texte_crash.format(croissance_parcourue, croissance_parcourue_totale)) sleep(0.5) |
Il y a numpy.clip pour ça :)
from numpy import clip
clip(value, min, max)
Ah oui, mais si le bus de l’innovation roule au super plombé, forcément ça va pas aller loin. Si on lui met un tout nouveau moteur électrique, directement issu des dernières innovations de Renault en Formule E, ça donne :
~> python3 -c 'print(len("█"))'
1
C’est pas de la faute de l’auteur. Il a posté son article en début 2016, donc encore en Python 2. C’est moi qui ait mis un an pour le publier.
J’ai eu l’occasion de voir l’auteur présenter sur scène la création de cette création, une sorte de petit cours introductif au python python déjanté et subversif: génial. Vive LA labomédia!
J’avoue que j’avais dû mal à saisir vers où l’auteur voulait nous emmener, mais tout s’est éclairé au moment où les pattes de poulet ont été mises en place.
Les félicitations du conseil de classe et encouragements du jury pour le logo French Tech qui fait toute la saveur de la photo.
Les branleurs ! De la part d’un vieuc qui pythonne.