Blog

Installer LineageOS sur un Samsung Galaxy S6

Bonjour,

J’ai le plaisir de vous annoncer que je suis parvenu à installer LineageOS sur mon téléphone portable, en l’occurrence un Samsung Galaxy S6. Mais je dois vous avouer que ça n’a pas été une partie de plaisir. Je me suis fait quelques frayeurs. L’objectif initial était d’installer /e/OS, un système d’exploitation complètement degagol, déglingo dégooglisé. Seulement, il y a un petit problème. Sur le site de la e.foundation, à la fin de cette page, il y a la liste de tous les smartphones compatibles avec /e/OS et malheureusement, le Samsung Galaxy S6 n’en fait pas partie. Dieu merci, je suis un peu cabochard et à force de recherches, j’ai réussi à trouver un lien très intéressant qui m’a permis d’envisager l’installation de LineageOS sur mon téléphone portable. Cliquez sur l’image ci-dessous:

Comme vous pouvez le constater, il ne s’agit pas d’une version officielle. C’est précisé en lettres majuscules… UNOFFICIAL. Malgré cet avertissement, je me suis lancé dans cette nouvelle aventure et grand bien m’en a pris puisque je suis parvenu à mes fins! Pour un tel projet, il est nécessaire d’installer plusieurs outils.

Préparation du téléphone
  • Cliquez sur Paramètres > À propos du téléphone (SM-G920F)
  • Cliquez sept fois sur numéro de build pour activer les paramètres de développement.
  • Revenez en arrière et cliquez sur Système > Préférences avancées > Options pour les développeurs. Puis, activez le débogage USB.
TWRP

TWRP est un outil de sauvegarde et de restauration qui permet également d’installer des logiciels sur un appareil Android… ou même un nouveau système d’exploitation et ça tombe bien car c’est ce que nous allons faire. Je vous invite à vous rendre sur cette page qui malheureusement est en anglais. Si vous suivez la procédure, vous allez pouvoir télécharger la version de TWRP qui correspond à votre modèle. Pour le Samsung Galaxy S6, voici le lien: twrp-3.3.1-0-zeroflte

Heimdall

Pour flasher TWRP en mode recovery sur votre téléphone, voici la procédure. Prenez le temps de la lire attentivement et gardez à l’esprit que ce genre de manipulation présente un risque de plantage total.

ADB

Ensuite, il faut installer adb (android debug bridge), outil qui permet de dialoguer nativement avec un périphérique android.

sudo apt update
sudo apt install android-tools-adb

Maintenant, la procédure est double:

  • sur le téléphone connecté à l’ordinateur, vous êtes dans le programme TWRP. Cliquez sur Advanced > adb sideload.
  • Sur l’ordinateur, ouvrez un terminal et lancez la commande:
adb sideload filename.zip 

Ai-je besoin de préciser qu’il faut remplacer filename.zip par le fichier zip que vous souhaitez flasher (ici en l’occurrence, ce sera lineage-17.1-20220515-UNOFFICIAL-zerofltexx.zip). Ne vous affolez pas si l’installation s’interrompt à 50 % et que le message suivant apparait dans la console: Total xfer: 1.00x. C’est bon signe. Cela signifie que l’opération a parfaitement fonctionné.

Je vous donne un lien vers une autre page qui synthétise toute la procédure décrite dans cet article. Normalement, cette page sert à installer /e/OS sur un Samsung Galaxy S7. Mais cela fonctionne aussi pour lineageOS si vous suivez les instructions à partir du paragraphe Preparing for installation using Heimdall. Ignorez tout ce qui précède.

Conclusion

L’installation de LineageOS sur son téléphone portable n’est pas une opération que je conseillerais à un débutant. Cela dit, elle est à la portée de toute personne qui utilise une distribution Linux et qui est capable d’entrer des commandes dans un terminal. Prenez le temps de lire et de comprendre la documentation. Piochez des informations à droite à gauche et tout se passera bien. N’écoutez pas les oiseaux de malheur. Le risque de rendre votre téléphone définitivement inutilisable est très réduit.

2- Dan’iel (récit d’anticipation)

Dan’iel, jeune docteur en exobiologie, revient tout juste d’une mission de deux ans sur la planète Mars. Il a participé à la dernière phase de la terraformation. De retour sur Terre, en Syrtes, il rend visite à Benoît, son quadrisaïeul âgé de cent-cinquante ans. Celui-ci vit à L’Île-d’Yeu et il a connu les Syrtes d’avant la Grande Extinction. À la demande de son descendant, il accepte de replonger dans ses souvenirs.

Lorsque la porte « papillon » s’est ouverte et qu’il a difficilement posé le pied sur le tarmac, je n’ai pas pu retenir mes larmes. Il est venu à ma rencontre d’un pas lourd et nous sommes tombés dans les bras l’un de l’autre. J’ai remarqué qu’il avait les yeux humides. Il retenait ses larmes.

– Je suis bien content que tu sois de retour, mon petit. J’ai trouvé le temps long, tu sais… En tout cas, tu as bonne mine ! On dirait que tu as grandi. Dan’iel est parti dans un grand éclat de rire:

