Liste à nom variable

Fermé
farreneit Messages postés 282 Date d'inscription jeudi 5 juillet 2012 Statut Membre Dernière intervention 13 janvier 2023 - Modifié le 2 déc. 2022 à 10:12
mamiemando Messages postés 33361 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 15 novembre 2024 - 2 déc. 2022 à 14:29

Bonjour,

Je fais de nouveau appel à votre aide pour un autre problème auquel je suis confronté.

Chaque sous-liste correspond à un cours, et chacun éléments de cette sous-liste correspond aux leçons correspondantes.

J'ai créé ma fonction permettant d'ajouter un nouveau cours :

def ajout_cours():
    nouveau_cours = 0
    if "temporaire" in listecours:
        listecours.remove("temporaire")
        print("\n\n\nIl n'y a pas encore de cours enregistré.\n")
    else:
        print("\n\n\nVoici la liste des cours : \n", listecours)
    nouveau_cours = input("\nEntrez le nom du cours à ajouter : \n")
    listecours.append(nouveau_cours)
    print("\n\nListe des cours : \n", listecours)

try:
    print(listecours)
except NameError:
    listecours = ["temporaire"]

ajout_cours()

J'aimerai que l'utilisateur puisse créer une leçon, et donc créer une liste portant le nom du cours qui vient d'être créé.

Ma question est la suivante : 

Comment puis-je programmer la creation d'une liste, avec un nom variable ?

Merci d'avance et bonne soirée !

4 réponses

yg_be Messages postés 23327 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 15 novembre 2024 Ambassadeur 1 551
Modifié le 1 déc. 2022 à 22:27

bonjour,

Tu pars dans une mauvaise direction en voulant ainsi "nommer" une liste.  Ce que tu souhaites faire, c'est, pour chaque cours, mémoriser deux éléments, un texte, et une liste de leçons.

La liste ne "porte" pas le nom du cours, tu crées une structure pour mémoriser un texte et une liste.

Puisque tu fais un exercice avec des listes, tu peux donc décider qu'un cours est une liste de deux éléments, le premier étant un texte, le second étant une liste, la liste des noms des leçons.

cours1=("nomdupremiercour",("nom d'une leçon", "nom d'une autre leçon"))
cours2=("nomdusecondcour",("nom d'une leçon du 2", "nom d'une autre leçon du 2"))
ecole=(cours1,cours2)
for c in ecole:
    nomducours,listelecons = c
    print("cours:", nomducours)
    for lecon in listelecons:
        print("    leçon:",lecon)
1
farreneit Messages postés 282 Date d'inscription jeudi 5 juillet 2012 Statut Membre Dernière intervention 13 janvier 2023 10
Modifié le 2 déc. 2022 à 10:16

Merci pour ta réponse. Effectivement, je suis peut-être mal parti.

L'idée était en fait de laisser le choix à l'utilisateur de la création de cours et de leçons par lui-même. Il faudrait ensuite qu'il puisse trier les cours, ou les leçons en fonction d'un paramètre "nombre de révisions".

Voici le code entier (incomplet) :

def debut():
    choix = 0
    print("Que souhaitez-vous faire ?\n")
    print("1 : Déclarer une révision")
    print("2 : Consulter l'ordre de mes révisions")
    print("3 : Ajouter/supprimer un cours/leçon\n")
    choix = input("Choisissez 1, 2 ou 3 : ")

    if choix == "1":
        declaration()
    elif choix == "2":
        ordre()
    elif choix == "3":
        modification()
    else:
        print("Réponse incorrecte")
        debut()

def declaration():
    #afficher la liste des cours
    print("")

def ordre():
    choix = 0
    print("\n\n\nComment voudriez-vous voir l'ordre ? \n")
    print("1 : Consulter l'ordre de mes révisions par cours")
    print("2 : Consulter l'ordre de mes révisions par leçons")
    print("0 : Retour au menu\n")
    choix = input("Choisissez 1, 2 ou 0 : ")

    if choix == "1":
        ordre_cours()
    elif choix == "2":
        ordre_leçon()
    elif choix == "0":
        debut()
    else:
        print("Réponse incorrecte")
        ordre()

