通过投票确定获胜者我错过了什么?



我正在想一种方法,使函数决定大多数选票的选举获胜者,以及一个函数决定赢家通吃的规则。

我的代码如下:
_base_dict = {}
    
def add_state(name: str, votes: dict[str, int]) -> None:
    global _base_dict
    for name, votes in _base_dict.items():
        _base_dict[name] += votes
def winner(college: dict[str, int]) -> str:
    global _base_dict
    rv = None
    bigger_percentage = 0
    for state, total_votes in college.items():
        majority = total_votes // 2
        for name, votes in _base_dict.items():
            if votes[state] > majority:
                percentage = votes[state] / float(total_votes)
                if percentage > bigger_percentage:
                    bigger_percentage = percentage
                    rv = name
                elif percentage == bigger_percentage:
                    rv = None
    
    if rv is None: 
        return "No Winner"
    return rv
def clear() -> None:    
    global _base_dict
    _base_dict.clear()
    _base_dict.update(_base_dict)

和在测试文件中,我通过以下方式运行函数:

import elections
college = {'Virginia': 13,
'Ohio': 18,
'Minnesota': 10,
'Alabama': 9,
'Maine': 4
}
print(elections.winner({}))
elections.add_state('Virginia', {
'Turing': 15,
'Lovelace': 20,
'Dijkstra': 10
})
elections.add_state('Ohio', {
'Turing': 1,
'Dijkstra': 15
})
elections.add_state('Alabama', {
'Turing': 10,
'Lovelace': 20,
'Dijkstra': 8
})
print(elections.winner(college))
elections.add_state('Minnesota', {
'Lovelace': 10,
'Dijkstra': 30,
})
elections.add_state('Florida', {
'Turing': 10,
'Lovelace': 30,
'Dijkstra': 15
})
print(elections.winner(college))
elections.clear()
elections.add_state('Maine', {
'Turing': 2,
'Dijkstra': 1,
'Lovelace': 5
})
print(elections.winner(college))

我想要的输出是:

No Winner
Lovelace
Dijkstra
Lovelace

但是我一直得到:

No Winner
No Winner
No Winner
No Winner
我不知道我做错了什么。任何帮助都是感激的。编辑:我更喜欢用逻辑来解决这个问题,尽管导入也很受欢迎。

我认为这解决了它:

首先,我建议_base_dict需要是defaultdict -所以你可以添加keys到它没有。像这样:

from collections import defaultdict
_base_dict = defaultdict(lambda: defaultdict(lambda: 0))

这样定义,每次调用_base_dict[<some state name>]时,如果该状态名还不是_base_dict中的键,则该键被添加到_base_dict中,并且分配给该键的值成为另一个defaultdict,其键将是候选名称,并且该状态的投票计数将从0开始。

其次,我对global _base_dict业务感到不舒服-这可能更多地说明了我而不是你的代码,但为了保持我的理智,我已经通过在开始定义_base_dict来解决它,然后在add_statewinner的每次调用时将其传递给它们。add_state接收_base_dict,修改它,然后返回它。这可能会让函数式编程爱好者疯狂——我很抱歉——我相信如果给我更多的时间,我可以想出一些更优雅的东西。

def add_state(statename: str, statevotes: dict, _base_dict: dict) -> dict:
    
    for candidatename, candidatevotes in statevotes.items():
        _base_dict[statename][candidatename] += candidatevotes
        
    return _base_dict 

winner然后接受college (keysvalues的状态名称分别为dictint)和_base_dict(上面已经定义了)。我已经重写了winner如下:

def winner(college: dict, _base_dict: dict) -> str:
    rv = None
    bigger_percentage = 0
    for state, total_votes in college.items():
        majority = total_votes // 2
        for candidatename, candidatevotes in _base_dict[state].items():
            if candidatevotes > majority:
                percentage = candidatevotes / float(total_votes)
                if percentage > bigger_percentage:
                    bigger_percentage = percentage
                    rv = candidatename
                elif percentage == bigger_percentage:
                    rv = None
    if rv is None:
        return "No Winner"
    return rv

