首页 > 编程问答 >当参与者数量不是 2 的幂时,我的程序无法生成 2 的幂的配对数量

当参与者数量不是 2 的幂时,我的程序无法生成 2 的幂的配对数量

时间:2024-09-24 20:50:30浏览次数:1  
标签:python python-3.x list math

我无法解决这个该死的错误。

该程序无法执行以下操作: 如果参赛人数不是 2 的幂,则使用“再见”自动将某些参赛者移至下一轮。

例如,A 学校有 4 个人,B 学校有 2 个人

它输入:

Enter school name (or 'done' to finish): A
Enter players for A (comma-separated): 1,2,3,4
Is 1 a semi-finalist from the last year? (y/n): n
Is 2 a semi-finalist from the last year? (y/n): n
Is 3 a semi-finalist from the last year? (y/n): n
Is 4 a semi-finalist from the last year? (y/n): n
Enter school name (or 'done' to finish): B
Enter players for B (comma-separated): 5,6
Is 5 a semi-finalist from the last year? (y/n): n
Is 6 a semi-finalist from the last year? (y/n): n
Enter school name (or 'done' to finish): done

它的输出将是:

Pairings for Round 1:

1 (A) vs. 5 (B)
2 (A) vs. 6 (B)
3 (A) vs. 4 (A)

当它的输出应该是:

Pairings for Round 1:

1 (A) vs. 5 (B)
2 (A) vs. 6 (B)
Bye: 3 (A)
Bye: 4 (A)

基本上,如果有 3 个玩家,输出中应该有 4 个配对。 如果有 6 个玩家,输出中应该有 8 个配对。

我仔细研究了程序以找到修复 bug 的方法,但找不到。

import math

# Define the Player class to store player information
class Player:
    def __init__(self, name, school, seed=False):
        self.name = name
        self.school = school
        self.seed = seed

# Function to read player information from user input
def read_players():
    players = []
    while True:
        school_name = input("Enter school name (or 'done' to finish): ").strip()
        if school_name.lower() == 'done':
            break
        player_names = input(f"Enter players for {school_name} (comma-separated): ").strip()
        if player_names:
            player_names_list = [name.strip() for name in player_names.split(',')]
            for player_name in player_names_list:
                while True:
                    seed_status = input(f"Is {player_name} a semi-finalist from the last year? (y/n): ").strip().lower()
                    if seed_status in ('y', 'n'):
                        seed = seed_status == 'y'
                        players.append(Player(player_name, school_name, seed))
                        break
                    else:
                        print("Invalid input. Please enter 'y' or 'n'.")
        else:
            print("No players entered for the school. Please try again.")
    return players

# Function to separate seeded and non-seeded players
def separate_seeds_and_non_seeds(players):
    seeds = [player for player in players if player.seed]
    non_seeds = [player for player in players if not player.seed]
    return seeds, non_seeds

# Function to calculate the number of byes needed to balance the rounds
def balance_byes(players):
    count = len(players)
    next_power_of_two = math.ceil(math.log(count,2)+1)
    byes_needed = next_power_of_two
    return byes_needed

# Function to create the first round pairings
def create_first_round(players):
    seeds, non_seeds = separate_seeds_and_non_seeds(players)
    pairings = []

    def can_pair(player1, player2):
        return player1.school != player2.school

    # Pair seed players with non-seed players, avoiding same school pairings if possible
    while seeds and non_seeds:
        seed = seeds.pop(0)
        opponent = next((p for p in non_seeds if can_pair(seed, p)), non_seeds[0])
        non_seeds.remove(opponent)
        pairings.append((seed, opponent))

    # Handle remaining seed players
    while seeds:
        seed = seeds.pop(0)
        opponent = next((p for p in seeds if can_pair(seed, p)), None)
        if opponent:
            seeds.remove(opponent)
        pairings.append((seed, opponent))

    # Handle remaining non-seed players
    while len(non_seeds) > 1:
        player1 = non_seeds.pop(0)
        opponent = next((p for p in non_seeds if can_pair(player1, p)), non_seeds[0])
        non_seeds.remove(opponent)
        pairings.append((player1, opponent))

    if non_seeds:
        pairings.append((non_seeds.pop(0), None))

    # Balance byes
    byes_needed = balance_byes(players)
    while byes_needed > 0:
        pairings.append((None, None))
        byes_needed -= 1

    return pairings

