Search code examples
pythonarraysnumpyargs

generalize a function based on variable arguments


This is my first post, and I am a beginner programmer. I hope you can help me become a better one.

I am trying to model a round robin domino game for five (05) players. On each round, only four (04) players play, in teams of two (02). The formula below does the trick, for a fixed number of 5 players.

My specific question is how to make it generic to any number of players; and how to make this one more efficient. (I assume it is possible, as I am a novice).

Thanks.

Results to be modeled

Code:

import numpy

def calculo(*args):

    wints= numpy.zeros(len(args),dtype=int)

    for i, item in enumerate(args):

        if i is 0:
            if item[0]>item[1]:
                wints+=[1,1,0,0,0] # players 12
            else:
                wints+=[0,0,1,1,0] # players 34

        if i is 1:
            if item[0]>item[1]:
                wints+=[1,0,0,0,1] # players 15
            else:
                wints+=[0,1,1,0,0] # players 23

        if i is 2:
            if item[0]>item[1]:
                wints+=[1,0,0,1,0] # players 14
            else:
                wints+=[0,1,0,0,1] # players 25

        if i is 3:
            if item[0]>item[1]:
                wints+=[1,0,1,0,0] # players 13
            else:
                wints+=[0,0,0,1,1] # players 45

        if i is 4:
            if item[0]>item[1]:
                wints+=[0,1,0,1,0] # players 24
            else:
                wints+=[0,0,1,0,1] # players 35

    return wints

print(calculo([118,28],[128,66],[26,133],[111,0],[57,109]))

Solution

  • It's hard to understand what you're trying to do, but you can first reduce redundant code like this:

    def calculo(items):
        wints = numpy.zeros(len(items), dtype=int)
    
        if items[0][0] > items[0][1]:
            wints += [1,1,0,0,0] # players 12
        else:
            wints += [0,0,1,1,0] # players 34
    
        if items[1][0] > items[1][1]:
            wints += [1,0,0,0,1] # players 15
        else:
            wints += [0,1,1,0,0] # players 23
    
        if items[2][0] > items[2][1]:
            wints += [1,0,0,1,0] # players 14
        else:
            wints += [0,1,0,0,1] # players 25
    
        if items[3][0] > items[3][1]:
            wints += [1,0,1,0,0] # players 13
        else:
            wints += [0,0,0,1,1] # players 45
    
        if items[4][0] > items[4][1]:
            wints += [0,1,0,1,0] # players 24
        else:
            wints += [0,0,1,0,1] # players 35
    
        return wints
    

    There seems to be a pattern here...

    def one_hot_encode(players, n):
        arr = numpy.zeros(n + 1, dtype=int)
        arr[players] = 1
        return arr[1:]
    
    def calculo(scores, pairings, n_players):
        wints = numpy.zeros(n_players, dtype=int)
    
        for (s1, s2), (p1, p2) in zip(scores, pairings):
            winner = p1 if s1 > s2 else p2
            wints += one_hot_encode(winner, n_players)
    
        return wints
    
    scores = [[118, 28], [128, 66], [26, 133], [111, 0], [57, 109]]
    pairings = [ [[1,2],[3,4]], [[1,5],[2,3]], [[1,4],[2,5]], [[1,3],[4,5]], [[2,4],[3,5]] ]
    print(calculo(scores, pairings, 5))
    

    Outputs:

    [3 2 2 0 3]

    You can generate the pairings as you desire.