我承认我并没有深入思考这里的计票逻辑,我只是简单地改编了你的原始代码来适应我在这里描述的变化。

最后,重新定义clear以接受_base_dict并返回它,如下所示:

def clear(_base_dict: dict) -> dict:    
    _base_dict.clear()
    _base_dict.update(_base_dict)
    return _base_dict

将它们放在一起并运行脚本的其余部分:

college = {'Virginia': 13,
'Ohio': 18,
'Minnesota': 10,
'Alabama': 9,
'Maine': 4
}
print(winner(college,_base_dict))
_base_dict = add_state('Virginia', {'Turing': 15,
                                    'Lovelace': 20,
                                    'Dijkstra': 10}, 
                       _base_dict)
_base_dict = add_state('Ohio', {'Turing': 1,
                                'Dijkstra': 15
                                }, 
                       _base_dict)
_base_dict = add_state('Alabama', {'Turing': 10,
                                   'Lovelace': 20,
                                   'Dijkstra': 8}, 
                       _base_dict)
print(winner(college, _base_dict))
_base_dict = add_state('Minnesota', {'Lovelace': 10,
                                     'Dijkstra': 30,}, 
                       _base_dict)
_base_dict = add_state('Florida', {'Turing': 10,
                                   'Lovelace': 30,
                                   'Dijkstra': 15}, 
                       _base_dict)
print(winner(college, _base_dict))
_base_dict = clear(_base_dict)
_base_dict = add_state('Maine', {'Turing': 2,
                                 'Dijkstra': 1,
                                 'Lovelace': 5}, 
                       _base_dict)
print(winner(college, _base_dict))

我们得到:

No Winner
Lovelace
Dijkstra
Lovelace

如你所料

绘制出数据结构总是有帮助的,这样可以减少混淆。这个问题可以通过向字典中添加一个键来解决,如果还没有键的话,我们可以直接用新数据更新字典。

_base_dict = {}
'''
'Turing': 'State1': Votes , 'State2': Votes, ...
'Lovelace': 'State': Votes , ...
'Dijkstra': ...
'''
class elections:
  
  def add_state(state: str, data: dict[str, int]) -> None:
      global _base_dict  
      
      for name, votes in data.items():
        if(_base_dict.get(name) == None):
          _base_dict[name] = {state: votes}
        _base_dict[name].update({state: votes}) 
        
  def winner(college: dict[str, int]) -> str:
      global _base_dict
      rv = None
      bigger_percentage = 0
      for state, total_votes in college.items():
          majority = total_votes // 2
          for name, votes in _base_dict.items():
            # print(f"name:{name}  votes:{votes}n")
            # print(f"state:{state}  total_votes:{total_votes}")
            try:
              if votes[state] > majority:
                  percentage = votes[state] / float(total_votes)
                  if percentage > bigger_percentage:
                      bigger_percentage = percentage
                      rv = name
                  elif percentage == bigger_percentage:
                      rv = None
            except:
              pass
          
      
      if rv is None: 
        return "No Winner"
      return rv
  def clear() -> None:    
      global _base_dict
      _base_dict.clear()
      _base_dict.update(_base_dict)
    
college = {'Virginia': 13,
'Ohio': 18,
'Minnesota': 10,
'Alabama': 9,
'Maine': 4
}
print(elections.winner({}))

elections.add_state('Virginia', {
'Turing': 15,
'Lovelace': 20,
'Dijkstra': 10
})
elections.add_state('Ohio', {
'Turing': 1,
'Dijkstra': 15
})
elections.add_state('Alabama', {
'Turing': 10,
'Lovelace': 20,
'Dijkstra': 8
})
print(elections.winner(college))
elections.add_state('Minnesota', {
'Lovelace': 10,
'Dijkstra': 30,
})
elections.add_state('Florida', {
'Turing': 10,
'Lovelace': 30,
'Dijkstra': 15
})
print(elections.winner(college))
elections.clear()
elections.add_state('Maine', {
'Turing': 2,
'Dijkstra': 1,
'Lovelace': 5
})
print(elections.winner(college))
No Winner 
Lovelace 
Dijkstra  
Lovelace 

相关内容

最新更新