def modification():
    choix = 0
    print("\n\n\nVoulez-vous ajouter ou supprimer un cours/leçon ?\n ")
    print("1 : ajouter un cours/leçon")
    print("2 : supprimer un cours/leçon")
    print("0 : Retour au menu\n")
    choix = input("Choisissez 1, 2 ou 0 : ")
    if choix == "1":
        ajout()
    elif choix == "2":
        suppression()
    elif choix == "0":
        debut()
    else:
        print("Réponse incorrecte")
        modification()

def ajout():
    choix = 0
    print("\n\n\nVoulez-vous ajouter un cours ou une leçon ? \n")
    print("1 : ajouter un cours")
    print("2 : ajouter une leçon")
    print("3 : Précèdent")
    print("0 : Retour au menu\n")
    choix = input("Choisissez 1, 2, 3 ou 0 : ")

    if choix == "1":
        ajout_cours()
    elif choix == "2":
        ajout_lecon()
    elif choix == "3":
        modification()
    elif choix == "0":
        debut()
    else:
        print("Réponse incorrecte")
        ajout()

def suppression():
    choix = 0
    print("\n\n\nVoulez-vous suprimmer un cours ou une leçon ? \n")
    print("1 : suprimmer un cours")
    print("2 : suprimmer une leçon")
    print("3 : Précèdent")
    print("0 : Retour au menu\n")
    choix = input("Choisissez 1, 2, 3 ou 0 : ")

    if choix == "1":
        suppression_cours()
    elif choix == "2":
        suppression_lecon()
    elif choix == "3":
        modification()
    elif choix == "0":
        debut()
    else:
        print("Réponse incorrecte")
        suppression()

def ajout_cours():
    nouveau_cours = 0

    if "temporaire" in listecours:
        listecours.remove("temporaire")
        print("\n\n\nIl n'y a pas encore de cours enregistré.\n")
    else:
        print("\n\n\nVoici la liste des cours : \n", listecours)

    nouveau_cours = input("\nEntrez le nom du cours à ajouter : \n")
    listecours.append(nouveau_cours)
    print("\n\nListe des cours : \n", listecours)

print("Bonjour !\n")
try:
    print(listecours)
except NameError:
    listecours = ["temporaire"]
debut()

Est-ce que tu penses toujours que je dois passer par ta méthode ?

Merci encore

0
mamiemando Messages postés 33361 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 15 novembre 2024 7 800
2 déc. 2022 à 10:35

Bonjour,

Avant de plonger dans le code, je t'invite à d'abord réfléchir à la conception de ton programme.

1) Quelle est la la nature des données (ce qui correspond aux objets en programmation orientée objet) que doit manipuler le programme ?

  • Qu'est-ce qui caractérise un cours ? Un nom et un liste de leçons ?
  • Qu'est-ce qui caractérise un leçon ? Un nom et un nombre de révision ?

2) Quelles sont les fonctionnalités (ce qui correspond aux méthodes en programmation orientée objet) que doit réaliser le programme ?

  • Création, liste, modification et suppression de cours ? Lister les leçons d'un cours ? Autre chose concernant les cours ? Quels sont les paramètres de chacune de ces fonctionnalités ? Par exemple, est-ce que lorsque tu listes les leçons d'un cours, l'énoncé attend de toi que tu puisses spécifier dans quel ordre dans lesquels les retourner ? Si oui, quels sont ces ordres ?
  • Même questions pour les leçons.

3) Quelles sont les contraintes de programmation imposées par l'énoncé (ou tes connaissances). Connais-tu les classes et as-tu le droit de les utiliser ? Dois-tu te limiter au listes ?

