Skip to content

Instantly share code, notes, and snippets.

@zhammer
Created March 29, 2018 21:32
Show Gist options
  • Save zhammer/0679016dca7e89352b23dd289a87c524 to your computer and use it in GitHub Desktop.
Save zhammer/0679016dca7e89352b23dd289a87c524 to your computer and use it in GitHub Desktop.
# I only have such long documentation on consecutive_date_ranges to run doctest.
from collections import namedtuple
DateRange = namedtuple('DateRange', 'start end length')
def is_after(lhs, rhs):
return lhs == rhs + 1
def consecutive_date_ranges(dates):
"""Given a list of dates, output a list of ranges of consecutive dates in the input.
>>> consecutive_date_ranges([])
[]
>>> consecutive_date_ranges([8])
[DateRange(start=8, end=8, length=0)]
>>> consecutive_date_ranges([1, 4, 2, 7, 9, 8])
[DateRange(start=1, end=2, length=1), DateRange(start=4, end=4, length=0), DateRange(start=7, end=9, length=2)]
>>> consecutive_date_ranges([1, 4, 7, 9, 8])
[DateRange(start=1, end=1, length=0), DateRange(start=4, end=4, length=0), DateRange(start=7, end=9, length=2)]
>>> consecutive_date_ranges([1, 4, 2, 11])
[DateRange(start=1, end=2, length=1), DateRange(start=4, end=4, length=0), DateRange(start=11, end=11, length=0)]
>>> consecutive_date_ranges([1, 2, 3, 4, 5])
[DateRange(start=1, end=5, length=4)]
"""
dates = sorted(dates)
range_starts = [date for i, date in enumerate(dates)
if i == 0 or not is_after(date, dates[i - 1])]
range_ends = [date for i, date in enumerate(dates)
if i == len(dates) - 1 or not is_after(dates[i + 1], date)]
return [DateRange(start, end, end - start)
for start, end in zip(range_starts, range_ends)]
@evanhammer
Copy link

Don't know why I got in such a Ramda pipe: https://repl.it/repls/SplendidYellowishGlitch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment