added age records to ote-bests
This commit is contained in:
@@ -1101,7 +1101,8 @@ def interactive_agegroup_plot(df):
|
|||||||
return script,div
|
return script,div
|
||||||
|
|
||||||
def interactive_cpchart(rower,thedistances,thesecs,theavpower,
|
def interactive_cpchart(rower,thedistances,thesecs,theavpower,
|
||||||
theworkouts,promember=0):
|
theworkouts,promember=0,
|
||||||
|
wcpower=[],wcdurations=[]):
|
||||||
|
|
||||||
message = 0
|
message = 0
|
||||||
# plot tools
|
# plot tools
|
||||||
@@ -1167,11 +1168,23 @@ def interactive_cpchart(rower,thedistances,thesecs,theavpower,
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# fitting the data to three parameter CP model
|
|
||||||
fitfunc = lambda pars,x: pars[0]/(1+(x/pars[2])) + pars[1]/(1+(x/pars[3]))
|
fitfunc = lambda pars,x: pars[0]/(1+(x/pars[2])) + pars[1]/(1+(x/pars[3]))
|
||||||
errfunc = lambda pars,x,y: fitfunc(pars,x)-y
|
errfunc = lambda pars,x,y: fitfunc(pars,x)-y
|
||||||
|
|
||||||
p0 = [500,350,10,8000]
|
p0 = [500,350,10,8000]
|
||||||
|
wcpower = pd.Series(wcpower)
|
||||||
|
wcdurations = pd.Series(wcdurations)
|
||||||
|
|
||||||
|
# fitting WC data to three parameter CP model
|
||||||
|
if len(wcdurations)>=4:
|
||||||
|
p1wc, success = optimize.leastsq(errfunc, p0[:],
|
||||||
|
args = (wcdurations,wcpower))
|
||||||
|
else:
|
||||||
|
p1wc = None
|
||||||
|
|
||||||
|
# fitting the data to three parameter CP model
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
p1 = p0
|
p1 = p0
|
||||||
if len(thesecs)>=4:
|
if len(thesecs)>=4:
|
||||||
@@ -1184,6 +1197,21 @@ def interactive_cpchart(rower,thedistances,thesecs,theavpower,
|
|||||||
fitt = pd.Series(10**(4*np.arange(100)/100.))
|
fitt = pd.Series(10**(4*np.arange(100)/100.))
|
||||||
|
|
||||||
fitpower = fitfunc(p1,fitt)
|
fitpower = fitfunc(p1,fitt)
|
||||||
|
if p1wc is not None:
|
||||||
|
fitpowerwc = 0.95*fitfunc(p1wc,fitt)
|
||||||
|
fitpowerexcellent = 0.7*fitfunc(p1wc,fitt)
|
||||||
|
fitpowergood = 0.6*fitfunc(p1wc,fitt)
|
||||||
|
fitpowerfair = 0.5*fitfunc(p1wc,fitt)
|
||||||
|
fitpoweraverage = 0.4*fitfunc(p1wc,fitt)
|
||||||
|
|
||||||
|
else:
|
||||||
|
fitpowerwc = 0*fitpower
|
||||||
|
fitpowerexcellent = 0*fitpower
|
||||||
|
fitpowergood = 0*fitpower
|
||||||
|
fitpowerfair = 0*fitpower
|
||||||
|
fitpoweraverage = 0*fitpower
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
message = ""
|
message = ""
|
||||||
if len(fitpower[fitpower<0]) > 0:
|
if len(fitpower[fitpower<0]) > 0:
|
||||||
@@ -1203,6 +1231,11 @@ def interactive_cpchart(rower,thedistances,thesecs,theavpower,
|
|||||||
),
|
),
|
||||||
spm = 0*fitpower,
|
spm = 0*fitpower,
|
||||||
power = fitpower,
|
power = fitpower,
|
||||||
|
fitpowerwc = fitpowerwc,
|
||||||
|
fitpowerexcellent = fitpowerexcellent,
|
||||||
|
fitpowergood = fitpowergood,
|
||||||
|
fitpowerfair = fitpowerfair,
|
||||||
|
fitpoweraverage = fitpoweraverage,
|
||||||
fpace = nicepaceformat(fitp2),
|
fpace = nicepaceformat(fitp2),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -1281,6 +1314,25 @@ def interactive_cpchart(rower,thedistances,thesecs,theavpower,
|
|||||||
plot.line('duration','power',source=sourcepaul,legend="Paul's Law")
|
plot.line('duration','power',source=sourcepaul,legend="Paul's Law")
|
||||||
plot.line('duration','power',source=sourcecomplex,legend="CP Model",
|
plot.line('duration','power',source=sourcecomplex,legend="CP Model",
|
||||||
color='green')
|
color='green')
|
||||||
|
plot.line('duration','fitpowerwc',source=sourcecomplex,
|
||||||
|
legend="World Class",
|
||||||
|
color='Maroon',line_dash='dotted')
|
||||||
|
|
||||||
|
plot.line('duration','fitpowerexcellent',source=sourcecomplex,
|
||||||
|
legend="Excellent",
|
||||||
|
color='Purple',line_dash='dotted')
|
||||||
|
|
||||||
|
plot.line('duration','fitpowergood',source=sourcecomplex,
|
||||||
|
legend="Good",
|
||||||
|
color='Olive',line_dash='dotted')
|
||||||
|
|
||||||
|
plot.line('duration','fitpowerfair',source=sourcecomplex,
|
||||||
|
legend="Fair",
|
||||||
|
color='Gray',line_dash='dotted')
|
||||||
|
|
||||||
|
plot.line('duration','fitpoweraverage',source=sourcecomplex,
|
||||||
|
legend="Average",
|
||||||
|
color='SkyBlue',line_dash='dotted')
|
||||||
|
|
||||||
|
|
||||||
script, div = components(plot)
|
script, div = components(plot)
|
||||||
|
|||||||
@@ -319,12 +319,26 @@ def calc_trimp(df,sex,hrmax,hrmin):
|
|||||||
|
|
||||||
return trimp
|
return trimp
|
||||||
|
|
||||||
def getagegroup2k(age,sex='male',weightcategory='hwt'):
|
def getagegrouprecord(age,sex='male',weightcategory='hwt',
|
||||||
df = pd.DataFrame(
|
distance=2000,duration=None):
|
||||||
list(
|
if not duration:
|
||||||
C2WorldClassAgePerformance.objects.filter(
|
df = pd.DataFrame(
|
||||||
sex=sex,
|
list(
|
||||||
weightcategory=weightcategory
|
C2WorldClassAgePerformance.objects.filter(
|
||||||
|
distance=distance,
|
||||||
|
sex=sex,
|
||||||
|
weightcategory=weightcategory
|
||||||
|
).values()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
duration=60*int(duration)
|
||||||
|
df = pd.DataFrame(
|
||||||
|
list(
|
||||||
|
C2WorldClassAgePerformance.objects.filter(
|
||||||
|
duration=duration,
|
||||||
|
sex=sex,
|
||||||
|
weightcategory=weightcategory
|
||||||
).values()
|
).values()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
1
rowers/templates/.#rankings.html
Normal file
1
rowers/templates/.#rankings.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
E408191@CZ27LT9RCGN72.12348:1512983261
|
||||||
@@ -160,6 +160,15 @@
|
|||||||
|
|
||||||
{{ the_div|safe }}
|
{{ the_div|safe }}
|
||||||
|
|
||||||
|
<p>The dashed lines are based on the Concept2 rankings for your age, gender
|
||||||
|
and weight category. World class means within 5% of World Record in terms
|
||||||
|
of power. Excellent, Good, and Fair indicate the power levels of the top
|
||||||
|
10%, 25% and 50% of the Concept2 rankings. Average is taken
|
||||||
|
as being in the top 75%, given that the Concept2 rankings probably
|
||||||
|
represent the more competitive sub-group of all people who erg.
|
||||||
|
Please note that this is a prediction for people of exactly your age,
|
||||||
|
and your actual place in the Concept2 Ranking may be different.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="predictions" class="grid_12 alpha">
|
<div id="predictions" class="grid_12 alpha">
|
||||||
@@ -259,9 +268,7 @@
|
|||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if worldclasspower %}
|
|
||||||
World class 2k for your age, weight is {{ worldclasspower }} Watt
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -165,6 +165,12 @@ urlpatterns = [
|
|||||||
url(r'^ote-bests/(?P<deltadays>\d+)$',views.rankings_view),
|
url(r'^ote-bests/(?P<deltadays>\d+)$',views.rankings_view),
|
||||||
url(r'^ote-bests/$',views.rankings_view),
|
url(r'^ote-bests/$',views.rankings_view),
|
||||||
url(r'^(?P<theuser>\d+)/ote-bests/$',views.rankings_view),
|
url(r'^(?P<theuser>\d+)/ote-bests/$',views.rankings_view),
|
||||||
|
url(r'^(?P<theuser>\d+)/ote-bests2/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view),
|
||||||
|
url(r'^(?P<theuser>\d+)/ote-bests2/(?P<deltadays>\d+)$',views.rankings_view2),
|
||||||
|
url(r'^ote-bests2/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view2),
|
||||||
|
url(r'^ote-bests2/(?P<deltadays>\d+)$',views.rankings_view2),
|
||||||
|
url(r'^ote-bests2/$',views.rankings_view2),
|
||||||
|
url(r'^(?P<theuser>\d+)/ote-bests2/$',views.rankings_view2),
|
||||||
url(r'^(?P<theuser>\d+)/otw-bests/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.otwrankings_view),
|
url(r'^(?P<theuser>\d+)/otw-bests/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.otwrankings_view),
|
||||||
url(r'^(?P<theuser>\d+)/otw-bests/(?P<deltadays>\d+)$',views.otwrankings_view),
|
url(r'^(?P<theuser>\d+)/otw-bests/(?P<deltadays>\d+)$',views.otwrankings_view),
|
||||||
url(r'^otw-bests/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.otwrankings_view),
|
url(r'^otw-bests/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.otwrankings_view),
|
||||||
|
|||||||
340
rowers/views.py
340
rowers/views.py
@@ -3223,7 +3223,7 @@ def rankings_view(request,theuser=0,
|
|||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
if r.birthdate:
|
if r.birthdate:
|
||||||
age = calculate_age(r.birthdate)
|
age = calculate_age(r.birthdate)
|
||||||
worldclasspower = int(metrics.getagegroup2k(
|
worldclasspower = int(metrics.getagegrouprecord(
|
||||||
age,
|
age,
|
||||||
sex=r.sex,
|
sex=r.sex,
|
||||||
weightcategory=r.weightcategory
|
weightcategory=r.weightcategory
|
||||||
@@ -3507,6 +3507,344 @@ def rankings_view(request,theuser=0,
|
|||||||
'teams':get_my_teams(request.user),
|
'teams':get_my_teams(request.user),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Show ranking distances including predicted paces
|
||||||
|
@login_required()
|
||||||
|
def rankings_view2(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 != "":
|
||||||
|
startdate = iso8601.parse_date(startdatestring)
|
||||||
|
|
||||||
|
if enddatestring != "":
|
||||||
|
enddate = iso8601.parse_date(enddatestring)
|
||||||
|
|
||||||
|
if enddate < startdate:
|
||||||
|
s = enddate
|
||||||
|
enddate = startdate
|
||||||
|
startdate = s
|
||||||
|
|
||||||
|
if theuser == 0:
|
||||||
|
theuser = request.user.id
|
||||||
|
|
||||||
|
promember=0
|
||||||
|
if not request.user.is_anonymous():
|
||||||
|
r = getrower(request.user)
|
||||||
|
wcdurations = []
|
||||||
|
wcpower = []
|
||||||
|
|
||||||
|
if r.birthdate:
|
||||||
|
age = calculate_age(r.birthdate)
|
||||||
|
durations = [1,4,30,60]
|
||||||
|
distances = [100,500,1000,2000,5000,6000,10000,21097,42195]
|
||||||
|
print r.weightcategory,r.sex,age,'aap'
|
||||||
|
for distance in distances:
|
||||||
|
worldclasspower = metrics.getagegrouprecord(
|
||||||
|
age,
|
||||||
|
sex=r.sex,
|
||||||
|
distance=distance,
|
||||||
|
weightcategory=r.weightcategory
|
||||||
|
)
|
||||||
|
velo = (worldclasspower/2.8)**(1./3.)
|
||||||
|
duration = distance/velo
|
||||||
|
wcdurations.append(duration)
|
||||||
|
wcpower.append(worldclasspower)
|
||||||
|
for duration in durations:
|
||||||
|
worldclasspower = metrics.getagegrouprecord(
|
||||||
|
age,
|
||||||
|
sex=r.sex,
|
||||||
|
duration=duration,
|
||||||
|
weightcategory=r.weightcategory
|
||||||
|
)
|
||||||
|
wcdurations.append(60.*duration)
|
||||||
|
velo = (worldclasspower/2.8)**(1./3.)
|
||||||
|
distance = int(60*duration*velo)
|
||||||
|
wcpower.append(worldclasspower)
|
||||||
|
else:
|
||||||
|
worldclasspower = None
|
||||||
|
|
||||||
|
result = request.user.is_authenticated() and ispromember(request.user)
|
||||||
|
if result:
|
||||||
|
promember=1
|
||||||
|
|
||||||
|
# get all indoor rows in date range
|
||||||
|
|
||||||
|
# process form
|
||||||
|
if request.method == 'POST' and "daterange" in request.POST:
|
||||||
|
dateform = DateRangeForm(request.POST)
|
||||||
|
deltaform = DeltaDaysForm(request.POST)
|
||||||
|
if dateform.is_valid():
|
||||||
|
startdate = dateform.cleaned_data['startdate']
|
||||||
|
enddate = dateform.cleaned_data['enddate']
|
||||||
|
if startdate > enddate:
|
||||||
|
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()
|
||||||
|
deltaform = DeltaDaysForm()
|
||||||
|
|
||||||
|
else:
|
||||||
|
dateform = DateRangeForm(initial={
|
||||||
|
'startdate': startdate,
|
||||||
|
'enddate': enddate,
|
||||||
|
})
|
||||||
|
deltaform = DeltaDaysForm()
|
||||||
|
|
||||||
|
# get all 2k (if any) - this rower, in date range
|
||||||
|
try:
|
||||||
|
r = getrower(theuser)
|
||||||
|
except Rower.DoesNotExist:
|
||||||
|
allergworkouts = []
|
||||||
|
r=0
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
uu = User.objects.get(id=theuser)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
uu = ''
|
||||||
|
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
rankingdistances = [100,500,1000,2000,5000,6000,10000,21097,42195,100000]
|
||||||
|
rankingdurations = []
|
||||||
|
rankingdurations.append(datetime.time(minute=1))
|
||||||
|
rankingdurations.append(datetime.time(minute=4))
|
||||||
|
rankingdurations.append(datetime.time(minute=30))
|
||||||
|
rankingdurations.append(datetime.time(hour=1,minute=15))
|
||||||
|
rankingdurations.append(datetime.time(hour=1))
|
||||||
|
|
||||||
|
thedistances = []
|
||||||
|
theworkouts = []
|
||||||
|
thesecs = []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rankingdistances.sort()
|
||||||
|
rankingdurations.sort()
|
||||||
|
|
||||||
|
for rankingdistance in rankingdistances:
|
||||||
|
|
||||||
|
workouts = Workout.objects.filter(user=r,distance=rankingdistance,
|
||||||
|
workouttype__in=['rower','dynamic','slides'],
|
||||||
|
startdatetime__gte=startdate,
|
||||||
|
startdatetime__lte=enddate).order_by('duration')
|
||||||
|
if workouts:
|
||||||
|
thedistances.append(rankingdistance)
|
||||||
|
theworkouts.append(workouts[0])
|
||||||
|
|
||||||
|
timesecs = 3600*workouts[0].duration.hour
|
||||||
|
timesecs += 60*workouts[0].duration.minute
|
||||||
|
timesecs += workouts[0].duration.second
|
||||||
|
timesecs += 1.e-6*workouts[0].duration.microsecond
|
||||||
|
|
||||||
|
thesecs.append(timesecs)
|
||||||
|
|
||||||
|
for rankingduration in rankingdurations:
|
||||||
|
|
||||||
|
workouts = Workout.objects.filter(user=r,duration=rankingduration,
|
||||||
|
workouttype='rower',
|
||||||
|
startdatetime__gte=startdate,
|
||||||
|
startdatetime__lte=enddate).order_by('-distance')
|
||||||
|
if workouts:
|
||||||
|
thedistances.append(workouts[0].distance)
|
||||||
|
theworkouts.append(workouts[0])
|
||||||
|
|
||||||
|
timesecs = 3600*workouts[0].duration.hour
|
||||||
|
timesecs += 60*workouts[0].duration.minute
|
||||||
|
timesecs += workouts[0].duration.second
|
||||||
|
timesecs += 1.e-5*workouts[0].duration.microsecond
|
||||||
|
|
||||||
|
thesecs.append(timesecs)
|
||||||
|
|
||||||
|
thedistances = np.array(thedistances)
|
||||||
|
thesecs = np.array(thesecs)
|
||||||
|
|
||||||
|
thevelos = thedistances/thesecs
|
||||||
|
theavpower = 2.8*(thevelos**3)
|
||||||
|
|
||||||
|
|
||||||
|
# create interactive plot
|
||||||
|
if len(thedistances) !=0 :
|
||||||
|
res = interactive_cpchart(
|
||||||
|
r,thedistances,thesecs,theavpower,
|
||||||
|
theworkouts,promember=promember,
|
||||||
|
wcdurations=wcdurations,wcpower=wcpower
|
||||||
|
)
|
||||||
|
script = res[0]
|
||||||
|
div = res[1]
|
||||||
|
paulslope = res[2]
|
||||||
|
paulintercept = res[3]
|
||||||
|
p1 = res[4]
|
||||||
|
message = res[5]
|
||||||
|
else:
|
||||||
|
script = ''
|
||||||
|
div = '<p>No ranking pieces found.</p>'
|
||||||
|
paulslope = 1
|
||||||
|
paulintercept = 1
|
||||||
|
p1 = [1,1,1,1]
|
||||||
|
message = ""
|
||||||
|
|
||||||
|
|
||||||
|
if request.method == 'POST' and "piece" in request.POST:
|
||||||
|
form = PredictedPieceForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
value = form.cleaned_data['value']
|
||||||
|
hourvalue,value = divmod(value,60)
|
||||||
|
if hourvalue >= 24:
|
||||||
|
hourvalue = 23
|
||||||
|
pieceunit = form.cleaned_data['pieceunit']
|
||||||
|
if pieceunit == 'd':
|
||||||
|
rankingdistances.append(value)
|
||||||
|
else:
|
||||||
|
rankingdurations.append(datetime.time(minute=int(value),hour=int(hourvalue)))
|
||||||
|
else:
|
||||||
|
form = PredictedPieceForm()
|
||||||
|
|
||||||
|
rankingdistances.sort()
|
||||||
|
rankingdurations.sort()
|
||||||
|
|
||||||
|
|
||||||
|
predictions = []
|
||||||
|
cpredictions = []
|
||||||
|
|
||||||
|
|
||||||
|
for rankingdistance in rankingdistances:
|
||||||
|
# Paul's model
|
||||||
|
p = paulslope*np.log10(rankingdistance)+paulintercept
|
||||||
|
velo = 500./p
|
||||||
|
t = rankingdistance/velo
|
||||||
|
pwr = 2.8*(velo**3)
|
||||||
|
a = {'distance':rankingdistance,
|
||||||
|
'duration':timedeltaconv(t),
|
||||||
|
'pace':timedeltaconv(p),
|
||||||
|
'power':int(pwr)}
|
||||||
|
predictions.append(a)
|
||||||
|
|
||||||
|
# CP model -
|
||||||
|
pwr2 = p1[0]/(1+t/p1[2])
|
||||||
|
pwr2 += p1[1]/(1+t/p1[3])
|
||||||
|
|
||||||
|
if pwr2 <= 0:
|
||||||
|
pwr2 = 50.
|
||||||
|
|
||||||
|
velo2 = (pwr2/2.8)**(1./3.)
|
||||||
|
|
||||||
|
if np.isnan(velo2) or velo2 <= 0:
|
||||||
|
velo2 = 1.0
|
||||||
|
|
||||||
|
t2 = rankingdistance/velo2
|
||||||
|
|
||||||
|
pwr3 = p1[0]/(1+t2/p1[2])
|
||||||
|
pwr3 += p1[1]/(1+t2/p1[3])
|
||||||
|
|
||||||
|
if pwr3 <= 0:
|
||||||
|
pwr3 = 50.
|
||||||
|
|
||||||
|
velo3 = (pwr3/2.8)**(1./3.)
|
||||||
|
if np.isnan(velo3) or velo3 <= 0:
|
||||||
|
velo3 = 1.0
|
||||||
|
|
||||||
|
t3 = rankingdistance/velo3
|
||||||
|
p3 = 500./velo3
|
||||||
|
|
||||||
|
a = {'distance':rankingdistance,
|
||||||
|
'duration':timedeltaconv(t3),
|
||||||
|
'pace':timedeltaconv(p3),
|
||||||
|
'power':int(pwr3)}
|
||||||
|
cpredictions.append(a)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for rankingduration in rankingdurations:
|
||||||
|
t = 3600.*rankingduration.hour
|
||||||
|
t += 60.*rankingduration.minute
|
||||||
|
t += rankingduration.second
|
||||||
|
t += rankingduration.microsecond/1.e6
|
||||||
|
|
||||||
|
# Paul's model
|
||||||
|
ratio = paulintercept/paulslope
|
||||||
|
|
||||||
|
u = ((2**(2+ratio))*(5.**(3+ratio))*t*np.log(10))/paulslope
|
||||||
|
|
||||||
|
d = 500*t*np.log(10.)
|
||||||
|
d = d/(paulslope*lambertw(u))
|
||||||
|
d = d.real
|
||||||
|
|
||||||
|
velo = d/t
|
||||||
|
p = 500./velo
|
||||||
|
pwr = 2.8*(velo**3)
|
||||||
|
a = {'distance':int(d),
|
||||||
|
'duration':timedeltaconv(t),
|
||||||
|
'pace':timedeltaconv(p),
|
||||||
|
'power':int(pwr)}
|
||||||
|
predictions.append(a)
|
||||||
|
|
||||||
|
# CP model
|
||||||
|
pwr = p1[0]/(1+t/p1[2])
|
||||||
|
pwr += p1[1]/(1+t/p1[3])
|
||||||
|
|
||||||
|
if pwr <= 0:
|
||||||
|
pwr = 50.
|
||||||
|
|
||||||
|
velo = (pwr/2.8)**(1./3.)
|
||||||
|
|
||||||
|
if np.isnan(velo) or velo <=0:
|
||||||
|
velo = 1.0
|
||||||
|
|
||||||
|
d = t*velo
|
||||||
|
p = 500./velo
|
||||||
|
a = {'distance':int(d),
|
||||||
|
'duration':timedeltaconv(t),
|
||||||
|
'pace':timedeltaconv(p),
|
||||||
|
'power':int(pwr)}
|
||||||
|
cpredictions.append(a)
|
||||||
|
|
||||||
|
|
||||||
|
messages.error(request,message)
|
||||||
|
return render(request, 'rankings.html',
|
||||||
|
{'rankingworkouts':theworkouts,
|
||||||
|
'interactiveplot':script,
|
||||||
|
'the_div':div,
|
||||||
|
'predictions':predictions,
|
||||||
|
'cpredictions':cpredictions,
|
||||||
|
'nrdata':len(thedistances),
|
||||||
|
'form':form,
|
||||||
|
'dateform':dateform,
|
||||||
|
'deltaform':deltaform,
|
||||||
|
'id': theuser,
|
||||||
|
'theuser':uu,
|
||||||
|
'startdate':startdate,
|
||||||
|
'enddate':enddate,
|
||||||
|
'teams':get_my_teams(request.user),
|
||||||
|
})
|
||||||
|
|
||||||
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
|
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
|
||||||
def workout_update_cp_view(request,id=0):
|
def workout_update_cp_view(request,id=0):
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user