# Function to display pairings for a given round
def display_pairings(pairings, round_number):
    print(f"\nPairings for Round {round_number}:\n")
    with open("pairings.txt", "a", encoding="utf-8") as file:
        file.write(f"Pairings for Round {round_number}:\n")
        for player1, player2 in pairings:
            if player1 and player2:
                print(f"{player1.name} ({player1.school}) vs. {player2.name} ({player2.school})")
                file.write(f"{player1.name} ({player1.school}) vs. {player2.name} ({player2.school})\n")
            elif player1:
                print(f"Bye: {player1.name} ({player1.school})")
                file.write(f"Bye: {player1.name} ({player1.school})\n")
            elif player2:
                print(f"Bye: {player2.name} ({player2.school})")
                file.write(f"Bye: {player2.name} ({player2.school})\n")
        file.write("\n")

# Main program execution
if __name__ == "__main__":
    all_players = read_players()  # Read player information
    pairings = create_first_round(all_players)  # Create first round pairings
    display_pairings(pairings, 1)  # Display the pairings for the first round

问题在于你如何计算轮空并将其添加到配对中。你只需要足够的轮空,以使参赛者总数达到 2 的幂次方。以下是经过修改的代码:

import math

# ...(其他函数和类保持不变)

# 函数来创建第一轮配对
def create_first_round(players):
    seeds, non_seeds = separate_seeds_and_non_seeds(players)
    pairings = []

    def can_pair(player1, player2):
        return player1.school != player2.school

    # 将种子选手与非种子选手配对,如果可能,避免来自同一学校的配对
    while seeds and non_seeds:
        seed = seeds.pop(0)
        opponent = next((p for p in non_seeds if can_pair(seed, p)), non_seeds[0])
        non_seeds.remove(opponent)
        pairings.append((seed, opponent))

    # 处理剩余的种子选手
    while seeds:
        seed = seeds.pop(0)
        opponent = next((p for p in seeds if can_pair(seed, p)), None)
        if opponent:
            seeds.remove(opponent)
        pairings.append((seed, opponent))

    # 处理剩余的非种子选手
    while len(non_seeds) > 1:
        player1 = non_seeds.pop(0)
        opponent = next((p for p in non_seeds if can_pair(player1, p)), non_seeds[0])
        non_seeds.remove(opponent)
        pairings.append((player1, opponent))

    if non_seeds:
        pairings.append((non_seeds.pop(0), None))

    # 平衡轮空
    byes_needed = balance_byes(players) - len(players)  # 计算所需的轮空数量
    for _ in range(byes_needed):
        pairings.append((None, None))

    return pairings

# ...(其余代码保持不变)

代码更改说明:

  1. 计算所需的轮空:
  2. create_first_round 函数中,我们现在通过从 balance_byes(players) 中减去 len(players) 来计算 byes_needed 。这提供了达到下一个 2 的幂次方所需的准确轮空数量。

  3. 添加轮空:

  4. 我们不再重复计算 byes_needed 。相反,我们使用 for 循环将所需的轮空数量添加到 pairings 列表中。

通过这些更改,代码现在将正确计算并显示具有非 2 次幂参赛者数量的比赛的轮空。例如,对于 6 个参赛者,它将创建 8 个配对(其中 2 个轮空),对于 3 个参赛者,它将创建 4 个配对(其中 1 个轮空)。

标签:python,python-3.x,list,math
From: 79018541