– Ça fait bien longtemps que ma croissance est terminée. Si je te parais plus grand, c’est certainement à cause de la pesanteur martienne qui est plus faible que sur la Terre. Mon squelette s’est allongé.

Sur le chemin du retour, je lui ai proposé de boire une bière dans une brasserie de Port-Joinville où j’ai mes habitudes. Mais il m’a répondu qu’il préférait rentrer tout de suite à la maison de famille de Ker Bossy.

– Tu as du vin m’a-t-il demandé ?

– Bien sûr ! Il ne se passe pas un jour sans que je boive mon petit verre. Comment crois-tu que je suis encore en vie ?

– Est-ce qu’il y a des cousins qui sont déjà arrivés ?

– Non, tu es le tout premier. Pierre et Gabrielle arrivent demain.

J’ai vite remarqué que Dan’iel souffrait de la pesanteur terrestre. Il ne se déplaçait pas normalement. Il fallait qu’il décolle ses pieds à chaque pas. Marie a pris congé de nous, après m’avoir libéré de l’exosquelette et avoir donné quelques consignes à Dan’iel. Il était midi et demi. Alors nous avons décidé de nous mettre à table pour déjeuner. J’ai annoncé à Dan’iel que j’avais acheté deux douzaines d’huîtres. Un large sourire s’est dessiné sur son visage.

– La bourriche est dans la cave en bas. Va la chercher s’il te plaît, et débouche la bouteille de Muscadet qui est dans le frigo.

Trop heureux de déguster des huîtres, Dan’iel ne s’est pas fait prier pour exécuter mes ordres. Je lui ai demandé s’il pouvait les ouvrir, car j’avais peur de me blesser. Je l’ai regardé faire. Il n’avait pas perdu la main. Je lui ai demandé si on trouvait des huîtres sur Mars ?

– Pas encore, m’a-t-il répondu, car malheureusement, l’ostréiculture ne fait pas partie des priorités de l’administration martienne.

Nous avons commencé à déguster les huîtres en silence. Je voyais bien qu’il ne fallait pas que je le dérange. Il savourait… Après en avoir avalé une demi-douzaine, il s’est essuyé la bouche avec sa serviette et il a porté son verre de Muscadet à ses lèvres. Je l’ai imité et j’en ai profité pour briser le silence.

– Raconte-moi donc un peu ton séjour sur Mars.

Dan’iel a reposé son verre, et d’une voix douce, il m’a répondu :

– Pas maintenant, Benoît. Je suis tout juste arrivé et je n’ai pas envie de retourner sur Mars ! Voici ce que je te propose. Avant de te raconter mes aventures, tu vas me parler de la Vendée, celle que tu as connue avant la Grande Extinction.

Son refus de me raconter son séjour sur Mars, m’a contrarié, mais à bien y réfléchir, ce n’était pas surprenant. Dan’iel était en vacances. Il avait envie de se vider l’esprit, ce qui signifiait oublier Mars et la mission délicate qu’il avait accomplie là-bas. Mais moi, de mon côté, je n’avais pas envie de déterrer un passé douloureux.

– Tu sais… J’ai cent-cinquante ans et mes souvenirs les plus anciens reposent à jamais au fond de ma mémoire. Il m’est impossible de les remonter à la surface.

– Benoît… Je sais que je te demande d’évoquer des souvenirs douloureux mais les témoins directs nés au vingtième siècle et qui ont survécu à la Grande Extinction, se comptent sur les doigts de la main. J’ai la chance d’être ton descendant et j’aimerais vraiment recueillir ton témoignage. Comme tous les survivants, tu n’as jamais parlé du monde d’avant. Le silence que tu gardes sur cette période est-il un choix délibéré de ta part, ou bien est-ce-que tu as conclu un pacte qui t’oblige à te taire?

– Le monde d’avant a disparu et c’est très bien comme ça. Je n’ai pas envie de contribuer à sa renaissance en libérant des souvenirs susceptibles de se transformer en métastases. Je ne veux pas mettre en péril l’harmonie de notre civilisation actuelle. La nouvelle humanité n’a pas besoin de savoir comment elle s’est comportée par le passé et ce qu’elle a été capable d’infliger à la vie sous toutes ses formes… La violence est un cancer qui ronge notre esprit. Personne ne peut y survivre. Mes souvenirs de l’ancien monde sont enkystés tout au fond de ma mémoire… Ils sont à jamais perdu. Ils vont disparaître avec moi et c’est ce que je souhaite.

Je sentais que mon esprit s’enflammait tandis que des larmes de colère brouillaient mon regard. La lave de mes souvenirs montait dans la cheminée d’un volcan qui n’allait jamais s’éteindre. Dan’iel ne disait rien. Dès que nos regard se croisaient, il baissait la tête. Je ne voulais pas penser au monde d’avant. J’avais trop peur de le réveiller. Malgré tout, j’éprouvais le besoin viscéral d’en parler. La pression était trop forte. Il fallait que le volcan de ma mémoire entre en éruption.

