Mon bio jardin (chapitre 1)

Chapitre 1

  • Création de la page d’accueil,
  • Création d’une page menu principal divisée en quatre catégories :
    • Légumes
    • Fruits
    • Herbes
    • Fleurs
  • Création d’un menu déroulant associé à chaque catégorie,
  • Création de la page de l’espèce sélectionnée.

Bonjour,

J’aime bien jardiner. Je trouve que c’est une activité qui est saine et je suis convaincu que maîtriser l’art de faire pousser des carottes est un atout indéniable pour espérer survivre à l’effondrement de notre monde.

En 2016, peu après être tombé la tête la première dans la marmite de python magique, j’ai commencé à coder une application qui s’appelait sobrement Mon jardin. Je suis arrivé au bout de cette épreuve, et trois ans après, le programme fonctionne encore, malgré un code qui ne ressemble à rien. J’ai donc décidé de reprendre complètement ce dernier pour donner naissance, tenez-vous bien, à l’application Qu’il est bio, mon jardin!

Ce diaporama nécessite JavaScript.

Tout comme la planète Archlinux, Mon bio jardin va s’étaler sur plusieurs épisodes. Ce format permet de se fixer des objectifs  réalisables à court terme et de progresser Stück für Stück vers le but final qu’on s’est fixé. Et puis, vous vous imaginez bien que je n’ai ni le temps ni les capacités intellectuelles pour venir à bout d’un tel projet en deux semaines.

Ça faisait un moment que je n’avais pas codé en Python et il y a quelques semaines, j’ai découvert l’utilité de setattr et getattr, deux fonctions dites built-in qui permettent de manipuler des chaînes de caractères pour transformer ces dernières en attributs. Je m’explique :

Définissons une classe Rectangle et créons l’objet rectangle (avec un r minuscule contrairement au nom de la classe qui, par convention, commence toujours par une majuscule).

Définissons maintenant des attributs de l’objet rectangle, c’est-à-dire longueur et largeur. Ces attributs sont liés à leur objet par un point.

#!/usr/bin/env python3
# -*- coding: utf8 -*-

class Rectangle(object):
    "Définition d'un rectangle"

rectangle = Rectangle()
rectangle.longueur = 5
rectangle.largeur = 4
rectangle.surface = rectangle.longueur * rectangle.largeur
print(rectangle.surface)

Résultat : 20

Eh bien, par la manipulation de chaînes de caractères, setattr et getattr produisent le même résultat :

  • setattr assigne une valeur à l’attribut d’un objet.
  • getattr appelle la valeur assignée à cet attribut.
#!/usr/bin/env python3
# -*- coding: utf8 -*-
class Rectangle(object):
    "Définition d'un rectangle"

setattr(r, "longueur", 5)
setattr(r, "largeur", 4)

setattr(r, "surface", getattr(r, "longueur") * getattr(r, "largeur"))
print(getattr(r, "surface"))

Résultat : 20

Comparez les deux codes… Alors, vous allez me dire que tout ça n’a aucun sens, que le deuxième code est bien plus lourd et plus obscur que le premier. Ce que vous dites n’est pas faux… Sauf que parfois, c’est bien pratique d’utiliser setattr et getattr lorsqu’on ne connait pas à l’avance le nombre d’attributs légumes ou d’attributs fruits qu’il faut créer. Moi, en tout cas, j’ai utilisé ces deux fonctions built-in dans mon code et même si j’aurais pu m’en passer, ça m’a grandement facilité le travail!

Tiens! En parlant du code, voilà le fichier python qui lance l’application : jardin.py . Je me suis efforcé de ne jamais dépasser les 79 colonnes, conformément aux consignes du langage, et de faire un effort de clarté en choisissant des noms de variables qui soient explicites.

Une chose est certaine : Le code python et les différents fichiers de configuration ne seront pas en quantité pléthorique comme dans ma précédente application. Je pense tout de même avoir fait quelques progrès.

La page d’accueil

Rien de bien compliqué. Ce plant de tomates est un gros bouton qui conduit à la page suivante, c’est-à-dire au menu principal. Quant à miamondo.org (sous l’illustration), ce label ouvre mon site grâce au module webbrowser.

acc

Le menu principal

Il se divise en quatre catégories :

  • Légumes,
  • Fruits,
  • Herbes (légales),
  • Fleurs.

Il s’agit de quatre boutons joliment décorés par des illustrations du temps jadis, qui nous rappelle combien la vie était belle entre deux guerres mondiales ou deux épidémies de grippe espagnole. Vous pouvez cliquer sur l’image pour l’agrandir.

menu_p

Le menu déroulant

Associé à chaque bouton, le menu déroulant contient les options ajouter une espèce et supprimer une espèce, suivies de la liste des espèces que l’utilisateur aura décidé de créer. Veuillez cliquer sur l’image pour l’agrandir.

2019-09-17-233933_1889x961_scrot

Rajouter une espèce

Cette option du menu ouvre une fenêtre de la classe Toplevel contenant un widget Entry qui vous permet de renseigner le nom d’un nouveau légume, par exemple poivron. Une fois ceci fait, l’application va vous demander si vous souhaitez importer une image pour illustrer la page poivron. Si vous acceptez, vous allez être invités à téléverser l’image de votre choix grâce au sous-module filedialog. Si vous refusez, c’est une icône par défaut qui va illustrer la nouvelle ligne du menu.

Ce diaporama nécessite JavaScript.

