this code is running finally 

import argparse
import csv
import math
import os
from collections import Counter
from typing import List

import dataclasses
import numpy as np
from numpy.ma import exp
from scipy.optimize import minimize\_scalar
from scipy.special import expit

PARENT\_DIR = os.path.dirname(os.path.realpath(\_\_file\_\_))

HISTORICAL\_SEED\_WIN\_RATES = {
 (1, 16): 1.000,
 (2, 15): 0.917,
 (3, 14): 0.833,
 (4, 13): 0.750,
 (5, 12): 0.667,
 (6, 11): 0.583,
 (7, 10): 0.583,
 (8, 9): 0.500,
}
@dataclasses.dataclass
class Team:
 team\_name: str
 team\_seed: int
 ken\_pom\_score: float

 @classmethod
 def extract\_teams(cls, file\_path: str):
 with open(os.path.join(PARENT\_DIR, file\_path), "r", newline="") as csvfile:
 return [cls(
 team\_name=row["team"],
 team\_seed=int(row["seed"]),
 ken\_pom\_score=float(row["score"])
 ) for row in (csv.DictReader(csvfile))]
class Tournament:

 def \_\_init\_\_(self, teams: List[Team]):
 self.teams: List[Team] = teams
 self.k = self.find\_best\_k()
 self.adj\_matrix = self.calculate\_adj\_matrix()

 @staticmethod
 def get\_opponent\_index(team\_index):
 return team\_index + 1 if team\_index % 2 == 0 else team\_index - 1

 def calculate\_adj\_matrix(self):
 num\_teams = len(self.teams)
 adj\_matrix = np.zeros((num\_teams, num\_teams))

 for i, team\_i in enumerate(self.teams):
 for j, team\_j in enumerate(self.teams):
 if i != j:
 p\_win = self.calculate\_win\_probability(team\_i, team\_j)
 adj\_matrix[i, j] = p\_win
 adj\_matrix[j, i] = 1 - p\_win

 return adj\_matrix

 def calculate\_win\_probability(self, team\_i: Team, team\_j: Team):
 seed\_diff = team\_j.team\_seed - team\_i.team\_seed
 ken\_pom\_diff = team\_i.ken\_pom\_score - team\_j.ken\_pom\_score
 return expit(self.k \* (ken\_pom\_diff + seed\_diff))

 def play\_single\_round(self):
 winners = []
 for i in range(0, len(self.teams), 2):
 p\_win\_i = self.adj\_matrix[i, i + 1]
 win\_i = np.random.rand() < p\_win\_i
 winning\_team\_index = i if win\_i else i + 1
 winners.append(winning\_team\_index)

 return winners

 def run\_rounds\_recursive(self, num\_simulations):
 if len(self.teams) == 0:
 print("No teams in the tournament. Exiting.")
 return

 print(f"Current teams in the round: {', '.join([team.team\_name for team in self.teams])}")
 if len(self.teams) == 1:
 print(f"Winner: {self.teams[0].team\_name}")
 return

 winners\_indices = self.play\_single\_round()
 winners: list[Team] = [self.teams[winner\_index] for winner\_index in winners\_indices]
 updated\_tournament = Tournament(winners)
 updated\_tournament.run\_rounds\_recursive(num\_simulations)

 def get\_team\_by\_name(self, team\_name: str):
 for team in self.teams:
 if team.team\_name == team\_name:
 return team
 return None

 @staticmethod
 def error\_function(k, average\_kenpom\_difference):
 error = 0
 for matchup, historical\_probability in HISTORICAL\_SEED\_WIN\_RATES.items():
 difference = average\_kenpom\_difference[matchup]
 probability = 1 / (1 + exp(-k \* difference))
 error += (probability - historical\_probability) \*\* 2
 return error

 @staticmethod
 def average\_kenpom\_difference(max\_seed=16, kenpom\_range=(0, 40)):
 min\_kenpom, max\_kenpom = kenpom\_range
 kenpom\_increment = (max\_kenpom - min\_kenpom) / max\_seed
 average\_difference = {}

 for higher\_seed in range(1, max\_seed + 1):
 for lower\_seed in range(higher\_seed + 1, max\_seed + 1):
 higher\_seed\_kenpom = max\_kenpom - (higher\_seed - 1) \* kenpom\_increment
 lower\_seed\_kenpom = max\_kenpom - (lower\_seed - 1) \* kenpom\_increment
 average\_difference[(higher\_seed, lower\_seed)] = higher\_seed\_kenpom - lower\_seed\_kenpom

 return average\_difference

 @staticmethod
 def find\_best\_k():
 average\_difference = Tournament.average\_kenpom\_difference()
 result = minimize\_scalar(Tournament.error\_function, args=(average\_difference,))
 return result.x
