Skip to content

Commit

Permalink
feat: compute z-scores at /z-score
Browse files Browse the repository at this point in the history
  • Loading branch information
ddunne6 committed May 14, 2023
1 parent 1950f3b commit 1a36c41
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
18 changes: 18 additions & 0 deletions app_ratings/models.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import itertools
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
from django.contrib.auth.models import User
from django.db.models import Avg
from django_countries.fields import CountryField
from django.utils.functional import cached_property
import numpy as np
import scipy.stats as stats

class Country(models.Model):
running_order = models.IntegerField()
Expand All @@ -27,6 +30,21 @@ def average_score(self):
else:
avg = str(round(avg, 2))
return avg

@cached_property
def z_score(self):
z_scores_for_country = []
for user in User.objects.all():
country_ids = list(Rating.objects.filter(voter=user.id).values_list("country__id", flat=True))
user_ratings = np.array(
list(
itertools.chain(*Rating.objects.filter(voter=user.id).values_list("score")))
)
z_scores = stats.zscore(user_ratings)
for i in range(0, len(country_ids)):
if country_ids[i] == self.id:
z_scores_for_country.append(round(z_scores[i], 3))
return round(sum(z_scores_for_country) / len(z_scores_for_country), 3)

class Rating(models.Model):
score = models.IntegerField(
Expand Down
3 changes: 2 additions & 1 deletion app_ratings/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.urls import path
from .views import CreateRating, EditRating, MyRatings, AllRatings
from .views import CreateRating, EditRating, MyRatings, AllRatings, ZScoreRatings

urlpatterns = [
path('rate/', CreateRating.as_view(), name='rate'),
path('update_rate/<int:pk>/', EditRating.as_view(), name='edit_rating'),
path('', MyRatings.as_view(), name='my_ratings'),
path('results/', AllRatings.as_view(), name='all_ratings'),
path('z-score/', ZScoreRatings.as_view(), name='z_score_ratings'),
]
12 changes: 10 additions & 2 deletions app_ratings/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ def get_all_ratings(self):
table_data = []

for country in countries:
table_data.append({"Running Order": f"{country.running_order}", "Country": f"{country.country.name}",
"Average Score": country.average_score})
table_data.append(self.get_table_data_row(country))
country_ratings = ratings.filter(country=country)
for user in users:
if country_ratings.filter(voter=user).exists():
Expand All @@ -120,6 +119,15 @@ def get_all_ratings(self):
table_data[-1][user.username] = "-"

return table_data

def get_table_data_row(self, country: Country):
return {"Running Order": f"{country.running_order}", "Country": f"{country.country.name}",
"Average Score": country.average_score}

def get_users(self):
return User.objects.all()

class ZScoreRatings(AllRatings):
def get_table_data_row(self, country: Country):
return {"Running Order": f"{country.running_order}", "Country": f"{country.country.name}",
"Z-Score": country.z_score}
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ django-crispy-forms==2.0
django-import-export==3.2.0
crispy-bootstrap5==0.7
django-storages[azure]
mysqlclient==2.1.1
mysqlclient==2.1.1
numpy==1.24.3
scipy==1.10.1

0 comments on commit 1a36c41

Please sign in to comment.