Je souhaite écrire un programme qui distribue une List de cartes (tuple de type (8, 'pique')) en n(nombre de joueurs) List de façon aléatoire.
Je dois donc écrire une fonction du type:
# type Carte = tuple [int, str]
# Distribution = List[List[Carte]]
def essai (n,L):
""" int * List [Carte] -> List[List[Carte]]
Hypothèse: List[Carte] >= n
n != 0
Renvoie une distibution aléatoire des cartes en paquets de taille égale.
"""
#nb_joueurs:int
nb_joueurs = n
#liste_cartes:[Carte]
liste_cartes = L
#i:int
i =0
#L[i]:List
L[i] =[]
#LR:Distribution
LR = []
#e:Carte
for e in L:
for i in range (0,n-1):
L[i].append(e)
LR.append(L[i])
return LR
mais cela ne fonctionne pas du tout et j'avoue ne pas savoir comment m'y prendre.
Merci d'avance a ceux qui m'aideront.
- Edité par François22520 15 janvier 2018 à 1:33:37
Avant de commencer, pourquoi avez-vous une variable i=0 ? Vous ne l'utilisez pas...
Premièrement, avez-vous le droit d'utiliser le module random?
Puisque, vous utilisez une énumération croissante, vous risquez fortement de toujours avoir les même numéros.
Si vous voulez continuer avec votre énumération croissante, vous devriez mélanger vos cartes dès le départ (avec un random.shuffle)..
Sinon, il suffit d'utiliser la méthode choice du module random, pour choisir aléatoirement chaque carte pendant l'énumération.. (random.choice)
Pour ce faire, il suffit de supprimer chaque carte choisit aléatoirement de la liste des cartes. Comme cela vous êtes sûr qu'il sortira pas une deuxièmement fois.
Voici un pseudo-code:
def essai(nombre_de_joueur, tous_les_cartes):
nombre_de_carte = tous_les_cartes (diviser par) nombre_de_joueur
paquets = []
pour chaque joueur dans nombre_de_joueur:
paquet = []
pour chaque nombre de carte dans nombre_de_carte:
choix = choisit aléatoirement une carte
supprime le choix de la liste des cartes (tous_les_cartes)
sauvegarde le choix dans le paquet
sauvegarde le paquet dans les paquets
return paquets
Essayez de comprendre ce pseudo-code. Il faut deux boucles FOR et deux listes.
Comme ceci:
paquets = [] ## Tous les paquets
for i in range(nombre_player):
paquet = [] ## Paquet individuelle
for j in range(nombre_carte):
paquet.append(choix)
paquets.append(paquet)
Effectivement, j'ai le droit d'utiliser le module random et la fonction random.shuffle (mais pas random.choice). Je vais donc essayer avec deux boucles FOR. Je vous tiens au courant.
1.J'aurai une question concernant random.shuffle et copy.deepcopy. J'ai voulu écrire un petit programme pour voir comment ces fonctions agissaient qui est le suivant:
import random
import copy
L1 = [1, 2, 3, 4, 5, 6]
def essai (L):
""" List[alpha] -> List[alpha]
renvoie une copie de L en mélangeant aléatoirement L.
"""
Ldep = L
Lcopie = copy.deepcopy(L)
random.shuffle (L)
return L
Ma fonction mélange bien ma liste (L1 par exemple) mais lorsque je tape ensuite L1, je ne retrouve pas ma fonction de départ dans le bon ordre.
Je ne comprends pas pourquoi?
2.Par ailleurs, j'ai écrit ceci:
# type Carte = tuple [int, str]
# Distribution = List[List[Carte]]
import random
def essai (n,L):
""" int * List [Carte] -> List[List[Carte]]
Hypothèse: List[Carte] >= n
n != 0
Renvoie une distibution aléatoire des cartes en paquets de taille égale.
"""
random.shuffle (L)
#nb_joueurs:int
nb_joueurs = n
#liste_cartes:[Carte]
liste_cartes = L
#a:int
a = len(L) // n
#i:int
i =0
#j:int
j=0
#D:Distribution
D=[]
#paquet:List[Carte]
paquet = []
len(paquet)==a
for j in range (0,n):
paquet = L[i:i+a]
if (len(paquet) == a):
D.append(paquet)
i=i+a
return D
La copie que tu fais dans la fonction essai n'a pas d'intérêt puisque tu ne l'utilises pas et qu'elle est perdue en sortie.
Ce que tu cherches à faire, je pense, c'est de mélanger la copie et de la renvoyer.
Au passage, pourquoi as-tu besoin d'une copie profonde plutôt qu'une simple ?
Pour le premier code, il serait plus avantageux d'utiliser random.sample si tu n'as pas besoin de copie profonde comme l'a relevé entwanne.
Pour le reste, tu peux utiliser assert pour exprimer tes hypothèses et les annotations de types (voir le module typing) pour exprimer le type de tes fonctions. Un petit exemple en rapport avec ce que tu veux faire:
"""Card/Items distribution utilities"""
from typing import Sequence, Tuple, TypeVar
T = TypeVar("T")
# ...
def deal(sequence: Sequence[T], n: int) -> Sequence[Tuple[T]]:
"""Random distribution of items into fixed-length chunks"""
assert n > 0 and len(sequence) % n == 0
# ...
# ...
Il existe un idiome en python pour grouper des éléments en paquets de taille fixe. C'est référencé quelque part ici (je te laisse chercher un peu). Tu peux aussi regarder ce que propose le module itertools.
- Edité par Mad scientist 17 janvier 2018 à 16:53:38
Python Tutor permet de visualiser les objets manipulés par Python. Je t'ai fait un petit exemple qui met en lumière ce qu'explique entwanne: https://goo.gl/54MzGx
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique