How can I use the content list of a list several times, but every value just once?

Question:

I’m very new to programming and python.

I want to create a "bad joke generator". I want to several list as tuples, which I fill with content and at the end it should print a sentence where it randomly picks out of the lists to create super bad jokes. 🙂
So far so good. I managed to get it working but there’s an issues I ran into.
I want every value out of the list to be used just once. Never twice. But I don’t know to to do it.

This is my project so far:

import random

person = ("donkey", "snake", "a beaver")
say1 = ("Where are my pants?", "Why do you look so sad?")
say2 = ("I don't know.", "That's what she said.")
place = ("bar", "restaurant", "hospital")

def person1_func():
    person1 = person[random.randint(0, len(person)-1)]
    return person1

def person2_func():
    person2 = person[random.randint(0, len(person)-1)]
    if person2 == str(person1_func()):
        person2_func() #This should restart the function, if person2 and person1 are identical. 
    return person2

def place_func():
    place1 = place[random.randint(0, len(person)-1)]
    return place1

print(person1_func())
print(person2_func())
print("A" + person1_func() + " and a " + person2_func() + " come into a " + place_func() + ". ")

In the person2_func() it just doesn’t compare the value with the output of person1_func().
What am I doing wrong? How can I achieve that both values are compared.
Thank you for your help and Merry Christmas. 🙂

Asked By: Moritz Menzel

||

Answers:

Remember that EVERY call to one of these functions returns a new random string. You seem to be thinking that person1_func() will return the same string every time.

You do not need two different functions here. Just have one person function, and let the CALLER decide how to handle dups. Like this:

import random

person = ("donkey", "snake", "a beaver")
say1 = ("Where are my pants?", "Why do you look so sad?")
say2 = ("I don't know.", "That's what she said.")
place = ("bar", "restaurant", "hospital")

def person_func():
    return person[random.randint(0, len(person)-1)]

def place_func():
    return place[random.randint(0, len(person)-1)]

per1 = person_func()
per2 = person_func()
while per1 == per2:
    per2 = person_func()
place1 = place_func()
print(per1)
print(per2)
print("A " + per1 + " and a " + per2 + " come into a " + place1 + ". ")

NOTE, however, that this is not a good design. You can use random.choices to pick N random samples without duplication from a given population. That’s a better plan.

Answered By: Tim Roberts

Forgive me for I don’t code in python so I’m not aware of the syntax to post actual code, but I can explain the pseudo code.

You don’t need to define two functions for doing the same work of picking out a value from the Person list.

Try the following approach:

  • Define a function personFunc(). This function will return a random
    value from the Person List. And remove it from the List, so it cannot
    be picked again.
  • If you don’t want to remove the elements from the list. There is a
    second approach.

Maintain a collection, something like a HashMap for storing your values along with a boolean.

PersonMap = {
    ("donkey", false),
    ("snake", false),
    ("a beaver", false)
}

And when you pick a value from this Map, mark it as true, indicating that this values has been previously used.

Answered By: Shantanu Srivastava

Another option is to generate two random indices with the same get_n_random_people custom function, in place of person1_func and person2_func. This approach will avoid you making extra checks among selected people.

import random

person = ("donkey", "snake", "a beaver")
say1 = ("Where are my pants?", "Why do you look so sad?")
say2 = ("I don't know.", "That's what she said.")
place = ("bar", "restaurant", "hospital")

def get_n_random_people(num):
    return [person[rand_idx] for rand_idx in random.sample(range(0, len(person)), num)]

def place_func():
    return place[random.randint(0, len(person)-1)]

people = get_n_random_people(2)
print(people[0])
print(people[1])
print("A" + people[0] + " and a " + people[1] + " come into a " + place_func() + ". ")

In this example the function get_n_random_people can give you 2 people when the input num is 2, though it’s generalized for any amount of people according to the value you pass as input.

Answered By: lemon
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.