Home > OS >  Can I limit how often an element is randomly chosen from a list?
Can I limit how often an element is randomly chosen from a list?

Time:06-15

I am trying to code a match fixture app which takes a certain number of teams and puts them vs each other without repeating the same team twice successively i.e having the same team play twice in two days e.g if the teams listed are "a", "b", "c", "d" and "e" and they are to play four matches this code prints results like

a vs b

c vs d

c vs e

but I am trying to prevent it from repeating the same element twice in a row i.e

c vs d

c vs e

but rather

a vs b

c vs d

e vs a

the code is below, what changes do I need to make

import random

number_of_teams = int(input('How many teams? : '))
other_number = number_of_teams   1
teams = []

number_of_matches = int(input("How many matches are to be played?: "))
real_number_of_matches = number_of_matches   1

for i in range(1, other_number):
    team_name = input("Input team name: ")
    teams.append (team_name)
print('The teams participating are', teams)


for i in range(1, real_number_of_matches):
    first_team = random.choice(teams)
    second_team = random.choice(teams)
    if first_team != second_team:
        print(f'{first_team} vs {second_team}')```

CodePudding user response:

I believe I found a way.

I created a dictionary called prev_teams which stores the previously used teams (we dont want to use them on the next turn). By default they are set to None as we dont have previous teams.

Then I create a copy of teams and store it into unique_teams. We use unique teams to create a list of teams we can select from. (Remove previous teams from this list using prev_teams i.e

unique_teams = [t for t in unique_teams if t not in prev_teams.values()]

Then, using a while loop we can check if the teams are the same, if not break out

while True:
    first_team = random.choice(unique_teams)
    second_team = random.choice(unique_teams)
    if first_team != second_team:
        break

Then we need to store the previous teams in prev_teams for later

prev_teams["first"] = first_team
prev_teams["second"] = second_team

So the final code would be

import random

while True:
    number_of_teams = int(input('How many teams? : '))
    if number_of_teams > 3:
        break
    else:
        print("Please enter a number greater than 3")
        
        
other_number = number_of_teams   1
teams = []

number_of_matches = int(input("How many matches are to be played?: "))

for i in range(1, other_number):
    team_name = input("Input team name: ")
    teams.append (team_name)
print('The teams participating are', teams)


prev_teams = {"first": None, "second": None}
for i in range(number_of_matches):
    unique_teams = teams.copy()
    #if prev_teams values occur in unique_teams, remove them
    unique_teams = [t for t in unique_teams if t not in prev_teams.values()]
    while True:
        first_team = random.choice(unique_teams)
        second_team = random.choice(unique_teams)
        if first_team != second_team:
            break
    prev_teams["first"] = first_team
    prev_teams["second"] = second_team
    print(f'{first_team} vs {second_team}')

Output

How many teams? : 8
How many matches are to be played?: 10
Input team name: a
Input team name: b
Input team name: c
Input team name: d
Input team name: e
Input team name: f
Input team name: g
Input team name: h
The teams participating are ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
11
e vs c
h vs d
g vs b
c vs f
e vs d
h vs g
c vs e
f vs d
e vs a
h vs f

CodePudding user response:

This works with some fairly simple restructuring of your original code.

Firstly, there's no need to be using variables like: real_number_of_matches in your case, you can alter your loops to use the raw input values. I did so by using while loops instead of for loops because it seemed cleaner, but you can do it with for loops if you like.

I add the cached_first_team and cached_second_team variables to store the last used teams. Checking against these cached values allow us to never repeat two teams in a row, while allowing duplicate matchups and allowing the team to appear later in the matchups.

I also added the matches list which we can use to keep track of the number of matches we have so far, as a condition of our while loop.

import random

teams = []
matches = []

cached_first_team = ''
cached_second_team = ''

number_of_matches = int(input("How many matches are to be played?: "))
number_of_teams = int(input('How many teams? : '))

if number_of_teams > 1:
    while len(teams) < number_of_teams:
        team_name = input("Input team name: ")
        teams.append (team_name)
    print('The teams participating are', teams)

    while len(matches) < number_of_matches:
        first_team = random.choice(teams)
        second_team = random.choice(teams)
        matchup = set([first_team, second_team])
        if first_team != second_team and first_team != cached_first_team and second_team != cached_second_team:
            print(f'{first_team} vs {second_team}')
            matches.append(matchup)
            cached_first_team = first_team
            cached_second_team = second_team
else:
    print('Not enough teams!')

Works with any number of matches (as long as the number of teams is greater than 1!)

  • Related