2016-09-15 10 views
2

チーム間のサッカーシーズン全体をシミュレートするプログラムを作成しました。ユーザーはチームの名前とスキル評価を入力します。次に、ポアソン分布を使用してスキル評価を比較し、2つのチーム間の結果を計算します。各試合の後、関連するリストが更新されます。勝ち取ったチームは3ポイントを獲得します(したがって、勝った3チーム目の場合、インデックス[2]の値は3増加します)。ポイント、ゴール、勝利、勝利、ゲーム、失われたゲームなどの別々のリストを持っています(サイドノート - これを行うための効率的な方法はありますか?) 問題は私が季節の終わりに来る:各チームは、チームが最初に入力した順序でデータとともに出力されます。これは、「名前」リストのチーム名が「ポイント」リストのポイントと同じインデックスであるという事実を使用して行われます。問題は、「ポイント」リストを注文すると、名前と同期が取れなくなるということです。Pythonでソート済みのサッカーリーグテーブルを作成

Enter number of teams in league: 4 
Enter team 1 name: a 
Enter team 2 name: b 
Enter team 3 name: c 
Enter team 4 name: d 
Enter a skill: 1 
Enter b skill: 3 
Enter c skill: 5 
Enter d skill: 8 
=========================================== 
a's home games: 
=========================================== 

a 2 - 0 b 

a 0 - 2 c 

a 0 - 0 d 

=========================================== 
b's home games: 
=========================================== 

b 2 - 3 a 

b 1 - 0 c 

b 0 - 0 d 

=========================================== 
c's home games: 
=========================================== 

c 1 - 0 a 

c 1 - 0 b 

c 0 - 1 d 

=========================================== 
d's home games: 
=========================================== 

d 4 - 0 a 

d 2 - 0 b 

d 0 - 0 c 

Final table: 
a    Skill: 1  Points: 7  For: 5  Against: 9  Goal difference: -4 Wins: 2  Draws: 1  Losses: 3  
b    Skill: 3  Points: 4  For: 3  Against: 8  Goal difference: -5 Wins: 1  Draws: 1  Losses: 4  
c    Skill: 5  Points: 10 For: 4  Against: 2 Goal difference: 2  Wins: 3  Draws: 1  Losses: 2  
d    Skill: 8  Points: 12 For: 7  Against: 0 Goal difference: 7  Wins: 3  Draws: 3  Losses: 0  
[4, 7, 10, 12] 

だから私が今したいどのような方法、それではなく、ポイントの多い順に、最終的なリーグテーブルを印刷できるようにすることです:私は、これは理にかなっているが、ここで季節の出力例であると思いますインデックス順に印刷するようになりました。

申し訳ありませんが、これは悪い言葉で表現されている場合 - 私のプログラムのためのコードは、それがあるので、ここでより便利かもしれません:

これは非常に長く、おそらく不十分な言葉で表現し、非効率的であるが、私は誰かがなることを願っていること
import math 
import random 
#Lambda value in Poisson distribution for higher rated team 
lambOne = 1.148698355 
#Lambda value for lower rated team 
lambTwo = 0.8705505633 

#Poisson distribution calculating goals scored by the home team 
def homeMatch(homeRating,awayRating): 
    global lambOne 
    global x 
    global y 
    if x == y: 
     raise ValueError 
    else: 
     lamb = lambOne**(int(homeRating)-int(awayRating)) 
     homeScore = 0 
     z = random.random()  
     while z > 0: 
      z = z - ((lamb**homeScore * math.exp(lamb * -1))/(math.factorial(homeScore))) 
      homeScore += 1 
     return (homeScore-1) 

#Poisson distribution calculating goals scored by away team 
def awayMatch(homeRating,awayRating): 
    global lambTwo 
    global x 
    global y 
    #This check is to stop a team playing itself 
    if x == y: 
     raise ValueError 
    else: 
     lamb = lambTwo**(int(homeRating)-int(awayRating)) 
     awayScore = 0 
     z = random.random()  
     while z > 0: 
      z = z - ((lamb**awayScore * math.exp(lamb * -1))/(math.factorial(awayScore))) 
      awayScore += 1 
     return (awayScore-1) 

#Selecting number of teams in league 
leagueSize = int(input("Enter number of teams in league: ")) 

#Initialising empty lists 
teamNames = [] 
teamSkill = [] 
teamPoints = [] 
teamFor = [] 
teamAgainst = [] 
teamWins = [] 
teamDraws = [] 
teamLosses = [] 

#Populating lists with number of zeroes equal to the number of teams (one zero for each) 
for x in range(leagueSize): 
    teamPoints += [0] 
    teamFor += [0] 
    teamAgainst += [0] 
    teamWins += [0] 
    teamDraws += [0] 
    teamLosses += [0] 

#Entering names and skill ratings for each team 
for i in range(leagueSize): 
    teamNames += [input("Enter team "+str(i+1)+" name: ")] 
for j in range(leagueSize): 
    teamSkill += [input("Enter "+teamNames[j]+" skill: ")] 

#Initialising variables 
homeScore = 0 
awayScore = 0 

