Résolue

Développement d'un projet de gestion de menus hebdomadaires

# Dictionnaires # Fonctions # Dates

Bonjour, je suis la formation sur Udemy. J'en suis à la gestion de la date. J'ai l'impression de connaître les pièces du puzzle mais j'ai du mal à les assembler ... Je souhaite un peu pratiquer ce que j'ai déjà appris afin d'être plus à l'aise avant de continuer la formation. J'ai un petit projet personnel de gestion des menus hebdomadaires avec une liste de course générée automatiquement par rapport aux plats choisis. (en bref et résumé). Je pense avoir générer un dictionnaire qui me permettra de récupérer facilement les informations et de pouvoir les modifier dans le futur. J'y ai mis quelques exemples pour illustrer mon propos (mais je souhaiterais laisser libre l'utilisateur d'ajouter lui-même les catégories, recettes, ingrédients etc, ce n'est qu'un exemple). Pourriez-vous m'aider à mettre le pied à l'étrier ? Voilà ce que j'ai réalisé :

# créer un dictionnaire où je peux y stocker une catégorie de plat, puis une recette associée à une ou plusieurs catégories puis une liste d'ingrédients

Joyeux_Menu = {
    "Catégories":{
        "Snack":["Pancakes", "Omelette"],
        "Volaille": ["Poulet rôti", "Salade César"]
    },
    "Recettes":{
        "Pancakes" : {
            "Catégories": ["Snack",],
            "Ingrédients": {
                "farine":{
                    "Quantité": 100,
                    "Unité": "g",
                },
                "lait":{
                    "Quantité": 100,
                    "Unité": "mL",
                },
            },
        },
        "Poulet rôti": {
            "Catégories": ["Volaille",],
            "Ingrédients": {
                "poulet": {
                    "Quantité": 100,
                    "Unité": "g",
                },
                "compote": {
                    "Quantité": 100,
                    "Unité": "g",
                },

            },
        },
    },
}
print(Joyeux_Menu)


# Créer un menu où je peux afficher les options suivantes:

#   Afficher les catégories
#   Afficher les recettes d'une catégorie
#   Afficher les ingrédients d'une recette

#   Ajouter une recette
#       Définition de la ou des catégories (Création d'une nouvelle ou ajout si déjà existante)
#       Définition du nom de la recette
#       Ajout des ingrédients
#       Définition de la quantité de l'ingrédient
#       Définition de l'unité de quantité de l'ingrédient
#   Supprimer une recette

#   Modifier la recette
#       Ajouter une catégorie à une recette
#       Supprimer une catégorie à une recette
#       Changer la catégorie d'une recette
#       Modifier les ingrédients d'une recette
#           Supprimer des ingrédients
#           Ajouter des ingrédients
#           Modifier les ingrédients (Nom de l'ingrédient, quantité de l'ingrédient, unité de quantité de l'ingrédient)

#   Renommer une catégorie

# Créer un deuxième menu où je peux utiliser toutes les informations du premier menu:
#   Attribuer une catégorie de repas à un jour de la semaine
#   Pouvoir choisir une recette contenue dans la catégorie définie pour chaque jour de la semaine
#   Pouvoir générer une liste de course sur base des plats voulus pour tous les jours de la semaine
#
# Créer une fonction pour chaque option pour faciliter la lecture du code (gestion des modules et du fichier principal)

Gabriel Trouvé

Mentor

Salut :)

J'ai quelques pistes.

