From cd9fba9121b2d308186313e79bab6f171cc6495a Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 14 Aug 2023 21:41:35 +0200 Subject: [PATCH 1/4] instantplans --- rowers/models.py | 3 +++ rowers/templates/instantplans.html | 3 +++ rowers/tests/testdata/testdata.tcx.gz | Bin 4001 -> 3998 bytes rowers/views/paymentviews.py | 7 ++++++- rowers/views/planviews.py | 11 +++++++++-- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/rowers/models.py b/rowers/models.py index 4d66ab55..e4e0cfe9 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -1715,6 +1715,8 @@ class InstantPlan(models.Model): price = models.IntegerField(default=0, verbose_name="Price in EURO") url = models.CharField(max_length=250, blank=True, verbose_name="Link to page with more information") + private = models.BooleanField(default=False, + verbose_name="Hidden, personal") def __str__(self): # pragma: no cover return self.name @@ -1753,6 +1755,7 @@ class InstantPlanForm(ModelForm): 'hoursperweek', 'sessionsperweek', 'yaml', + 'private' ] diff --git a/rowers/templates/instantplans.html b/rowers/templates/instantplans.html index 17c076b8..b424f226 100644 --- a/rowers/templates/instantplans.html +++ b/rowers/templates/instantplans.html @@ -30,6 +30,9 @@

Created by: {{ plan.owner.first_name }} {{ plan.owner.last_name }}

Plan length: {{ plan.duration }} days

{{ plan.description }}

+ {% if plan.private %} +

Private

+ {% endif %} {% if plan.target %}

What the plan will achieve: {{ plan.target }}