Ce que je peux dire vu le message #4 :

  • Tous les menus ne sont que de l'interface. En vrai c'est assez secondaire et tu peux tout à fait tester les différentes primitives que tu auras choisi d'implémenter dans ton programme principale en reproduisant les choix qu'auraient pu faire un utilisateur. Cela t'évitera de faire une saisie à chaque fois que tu veux traiter ton programme. Il sera toujours temps de l'exécuter au travers de ces menus par la suite.
  • Tu devrais éviter d'employer des caractères accentués ou des cédilles dans tes noms de fonctions, car il y a de fortes chances pour que ton interpréteur python n'apprécie pas.
  • Tu devrais nommer tes fonctions de sorte à les organiser par leur nom pour améliorer la lisibilité de ton programme. Par exemple toutes les fonctions en rapport avec un menu devraient sans doute avoir un nom qui commence par "menu_...". Car a terme j'imagine que tu auras des fonctions comme supprimer_cours ou supprimer_lecon et il ne faudrait pas qu'elles s'appellent toutes suppression :-)
  • Quel est le rôle des leçons temporaire ? Ce n'est pas précisé dans l'énoncé que tu nous as transmis ?
  • Ta fonction ajout_cours mélange des fonctionnalités a priori indépendantes les unes des autres.Pourquoi supprimer un cours temporaire ? Ce devrait être le rôle de l'appel supprimer_cours(cours, "temporaire") ? Pourquoi initialises-tu nouveau_cours à 0. En python ce serait plutôt None, et surtout, cette variable sera initialisée quoi qu'il arrive une fois que l'input correspondant aura été exécuté. L'initialisation à 0 (ou None) est donc superflue.

Bonne chance

1
farreneit Messages postés 282 Date d'inscription jeudi 5 juillet 2012 Statut Membre Dernière intervention 13 janvier 2023 10
Modifié le 2 déc. 2022 à 11:29

Merci beaucoup pour ta réponse et tes conseils.

Je vais essayer de répondre au mieux :

1)

  • Un cours est caractérisé par son nom et par les leçons qui le compose
  • Une leçon est caractérisée par son nom et par un nombre de révisions

2)

  • Je n'ai pas d'enoncé précis. L'idée est, comme la fonction "menu" l'indique, de pouvoir : 
    • Déclarer une révision : Qui me permettra de choisir un cours et une leçon de ce cours pour lui ajouter '+1' au nombre de revisions
    • Consulter l'ordre des revisions: Qui permettra soit :
      • de trier et d'afficher la liste des leçons (tout cours confondu) en fonction du nombre de révision 
      • de trier et d'afficher la liste des leçons pour chaque cours en fonction du nombre de révision
    • Ajouter ou supprimer un cours ou une leçon
      • ajouter un cours ou une leçon
        • ajouter un cours
        • ajouter une leçon
      • supprimer un cours ou une leçon
        • supprimer un cours
        • supprimer une leçon

3) Mes connaissances me limitent beaucoup, mais c'est le but de ce programme, d'apprendre de nouvelles choses.

J'ai commencé à apprendre les classes, je voulais justement les utiliser pour mes leçons afin de leur donner le paramètre de nombre de révision.

  • Effectivement, ce n'est que de l'interface. J'avais choisi de commencer par là car c'est ce qui me semblait le plus simple et me permet de voir mon programme avancer ahah. Je me faisais ensuite des raccourcis pour accéder directement à la fonction sur laquelle je suis en train de travailler.
  • C'est un point que j'avais retenu, donc il ne me semble pas avoir laissé de caractère spécial dans les noms de variables (j'en ai laissé sur du texte affiché). Mais peut être que j'en ai laissé sans faire exprès
  • C'est noté merci
  • la leçon temporaire et le moyen que j'ai trouvé pour déclarer ma liste (afin que l'utilisateur puisse ajouter un premier cours), sans qu'il n'y ait rien dedans au préalable. Ainsi, au début de mon programme je teste si ma liste existe. Si elle existe tant mieux, sinon je la créais en lui ajoutant 'temporaire' dedans. Puis dans ma fonction d'ajout de cours, je regarde si ma liste contient 'temporaire', si c'est le cas, j'indique qu'il n'y a pas encore de cours enregistré, et je viens supprimer 'temporaire' pour avoir une liste vide. Si ce n'est pas le cas, je peux afficher la liste des cours.

J'éspère avoir pu être clair.

Je vais retravailler avec tes conseils.

Merci beaucoup !

1

As-tu essayé le code que tu nous présentes?
Tu parles de liste de listes, ce n'est pas ce que je trouve ici. Ça ressemble à une liste de chaînes.
Pourquoi créer une liste avec un nouveau nom? Tu fournis le nom de la liste dans le code.
Tu appelles ta fonction sans paramètre. Donc, la liste n'est pas fournie et non initialisée.

