rowingdata 3.6.5__tar.gz → 3.6.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rowingdata-3.6.5/rowingdata.egg-info → rowingdata-3.6.7}/PKG-INFO +20 -1
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/checkdatafiles.py +13 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/csvparsers.py +10 -2
- rowingdata-3.6.7/rowingdata/laptesting.py +293 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/rowingdata.py +650 -23
- {rowingdata-3.6.5 → rowingdata-3.6.7/rowingdata.egg-info}/PKG-INFO +20 -1
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata.egg-info/SOURCES.txt +1 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/testdatasummary.csv +82 -84
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/testtcx.tcx +1 -1
- {rowingdata-3.6.5 → rowingdata-3.6.7}/tests/test_rowingdata.py +26 -8
- {rowingdata-3.6.5 → rowingdata-3.6.7}/LICENSE +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/MANIFEST.in +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/README.rst +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/bin/crewnerddata.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/bin/crewnerddata.tcx +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/bin/testdata.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/.buildinfo +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_images/2x20min.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_images/editrower.JPG +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_images/greghoc.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_images/image001.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_images/otwlogbook.JPG +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_images/otwscreenshot.JPG +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_images/screenshot.JPG +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_images/screenshotlogbook.JPG +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_images/woensdag.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_sources/index.txt +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_sources/modules.txt +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_sources/rowingdata.txt +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/ajax-loader.gif +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/alabaster.css +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/basic.css +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/comment-bright.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/comment-close.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/comment.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/custom.css +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/doctools.js +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/down-pressed.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/down.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/file.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/jquery-1.11.1.js +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/jquery.js +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/minus.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/plus.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/pygments.css +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/searchtools.js +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/underscore-1.3.1.js +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/underscore.js +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/up-pressed.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/up.png +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/_static/websupport.js +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/genindex.html +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/index.html +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/modules.html +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/objects.inv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/py-modindex.html +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/rowingdata.html +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/search.html +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/docs/_build/html/searchindex.js +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/__init__.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/__main__.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/boatedit.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/copystats.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/crewnerdplot.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/crewnerdplottime.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/ergdataplot.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/ergdataplottime.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/ergdatatotcx.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/ergstickplot.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/ergstickplottime.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/ergsticktotcx.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/gpxtools.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/gpxwrite.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/konkatenaadje.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/obsolete.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/otherparsers.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/painsled_desktop_plot.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/painsled_desktop_plottime.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/painsled_desktop_toc2.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/painsledplot.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/painsledplottime.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/painsledtoc2.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/roweredit.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/rowproplot.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/rowproplottime.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/speedcoachplot.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/speedcoachplottime.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/speedcoachtoc2.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/tcxplot.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/tcxplot_nogeo.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/tcxplottime.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/tcxplottime_nogeo.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/tcxtoc2.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/tcxtools.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/trainingparser.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/utils.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/windcorrected.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata/writetcx.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata.egg-info/dependency_links.txt +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata.egg-info/not-zip-safe +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata.egg-info/requires.txt +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/rowingdata.egg-info/top_level.txt +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/setup.cfg +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/setup.py +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/2016-03-25-0758.CSV +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/2016-03-25-0758_data.CSV +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/2x20min_o.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/3km_cd_o.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/EUBoatCoach.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/EmpowerSpeedCoachForce.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/NKEmporfromgreg.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/NKLiNKv130.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/NoHR.tcx +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/PainsledForce.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/RP_interval.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/RP_interval.csv_o.CSV +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/RP_testdata.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/SpdCoach2_imp_inconsistent.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/SpdCoachAmbiguous.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/SpeedCoach GPS Workout.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/SpeedCoach2Link_interval.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/SpeedCoach2Linkv1.27.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/SpeedCoach2v2.12.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/Speedcoach2example.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/aritmo.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/bc1.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/bc2.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/bc3.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/boatcoach.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/boatcoach_fixed_distance.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/boatcoach_otw.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/correctedpainsled.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/coxmate.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/crewnerd_interval.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/crewnerddata.CSV +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/crewnerddata.tcx +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/crewnerddata_o.CSV +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/cumvalues.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/ergdata_example.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/ergdata_example.csv_o.CSV +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/ergstick.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/ergstick.csv_o.CSV +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/ergstick2.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/ergstick_o.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/example.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/example_data.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/faketcx.tcx +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/float.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/herodata.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/humon.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/impeller_empower.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/invalidchar.tcx +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/kinomap.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/mystery.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/nk_logbook.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/painsled.tcx +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/painsled_desktop_example.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/painsled_out_data.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/painsled_to_csv_20160221-105218_erg-400150318_760465m.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/quiske_per_stroke_left.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/quiske_per_stroke_new.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/quiske_per_stroke_right.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/quiske_per_stroke_seat.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/recover.tcx +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/ritmointervals.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rowingdata_eth.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rowinginmotionexample.TCX +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rowinginmotionexample.TCX_o.CSV +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rowperfect.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rowpro5.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rowpro_carrick.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rp3_curve.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rp3intervals.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rp3intervals2.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/rp_out.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/smartrow.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/smartrow_intervals.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/spdcoach2noheader.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/speedcoach2test2.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/speedcoach3test3.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/speedcoachexample.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/speedcoachexample.csv_o.CSV +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/summarytest.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/testdata.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/testdata_part1.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/testdata_part2.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/testlapidx.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/testtcs_210614.tcx +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/testtcx_210614.tcx +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata/tim.csv +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/testdata//345/210/222/350/210/271.csv" +0 -0
- {rowingdata-3.6.5 → rowingdata-3.6.7}/tests/testparser.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rowingdata
|
|
3
|
-
Version: 3.6.
|
|
3
|
+
Version: 3.6.7
|
|
4
4
|
Summary: The rowingdata library to create colorful plots from CrewNerd, Painsled and other rowing data tools
|
|
5
5
|
Home-page:
|
|
6
6
|
Author: Sander Roosendaal
|
|
@@ -9,6 +9,25 @@ License: MIT
|
|
|
9
9
|
Keywords: rowing ergometer concept2
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
11
|
License-File: LICENSE
|
|
12
|
+
Requires-Dist: Cython
|
|
13
|
+
Requires-Dist: numpy
|
|
14
|
+
Requires-Dist: scipy
|
|
15
|
+
Requires-Dist: matplotlib
|
|
16
|
+
Requires-Dist: pandas
|
|
17
|
+
Requires-Dist: fitparse
|
|
18
|
+
Requires-Dist: arrow>=1.0.2
|
|
19
|
+
Requires-Dist: python-dateutil
|
|
20
|
+
Requires-Dist: docopt
|
|
21
|
+
Requires-Dist: tqdm
|
|
22
|
+
Requires-Dist: rowingphysics>=0.2.3
|
|
23
|
+
Requires-Dist: iso8601
|
|
24
|
+
Requires-Dist: lxml
|
|
25
|
+
Requires-Dist: xmltodict
|
|
26
|
+
Requires-Dist: nose_parameterized
|
|
27
|
+
Requires-Dist: timezonefinder
|
|
28
|
+
Requires-Dist: pycairo
|
|
29
|
+
Requires-Dist: tk
|
|
30
|
+
Requires-Dist: requests
|
|
12
31
|
|
|
13
32
|
**************
|
|
14
33
|
Rowingdata
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import absolute_import
|
|
2
2
|
from __future__ import print_function
|
|
3
|
+
import polars as pl
|
|
3
4
|
|
|
4
5
|
try:
|
|
5
6
|
from . import rowingdata
|
|
@@ -151,6 +152,11 @@ def checkfile(f2, verbose=False):
|
|
|
151
152
|
else:
|
|
152
153
|
row = rowingdata.rowingdata(csvfile=f2)
|
|
153
154
|
|
|
155
|
+
row.write_csv(f2+'pl.csv')
|
|
156
|
+
row2 = rowingdata.rowingdata_pl(csvfile=f2 + 'pl.csv')
|
|
157
|
+
os.remove(f2 + 'pl.csv')
|
|
158
|
+
row2 = rowingdata.rowingdata_pl(df=pl.from_pandas(row.df))
|
|
159
|
+
|
|
154
160
|
nr_of_rows = row.number_of_rows
|
|
155
161
|
distmax = row.df['cum_dist'].max()
|
|
156
162
|
timemax = row.df['TimeStamp (sec)'].max() - row.df['TimeStamp (sec)'].min()
|
|
@@ -170,6 +176,11 @@ def checkfile(f2, verbose=False):
|
|
|
170
176
|
int1time = res[0][0]
|
|
171
177
|
int1dist = res[1][0]
|
|
172
178
|
|
|
179
|
+
# alternative
|
|
180
|
+
summary_df = row.summarize_rowing_data()
|
|
181
|
+
int1time_new = summary_df['lap_duration'].values[0]
|
|
182
|
+
int1dst_new = summary_df['total_distance_per_lap'].values[0]
|
|
183
|
+
|
|
173
184
|
if verbose:
|
|
174
185
|
print(("Interval 1 time ", int1time))
|
|
175
186
|
print(("Interval 1 dist ", int1dist))
|
|
@@ -196,6 +207,8 @@ def checkfile(f2, verbose=False):
|
|
|
196
207
|
'nrintervals': nrintervals,
|
|
197
208
|
'lap 1 time': int(int1time),
|
|
198
209
|
'lap 1 dist': int(int1dist),
|
|
210
|
+
'lap 1 time new': int(int1time_new),
|
|
211
|
+
'lap 1 dist new': int(int1dst_new),
|
|
199
212
|
'timezone': tz,
|
|
200
213
|
'summary':summary,
|
|
201
214
|
}
|
|
@@ -1969,10 +1969,18 @@ class HeroParser(CSVParser):
|
|
|
1969
1969
|
|
|
1970
1970
|
class SmartRowParser(CSVParser):
|
|
1971
1971
|
def __init__(self, *args, **kwargs):
|
|
1972
|
+
if args:
|
|
1973
|
+
csvfile = args[0]
|
|
1974
|
+
else: # pragma: no cover
|
|
1975
|
+
csvfile = kwargs['csvfile']
|
|
1976
|
+
|
|
1977
|
+
separator = get_separator(5, csvfile)
|
|
1978
|
+
kwargs['sep'] = separator
|
|
1979
|
+
|
|
1972
1980
|
super(SmartRowParser, self).__init__(*args, **kwargs)
|
|
1973
1981
|
|
|
1974
1982
|
self.cols = [
|
|
1975
|
-
'
|
|
1983
|
+
'Timestamp (UTC)',
|
|
1976
1984
|
'Distance (m)',
|
|
1977
1985
|
'Stroke rate (SPM)',
|
|
1978
1986
|
'Heart rate (bpm)',
|
|
@@ -1986,7 +1994,7 @@ class SmartRowParser(CSVParser):
|
|
|
1986
1994
|
'', #' AverageDriveForce (lbs)',
|
|
1987
1995
|
'', #' PeakDriveForce (lbs)',
|
|
1988
1996
|
'', #' lapIdx',
|
|
1989
|
-
'
|
|
1997
|
+
'Second (#)',
|
|
1990
1998
|
'', #' latitude',
|
|
1991
1999
|
'', #' longitude',
|
|
1992
2000
|
]
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
def summarize_rowing_data(df):
|
|
4
|
+
# Ensure the DataFrame is sorted by time
|
|
5
|
+
df = df.sort_values(by='TimeStamp (sec)')
|
|
6
|
+
|
|
7
|
+
# Convert numeric columns to numeric type, handling non-numeric values
|
|
8
|
+
numeric_cols = [
|
|
9
|
+
'TimeStamp (sec)',
|
|
10
|
+
' Horizontal (meters)',
|
|
11
|
+
' Cadence (stokes/min)',
|
|
12
|
+
' HRCur (bpm)',
|
|
13
|
+
' Stroke500mPace (sec/500m)',
|
|
14
|
+
' Power (watts)',
|
|
15
|
+
' DriveLength (meters)',
|
|
16
|
+
' StrokeDistance (meters)',
|
|
17
|
+
' DriveTime (ms)',
|
|
18
|
+
' StrokeRecoveryTime (ms)',
|
|
19
|
+
' AverageDriveForce (lbs)',
|
|
20
|
+
' PeakDriveForce (lbs)',
|
|
21
|
+
' lapIdx',
|
|
22
|
+
' ElapsedTime (sec)',
|
|
23
|
+
' WorkoutState'
|
|
24
|
+
]
|
|
25
|
+
df[numeric_cols] = df[numeric_cols].apply(pd.to_numeric, errors='coerce')
|
|
26
|
+
|
|
27
|
+
# Drop rows with NaN values
|
|
28
|
+
df = df.dropna()
|
|
29
|
+
|
|
30
|
+
# Initialize variables to store summarized data
|
|
31
|
+
lap_summaries = []
|
|
32
|
+
|
|
33
|
+
# Initialize variables to track the start time and data for each lap
|
|
34
|
+
lap_start_time = None
|
|
35
|
+
lap_end_time = None
|
|
36
|
+
lap_cadences = []
|
|
37
|
+
lap_paces = [] # Added lap_paces to store paces for each lap
|
|
38
|
+
lap_distances = []
|
|
39
|
+
lap_powers = []
|
|
40
|
+
lap_heart_rates = []
|
|
41
|
+
lap_id = None
|
|
42
|
+
|
|
43
|
+
# Use a mask to filter rows where the workout_state is work strokes
|
|
44
|
+
work_strokes_mask = df[' WorkoutState'].isin([1, 4, 5, 6, 7, 8, 9])
|
|
45
|
+
|
|
46
|
+
# Iterate through rows in the DataFrame
|
|
47
|
+
for index, row in df.iterrows():
|
|
48
|
+
if work_strokes_mask[index]:
|
|
49
|
+
# If the lap has started or the lap ID changes, append cadence, pace, and heart rate to lap lists
|
|
50
|
+
if lap_start_time is not None and row[' lapIdx'] == lap_id:
|
|
51
|
+
lap_cadences.append(row[' Cadence (stokes/min)'])
|
|
52
|
+
lap_paces.append(row[' Stroke500mPace (sec/500m)'])
|
|
53
|
+
lap_distances.append(row[' StrokeDistance (meters)'])
|
|
54
|
+
lap_powers.append(row[' Power (watts)'])
|
|
55
|
+
lap_heart_rates.append(row[' HRCur (bpm)'])
|
|
56
|
+
lap_end_time = row['TimeStamp (sec)']
|
|
57
|
+
else:
|
|
58
|
+
# If the lap has not started or the lap ID changes, initialize lap-related variables
|
|
59
|
+
if lap_start_time is not None:
|
|
60
|
+
# If a lap has ended, calculate lap duration and append averages to summary list
|
|
61
|
+
lap_duration = lap_end_time - lap_start_time
|
|
62
|
+
avg_cadence = sum(lap_cadences) / len(lap_cadences)
|
|
63
|
+
avg_pace = sum(lap_paces) / len(lap_paces)
|
|
64
|
+
avg_speed = 500 / avg_pace # Speed is derived from the reciprocal of pace
|
|
65
|
+
total_distance_per_lap = sum(lap_distances) # Improved calculation of total distance per lap
|
|
66
|
+
avg_power = sum(lap_powers) / len(lap_powers)
|
|
67
|
+
max_heart_rate = max(lap_heart_rates)
|
|
68
|
+
avg_heart_rate = sum(lap_heart_rates) / len(lap_heart_rates)
|
|
69
|
+
total_strokes_in_lap = len(lap_cadences)
|
|
70
|
+
distance_per_stroke = total_distance_per_lap / total_strokes_in_lap
|
|
71
|
+
|
|
72
|
+
lap_summaries.append({
|
|
73
|
+
'lap_id': lap_id,
|
|
74
|
+
'lap_duration': lap_duration,
|
|
75
|
+
'avg_cadence': avg_cadence,
|
|
76
|
+
'avg_pace': avg_pace,
|
|
77
|
+
'avg_speed': avg_speed,
|
|
78
|
+
'total_distance_per_lap': total_distance_per_lap,
|
|
79
|
+
'avg_power': avg_power,
|
|
80
|
+
'max_heart_rate': max_heart_rate,
|
|
81
|
+
'avg_heart_rate': avg_heart_rate,
|
|
82
|
+
'total_strokes_in_lap': total_strokes_in_lap,
|
|
83
|
+
'distance_per_stroke': distance_per_stroke
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
# Reset lap-related variables
|
|
87
|
+
lap_start_time = row['TimeStamp (sec)']
|
|
88
|
+
lap_end_time = row['TimeStamp (sec)']
|
|
89
|
+
lap_cadences = [row[' Cadence (stokes/min)']]
|
|
90
|
+
lap_paces = [row[' Stroke500mPace (sec/500m)']]
|
|
91
|
+
lap_distances = [row[' StrokeDistance (meters)']]
|
|
92
|
+
lap_powers = [row[' Power (watts)']]
|
|
93
|
+
lap_heart_rates = [row[' HRCur (bpm)']]
|
|
94
|
+
lap_id = row[' lapIdx']
|
|
95
|
+
|
|
96
|
+
# If the last lap is work stroke, add it to the summary
|
|
97
|
+
if lap_start_time is not None:
|
|
98
|
+
lap_duration = lap_end_time - lap_start_time
|
|
99
|
+
avg_cadence = sum(lap_cadences) / len(lap_cadences)
|
|
100
|
+
avg_pace = sum(lap_paces) / len(lap_paces)
|
|
101
|
+
avg_speed = 500 / avg_pace # Speed is derived from the reciprocal of pace
|
|
102
|
+
total_distance_per_lap = sum(lap_distances) # Improved calculation of total distance per lap
|
|
103
|
+
avg_power = sum(lap_powers) / len(lap_powers)
|
|
104
|
+
max_heart_rate = max(lap_heart_rates)
|
|
105
|
+
avg_heart_rate = sum(lap_heart_rates) / len(lap_heart_rates)
|
|
106
|
+
total_strokes_in_lap = len(lap_cadences)
|
|
107
|
+
distance_per_stroke = total_distance_per_lap / total_strokes_in_lap
|
|
108
|
+
|
|
109
|
+
lap_summaries.append({
|
|
110
|
+
'lap_id': lap_id,
|
|
111
|
+
'lap_duration': lap_duration,
|
|
112
|
+
'avg_cadence': avg_cadence,
|
|
113
|
+
'avg_pace': avg_pace,
|
|
114
|
+
'avg_speed': avg_speed,
|
|
115
|
+
'total_distance_per_lap': total_distance_per_lap,
|
|
116
|
+
'avg_power': avg_power,
|
|
117
|
+
'max_heart_rate': max_heart_rate,
|
|
118
|
+
'avg_heart_rate': avg_heart_rate,
|
|
119
|
+
'total_strokes_in_lap': total_strokes_in_lap,
|
|
120
|
+
'distance_per_stroke': distance_per_stroke
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
# Create a new DataFrame with the summarized data
|
|
124
|
+
summary_df = pd.DataFrame(lap_summaries)
|
|
125
|
+
|
|
126
|
+
return summary_df
|
|
127
|
+
|
|
128
|
+
import pandas as pd
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
import pandas as pd
|
|
132
|
+
|
|
133
|
+
def summarize_entire_workout(df):
|
|
134
|
+
# Ensure the DataFrame is sorted by time
|
|
135
|
+
df = df.sort_values(by='TimeStamp (sec)')
|
|
136
|
+
|
|
137
|
+
# Convert numeric columns to numeric type, handling non-numeric values
|
|
138
|
+
numeric_cols = [
|
|
139
|
+
'TimeStamp (sec)',
|
|
140
|
+
' Horizontal (meters)',
|
|
141
|
+
' Cadence (stokes/min)',
|
|
142
|
+
' HRCur (bpm)',
|
|
143
|
+
' Stroke500mPace (sec/500m)',
|
|
144
|
+
' Power (watts)',
|
|
145
|
+
' DriveLength (meters)',
|
|
146
|
+
' StrokeDistance (meters)',
|
|
147
|
+
' DriveTime (ms)',
|
|
148
|
+
' StrokeRecoveryTime (ms)',
|
|
149
|
+
' AverageDriveForce (lbs)',
|
|
150
|
+
' PeakDriveForce (lbs)',
|
|
151
|
+
' lapIdx',
|
|
152
|
+
' ElapsedTime (sec)',
|
|
153
|
+
' WorkoutState'
|
|
154
|
+
]
|
|
155
|
+
df[numeric_cols] = df[numeric_cols].apply(pd.to_numeric, errors='coerce')
|
|
156
|
+
|
|
157
|
+
# Drop rows with NaN values
|
|
158
|
+
df = df.dropna()
|
|
159
|
+
|
|
160
|
+
# Use a mask to filter rows where the workout_state is work strokes or resting strokes
|
|
161
|
+
work_strokes_mask = df[' WorkoutState'].isin([1, 4, 5, 6, 7, 8, 9])
|
|
162
|
+
rest_strokes_mask = df[' WorkoutState'] == 3
|
|
163
|
+
|
|
164
|
+
# Filter rows for work strokes, resting strokes, and entire workout
|
|
165
|
+
work_intervals_df = df[work_strokes_mask]
|
|
166
|
+
rest_intervals_df = df[rest_strokes_mask]
|
|
167
|
+
|
|
168
|
+
# Calculate total distance for work intervals and resting intervals
|
|
169
|
+
total_distance_work_intervals = (
|
|
170
|
+
work_intervals_df.groupby(' lapIdx')[' Horizontal (meters)'].max().diff().fillna(
|
|
171
|
+
work_intervals_df.groupby(' lapIdx')[' Horizontal (meters)'].max()
|
|
172
|
+
).sum()
|
|
173
|
+
)
|
|
174
|
+
total_distance_rest_intervals = (
|
|
175
|
+
rest_intervals_df.groupby(' lapIdx')[' Horizontal (meters)'].max().diff().fillna(
|
|
176
|
+
rest_intervals_df.groupby(' lapIdx')[' Horizontal (meters)'].max()
|
|
177
|
+
).sum()
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Calculate total distance for the entire workout
|
|
181
|
+
total_distance_workout = (
|
|
182
|
+
df.groupby(' lapIdx')[' Horizontal (meters)'].max().diff().fillna(
|
|
183
|
+
df.groupby(' lapIdx')[' Horizontal (meters)'].max()
|
|
184
|
+
).sum()
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# Get the maximum total time among all laps
|
|
188
|
+
total_time = df.groupby(' lapIdx')[' ElapsedTime (sec)'].max().max()
|
|
189
|
+
|
|
190
|
+
# Calculate averages for the entire workout
|
|
191
|
+
avg_cadence_workout = df[' Cadence (stokes/min)'].mean()
|
|
192
|
+
avg_pace_workout = df[' Stroke500mPace (sec/500m)'].mean()
|
|
193
|
+
avg_speed_workout = 500 / avg_pace_workout
|
|
194
|
+
avg_power_workout = df[' Power (watts)'].mean()
|
|
195
|
+
avg_heart_rate_workout = df[' HRCur (bpm)'].mean()
|
|
196
|
+
|
|
197
|
+
# Calculate averages for work intervals
|
|
198
|
+
avg_cadence_work = work_intervals_df[' Cadence (stokes/min)'].mean()
|
|
199
|
+
avg_pace_work = work_intervals_df[' Stroke500mPace (sec/500m)'].mean()
|
|
200
|
+
avg_speed_work = 500 / avg_pace_work
|
|
201
|
+
avg_power_work = work_intervals_df[' Power (watts)'].mean()
|
|
202
|
+
avg_heart_rate_work = work_intervals_df[' HRCur (bpm)'].mean()
|
|
203
|
+
|
|
204
|
+
# Calculate averages for resting intervals
|
|
205
|
+
avg_cadence_rest = rest_intervals_df[' Cadence (stokes/min)'].mean()
|
|
206
|
+
avg_pace_rest = rest_intervals_df[' Stroke500mPace (sec/500m)'].mean()
|
|
207
|
+
avg_speed_rest = 500 / avg_pace_rest
|
|
208
|
+
avg_power_rest = rest_intervals_df[' Power (watts)'].mean()
|
|
209
|
+
avg_heart_rate_rest = rest_intervals_df[' HRCur (bpm)'].mean()
|
|
210
|
+
|
|
211
|
+
# Create a summary dictionary
|
|
212
|
+
summary_dict = {
|
|
213
|
+
'total_distance_workout': total_distance_workout,
|
|
214
|
+
'total_distance_work_intervals': total_distance_work_intervals,
|
|
215
|
+
'total_distance_rest_intervals': total_distance_rest_intervals,
|
|
216
|
+
'total_time': total_time,
|
|
217
|
+
'avg_cadence_workout': avg_cadence_workout,
|
|
218
|
+
'avg_pace_workout': avg_pace_workout,
|
|
219
|
+
'avg_speed_workout': avg_speed_workout,
|
|
220
|
+
'avg_power_workout': avg_power_workout,
|
|
221
|
+
'avg_heart_rate_workout': avg_heart_rate_workout,
|
|
222
|
+
'avg_cadence_work': avg_cadence_work,
|
|
223
|
+
'avg_pace_work': avg_pace_work,
|
|
224
|
+
'avg_speed_work': avg_speed_work,
|
|
225
|
+
'avg_power_work': avg_power_work,
|
|
226
|
+
'avg_heart_rate_work': avg_heart_rate_work,
|
|
227
|
+
'avg_cadence_rest': avg_cadence_rest,
|
|
228
|
+
'avg_pace_rest': avg_pace_rest,
|
|
229
|
+
'avg_speed_rest': avg_speed_rest,
|
|
230
|
+
'avg_power_rest': avg_power_rest,
|
|
231
|
+
'avg_heart_rate_rest': avg_heart_rate_rest
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return summary_dict
|
|
235
|
+
|
|
236
|
+
def create_workout_summary_string(summary_df, summary_dict):
|
|
237
|
+
# Extract values from the summary_dict
|
|
238
|
+
total_distance_workout = int(summary_dict['total_distance_workout'])
|
|
239
|
+
total_distance_work_intervals = int(summary_dict['total_distance_work_intervals'])
|
|
240
|
+
total_distance_rest_intervals = int(summary_dict['total_distance_rest_intervals'])
|
|
241
|
+
total_time = str(summary_dict['total_time'])
|
|
242
|
+
avg_cadence_workout = str(round(summary_dict['avg_cadence_workout'], 1))
|
|
243
|
+
avg_pace_workout = str(summary_dict['avg_pace_workout'])
|
|
244
|
+
avg_speed_workout = str(round(summary_dict['avg_speed_workout'], 1))
|
|
245
|
+
avg_power_workout = str(round(summary_dict['avg_power_workout'], 1))
|
|
246
|
+
avg_heart_rate_workout = str(round(summary_dict['avg_heart_rate_workout'], 1))
|
|
247
|
+
avg_cadence_work = str(round(summary_dict['avg_cadence_work'], 1))
|
|
248
|
+
avg_pace_work = str(summary_dict['avg_pace_work'])
|
|
249
|
+
avg_speed_work = str(round(summary_dict['avg_speed_work'], 1))
|
|
250
|
+
avg_power_work = str(round(summary_dict['avg_power_work'], 1))
|
|
251
|
+
avg_heart_rate_work = str(round(summary_dict['avg_heart_rate_work'], 1))
|
|
252
|
+
avg_cadence_rest = str(round(summary_dict['avg_cadence_rest'], 1))
|
|
253
|
+
avg_pace_rest = str(summary_dict['avg_pace_rest'])
|
|
254
|
+
avg_speed_rest = str(round(summary_dict['avg_speed_rest'], 1))
|
|
255
|
+
avg_power_rest = str(round(summary_dict['avg_power_rest'], 1))
|
|
256
|
+
avg_heart_rate_rest = str(round(summary_dict['avg_heart_rate_rest'], 1))
|
|
257
|
+
|
|
258
|
+
# Create the workout summary string
|
|
259
|
+
workout_summary_string = (
|
|
260
|
+
f"Workout Summary - testdata.csv\n"
|
|
261
|
+
"--|Total|-Total----|--Avg--|-Avg-|Avg-|-Avg-|-Max-|-Avg\n"
|
|
262
|
+
f"--|{total_distance_workout:05d}|{total_time}|{avg_pace_workout}|{avg_power_workout}|"
|
|
263
|
+
f"{avg_cadence_workout}|{avg_heart_rate_workout}|XXX.X|{avg_heart_rate_workout}\n"
|
|
264
|
+
f"W-|{total_distance_work_intervals:05d}|{total_time}|{avg_pace_work}|{avg_power_work}|"
|
|
265
|
+
f"{avg_cadence_work}|{avg_heart_rate_work}|XXX.X|{avg_heart_rate_work}\n"
|
|
266
|
+
f"R-|{total_distance_rest_intervals:05d}|00:00.0|00:00.0|000.0|00.0|000.0|{avg_heart_rate_rest}|00.0\n"
|
|
267
|
+
"Workout Details\n"
|
|
268
|
+
"#-|SDist|-Split-|-SPace-|-Pwr-|SPM-|AvgHR|MaxHR|DPS-\n"
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
# Iterate over rows in the summary DataFrame to create details
|
|
272
|
+
for _, row in summary_df.iterrows():
|
|
273
|
+
lap_distance = int(row['total_distance_per_lap'])
|
|
274
|
+
split_time = str(row['lap_duration'])
|
|
275
|
+
split_pace = str(row['avg_pace'])
|
|
276
|
+
split_power = str(row['avg_power'])
|
|
277
|
+
split_cadence = str(row['avg_cadence'])
|
|
278
|
+
avg_heart_rate_split = str(row['avg_heart_rate'])
|
|
279
|
+
max_heart_rate_split = str(row['max_heart_rate'])
|
|
280
|
+
dps = str(row['distance_per_stroke'])
|
|
281
|
+
lap_id = int(row['lap_id'])
|
|
282
|
+
|
|
283
|
+
workout_summary_string += (
|
|
284
|
+
f"{lap_id:02d}|{lap_distance:05d}|{split_time}|{split_pace}|{split_power}|"
|
|
285
|
+
f"{split_cadence}|{avg_heart_rate_split}|{max_heart_rate_split}|{dps}\n"
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
return workout_summary_string
|
|
289
|
+
|
|
290
|
+
# Example usage:
|
|
291
|
+
# Assuming your DataFrame is named 'rowing_data_df'
|
|
292
|
+
#summary_entire_workout = summarize_entire_workout(rowing_data_df)
|
|
293
|
+
#print(summary_entire_workout)
|