Ranking methods: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|AWK}}: Language name caps.)
Line 24: Line 24:


=={{header|AWK}}==
=={{header|AWK}}==
This needs separate files for each method of ranking:
This uses separate files for each method of ranking:
<lang awk>##
<lang awk>##
## Dense ranking in file: ranking_d.awk
## Dense ranking in file: ranking_d.awk

Revision as of 22:48, 6 July 2014

Ranking methods is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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:

  1. Standard.
  2. Modified.
  3. Dense.
  4. Ordinal.
  5. 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>##

    1. 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() }

    1. 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) }}}
    1. 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++]} }
    1. Ordinal ranking in file: ranking_o.awk

function o_rank(){ print FNR, $0 } //{o_rank() }

    1. 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')