Python3 ensemble (set) et tri

Bonsoir,

J'étudie toujours le langage Python.
Dans le cadre de la conception d'un jeu du pendu encapsulé dans une classe et utilisant une interface graphique, j'utilise un ensemble car l'interêt c'est qu'il n'y a pas de doublons.
Si et seulement si j'ai bien compris, les ensembles ne peuvent pas être triés ? Il n'existe donc aucune fonction ou méthode permettant le trie pour ce type de séquence ...

Pour contourner le problème, je transforme mon ensemble en liste et j'utilise la fonction sorted qui me retourne un nouvel objet trié.

Voilà tout ça n'est pas clairement expliqué dans mes livres et je n'ai rien trouvé de précis sur le net (peut-être parce que c'est une évidence sauf pour moi :wink:).
Donc la question est : les ensembles peuvent-ils être triés au même titre que les listes, tuples et dictionnaires ?

Merci par avance et Bonne soirée.

En Python, vous ne pouvez pas trier directement un ensemble (set) car les ensembles sont par nature non ordonnés.

Cependant, vous pouvez trier les éléments d'un ensemble en les extrayant dans une liste en effet, en les triant dans cette liste, puis en créant éventuellement un nouvel ensemble à partir de la liste triée. (Mais l'ordre des éléments dans un ensemble est indéterminé)

Mais si le tri est important alors posez vous la question de la pertinence du choix de l’ensemble

Merci @J-M-L pour votre réponse. En fait je récupère toutes les lettres choisies par le joueur qui joue à mon jeu du pendu. Afin d’éviter les doublons, je les place dans un ensemble.
Jusqu’à concurrence du nombre de chances dont dispose le joueur, je compare les lettres du mot à trouver avec les lettres de l’ensemble, si ma fonction en trouve une, elle l’affiche sinon elle affiche une étoile. Le joueur a 8 chances donc si dans l’ensemble se trouve toutes les lettres du mot à découvrir et qu’il lui reste au moins une chance, il a gagné.
C’est le principe du jeu du pendu et l’ensemble simplifie le code en supprimant les doublons :wink:
Pour aider le joueur, je lui présente la liste triée des lettres qu’il a déjà utilisées et c’est là que je transforme l’ensemble en liste pour pouvoir la trier (c’est très simple).

Voilà vous avez répondu à ma question.
On ne peut pas trier un ensemble et c’est bien ce qui me semblait :wink:
Merci @J-M-L
Bonne soirée.

D’accord, je vois Le principe

Pourquoi ne pas faire le contraire en rajoutant un contrôle de non doublon à la liste lors de l'ajout ?

C’est aussi possible, faut juste rajouter le contrôle

Tout est possible :slight_smile: , c'était plus si il y voyait une contrainte que je n'aurais pas vu ou moins logique pour lui.

oui

def collecterEtTrierCaracteres():
    caracteres = []
    while True:
        caractere = input("Entrez un caractère (ou '$' pour quitter) : ")
        if caractere == '$':
            break
        if caractere not in caracteres:  # Vérifiez si le caractère n'est pas déjà dans la liste
            caracteres.append(caractere)
    return sorted(caracteres)  # Tri de la liste

liste = collecterEtTrierCaracteres()
print("Caractères triés : ", liste)

ou

def collecterEtTrierCaracteres():
    caracteres = set()  # Utilisation d'un ensemble pour des caractères uniques
    while True:
        caractere = input("Entrez un caractère (ou '$' pour quitter) : ")
        if caractere == '$':
            break
        caracteres.add(caractere)
    return sorted(caracteres)  # Tri de l'ensemble

liste = collecterEtTrierCaracteres()
print("Caractères triés : ", liste)

C’est juste parce que Python le fait pour toi avec un ensemble. Donc c’est du code en moins et plus de lisibilité.
De plus caster un ensemble en liste et la trier c’est simple, court et lisible.

PS : après si tu préfères ajouter un « contrôle de non doublon » alors que Python le fait tout seul. Libre à toi de l’appréhender de cette façon.

Merci @J-M-L
Bonne journée

Ba non Python comme tu le dis n'offre pas de trie sur un ensemble et tu es obligé de faire une conversion vers une liste!

