From 37fa023d707928bdd6d01af02e18f59219ce5577 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 22 Oct 2018 18:11:48 +0200 Subject: [PATCH 1/3] made table bigger in data view --- static/css/rowsandall2.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/css/rowsandall2.css b/static/css/rowsandall2.css index b6a678db..329faf27 100644 --- a/static/css/rowsandall2.css +++ b/static/css/rowsandall2.css @@ -992,7 +992,7 @@ a.wh:hover { .pandastable tbody { display: block; - height: 300px; + height: 1200px; overflow: auto; } From f359082be4257d56afb346fb974a1f95faca5ca2 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 22 Oct 2018 19:30:31 +0200 Subject: [PATCH 2/3] improved date form on oterankings --- rowers/forms.py | 29 ++++++++- rowers/templates/oterankings.html | 16 ++--- rowers/views.py | 98 ++++++++++--------------------- 3 files changed, 63 insertions(+), 80 deletions(-) diff --git a/rowers/forms.py b/rowers/forms.py index 66051470..3a086e4c 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -286,14 +286,41 @@ class WorkoutSplitForm(forms.Form): # This form is used on the Analysis page to add a custom distance/time # trial and predict the pace +from rowers.utils import rankingdistances,rankingdurations +from time import strftime class PredictedPieceForm(forms.Form): unitchoices = ( ('t','minutes'), ('d','meters'), ) + + rankingdistancechoices = [] + rankingdurationchoices = [] + for d in rankingdistances: + thetuple = (d,str(d)+' m') + rankingdistancechoices.append(thetuple) + + for d in rankingdurations: + timestr = d.strftime("%H:%M:%S") + thetuple = (timestr,timestr) + rankingdurationchoices.append(thetuple) + + trankingdistances = forms.MultipleChoiceField( + required=True, + choices=rankingdistancechoices,initial=rankingdistances, + label='Ranking Distances' + ) + + trankingdurations = forms.MultipleChoiceField( + required=True, + choices=rankingdurationchoices, + initial=[a for a,b in rankingdurationchoices], + label='Ranking Durations' + ) + + value = forms.FloatField(initial=10,label='Free ranking piece') pieceunit = forms.ChoiceField(required=True,choices=unitchoices, initial='t',label='Unit') - value = forms.FloatField(initial=10,label='Value') class Meta: fields = ['value','pieceunit'] diff --git a/rowers/templates/oterankings.html b/rowers/templates/oterankings.html index 04dbec69..2a0bc4fb 100644 --- a/rowers/templates/oterankings.html +++ b/rowers/templates/oterankings.html @@ -42,7 +42,6 @@

At the bottom of the page, you will find predictions derived from the model.

  • -

    Use this form to select a different date range:

    Select start and end date for a date range:

    @@ -50,6 +49,10 @@ {{ dateform.as_table }}
    +

    Pieces used for predictions

    + + {{ form.as_table }} +
    {% csrf_token %}
    @@ -144,17 +147,6 @@
  • -
  • -
    - {{ form.value }} {{ form.pieceunit }} - - {% csrf_token %} - minutes - -
    -
  • diff --git a/rowers/views.py b/rowers/views.py index 39a35c80..0762b6cf 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -4544,13 +4544,9 @@ def otwcp_toadmin_view(request,theuser=0, def oterankings_view(request,theuser=0, startdate=timezone.now()-datetime.timedelta(days=365), enddate=timezone.now(), - deltadays=-1, startdatestring="", enddatestring=""): - if deltadays>0: - startdate = enddate-datetime.timedelta(days=int(deltadays)) - if startdatestring != "": try: startdate = iso8601.parse_date(startdatestring) @@ -4563,13 +4559,6 @@ def oterankings_view(request,theuser=0, except ParseError: pass -# if 'startdate' in request.session: -# startdate = iso8601.parse_date(request.session['startdate']) - - -# if 'enddate' in request.session: -# enddate = iso8601.parse_date(request.session['enddate']) - if enddate < startdate: s = enddate enddate = startdate @@ -4596,9 +4585,8 @@ def oterankings_view(request,theuser=0, # get all OTW rows in date range # process form - if request.method == 'POST' and "daterange" in request.POST: + if request.method == 'POST': dateform = DateRangeForm(request.POST) - deltaform = DeltaDaysForm(request.POST) if dateform.is_valid(): startdate = dateform.cleaned_data['startdate'] enddate = dateform.cleaned_data['enddate'] @@ -4606,34 +4594,38 @@ def oterankings_view(request,theuser=0, s = enddate enddate = startdate startdate = s - elif request.method == 'POST' and "datedelta" in request.POST: - deltaform = DeltaDaysForm(request.POST) - if deltaform.is_valid(): - deltadays = deltaform.cleaned_data['deltadays'] - if deltadays: - enddate = timezone.now() - startdate = enddate-datetime.timedelta(days=deltadays) - if startdate > enddate: - s = enddate - enddate = startdate - startdate = s - dateform = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - else: - dateform = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - deltaform = DeltaDaysForm() - + form = PredictedPieceForm(request.POST) + clean = form.is_valid() + value = form.cleaned_data['value'] + trankingdistances = form.cleaned_data['trankingdistances'] + trankingdistances = [int(d) for d in trankingdistances] + trankingdurations = form.cleaned_data['trankingdurations'] + trankingdurations = [ + datetime.datetime.strptime(d,"%H:%M:%S").time() for d in trankingdurations + ] + hourvalue,tvalue = divmod(value,60) + hourvalue = int(hourvalue) + minutevalue = int(tvalue) + tvalue = int(60*(tvalue-minutevalue)) + if hourvalue >= 24: + hourvalue = 23 + pieceunit = form.cleaned_data['pieceunit'] + if pieceunit == 'd': + trankingdistances.append(value) + else: + trankingdurations.append(datetime.time( + minute=minutevalue, + hour=hourvalue, + second=tvalue + )) else: + form = PredictedPieceForm() dateform = DateRangeForm(initial={ 'startdate': startdate, 'enddate': enddate, }) - deltaform = DeltaDaysForm() + trankingdistances = rankingdistances + trankingdurations = rankingdurations # get all 2k (if any) - this rower, in date range try: @@ -4653,7 +4645,6 @@ def oterankings_view(request,theuser=0, # test to fix bug startdate = datetime.datetime.combine(startdate,datetime.time()) enddate = datetime.datetime.combine(enddate,datetime.time(23,59,59)) - #enddate = enddate+datetime.timedelta(days=1) @@ -4754,34 +4745,14 @@ def oterankings_view(request,theuser=0, message = "" - if request.method == 'POST' and "piece" in request.POST: - form = PredictedPieceForm(request.POST) - clean = form.is_valid() - value = form.cleaned_data['value'] - hourvalue,tvalue = divmod(value,60) - hourvalue = int(hourvalue) - minutevalue = int(tvalue) - tvalue = int(60*(tvalue-minutevalue)) - if hourvalue >= 24: - hourvalue = 23 - pieceunit = form.cleaned_data['pieceunit'] - if pieceunit == 'd': - rankingdistances.append(value) - else: - rankingdurations.append(datetime.time( - minute=minutevalue, - hour=hourvalue, - second=tvalue - )) - else: - form = PredictedPieceForm() + cpredictions = [] - for rankingduration in rankingdurations: + for rankingduration in trankingdurations: t = 3600.*rankingduration.hour t += 60.*rankingduration.minute t += rankingduration.second @@ -4828,7 +4799,7 @@ def oterankings_view(request,theuser=0, paulslope = 5. - for rankingdistance in rankingdistances: + for rankingdistance in trankingdistances: delta = paulslope * np.log(rankingdistance/distance_10)/np.log(2) @@ -4880,12 +4851,6 @@ def oterankings_view(request,theuser=0, # del form.fields["pieceunit"] - startdatestring = startdate.strftime('%Y-%m-%d') - enddatestring = enddate.strftime('%Y-%m-%d') - request.session['startdate'] = startdatestring - request.session['enddate'] = enddatestring - - messages.error(request,message) return render(request, 'oterankings.html', @@ -4898,7 +4863,6 @@ def oterankings_view(request,theuser=0, 'avgpower':avgpower, 'form':form, 'dateform':dateform, - 'deltaform':deltaform, 'id': theuser, 'theuser':uu, 'startdate':startdate, From 47682f69e5eb85bcb67b2b99038c82461e31e976 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 22 Oct 2018 20:14:33 +0200 Subject: [PATCH 3/3] otwranking and oteranking improved forms --- rowers/forms.py | 36 +++++++- rowers/templates/oterankings.html | 8 +- rowers/templates/otwrankings.html | 15 +--- rowers/views.py | 133 +++++++++++++----------------- 4 files changed, 99 insertions(+), 93 deletions(-) diff --git a/rowers/forms.py b/rowers/forms.py index 3a086e4c..834494fb 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -288,6 +288,20 @@ class WorkoutSplitForm(forms.Form): # trial and predict the pace from rowers.utils import rankingdistances,rankingdurations from time import strftime +class OteWorkoutTypeForm(forms.Form): + choices = ( + ('rower','Indoor Rower'), + ('dynamic','Dynamic Indoor Rower'), + ('slides','Indoor Rower on Slides'), + ) + + workouttypes = forms.MultipleChoiceField( + required=True, + choices=choices, + label='Workout Types', + initial = [a for a,b in choices], + ) + class PredictedPieceForm(forms.Form): unitchoices = ( ('t','minutes'), @@ -318,13 +332,33 @@ class PredictedPieceForm(forms.Form): label='Ranking Durations' ) - value = forms.FloatField(initial=10,label='Free ranking piece') + value = forms.FloatField(initial=10,label='Free ranking piece (minutes)') pieceunit = forms.ChoiceField(required=True,choices=unitchoices, initial='t',label='Unit') class Meta: fields = ['value','pieceunit'] +class PredictedPieceFormNoDistance(forms.Form): + + rankingdurationchoices = [] + + for d in rankingdurations: + timestr = d.strftime("%H:%M:%S") + thetuple = (timestr,timestr) + rankingdurationchoices.append(thetuple) + + + trankingdurations = forms.MultipleChoiceField( + required=True, + choices=rankingdurationchoices, + initial=[a for a,b in rankingdurationchoices], + label='Ranking Durations' + ) + + value = forms.FloatField(initial=10,label='Free ranking piece') + + # On the Geeky side, to update stream information for river dwellers class UpdateStreamForm(forms.Form): unitchoices = ( diff --git a/rowers/templates/oterankings.html b/rowers/templates/oterankings.html index 2a0bc4fb..68f3e313 100644 --- a/rowers/templates/oterankings.html +++ b/rowers/templates/oterankings.html @@ -53,6 +53,10 @@ {{ form.as_table }}
    +

    Workout Type

    + + {{ workouttypeform.as_p }} +
    {% csrf_token %} @@ -109,10 +113,6 @@
  • Pace predictions for Ranking Pieces

    -

    Add non-ranking piece using the form. The piece will be added in the prediction tables below.

    - - - diff --git a/rowers/templates/otwrankings.html b/rowers/templates/otwrankings.html index dd56f3c4..5ca5321e 100644 --- a/rowers/templates/otwrankings.html +++ b/rowers/templates/otwrankings.html @@ -50,6 +50,10 @@
    {{ dateform.as_table }}
    +

    Pieces used for predictions

    + + {{ form.as_table }} +
    {% csrf_token %} @@ -138,17 +142,6 @@
  • -
  • -
    - {{ form.value }} {{ form.pieceunit }} - - {% csrf_token %} - minutes - -
    -
  • diff --git a/rowers/views.py b/rowers/views.py index 0762b6cf..00fd1659 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -44,7 +44,7 @@ from rowers.forms import ( PlannedSessionTeamForm,PlannedSessionTeamMemberForm, VirtualRaceSelectForm,WorkoutRaceSelectForm,CourseSelectForm, RaceResultFilterForm,PowerIntervalUpdateForm,FlexAxesForm, - FlexOptionsForm,DataFrameColumnsForm, + FlexOptionsForm,DataFrameColumnsForm,OteWorkoutTypeForm, ) from django.core.urlresolvers import reverse, reverse_lazy @@ -58,7 +58,7 @@ from django.core.mail import send_mail, BadHeaderError from rowers.forms import ( SummaryStringForm,IntervalUpdateForm,StrokeDataForm, StatsOptionsForm,PredictedPieceForm,DateRangeForm,DeltaDaysForm, - FitnessMetricForm, + FitnessMetricForm,PredictedPieceFormNoDistance, EmailForm, RegistrationForm, RegistrationFormTermsOfService, RegistrationFormUniqueEmail,RegistrationFormSex, CNsummaryForm,UpdateWindForm, @@ -4114,13 +4114,9 @@ def workout_update_cp_view(request,id=0): def otwrankings_view(request,theuser=0, startdate=timezone.now()-datetime.timedelta(days=365), enddate=timezone.now(), - deltadays=-1, startdatestring="", enddatestring=""): - if deltadays>0: - startdate = enddate-datetime.timedelta(days=int(deltadays)) - if startdatestring != "": try: startdate = iso8601.parse_date(startdatestring) @@ -4133,13 +4129,6 @@ def otwrankings_view(request,theuser=0, except ParseError: pass -# if 'startdate' in request.session: -# startdate = iso8601.parse_date(request.session['startdate']) - - -# if 'enddate' in request.session: -# enddate = iso8601.parse_date(request.session['enddate']) - if enddate < startdate: s = enddate enddate = startdate @@ -4165,9 +4154,8 @@ def otwrankings_view(request,theuser=0, # get all OTW rows in date range # process form - if request.method == 'POST' and "daterange" in request.POST: + if request.method == 'POST': dateform = DateRangeForm(request.POST) - deltaform = DeltaDaysForm(request.POST) if dateform.is_valid(): startdate = dateform.cleaned_data['startdate'] enddate = dateform.cleaned_data['enddate'] @@ -4175,34 +4163,36 @@ def otwrankings_view(request,theuser=0, s = enddate enddate = startdate startdate = s - elif request.method == 'POST' and "datedelta" in request.POST: - deltaform = DeltaDaysForm(request.POST) - if deltaform.is_valid(): - deltadays = deltaform.cleaned_data['deltadays'] - if deltadays: - enddate = timezone.now() - startdate = enddate-datetime.timedelta(days=deltadays) - if startdate > enddate: - s = enddate - enddate = startdate - startdate = s - dateform = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - else: - dateform = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - deltaform = DeltaDaysForm() + form = PredictedPieceFormNoDistance(request.POST) + if form.is_valid(): + value = form.cleaned_data['value'] + else: + value = None + trankingdurations = form.cleaned_data['trankingdurations'] + trankingdurations = [ + datetime.datetime.strptime(d,"%H:%M:%S").time() for d in trankingdurations + ] + if value: + hourvalue,tvalue = divmod(value,60) + hourvalue = int(hourvalue) + minutevalue = int(tvalue) + tvalue = int(60*(tvalue-minutevalue)) + if hourvalue >= 24: + hourvalue = 23 + trankingdurations.append(datetime.time( + minute=minutevalue, + hour=hourvalue, + second=tvalue + )) else: + form = PredictedPieceFormNoDistance() dateform = DateRangeForm(initial={ 'startdate': startdate, 'enddate': enddate, }) - deltaform = DeltaDaysForm() + workouttypes = ['rower','slides','dynamic'] + trankingdurations = rankingdurations # get all 2k (if any) - this rower, in date range try: @@ -4320,26 +4310,11 @@ def otwrankings_view(request,theuser=0, message = "" - if request.method == 'POST' and "piece" in request.POST: - form = PredictedPieceForm(request.POST) - clean = form.is_valid() - value = form.cleaned_data['value'] - hourvalue,value = divmod(value,60) - hourvalue = int(hourvalue) - minutevalue = int(value) - value = int(60*(value-minutevalue)) - if hourvalue >= 24: - hourvalue = 23 - rankingdurations.append(datetime.time(minute=minutevalue, - hour=hourvalue, - second=value)) - else: - form = PredictedPieceForm() cpredictions = [] - for rankingduration in rankingdurations: + for rankingduration in trankingdurations: t = 3600.*rankingduration.hour t += 60.*rankingduration.minute t += rankingduration.second @@ -4368,7 +4343,6 @@ def otwrankings_view(request,theuser=0, cpredictions.append(a) - del form.fields["pieceunit"] startdatestring = startdate.strftime('%Y-%m-%d') enddatestring = enddate.strftime('%Y-%m-%d') @@ -4386,7 +4360,6 @@ def otwrankings_view(request,theuser=0, 'avgpower':avgpower, 'form':form, 'dateform':dateform, - 'deltaform':deltaform, 'id': theuser, 'theuser':uu, 'startdate':startdate, @@ -4594,36 +4567,45 @@ def oterankings_view(request,theuser=0, s = enddate enddate = startdate startdate = s + workouttypeform = OteWorkoutTypeForm(request.POST) + if workouttypeform.is_valid(): + workouttypes = workouttypeform.cleaned_data['workouttypes'] form = PredictedPieceForm(request.POST) - clean = form.is_valid() - value = form.cleaned_data['value'] + if form.is_valid(): + value = form.cleaned_data['value'] + pieceunit = form.cleaned_data['pieceunit'] + else: + value = None + trankingdistances = form.cleaned_data['trankingdistances'] trankingdistances = [int(d) for d in trankingdistances] trankingdurations = form.cleaned_data['trankingdurations'] trankingdurations = [ datetime.datetime.strptime(d,"%H:%M:%S").time() for d in trankingdurations ] - hourvalue,tvalue = divmod(value,60) - hourvalue = int(hourvalue) - minutevalue = int(tvalue) - tvalue = int(60*(tvalue-minutevalue)) - if hourvalue >= 24: - hourvalue = 23 - pieceunit = form.cleaned_data['pieceunit'] - if pieceunit == 'd': - trankingdistances.append(value) - else: - trankingdurations.append(datetime.time( - minute=minutevalue, - hour=hourvalue, - second=tvalue - )) + if value: + hourvalue,tvalue = divmod(value,60) + hourvalue = int(hourvalue) + minutevalue = int(tvalue) + tvalue = int(60*(tvalue-minutevalue)) + if hourvalue >= 24: + hourvalue = 23 + if pieceunit == 'd': + trankingdistances.append(value) + else: + trankingdurations.append(datetime.time( + minute=minutevalue, + hour=hourvalue, + second=tvalue + )) else: form = PredictedPieceForm() dateform = DateRangeForm(initial={ 'startdate': startdate, 'enddate': enddate, }) + workouttypeform = OteWorkoutTypeForm() + workouttypes = ['rower','slides','dynamic'] trankingdistances = rankingdistances trankingdurations = rankingdurations @@ -4654,11 +4636,7 @@ def oterankings_view(request,theuser=0, theworkouts = Workout.objects.filter( user=r,rankingpiece=True, - workouttype__in=[ - 'rower', - 'dynamic', - 'slides' - ], + workouttype__in=workouttypes, startdatetime__gte=startdate, startdatetime__lte=enddate ).order_by("-startdatetime") @@ -4863,6 +4841,7 @@ def oterankings_view(request,theuser=0, 'avgpower':avgpower, 'form':form, 'dateform':dateform, + 'workouttypeform':workouttypeform, 'id': theuser, 'theuser':uu, 'startdate':startdate,