From 9143ce6397082eaf60f083679ea0241ca498a6d1 Mon Sep 17 00:00:00 2001 From: Antonio Golfari Date: Wed, 30 Aug 2023 12:52:44 +0200 Subject: [PATCH] team / nation rankings --- airscore/core/result.py | 63 ++++--- airscore/static/js/pop_country_overall.js | 160 ++++++++---------- airscore/static/js/pop_country_task.js | 32 ++-- airscore/static/js/pop_team_overall.js | 30 ++-- airscore/static/js/pop_team_task.js | 27 ++- .../templates/public/country_overall.html | 11 +- 6 files changed, 160 insertions(+), 163 deletions(-) diff --git a/airscore/core/result.py b/airscore/core/result.py index edbd22e5..61270d2b 100644 --- a/airscore/core/result.py +++ b/airscore/core/result.py @@ -1152,6 +1152,10 @@ def get_task_country_scoring(filename): if not formula['country_scoring']: print(f'Country Scoring is not available') return {'error': 'Country Scoring is not available'} + + '''score decimals''' + td = 0 if 'task_result_decimal' not in formula.keys() else int(data['formula']['task_result_decimal']) + countries = get_country_list(countries=set(map(lambda x: x['nat'], data['results']))) size = formula['team_size'] if 'country_size' not in formula.keys() else formula['country_size'] for nat in countries: @@ -1162,12 +1166,12 @@ def get_task_country_scoring(filename): ) nat['score'] = sum([p['score'] for p in nat_pilots][:size]) for rank, p in enumerate(nat_pilots): - p['group'] = f". {nat['name']} - {nat['score']:.0f} points" + p['group'] = f". {nat['name']} - {c_round(nat['score'], td)} points" p['nation_score'] = nat['score'] if rank >= size: - p['score'] = f"{p['score']:.2f}" + p['score'] = f"{c_round(p['score'], td)}" else: - p['score'] = f"{p['score']:.2f}" + p['score'] = f"{c_round(p['score'], td)}" teams.append(nat) pilots.extend(nat_pilots) # get rank after sort @@ -1188,19 +1192,24 @@ def get_comp_country_scoring(filename): if not formula['country_scoring']: print(f'Country Scoring is not available') return None + + '''score decimals''' + td = 0 if 'task_result_decimal' not in formula.keys() else int(data['formula']['task_result_decimal']) + cd = 0 if 'comp_result_decimal' not in formula.keys() else int(data['formula']['comp_result_decimal']) + '''get info: countries list, team size, task codes''' countries = get_country_list(countries=set(map(lambda x: x['nat'], data['results']))) + '''rankings''' + rankings = [dict(rank=1, counter=0, prev=None, **rank) for rank in data['rankings'] + if rank['rank_type'] in ('overall', 'country')] size = formula['team_size'] if 'country_size' not in formula.keys() else formula['country_size'] - tasks = [t['task_code'] for t in data['tasks']] + tasks = [t['task_code'] for t in data['tasks'] if not t['training']] teams = [] pilots = [] all_scores = [] - all_possible_tasks = [] - - # setup the 20 task placeholders - for t in range(1, 21): - all_possible_tasks.append('T' + str(t)) + rank = 0 + prev = None for nat in countries: nat_pilots = [p for p in data['results'] if p['nat'] == nat['code'] and p['nat_team'] == 1] score = 0 @@ -1209,32 +1218,34 @@ def get_comp_country_scoring(filename): nat_pilots = sorted(nat_pilots, key=lambda k: k['results'][t]['pre'], reverse=True) '''adjust values''' for idx, p in enumerate(nat_pilots): + pre = c_round(p['results'][t]['pre'] or 0, td) if idx < size: - score += p['results'][t]['pre'] - p['results'][t]['score'] = p['results'][t]['pre'] + score += pre + p['results'][t]['score'] = pre p['results'][t]['perf'] = 1 else: - p['results'][t]['score'] = f"{int(p['results'][t]['pre'])}" + p['results'][t]['score'] = f"{pre}" p['results'][t]['perf'] = 0 - for t in list(set(all_possible_tasks) - set(tasks)): - for idx, p in enumerate(nat_pilots): - p['results'][t] = {'score': ''} '''final nation sorting''' for p in nat_pilots: p['score'] = sum(p['results'][t]['score'] for t in tasks if not isinstance(p['results'][t]['score'], str)) - p['group'] = f". {nat['name']} - {score:.0f} points" + p['group'] = f". {nat['name']} - {c_round(score, cd)} points" p['nation_score'] = score nat_pilots = sorted(nat_pilots, key=lambda k: k['score'], reverse=True) pilots.extend(nat_pilots) nat['score'] = score teams.append(nat) + # get rank after sort for t in teams: all_scores.append(t['score']) for row in pilots: row['group'] = str(sum(map(lambda x: x > row['nation_score'], all_scores)) + 1) + row['group'] - return {'teams': teams, 'data': pilots, 'info': data['info'], 'formula': data['formula'], 'stats': data['stats']} + # '''manage rankings''' + + return {'data': pilots, 'info': data['info'], 'tasks': data['tasks'], + 'formula': data['formula'], 'stats': data['stats'], 'rankings': rankings} def get_task_team_scoring(filename): @@ -1250,6 +1261,10 @@ def get_task_team_scoring(filename): if not formula['team_scoring']: print(f'Team Scoring is not available') return None + + '''score decimals''' + td = 0 if 'task_result_decimal' not in formula.keys() else int(data['formula']['task_result_decimal']) + pilots_list = [p for p in data['results'] if not p['team'] in [None, '']] teams_list = set(map(lambda x: x['team'].strip().title(), pilots_list)) size = formula['team_size'] @@ -1263,12 +1278,12 @@ def get_task_team_scoring(filename): team['pilots'] = team_pilots team['score'] = sum([p['score'] for p in team_pilots][:size]) for rank, p in enumerate(team_pilots): - p['group'] = f". {team['name']} - {team['score']:.0f} points" + p['group'] = f". {team['name']} - {c_round(team['score'], td)} points" p['team_score'] = team['score'] if rank >= size: - p['score'] = f"{p['score']:.2f}" + p['score'] = f"{c_round(p['score'], td)}" else: - p['score'] = f"{p['score']:.2f}" + p['score'] = f"{c_round(p['score'], td)}" teams.append(team) pilots.extend(team_pilots) # get rank after sort @@ -1293,12 +1308,16 @@ def get_comp_team_scoring(filename): pilots_list = [p for p in data['results'] if not p['team'] in [None, '']] teams_list = set(map(lambda x: x['team'].strip().title(), pilots_list)) size = formula['team_size'] - tasks = [t['task_code'] for t in data['tasks']] + tasks = [t['task_code'] for t in data['tasks'] if not t.get('training')] teams = [] pilots = [] all_scores = [] all_possible_tasks = [] + '''score decimals''' + td = 0 if 'task_result_decimal' not in formula.keys() else int(data['formula']['task_result_decimal']) + cd = 0 if 'comp_result_decimal' not in formula.keys() else int(data['formula']['comp_result_decimal']) + # setup the 20 task placeholders for t in range(1, 21): all_possible_tasks.append('T' + str(t)) @@ -1325,7 +1344,7 @@ def get_comp_team_scoring(filename): '''final team sorting''' for p in team_pilots: p['score'] = sum(p['results'][t]['score'] for t in tasks if not isinstance(p['results'][t]['score'], str)) - p['group'] = f". {team['name']} - {score:.0f} points" + p['group'] = f". {team['name']} - {c_round(score, cd)} points" p['team_score'] = score team_pilots = sorted(team_pilots, key=lambda k: k['score'], reverse=True) pilots.extend(team_pilots) diff --git a/airscore/static/js/pop_country_overall.js b/airscore/static/js/pop_country_overall.js index 4f258444..2335a933 100644 --- a/airscore/static/js/pop_country_overall.js +++ b/airscore/static/js/pop_country_overall.js @@ -1,99 +1,77 @@ -function populate_country_overall(comPk){ -$(document).ready(function() { - $('#task_result').dataTable({ - ajax: '/_get_comp_country_result/'+comPk, - paging: false, - searching: true, - saveState: true, - info: false, - "dom": 'lrtip', - columns: [ - {data: 'group', title:'group'}, - {data: 'score', title:'Total'}, - {data: 'nation_score', title:'Nation Total'}, - {data: 'fai_id', title:'FAI'}, - {data: 'civl_id', title:'CIVL'}, - {data: 'glider', title:'Glider'}, - {data: 'glider_cert', title:'EN'}, - {data: 'name', title:'Name'}, - {data: 'nat', title:'NAT'}, - {data: 'sex', title:'Sex'}, - {data: 'sponsor', title:'Sponsor'}, - {data: 'results.T1.score', title:'T1'}, - {data: 'results.T2.score', title: 'T2'}, - {data: 'results.T3.score', title: 'T3'}, - {data: 'results.T4.score', title: 'T4'}, - {data: 'results.T5.score', title: 'T5'}, - {data: 'results.T6.score', title: 'T6'}, - {data: 'results.T7.score', title: 'T7'}, - {data: 'results.T8.score', title: 'T8'}, - {data: 'results.T9.score', title: 'T9'}, - {data: 'results.T10.score', title: 'T10'}, - {data: 'results.T11.score', title: 'T11'}, - {data: 'results.T12.score', title: 'T12'}, - {data: 'results.T13.score', title: 'T13'}, - {data: 'results.T14.score', title: 'T14'}, - {data: 'results.T15.score', title: 'T15'}, - {data: 'results.T16.score', title: 'T16'}, - {data: 'results.T17.score', title: 'T17'}, - {data: 'results.T18.score', title: 'T18'}, - {data: 'results.T19.score', title: 'T19'}, - {data: 'results.T20.score', title: 'T20'} -], +function populate_country_overall(compid){ + $('#comp_name').text('Loading Results ...'); - orderFixed: [[2, 'desc'],[1, 'desc']], - - rowGroup: { - dataSrc: ['group'] -// startRender: function (rows, group) { return (group )} - - }, - "columnDefs": [ - { - "targets": [ 0, 1, 2, 3, 4, 5, 6,], - "visible": false - }, - ], - "initComplete": function(settings, json) - { - var table= $('#task_result'); - var rows = $("tr", table).length-1; - var numCols = $("th", table).length+6; - - // comp info - $('#comp_name').text(json.info.comp_name + " - Nations"); - $('#comp_date').text(json.info.date_from + ' - ' + json.info.date_to); + $.ajax({ + type: "GET", + url: '/_get_comp_country_result/'+compid, + contentType:"application/json", + dataType: "json", + success: function (json) { + var compid = json.info.id; + var taskNum = json.stats.valid_tasks + console.log('taskNum='+taskNum); + var columns = []; + var idx = 0; + // rankings + // console.log(json.rankings); + // json.rankings.forEach( function(item, index) { + // columns.push({data: 'rankings.'+item.rank_id.toString(), title: '#', name: item.rank_id.toString(), className: "text-right", defaultContent: '', visible: false}); + // }); + columns.push({data: 'group', title:'Group', className: "text-right", defaultContent: '', visible: false}); + columns.push({data: 'score', title:'Total', className: "text-right", defaultContent: '', visible: false}); + columns.push({data: 'nation_score', title:'Nation Total', className: "text-right", defaultContent: '', visible: false}); + columns.push({data: 'fai_id', title:'FAI', className: "text-right", defaultContent: '', visible: false}); + columns.push({data: 'civl_id', title:'CIVL', className: "text-right", defaultContent: '', visible: false}); + columns.push({data: 'name', title:'Name', render: function ( data, type, row ) { let span = ''; if (row.sex == 'F'){span=''}; return span + data + ''}}); + columns.push({data: 'glider', title:'Equip'}); + columns.push({data: 'glider_cert', title:'EN', defaultContent: '', visible: false}); + columns.push({data: 'nat', title:'NAT', defaultContent: '', visible: false}); + columns.push({data: 'sex', title:'Sex', defaultContent: '', visible: false}); + columns.push({data: 'sponsor', title:'Sponsor'}); + json.tasks.forEach( function(item, index) { + let code = item.task_code + console.log( item.task_code.toString() + ': ' + item.training.toString()); + if ( !item.training ) { + columns.push({data: 'results.'+code+'.score', title: code, className: "text-right", defaultContent: ''}); + } + }); + $('#results_table').dataTable({ + data: json.data, + paging: false, + searching: true, + saveState: true, + info: false, + dom: 'lrtip', + columns: columns, + orderFixed: [[3, 'desc'],[2, 'desc']], + rowGroup: {dataSrc: 'group'}, + initComplete: function(settings) { + var table= $('#results_table'); + var rows = $("tr", table).length-1; + var numCols = table.DataTable().columns().nodes().length; - // some GAP parameters - $('#formula tbody').append( - "Director" + json.info.MD_name + '' + - "Location" + json.info.comp_site + '' + - "Formula" + json.formula.formula + '' + - "Overall Scoring" + json.formula.overall_validity + ' (' + json.formula.validity_param*100 + ')'); - if (json.formula.overall_validity == 'ftv') - { - $('#formula tbody').append( - "Total Validity" + json.stats.tot_validity + ''); - } + // comp info + console.log(json.info); + $('#comp_name').text(json.info.comp_name + " - Nations"); + $('#comp_date').text(json.info.date_from + ' - ' + json.info.date_to); - // remove empty cols - for ( var i=1; i<=numCols; i++ ) - { - var empty = true; - table.DataTable().column(i).data().each( function (e, i) { - if (e != "") - { - empty = false; - return false; - } - } ); + // some GAP parameters + $('#formula tbody').append( + "Director" + json.info.MD_name + "" + + "Location" + json.info.comp_site + "" + + "Formula" + json.formula.country_size + " scoring, max " + json.formula.max_country_size + " pilots" + ); - if (empty) { - table.DataTable().column( i ).visible( false ); + $("#dhv option").remove(); // Remove all ") + // .text(item.rank_name) + // .val(item.rank_id) + // ); + // }); } - } - + }); } }); -}); } \ No newline at end of file diff --git a/airscore/static/js/pop_country_task.js b/airscore/static/js/pop_country_task.js index 9e897641..3b8557d5 100644 --- a/airscore/static/js/pop_country_task.js +++ b/airscore/static/js/pop_country_task.js @@ -14,12 +14,11 @@ $(document).ready(function() { {data: 'civl_id', title:'CIVL'}, {data: 'glider', title:'Glider'}, {data: 'glider_cert', title:'EN'}, - {data: 'name', title:'Name'}, + {data: 'name', title:'Name', "render": function ( data, type, row ) { let span = ''; if (row.sex == 'F'){span=''}; return span + data + ''}}, {data: 'nat', title:'NAT'}, {data: 'sex', title:'Sex'}, {data: 'sponsor', title:'Sponsor'}, - {data: 'score', title:'Total'} - + {data: 'score', title:'Total', className: "text-right"} ], orderFixed: [[1, 'desc'],[10, 'desc']], @@ -30,7 +29,7 @@ $(document).ready(function() { }, "columnDefs": [ { - "targets": [ 0, 1, 2, 3, 4, 5], + "targets": [0, 1, 2, 3, 4, 5], "visible": false }, ], @@ -47,20 +46,19 @@ $(document).ready(function() { // some GAP parameters $('#formula tbody').append( - "Director" + json.info.MD_name + '' + - "Location" + json.info.comp_site + '' + - "Formula" + json.formula.formula_name + '' + - "Overall Scoring" + json.formula.overall_validity); - if (json.formula.overall_validity == 'ftv') { - $('#formula tbody').append( - ' (' + json.formula.validity_param*100 + ')' + - "Total Validity" + json.stats.total_validity + ''); - } - else { - $('#formula tbody').append(''); - } - + "Director" + json.info.MD_name + "" + + "Location" + json.info.comp_site + "" + + "Formula" + json.formula.country_size + " scoring, max " + json.formula.max_country_size + " pilots" + ); + $("#dhv option").remove(); // Remove all ") + // .text(item.rank_name) + // .val(item.rank_id) + // ); + // }); } }); }); diff --git a/airscore/static/js/pop_team_overall.js b/airscore/static/js/pop_team_overall.js index 4b167533..14ec66b0 100644 --- a/airscore/static/js/pop_team_overall.js +++ b/airscore/static/js/pop_team_overall.js @@ -7,7 +7,6 @@ function populate_team_overall(compid){ contentType:"application/json", dataType: "json", success: function (json) { - var compid = json.info.id; var taskNum = json.stats.valid_tasks console.log('taskNum='+taskNum); @@ -23,7 +22,7 @@ function populate_team_overall(compid){ columns.push({data: 'team_score', title:'Team Total', className: "text-right", defaultContent: '', visible: false}); columns.push({data: 'fai_id', title:'FAI', className: "text-right", defaultContent: '', visible: false}); columns.push({data: 'civl_id', title:'CIVL', className: "text-right", defaultContent: '', visible: false}); - columns.push({data: 'name', title:'Name'}); + columns.push({data: 'name', title:'Name', render: function ( data, type, row ) { let span = ''; if (row.sex == 'F'){span=''}; return span + data + ''}}); columns.push({data: 'glider', title:'Equip'}); columns.push({data: 'glider_cert', title:'EN', defaultContent: '', visible: false}); columns.push({data: 'nat', title:'NAT', defaultContent: '', visible: false}); @@ -58,24 +57,19 @@ function populate_team_overall(compid){ // some GAP parameters $('#formula tbody').append( - "Director" + json.info.MD_name + '' + - "Location" + json.info.comp_site + '' + - "Formula" + json.formula.formula + '' + - "Overall Scoring" + json.formula.overall_validity + ' (' + json.formula.validity_param*100 + ')' + "Director" + json.info.MD_name + "" + + "Location" + json.info.comp_site + "" + + "Formula" + json.formula.team_size + " scoring, max " + json.formula.max_team_size + " pilots" ); - if (json.formula.overall_validity == 'ftv') { - $('#formula tbody').append("Total Validity" + json.stats.tot_validity + ''); - } + $("#dhv option").remove(); // Remove all ") - .text(item.rank_name) - .val(item.rank_id) - ); - }); + // $.each(json.rankings, function(index, item) { + // $("#dhv").append( + // $("") + // .text(item.rank_name) + // .val(item.rank_id) + // ); + // }); } }); } diff --git a/airscore/static/js/pop_team_task.js b/airscore/static/js/pop_team_task.js index 8a27d346..ffe4e4d8 100644 --- a/airscore/static/js/pop_team_task.js +++ b/airscore/static/js/pop_team_task.js @@ -18,7 +18,7 @@ $(document).ready(function() { {data: 'nat', title:'NAT'}, {data: 'sex', title:'Sex'}, {data: 'sponsor', title:'Sponsor'}, - {data: 'score', title:'Total'} + {data: 'score', title:'Total', className: "text-right"} ], @@ -47,20 +47,19 @@ $(document).ready(function() { // some GAP parameters $('#formula tbody').append( - "Director" + json.info.MD_name + '' + - "Location" + json.info.comp_site + '' + - "Formula" + json.formula.formula_name + '' + - "Overall Scoring" + json.formula.overall_validity); - if (json.formula.overall_validity == 'ftv') { - $('#formula tbody').append( - ' (' + json.formula.validity_param*100 + ')' + - "Total Validity" + json.stats.total_validity + ''); - } - else { - $('#formula tbody').append(''); - } - + "Director" + json.info.MD_name + "" + + "Location" + json.info.comp_site + "" + + "Formula" + json.formula.country_size + " scoring, max " + json.formula.max_country_size + " pilots" + ); + $("#dhv option").remove(); // Remove all ") + // .text(item.rank_name) + // .val(item.rank_id) + // ); + // }); } }); }); diff --git a/airscore/templates/public/country_overall.html b/airscore/templates/public/country_overall.html index 1e591eb0..69993b31 100644 --- a/airscore/templates/public/country_overall.html +++ b/airscore/templates/public/country_overall.html @@ -19,6 +19,14 @@

+
@@ -33,7 +41,7 @@

{% from "macros.html" import datatable with context %} - {{ datatable('task_result') }} + {{ datatable('results_table') }} {% endblock %} @@ -41,5 +49,6 @@

+ {% endblock %} \ No newline at end of file