World Cup: 課題

ワールドカップでどの国が優勝するかをシミュレーションするプログラムをPython(パイソン)で書く

https://cs50.harvard.edu/x/2021/labs/6/

各国のFIFA Rating(レーティング)情報が入ったCSVファイルを読み込み、シミュレーション結果を出力する。FIFA Ratingは次の通り2年分用意されている。

 

2018年度:FIFA Rating

team,rating
Uruguay,976
Portugal,1306
France,1166
Argentina,1254
Brazil,1384
Mexico,1008
Belgium,1346
Japan,528
Spain,1162
Russia,493
Croatia,975
Denmark,1054
Sweden,889
Switzerland,1179
Colombia,989
England,1040

2019年度:FIFA Rating

team,rating
Norway,1915
Australia,2003
England,2049
Cameroon,1499
France,2043
Brazil,1944
Spain,1913
United States,2101
Italy,1868
China PR,1866
Netherlands,1967
Japan,1991
Germany,2072
Nigeria,1599
Sweden,1962
Canada,2006

World Cup: 回答例

# Simulate a sports tournament

import csv
import sys
import random

# Number of simluations to run
N = 1000


def main():

    # Ensure correct usage
    if len(sys.argv) != 2:
        sys.exit("Usage: python tournament.py FILENAME")

    # Read teams into memory
    teams = []
    filename = sys.argv[1]
    with open(filename) as f:
        reader = csv.DictReader(f)
        for team in reader:
            team["rating"] = int(team["rating"])
            teams.append(team)

    # Keep track of number of wins for each team
    counts = {}
    for i in range(N):
        winner = simulate_tournament(teams)
        if winner in counts:
            counts[winner] += 1
        else:
            counts[winner] = 1

    # Print each team's chances of winning, according to simulation
    for team in sorted(counts, key=lambda team: counts[team], reverse=True):
        print(f"{team}: {counts[team] * 100 / N:.1f}% chance of winning")


def simulate_game(team1, team2):
    """Simulate a game. Return True if team1 wins, False otherwise."""
    rating1 = team1["rating"]
    rating2 = team2["rating"]
    probability = 1 / (1 + 10 ** ((rating2 - rating1) / 600))
    return random.random() < probability


def simulate_round(teams):
    """Simulate a round. Return a list of winning teams."""
    winners = []

    # Simulate games for all pairs of teams
    for i in range(0, len(teams), 2):
        if simulate_game(teams[i], teams[i + 1]):
            winners.append(teams[i])
        else:
            winners.append(teams[i + 1])

    return winners


def simulate_tournament(teams):
    """Simulate a tournament. Return name of winning team."""
    while len(teams) > 1:
        teams = simulate_round(teams)
    return teams[0]["team"]


if __name__ == "__main__":
    main()

シミュレーション結果

2018年

2018年のFIFA Ratingをベースにシミュレーションした結果は、ブラジルが優勝!

simulation2018

2019年

2019年のFIFA Ratingをベースにシミュレーションした結果は、ドイツが優勝!そしてなんと我らが日本も上位に食い込んできているのが分かる。当然シミュレーション結果は、プログラムを走らせる都度違う結果になるが、可能性はゼロではないことが分かる。

simulation2019