From 545d8e4906f229d50d00a3855aeba14223651941 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 5 Jan 2018 11:44:12 +0100 Subject: [PATCH 1/4] prep for speeding up rankings view 2.0 --- rowers/views.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/rowers/views.py b/rowers/views.py index dca8b0a2..0ba882d2 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -3540,9 +3540,20 @@ def rankings_view2(request,theuser=0, r = getrower(request.user) wcdurations = [] wcpower = [] - + + if 'options' in request.session: + options = request.session['options'] + try: + wcdurations = options['wcdurations'] + wcpower = options['wcpower'] + except KeyError: + pass + if r.birthdate: age = calculate_age(r.birthdate) + +# job = myqueue + durations = [1,4,30,60] distances = [100,500,1000,2000,5000,6000,10000,21097,42195] for distance in distances: @@ -3576,6 +3587,11 @@ def rankings_view2(request,theuser=0, else: worldclasspower = None age = 0 + + options['wcpower'] = wcpower + options['wcdurations'] = wcdurations + + request.session['options'] = options result = request.user.is_authenticated() and ispromember(request.user) if result: From df7f300d87d9a735aef95fb8ef45cd6b61335490 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 5 Jan 2018 16:16:11 +0100 Subject: [PATCH 2/4] quickened Ranking 2.0 --- rowers/metrics.py | 15 +++- rowers/tasks.py | 3 + rowers/templates/.#multiflex.html | 1 + rowers/templates/rankings.html | 19 +++++ rowers/urls.py | 2 + rowers/views.py | 129 +++++++++++++++++++++--------- 6 files changed, 129 insertions(+), 40 deletions(-) create mode 100644 rowers/templates/.#multiflex.html diff --git a/rowers/metrics.py b/rowers/metrics.py index 72d2d1bb..b2f3eaa6 100644 --- a/rowers/metrics.py +++ b/rowers/metrics.py @@ -354,14 +354,21 @@ def getagegrouprecord(age,sex='male',weightcategory='hwt', p0 = [700,120,700,10,100,100] - p1, success = optimize.leastsq(errfunc,p0[:], + try: + p1, success = optimize.leastsq(errfunc,p0[:], args = (ages,powers)) + except: + p1 = p0 + success = 0 - power = fitfunc(p1, float(age)) + if success: + power = fitfunc(p1, float(age)) - #power = np.polyval(poly_coefficients,age) + #power = np.polyval(poly_coefficients,age) - power = 0.5*(np.abs(power)+power) + power = 0.5*(np.abs(power)+power) + else: + power = 0 else: power = 0 diff --git a/rowers/tasks.py b/rowers/tasks.py index f17fb216..a89377de 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -66,7 +66,10 @@ def long_test_task2(self,aantal,**kwargs): kwargs['jobid'] = job_id return longtask.longtask2(aantal,**kwargs) + + + # create workout @app.task def handle_new_workout_from_file(r, f2, diff --git a/rowers/templates/.#multiflex.html b/rowers/templates/.#multiflex.html new file mode 100644 index 00000000..9fe5f5d9 --- /dev/null +++ b/rowers/templates/.#multiflex.html @@ -0,0 +1 @@ +E408191@CZ27LT9RCGN72.81156:1514927368 \ No newline at end of file diff --git a/rowers/templates/rankings.html b/rowers/templates/rankings.html index ee6fc209..6c0b0b6a 100644 --- a/rowers/templates/rankings.html +++ b/rowers/templates/rankings.html @@ -5,6 +5,25 @@ {% block title %}Workouts{% endblock %} {% block scripts %} {% include "monitorjobs.html" %} + + + {% endblock %} {% block content %} diff --git a/rowers/urls.py b/rowers/urls.py index 7c5b3679..7d345028 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -123,6 +123,8 @@ urlpatterns = [ url(r'^imports/$', TemplateView.as_view(template_name='imports.html'), name='imports'), url(r'^agegroupcp/(?P\d+)$',views.agegroupcpview), url(r'^agegroupcp/(?P\d+)/(?P\d+)$',views.agegroupcpview), + url(r'^ajax_agegroup/(?P\d+)/(?P\w+.*)/(?P\w+.*)/(?P\d+)$', + views.ajax_agegrouprecords), url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)m$', views.agegrouprecordview), url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)min$', diff --git a/rowers/views.py b/rowers/views.py index 0ba882d2..759b49a9 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -3509,6 +3509,66 @@ def rankings_view(request,theuser=0, 'teams':get_my_teams(request.user), }) +@login_required() +def ajax_agegrouprecords(request, + age=25, + sex='female', + weightcategory='hwt', + userid=0): + + wcdurations = [] + wcpower = [] + durations = [1,4,30,60] + distances = [100,500,1000,2000,5000,6000,10000,21097,42195] + for distance in distances: + worldclasspower = metrics.getagegrouprecord( + age, + sex=sex, + distance=distance, + weightcategory=weightcategory + ) + velo = (worldclasspower/2.8)**(1./3.) + try: + duration = distance/velo + wcdurations.append(duration) + wcpower.append(worldclasspower) + except ZeroDivisionError: + pass + for duration in durations: + worldclasspower = metrics.getagegrouprecord( + age, + sex=sex, + duration=duration, + weightcategory=weightcategory + ) + try: + velo = (worldclasspower/2.8)**(1./3.) + distance = int(60*duration*velo) + wcdurations.append(60.*duration) + wcpower.append(worldclasspower) + except ValueError: + pass + + options = {} + options['wcpower'] = wcpower + options['wcdurations'] = wcdurations + + thenowtime = timezone.now().isoformat() + options['lastupdated'] = thenowtime + options['userid'] = userid + + request.session['options'] = options + + + return JSONResponse( + { + 'wcdurations': wcdurations, + 'wcpower': wcpower, + 'lastupdated': thenowtime, + } + ) + + # Show ranking distances including predicted paces @login_required() def rankings_view2(request,theuser=0, @@ -3534,64 +3594,60 @@ def rankings_view2(request,theuser=0, if theuser == 0: theuser = request.user.id + else: + lastupdated = "01-01-1900" + promember=0 if not request.user.is_anonymous(): - r = getrower(request.user) + r = getrower(theuser) wcdurations = [] wcpower = [] - + + lastupdated = "01-01-1900" + userid = 0 if 'options' in request.session: options = request.session['options'] try: wcdurations = options['wcdurations'] wcpower = options['wcpower'] + lastupdated = options['lastupdated'] except KeyError: pass + try: + userid = options['userid'] + except KeyError: + userid = 0 + else: + options = {} - if r.birthdate: - age = calculate_age(r.birthdate) - -# job = myqueue - durations = [1,4,30,60] - distances = [100,500,1000,2000,5000,6000,10000,21097,42195] - for distance in distances: - worldclasspower = metrics.getagegrouprecord( - age, - sex=r.sex, - distance=distance, - weightcategory=r.weightcategory - ) - velo = (worldclasspower/2.8)**(1./3.) - try: - duration = distance/velo - wcdurations.append(duration) - wcpower.append(worldclasspower) - except ZeroDivisionError: - pass - for duration in durations: - worldclasspower = metrics.getagegrouprecord( - age, - sex=r.sex, - duration=duration, - weightcategory=r.weightcategory - ) - try: - velo = (worldclasspower/2.8)**(1./3.) - distance = int(60*duration*velo) - wcdurations.append(60.*duration) - wcpower.append(worldclasspower) - except ValueError: - pass + + lastupdatedtime = arrow.get(lastupdated).timestamp + current_time = arrow.utcnow().timestamp + + deltatime_seconds = current_time - lastupdatedtime + recalc = False + if str(userid) != str(theuser) or deltatime_seconds > 3600: + recalc = True + else: + recalc = False + + options['userid'] = theuser + + if r.birthdate: + age = calculate_age(r.birthdate) else: worldclasspower = None age = 0 options['wcpower'] = wcpower options['wcdurations'] = wcdurations + if theuser: + options['userid'] = theuser request.session['options'] = options + result = request.user.is_authenticated() and ispromember(request.user) if result: @@ -3868,6 +3924,7 @@ def rankings_view2(request,theuser=0, 'theuser':uu, 'age':age, 'sex':r.sex, + 'recalc':recalc, 'weightcategory':r.weightcategory, 'startdate':startdate, 'enddate':enddate, From 9daf87605455ca9c8893c455d89710c330750a64 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 5 Jan 2018 16:17:35 +0100 Subject: [PATCH 3/4] cleaning up junk --- rowers/templates/.#multiflex.html | 1 - 1 file changed, 1 deletion(-) delete mode 100644 rowers/templates/.#multiflex.html diff --git a/rowers/templates/.#multiflex.html b/rowers/templates/.#multiflex.html deleted file mode 100644 index 9fe5f5d9..00000000 --- a/rowers/templates/.#multiflex.html +++ /dev/null @@ -1 +0,0 @@ -E408191@CZ27LT9RCGN72.81156:1514927368 \ No newline at end of file From cd94649e0bba2048ca82834012d5befe9b508362 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 6 Jan 2018 09:59:18 +0100 Subject: [PATCH 4/4] bug fix order of activity chart --- rowers/interactiveplots.py | 16 ++++++++++-- rowers/views.py | 50 ++++++++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 57405046..49d8cb7f 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -13,6 +13,7 @@ import itertools from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation from bokeh.charts import Histogram,HeatMap,Area,BoxPlot,Bar +from bokeh.charts.attributes import CatAttr from bokeh.resources import CDN,INLINE from bokeh.embed import components from bokeh.layouts import layout,widgetbox @@ -227,6 +228,7 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'): return "","" dates = [] + dates_sorting = [] types = [] rowers = [] durations = [] @@ -234,8 +236,10 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'): for w in workouts: if w.privacy == 'visible': dd = w.date.strftime('%m/%d') + dd2 = w.date.strftime('%Y/%m/%d') du = w.duration.hour*60+w.duration.minute dates.append(dd) + dates_sorting.append(dd2) durations.append(du) types.append(w.workouttype) try: @@ -253,9 +257,10 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'): except ValueError: pass - + # add dates with no activity while d<=enddate: dates.append(d.strftime('%m/%d')) + dates_sorting.append(d.strftime('%Y/%m/%d')) durations.append(0) types.append('rower') rowers.append('Sander') @@ -263,12 +268,19 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'): df = pd.DataFrame({ 'date':dates, + 'date_sorting':dates_sorting, 'duration':durations, 'type':types, 'rower':rowers, }) + + df.sort_values('date_sorting',inplace=True) - p = Bar(df,'date',values='duration',title='Activity', + p = Bar(df,values='duration', + label = CatAttr(columns=['date'], sort=False), + xlabel='Date', + ylabel='Time', + title='Activity', stack=stack, plot_width=350, plot_height=250, diff --git a/rowers/views.py b/rowers/views.py index 759b49a9..5364fbdc 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -2957,9 +2957,15 @@ def histo(request,theuser=0, if 'options' in request.session: options = request.session['options'] - workouttypes = options['workouttypes'] - includereststrokes = options['includereststrokes'] - waterboattype = options['waterboattype'] + try: + workouttypes = options['workouttypes'] + includereststrokes = options['includereststrokes'] + waterboattype = options['waterboattype'] + except KeyError: + workouttypes = ['water','rower','dynamic','slides'] + waterboattype = ['1x','2x','2-','4x','4-','8+'] + includereststrokes = False + workstrokesonly = not includereststrokes @@ -5760,15 +5766,25 @@ def boxplot_view_data(request,userid=0, if 'options' in request.session: options = request.session['options'] - - includereststrokes = options['includereststrokes'] - spmmin = options['spmmin'] - spmmax = options['spmmax'] - workmin = options['workmin'] - workmax = options['workmax'] - ids = options['ids'] - userid = options['userid'] - plotfield = options['plotfield'] + + try: + includereststrokes = options['includereststrokes'] + spmmin = options['spmmin'] + spmmax = options['spmmax'] + workmin = options['workmin'] + workmax = options['workmax'] + ids = options['ids'] + userid = options['userid'] + plotfield = options['plotfield'] + except KeyError: + includereststrokes = False + spmmin = 15 + spmmax = 55 + workmin = 0 + workmax = 55 + ids = [] + userid = 0 + plotfield = 'spm' workstrokesonly = not includereststrokes @@ -5840,8 +5856,13 @@ def boxplot_view(request,userid=0, if 'options' in request.session: options = request.session['options'] + + try: + includereststrokes = options['includereststrokes'] + except KeyError: + includereststrokes = False + options['includereststrokes'] = False - includereststrokes = options['includereststrokes'] workstrokesonly = not includereststrokes if userid==0: @@ -5960,7 +5981,6 @@ def workouts_view(request,message='',successmessage='', except ValueError: activity_enddate = enddate - if teamid: try: theteam = Team.objects.get(id=teamid) @@ -6027,7 +6047,7 @@ def workouts_view(request,message='',successmessage='', stack='rower' else: stack='type' - + script,div = interactive_activitychart(g_workouts, activity_startdate, activity_enddate,