Déjà est-ce que tu sauvegardes tout ça en mémoire Python, ou sur un Json ?
Au passage : projet Django intéressant à faire et largement faisaible (c'est le dev django qui parle ahah).

Tu connais déjà les fonctions et classes ?
Je pars du principe que non pour le moment.

Je pars sur le principe que j'utilise ton dict.
je te donne des pistes, mais je te laisse réfléchir :

  • Pourquoi pas une while pour ton programme principal... ^^

  • Et imagine si je veux afficher les catégories à l'utilisateur :

    categories = Joyeux_Menu["Catégories"]
    for categorie in categories:
        print(categorie)
    

Là il sait ce qu'il y a en catégories.

  • Puis s'il souhaite afficher les recettes d'une catégorie
    categories = Joyeux_Menu["Catégories"]
    for categorie in categories:
        print(categorie)
    
    
    choice = input("Quelle catégorie ? ")
    print(categories.get(choice))
    

Exemple :

Et ainsi de suite, tu peux facilement manipuler les éléments, en ajouter, supprimer, modifier etc.
Là, j'ai tous mis sans fonction, sans rien. C'est vraiment juste pour te donner des idées et te lancer.

Tu vois comment tu peux manipuler les éléments ? Est-ce que ça permet de te lancer ? ^^

Hello !
Merci pour ta réponse !

Oui je compte tout enregistrer sur un fichier JSON !
Django, je ne suis pas encore arrivé jusque là ! Je suis à la section 55 (donc le paragraphe sur l'orienté objet).
Mais je dois dire que j'ai l'impression de ne pas maîtriser suffisamment les points antérieurs. J'ai eu le cours sur les fonctions.
Les classes j'ai pas bien compris ce que c'était.
Au sujet des boucles, oui je compte itérer sur chaque jour avec une boucle for et créer une boucle while pour que l'utilisateur choisisse sa catégorie.
Je me suis aider avec l'IA (qui a réussi à me générer un code qui marche plutôt bien d''ailleurs). Pour avoir un exemple mais je veux avoir le plaisir d'écrire ce code moi-même. Mais je ne comprends pas tout ... notament les boucles for ou if du style : if categorie in (key for key in Joyeux_Menu["Categories"]):
Je comprends bien qu'on cherche si la catégorie est présente dans les clés du dictionnaire ["Catégories"] mais que veut dire le key fo key ? Si je décompose tout, il cherche la catégorie qui est la clé parmi toutes les clés du dictionnaire.
Moi j'aurais juste envie d'écrire : If categorie in Joyeux_menu["Categories"] ...

Re ^^

Oui ce que tu veux écrire fonctionne. Alors là l'IA te fait faire une expression génératrice. Je ne pense pas que ça soit utile ici, et je ne le ferai pas je pense...

categories = (k for k in Joyeux_Menu["Catégories"])

categories est un générateur ici. Là l'IA veut te compliquer la vie. Il faut que tu sois à l'aise avec les compréhensions de liste et les expressions génératrices si tu veux les utiliser.
Si tu veux voir ce qu'il y a dans ton générateur tu peux faire :
print(list(categories))

Mais attention, tu vas consommer ton expression en faisant un print de cette façon. Donc si tu veux l'utiliser de nouveau, il faut la créer de nouveau... Tout ça pour dire, n'utilises pas ça pour le moment ahah.

Tu peux continuer avec :

if categorie in Joyeux_Menu["Catégories"]:
    ...

Surtout, n'hésites pas à revoir, et revoir (si besoin) les concepts de base. Si ça peut te rassurer, quand j'ai commencé j'ai fait deux fois la formation de base de Thibault :).

Pour ton projet, pour commencer reste simple, utilise les bases, n'utilises pas ce que l'ia te donne pour le moment.

Quelques ressources :
https://www.docstring.fr/formations/faq/boucles/comment-creer-et-utiliser-des-generateurs-en-python/
https://docs.python.org/fr/3.10/reference/expressions.html#generator-expressions

J'ai bossé de mon côté en relisant les glossaires et les chapitres de la formation de Thibaut. Je n'ai utilisé l'IA que pour des questions précises, par exemple quand je n'arrivais pas à afficher une valeur précise du dictionnaire. Mon frère m'a conseillé de rajouter la ligne raise, mais je ne la comprends pas encore. Voila ce que j'ai écris. Est-ce que je pars dans la bonne direction ?

Joyeux_Menu = {
    "Categories":{
        "Snack":["Pancakes", "Omelette"],
        "Volaille": ["Poulet rôti", "Salade César"]
    },
    "Recettes":{
        "Pancakes" : {
            "Categories": ["Snack",],
            "Ingredients": {
                "farine":{"Quantite": 100, "Unite": "g"},
                "lait":{"Quantite": 100, "Unite": "mL"},
            },
        },"Omelette" : {
            "Categories": ["Snack",],
            "Ingredients": {
                "farine":{"Quantite": 100, "Unite": "g"},
                "lait":{"Quantite": 100, "Unite": "mL"},
            },
        },
        "Poulet rôti": {
            "Categories": ["Volaille",],
            "Ingredients": {
                "poulet": {"Quantite": 100, "Unite": "g"},
                "compote": {"Quantite": 100, "Unite": "g"},
            },
        },"Salade César": {
            "Categories": ["Volaille",],
            "Ingredients": {
                "poulet": {"Quantite": 100, "Unite": "g"},
                "compote": {"Quantite": 100, "Unite": "g"},
            },
        },
    },
}

# Créer un deuxième menu  je peux utiliser toutes les informations du premier menu:
#   Attribuer une catégorie de repas à un jour de la semaine

agenda = {
    "lundi": {"categorie": None, "recette": None},
    "mardi": {"categorie": None, "recette": None},
    "mercredi": {"categorie": None, "recette": None},
    "jeudi": {"categorie": None, "recette": None},
    "vendredi": {"categorie": None, "recette": None},
    "samedi": {"categorie": None, "recette": None},
    "dimanche": {"categorie": None, "recette": None},
}

#   Parcourir chaque jour pour demander la catégorie
def assigner_categorie(agenda: dict) -> dict:
    """
    Assigne une catégorie de repas à chaque jour de la semaine dans le dictionnaire "agenda".

    La fonction parcourt les jours de la semaine présents dans le dictionnaire `agenda` et
    demande à l'utilisateur de choisir une catégorie parmi celles définies dans
    `Joyeux_Menu["Categories"]`. La catégorie choisie est ajoutée sous la clé "categorie"
    pour chaque jour.

    :param agenda: dict
        Un dictionnaire contenant les jours de la semaine comme clés, avec des sous-dictionnaires
        pour chaque jour.

    :raises KeyError:
        Si une catégorie saisie par l'utilisateur n'est pas présente dans `Joyeux_Menu["Categories"]`.

    :return: dict
        Le dictionnaire `agenda` mis à jour, incluant la catégorie attribuée à chaque jour.
    """
    print(f" Les catégories disponibles sont : {list(Joyeux_Menu["Categories"].keys())}") # !!! En interface graphique, un onglet avec menu déroulant affichera les catégories disponibles
    for jour in agenda:
        cat = input(f"Quelle catégorie souhaites-tu attribuer à {jour} ?")
        if cat not in Joyeux_Menu["Categories"]:
            raise KeyError("Cette catégorie n'existe pas.")
        else:
            agenda[jour]["categorie"] = cat
    return agenda

assigner_categorie(agenda)

#   Pouvoir choisir une recette contenue dans la catégorie définie pour chaque jour de la semaine

def assigner_recette(agenda: dict) -> dict:
    """
        Associe une recette à chaque jour de la semaine en fonction de la catégorie.

        Parcourt l'agenda, affiche les recettes disponibles pour chaque catégorie,
        demande à l'utilisateur de choisir une recette, et l'ajoute au jour correspondant.

        :param agenda: dict
            Dictionnaire contenant les jours de la semaine avec leurs catégories et recettes.
        :return: dict
            L'agenda mis à jour avec les recettes choisies.
        :raises KeyError:
            Si la recette saisie n'est pas disponible dans la catégorie.
        """
    for jour in agenda:
        categorie = agenda[jour]["categorie"]
        recettes = Joyeux_Menu["Categories"].get(categorie)
        print (f"Les recettes disponibles sont : {recettes}.")
        rec = input(f"Quelle recette souhaites-tu pour {jour} ?")
        if rec not in recettes:
            raise KeyError("Cette recette n'existe pas.")
        else:
            agenda[jour]["recette"] = rec
    return agenda

assigner_recette(agenda)

#   Pouvoir générer une liste de course sur base des plats voulus pour tous les jours de la semaine

def creation_liste_de_course(agenda : dict, Joyeux_Menu :dict) -> None :
    """
    Génère et affiche une liste de courses à partir des recettes assignées dans l'agenda.

    Parcourt l'agenda pour récupérer les ingrédients des recettes, additionne les quantités
    pour les ingrédients communs, et affiche la liste finale avec les noms, quantités totales,
    et unités des ingrédients.

    :param agenda: dict
        Contient les jours de la semaine et les recettes assignées.
    :param Joyeux_Menu: dict
        Contient les recettes et leurs ingrédients associés.
    :return: None
        Affiche directement la liste de courses.
    """
    liste_de_course = {}
    for jour in agenda:
        recette = agenda[jour]["recette"]
        ingredient = Joyeux_Menu["Recettes"][recette]["Ingredients"]
        for ing, mesure in ingredient.items():
            quantite = mesure["Quantite"]
            unite = mesure["Unite"]
            if ing not in liste_de_course:
                liste_de_course[ing] = {"Quantite": quantite, "Unite": unite}
            else:
                liste_de_course[ing]["Quantite"] += quantite
    for ing, details in liste_de_course.items():
        print(f"{ing} : {details['Quantite']}{details['Unite']}")


creation_liste_de_course(agenda, Joyeux_Menu)

Gabriel Trouvé

Mentor

Super sympa ce que tu as fait... Tu vois, tu as envie de séparer les choses. Tu as fait différentes fonction. Tu vas t'améliorer au fur et à mesure, jusqu'à le faire en POO peut-être ?

En attendant, tu pourrais penser à la saisie utilisateur en évitant de planter le programme, mais de gérer une mauvaise saisie avec une boucle :)

Et même gérer la casse avec des méthodes de chaines de caractères par exemple.

Je te donne des petits indices, mais en tous cas bravo !

Merci ! L'orienté objet c'est bientôt dans le programme ! Là je n'y suis pas encore... Je vais m'atteler à la création des recettes avec la saisie utilisateur du coup. Par contre je ne connais pas encore les méthodes de chaines de caractères. Je vais étudier ça ! Merci !

Gabriel Trouvé

Mentor

Super ! Très important les méthodes sur les str :)

