Private
Public Access
1
0

stats report alert

This commit is contained in:
Sander Roosendaal
2019-08-29 14:46:34 +02:00
parent 890a93044c
commit a91e454eaa
6 changed files with 93 additions and 16 deletions

View File

@@ -169,6 +169,10 @@ def alert_get_stats(alert,nperiod=0):
percentage = int(100.*nr_strokes_qualifying/nr_strokes) percentage = int(100.*nr_strokes_qualifying/nr_strokes)
else: else:
percentage = 0 percentage = 0
median_q = df2[alert.measured.metric].median()
median = df[alert.measured.metric].median()
std = df[alert.measured.metric].std()
return { return {
'workouts':len(workouts), 'workouts':len(workouts),
@@ -177,7 +181,10 @@ def alert_get_stats(alert,nperiod=0):
'nr_strokes':nr_strokes, 'nr_strokes':nr_strokes,
'nr_strokes_qualifying':nr_strokes_qualifying, 'nr_strokes_qualifying':nr_strokes_qualifying,
'percentage': percentage, 'percentage': percentage,
'nperiod':nperiod, 'nperiod':nperiod,
'median':median,
'median_q':median_q,
'standard_dev':std,
} }
# run alert report # run alert report

View File

@@ -881,9 +881,12 @@ class Rower(models.Model):
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
try: try:
for group in self.coachinggroups.all(): for group in self.coachinggroups.all():
coach = Rower.objects.get(mycoachgroup=group) try:
if coach.rowerplan == 'freecoach': coach = Rower.objects.get(mycoachgroup=group)
self.coachinggroups.remove(group) if coach.rowerplan == 'freecoach':
self.coachinggroups.remove(group)
except Rower.DoesNotExist:
pass
except ValueError: except ValueError:
pass pass
@@ -1093,6 +1096,11 @@ class Alert(models.Model):
return stri return stri
def metricname(self):
metricdict = {key:value for (key,value) in parchoicesy1}
return metricdict[self.measured.metric]
def description(self): def description(self):
metricdict = {key:value for (key,value) in parchoicesy1} metricdict = {key:value for (key,value) in parchoicesy1}
@@ -1115,6 +1123,24 @@ class Alert(models.Model):
return description return description
def shortdescription(self):
metricdict = {key:value for (key,value) in parchoicesy1}
if self.measured.condition == 'between':
description = '{value1} < {metric} < {value2}'.format(
metric = self.measured.metric,
value1 = self.measured.value1,
value2 = self.measured.value2,
)
else:
description = '{metric} {condition} {value1}'.format(
metric = self.measured.metric,
value1 = self.measured.value1,
condition = self.measured.condition
)
return description
class AlertEditForm(ModelForm): class AlertEditForm(ModelForm):
class Meta: class Meta:

View File

@@ -1,5 +1,6 @@
{% extends "newbase.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %}
{% block title %}Metric Alert{% endblock %} {% block title %}Metric Alert{% endblock %}
@@ -13,19 +14,33 @@
</p> </p>
<ul class="main-content"> <ul class="main-content">
<li>
{{ stats|lookuplong:'startdate' }} - {{ stats|lookuplong:'enddate' }}
</li>
<li class="grid_4"> <li class="grid_4">
<h2>Alert</h2> <h2>{{ alert.name }}</h2>
<p>{{ alert }}</p> <p>{{ alert }}</p>
<p>{{ alert.description }}</p> <p>{{ alert.description }}</p>
<p>This is a page under construction. Currently with minimal information</p> <p>This is a page under construction. Currently with minimal information</p>
</li> </li>
{% for key, value in stats.items %} <li class="rounder">
<li> <h2>Score</h2>
<h2>{{ key }}</h2> <hr>
<p>{{ value }}</p> <h2>{{ stats|lookup:'percentage' }}%</h2>
</li>
<li class="rounder">
<h2>Data set</h2>
<hr>
<p>{{ stats|lookup:'workouts' }} workouts</p>
<p>{{ stats|lookup:'nr_strokes_qualifying' }} strokes out of {{ stats|lookup:'nr_strokes' }}</p>
</li>
<li class="rounder">
<h2>Statistics</h2>
<hr>
<p>Median {{ alert.metricname }}: {{ stats|lookup:'median'|sigdig }}</p>
<p>Median {{ alert.metricname }}: {{ stats|lookup:'median_q'|sigdig }} ({{ alert.shortdescription }})</p>
</li> </li>
{% endfor %}
</ul> </ul>

View File

@@ -4,6 +4,7 @@ from time import strftime
from django.utils import timezone from django.utils import timezone
import dateutil.parser import dateutil.parser
import json import json
import math
import datetime import datetime
import re import re
register = template.Library() register = template.Library()
@@ -37,6 +38,25 @@ from django.template.defaultfilters import stringfilter
from six import string_types from six import string_types
@register.filter
def sigdig(value, digits = 3):
try:
order = int(math.floor(math.log10(math.fabs(value))))
except (ValueError,TypeError):
return value
# return integers as is
if value % 1 == 0:
return value
places = digits - order - 1
if places > 0:
fmtstr = "%%.%df" % (places)
else:
fmtstr = "%.0f"
return fmtstr % (round(value, places))
@register.filter(is_safe=True, needs_autoescape=True) @register.filter(is_safe=True, needs_autoescape=True)
@stringfilter @stringfilter
def urlshorten(value, limit,autoescape=None): def urlshorten(value, limit,autoescape=None):
@@ -278,18 +298,26 @@ def jsdict(dict,key):
s = dict.get(key) s = dict.get(key)
return mark_safe(json.dumps(s)) return mark_safe(json.dumps(s))
@register.filter @register.filter
def lookup(dict, key): def lookup(dict, key):
s = dict.get(key) try:
s = dict.get(key)
except KeyError:
return None
if isinstance(s,string_types) and len(s) > 22: if isinstance(s,string_types) and len(s) > 22:
s = s[:22] s = s[:22]
return s return s
@register.filter @register.filter
def lookuplong(dict, key): def lookuplong(dict, key):
s = dict.get(key) try:
s = dict.get(key)
except KeyError:
return None
return s return s
@register.filter @register.filter

Binary file not shown.

View File

@@ -4328,7 +4328,8 @@ def alerts_view(request,userid=0):
for alert in alerts: for alert in alerts:
stats.append(alert_get_stats(alert)) stats.append(alert_get_stats(alert))
breadcrumbs = [ breadcrumbs = [
{ {
'url':'/rowers/analysis', 'url':'/rowers/analysis',