相关文章

  • List Comprehensions, Classe Data
    Assignment#2-ListComprehensions,Classes,CSV,TabularDataThisassignmentconsistsofthreeparts:1.HighestandLowestPotentiallyaffectedvehicles.2.nelta.py3.nelta.pyandRecallswithPotentiallyaffectedvehicles>500,000Clickonthis......
  • Python实现图形学光照和着色的Gouraud着色算法
    目录使用Python实现图形学光照和着色的Gouraud着色算法引言1.Gouraud着色算法概述1.1算法原理2.Python实现Gouraud着色算法2.1向量类2.2光源类2.3材质类2.4Gouraud着色器类2.5使用示例3.实例分析4.Gouraud着色算法的优缺点4.1优点4.2缺点5.改进方向6.应......
  • Python实现Phong着色模型算法
    目录使用Python实现Phong着色模型算法引言Phong着色模型的基本原理1.模型组成2.公式Phong着色模型的Python实现1.向量类的实现2.光源类的实现3.材质类的实现4.Phong着色器类的实现整体实现总结使用Python实现Phong着色模型算法引言在计算机图形学中,光照和......
  • 头歌实践教学平台 Python程序设计实训答案(二)
    第四阶段组合数据类型实验一列表的基本操作第1关:列表增删改:客人名单的变化任务描述列表是由按一定顺序排列的元素组成,其中的元素根据需要可能会发生变化。其中,列表元素的添加、删除或修改等是最常见的操作。下面以一则请客的故事来说明列表元素操作的应用场景。有个人邀......
  • 1、A+B(python语法格式,模块,主模块等)
    总结:python有许多模块,通过import引入模块,或者使用from从模块导入函数#导入math模块importmath#使用模块中的定义的变量或者函数的语法格式为:模块.变量/函数print(math.sqrt(25))#使用math模块中的sqrt函数,表示开平方根#从math模块中导入sqrtfrommathimpor......
  • 【Python学习笔记】字符串
    目录1.定义字符串2.基本操作2.1索引:2.2访问单个字符:2.3访问范围内字符:2.4单个字符编码3.转义符4.运算符5.格式化6.常用字符串函数6.1查找类函数6.2分割类函数6.3字符串连接方法6.4大小写字符转换方法6.5替换方法6.6删除字符串两端、右端或左端连续空白字符......
  • vscode 远程 切换python 虚拟环境
    在VSCode中远程切换Python虚拟环境是一个涉及多个步骤的过程,包括安装必要的扩展、连接到远程服务器、创建或激活虚拟环境,并在VSCode中选择相应的Python解释器。以下是一个详细的步骤指南,包括代码示例,旨在帮助我们完成这一过程。1.Vscode远程切换Python虚拟环境的步骤1.1步骤1:......
  • 常见算法——自相关的含义及Python、C实现
    常见算法——自相关的含义及C实现一、概念1.自相关概念2.滞后期示例说明:二、自相关的计算步骤:1.确定滞后期(Lag):2.计算平均值:3.计算自相关:三、示例Python自相关计算1.代码2.运行结果四、C语言实现自相关算法1.代码2.运行结果:3.优化4.检测规律波动一、概念1.自相关......
  • python中多维数组的cumsum的逆
    我想知道如何在Python中对多维数组进行累积和的逆运算。例如,我们可以通过PMy获得给定二维数组的累积数组T问题是,我如何从importnumpyasnpT=np.array([[1,3,2],[5,5,6],[1,8,3]])P=np.cumsum(np.cumsum(T,axis=0),axis=1)print(P)#Pisthe......
  • Vscode 远程切换Python虚拟环境
    在VSCode中远程切换Python虚拟环境是一个涉及多个步骤的过程,包括安装必要的扩展、连接到远程服务器、创建或激活虚拟环境,并在VSCode中选择相应的Python解释器。以下是一个详细的步骤指南,包括代码示例,旨在帮助我们完成这一过程。1.Vscode远程切换Python虚拟环境的步骤1.1步骤1......