0
yg_be Messages postés 23327 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 15 novembre 2024 1 551
1 déc. 2022 à 22:47

Son code est incomplet, il a commencé à l'écrire avant de réfléchir à ses structures de données.

En effet, il a pour le moment une liste de chaines, chaque chaine étant le nom d'un cours.

Il souhaite maintenant mémoriser, pour chaque cours, en plus du nom du cours, une liste de chaines, chaque chaine étant le nom d'une leçon.

Il cherche donc à représenter chaque cours comme une liste "nommée" de leçons.

1
mamiemando Messages postés 33361 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 15 novembre 2024 7 800
Modifié le 2 déc. 2022 à 14:36

 Bonjour,

Étant donnée la réponse #6, la manière la plus naturelle d'aborder ton problème est d'écrire comme je le suggérais dans le message #4 d'écrire deux classes (respectivement Cours et Lecon). Bon si comme tu trouves ça moche par ce que ça fait "le con", tu peux rédiger ton programme en anglais (donc Lesson et Course), c'est plutôt une bonne habitude d'ailleurs dans l'absolu. Mais bref, je vais garder les mots français.

La classe Lecon est caractérisée par un nom et un nombre de revision donc elle ressemblerait à :

class Lecon:
    def __init__(self, nom: str, num_revisions: int = 0):
        self.nom = nom
        self.num_revisions = num_revisions
    def __repr__(self) -> str:
        return f"<self.__class_.__name__>({repr(self.nom)}, {self.num_revisions})"

Pour l'utiliser on peut par exemple écrire :

lecon = Lecon("ma leçon", num_revisions = 10)
print(lecon)
# Affiche <Lecon>('ma leçon', 10)

La classe Cours est caractérisée par un nom et un itérable (une liste par exemple) de Lecons. Vu qu'un cours est composé de 0 ou plusieurs leçons, il serait assez naturel de faire hériter la classe Cours de la classe list ce qui permettrait de bénéficier directement de ses méthodes sans avoir à les réimplémenter, en particulier son nombre d'élément, la possibilité d'itérer dessus, etc.

class Cours(list):
    def __init__(self, nom = "", *cls, **kwargs):
        kwargs.pop("nom", None)
        super().__init__(*cls, **kwargs)
        self.nom = nom
    def __repr__(self) -> str:
        return f"{self.__class__.__name__}<{self.nom}, {super().__repr__()}>"

Pour l'utiliser, on peut par exemple faire ceci : 

cours_maths = Cours("Maths", [Lecon(f"Leçon {i}", i * 2) for i in range(5)])
for lecon in cours_maths:
    print(lecon)
# Affiche :
# <Lecon>('Leçon 0', 0)
# <Lecon>('Leçon 1', 2)
# <Lecon>('Leçon 2', 4)
# <Lecon>('Leçon 3', 6)
# <Lecon>('Leçon 4', 8)

Ensuite, vu qu'il s'agit d'une liste, tu peux parfaitement utiliser la fonction sorted pour réordonner les éléments comme bon te semble (en particulier, avec une callback qui regarde le nombre de révisions de chacune des Lecons stockées dans le Cours).

print(sorted(cours_maths, key=lambda lecon: lecon.num_revisions))
#[<Lecon>('Leçon 0', 0),
# <Lecon>('Leçon 1', 2),
# <Lecon>('Leçon 2', 4),
# <Lecon>('Leçon 3', 6),
# <Lecon>('Leçon 4', 8)]

print(sorted(cours_maths, key=lambda lecon: lecon.num_revisions, reverse=True))
#[<Lecon>('Leçon 4', 8),
# <Lecon>('Leçon 3', 6),
# <Lecon>('Leçon 2', 4),
# <Lecon>('Leçon 1', 2),
# <Lecon>('Leçon 0', 0)]

Libre à toi de définir une méthode dans Cours, par exemple afficherLecons, qui itère sur le résultat de sorted pour faire l'affichage de ton choix.

Je te laisse également consulter les méthodes de liste pour voir comment les utiliser (suppression, mise à jour, etc.) et éventuellement les surcharger si le besoin s'en fait sentir.

Bonne chance

0