Dan’iel gardait le silence. Sans doute ne voulait-il pas me brusquer. Je cherchais mes mots. Je ne savais pas par quoi commencer.

– Tout ce que je peux te dire, c’est que nous vivions dans une insouciance qui n’était que le fruit de notre lâcheté collective. Personne ne voulait sacrifier son confort pour assurer un avenir à ses enfants. La protection de l’environnement était le cadet de nos soucis. Toutes les familles possédaient un ou deux moyens de déplacement à moteur thermique.

– Il n’y avait pas de transport en commun ?

– Très peu… De nos jours, Tous les transports sont effectués par des drones-lourds pour la marchandise, ou par des drones-bus pour les passagers, de sorte qu’il ne reste plus un seul centimètre carré d’asphalte. Comme tous nos déplacements sont aériens, toutes les voies de communication terrestres ont été revégétalisées. Vu du ciel, tout est vert. Mais lorsque j’étais jeune, je me souviens de la mise en service de deux autoroutes. Elles formaient une croix sur la Vendée, et nous en étions très fiers car cela signifiait le désenclavement du département et par voie de conséquence, la croissance économique.

– Tu as possédé une voiture ?

– Oui, bien sûr ! Comme tout le monde ! Mais je m’en suis débarrassé quelques années avant la Grande Extinction.

– Comment est-ce que ça a commencé ?

– La Grande Extinction ?

– Oui.

– Je n’ai pas le souvenir d’une date précise… C’est plutôt que… sans nous en rendre compte, nous avons glissé. Lorsque nous nous sommes réveillés et que nous avons pris conscience de la catastrophe, il était trop tard. Les cavaliers de l’Apocalypse étaient déjà entrés en action.

1- Dan’iel (récit d’anticipation)

Résumé

Dan’iel, jeune docteur en exobiologie, revient tout juste d’une mission de deux ans sur la planète Mars. Il a participé à la dernière phase de la terraformation. De retour sur Terre, en Syrtes, il rend visite à Benoît, son quadrisaïeul âgé de cent-cinquante ans. Celui-ci vit à L’Île-d’Yeu et il a connu les Syrtes d’avant la Grande Extinction. À la demande de son descendant, il accepte de replonger dans ses souvenirs.


Cette nuit, j’ai très bien dormi. Dan’iel, mon descendant, a débarqué hier pour passer deux semaines de vacances à la maison. Il m’avait promis qu’il serait présent à mon anniversaire et il a tenu parole. Je vais fêter mes cent cinquante ans dans quelques jours. Ça fait longtemps que je ne me suis pas senti aussi heureux. Dan’iel et moi avons toujours été très proches. Mais il y a deux ans, juste après avoir obtenu son doctorat d’exobiologie, nous avons été séparés. Dan’iel s’est vu proposer une mission sur Mars : engager la dernière phase du processus de terraformation. La planète rouge qui, autrefois, n’était qu’un désert minéral inhospitalier, a changé de couleur. Elle est devenue verte et elle grouille de vie maintenant! Dan’iel m’a dit que ces deux années sur Mars étaient passées à la vitesse de la lumière. Moi, elles m’ont paru interminables… Avec toujours cette crainte de mourir avant son retour.

Depuis quatre-vingts ans, trois millions de colons, poussés par l’aventure ou la promesse d’une vie meilleure, ont accepté de quitter définitivement la Terre et d’entamer un périlleux voyage vers Mars… Après avoir dévasté son berceau, l’humanité n’avait pas d’autre choix que de rebâtir une biosphère propice à sa survie. Les colons vivent enterrés dans des installations troglodytiques qui les protègent des radiations. L’atmosphère est encore trop ténue et ils ne peuvent toujours pas se passer d’une combinaison pour se déplacer à la surface. Mais le projet de terraformation avance bien et dans quelques sols1, les martiens devraient pouvoir évoluer à l’air libre sans aucune protection individuelle. Dan’iel est arrivé en orbite terrestre, il y a trois semaines, à bord du croiseur interplanétaire Guena’him III. J’ai pu lui parler en visio, sans avoir à patienter de longues minutes entre les questions et les réponses2. Comme tous les autres passagers, il était très fatigué, car le vaisseau avait calibré sa pesanteur sur celle de la Terre3. Tous ses déplacements étaient une épreuve. Il avait l’impression de peser trois cents kilos et d’avoir des semelles de plomb dans ses chaussures.

Drapeau de l’Union martienne

Avant-hier, le Docteur Benarfa, médecin de bord du Guena’him III, l’a autorisé à embarquer dans une navette à destination de la gare aérospatiale de Bonchamps4, en Syrtes. Il a fait sa rentrée atmosphérique ce matin à sept heures. Puis, il a pris un drone-bus pour l’Île-d’Yeu, dernière étape de son long voyage-retour.

