Générateur d'images aléatoires

Bonsoir,

Je souhaite créer un générateur de recettes aléatoires avec Python et je suis un peu perdu.
Je vais essayer de résumer ma démarche :
j'ai trié une 40aine de recettes dans 8 dossier sous forme de photos au format png (1 photo par recette). Les dossiers représentent :
- 3 possibilités pour le temps de préparation ; <15min, <30min, >30min, donc 3 dossiers,
- 3 possibilités pour le niveau de difficulté ; Facile, Moyen, Difficile, donc 3 dossiers,
et 2 possibilités pour le prix ; bon marché, cher, donc 2 dossiers.

J'utilise tkinter pour l'interface graphique et je souhaite faire apparaitre au début une image sur le Canvas, ainsi que 3 premier bouton avec comme choix le temps de préparation.
Lorsqu'un bouton est cliqué, les 3 boutons disparaissent et 3 nouveaux apparaissent cette fois-ci pour la difficulté, idem qu'avant, les boutons disparaissent et laissent place à deux boutons pour le prix et lorsqu'on clique sur l'un des deux, les boutons sont remplacer par un ultime bouton : quit, et l'image du Canvas est remplacée par une recette correspondant au critères choisies par l'utilisateur, donc dépendant des boutons..

J'ai déjà fais 8 listes qui regroupent les noms des photos.png dans les 8 dossiers, et l'idéé c'est de dire si Button1 = x, prendre list1, 2, ou 3, si Button2 = y, prendre la list précédente et regarder quelle sont les string en commun avec la list attribuée à y - éventuellement créer une nouvelle list de valeurs -, et si Button3 = z, prendre prendre la list précédente et regarder quelle sont les string en commun avec la list attribuée à z - et pareil éventuellement créer une nouvelle list avec ces valeurs -.

Une fois que l'on a cette list, on fais PhotoImage(file=( a1)) où
a1--> a1=str(random.choice(listFinalGénrée)) et tadaaa on fait en sorte que l'interface final, comme dis plus haut, soit une image de recette sur le Canvas et un bouton qui.

Le truc c'est que je pars dans tout les sens, je dois utiliser la Programmation orienté objet et j'en ai jamais fais avant, je confonds tout et je suis assez perdu car je ne comprends pas mes erreurs. Quelqu'un pourrait me proposer un programme type que je puisse reprendre sur des bonnes bases stp car j'ai l'impression de ne pas du tout prendre le chemin le plus cours...

Merci les amis.

Clarsson

Configuration: Macintosh / Safari 14.1.2

