A weather station sends an endless feed of hourly readings (day, hour, temperature). The feed is in time order: all readings of day 1, then all of day 2, and so on. Some hours are missing, and a temperature of None marks a sensor dropout.
Write a generator function daily_peaks(readings) that yields one summary per day, in order, as soon as that day is complete: (day, valid, peak, peak_hour), where valid is the number of readings of the day that are not None, peak is the highest temperature of the day and peak_hour the earliest hour at which it was measured. A day whose readings are all None gives (day, 0, None, None). Days that do not appear in the feed at all are skipped.
The feed never ends, so daily_peaks cannot collect it first; the tests take the first few summaries with first(gen, n). Other helpers you can use with Run: stream(items) (hands out a list as a one-pass feed) and endless_log(seed) (a generated station).
Examples
Input: first(daily_peaks(stream([(1, 0, 3.5), (1, 5, 7.25), (1, 9, 7.25), (1, 13, None), (2, 3, None), (4, 1, -2.0)])), 5)
Output: [(1, 3, 7.25, 5), (2, 0, None, None), (4, 1, -2.0, 1)]
Input: first(daily_peaks(endless_log(1)), 2)
Output: [(1, 20, 12.1, 16), (2, 19, 21.7, 14)]
Constraints
- Days are positive integers and never decrease along the feed; hours go from 0 to 23.
- Nothing depends on the clock.
Goals
- Group consecutive items of a stream with `itertools.groupby` and a key function
- Summarise each group in one pass over its items, without making a list of the whole stream
- Turn a function over an endless stream into a generator that yields one summary per group