Skip to content

Commit

Permalink
Merge pull request #8 from noizwaves/master
Browse files Browse the repository at this point in the history
Parse time values
  • Loading branch information
vkurup committed May 29, 2016
2 parents aa435e0 + 5ada658 commit f849492
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 28 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Data extracted:
- average altitude during workout
- ascent and descent of workout
- max and min altitude
- time stamp of each data point (in ISO UTC)

## Installation

Expand Down
44 changes: 24 additions & 20 deletions tcxparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@

namespace = 'http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2'


class TCXParser:

def __init__(self, tcx_file):
tree = objectify.parse(tcx_file)
self.root = tree.getroot()
self.activity = self.root.Activities.Activity

def hr_values(self):
return [int(x.text) for x in self.root.xpath('//ns:HeartRateBpm/ns:Value', namespaces={'ns': namespace})]

def altitude_points(self):
return [float(x.text) for x in self.root.xpath('//ns:AltitudeMeters', namespaces={'ns': namespace})]


def time_values(self):
return [x.text for x in self.root.xpath('//ns:Time', namespaces={'ns': namespace})]

@property
def latitude(self):
return self.activity.Lap.Track.Trackpoint.Position.LatitudeDegrees.pyval
Expand Down Expand Up @@ -50,65 +54,65 @@ def duration(self):
@property
def calories(self):
return sum(lap.Calories for lap in self.activity.Lap)

@property
def hr_avg(self):
"""Average heart rate of the workout"""
hr_data = self.hr_values()
return sum(hr_data)/len(hr_data)

@property
def hr_max(self):
"""Minimum heart rate of the workout"""
return max(self.hr_values())

@property
def hr_min(self):
"""Minimum heart rate of the workout"""
return min(self.hr_values())

@property
def pace(self):
"""Average pace (mm:ss/km for the workout"""
secs_per_km = self.duration/(self.distance/1000)
return time.strftime('%M:%S', time.gmtime(secs_per_km))

@property
def altitude_avg(self):
"""Average altitude for the workout"""
altitude_data = self.altitude_points()
return sum(altitude_data)/len(altitude_data)

@property
def altitude_max(self):
"""Max altitude for the workout"""
altitude_data = self.altitude_points()
return max(altitude_data)

@property
def altitude_min(self):
"""Min altitude for the workout"""
altitude_data = self.altitude_points()
return min(altitude_data)

@property
def ascent(self):
"""Returns ascent of workout in meters"""
total_ascent = 0.0
altitude_data = self.altitude_points()
for i in range(len(altitude_data) - 1):
diff = altitude_data[i+1] - altitude_data[i]
if diff > 0.0:
total_ascent += diff
diff = altitude_data[i+1] - altitude_data[i]
if diff > 0.0:
total_ascent += diff
return total_ascent
@property

@property
def descent(self):
"""Returns descent of workout in meters"""
total_descent = 0.0
total_descent = 0.0
altitude_data = self.altitude_points()
for i in range(len(altitude_data) - 1):
diff = altitude_data[i+1] - altitude_data[i]
if diff < 0.0:
total_descent += abs(diff)
return total_descent
diff = altitude_data[i+1] - altitude_data[i]
if diff < 0.0:
total_descent += abs(diff)
return total_descent
28 changes: 20 additions & 8 deletions test_tcxparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ def setUp(self):
tcx_file = 'test.tcx'
self.tcx = TCXParser(tcx_file)

def test_hr_values_are_correct(self):
self.assertEquals(self.tcx.hr_values()[0], 62)
self.assertEquals(self.tcx.hr_values()[-1], 180)

def test_altitude_points_are_correct(self):
self.assertEquals(self.tcx.altitude_points()[0], 178.942626953)
self.assertEquals(self.tcx.altitude_points()[-1], 166.4453125)

def test_time_values_are_correct(self):
self.assertEquals(self.tcx.time_values()[0], '2012-12-26T21:29:53Z')
self.assertEquals(self.tcx.time_values()[-1], '2012-12-26T22:03:05Z')

def test_latitude_is_correct(self):
self.assertEquals(self.tcx.latitude, 35.951880198)

Expand All @@ -31,7 +43,7 @@ def test_duration_is_correct(self):

def test_calories_is_correct(self):
self.assertEquals(self.tcx.calories, 379)

def test_hr_max(self):
self.assertEquals(self.tcx.hr_max, 189)

Expand All @@ -40,24 +52,24 @@ def test_hr_min(self):

def test_hr_avg(self):
self.assertEquals(self.tcx.hr_avg, 156)

def test_pace(self):
self.assertEquals(self.tcx.pace, '07:05')

def test_altitude_avg_is_correct(self):
self.assertAlmostEqual(self.tcx.altitude_avg, 172.020056184)

def test_altitude_max_is_correct(self):
self.assertAlmostEqual(self.tcx.altitude_max, 215.95324707)

def test_altitude_min_is_correct(self):
self.assertAlmostEqual(self.tcx.altitude_min, 157.793579102)

def test_ascent_is_correct(self):
self.assertAlmostEqual(self.tcx.ascent, 153.80981445)

def test_descent_is_correct(self):
self.assertAlmostEqual(self.tcx.descent, 166.307128903)

if __name__ == '__main__':
unittest.main()

0 comments on commit f849492

Please sign in to comment.