Malgré mon âge canonique, j’habite encore dans la grande maison familiale aux murs blancs et aux volets bleu ciel, située dans le hameau de Ker Bossy, au centre de l’île. Dieu merci, grâce au suivi médical personnalisé à distance (SMPD), les maisons de relégation pour personnes âgées dépendantes ont définitivement fermé leurs portes. L’euthanasie sans consentement individuel n’est plus qu’un mauvais souvenir. Chaque citoyen à le droit d’être suivi et soigné à domicile jusqu’au terme de son existence. Je bénéficie de l’aide d’un auxiliaire de vie à cause de mon grand âge qui fait de moi, depuis trois semaines, le doyen de la Province. Je suis le dernier Syrte né en 1972. Mon auxiliaire de vie s’appelle Marie, un jeune étudiant toujours soucieux de bien faire et à qui je n’ai rien à reprocher (sauf les jours où je suis de mauvaise humeur).

Je m’éteins lentement comme une bougie, mais je ne suis pas malade. Grâce aux cellules souches qui soignent des maladies autrefois incurables, mon Parkinson n’est plus qu’aucun mauvais souvenir. Cela dit, malgré les progrès de la science, il existe une barrière chrono-biologique qui fait qu’aucun être humain n’a réussi à dépasser les cent-soixante-deux-ans. Je sais donc que je vais bientôt mourir et rencontrer mon Créateur. Marie m’a aidé à m’habiller et à sangler correctement mon exosquelette. Je suis au crépuscule de ma vie et sans cet appareillage, mes jambes ne me portent plus. L’avantage est que je n’ai plus besoin de cannes. Je peux même trottiner mais pas longtemps, car le souffle finit par me manquer. Nous sommes partis à pied jusqu’à la gare aéroterrestre. Nous étions en avance, mais je tenais à être présent à l’arrivée de Dan’iel. Au bout de dix minutes qui m’ont paru interminables, le drone-bus est apparu à l’horizon. J’ai senti l’émotion me gagner…


1) Durée d’un jour solaire sur la planète Mars

2) Le temps de communication entre Mars et la Terre est compris entre trois et vingt minutes.

3) La force gravitationelle martienne correspond à 38 % de celle de la Terre. Une personne qui pèse 100 Kg sur la Terre, pèse 38 Kg sur Mars. La masse, quant à elle, ne change pas.

4) Nouveau nom de la Roche-sur-Yon

Coder un indicateur de charge de batterie en Python

Bonjour,

L’objectif de ce billet est de coder en langage Python, un indicateur de charge pour les batteries d’ordinateurs portables. Pour ce faire, nous avons besoin de dix icônes qui correspondent chacune à un degré de charge ou de décharge. Le programme détecte également si l’ordinateur portable est branché sur le secteur.

Le code

Le voici. Il n’est pas très compliqué. On peut le découper en trois parties. Tout d’abord, dans la méthode __init__, on trouve un dicitionnaire dont les clés sont des tuples contenant deux éléments:

  • l’état de charge ( ordinateur branché sur le secteur ou bien en décharge),
  • le pourcentage de charge encore disponible.

Les valeurs, quant à elles, correspondent aux icônes.

Il est nécessaire de créer une boucle infinie (while True) pour que l’icône se mette à jour automatiquement. subprocess.Popen lance la commande acpi. Les informations sont traitées. On obtient un tuple qui correspond à l’une des clés du dictionnaire et qui nous permet de récupérer l’icône. On met à jour l’image du widget Label ainsi que le pourcentage de charge de la batterie et le tour est joué!

Labortablo-2.0, interface graphique de bureau codée en Python

Bonjour,

Aujourd’hui, je vais vous présenter un programme que j’ai codé en Python. Je l’ai baptisé Labortablo, ce qui signifie Bureau en espéranto. Il s’agit d’un menu de catégories ouvrant des sous-menus d’applications. Il est couplé avec un fond d’écran qui est en fait, un gros bouton tkinter dont la taille correspond exactement à celle de l’écran. Un clic droit sur ce fond d’écran ferme les menus qui sont ouverts. Tout ceci repose sur une base Ubuntu Server 22.04 couplée avec le gestionnaire de fenêtres Openbox. Voici à quoi cela ressemble. Le menu des catégories est déployé, tout comme le sous-menu des applications appartenant à la catégorie Accessoires. Le fond d’écran recouvre celui d’Openbox. Le menu des catégories s’ouvre en cliquant sur le bouton Menu en bas à gauche.

Lire la suite de « Labortablo-2.0, interface graphique de bureau codée en Python »

Un calendrier-agenda codé en Python (2ème partie)

Bonjour,

Plusieurs semaines de tergiversations m’ont conduit à modifier complètement le calendrier-agenda que je vous avais présenté dans l’article précédent. Le résultat est à la hauteur de mes attentes (ou plutôt de mes capacités… ). Jugez par vous-même. Après avoir téléchargé et décompressé l’archive zip de mon programme, voici ce que ce dernier contient :

Lire la suite de « Un calendrier-agenda codé en Python (2ème partie) »

8. Les listes

Une liste est un ensemble d’éléments séparés par des virgules et entourés de crochets. Ces éléments peuvent être de n’importe quel type: str(), int(), float(). Il existe même des listes de listes! Contrairement aux chaînes de caractères, il est possible de modifier une liste grâce au slicing et à différentes méthodes que je vais vous présenter dans ce chapitre.

