Private
Public Access
1
0

Merge branch 'release/v2.85'

This commit is contained in:
Sander Roosendaal
2017-05-16 20:07:12 +02:00
6 changed files with 182 additions and 32 deletions
+17
View File
@@ -95,6 +95,23 @@ from scipy.signal import savgol_filter
import datetime import datetime
def filter_df(datadf,fieldname,value,largerthan=True):
try:
x = datadf[fieldname]
except KeyError:
return datadf
if largerthan:
mask = datadf[fieldname] < value
else:
mask = datadf[fieldname] >= value
datadf.loc[mask,fieldname] = np.nan
return datadf
def clean_df_stats(datadf,workstrokesonly=True,ignorehr=True, def clean_df_stats(datadf,workstrokesonly=True,ignorehr=True,
ignoreadvanced=False): ignoreadvanced=False):
# clean data remove zeros and negative values # clean data remove zeros and negative values
+12
View File
@@ -300,6 +300,18 @@ parchoices = list(sorted(formaxlabels.items(), key = lambda x:x[1]))
class BoxPlotChoiceForm(forms.Form): class BoxPlotChoiceForm(forms.Form):
yparam = forms.ChoiceField(choices=parchoices,initial='spm', yparam = forms.ChoiceField(choices=parchoices,initial='spm',
label='Metric') label='Metric')
spmmin = forms.FloatField(initial=15,
required=False,label = 'Min SPM')
spmmax = forms.FloatField(initial=55,
required=False,label = 'Max SPM')
workmin = forms.FloatField(initial=0,
required=False,label = 'Min Work per Stroke')
workmax = forms.FloatField(initial=1500,
required=False,label = 'Max Work per Stroke')
includereststrokes = forms.BooleanField(initial=False,
required=False,
label='Include Rest Strokes')
class ChartParamChoiceForm(forms.Form): class ChartParamChoiceForm(forms.Form):
plotchoices = ( plotchoices = (
+18 -2
View File
@@ -88,12 +88,19 @@ from rowers.dataprep import nicepaceformat,niceformat
from rowers.dataprep import timedeltaconv from rowers.dataprep import timedeltaconv
def interactive_boxchart(datadf,fieldname,extratitle=''): def interactive_boxchart(datadf,fieldname,extratitle=''):
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,resize'
if datadf.empty:
return '','It looks like there are no data matching your filter'
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,resize,hover'
plot = BoxPlot(datadf, values=fieldname, label='date', plot = BoxPlot(datadf, values=fieldname, label='date',
legend=False, legend=False,
title=axlabels[fieldname]+' '+extratitle, title=axlabels[fieldname]+' '+extratitle,
outliers=False, outliers=False,
tools=TOOLS, tools=TOOLS,
toolbar_location="above",
toolbar_sticky=False,
x_mapper_type='datetime') x_mapper_type='datetime')
yrange1 = Range1d(start=yaxminima[fieldname],end=yaxmaxima[fieldname]) yrange1 = Range1d(start=yaxminima[fieldname],end=yaxmaxima[fieldname])
@@ -134,11 +141,20 @@ def interactive_boxchart(datadf,fieldname,extratitle=''):
plot.xaxis.major_label_orientation = pi/4 plot.xaxis.major_label_orientation = pi/4
hover = plot.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([
('Value','@y'),
('Date','@x'),
])
hover.mode = 'mouse'
script, div = components(plot) script, div = components(plot)
return script,div return script,div
def interactive_forcecurve(theworkouts,workstrokesonly=False): def interactive_forcecurve(theworkouts,workstrokesonly=False):
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair' TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair'
+47
View File
@@ -0,0 +1,47 @@
#!/srv/venv/bin/python
import sys
import os
# If you find a solution that does not need the two paths, please comment!
sys.path.append('$path_to_root_of_project$')
sys.path.append('$path_to_root_of_project$/$project_name$')
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from django.core.mail import send_mail, BadHeaderError,EmailMessage
import datetime
from rowers.models import Rower
from rowsandall_app.settings import BASE_DIR
def getexpired():
rs = Rower.objects.all()
lijst = []
for r in rs:
if r.planexpires < datetime.datetime.now().date():
lijst.append(r)
return lijst
class Command(BaseCommand):
def handle(self, *args, **options):
expiredrowers = getexpired()
fullemail = 'roosendaalsander@gmail.com'
subject = "Expired rowers report"
message = "Dear Sander,\n\n"
message += "Best Regards, the Rowsandall Team"
message += "Expired rowers report\n\n"
for r in expiredrowers:
message += r.user.first_name+" "+r.user.last_name+" "+r.user.username
message += "\n"
email = EmailMessage(subject, message,
'Rowsandall <info@rowsandall.com>',
[fullemail])
res = email.send()
+28 -21
View File
@@ -34,28 +34,35 @@
</style> </style>
<div id="workouts" class="grid_8 alpha">
<h1>Box Chart</h1>
</div>
<div class="grid_4 omega">
<form enctype="multipart/form-data" action="/rowers/user-boxplot/{{ userid }}" method="post">
{% csrf_token %}
<table>
{{ chartform.as_table }}
</table>
<div class="grid_1 prefix_2 suffix_1">
<p>
<input name='workoutselectform' class="button green" type="submit" value="Submit">
</p>
</div>
</form>
</div>
<div class="grid_12 alpha"> <div class="grid_12 alpha">
<h1>Box Chart</h1>
<div id="workouts" class="grid_8 alpha">
<div id="theplot" class="grid_8 alpha flexplot">
<div id="theplot" class="grid_12 alpha flexplot"> {{ the_div|safe }}
{{ the_div|safe }} </div>
</div>
<div class="grid_4 omega">
<div class="grid_4">
<form enctype="multipart/form-data" action="/rowers/user-boxplot/{{ userid }}" method="post">
{% csrf_token %}
<table>
{{ chartform.as_table }}
</table>
<div class="grid_1 prefix_2 suffix_1">
<p>
<input name='workoutselectform' class="button green" type="submit" value="Submit">
</p>
</div>
</form>
</div>
<div class="grid_4">
<p>
You can use the form above to change the metric or filter the data.
Set Min SPM and Max SPM to select only strokes in a certain range of
stroke rates.
Set Work per Stroke to a minimum value to remove "paddle" strokes or turns.
</p>
</div>
</div> </div>
</div> </div>
+58 -7
View File
@@ -3043,6 +3043,15 @@ def boxplot_view(request,userid=0,
cd = form.cleaned_data cd = form.cleaned_data
workouts = cd['workouts'] workouts = cd['workouts']
plotfield = chartform.cleaned_data['yparam'] plotfield = chartform.cleaned_data['yparam']
includereststrokes = chartform.cleaned_data['includereststrokes']
request.session['includereststrokes'] = includereststrokes
workstrokesonly = not includereststrokes
spmmin = chartform.cleaned_data['spmmin']
spmmax = chartform.cleaned_data['spmmax']
workmin = chartform.cleaned_data['workmin']
workmax = chartform.cleaned_data['workmax']
ids = [int(w.id) for w in workouts] ids = [int(w.id) for w in workouts]
request.session['ids'] = ids request.session['ids'] = ids
@@ -3058,12 +3067,25 @@ def boxplot_view(request,userid=0,
fieldlist,fielddict = dataprep.getstatsfields() fieldlist,fielddict = dataprep.getstatsfields()
fieldlist = [plotfield,'workoutid'] fieldlist = [plotfield,'workoutid','spm','driveenergy',
'workoutstate']
# prepare data frame # prepare data frame
datadf = dataprep.read_cols_df_sql(ids,fieldlist) datadf = dataprep.read_cols_df_sql(ids,fieldlist)
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
datadf = dataprep.filter_df(datadf,'spm',spmmin,
largerthan=True)
datadf = dataprep.filter_df(datadf,'spm',spmmax,
largerthan=False)
datadf = dataprep.filter_df(datadf,'driveenergy',workmin,
largerthan=True)
datadf = dataprep.filter_df(datadf,'driveneergy',workmax,
largerthan=False)
datadf.dropna(axis=0,how='any',inplace=True)
datadf['workoutid'].replace(datemapping,inplace=True) datadf['workoutid'].replace(datemapping,inplace=True)
datadf.rename(columns={"workoutid":"date"},inplace=True) datadf.rename(columns={"workoutid":"date"},inplace=True)
datadf = datadf.sort_values(['date']) datadf = datadf.sort_values(['date'])
@@ -3093,6 +3115,13 @@ def boxplot_view(request,userid=0,
chartform = BoxPlotChoiceForm(request.POST) chartform = BoxPlotChoiceForm(request.POST)
if chartform.is_valid(): if chartform.is_valid():
plotfield = chartform.cleaned_data['yparam'] plotfield = chartform.cleaned_data['yparam']
includereststrokes = chartform.cleaned_data['includereststrokes']
spmmin = chartform.cleaned_data['spmmin']
spmmax = chartform.cleaned_data['spmmax']
workmin = chartform.cleaned_data['workmin']
workmax = chartform.cleaned_data['workmax']
request.session['includereststrokes'] = includereststrokes
workstrokesonly = not includereststrokes
ids = request.session['ids'] ids = request.session['ids']
request.session['ids'] = ids request.session['ids'] = ids
workouts = [Workout.objects.get(id=id) for id in ids] workouts = [Workout.objects.get(id=id) for id in ids]
@@ -3106,12 +3135,31 @@ def boxplot_view(request,userid=0,
} }
fieldlist,fielddict = dataprep.getstatsfields() fieldlist,fielddict = dataprep.getstatsfields()
fieldlist = [plotfield,'workoutid'] fieldlist = [plotfield,'workoutid','spm','driveenergy',
'workoutstate']
# prepare data frame # prepare data frame
datadf = dataprep.read_cols_df_sql(ids,fieldlist) datadf = dataprep.read_cols_df_sql(ids,fieldlist)
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) # dummy values for drive energy
mask = datadf['driveenergy'] == 0
datadf.loc[mask,'driveenergy'] = 450
datadf = dataprep.clean_df_stats(datadf,
workstrokesonly=workstrokesonly)
datadf = dataprep.filter_df(datadf,'spm',spmmin,
largerthan=True)
datadf = dataprep.filter_df(datadf,'spm',spmmax,
largerthan=False)
datadf = dataprep.filter_df(datadf,'driveenergy',workmin,
largerthan=True)
datadf = dataprep.filter_df(datadf,'driveneergy',workmax,
largerthan=False)
datadf.dropna(axis=0,how='any',inplace=True)
datadf['workoutid'].replace(datemapping,inplace=True) datadf['workoutid'].replace(datemapping,inplace=True)
datadf.rename(columns={"workoutid":"date"},inplace=True) datadf.rename(columns={"workoutid":"date"},inplace=True)
datadf = datadf.sort_values(['date']) datadf = datadf.sort_values(['date'])
@@ -3136,7 +3184,7 @@ def boxplot_view(request,userid=0,
else: else:
return HttpResponse("invalid form") return HttpResponse("invalid form")
else: else:
url = reverse(workouts_view) url = reverse(user_boxplot_select)
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
# List Workouts # List Workouts
@@ -5083,7 +5131,10 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
row.distance = distance row.distance = distance
row.boattype = boattype row.boattype = boattype
row.privacy = privacy row.privacy = privacy
row.save() try:
row.save()
except IntegrityError:
pass
# change data in csv file # change data in csv file
r = rdata(row.csvfilename) r = rdata(row.csvfilename)
@@ -5106,8 +5157,8 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
response = HttpResponseRedirect(url) response = HttpResponseRedirect(url)
else: # form not POSTed #else: # form not POSTed
form = WorkoutForm(instance=row) form = WorkoutForm(instance=row)
try: try: