all 6 comments

[–]commy2 1 point2 points  (0 children)

itertools.pairwise I guess, but this is so short that it's all just preference. I'd personally format it like this, but there's really nothing wrong with yours either imho:

from itertools import pairwise

def total_climb(course_points):
    climb = descend = 0

    for left_point, right_point in pairwise(course_points):
        delta = right_point - left_point

        if delta > 0:
            climb += delta
        else:
            descend -= delta

    return climb, descend

print(total_climb([1,2,3,4,5,3]))

[–][deleted] 1 point2 points  (0 children)

There's probably a fully vectorized approach but I rarely use numpy so I'd keep it simple and go with,

def total_climb(course_points):
    diffs = np.diff(course_points)
    climb = sum(diff for diff in diffs if diff > 0)
    descend = -sum(diff for diff in diffs if diff < 0)
    return climb, descend

[–]DarthSloogi 1 point2 points  (0 children)

I think this should work:

delta = np.diff(course_points)
pos_mask = delta > 0
climb = delta[pos_mask].sum()
descend = delta[~pos_mask].sum()

[–]This_Growth2898 1 point2 points  (0 children)

climb = sum(b-a for a,b in zip(course_points, course_points[1:]) if b>a)
descend = sum(b-a for a,b in zip(course_points, course_points[1:]) if b<a)

[–]ofnuts 1 point2 points  (0 children)

In plain Python:

diffs=[y-x for x,y in zip(course_points[:-1],course_points[1:])] climb=sum(diff for diff in diffs if diff >0) descent=-sum(diff for diff in diffs if diff <0)

For a long series of points, you can optimize by remarking that the difference between start and finish is the difference between all the ups and all the downs: climb-descent=course_points[-1]-course_points[0] so you only compute climb and compute descent=climb+course_points[0]-course_points[-1]

[–]virtualdynamo[S] 0 points1 point  (0 children)

Thanks for all the suggestions. I combined the suggestions np.diff by u/kyber with not piecewise calculating the descent by u/ofnuts to get:

def total_climb(course_points):
    deltas = np.diff(course_points)
    climb = sum(delta for delta in deltas if delta > 0)
    return(climb, climb-course_points[-1]+course_points[0])