#The season begins - each team plays all of its home games in one go 
for x in range(leagueSize): 
    #input("Press enter to continue ") 
    print("===========================================") 
    print(teamNames[x]+"'s home games: ") 
    print("===========================================\n") 
    for y in range(leagueSize): 
     error = 0 
     try: 
      homeScore = homeMatch(teamSkill[x],teamSkill[y]) 
     #Skipping a game to stop a team playing itself 
     except ValueError: 
      pass 
      error += 1 
     try: 
      awayScore = awayMatch(teamSkill[x],teamSkill[y]) 
     except ValueError: 
      pass 
     if error == 0: 
      #Updating lists 
      print(teamNames[x],homeScore,"-",awayScore,teamNames[y],"\n") 
      teamFor[x] += homeScore 
      teamFor[y] += awayScore 
      teamAgainst[x] += awayScore 
      teamAgainst[y] += homeScore 
      if homeScore > awayScore: 
       teamWins[x] += 1 
       teamLosses[y] += 1 
       teamPoints[x] += 3 
      elif homeScore == awayScore: 
       teamDraws[x] += 1 
       teamDraws[y] += 1 
       teamPoints[x] += 1 
       teamPoints[y] += 1 
      else: 
       teamWins[y] += 1 
       teamLosses[x] += 1 
       teamPoints[y] += 3 
     else: 
      pass 

#Printing table (unsorted) 
print("Final table: ") 
for x in range(leagueSize): 
    #Lots of formatting 
    print(teamNames[x]+(15-len(teamNames[x]))*" "+" Skill: "+str(teamSkill[x])+(5-len(str(teamSkill[x])))*" "+" Points: "+str(teamPoints[x])+(5-len(str(teamPoints[x])))*" "+" For: "+str(teamFor[x])+(5-len(str(teamFor[x])))*" "+" Against: "+str(teamAgainst[x])+(5-len(str(teamPoints[x])))*" "+" Goal difference: "+str(teamFor[x]-teamAgainst[x])+(5-len(str(teamFor[x]-teamAgainst[x])))*" "+" Wins: "+str(teamWins[x])+(5-len(str(teamWins[x])))*" "+" Draws: "+str(teamDraws[x])+(5-len(str(teamDraws[x])))*" "+" Losses: "+str(teamLosses[x])+(5-len(str(teamLosses[x])))*" ") 
teamPoints.sort() 
print(teamPoints) 

申し訳ありません私を助けることができる!ありがとうございました:)

+1

異なるデータ構造の使用を検討する必要があります。 3つのリストを同期させようとする代わりに、辞書の辞書にすべてのデータを保存することができます: '{'team_name':{'wins':1、 'draws':1、 'lose':0、 'points':4 }} 'など – DeepSpace

+0

これはいいアイデアです、ありがとう! –

答えて

3

あなたの現在のアプローチは(わずかに)実行可能ですが、各チームについて保存したい情報を変更するなど、非常に困難です。代わりにチームクラスを定義することを検討してください。それぞれのインスタンスには、特定のチームに関するすべての情報が格納されます。

t1 = Team("Bradford City", 3) 

t1は今、属性に指定した値でnameskillを持っているだけでなく、:

class Team: 
    def __init__(self, name, skill): 
     self.name = name 
     self.skill = skill 
     self.points = self.goals_for = self.goals_against = \ 
        self.wins = self.draws = self.losses = 0 

これは、あなたがこのような方法で、名前とスキルレベルを渡すことによって、新しいチームのオブジェクトを作成することができます値がすべてゼロである多数の他のもの(pointsgoals_for、など)。

その後、あなたは非常に簡単にリーグを初期化することができます

league_size = 4 
teams = [] 
for _ in range(league_size): 
    teams.append(Team(input("Name of team "+str(_)+": "), 
         int(input("Team "+str(_)+"'s skill level: "))) 

はその後、各チームのスキルレベルを印刷することができますリストをループ:私は、これはあなたにいくつかのアイデアを与える願っています

for team in teams: 
    print(team.name, team.skill) 

どのようにあなたのアプローチを簡素化することができます。また、マッチを行うための関数はチームを引数としてとり、計算された結果に従ってチームオブジェクトを直接変更することもできます。あなたがチームのリストを持っていたら、あなたは、彼らは非常に簡単に保持するポイントの数によってソートされたそれらをプリントアウトすることができ、あなたが望む答えに到達するために

:私の知る限り見ることができるように

for team in sorted(teams, key=lambda t: t.points): 
    print(team.name, team.skill, team.points, ...) 

、なしglobal宣言が必要でした(名前がローカルで定義されていない場合、Pythonは参照を満たすためにグローバル名を探します)。それ以外にも、関数への入力は通常引数として渡されるべきであり、環境からものを取得するのはむしろ悪い習慣です!

これは、あなたのプログラムをより扱いやすくするために十分であることを望みます。初心者であれば、これまでにはあなたが非常にうまくいったと言いたいと思います。次のステップはあなたのためにエキサイティングなものになるでしょう!

追加後で:あなたのすべてのプレイ-すべてが結果としてプログラムすることが容易にできます。

for home in teams: 
    for away in teams: 
     if home is away: # Teams don't play themselves 
      continue 
     play_match(home, away) 

play_match機能が試合をシミュレートし、各チームの統計値を調整します。もちろん、あなたは離れて、私はあなたのアルゴリズムは、そのための対称的であるかわからないけれども

  play_match(away, home) 

を読んで別の行と一致するシミュレートすることができます。

+0

このような詳細で有益な回答をいただきありがとうございます!私はできるだけ早くこのすべてを実装しようとします!私たちはコンピュータサイエンスレッスンの授業については学んでいませんでした。しかし、それはかなり多くのプログラムを簡素化するように見えるええ!ハハはありがとう、このプログラムは何百行もの非効率性の最初のバージョンから大幅に改善されています...とにかくええ、ありがとうございます:) –

+0

経験によって他の方法を発見するまで、クラスについて学ぶのを待つことが最善です問題を表現するには欠点があります。あなたは確かにスペードでそれを学んだことがあります! – holdenweb

関連する問題