{% endif %} diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 95c8d3aade9d9e4c3e804e66c841582354bea64d..a0bbfcb73e602558aa0d5d364887d8d7d7034fd3 100644 GIT binary patch literal 3998 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 Date: Tue, 15 Aug 2023 09:05:10 +0200 Subject: [PATCH 2/4] adding better rscore calc from power zone --- rowers/forms.py | 4 +++- rowers/models.py | 2 +- rowers/plannedsessions.py | 8 ++++++-- rowers/templates/instantplan.html | 3 +++ rowers/utils.py | 10 +++++++--- rowers/views/planviews.py | 20 ++++++++++++++++++-- rowers/views/statements.py | 2 +- 7 files changed, 39 insertions(+), 10 deletions(-) diff --git a/rowers/forms.py b/rowers/forms.py index 542f7cba..3cafb247 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -991,7 +991,9 @@ class SessionDateShiftForm(forms.Form): class DeltaDaysForm(forms.Form): deltadays = forms.IntegerField(initial=7, required=False, label='') - +class PlanByRscoreForm(forms.Form): + byrscore = forms.BooleanField(initial=False, required=False, label='plan by rScore') + class RegistrationForm(UserCreationForm): """ Form for registering a new user account. diff --git a/rowers/models.py b/rowers/models.py index e4e0cfe9..63da2915 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -2813,7 +2813,7 @@ class PlannedSession(models.Model): self.sessionvalue = self.approximate_duration elif self.sessionmode == 'distance': # pragma: no cover self.sessionvalue = self.approximate_distance - elif self.sessionmode == 'rscore': # pragma: no cover + elif self.sessionmode == 'rScore': # pragma: no cover self.sessionvalue = self.approximate_rscore super(PlannedSession, self).save(*args, **kwargs) diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 1b52f280..8b795e05 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -1063,7 +1063,7 @@ def get_workouts_session(r, ps): return ws -def create_sessions_from_json(plansteps, rower, startdate, manager): +def create_sessions_from_json(plansteps, rower, startdate, manager, planbyrscore=False): trainingdays = plansteps['trainingDays'] planstartdate = startdate for day in trainingdays: @@ -1076,6 +1076,10 @@ def create_sessions_from_json(plansteps, rower, startdate, manager): preferreddate = planstartdate+timedelta(days=day['order']) + sessionmode = 'time' + if planbyrscore: + sessionmode = 'rScore' + ps = PlannedSession( startdate=preferreddate - timedelta(days=preferreddate.weekday()), @@ -1086,7 +1090,7 @@ def create_sessions_from_json(plansteps, rower, startdate, manager): name=workout['workoutName'], steps=workout, manager=manager, - sessionmode='time', + sessionmode=sessionmode, comment=workout['description'] ) diff --git a/rowers/templates/instantplan.html b/rowers/templates/instantplan.html index 313d75d8..727bcbcf 100644 --- a/rowers/templates/instantplan.html +++ b/rowers/templates/instantplan.html @@ -58,6 +58,9 @@ {% endif %} {{ form.as_table }} + {% if byrscoreform %} + {{ byrscoreform.as_table }} + {% endif %}
{% csrf_token %} {% if plan.price|discounted:rower == 0 %} diff --git a/rowers/utils.py b/rowers/utils.py index 72e4b799..9ec563ad 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -690,7 +690,7 @@ def steps_write_fit(steps): return filename -def step_to_time_dist(step, avgspeed=3.2, ftp=200, ftspm=25, ftv=3.7): +def step_to_time_dist(step, avgspeed=3.2, ftp=200, ftspm=25, ftv=3.7, powerzones=None): seconds = 0 distance = 0 rscore = 0 @@ -732,7 +732,9 @@ def step_to_time_dist(step, avgspeed=3.2, ftp=200, ftspm=25, ftv=3.7): if value != 0: if value < 10 and value > 0: # pragma: no cover - targetpower = ftp*0.6 + targetpower = ftp*0.6 # dit is niet correct + if powerzones is not None and value < len(powerzones)-1 and value>1: + targetpower = (powerzones[int(value)-1]+powerzones[int(value)])/(2.) elif value > 10 and value < 1000: # pragma: no cover targetpower = value*ftp/100. elif value > 1000: @@ -890,15 +892,17 @@ def ps_dict_order(d, short=False, rower=None, html=True): steps = d['steps'] ftp = 200 + powerzones = None if rower is not None: ftp = rower.ftp + powerzones = [rower.pw_ut2, rower.pw_ut1, rower.pw_at, rower.pw_tr, rower.pw_an] # ftv = rower.ftv # ftspm = rower.ftspm for step in steps: sstring, type, stepID, repeatID, repeatValue = step_to_string( step, short=short) - seconds, meters, rscore = step_to_time_dist(step, ftp=ftp) + seconds, meters, rscore = step_to_time_dist(step, ftp=ftp, powerzones=powerzones) sdict[stepID] = { 'string': sstring, diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index 24b84ec4..e92669e1 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -1417,7 +1417,6 @@ def save_plan_yaml(request, userid=0): elif ps.sessionmode == 'time': ps.interval_string = '{d}min'.format(d=ps.sessionvalue) elif ps.sessionmode == 'rScore': - print('aap') ps.approximate_duration = ps.sessionvalue ps.interval_string = '{d}min'.format(d=ps.sessionvalue) elif ps.sessionmode == 'TRIMP': @@ -2670,6 +2669,14 @@ def rower_view_instantplan(request, id='', userid=0): return HttpResponseRedirect(url) form = InstantPlanSelectForm(request.POST, targets=targets) + byrscoreform = PlanByRscoreForm(request.POST) + if byrscoreform.is_valid(): + try: + byrscore = byrscoreform.cleaned_data['byrscore'] + except KeyError: + byrscore = False + else: + byrscore = False if form.is_valid(): if plan.price > 0: # pragma: no cover @@ -2718,7 +2725,7 @@ def rower_view_instantplan(request, id='', userid=0): p.save() p.rowers.add(r) - create_sessions_from_json(plansteps, r, startdate, r.user) + create_sessions_from_json(plansteps, r, startdate, r.user, planbyrscore=byrscore) messages.info(request, 'Your Sessions have been added') @@ -2739,6 +2746,13 @@ def rower_view_instantplan(request, id='', userid=0): } form = InstantPlanSelectForm( targets=targets, instantplan=plan, initial=initial) + if request.user.is_superuser: + byrscoreform = PlanByRscoreForm() + else: + byrscoreform = None + + + else: # pragma: no cover form = None @@ -2771,6 +2785,7 @@ def rower_view_instantplan(request, id='', userid=0): 'rower': r, 'active': 'nav-plan', 'plan': plan, + 'byrscoreform': byrscoreform, 'trainingdays': trainingdays2, 'breadcrumbs': breadcrumbs, 'form': form, @@ -2983,6 +2998,7 @@ def rower_create_trainingplan(request, id=0): initial={'status': False, 'rowers': [therower]}, user=request.user) + breadcrumbs = [ { 'url': reverse(plannedsessions_view, diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 1dc57d34..a1d2acc3 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -113,7 +113,7 @@ from rowers.forms import ( StravaChartForm, FitnessFitForm, PerformanceManagerForm, TrainingPlanBillingForm, InstantPlanSelectForm, TrainingZonesForm, InstrokeForm, InStrokeMultipleCompareForm, - ForceCurveMultipleCompareForm + ForceCurveMultipleCompareForm, PlanByRscoreForm ) from django.urls import reverse, reverse_lazy From 2db622fc3d6b1e27f38aa33296cf99d166d00305 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 15 Aug 2023 09:17:08 +0200 Subject: [PATCH 3/4] passing tests --- rowers/tests/testdata/testdata.tcx.gz | Bin 3998 -> 4002 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index a0bbfcb73e602558aa0d5d364887d8d7d7034fd3..7e8926dc0c1a712966a42b67d32bdfd83d3aeb22 100644 GIT binary patch delta 1353 zcmV-P1-AO0AEF$*tOE;c~YEt;U)x5d;}9qrn(Ax$p*_e)BN<0Kxm$KD}01Lh&HMsw4AbI5b& z(YJ3e&JSKMH`~?a`kRMn;Niiy#}AHPY`WEYwLW{iT=&a=&G%j3{nl-l2WjW^_M3+< z`~K>1v3T?5jXCQ!7pt{7xx84UFSjQzmlxf3ar@zm*Yt3Iio@>hUpUL7lYaGj)&KFs z+kUyuH+bU&Z?~(D&hUoK<>qWb0J!+|+0*B{Q+%~rZ~Jb2vP?&9SBLxaKD|8Y`rWU+ z(+wQxk9tji=I!?M&ky{2*FWygFE^{@cJUhjeE;9O{$#)Z^7>Nv*Df^(=&pzEf8)dB z2L}g7?;b$<8TsRf4SyUwzq;J?-#q+h|8lu`xc@SJ{p9qR0Nqz0UlF`OKD2m9&O}EX z;cozk07r|o)BF9Oc2@__`)<>}SY0f?dH83?USBAG9s1(3@6PjK&zC2c>(lMAus>RS zw)MjS->>#>(6eRwvDK|7(c=2khaDazQR~i@|5&EG|GDdz-(6ko zUd{fGtMp5*H$Pc_x9s}uPs`1-)%sPx{C9ujN2JsI(w)Cr9-~bc+5h?B3X5AVapUV} z-P_fF#jA_|(+!Bb zJ4?5=>|b7<9zW~Wue$R@@uRIb_wG*q`_bL+wp?AV*8R=R`HS=p{DpUMx7)`@e)39) zvBR&)?tps|xJiNhXB74%Zb$IZ1BP3k?{0@K>(Oib*=1k+^y^=q32q(3KRshQ=fAqX zPht~~7W=aJF&kne}^y5`mc```vV^A&-DH`=Fiuk zR{QUd9&ZxI%gwuef9%rRv$=e;?bfH=`T6c?rH_BB_1S6Hcj>&{{_RRsJ{))S=vDvn za&zM~d31GkzB=jp^wY0jjO%lMcCz%{cdu6Gr`JFCm-IfSLvK8scUzuy|4En3&Vrkt zKi_S&PMf`a*l)Mt`q6%J{-YP^rjLJKo-e!YGI7YC-aWb-_jUBNTc17o{`iLveJG=58$K7Q~& LiIo6Y#DD<+@~`L+ delta 1370 zcmV-g1*Q6;AD$n7ABzYGKYQ9_0{?Vnb97{3bYU)ZV|W1Vom+1dM;3tJ`4tuq$-|18 zbE#7o$2cO8)gl2K1(eO(s$(W*cI~m{X>R|1t7gC$a4Q^pyHwpO9+0P}Z_{6&s&lV{ zAK#sx?7dlDY*uIM`*+d6-Mt?V?;O0i=vM31`uO2;-7hbH9(8^9N4Ht-rJdKC`*&aU z{rUc4@%HUobKG5=uGZ%0>~xX7+#J1Ho_3qX^@lIs(B0iB_PclAaFz#0{p!uCfB*Bl ze!0#!c;y7|HmlFh@RrTl#qojwaPj-oC(pO1xVKtw`fh!+Oh;{2`@8c#IXmk5?XSJj z4eaTUdPC-a-R9+AANcpKf7qRzU96Uy#T)$V{r~Lxquu_?%S++6U1|`}O%L7u#=D1i z_Vx}wJb?5w^2bjb-tRp>KfCDf-~DI*YI$*Y_htI}@ykO3boW5+5xhX&x42KvL`NLq zZvguM2aB}R$Nisl=X=ll?xKIOI$hqs`&Y+aUML-Z`r@qbPV!;Tmq%yomzzUjf3Wy! z>!$-At#)tF(`EXxn{=P~UcT7)Y44Bt4iUq_;_}m{9Udf6>yDTISf;!Gwdds{rTw%i)$`%(l?!4T!tu2Clipm9HPKx36md{&4$NEECzwEmt4p%Vm1NhlKet?*6_)@nUs+ zoNjH|zdCz)__SNU?oJZL&$eFOyF2>tXLrBda(=d2_g6RPFVZ{k4e#Q1x6hCK;*}6% zhhLNJ0k+&%DC|gFkKnTh4A(s0?GBeMqu1uE%f9&K_ivsFt{ua_JYzcNzq-Cp zViOM*yT87?<|1A6%b$1sE#?>DI+LjaBLO*+%>pV6ZO3`1;BJGVg52>IlLG@~3vWT5 z>LO3oO!2f2lXC-b0dAAz191V{lU4+T0qc|71T6uOlL-Ye3%9wqsupOrY(?d*lSKtN z0k)HW1+oE@lQIU?5tMvIy1fO%UR0hOkG7*Ify zUEihicDuJLQTcS-!GqWRtFwzMugQb+^OMz4*QcL;`C?q2`>T_s?|yo{I(d2dbALkf9|&blHNArXRlBHSf)DzxCgNN|6p Date: Tue, 15 Aug 2023 15:19:38 +0200 Subject: [PATCH 4/4] private plan seems to be working --- rowers/tests/testdata/testdata.tcx.gz | Bin 4002 -> 3999 bytes rowers/utils.py | 13 +++++++++++-- rowers/views/planviews.py | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 7e8926dc0c1a712966a42b67d32bdfd83d3aeb22..8081d0e695a6522e399347595a05ff38aa17db16 100644 GIT binary patch literal 3999 zcmV;Q4`A>giwFqtdD~uIcmVC4NpBoC7J%>m6@m}RVG#CP__!#t zf^35^U}u8Z$mBMtNFBLnq?XWKUh?mU?6zguRv~`U6u~Oc2SZ(5Th~{Qd^?Z6d2?}o z@M^i)t}fS)9-@JV2j3h&IC{S6R_oRJ?EB@qUv7Tr`tJ8`yF5rcueXmLzUcd_!^PtD z>(}P2+gz;H=H&8Xk-prXyjWgz+r{mNFJ95Z{V5K+H=l8qZ%_Kwt5yH!k8k?rI^W=p z6TI23J~+c`HkX^T1p(mVx2I2@?N0I4YQ62d^~o|FwOt+V&->)^r0aLT_D(l&pg-yr znK#?hzdrEqUH^S|ez{pKw~JT!*Zcp`^(XuNm)DoV&%4whpt~Nr|BVli9~>MUy?p@b zXXKCXH~e|5_haQ|ic`tj*80lKe1z9M*zd}#5IoQaM&!ruT60ge`F zr+525>8=i*_1&g_zPeaGdiYnzUSB93`uwu*&huf6ct@ ze!Tu}+4b9>mz$@n^~-+w@BYS*NT>O=JAb)6Mw>3O|MUG77PnmD#@A1~H>-=67yqXl z5O>QB+;WK&Ue*53F_9Sjc@WBIyTb}Q3hwIU6`^jaW|NPr$&jh!Q;UAwdo%3H^-zTw&M~nSmA768k zF8cA$yZsjPi*OrWEp-Nyq+P6nIPg?r}EUovny_O!98UYq-af^3E_D?!F@KmUiR3Q*gJzP(ki^5AIkM z_W%`fm&82@l}4NQ#!ZBKUGg5dBJSP<4^E@cJ6F<-W10_lUk`Ty;{#fayn8V+5$=_Z z^A*`~!X|=^8ty?#+V69c_fQdcXB-e{^tvcT_4)b8J3>W@okYW|bJHS}CC~RDPj!)} zYNmKPgk;Kz&XhxxlD-?Z^O1R$ipX0NlTxpec@h%}l9w5gj}?(m=A0l0Rd~h~wd37< z$Xizrc?9Dul1k>2@n6z&=jSue3sgj&jb#+pkT2}Ji!&lm6_Ixaoz97a&X=6$Ews^o z6!O7D5~~T%p${efclRRSM*BhXgvJqg)o35elAlk64y7Wij;s+tRB3oImbB;RMBavq z$R|CW3028g5KBhsEX`=N$BM{D6A-*rrQJ31Ga%1oT*Rm%pObS7lAn>^zNXQh#jpdf zndixtC2wa$zM_Z?2Lk|JG~@+JM(6E){Px_ex*_sOeyu}Q8Wu?`>BE~9`HFmamJK6X zO_Y{=(G2@WekAhFfK`$YFd3PzZJw_vN^67h=~YzO^AU`18s60Bc|nszUS-cSK+%ZJ zj7IyKWL~UE&lX5S9&s|deT&i#lXu1o22GTf35(kEb0S}nJ)bQ!wyJra8BLrBd2I9i z?c_P<-ZCI*JUQt_DVcR`UGv+ILS76o1eMGS6^+<5^5c;ACM1bR4SB~+=I=miR| zBtTF#$?#lM=6%!cMgB=55)m z>)2{(MGorgM=%kIHQrkX*m7^DFZ0Mo0+A+4>u@^c zxp{I1$-A6&t?Gp62#f0Wb0S~UXdewA22Fh4F%_+%_ANd?2Kk(O8!%}4-a1P~b8qKF zz9M^`tRaW2n&*WklY7gpetwX=H)xSmqrIb|_WX>2L2m7oF$lM7|>3 zK51(lQMGEB3*4f#GaxSpKvZ4MUE~&}o&IRg-iYWrA$n-!?@GQR-QI#>FDg%tM_W?E zyH_4w)9{ALbMAhs^4|Jn3C5OzIeGG8ymhFF)%m0w6pYmg&d8pxC_Zn4vB;>&$?@rJ zu@fO*n-4G4LtZe~(yG?9@KUsXeoiu9lZGd3ybx-9c;2~^e*0O?^A*|iNq#w!s>a59 z*D5OSNWP*dtwaM%pc?Iin~ZMXytf17g15oSSD3w zMnrDpryj9Mmsax;c@r$dhA(p-7;~w~yWz9qnCP zi+T+5``laIJRd?)t8Px@EAr$>ve1}7MLve2IXSM)^P`Y=CRk!klokQXhH2-7z9LtS z#GG&sL4}^6p}%AQ(`v?hmpk9Os2lGQ7>lOd-v>QZhF&T{FS%g~=mvaClR=NI-}NB+ zU<3(Cg+8fqkLvjTKb+a1p#TslOw7stCQ$EwVhS z&<8gesjmz@yL!+kJIw|Ht3n@rQ8jN)13p%Sp3_`UpqlFu!er3bHsIGJ_0BLLspfjb zvgI~&LeCYUk6FWyI;k(aYGFe^4*J{))v+ow3)76%H2fK$mptIBLbixPMWgj|Qu8V@ z?l>6o7*rZQy5`Nht8o|VL7&EMaJfI82E8xZ2lrkXnb3^8LG;!D5bLBq*vX*BX50;; z_X)kOiAK)mDvF*P`ccqF6RpyvL*R-UchtOjW1vsUdPH5>4N`XeH>saIdNIyx(No!0 zX>*c#s0e*9BBW}7jg%}x-_TFnrQ>sFOzT8c#vLUEK_=2Z2ivmrgXpbcuWO%^7si-O z=cH!W52N>nf&|@w@1ba6JvKFO4D^@;SXpp~6mT*faj~Uk4x(p+PS-UHDHdJ0bXEgC zRfOIdu%ye#W#GxIant7dVf4X7QC8nD+M+I)cSQxf=t0&af2J)z`C>ZKpy_%^L+h8v%?usdr&A z13tC{twHq8Sk$d$i0ot0#%a{-`ccqFLlLb`!w+S{H{85=W1zQ``)BFAc^qR?^QJ%G zTQMNY!Yhj~nRtC|$=DSIZEe!nkYZG!Cu(#3^wA5Ls9d-hEmP6RUGw3OgPu)vNILYE zC$qd+bL0-A-?dEiDmBlFZ7!YZJ92j|6VdDDdMA@f&}wO!1L(u9Wg_U7yg}=w8Fy2+ z>qBmtXhl%v$hDzW-`o{_s0e+?9kg^^HEb*!zTr0DkAWW1FpE=3y+GOJ>UlUs=mSosp-NNp2GGacG7%7?&aRKt(lTd&o=pIyH_t=a z<&2^A(isK4%jl!ZuJ_1AYwn;KccY+>#-lP1-&5HV3}`{yG0-FBhAK*_=dvXj(1Nz3 zpqJcGg>+JHrD)_1nwmEX`e0Zv=%ij;(NvA5=8b}$l5t1M)(YOa=E$A8ODE=*iJ)E6 z)_Xshxt?0kb`X6ovSv_)Z+!60uAc$=Xe3#8I;oF-GIl*RHE#$#lM!om;hO-V+4VC( zFS+mvbm*}t`n*(78}LU!9}F<+`r(J1ygw22)Vz5^=<`a}fI)|z<7Cjc_3MYxvk5}F z$X$9-N^1DI6GcNm0(xgW+o*Es1cxPEI4Z?U()M2HTg}}tddbx{L6wmkV$n+5dky%lm(DQykk_=;MeZULUF>XD8h$NVIs&_u ztO32sksDDa1o=8b}$cZ-;-jJqhYt!_DSZ(c_4a^aN{y^BSqzBNi62Yt+iS30{s258OG zChpBk=yxkwD$?p{iznUH^@pD>`{nld zi}U{LAJ3N;%XNS7ze!hEJ>EmjBcG~q_I&ZgsyAqZ6#~pq9vVU>8x$&BO zdv$fbI_diK)30BQ>vMl{vh>||FIVTM*FX2y^ggCTZ#Z@1z4(SCIPqvz?SkAGR7FT3qBamb(EKDrzCb@ZfLpFRHJ_{X0zo86!L?LVit z_@|c_zc16B0el6p|Nm%l
1-#w<|2RqcOb$SlpCzQ+059w+Ao-Td-;D5uw#wf&q F0RUTrLE8WT literal 4002 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 ISj2z<03azh%K!iX diff --git a/rowers/utils.py b/rowers/utils.py index 9ec563ad..a77e3fd8 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -721,6 +721,8 @@ def step_to_time_dist(step, avgspeed=3.2, ftp=200, ftspm=25, ftv=3.7, powerzones else: velomid = avgspeed + distance = velomid*seconds + veloratio = (velomid/ftv)**(3.0) rscoreperhour = 100.*veloratio rscore = rscoreperhour*seconds/3600. @@ -744,7 +746,7 @@ def step_to_time_dist(step, avgspeed=3.2, ftp=200, ftspm=25, ftv=3.7, powerzones avgpower = targetpower if valuelow != 0 and valuehigh != 0: # pragma: no cover avgpower = (valuelow+valuehigh)/2. - avgspeed = ftv*(avgspeed/ftv)**(1./3.) + avgspeed = ftv*(avgpower/ftp)**(1./3.) distance = avgspeed*seconds rscore = 100.*(avgpower/ftp)*seconds/3600. @@ -760,6 +762,9 @@ def step_to_time_dist(step, avgspeed=3.2, ftp=200, ftspm=25, ftv=3.7, powerzones avgspm = (valuelow+valuehigh)/2. avgpower = ftp*avgspm/ftspm + avgspeed = ftv*(avgpower/ftp)**(1./3.) + distance = avgspeed*seconds + rscore = 100*(avgpower/ftp)*seconds/3600. return seconds, distance, rscore @@ -784,6 +789,7 @@ def step_to_time_dist(step, avgspeed=3.2, ftp=200, ftspm=25, ftv=3.7, powerzones veloratio = (velomid/ftv)**(3.0) rscoreperhour = 100.*veloratio rscore = rscoreperhour*seconds/3600. + seconds = distance/velomid if targettype == 'Power': # pragma: no cover value = step.get('targetValue', 0) @@ -802,7 +808,7 @@ def step_to_time_dist(step, avgspeed=3.2, ftp=200, ftspm=25, ftv=3.7, powerzones avgpower = targetpower if valuelow != 0 and valuehigh != 0: avgpower = (valuelow+valuehigh)/2. - avgspeed = ftv*(avgspeed/ftv)**(1./3.) + avgspeed = ftv*(avgpower/ftp)**(1./3.) seconds = distance/avgspeed rscore = 100.*(avgpower/ftp)*seconds/3600. @@ -819,6 +825,8 @@ def step_to_time_dist(step, avgspeed=3.2, ftp=200, ftspm=25, ftv=3.7, powerzones avgpower = ftp*avgspm/ftspm rscore = 100*(avgpower/ftp)*seconds/3600. + avgspeed = ftv*(avgpower/ftp)**(1./3.) + seconds = distance/avgspeed return seconds, distance, rscore elif durationtype in ['PowerLessThan', 'PowerGreaterThan', 'HrLessThan', 'HrGreaterThan']: # pragma: no cover @@ -917,6 +925,7 @@ def ps_dict_order(d, short=False, rower=None, html=True): sdict2 = collections.OrderedDict(reversed(list(sdict.items()))) + for step in steps: sstring, type, stepID, repeatID, repeatValue = step_to_string( step, short=short) diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index e92669e1..bb0248a7 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -2623,6 +2623,8 @@ def rower_view_instantplan(request, id='', userid=0): nextday['week'] = (divmod(i, 7)[0])+1 trainingdays2.append(nextday) + + workouts = nextday['workouts'] try: nextday = trainingdays.pop(0) except IndexError: