A bicycle courier logs every delivery as a distance in kilometres and a time in minutes. The dispatcher wants a rule of the form
minutes = a + b * km
that is as close as possible to the logged deliveries, in the sense that the sum of the squared differences between the logged minutes and the rule's minutes is as small as possible. No other pair (a, b) may give a smaller sum.
Write delivery_line(km, minutes, new_km) that returns a tuple (a, b, predictions), where predictions is the list of the rule's minutes for each distance in new_km, in order. If all the logged distances are equal, no single line is best: return None.
The setup provides courier_log(n, seed), which returns random lists (km, minutes) of n deliveries.
Examples
Input: km = [1, 2, 3, 4], minutes = [6, 9, 10, 15], new_km = [0, 5]
Output: (3.0, 2.8, [3.0, 17.0])
Explanation: the best line is minutes = 3 + 2.8 * km: about 2.8 minutes for each
kilometre, plus 3 minutes to pick up and hand over. For 5 km it predicts 17 minutes.
Input: km = [3, 3, 3], minutes = [10, 12, 14], new_km = [3]
Output: None
Constraints
2 <= len(km) == len(minutes) <= 10**5,0 <= len(new_km) <= 1000- values are integers or floats between
0and10**4 - floats are compared with a tolerance of
1e-6
Goals
- Fit the straight line with the smallest sum of squared residuals
- Compute the slope from the covariance and the variance, and the intercept from the means
- Use the line to predict new values