6 réponses

  1. Bonjour,

    Moi, je ne m'embêterais pas à faire apparaitre et disparaitre des boutons, je ferais 3 listes déroulantes (Combobox) et un bouton pour afficher la recette en fonction des 3 choix:


    La recette s'afficherait dans un Canvas à droite des 3 listes, tout simplement

    De plus, le choix de la recette n'a pas l'air simple
    Une recette donnée est forcément soit facile, soit difficile soit moyenne, pas les 3 à la fois
    idem pour le prix et le temps

    Donc une recette donnée est, par exemple, facile ET en - de 15mn ET bon marché
    Je nommerais donc l'image f_15_bm.png

    Ensuite, je reconstituerais la chaine de caractères en fonction des 3 choix des 3 listes déroulantes et ça donnerait automatiquement le nom de l'image à afficher
    (et un seul dossier pour toutes les images)
    1
    1. C'est une super idée les listes déroulantes je n'y avait même pas pensé ! Serais-ce possible d'avoir le code que tu as fais pour générer la fenêtre s'il-te-plaît ?

      pour ça "De plus, le choix de la recette n'a pas l'air simple
      Une recette donnée est forcément soit facile, soit difficile soit moyenne, pas les 3 à la fois
      idem pour le prix et le temps

      Donc une recette donnée est, par exemple, facile ET en - de 15mn ET bon marché
      Je nommerais donc l'image f_15_bm.png " C'est ce que j'essaye de faire, je pensais mettre des conditions sur les boutons pour n'en choisir qu'un à chaque étape mais je vais faire des listes déroulantes finalement.

      pour "Ensuite, je reconstituerais la chaine de caractères en fonction des 3 choix des 3 listes déroulantes et ça donnerait automatiquement le nom de l'image à afficher
      (et un seul dossier pour toutes les images)", je ne comprends pas, je n'ai pas qu'une seule recette facile, <15min et bon marché, pourquoi nommer une image f_15_bm.png plutôt que d'utiliser un dossier contenant toute les images correspondantes ? Idem que pour la première remarque, est-ce que t'aurais un exemple sous la main s'il-te plaît ?

      Quoiqu'il en soit merci pour ta réponse ça m'a déjà bien aidé !
      0
    2. Pour résumer, j'aimerai savoir s'il-vous-plaît :
      -Comment mettre une image png dans un Canvas (je n'arrive pas à importer le module PIL je ne sais pas si c'est pour ça),
      -Comment associer mes listes à la sélection de l'utilisateur (comment faire pour que mon programme sache quoi afficher depuis quelle valeur/dossier/list... en fonction des choix réalisé),
      - et comment coder tout ça en POO...

      Des exemples de codes sont les bienvenus.

      Merci pour votre futur aide précieuse et très appréciée .
      0
    3. @pelopelo4Je t'ai répondu plus bas ...
      0
  2. Contributeur Ambassadeur
    bonjour,
    As-tu déjà de l'expérience avec tkinter?
    Si tu commences avec la programmation orienté objet, je pense préférable de faire d'abord des exercices beaucoup plus simples.
    0
    1. Le choix de l'image me parait plus simple comme ça
      Evidemment que tu n'as pas qu'une seule recette de ce type, tu peux ajouter un indice à la fin:

      f_15_bm_01.png
      f_15_bm_02.png
      d_30_c_01.png
      etc ...


      Lorsque tu as reconstitué la 1ere partie de la chaine, par exemple f_15_bm, tu en tire une au hasard parmi celles qui commencent comme ça, et tu l'affiche

      Pour ce qui est du widget Combobox, tu trouveras plein de tutos sur Internet
      En gros ça donne ça:
      def valeur_combo_1(evt):
          choix_difficulte = liste_1.get()
      
      liste_1=["Facile","Moyen","Difficile"]
      c1 = ttk.Combobox(fenetre_principale, values=liste_1)
      c1.current(0)
      c1.bind("<<ComboboxSelected>>", valeur_combo_1)
      


      as-tu installé le module PIL sur ton PC ?
      si oui, il faut écrire en en-tete de code:

      from PIL import Image, ImageTk


      Est-ce que l'on t'impose la POO ou pas ?

      0
      1. Merci ! Je dois importer un module non ? Je comprends tes explications, néanmoins est-ce qu'il serait possible d'avoir le code en entier pour afficher la fenêtre que tu as s'il te plaît ? Comme ça j'ai déjà la base et je peux travailler directement dessus !

        Encore merci !
        0
      2. @pelopelo4Désolé je n'avais pas vu le texte au dessus de l'image, je suis un peu fatigué hehe

        Non je n'ai pas installé le module PIL et oui malheureusement on m'impose la POO sinon ça aurait été plus vite je pense. Je ne remet pas en cause son utilité mais c'est fastidieux je trouve et compliqué.
        0
    2. Si tu n'as pas installé PIL il faut le faire d'abord

      Moi, sous Python 3.7.2, j'ai fait ça:


      Ensuite, on ne donne jamais de code tout fait sur ce forum, mais plutôt des pistes, des conseils ...
      Ce que tu vois sur mon image a été fait sans POO..
      Affiche nous ici ce que tu as déjà essayé, avec les balises de code:

      https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

      "Comment associer mes listes à la sélection de l'utilisateur ?"

      Si tu nommes tes images comme dans mes exemples, tu peux faire ça:
      tu récupères les 3 critères des 3 listes déroulantes, comme dans l'exemple que je t'ai donné plus haut,
      dans 3 variables difficulté, temps et prix

      Tu concatènes les 3 pour former le début du nom d'image:
      nom_img = difficulte+'_'+temps+'_'+prix, ca donne, par exemple : "f_15_bm"

      Ensuite tu parcours ton répertoire d'images pour chercher les fichiers .png (il y a un module glob pour ça)
      et tu ajoutes dans une liste les noms qui commencent par nom_img

      Tu tires un nom de la liste au hasard (grâce au module random) et tu l'affiches avec une fonction déclenchée par le bouton "afficher recette" :

      mon_canevas.create_image(0,0,image = img, anchor = 'nw')


      img étant l'objet créé par PIL avec ton nom de fichier .png
      0
      1. Okay, j'étais au boulot désolé,

        Alors mon code a un peu évolué depuis ça donne ça :

        class Application(object):
            def __init__(self):
                self.root = Tk()
                self.root.title("Cuisto sous la manche")
                self.root.geometry("900x500")
                self.root.resizable(width=False, height=False)
                Canvas(self.root,)
                Button(self.root, text="Temps : <15min").grid(row=1, column=1)
                Button(self.root, text="Temps : <30min").grid(row=1, column=2)
                Button(self.root, text="Temps : >30min").grid(row=1, column=3)
                self.root.mainloop()
        
                def valeur_combo_1():
                    choix_difficulte = liste_1.get()
        
                liste_1 = ["Temps : <15min", "Temps : <30min", "Temps : >30min"]
                c1 = ttk.Combobox(fenetre_principale, values=liste_1)
                c1.current(0)
                c1.bind("<<ComboboxSelected>>", valeur_combo_1)
                liste_2 = ["Facile", "Moyen", "Difficile"]
                c1 = ttk.Combobox(fenetre_principale, values=liste_2)
                c1.current(0)
                c1.bind("<<ComboboxSelected>>", valeur_combo_1)
                liste_3 = ["bon marché", "cher"]
                c1 = ttk.Combobox(fenetre_principale, values=liste_3)
                c1.current(0)
                c1.bind("<<ComboboxSelected>>", valeur_combo_1)
        
        
        # Programme principal :
        if __name__ == '__main__':
            from tkinter import *
            f = Application()  # instanciation de l'objet application
        
            import random
            from tkinter  import * # GUI
            from tkinter.ttk import * # Widgets avec thèmes
        
            All = list(
                ["Croque-monsieur.png", "Fondue.png", "Burger.png", "Wraps.png", "Sandwich.png", "Tacos.png",
                 "Escalopes-de-veau-a-la-creme.png", "Hot-dog-a-la-vachette.png", "Tagliatelles-au-saumon", "Crepes",
                 "Mac-and-cheese", "Pates-carbonara", "Sole-meuniere.png", "Steak-de-thon.png", "Riz-cantonais.png", "Steak-tartare.png", "Escalopes-milanaises.png",
                 "Poulet-curry.png", "Risotto-au-chorizo.png", "Pates-aux-crevettes.png", "Tagliata-de-boeuf.png",
                 "Galettes-de-pommes-de-terre.png", "Poulet-au-roquefort.png", "Filet-de-truite-saumonee.png",
                 "Tartiflette.png", "Hachis-parmentier.png", "Gnocchis.png", "Porc-au-caramel.png", "Poulet-et-creme-de-citron.png",
                 "Pommes-de-terre-farcies.png", "Filet-mignon-de-porc-a-la-moutarde.png", "Poulet-de-Bresse.png",
                 "Jambalaya-poulet.png"])
        
            #iq= "<15" ; it= "<30" ; st= ">30"
            #s=simple ; m=moyen ; d=difficile;
            #bm=bon marché ; c=cher
        
            iq_s_bm=list(
                ["Croque-monsieur.png", "Burger.png", "Wraps.png", "Sandwich.png", "Hot-dog-a-la-vachette.png", "Crepes",
                 "Mac-and-cheese", "Pates-carbonara"])
            iq_m_bm=list(
                ["Tacos.png", "Escalopes-de-veau-a-la-creme.png", "Tagliatelles-au-saumon"])
            iq_m_c=list(
                ["Fondue.png"])
            it_s_bm=list(
                ["Galettes-de-pommes-de-terre.png", "Risotto-au-chorizo.png"])
            it_s_c=list(
                ["Pates-aux-crevettes.png"])
            it_m_bm=list(
                ["Poulet-au-roquefort.png", "Escalopes-milanaises.png"])
            it_m_c=list(
                ["Sole-meuniere.png", "Steak-de-thon.png", "Steak-tartare.png", "Tagliata-de-boeuf.png"])
            it_d_bm=list(
                ["Poulet-curry.png", "Riz-cantonais.png"])
            it_d_c=list(
                ["Filet-de-truite-saumonee.png"])
            st_s_bm=list(
                ["Galettes-de-pommes-de-terre.png","Hachis-parmentier.png"])
            st_s_c=list(
                ["Porc-au-caramel.png"])
            st_m_bm=list(
                ["Tartiflette.png","Poulet-et-creme-de-citron.png"])
            st_m_c=list(
                ["Filet-mignon-de-porc-a-la-moutarde.png", "Jambalaya-poulet.png"])
            st_d_bm=list(
                ["Gnocchis.png"])
            st_d_c=list(
                ["Poulet-de-Bresse.png"])
        """
            a1 = str(random.choice(infQuinze))
        
        
        def cmd(image):
            PhotoImage(file=("<15/" + a1)) """
        


        J'ai tout compris ton dernier message, je suis allez voir le module glob c'est top je vais essayer, par contre toujours pas moyen de savoir quand est-ce qu'il faut utiliser la POO et comment l'utiliser ; faut-il le faire pour tout les variables ? Quel sont les objets que je peux créer qui me faciliterai la vie et quoi mettre dedans ?
        Pour tkinter, comment mettre un Canvas avec une image dessus pour afficher la recette ?

        J'ai mis les dernière lignes en commentaire car c'est ce que je voulais faire avant que tu me donne ta méthode, et je n'ai pas encore importé le module PIL ni fais les changement de ton dernier message.

        Merci beaucoup j'apprécie vraiment le coup de pouce.
        0
    3. Bonjour,

      Moi, si je débutais, je ferais ca étape par étape : sans POO pour commencer, pour tester la mécanique, j'ajouterais la POO en dernier

      Pour créer un Canvas et mettre une image, tu peux aller sur Internet, c'est bien expliqué

      Remarques:

      On met toujours les imports en début de programme, pas au milieu du code comme tu le fais

      Ligne 8,9,10 tu as toujours 3 boutons, ce n'est pas ce que l'on a dit

      Il te faut 3 fonctions comme valeur_combo_1() pour récupérer les 3 valeurs des 3 Combobox

      Les noms des images ne suivent pas la méthode que je t'ai donnée, mais bon, tu fais comme tu veux ..
      0
      1. Bonsoir à nouveau,

        Alors j'ai finis mon programme en suivant (presque) tout tes conseils et j'aurais maintenant besoin d'un petit peu d'aide pour le faire fonctionner.

        Voici le programme final commenté en espérant qu'il soit le plus clair possible :

        class Application(object):
            def __init__(self):
                #création d'un interface graphique
                self.root = Tk()
                self.root.title("Cuisto sous la manche")
                self.root.geometry("900x500")
                self.root.resizable(width=False, height=False)
                Canvas(self.root, bg="black", height=400, width=900)
                #création de 3 listes déroulantes
                liste_1 = ["Temps : <15min", "Temps : <30min", "Temps : >30min"]
                c1 = ttk.Combobox(self.root, values=liste_1)
                c1.current(0)
                c1.bind("<<ComboboxSelected>>", valeur_combo_1)
                c1['values'] = ('value1', 'value2', 'value3')
                liste_2 = ["Facile", "Moyen", "Difficile"]
                c2 = ttk.Combobox(self.root, values=liste_2)
                c2.current(0)
                c2.bind("<<ComboboxSelected>>", valeur_combo_2)
                liste_3 = ["bon marché", "cher"]
                c3 = ttk.Combobox(self.root, values=liste_3)
                c3.current(0)
                c3.bind("<<ComboboxSelected>>", valeur_combo_3)
                #Boutton afficher recette
                Button(self.root, text="Afficher recette", bg="red",  command=[
                if True:
                    canevas_final
                else:
                    pass
                ])
                self.root.mainloop()
        
        # Programme principal :
        if __name__ == '__main__':
            from tkinter import *
            import random
            import PIL
            from tkinter.ttk	import *	# Widgets avec thèmes
            f = Application()  # instanciation de l'objet application
        
        
            #définition des variables temps, difficulte et prix des listes déroulantes
            def valeur_combo_1 (evt, liste_1=None):
                temps=liste_1.get("iq", "it", "st")
            def valeur_combo_2 (evt, liste_2=None):
                difficulte=liste_2.get("s", "m", "d")
            def valeur_combo_3 (evt, liste_3=None):
                prix=liste_3.get("bm", "c")
        
            #iq= "<15" ; it= "<30" ; st= ">30"
            #s=simple ; m=moyen ; d=difficile;
            #bm=bon marché ; c=cher
        
            iq_s_bm=list(
                ["Croque-monsieur.png", "Burger.png", "Wraps.png", "Sandwich.png", "Hot-dog-a-la-vachette.png", "Crepes",
                 "Mac-and-cheese", "Pates-carbonara"])
            iq_m_bm=list(
                ["Tacos.png", "Escalopes-de-veau-a-la-creme.png", "Tagliatelles-au-saumon"])
            iq_m_c=list(
                ["Fondue.png"])
            it_s_bm=list(
                ["Galettes-de-pommes-de-terre.png", "Risotto-au-chorizo.png"])
            it_s_c=list(
                ["Pates-aux-crevettes.png"])
            it_m_bm=list(
                ["Poulet-au-roquefort.png", "Escalopes-milanaises.png"])
            it_m_c=list(
                ["Sole-meuniere.png", "Steak-de-thon.png", "Steak-tartare.png", "Tagliata-de-boeuf.png"])
            it_d_bm=list(
                ["Poulet-curry.png", "Riz-cantonais.png"])
            it_d_c=list(
                ["Filet-de-truite-saumonee.png"])
            st_s_bm=list(
                ["Galettes-de-pommes-de-terre.png","Hachis-parmentier.png"])
            st_s_c=list(
                ["Porc-au-caramel.png"])
            st_m_bm=list(
                ["Tartiflette.png","Poulet-et-creme-de-citron.png"])
            st_m_c=list(
                ["Filet-mignon-de-porc-a-la-moutarde.png", "Jambalaya-poulet.png"])
            st_d_bm=list(
                ["Gnocchis.png"])
            st_d_c=list(
                ["Poulet-de-Bresse.png"])
        
            liste_choix = (
                [iq_s_bm, iq_m_bm, iq_m_c, it_s_bm, it_s_c, it_m_bm, it_m_c, it_d_bm, it_d_c, st_s_bm, st_s_c, st_m_bm,
                st_m_c, st_d_bm, st_d_c])
        
            nom_image = temps + '_' + difficulte + '_' + prix
        
            #la variable recette va vérifier lorsque la variable nom_image est égale à une variable dans la liste de choix.
            recette = [s for s in liste_choix if nom_image in s]
            
            # lorsque c'est le cas, la variable a1 va sortir une valeur aléatoire dans la liste concernée
            a1 = str(random.choice(recette))
            
            #le lien vers l'image final peut don être crée à l'aide de la ligne de code suivante :
            image_final = str(PhotoImage(file=("mini-projet/all"+a1)))
        
            #l'image va s'afficher sur le canevas final comme :
            canevas_final = Canvas.create_image(0, 0, image=image_final, anchor='nw')
        


        Les news :
        - Si je créer juste une partie en POO (ici la partie root avec tkinter) c'est ok,
        - Je n'ai effectivement pas utilisé ta méthode pour les images car je n'ai pas très bien saisi comment cela fonctionnait, donc pas de module glob,
        - Le rendu est pour demain 8h.

        Serais-ce possible d'obtenir de l'aide sur :
        -la syntaxe du bouton "afficher recette",
        -la syntaxe global et l'ordre des choses du programme,

        Peux-tu éclairer les erreurs suivantes que PyCharm m'affiche :


        Voilà, tout ceci accompagné d'un énorme s'il-te-plaît,

        Merci encore à toi pour ta future aide.
        0
    4. Bonjour,

      Si les noms d'images correspondent aux 3 critères comme je te le disais, ça évite de mettre la liste des images dans le code et donc de l'éditer à chaque fois que l'on veut mettre la liste à jour

      Sans POO, ca donnerait ça, en admettant que les fichiers s'appellent:
      it_s_bm_01.JPG
      it_s_bm_02.JPG
      st_m_c_01.JPG
      etc ...

      from tkinter import *
      from tkinter import ttk
      from PIL import Image, ImageTk
      import glob
      import random
      
      global criteres
      
      def liste_images():
          ''' Liste des fichiers images du répertoire courant'''
      
          images, noms_images = [], []
          
          for f in glob.glob('*.jpg'):
              noms_images.append(f)
              images.append(ImageTk.PhotoImage(Image.open(f)))
      
          return(images, noms_images)
      
      def affiche_recette():
          ''' Affichage d'une image au hasard en fonction des 3 critères sélectionnés '''
      
          recettes_possibles = []
      
          recette_possible  = dic[criteres[0]] + '_' +dic[criteres[1]] + '_' +dic[criteres[2]]
          for k in range(len(noms_images)):
              if(recette_possible in noms_images[k]): recettes_possibles.append(images[k])
      
          recette = random.choice(recettes_possibles)
          graph_area.create_image(0,0,image = recette, anchor = 'nw')
      
      def valeur_combo(event, c, x):
          ''' Valeur de Combobox c '''
      
          criteres[x] = c.get()
      
      
      WIDTH, HEIGHT = 540, 250
      bg_col = 'salmon1'
      
      main_win = Tk()
      main_win.configure(background = bg_col)
      main_win.title('Recettes')
      main_win.geometry(str(WIDTH)+'x'+str(HEIGHT)+'+300+100')
      
      L1 = Label(main_win, text = 'Temps de préparation', bg = bg_col)
      L1.place(x = 10,y = 10)
      
      c_valeurs=["< 15 min","< 30 min","> 30 min"]
      c1 = ttk.Combobox(main_win, values=c_valeurs)
      c1.current(0)
      c1.place(x = 150,y = 10)
      c1.bind("<<ComboboxSelected>>", lambda  evt, c = c1, x=0 : valeur_combo(evt, c, x))
      
      L2 = Label(main_win, text = 'Difficulté', bg = bg_col)
      L2.place(x = 10,y = 50)
      
      c_valeurs=["Facile","Moyen","Difficile"]
      c2 = ttk.Combobox(main_win, values=c_valeurs)
      c2.current(0)
      c2.place(x = 150,y = 50)
      c2.bind("<<ComboboxSelected>>", lambda  evt, c=c2, x=1 : valeur_combo(evt, c, x))
      
      L3 = Label(main_win, text = 'Prix', bg = bg_col)
      L3.place(x = 10,y = 90)
      
      c_valeurs=["Bon marché","Cher"]
      c3 = ttk.Combobox(main_win, values=c_valeurs)
      c3.current(0)
      c3.place(x = 150,y = 90)
      c3.bind("<<ComboboxSelected>>", lambda  evt, c=c3, x=2 : valeur_combo(evt, c, x))
      
      b = Button(main_win, text = 'Afficher recette', command = affiche_recette)
      b.place(x = 10,y = 130)
      
      graph_area = Canvas(main_win,height=200,width=200)
      graph_area.place(x = 300,y = 10)
      
      criteres = ['','','']
      dic = {'< 15 min':'iq','< 30 min':'it','> 30 min':'st','Facile':'s','Moyen':'m','Difficile':'d','Bon marché':'bm','Cher':'c'}
      images, noms_images = liste_images()
      
      main_win.mainloop()
      0