if \_\_name\_\_ == "\_\_main\_\_":
 parser = argparse.ArgumentParser(
 description="NCAA Tournament Simulation"
 )
 parser.add\_argument(
 '-f', '--file',
 default='2023ncaab.csv',
 help="Path to the data file (default: '2023ncaab.csv')"
 )
 parser.add\_argument(
 '-n', '--num-simulations',
 type=int,
 default=100000,
 help="Number of simulations to run (default: 100000)"
 )
 args = parser.parse\_args()
 teams\_ = Team.extract\_teams(args.file)
 tournament = Tournament(teams\_)
 tournament.run\_rounds\_recursive(args.num\_simulations)
but it is only doing one trial for each round it is not doing any accumulation anymore. When we run play\_single\_round we should run the round num\_simulations number of times. lets add num simulations as a constructor arg so that we can use it. when play single round runs over and over, we should do the following
\* keep track of how many times each team one
\* for any two consecutive teams self.teams[i] self.teams[i+j] the one that won the most is who should go into the output of play\_single\_round
그의 코드가 마침내 실행 중입니다. argparse 임포트import csv임포트 수학import os컬렉션에서 임포트 카운터입력에서 임포트 목록데이터 클래스 임포트numpy를 np로 임포트numpy.ma에서 exp 임포트scipy.optimize에서 가져 오기 최소화\_스칼라from scipy.special import expitPARENT\_DIR = os.path.dirname(os.path.realpath(\_\_file\_\_))historical\_seed\_win\_rates = { (1, 16): 1.000, (2, 15): 0.917, (3, 14): 0.833, (4, 13): 0.750, (5, 12): 0.667, (6, 11): 0.583, (7, 10): 0.583, (8, 9): 0.500,}@dataclasses.dataclass팀 클래스: team\_name: str 팀\_씨앗: int ken\_pom\_score: float @classmethod def extract\_teams(cls, file\_path: str): with open(os.path.join(PARENT\_DIR, file\_path), "r", newline="") as csvfile: return [cls( team\_name=row["team"], team\_seed=int(row["seed"]), ken\_pom\_score=float(row["score"]) ) for row in (csv.DictReader(csvfile))]토너먼트 클래스: def \_\_init\_\_(self, teams: List[Team]): self.teams: List[Team] = teams self.k = self.find\_best\_k() self.adj\_matrix = self.calculate\_adj\_matrix() 정적 메서드 def get\_opponent\_index(team\_index): return team\_index + 1 if team\_index % 2 == 0 else team\_index - 1 def calculate\_adj\_matrix(self): num\_teams = len(self.teams) adj\_matrix = np.zeros((num\_teams, num\_teams)) for i, team\_i in enumerate(self.teams): for j, team\_j in enumerate(self.teams): IF I != J: p\_win = self.calculate\_win\_probability(team\_i, team\_j) adj\_matrix[i, j] = p\_win adj\_matrix[j, i] = 1 - p\_win 반환 adj\_matrix def calculate\_win\_probability(self, team\_i: 팀, team\_j: 팀): seed\_diff = team\_j.team\_seed - team\_i.team\_seed ken\_pom\_diff = team\_i.ken\_pom\_score - team\_j.ken\_pom\_score return expit(self.k \* (ken\_pom\_diff + seed\_diff)) def play\_single\_round(self): winners = [] for i in range(0, len(self.teams), 2): p\_win\_i = self.adj\_matrix[i, i + 1] win\_i = np.random.rand() < p\_win\_i winning\_team\_index = i if win\_i else i + 1 winners.append(winning\_team\_index) 우승자 반환 def run\_rounds\_re귀적(self, num\_simulations): len(self.teams) == 0: print("토너먼트에 참가팀이 없습니다. 종료합니다.") return print(f"현재 라운드에 있는 팀들: {', '.join([self.teams의 팀에 대한 팀.팀\_이름])}") len(self.teams) == 1: print(f"우승자: {self.teams[0].team\_name}") 반환 winners\_indices = self.play\_single\_round() winners: list[Team] = [self.teams[winner\_index] for winner\_index in winners\_indices] updated\_tournament = 토너먼트(우승자) updated\_tournament.run\_rounds\_re귀적(num\_simulations) def get\_team\_by\_name(self, team\_name: str): for team in self.teams: if team.team\_name == team\_name: 반환 팀 반환 없음 정적 메서드 def error\_function(k, average\_kenpom\_difference): error = 0 매치업의 경우, HISTORICAL\_SEED\_WIN\_RATES.items()의 historical\_probability: 차이 = 평균\_켄폼\_차이[매치업] 확률 = 1 / (1 + exp(-k \* 차이)) error += (확률 - 과거\_확률) \*\* 2 반환 오류 정적 메서드 def average\_kenpom\_difference(max\_seed=16, kenpom\_range=(0, 40)): MIN\_KENPOM, MAX\_KENPOM = KENPOM\_RANGE kenpom\_increment = (max\_kenpom - min\_kenpom) / max\_seed 평균\_차이 = {} 범위(1, 최대\_씨드 + 1)에서 더 높은\_씨드의 경우: FOR LOWER\_SEED IN RANGE(HIGHER\_SEED + 1, MAX\_SEED + 1): higher\_seed\_kenpom = max\_kenpom - (higher\_seed - 1) \* kenpom\_increment lower\_seed\_kenpom = max\_kenpom - (lower\_seed - 1) \* kenpom\_increment average\_difference[(higher\_seed, lower\_seed)] = higher\_seed\_kenpom - lower\_seed\_kenpom 반환 평균\_difference @staticmethod def find\_best\_k(): average\_difference = Tournament.average\_kenpom\_difference() result = minimize\_scalar(Tournament.error\_function, args=(average\_difference,)) 반환 결과.xif \_\_name\_\_ == "\_\_main\_\_": parser = argparse.ArgumentParser( description="NCAA 토너먼트 시뮬레이션" ) parser.add\_argument( '-f', '--file', default='2023ncaab.csv', help="데이터 파일 경로(기본값: '2023ncaab.csv')" ) parser.add\_argument( '-n', '--num-simulations', type=int, default=100000, help="실행할 시뮬레이션 수(기본값: 100000)" ) args = 파서.파싱\_args() teams\_ = Team.extract\_teams(args.file) 토너먼트 = 토너먼트(팀\_) tournament.run\_rounds\_재귀적(args.num\_simulations)를 실행하지만 각 라운드에 대해 한 번만 시도하고 더 이상 누적을 수행하지 않습니다. play\_single\_round를 실행할 때 라운드 num\_simulations 횟수를 실행해야 합니다. 이를 사용할 수 있도록 생성자 인수로 num simulations를 추가하겠습니다. 플레이 싱글 라운드가 반복해서 실행될 때 다음을 수행해야 합니다.\* 각 팀이 한 팀씩 몇 번을 플레이했는지 추적합니다.\* 연속된 두 팀에 대해 self.teams[i] self.teams[i+j] 가장 많이 이긴 팀이 play\_single\_round의 출력에 들어가야 합니다.