2016-04-15 3 views
1

Я пишу программу, в которую вы можете добавить домашнюю команду, команду гостей и результат игры. Я хочу, чтобы данные команд менялись в соответствии с этим, и большинство из них. Но я не могу изменить «очки», «разницу мячей» и «сыграть» (игры), чтобы измениться! Это код, который я написал до сих пор:Создание атрибутов, которые вычисляются со значением других атрибутов

class team: 
    def __init__(self, name, wins, drawn, losses, goals_for, goals_against): 
     self.name = name 
     self.wins = int(wins) 
     self.drawn = int(drawn) 
     self.losses = int(losses) 
     self.goals_for = int(goals_for) 
     self.goals_against = int(goals_against) 
     self.goals_difference = (self.goals_for - self.goals_against) 
     self.points = ((self.wins * 3) + self.drawn) 
     self.played = (self.wins + self.drawn + self.losses) 
    def __repr__(self): 
     return 'Name:{} P:{} W:{} D:{} L:{} GF:{} GA:{} GD:{} PTS:{}'.format(self.name, self.played, self.wins, self.drawn, self.losses, self.goals_for, self.goals_against, self.goals_difference, self.points)  

detroit_red_wings = team("Detroit", 1, 0, 3, 4, 5) 
los_angeles_kings = team("LA", 0, 1, 4, 3, 7) 
toronto_maple_leafs = team("Toronto", 1, 2, 2, 3, 6) 

teamlist = [detroit_red_wings, los_angeles_kings, toronto_maple_leafs] 
print(teamlist) 

class data_input: 
    def home_team_input(self): 
     home_team = input("Type in the home team: ") 
     for i in teamlist: 
      if i.name == home_team: 
       return i 
    def away_team_input(self):   
     away_team = input("Type in the away team: ") 
     for t in teamlist: 
      if t.name == away_team: 
       return t 
    def result_input(self): 
     goals_home_team = int(input("Type in the number of goals made by the home team: ")) 
     goals_away_team = int(input("Type in the number of goals made by the away team: ")) 
     return (goals_home_team, goals_away_team) 

def adding_result(): 
    home_team = data_input.home_team_input() 
    away_team = data_input.away_team_input() 
    goals_home_team, goals_away_team = data_input.result_input() 

    home_team.goals_for += goals_home_team 
    home_team.goals_against += goals_away_team 
    away_team.goals_for += goals_away_team 
    away_team.goals_against += goals_home_team 

    if goals_home_team > goals_away_team: 
     home_team.wins += 1 
     away_team.losses += 1 
    if goals_home_team < goals_away_team: 
     away_team.wins += 1 
     home_team.losses += 1 
    if goals_home_team == goals_away_team: 
     home_team.drawn += 1 
     away_team.drawn += 1 

data_input = data_input() 
adding_result() 
print(teamlist) 

Я написал указание для атрибутов в __init__ методе класса team и как вы можете видеть точки зависит от wins. Это все работает, когда я создаю объекты, но когда я вставляю результат новой игры, points не изменяется (также нет played или goals_difference). Это меня удивляет, потому что другие атрибуты меняются, когда я ввожу результат игры в функцию input.

ответ

0

points, goals_difference и played не обновлять, потому что ваш метод __init__ не запускается еще раз, как только вы обновите другие свойства - вы просто обновляя другие свойства явно с новым значением. Обратите внимание, что эти свойства, которые не обновляются, назначаются значением, а не ссылкой, у вашего объекта нет способа узнать, что эти свойства должны обновляться, если вы не сделаете это явно.

Есть несколько вещей, которые вы могли бы сделать - простым вариантом может быть предоставление способа обновления агрегирующих свойств, которые вы можете вызывать после явного изменения других свойств. Я бы взял все свойства, которые являются просто математической формулировкой других свойств (поэтому points, goals_difference и played) и удалите их из вашего метода инициализации. Вместо того, чтобы вызвать небольшой метод, как update_aggregates, если вам действительно нужны эти свойства, которые могли бы выглядеть следующим образом

def update_aggregates(self): 
    self.goals_difference = (self.goals_for - self.goals_against) 
    self.points = ((self.wins * 3) + self.drawn) 
    self.played = (self.wins + self.drawn + self.losses) 

Edit: игнорируя мою попытку простоты, решение, предложенное Стив Коэн всех средствам лучше - использование @property гарантирует, что ваши значения будут обновляться надлежащим образом в любое время без необходимости ручного вызова.

+0

Это сработало отлично! Большое вам спасибо!! –

+0

Наличие отдельной функции обновления просто ужасно. Вычислительные результаты должны быть доступны через @properties или функции, чтобы они всегда были точными для текущего состояния других элементов. –

+0

@SteveCohen хорошая точка, я не могу обновить свой ответ в данный момент, но я буду как можно скорее, я пытался быть простым, но в этом случае простота - это просто плохая практика. – miradulo

3

Если вы обновите свой класс team, чтобы выполнить рассчитанные свойства полей, функции свойств всегда вернут правильный результат. Вы также получите ошибку, если попытаетесь установить эти свойства, поскольку они не устанавливаются, т. Е. Они являются результатом вычисления других данных набора.

class team: 
    def __init__(self, name, wins, drawn, losses, goals_for, goals_against): 
     self.name = name 
     self.wins = int(wins) 
     self.drawn = int(drawn) 
     self.losses = int(losses) 
     self.goals_for = int(goals_for) 
     self.goals_against = int(goals_against) 

    @property 
    def goals_difference(self): 
     return self.goals_for - self.goals_against 

    @property 
    def points(self): 
     return self.wins * 3 + self.drawn 

    @property 
    def played(self): 
     return self.wins + self.drawn + self.losses 

    def __repr__(self): 
     return 'Name:{} P:{} W:{} D:{} L:{} GF:{} GA:{} GD:{} PTS:{}'.format(
      self.name, self.played, self.wins, self.drawn, self.losses, 
      self.goals_for, self.goals_against, self.goals_difference, 
      self.points) 

Я хотел бы также рассмотреть возможность сделать W/L/D и GF/GA инициализаторы tupples или словари, а не прохождение 5 переменных к инициализатору.

+1

'return' не является функцией, поэтому постарайтесь не сделать его похожим на – Eric

+0

Тридцать лет привычек C умереть. Удалены лишние круглые скобки по возвращаемым значениям. Странно, что ни PEP8, ни pylint не обозначают это. –

+0

Обновлен мой ответ, чтобы отразить, что это должен быть принятый ответ -_- – miradulo

Смежные вопросы