This repository was archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathcumulative-deliveries.js
96 lines (88 loc) · 3.11 KB
/
cumulative-deliveries.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
const {vaccineLabels} = require('./known-vaccines.js');
const {addDays, readCsvFile, sortMapEntriesByKey} = require('./utils.js');
const getCumulativeDeliveries = ({ startDate, endDate }) => {
const deliveries = readCsvFile('./data/deliveries.csv');
const cumulativeTotalPerVaccine = {};
for (const label of vaccineLabels) {
cumulativeTotalPerVaccine[label] = 0;
}
const map = new Map(); // date => Map<state, cumulativeDeliveries>
const currentCounts = new Map(); // state => currentCumulativeCount
const currentNationalCountsPerVaccine = new Map(); // date => vaccineLabel => currentCumulativeCount
let latestDate = '1970-01-01';
for (const {date, state, type, doses: _doses} of deliveries) {
const doses = Number(_doses);
cumulativeTotalPerVaccine[type] += doses;
const currentCount = (currentCounts.get(state) ?? 0) + doses;
currentCounts.set(state, currentCount);
if (map.has(date)) {
map.get(date).set(state, currentCount);
} else {
map.set(date, new Map([
[state, currentCount],
]));
}
if (currentNationalCountsPerVaccine.has(date)) {
currentNationalCountsPerVaccine.get(date).set(type, cumulativeTotalPerVaccine[type]);
} else {
currentNationalCountsPerVaccine.set(
date,
new Map(Object.entries(cumulativeTotalPerVaccine))
);
}
if (date > latestDate) {
latestDate = date;
}
}
// Fill the gaps in the data. (Missing days, usually over the weekend.)
// Handle `map`.
let lastEntries = map[Symbol.iterator]().next().value[1];
for (let date = startDate; date <= endDate; date = addDays(date, 1)) {
if (map.has(date)) {
const entries = map.get(date);
// We’re expecting 18 entries: 16 states + Bund + Companies.
if (entries.size !== 18) {
// Add missing states, if any.
for (const [k, v] of lastEntries) {
if (!entries.has(k)) {
entries.set(k, v);
}
}
}
lastEntries = entries;
continue;
} else {
map.set(date, new Map(lastEntries));
}
}
// Handle `currentNationalCountsPerVaccine`.
let lastEntriesNational;
for (let date = startDate; date <= endDate; date = addDays(date, 1)) {
if (currentNationalCountsPerVaccine.has(date)) {
const entries = currentNationalCountsPerVaccine.get(date);
lastEntriesNational = entries;
continue;
} else {
currentNationalCountsPerVaccine.set(date, new Map(lastEntriesNational));
}
}
// Add national totals.
let max = 0;
for (const entry of map.values()) {
let sum = 0;
for (const number of entry.values()) {
sum += number;
}
entry.set('Total', sum);
if (sum > max) max = sum;
}
const sortedMap = sortMapEntriesByKey(map);
const cumulativeNationalDosesDeliveredPerVaccine = sortMapEntriesByKey(currentNationalCountsPerVaccine);
return {
cumulativeDeliveryMap: sortedMap,
latestDeliveryDate: latestDate,
cumulativeNationalDosesDelivered: max,
cumulativeNationalDosesDeliveredPerVaccine: cumulativeNationalDosesDeliveredPerVaccine,
};
};
module.exports = getCumulativeDeliveries;