N'hésites pas à passer un peu de temps dessus.

Au plaisir ^^

J'ai pas mal travaillé sur mon code depuis ma dernière question. J'ai travaillé aussi sur les méthode de chaine de caractère (je ne l'ai peut être pas fait partout ...).

J'ai trois questions :

-1- J'ai quand même beaucoup de répétition dans mon code, j'aimerais bien passer sur la POO. J'ai regardé les videos sur docstring, sur d'autres site et avec l'IA. Mais j'ai dû mal à comprendre comment je dois faire avec mon code ... Vous auriez une idée ?

-2- J'aimerais faire une interface graphique par la suite mais je n'ai suivi absolument aucune formation à ce sujet pour l'instant. Est-ce que mon code doit tenir compte de l'interface graphique ou alors je peux faire mes fonctions sans y penser et je pourrai par la suite créer l'interface graphique comme je le veux ?

-3- Pour la sauvegarde, j'hésite entre le JSON et le SQL. Je ne maitrise pas du tout pour l'instant le SQL car les exercices que j'ai fait était avec les JSON. Mais je souhaiterais par la suite rajouter d'autres informations sur mes ingrédients par exemple.

Merci beaucoup !!

Gabriel Trouvé

Mentor

Salut :)

Alors, tu peux faire ça en POO oui. Tu as pas mal d'éléments.

Tu peux avoir une logique : MVC (Model-View-Controller). Tu créés des classes Modèles, une classe Interface et une classe Controller.

Exemple en modèles tu aurais Recettes, Catégories etc...

Ce qui m'amène à te dire, que Django pourrait être une super solution :) Où tu aurais tes Modèles, Vues, et templates. Donc avec Django, tu utilises une BDD sqlite, Mysql, ou postgre en moyenne.

Si tu veux, tu peux faire ça autrement. Hors framework, et enregistré en json ou avec https://tinydb.readthedocs.io/en/latest/

Je t'ai donné quelques pistes ahah

Gabriel Trouvé

Mentor

Tiens, je me suis amusé à faire un petit exemple de MVC très simpliste : https://github.com/gabigab117/simplistic_mvc

Alors je n'ai pas ajouté de tests, mais ça peut te donner une idée. Par contre je ne gère pas trop les exceptions etc c'est assez simple. J'avais envie de me faire un gestionnaire de tâches.
Après tu peux t'amuser à save en JSON, ou tinyDB par exemple

Merci beaucoup pour tes réponses ! Je vais continuer à bosser tout ça ! Je vais regarder ton code, merci beaucoup !

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.