代码之家  ›  专栏  ›  技术社区  ›  L4w1i3t

通过投票决定获胜者,我缺少什么?

  •  0
  • L4w1i3t  · 技术社区  · 3 年前

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

    我的代码如下:

    _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
    

    我不知道我做错了什么。感谢您的帮助。 编辑:我更喜欢用逻辑来解决这个问题,尽管进口也很受欢迎。

    0 回复  |  直到 3 年前
        1
  •  0
  •   Vin    3 年前

    我认为这可以解决问题:

    首先,我建议 _base_dict 需要成为 defaultdict -这样你就可以添加 keys 它还没有。就像这样:

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

    如此定义,每次调用 _base_dict[<some state name>] ,如果该状态名称还不是中的键 _base_dict ,密钥被添加到 _base_dict ,并且分配给该键的值变为另一个 默认dict 其密钥将是候选人姓名,该州的计票将从 0 。

    其次,我对 global _base_dict 商业——这可能比你的代码更能说明我,但为了保持理智,我通过定义 _base_dict 在开始时,然后将其传递给 add_state 和 winner 在他们的每一次通话中。 添加状态 接受 _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 
    

    赢家 然后两者兼得 college (a dict 其州名称 按键 和 int values ),以及 _base_dict -已在上面定义。我重写了 赢家 下面是:

    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
    

    正如你所料。

        2
  •  0
  •   Kings_M    3 年前

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

    _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