Ranking methods
The numerical rank of competitors in a competition shows if one is better than, equal to, or worse than another based on their results in a competition.
The numerical rank of a competitor can be assigned in several different ways.
- Task
The following scores are accrued for all competitors of a competition (in best-first order):
44 Solomon 42 Jason 42 Errol 41 Garry 41 Bernard 41 Barry 39 Stephen
Create functions/methods/procedures/subroutines... that apply one, each, of the following ranking methods to an ordered list of scores with scorers:
- Standard.
- Modified.
- Dense.
- Ordinal.
- Fractional.
Show here, on this page, the ranking of the test scores under each of the numbered ranking methods.
AWK
This uses separate files for each method of ranking: <lang awk>##
- Dense ranking in file: ranking_d.awk
BEGIN{ lastresult = "!"; lastrank = 0 }
function d_rank(){
if($1==lastresult){ print lastrank, $0 }else{ lastresult = $1 print ++lastrank, $0 }
} //{d_rank() }
- Fractional ranking in file: ranking_f.awk
BEGIN{
last = "!" flen = 0 }
function f_rank(){
item = $0 if($1!=last){ if(flen){ sum = 0 for(fl=0; fl < flen;){ $0 = fifo[fl++] sum += $1 } mean = sum / flen for(fl=0; fl < flen;){ $0 = fifo[fl++] $1 = "" printf("%3g %s\n", mean, $0) } flen = 0 }} $0 = item last = $1 fifo[flen++] = sprintf("%i %s", FNR, item)
} //{f_rank()}
END{ if(flen){
sum = 0 for(fl=0; fl < flen;){ $0 = fifo[fl++] sum += $1 } mean = sum / flen for(fl=0; fl < flen;){ $0 = fifo[fl++] $1 = "" printf("%3g %s\n", mean, $0) }}}
- Modified competition ranking in file: ranking_mc.awk
BEGIN{
lastresult = "!" flen = 0 }
function mc_rank(){
if($1==lastresult){ fifo[flen++] = $0 }else{ for(fl=0; fl < flen;){ print FNR-1, fifo[fl++]} flen = 0 fifo[flen++] = $0 lastresult = $1}
} //{mc_rank()}
END{ for(fl=0; fl < flen;){
print FNR, fifo[fl++]} }
- Ordinal ranking in file: ranking_o.awk
function o_rank(){ print FNR, $0 } //{o_rank() }
- Standard competition ranking in file: ranking_sc.awk
BEGIN{ lastresult = lastrank = "!" }
function sc_rank(){
#print"sc_rank" if($1==lastresult){ print lastrank, $0 }else{ print FNR, $0 lastresult = $1 lastrank = FNR}
} //{sc_rank()} </lang>
The input as a file ranking.txt
:
44 Solomon 42 Jason 42 Errol 41 Garry 41 Bernard 41 Barry 39 Stephen
- Output:
C:\Users\RC\Code>awk -f ranking_sc.awk ranking.txt 1 44 Solomon 2 42 Jason 2 42 Errol 4 41 Garry 4 41 Bernard 4 41 Barry 7 39 Stephen C:\Users\RC\Code>awk -f ranking_mc.awk ranking.txt 1 44 Solomon 3 42 Jason 3 42 Errol 6 41 Garry 6 41 Bernard 6 41 Barry 7 39 Stephen C:\Users\RC\Code>awk -f ranking_d.awk ranking.txt 1 44 Solomon 2 42 Jason 2 42 Errol 3 41 Garry 3 41 Bernard 3 41 Barry 4 39 Stephen C:\Users\RC\Code>awk -f ranking_o.awk ranking.txt 1 44 Solomon 2 42 Jason 3 42 Errol 4 41 Garry 5 41 Bernard 6 41 Barry 7 39 Stephen C:\Users\RC\Code>awk -f ranking_f.awk ranking.txt 1 44 Solomon 2.5 42 Jason 2.5 42 Errol 5 41 Garry 5 41 Bernard 5 41 Barry 7 39 Stephen C:\Users\RC\Code>
Python
<lang python>def mc_rank(iterable, start=1):
"""Modified competition ranking""" lastresult, fifo = None, [] for n, item in enumerate(iterable, start-1): if item[0] == lastresult: fifo += [item] else: while fifo: yield n, fifo.pop(0) lastresult, fifo = item[0], fifo + [item] while fifo: yield n+1, fifo.pop(0)
def sc_rank(iterable, start=1):
"""Standard competition ranking""" lastresult, lastrank = None, None for n, item in enumerate(iterable, start): if item[0] == lastresult: yield lastrank, item else: yield n, item lastresult, lastrank = item[0], n
def d_rank(iterable, start=1):
"""Dense ranking""" lastresult, lastrank = None, start - 1, for item in iterable: if item[0] == lastresult: yield lastrank, item else: lastresult, lastrank = item[0], lastrank + 1 yield lastrank, item
def o_rank(iterable, start=1):
"""Ordinal ranking""" yield from enumerate(iterable, start)
def f_rank(iterable, start=1):
"""Fractional ranking""" last, fifo = None, [] for n, item in enumerate(iterable, start): if item[0] != last: if fifo: mean = sum(f[0] for f in fifo) / len(fifo) while fifo: yield mean, fifo.pop(0)[1] last = item[0] fifo.append((n, item)) if fifo: mean = sum(f[0] for f in fifo) / len(fifo) while fifo: yield mean, fifo.pop(0)[1]
if __name__ == '__main__':
scores = [(44, 'Solomon'), (42, 'Jason'), (42, 'Errol'), (41, 'Garry'), (41, 'Bernard'), (41, 'Barry'), (39, 'Stephen')]
print('\nScores to be ranked (best first):') for s in scores: print(' %2i %s' % (s )) for ranker in [sc_rank, mc_rank, d_rank, o_rank, f_rank]: print('\n%s:' % ranker.__doc__) for rank, score in ranker(scores): print(' %3g, %r' % (rank, score))</lang>
- Output:
Scores to be ranked (best first): 44 Solomon 42 Jason 42 Errol 41 Garry 41 Bernard 41 Barry 39 Stephen Standard competition ranking: 1, (44, 'Solomon') 2, (42, 'Jason') 2, (42, 'Errol') 4, (41, 'Garry') 4, (41, 'Bernard') 4, (41, 'Barry') 7, (39, 'Stephen') Modified competition ranking: 1, (44, 'Solomon') 3, (42, 'Jason') 3, (42, 'Errol') 6, (41, 'Garry') 6, (41, 'Bernard') 6, (41, 'Barry') 7, (39, 'Stephen') Dense ranking: 1, (44, 'Solomon') 2, (42, 'Jason') 2, (42, 'Errol') 3, (41, 'Garry') 3, (41, 'Bernard') 3, (41, 'Barry') 4, (39, 'Stephen') Ordinal ranking: 1, (44, 'Solomon') 2, (42, 'Jason') 3, (42, 'Errol') 4, (41, 'Garry') 5, (41, 'Bernard') 6, (41, 'Barry') 7, (39, 'Stephen') Fractional ranking: 1, (44, 'Solomon') 2.5, (42, 'Jason') 2.5, (42, 'Errol') 5, (41, 'Garry') 5, (41, 'Bernard') 5, (41, 'Barry') 7, (39, 'Stephen')