Partage

Fonction Random

Random.choice

13 janvier 2018 à 21:04:55

Bonjour à tous, je suis sous python 3.4 et j'ai une question à propos de la fonction random.choice().

J'aimerais que sur n réponse il m'affiche n fois un caractère de ma liste. Par exemple:

random.choice(["a","b","c","d"])

J'aimerais que sur 10 réponses il m'affiche très exactement 5 fois a et 2 fois c

Est-ce possible ?

Merci d'avance pour vos réponses :)

13 janvier 2018 à 22:14:08

Il suffit de poser la condition intéressante sur un exemple de configuration comme tu le présentes ci-dessus.

Ça donnerait ceci,

from random import choice

elems = ["a", "b", "c", "d"]
while True:
    result = []
    for i in range(10):
        elem = choice(elems)
        result.append(elem)
    if result.count("a") == 5 and result.count("c") == 2:
        print(result)
        break

Ensuite le plus propre est de le faire sous forme de fonction, avec comme paramètres tes conditions

EDIT: Je précise, une signature de fonction ressemblant à

create_list_random(elems, 10, a=5, c=2)



-
Edité par oldProgrammer 13 janvier 2018 à 22:29:15

Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
14 janvier 2018 à 0:49:29

Merci beaucoup pour ta réponse. Cependant la solution que tu m'as donnée affiche un tableau avec (pour l'exemple) 5 a et 2 c.

J'aimerais que le résultat soit "a" 5 fois parmi les 10 résultats que je vais lui demander. Par exemple il va m'afficher "a" puis il va m'afficher "c" puis il va m'afficher "a" puis encore "a" et ainsi de suite jusqu'à ce que j’exécute la commande 10 fois. Une fois la commande répétée 10 fois le compte recommencera à 0.

Je pose cette question car je suis en train de créer un bot discord intégrant le jeu du loup garou. J'aimerais que dès que l'on commence à jouer le bot nous envoie a tous nos rôles de manière aléatoire. Seulement il y a des rôles qui ne doivent s'envoyer qu'une seule fois (je sais pas si vous connaissez les règles du jeu mais il y a plusieurs rôles, par exemple la sorcière ne peut être qu'une seule personne et il peut y avoir plusieurs simples villageois). Voici ma commande qui permet d'envoyer ces messages privés :

    if command == "&start2":
        role = [("Vous êtes un simple villageois."),("Vous êtes un terrifiant Loup-Garou."),("Vous êtes une gentille sorcière."),("Vous êtes une véritable voyante."),("Vous êtes une mignonne petite fille."),("Vous êtes un bon chasseur."),]
        while True:
            result = []
            for i in range(13):
                elem = choice(role)
                result.append(elem)
            if result.count("Vous êtes un simple villageois.") == 5 and result.count("Vous êtes un terrifiant Loup-Garou.") == 4 and result.count("Vous êtes une gentille sorcière.") == 1 and result.count("Vous êtes une véritable voyante.") == 1 and result.count("Vous êtes une mignonne petite fille.") == 1 and result.count("Vous êtes un bon chasseur.") == 1:
                for server_member in message.channel.server.members:
                    try:
                        yield from client.send_message(server_member, result)
                    except discord.errors.Forbidden as e:
                        print("Can not send mp to {}".format(server_member))
                        print(type(e).__name__, e)
                    except discord.errors.HTTPException as e:
                        print("Can not send mp to {}".format(server_member))
                        print(type(e).__name__, e)
                break

Grâce à votre aide j'ai réussi à avoir ça sauf que le bot envoie à tous les utilisateurs un tableau avec toutes les chaines de caractères.

Merci pour votre aide :)

14 janvier 2018 à 7:59:58

EliasChaibi a écrit:

J'aimerais que le résultat soit "a" 5 fois parmi les 10 résultats que je vais lui demander. Par exemple il va m'afficher "a" puis il va m'afficher "c" puis il va m'afficher "a" puis encore "a" et ainsi de suite jusqu'à ce que j’exécute la commande 10 fois. Une fois la commande répétée 10 fois le compte recommencera à 0.

Je n'ai absolument pas compris ce paragraphe. Et je ne comprend pas que l'on parle de compte sur cet exercice du coup.

Le plus simple reste un exemple pratique...

Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
14 janvier 2018 à 9:33:24

Idem que toi pour ce passage :lol:

De ce que j'ai compris du dernier paragraphe, c'est en rapport avec le jeu du loup garou et notamment sur la partie attribution des rôles. Mais dans ce cas, une simple liste contenant le nombre adéquat de rôles couplée à la fonction shuffle du module random suffit:

from random import shuffle