PS: je ne préfère rien, je pose simplement une question, sur un choix alternatif au tien, si bien sûre tu me le permet!!!
Si Python fait tout seul le trie et le non doublon, du coup en fait tu n'a aucun problème :slight_smile:

Pour ma pars, j'en resterais donc là, sur cet échange!

Je te rappelle ta question.
Encore une fois tu fais tes chansons et tu les chantes :wink:
PS : je te remets en sourdine …

Je ne fais rien, ma question est simple et parle bien d'un jeu de donnée "triable" et sans doublon.
Encore une fois tu devrais malheureusement un peu plus t'appliquer tes dictons :frowning:

Bonne journée à toi :slight_smile:

bon, vous pouvez trier un ensemble, vous obtenez une liste mais rien ne vous empêche de remettre la liste dans un ensemble ensuite :slight_smile:

Ca tourne en rond quoi :rofl:
Sinon comme c'est toujours dans les vieux pots que l'on fait les meilleurs confitures, une bonne veille liste chainée et on a tout ce qu'il faut :face_with_hand_over_mouth:

gif-poisson.gif

Bonjour,
Sinon au final voilà à quoi ressemble ce jeu du pendu. Il fonctionne bien mais peut-être avec des imperfections au niveau du code. Je lai testé uniquement sur Mac.
Il comporte deux fichiers :

from donnes import *
import string
import tkinter as tk
from tkinter import ttk
from random import choice

class Pendu(tk.Tk):
    def __init__(self):
        self.var=""
        self.var2=""
        self.var3 =""
        self.var4=""
        self.lettre=""
        self.alphabet = list(string.ascii_uppercase)
        self.mot_a_trouver = self.choisir_mot()
        self.lettres_du_joeur = set()
        self.nb_chances = NB_COUPS
        self.mot_a_trouver = self.choisir_mot()
        self.mot_trouve=""
        
        super().__init__()
        self.create_menu_bar()
        self.creation_fenetre()
        self.var.set("*******")
        
    def nouveau(self):
        for children in fenetre.winfo_children():
            children.destroy()
        self.var=""
        self.var2=""
        self.var3 =""
        self.var4=""
        self.lettre=""
        self.alphabet = list(string.ascii_uppercase)
        self.mot_a_trouver = self.choisir_mot()
        self.lettres_du_joeur = set()
        self.nb_chances = NB_COUPS
        self.mot_a_trouver = self.choisir_mot()
        self.mot_trouve=""
        self.create_menu_bar()
        self.creation_fenetre()
        self.var.set("*******")
           
        
    def Combobox_action(self,event) -> str:
        self.lettre = self.listeCombo.get()
        self.lettre = self.lettre.lower()
        self.jeu()
        
    def choisir_mot(self) -> str:
        return choice(LISTE_MOTS)

    def recuperer_mot_masque(self,mot_complet: str, lettres_du_joeur: set[str]) -> str:
        mot_masque = ""
        for lettre in mot_complet:
            if lettre in lettres_du_joeur:
                mot_masque += lettre
            else:
                mot_masque +="*"
        return mot_masque

    def jeu(self):       
        if  self.mot_a_trouver != self.mot_trouve and self.nb_chances > 0:       
            if self.lettre in self.lettres_du_joeur:
                self.var2.set(f"vous avez déjà choisi cette lettre : {self.lettre}")
                self.nb_chances -=1
                
            elif self.lettre in self.mot_a_trouver:
                self.var2.set("bien joué")
                self.lettres_du_joeur.add(self.lettre)
                self.mot_trouve = self.recuperer_mot_masque(self.mot_a_trouver, self.lettres_du_joeur)
                self.var.set(self.mot_trouve)
            else:
                self.nb_chances -=1
                self.lettres_du_joeur.add(self.lettre)
                self.var2.set(f" non, la lettre {self.lettre} ne se trouve pas dans le mot")
                
            self.var3.set(f"encore {self.nb_chances} chances")
            #ici on trie en une ligne l'ensemble lettres_du_joeur
            self.var4.set(sorted(self.lettres_du_joeur))
            
        if self.mot_a_trouver == self.mot_trouve:
            self.var2.set(f"Félicitations ! Vous avez trouvé le mot {self.mot_a_trouver}.")   
        elif self.nb_chances == 0:
            self.var2.set("PENDU !!! Vous avez perdu.")
            
    def creation_fenetre(self):
        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=3)
     
        self.var2 = tk.StringVar()
        self.text_info = tk.Label(self, textvariable=self.var2, fg="red", font=("Arial", 20), justify = 'left')
        self.text_info.grid( column=0, row=0, sticky= tk.E,padx=0 , pady=0, ipadx =5, ipady = 5)
        self.var2.set("choisissez une lettre dans la liste")
        
        self.var = tk.StringVar()
        self.text_resultat = tk.Label(self, textvariable=self.var,  bg="#a2af77", fg="black", font=("Arial", 24), justify = 'center', relief = 'raised')
        self.text_resultat.grid(column=1,row=0, ipadx=40, ipady=5)

        self.var3 = tk.StringVar()
        self.text_chance = tk.Label(self, textvariable=self.var3,  bg="#a2af77", fg="red", font=("Arial", 24), justify = 'center', relief = 'raised')
        self.text_chance.grid(column=1,row=2, ipadx=75, ipady=5)
        self.var3.set(f"{self.nb_chances} chances")

        self.var4 = tk.StringVar()
        self.text_lettres_jouees = tk.Label(self, textvariable=self.var4,  bg="black", fg="red",font=("Arial", 15),  justify = 'center', relief = 'raised')
        self.text_lettres_jouees.grid(column=0,row=2, padx=5 , pady=10, ipadx=75, ipady=5)
        self.var4.set("a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z.")
        
        #Création de la Combobox via la méthode ttk.Combobox()   
        self.listeCombo =ttk.Combobox( self, values=self.alphabet)
        self.listeCombo.grid(row=1, column=0, padx=5 , pady=5)
        self.listeCombo.current(0)
        self.listeCombo.bind('<<ComboboxSelected>>',  self.Combobox_action)

    #Création barre de menu
    def create_menu_bar(self):
        self.menu_bar = tk.Menu(self)
        
        self.menu_file = tk.Menu(self.menu_bar, tearoff=0)
        self.menu_bar.add_cascade(label="Fichier", menu=self.menu_file)
        self.menu_file.add_command(label="Nouveau jeu", command=self.nouveau)
        self.menu_file.add_separator()
        self.menu_file.add_command(label="Quitter", command=self.destroy)
        self.config(menu=self.menu_bar)

        
