Home > other >  Python dictionaries output not printing as expected
Python dictionaries output not printing as expected

Time:04-23

Question is as follows : In each competition there are two teams that compete. There will be one winner and one loser out of all of these competitions and there are no ties. Each team will compete against all other teams exactly once. A team gets 3 points for each competition it wins and 0 points for each competition it loses. It's guaranteed that the tournament always has at least two teams and there will be only one tournament winner.

We are given two inputs, the competitions array and the results array. We need to write a function that returns the winner of the tournament, or more specifically, the name of the team that has the most number of points.we have two strings: the first one is the name of the home team and the second one is the name of the away team. The results array represents the winner of each of these competitions. Inside the results array, a 1 means that the home team won and a 0 means the away team won. The results array is the same length as the competitions array, and the indices in the results array correspond with the indices in the competitions array.

    def tournamentWinner(competitions, results):
        # Write your code here.
        
            d = {}
            for i in range(len(results)):
                if results[i] == 0:
                    if competitions[i][1] not in d:
                        d[competitions[i][1]]  = 3
                    else:
                        d[competitions[i][1]]   = 3
                elif results[i] == 1:
                    if competitions[i][0] not in d:
                        competitions[i][0] = 3
                    else:
                        d[competitions[i][0]]  = 3
    
            print(max(d,key=d.get))

tournamentWinner([
    ["HTML", "Java"],
    ["Java", "Python"],
    ["Python", "HTML"],
    ["C#", "Python"],
    ["Java", "C#"],
    ["C#", "HTML"]
  ],[0, 1, 1, 1, 0, 1])

The output should be C#, but I am getting Java as per my code. Can someone please guide me through this?

CodePudding user response:

You forgot one index into d so home-wins never are added to your dictionary:

def tournamentWinner(competitions, results):         
        d = {}
        for i in range(len(results)):
            if results[i] == 0:
                if competitions[i][1] not in d:
                    d[competitions[i][1]]  = 3
                else:
                    d[competitions[i][1]]   = 3
            elif results[i] == 1:
                if competitions[i][0] not in d:
                    competitions[i][0] = 3   # HERE missing d[...] = 3
                else:
                    d[competitions[i][0]]  = 3

        print(d) # => {'Java': 6, 'C#': 6} - theres smth missing ;)
        print(max(d,key=d.get))

Easily viewable by stepping through or printing out the d before returning the result.


You can simplify this (changed to returning result instead of printing):

def tournamentWinner(competitions, results):
    d = {}
    for teams,result in zip(competitions,results):
        # teams is a list of 2 elements, result is 0 or 1:
        # the winner is the index into the 2-elem-list by 1-result
        winner = teams[1-result] # [home,far], 1 == home wins
        d.setdefault(winner,0) # create key with 0 if not there
        d[winner]  = 1 # no need to add up 3 - the points are never used

    print(d) # ==>  {'Java': 2, 'Python': 1, 'C#': 3}
    return max(d.items(), key=lambda tup:tup[1]) [0] # select the key


result = tournamentWinner([
["HTML", "Java"],
["Java", "Python"],
["Python", "HTML"],
["C#", "Python"],
["Java", "C#"],
["C#", "HTML"]
],[0, 1, 1, 1, 0, 1])

print(result)

outputs

C#

On any draw the result will only show the first team having that score - you could work around that but the task does not tell you to so not needed.

CodePudding user response:

Your offending line is at

 competitions[i][0] = 3

where you modify the competitions not the scoreboard, where you should then have

 d[competitions[i][0]] = 3

I propose the following which may be more easy to understand to compute the whole scoreboard:

  • explicit variables
  • edge case handling (missing team in the scoreboard).
def get_winner_in_score_board(score_board):
    return max(score_board, key=score_board.get)


def tournament_winner(competitions, results):
    score_board = {}
    for competitors, result in zip(competitions, results):
        if result == 1:
            loser = competitors[1]
            winner = competitors[0]
        else:
            loser = competitors[0]
            winner = competitors[1]

        try:
            score_board[winner]  = 3
        except KeyError:
            score_board[winner] = 3

    return get_winner_in_score_board(score_board)


tournament_winner(
    [
        ["HTML", "Java"],
        ["Java", "Python"],
        ["Python", "HTML"],
        ["C#", "Python"],
        ["Java", "C#"],
        ["C#", "HTML"],
    ],
    [0, 1, 1, 1, 0, 1],
)

Note that teams not winning at least once will not appear in scoreboard. Maybe we would like to have them as well, there are different solutions for that, but as you seem only to want the winner, I didn’t add it.

  • Related