Supprimer une espèce

Cette option va vous permettre de renseigner l’espèce que vous souhaitez supprimer, non sans vous demander au préalable de confirmer votre choix.

Ce diaporama nécessite JavaScript.

Ouvrir la page carotte

Il suffit pour cela, de cliquer sur la ligne carotte. Nous arrivons sur la page du même nom qui est encore un vaste chantier… il n’y a presque rien, à part une image et le titre de la page qui est un bouton en fait. Si vous cliquez sur celui-ci, vous ouvrez l’article Wikipedia consacré aux carottes.

Cette page sera constituée de panneaux coulissants grâce au widget PanedWindow. On aperçoit déjà les montants et les traverses. Ces fenêtres à panneaux sont bien pratiques car elles permettent de disposer de plusieurs sous-pages sur une seule et même page. Vous pouvez les agrandir ou les réduire à votre guise.

Mais pour aujourd’hui, nous allons nous arrêter là car la création de cette page fera l’objet d’un nouvel article qui constituera l’acte 2 de notre nouvelle série Mon bio jardin.

2019-09-18-010706_1873x1024_scrot

À bientôt,

B.B. (biodégradable)

13 commentaires sur “Mon bio jardin (chapitre 1)

  1. Bonsoir,
    J’ai voulu tester :

    $ ./jardin.py
    Traceback (most recent call last):
    File « ./jardin.py », line 25, in
    from PIL import Image, ImageTk
    ImportError: cannot import name ‘ImageTk’

    Je suis sous Mageia.

    Où est ce que je trouve ce ‘ImageTk’ ?

    1. Bonsoir,

      Il me semble que c’est python3-pil.imagetk. Mais moi je suis sous archlinux donc j’ai installé python-pillow. L’application n’est pas terminée. Je viens de m’y remettre. Les idées et conseils sont les bienvenus 🙂

  2. Oui, c’est python3-pillow-tk, sous Mageia.
    A présent, je peux lancer le programme, mais je n’y trouve que la catégorie Légumes.
    Et quand je veux y rajouter un légume, il me répond que l’espèce est enregistrée, mais en fait, non, aucune espèce n’apparaît, même après avoir redémarré le programme…

    1. Ça y est. C’est bon. J’avais téléversé sur mon dépôt par erreur, un fichier légumes qui n’était pas vierge. Mais il faut quand-même que je modifie le code pour contourner ce genre d’erreur. Merci pour le retour.

      1. OK, j’ai bien les 4 catégories à présent.

        Je n’ai pas cloné, j’ai téléchargé https://framagit.org/Ordinosor/mon-bio-jardin/-/archive/master/mon-bio-jardin-master.zip

        Par contre, l’ajout d’espèce est toujours inopérant.

        Voici ce que dit la console :

        $ ./jardin.py
        Exception in Tkinter callback
        Traceback (most recent call last):
        File « /usr/lib64/python3.5/tkinter/__init__.py », line 1558, in __call__
        return self.func(*args)
        File « ./jardin.py », line 271, in save_value
        « images/downloaded_images »))
        File « /usr/lib64/python3.5/shutil.py », line 241, in copy
        copyfile(src, dst, follow_symlinks=follow_symlinks)
        File « /usr/lib64/python3.5/shutil.py », line 104, in copyfile
        raise SameFileError(« {!r} and {!r} are the same file ».format(src, dst))
        shutil.SameFileError: ‘/documents/jardin/mon-bio-jardin-master/mon-bio-jardin-master/images/downloaded_images/tomates.png’ and ‘./images/downloaded_images/tomates.png’ are the same file

      2. C’est parce que tu essaies de copier au même endroit un document qui s’y trouve déjà. En fait, la source de l’image et sa destination sont identiques.

        « (master/images/downloaded_images/tomates.png’ and ‘./images/downloaded_images/tomates.png’ are the same file »

        Essaye de déplacer l’image que tu veux sélectionner dans un autre dossier, n’importe lequel, pourvu que la source et la destination soient différentes.
        Et moi, il faudra que je mette en place un mécanisme pour gérer cette exception et éviter que le programme ne plante.

  3. Bonjour,

    Je suivais l’explication sur getattr et setattr et j’ai été largué à ce moment :

    « Sauf que parfois, c’est bien pratique d’utiliser setattr et getattr lorsqu’on ne connait pas à l’avance le nombre d’attributs légumes ou d’attributs fruits qu’il faut créer »

    Le rapport entre les rectangles et les légumes ne m’apparaît pas clairement, il me semble qu’il manque quelque chose… Peut-être qu’après un café ce sera plus évident…

    En tout cas chouette projet.

    1. Bonjour,

      Merci pour votre commentaire. C’est difficile à expliquer. Prenons une liste qui contient les éléments suivants : [« a », « b », « c », « d »]. S’il me faut créer autant d’objets que de chaînes de caractères contenues dans la liste, alors setattr permet de créer self.a, self.b. self.c et self.d , sans qu’on ait besoin de s’en préoccuper, parce que la liste des légumes ou des fruits varie selon le bon vouloir de l’utlisateur. Elle n’est pas fixée. L’utilisateur peut très bien supprimer ou rajouter un fruit ou un légume.

      Benoît

    1. C’est moi qui te remercie de « beta-tester » mon application. J’écris le code et j’ai donc du mal à me mettre dans la peau de l’utilisateur. Je me rend compte que sans un mécanisme solide pour gérer les exceptions, eh bien ça plante.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.