Visualisé avec pythontutor.com

 

Déclarer une liste

Pour déclarer une liste vide, il existe deux syntaxes différentes:

liste_1 = []
liste_2 = list()
print(liste_1, liste_2
[] []

Bien sûr, vous pouvez déclarer une liste et lui affecter directement des valeurs :

mixed_list = [8, 6.9, "Kevin"]
print(mixed_list)
[8, 6.9, 'Kevin']

La deuxième syntaxe, list(), est utilisée pour convertir par exemple un tuple en liste. Nous verrons les tuples dans un prochain chapitre mais sachez déjà qu’un tuple est un ensemble d’éléments immuable séparés par des virgules et entourés de parenthèses. En fait, un tuple est une liste qu’on ne peut pas modifier. La seule solution est donc de transformer le tuple en liste.

tuple_prenoms = ("Gustave", "Solange", "Alphonse")
liste_prenoms = list(tuple_prenoms)
print(liste_prenoms)
['Gustave', 'Solange', 'Alphonse']

La méthode append()

Grâce à la méthode append(), vous pouvez ajouter des éléments qui seront affectés à la fin de la liste.

mixed_list = [8, 6.9, "Kevin"]
mixed_list.append("Joanna")
print(mixed_list)
[8, 6.9, 'Kevin', 'Joanna']

La fonction intégrée len()

La fonction intégrée len() retourne un entier qui correspond au nombre d’éléments contenus dans la liste passée en argument.

print(len(mixed_list))
4

Accéder à un élément d’une liste grâce à son indice

mixed_list contient quatre éléments indicés à partir de zéro, c’est-à-dire que l’indice du quatrième élément est 3. Avec l’indice, il est donc possible d’accéder à un élément précis de la liste. Je place l’indice de l’élément recherché entre crochets:

element = mixed_list[2]
'Kevin'  # Cela correspond au troisième élément de la liste, c'est-à-dire celui qui porte l'indice 2.

La méthode insert()

La méthode insert(indice, nouvel_element) permet d’intercaler un nouvel élément dans une liste:

mixed_list.insert(1, "Gabrielle")
[8, 'Gabrielle', 6.9, 'Kevin', 'Joanna']

Cette méthode intercale l’élément passé en argument à l’indice passé en argument. Gabrielle se retrouve donc à l’indice 1 et les valeurs qui suivent, changent d’indice (i devient i + 1). Ainsi, le nombre décimal 6.9 qui était à l’indice 1, se retrouve à l’indice 2.

La méthode extend()

La méthode extend() permet de concaténer deux listes :

jours = ["lundi", "mardi", "mercredi"]
jours2 = ["jeudi", "vendredi"]
jours.extend(jours2)
print(jours)
["lundi", "mardi", "mercredi", "jeudi", "vendredi"]

Attention! Il ne faut pas confondre extend() et append()! extend() effectue une concaténation de listes tandis que append() rajoute l’élément passé en argument, à la fin de la liste sur laquelle la méthode est appliquée.

Dans l’exemple précédent, voici ce que j’aurais obtenu si j’avais utilisé la méthode append():

jours = ["lundi", "mardi", "mercredi"]
jours2 = ["jeudi", "vendredi"]
jours.append(jours2)
print(jours)
["lundi", "mardi", "mercredi", ["jeudi", "vendredi"]]

Je n’ai pas concaténé deux  listes mais j’ai rajouté la liste jours2 aux éléments de la liste jours. Cette dernière ne contient donc pas 5 éléments (comme dans le premier exemple) mais quatre éléments : Trois chaînes de caractères et une liste! Pour vous en convaincre, il vous suffit d’utiliser la fonction intégrée len().

Accéder à un élément d’une liste qui se trouve elle-même dans une autre liste

jours est donc une liste qui contient désormais une autre liste plus petite. Nous avons vu qu’il était possible d’accéder à un élément en utilisant l’indice entouré de crochets.

jours = ["lundi", "mardi", "mercredi", ["jeudi", "vendredi"]]
# Je place l'indice de l'élément recherché entre crochets:
element = jours[2]
print(element)
'mercredi'

Mais comment faire pour accéder à Vendredi qui est un élément de la petite liste se trouvant en dernière position de la liste principale? C’est très simple! Il suffit d’utiliser cette syntaxe :

jours = ["lundi", "mardi", "mercredi", ["jeudi", "vendredi"]]
# Je place les indices de l'élément recherché entre crochets:
element = jours[3][1]
print(element)
'vendredi'

Cette valeur correspond donc à jours[3][1].

  • 3 est l’indice de la petite liste dans la liste principale.
  • 1 est l’indice de vendredi dans la petite liste.

Utiliser le slicing pour modifier une liste

Il est tout à fait possible d’utiliser les crochets et les indices pour insérer ou supprimer des éléments dans une liste. Cette technique s’appelle le slicing. Cela se traduit par découpe en tranches. C’est clairement plus délicat à manipuler que les méthodes mais c’est très efficace et d’une grande souplesse. Par exemple, au lieu d’appliquer la méthode list.insert(), on peut utiliser la syntaxe list[i:i].

jours = ["lundi", "mardi", "jeudi"]
# Je souhaite insérer "mercredi"
jours[2:2] = ["mercredi"]
print(jours)
['Lundi', 'Mardi', 'Mercredi', 'Jeudi']

Attention! L’élément à insérer doit forcément être une liste. Si vous n’insérez qu’un seul élément comme dans l’exemple ci-dessus, il faut le présenter entre crochets et par conséquent le convertir en une liste d’un seul élément. Si vous oubliez les crochets, Python va insérer chaque caractère de la chaîne Mercredi en tant qu’élément :

['Lundi', 'Mardi', 'M', 'e', 'r', 'c', 'r', 'e', 'd', 'i', 'Jeudi']

Pour faire un print() d’une partie des éléments d’une liste, par exemple les éléments indicés 1 et 2 dans la liste [‘Gabrielle’, ‘Alphonse’, ‘Kevin’, ‘Joanna’], le code sera celui-ci :

prenoms =['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
print(prenoms[1:3])
['Alphonse', 'Kevin']

Dans cette tranche, l’élément indicé 1 est pris en compte tout comme l’élément indicé 2 mais pas l’élément indicé 3! Voici un schéma qui permet de mieux comprendre comment fonctionne le slicing. La tranche [1:3] correspond à Alphonse et Kevin. La tranche [3:4] correspond au prénom Joanna.

explication_indice

Si j’insère Gustave dans la tranche [1:3], alors ce prénom remplace Alphonse et Kevin.

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
prenoms[1:3] = ["Gustave"]
print(prenoms)
['Gabrielle', 'Gustave', 'Joanna']

Autres exemples de slicing

prenoms[:] = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna'] (liste entière)
prenoms[1:] = ['Alphonse', 'Kevin', 'Joanna']
prenoms[:-1] = ['Gabrielle', 'Alphonse', 'Kevin']
prenoms[:-2] = ['Gabrielle', 'Alphonse']
prenoms[-1] = prenoms[3] = 'Joanna'
prenoms[::2] = ['Gabrielle', 'Kevin']
prenoms[::3] = ['Gabrielle', 'Joanna']
prenoms[::-1] = ['Joanna', 'Kevin', 'Alphonse', 'Gabrielle'] (inverse les éléments)

Il n’est pas toujours évident de manipuler les indices négatifs. Pour vous faciliter la tâche, il faut savoir que prenoms[-3] correspond à prenoms[len(prenoms) – 3] c’est-à-dire à prenoms[1].

[-1] est un indice négatif particulièrement intéressant car il permet d’accéder au dernier  élément d’une liste sans connaître la longueur de celle-ci.

Il est possible de parcourir une liste en utilisant un pas qui ne prend qu’un élément sur deux [::2] ou qu’un élément sur trois [::3] par exemple. Un pas de [::-1] inverse les éléments d’une liste.

Quelques méthodes associées aux objets de type list()

Nous avons déjà vu list.append(), list.extend() et list.insert(). Il existe également :

  • list.sort()

Effectue le tri d’une liste dans l’ordre numérique croissant (ou dans l’ordre alphabétique croissant).

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
nombres = [8, 52, 0, 3.2, -5.6, 7, -23]
prenoms.sort()
nombres.sort()
print(prenoms)
print(nombres)
['Alphonse', 'Gabrielle', 'Kevin', 'Joanna']
[-23, -5.6, 0, 3.2, 7, 8, 52]

list.sort() peut prendre l’argument reverse = True. Dans ce cas, le tri est décroissant :

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
nombres = [8, 52, 0, 3.2, -5.6, 7, -23]
prenoms.sort(reverse = True)
nombres.sort(reverse = True)
print(prenoms)
print(nombres)
['Joanna', 'Kevin', 'Gabrielle', 'Alphonse']
[52, 8, 7, 3.2, 0, -5.6, -23]
  • list.index()

list.index() retourne l’index de l’élément passé en argument. Si l’élément est absent de la liste, Python lève une exception. Si l’élément est présent plusieurs fois, la méthode retourne l’index de la première occurrence.

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
nombres = [8, 52, 0, 3.2, -5.6, 7, -23]
i = prenoms.index('Gabrielle')
i2 = nombres.index(53)
print(i)
print(i2)
0
ValueError: 53 is not in list

Si une valeur est présente plusieurs fois, il est possible de passer en argument l’index à laquelle doit débuter la recherche sous la forme list.index(valeur, i):

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna', 'Gabrielle']
nombres = [8, 52, 0, 3.2, -5.6, 7, -23]
i = prenoms.index('Gabrielle', 3)
print(i)
4  # la première valeur 'Gabrielle' est ignorée.
  • list.reverse()

Cette méthode inverse les valeurs de la liste.

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
prenoms.reverse()
print(prenoms)
['Joanna', 'Kevin', 'Alphonse', 'Gabrielle']
  • list.pop()

list.pop() est une drôle de méthode. Elle supprime et retourne par défaut la dernière valeur de la liste. Cette méthode peut prendre un indice en argument. Dans ce cas, c’est la valeur indicée qui est supprimée et retournée. Amusons-nous à poper deux exemples!

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
popped = prenoms.pop()
print(popped)
print(prenoms)
Joanna
['Gabrielle', 'Alphonse', 'Kevin']
prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
popped = prenoms.pop(1)
print(popped)
print(prenoms)
Alphonse
['Gabrielle', 'Kevin', 'Joanna']
  • list.remove()

Cette méthode supprime la première occurrence de la valeur passée en argument. Voici un exemple avec une liste contenant deux « Kevin ».

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna', 'Kevin']
prenoms.remove('Kevin')
print(prenoms)
['Gabrielle', 'Alphonse', 'Joanna', 'Kevin']
  • list.count()

Cette méthode compte le nombre de fois où une occurrence apparaît dans une liste et elle retourne la valeur correspondante.

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna', 'Kevin']
n = prenoms.count('Kevin')
print(n)
2

Tester l’appartenance d’une valeur à une liste

L’instruction conditionnelle if… in autorise très facilement ce genre de test. Elle valide la présence ou l’absence de la valeur recherchée dans la liste.

prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
if 'Kevin' in prenoms:
    print("Le test d'appartenance est positif.")
else:
    print("Ce prénom est absent de la liste.")
Le test d'appartenance est positif.
prenoms = ['Gabrielle', 'Alphonse', 'Kevin', 'Joanna']
result = 'Baptiste' in prenoms 
# Retourne un booléen (True ou False)
print(result)
False

 

7. Méthodes associées aux objets de type str( )

En Python, tout est objet. Les chaînes de caractères sont par exemple des objets créés par instanciation de la classe str( ). Une classe, c’est un peu comme une caisse à outils qui permet de créer un objet et de le façonner. La classe contient des méthodes et des variables que l’on pourrait comparer aux outils d’un menuisier :

  • La méthode scie-sauteuse permet de scier des variables en contreplaqué.
  • La méthode perçeuse permet de faire des trous de différents diamètres dans la variable sus-mentionnée.
  • La méthode visseuse permet d’assembler les variables en contreplaqué grâce à différentes variables de quincaillerie (vis, équerres, etc…)

C’est pas plus compliqué que ça! Programmer, c’est fabriquer des objets dans un atelier digital. Je créé l’objet prenom par instanciation de la classe str() et je lui affecte une chaîne de caractères.

prenom = "Jules"

À cet objet dénommé prenom, je peux désormais appliquer différentes méthodes qui sont en fait des fonctions définies dans une classe. Hors d’une classe, on parle de fonction tandis qu’à l’intérieur d’une classe, on parle de méthode mais c’est exactement le même procédé.

lower(), capitalize() et upper()

Par exemple, si je veux mettre la chaîne de caractères tout en minuscules, je vais utiliser la méthode lower():

min_prenom = prenom.lower()
print(min_prenom)
'jules'

Maintenant, si je veux remettre la première lettre en majuscule, quel outil vais-je donc utiliser? Ah! Ça y est, j’ai trouvé! La méthode capitalize() va me permettre de mener à bien cette opération:

cap_prenom = min_prenom.capitalize()
print(cap_prenom)
'Jules'

La méthode upper() permet de mettre une chaîne de caractères en majuscules:

maj_prenom = prenom.upper()
print(maj_prenom)
'JULES'

Maintenant, je voudrais préciser quelque chose d’important. Une chaine de caractères est un objet immuable, c’est-à dire qu’il n’est pas possible de le modifier. Alors, vous allez me dire : « Mais enfin! Tu viens tout juste de modifier la variable prenom pour mettre son contenu tout en majuscules! »

Détrompez-vous! Grâce à la méthode upper(), j’ai créé une nouvelle chaîne de caractères en majuscules que j’ai d’ailleurs stockée dans une nouvelle variable qui possède une autre adresse mémoire (maj_prenom). Si j’affiche à nouveau la variable prenom, je vais obtenir ceci : « Jules ». Ce qui prouve que depuis le début de l’exercice, je n’ai apporté aucune modification à la variable prenom.

Mais quelle est l’utilité pratique de vouloir mettre une chaîne de caractères tout en minuscules? Eh bien parfois, vous devez récupérer la valeur contenue dans un champ d’entrée. Or, il se peut que tel usager va renseigner son prénom sans mettre de majuscules tandis que tel autre va le renseigner avec une majuscule. La méthode lower() permet d’uniformiser tout cela et de faciliter le traitement des informations. Découvrons ensemble d’autres méthodes :

replace(old, new)

Cette méthode prend deux arguments. old correspond au(x) caractère(s) remplacé(s), new correspond au(x) caractère(s) remplaçant(s).

mot = "crudité"
nouveau_mot = mot.replace('di', 'au')
'cruauté'

Là encore, j’ai créé une nouvelle chaîne stockée dans une nouvelle variable. Je n’ai pas modifié la chaîne contenue dans la variable mot.

strip(), lstrip(), rstrip()

strip() supprime les espaces éventuels (par défaut) en début et en fin de chaîne. lstrip() enlève les espaces éventuels seulement en début de chaîne tandis que rstrip() enlève les espaces éventuels en fin de chaîne. Vous pouvez préciser la valeur à supprimer (par exemple « J »)

prenom = "   Jules   "
nouveau_prenom = prenom.strip()
print(nouveau_prenom)
'Jules'

Notez qu’il est tout à fait possible d’utiliser deux méthodes simultanément sur un même objet. Par exemple, je vais supprimer les espaces en début de chaîne et mettre cette dernière en majuscules.

prenom = "   Jules   "
nouveau_prenom = prenom.lstrip().upper()
print(nouveau_prenom)
'JULES   '

split()

La méthode split() transforme une chaîne en une liste de sous-chaînes. Le séparateur par défaut est un espace mais il est possible de lui donner en argument n’importe quel autre séparateur.

phrase = "Jules préfère jouer au rugby."
liste_mots = phrase.split()
['Jules', 'préfère', 'jouer', 'au', 'rugby.']
phrase = "J'ai trouvé un porte-clé."
liste_mots = phrase.split("-")  # Le séparateur est un petit tiret
print(liste_mots)
["J'ai trouvé un porte", 'clé.']

join(liste)

Cette méthode effectue l’opération inverse de la précédente.

liste_mots = ['Jules', 'préfère', 'jouer', 'au', 'rugby.']
phrase = " ".join(liste_mots)
print(phrase)
'Jules préfère jouer au rugby.'
liste_mots =["J'ai trouvé un porte", "clé."]
phrase = "-".join(liste_mots)
print(phrase)
"J'ai trouvé un porte-clé."

index(y)

Cette méthode retourne l’indice de la première occurrence de la chaîne passée en argument.

phrase = "J'ai trouvé un porte-clé."
mot = 'porte'
indice = phrase.index(mot)
print(indice)
15

Il est possible de préciser à partir de quel indice la méthode doit chercher l’occurrence. Cherchons un « é » à partir de l’indice 11.

phrase = "J'ai trouvé un porte-clé."
car = 'é'
indice = phrase.index(car, 11)
print(indice)
23

Si la méthode index() ne trouve pas la sous-chaîne, elle retourne une exception :

ValueError: substring not found

find(x)

Cette méthode fait exactement la même chose que la précédente sauf que si elle ne trouve pas la sous-chaîne, elle retourne -1.

phrase = "J'ai trouvé un porte-clé."
car = 'z'
indice = phrase.find(car)
print(indice)
-1

count()

Cette méthode retourne le nombre de fois où une sous-chaîne apparait dans une chaîne.

phrase = "J'ai trouvé un porte-clé."
car = 'é'
number = phrase.count(car)
print(number)
2

startswith() et endswith()

startswith() retourne True si la chaîne commence par la sous-chaîne passée en argument. Sinon, elle retourne False.

phrase = "Jules préfère jouer au rugby."
mot = phrase.startswith("Jules")
print(mot)
True

endswith() retourne True si la chaîne se termine par la sous-chaîne passée en argument. Sinon, elle retourne False.

phrase = "Jules préfère jouer au rugby."
mot = endswith("football")
print(mot)
False

Conclusion

Il existe bien d’autres méthodes applicables aux chaînes de caractères (isalnum(), isalpha(), isdigit(), etc…). Si vous souhaitez les découvrir et les appliquer dans vos codes, je vous invite à consulter la documentation officielle du langage Python. Vous y trouverez certainement votre bonheur. Au fil des jours, je ne manquerai pas de compléter cet article avec de nouvelles méthodes.

Un calendrier-agenda codé en Python (1ère partie)

Bonjour à toutes et à tous,

Aujourd’hui, j’ai envie de vous présenter un programme que j’ai codé en Python, avec l’aide de la bibliothèque Tkinter. Il s’agit d’un calendrier mensuel dont chaque jour correspond à un bouton. Si vous cliquez sur l’un d’entre eux, vous ouvrez une page d’agenda qui correspond bien évidemment à la date sélectionnée.

Lire la suite de « Un calendrier-agenda codé en Python (1ère partie) »

16. France, fille aînée de la guerre…

Peut-on s’imaginer embrasser le métier des armes avec pour seul horizon professionnel, celui de toujours s’entraîner sans jamais faire la guerre? Ou bien s’engage-t-on avec le désir inavoué d’être un jour appelé à combattre et par conséquent à se servir d’armes létales? On n’imagine pas un sportif s’entraîner sans jamais participer à une compétition. Cela signifie que l’armée a un besoin existentiel de faire la guerre. C’est sa raison d’être. Les généraux chinois en sont bien conscients. Ils n’hésitent pas à mettre en doute les capacités opérationnelles de leurs forces armées frappées, selon eux, par la maladie de la paix (sic!). Il faut dire que le dernier coup de feu a été tiré il y a quarante-quatre ans contre le Vietnam. Depuis, plus rien…

Lire la suite de « 16. France, fille aînée de la guerre… »