Handle short workouts when calculating normalized intensity
This commit is contained in:
parent
77c6a721d4
commit
adebc3d460
|
|
@ -0,0 +1,75 @@
|
|||
import { Interval } from "../ast";
|
||||
import { Duration } from "../Duration";
|
||||
import { ConstantIntensity, RangeIntensity } from "../Intensity";
|
||||
import { normalizedIntensity } from "./normalizedIntensity";
|
||||
|
||||
const round = (intensity: ConstantIntensity) => Math.round(intensity.value * 100) / 100;
|
||||
|
||||
describe("normalizedIntensity()", () => {
|
||||
it("when no intervals, returns 0 for all zones", () => {
|
||||
expect(round(normalizedIntensity([]))).toEqual(0);
|
||||
});
|
||||
|
||||
it("returns plain average for < 30-seconds workout", () => {
|
||||
expect(
|
||||
round(
|
||||
normalizedIntensity([
|
||||
{
|
||||
type: "Interval",
|
||||
duration: new Duration(10),
|
||||
intensity: new ConstantIntensity(0.5),
|
||||
comments: [],
|
||||
},
|
||||
{
|
||||
type: "Interval",
|
||||
duration: new Duration(10),
|
||||
intensity: new ConstantIntensity(0.7),
|
||||
comments: [],
|
||||
},
|
||||
]),
|
||||
),
|
||||
).toEqual(0.6);
|
||||
});
|
||||
|
||||
it("is the intensity of an interval for single-interval workout", () => {
|
||||
const intervals: Interval[] = [
|
||||
{
|
||||
type: "Interval",
|
||||
duration: new Duration(20 * 60),
|
||||
intensity: new ConstantIntensity(0.75),
|
||||
comments: [],
|
||||
},
|
||||
];
|
||||
expect(round(normalizedIntensity(intervals))).toEqual(0.75);
|
||||
});
|
||||
|
||||
it("leans towards higher intensity for two-interval workout", () => {
|
||||
const intervals: Interval[] = [
|
||||
{
|
||||
type: "Interval",
|
||||
duration: new Duration(10 * 60),
|
||||
intensity: new ConstantIntensity(0.5),
|
||||
comments: [],
|
||||
},
|
||||
{
|
||||
type: "Interval",
|
||||
duration: new Duration(10 * 60),
|
||||
intensity: new ConstantIntensity(1.0),
|
||||
comments: [],
|
||||
},
|
||||
];
|
||||
expect(round(normalizedIntensity(intervals))).toEqual(0.85);
|
||||
});
|
||||
|
||||
it("handles range-intensities", () => {
|
||||
const intervals: Interval[] = [
|
||||
{
|
||||
type: "Warmup",
|
||||
duration: new Duration(20 * 60),
|
||||
intensity: new RangeIntensity(0.5, 1.0),
|
||||
comments: [],
|
||||
},
|
||||
];
|
||||
expect(round(normalizedIntensity(intervals))).toEqual(0.79);
|
||||
});
|
||||
});
|
||||
|
|
@ -7,11 +7,16 @@ import { intervalsToIntensityNumbers } from "./intervalsToIntensityNumbers";
|
|||
// Starting at the beginning of the data, calculate 30-second rolling average
|
||||
const windowSize = 30; // equals to nr of seconds, but also to nr of entries in intensities array
|
||||
const rollingAverages = (intensities: number[]): number[] => {
|
||||
if (intensities.length < windowSize) {
|
||||
throw new Error(`Workout must be at least ${windowSize} seconds long`);
|
||||
}
|
||||
const averages: number[] = [];
|
||||
let rollingSum: number = sum(intensities.slice(0, windowSize));
|
||||
|
||||
if (intensities.length === 0) {
|
||||
return [0];
|
||||
}
|
||||
if (intensities.length < windowSize) {
|
||||
return [rollingSum / intensities.length];
|
||||
}
|
||||
|
||||
const averages: number[] = [];
|
||||
averages.push(rollingSum / windowSize);
|
||||
for (let i = 0; i < intensities.length - windowSize; i++) {
|
||||
rollingSum -= intensities[i];
|
||||
|
|
|
|||
Loading…
Reference in New Issue