fenetre = Pendu()
fenetre.title("Jeu du Pendu")
fenetre.geometry('900x150')
fenetre.mainloop()

le fichier donnes :

NB_COUPS = 8
LISTE_MOTS = [
    "armoire",
    "boucle",
    "buisson",
    "blaireau",
    "chaise",
]

Bonne journée.

bravo :slight_smile:

petit truc de mise en page (j'ai édité votre post pour le rajouter) quand vous postez du code python, dites au forum que c'est du python et pas du C++ en rajoutant le mot python après les trois back-ticks

image
••• votre code python
image

sans :

    def creation_fenetre(self):
        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=3)
     
        self.var2 = tk.StringVar()
        self.text_info = tk.Label(self, textvariable=self.var2, fg="red", font=("Arial", 20), justify = 'left')
        self.text_info.grid( column=0, row=0, sticky= tk.E,padx=0 , pady=0, ipadx =5, ipady = 5)
        self.var2.set("choisissez une lettre dans la liste")
        

versus avec

    def creation_fenetre(self):
        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=3)
     
        self.var2 = tk.StringVar()
        self.text_info = tk.Label(self, textvariable=self.var2, fg="red", font=("Arial", 20), justify = 'left')
        self.text_info.grid( column=0, row=0, sticky= tk.E,padx=0 , pady=0, ipadx =5, ipady = 5)
        self.var2.set("choisissez une lettre dans la liste")

➜ remarquez les changements de couleurs

Bonjour @J-M-L ,

Merci pour la correction, je ne savais pas :wink:
A l’avenir je le ferai.
Bonne journée

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.