roles = ["loup garou", "sorcière", "petite fille", "chasseur", "voyante",
         "villageois", "villageois", "villageois", "villagois", "villagois"]


#Mélange in-place
shuffle(roles)


for role in roles:
    print("Vous êtes un·e {}".format(role))



Et il faut réfléchir un peu sur la bonne façon de faire, mais on pourrait automatiser un peu en fonction du nombre de joueurs:

from random import shuffle


#Nombre de chaque rôle en fonction du nombre de joueurs
NB_JOUEURS_VS_ROLES = {
                       5: {"loup-garou": 1, "villageois": 2, "chasseur": 1,
                            "voyante": 1, "petite fille": 0, "sorcière": 0},

                       6: {"loup-garou": 1, "villageois": 2, "chasseur": 1,
                            "voyante": 1, "petite fille": 1, "sorcière": 0},

                       7: {"loup-garou": 1, "villageois": 2, "chasseur": 1,
                            "voyante": 1, "petite fille": 1, "sorcière": 1}

                       #...
                      }



#Nombre de joueurs dans la partie
NB_JOUEURS = 6


#Construction de la liste des rôles
roles = []
for role, nb in NB_JOUEURS_VS_ROLES[NB_JOUEURS].items():
    if nb:
        roles.extend([role]*nb)


#Mélange
shuffle(roles)
#print(len(roles), roles, sep="\n")


#Affichage / distribution des rôles
for role in roles:
    print("Vous êtes un·e {}".format(role))

-
Edité par Olygrim 14 janvier 2018 à 9:36:06

Précepte: Le mieux est l'ennemi du bien
14 janvier 2018 à 14:02:35

Bonjour, merci pour vos réponses,

Je suis désolé de ne pas avoir été assez clair ici :)

EliasChaibi a écrit:

J'aimerais que le résultat soit "a" 5 fois parmi les 10 résultats que je vais lui demander. Par exemple il va m'afficher "a" puis il va m'afficher "c" puis il va m'afficher "a" puis encore "a" et ainsi de suite jusqu'à ce que j’exécute la commande 10 fois. Une fois la commande répétée 10 fois le compte recommencera à 0.

Olygrim m'a très bien compris c'était exactement ce que je cherchais :).

Cependant comme le montre ce morceau de code ci dessous j'ai une boucle for pour récupérer tous les utilisateurs de mon serveur et leur envoyer un message privé:

for server_member in message.channel.server.members:
                try:
                    yield from client.send_message(server_member, result)
                except discord.errors.Forbidden as e:
                    print("Can not send mp to {}".format(server_member))
                    print(type(e).__name__, e)
                except discord.errors.HTTPException as e:
                    print("Can not send mp to {}".format(server_member))
                    print(type(e).__name__, e)
            break

J'ai donc placé ma boucle à l’intérieur de cette boucle :

for role in roles:

Mais j'ai le problème suivant, Cela envoie le même message à tous les membres de mon serveur. Je sais pourquoi mais je ne vois pas comment régler ce problème. En fait au lieu de luire d'afficher un rôle aléatoire de la liste je lui dit de l'envoyer aux utilisateurs de mon serveur. Donc c'est normal qu'il envoie le même message à tout le monde. Mais j'aimerais qu'il envoie un message différent à chaque utilisateur parmis la liste de rôles créée. Quelqu'un aurait une solution ? 

Merci d'avance ;)

14 janvier 2018 à 14:57:18

En toute sincérité et sans vouloir être désobligeant, je pense que ce projet est bien au-delà de tes compétences actuelles en python. Je pense que ce serait mieux pour toi de lire un bon tutoriel.

Mais comme je ne veux pas paraître goujat, voici un petit code qui illustre une manière de procéder.

import random
#Nombre de chaque rôle en fonction du nombre de joueurs
NB_JOUEURS_VS_ROLES = {
                   5: ["loup-garou", "villageois", "villageois", "chasseur",
                        "voyante"],

                   6: ["loup-garou", "villageois", "villageois", "chasseur",
                        "voyante", "petite fille"],

                   7: ["loup-garou", "villageois", "villageois", "chasseur",
                        "voyante", "petite fille", "sorcière"]

                   #...
                  }

def gen_roles(nombre_participants):
    roles_melanges = NB_JOUEURS_VS_ROLES[nombre_participants].copy()
    random.shuffle(roles_melanges)
    while roles_melanges:
        yield roles_melanges.pop()

membres = ["Luc", "Jean", "Carole", "Fred", "Pierre"]

roles = gen_roles(len(membres))

for membre, role in zip(membres, roles):
    print("{} aura comme rôle {}".format(membre, role))



Fonction Random

× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
  • Editeur
  • Markdown