From bbb5e63b77a245e7d4b4e172662005db6d270e9c Mon Sep 17 00:00:00 2001 From: Brennan Bibic Date: Fri, 13 Sep 2024 09:28:25 -0400 Subject: [PATCH] Speed + corrections on calculations --- ranked/templates/ranked/player_info.html | 8 ++- ranked/views.py | 68 ++++++++++++------------ 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/ranked/templates/ranked/player_info.html b/ranked/templates/ranked/player_info.html index cd59d59..46a447e 100644 --- a/ranked/templates/ranked/player_info.html +++ b/ranked/templates/ranked/player_info.html @@ -91,14 +91,16 @@
Player Win Rate + W-T-L Total Matches {% for player_with in players_with %} - {{ player_with.player__username }} + {{ player_with.username }} {{ player_with.win_rate|floatformat:2 }}% + {{ player_with.wins }}-{{ player_with.ties }}-{{ player_with.losses }} {{ player_with.total_matches }} {% endfor %} @@ -124,14 +126,16 @@
Player Win Rate + W-T-L Total Matches {% for player_against in players_against %} - {{ player_against.player__username }} + {{ player_against.username }} {{ player_against.win_rate|floatformat:2 }}% + {{ player_against.wins }}-{{ player_against.ties }}-{{ player_against.losses }} {{ player_against.total_matches }} {% endfor %} diff --git a/ranked/views.py b/ranked/views.py index 70475ae..b3bb3fa 100644 --- a/ranked/views.py +++ b/ranked/views.py @@ -1,5 +1,5 @@ from django.shortcuts import render, HttpResponseRedirect -from django.db.models import Max, Min, F, Q, Count, ExpressionWrapper, FloatField, Case, When, Value +from django.db.models import Max, Min, F, Q, Count, ExpressionWrapper, FloatField, Case, When, Value, IntegerField, Sum from django.utils import timezone from datetime import datetime, timedelta import math @@ -122,23 +122,22 @@ def player_info(request, name, player_id): Q(blue_alliance__in=matches.filter(blue_alliance=player.player)) ).exclude(id=player.player.id).distinct() - players_with_stats = [] - for played_with in players_with: - matches_together = matches.filter( - (Q(red_alliance=player.player) & Q(red_alliance=played_with)) | - (Q(blue_alliance=player.player) & Q(blue_alliance=played_with)) - ) - total_matches = matches_together.count() - wins = matches_together.filter( - (Q(red_alliance=player.player) & Q(red_alliance=played_with) & Q(red_score__gt=F('blue_score'))) | - (Q(blue_alliance=player.player) & Q(blue_alliance=played_with) & Q(blue_score__gt=F('red_score'))) - ).count() - win_rate = (wins / total_matches * 100) if total_matches > 0 else 0 - players_with_stats.append({ - 'player__username': played_with.username, - 'total_matches': total_matches, - 'win_rate': win_rate - }) + players_with_stats = players_with.annotate( + total_matches=Count('red_alliance', filter=Q(red_alliance__in=matches)) + + Count('blue_alliance', filter=Q(blue_alliance__in=matches)), + wins=Count(Case( + When(Q(red_alliance__in=matches.filter(red_alliance=player.player), red_score__gt=F('blue_score')), then=1), + When(Q(blue_alliance__in=matches.filter(blue_alliance=player.player), blue_score__gt=F('red_score')), then=1), + output_field=IntegerField(), + )), + ties=Count(Case( + When(Q(red_alliance__in=matches) | Q(blue_alliance__in=matches), red_score=F('blue_score'), then=1), + output_field=IntegerField(), + )), + ).annotate( + losses=F('total_matches') - F('wins') - F('ties'), + win_rate=(F('wins') * 2 + F('ties')) * 100.0 / (F('total_matches') * 2) + ).values('username', 'total_matches', 'wins', 'ties', 'losses', 'win_rate') players_with_stats = sorted(players_with_stats, key=lambda x: (-x['win_rate'], -x['total_matches'])) @@ -148,23 +147,22 @@ def player_info(request, name, player_id): Q(blue_alliance__in=matches.filter(red_alliance=player.player)) ).distinct() - players_against_stats = [] - for played_against in players_against: - matches_against = matches.filter( - (Q(red_alliance=player.player) & Q(blue_alliance=played_against)) | - (Q(blue_alliance=player.player) & Q(red_alliance=played_against)) - ) - total_matches = matches_against.count() - wins = matches_against.filter( - (Q(red_alliance=player.player) & Q(red_score__gt=F('blue_score'))) | - (Q(blue_alliance=player.player) & Q(blue_score__gt=F('red_score'))) - ).count() - win_rate = (wins / total_matches * 100) if total_matches > 0 else 0 - players_against_stats.append({ - 'player__username': played_against.username, - 'total_matches': total_matches, - 'win_rate': win_rate - }) + players_against_stats = players_against.annotate( + total_matches=Count('red_alliance', filter=Q(red_alliance__in=matches)) + + Count('blue_alliance', filter=Q(blue_alliance__in=matches)), + wins=Count(Case( + When(Q(red_alliance__in=matches.filter(blue_alliance=player.player), red_score__gt=F('blue_score')), then=1), + When(Q(blue_alliance__in=matches.filter(red_alliance=player.player), blue_score__gt=F('red_score')), then=1), + output_field=IntegerField(), + )), + ties=Count(Case( + When(Q(red_alliance__in=matches) | Q(blue_alliance__in=matches), red_score=F('blue_score'), then=1), + output_field=IntegerField(), + )), + ).annotate( + losses=F('total_matches') - F('wins') - F('ties'), + win_rate=(F('wins') * 2 + F('ties')) * 100.0 / (F('total_matches') * 2) + ).values('username', 'total_matches', 'wins', 'ties', 'losses', 'win_rate') players_against_stats = sorted(players_against_stats, key=lambda x: (-x['win_rate'], -x['total_matches']))