Created
November 15, 2019 21:36
-
-
Save LoganBarnett/b949bef193e2a28389e3d1613cd85737 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const R = require('ramda') | |
const fs = require('fs').promises | |
const headers = [ | |
'Device', | |
'Serial Number', | |
'Device Timestamp', | |
'Record Type', | |
'Historic Glucose mg/dL', | |
'Scan Glucose mg/dL', | |
'Non-numeric Rapid-Acting Insulin', | |
'Rapid-Acting Insulin (units)', | |
'Non-numeric Food', | |
'Carbohydrates (grams)', | |
'Carbohydrates (servings)', | |
'Non-numeric Long-Acting Insulin', | |
'Long-Acting Insulin (units)', | |
'Notes', | |
'Strip Glucose mg/dL', | |
'Ketone mmol/L', | |
'Meal Insulin (units)', | |
'Correction Insulin (units)', | |
'User Change Insulin (units)\r' | |
] | |
// Remove all but 4 entries per day - around 7am, 12pm, 5pm, 9pm. | |
// Needs to be random timestamps. | |
// Historic needs to be moved to strip column (prefer strip values). | |
// Remove all but strip and device timestamp columns. | |
const swap = R.curry((a, b, list) => R.move(b + (a > b ? 1 : -1), a, R.move(a, b, list))) | |
const sortByDate = R.sortBy(R.pipe( | |
R.nth(0), | |
R.invoker(0, 'valueOf'), | |
)) | |
fs.readFile('./input.csv').then(R.pipe( | |
R.toString, | |
R.split('\n'), | |
R.map( | |
R.split(','), | |
), | |
R.drop(2), // skip header rows | |
R.map(R.pipe( | |
R.converge( | |
R.unapply(R.identity), | |
[ | |
R.pipe( | |
R.nth(R.findIndex(R.equals('Device Timestamp'), headers)), | |
// constructN is needed because I think this fools currying with | |
// Date's many argument forms it takes. Ramda does not know when the | |
// function is saturated. | |
R.constructN(1, Date), | |
), | |
R.nth(R.findIndex(R.equals('Strip Glucose mg/dL'), headers)), | |
R.nth(R.findIndex(R.equals('Historic Glucose mg/dL'), headers)), | |
R.nth(R.findIndex(R.equals('Scan Glucose mg/dL'), headers)), | |
], | |
), | |
row => [ | |
row[0], | |
R.ifElse( | |
R.isEmpty, | |
R.always(R.ifElse( | |
R.isEmpty, | |
R.always(row[2]), | |
R.identity, | |
)(row[3])), | |
R.identity, | |
)(row[1]), | |
], | |
)), | |
R.filter(row => !R.isEmpty(row[1])), | |
sortByDate, | |
R.groupWith( | |
R.eqBy( | |
R.pipe( | |
R.nth(0), | |
R.converge(R.unapply(R.identity), [ | |
R.invoker(0, 'getFullYear'), | |
R.pipe(R.invoker(0, 'getMonth'), R.add(1)), | |
R.invoker(0, 'getDate'), | |
]), | |
), | |
), | |
), | |
R.map(R.pipe( | |
R.filter(R.pipe( | |
R.nth(0), | |
R.invoker(0, 'getHours'), | |
R.anyPass([ | |
R.both( | |
R.lte(5), | |
R.gte(9), | |
), | |
R.both( | |
R.lte(10), | |
R.gte(14), | |
), | |
R.both( | |
R.lte(15), | |
R.gte(18), | |
), | |
R.both( | |
R.lte(19), | |
R.gte(23), | |
), | |
]), | |
)), | |
R.groupWith( | |
R.eqBy(R.pipe( | |
R.nth(0), | |
R.invoker(0, 'getHours'), | |
R.cond([ | |
[R.both(R.lte(5), R.gte(9)), R.always(1)], | |
[R.both(R.lte(10), R.gte(14)), R.always(2)], | |
[R.both(R.lte(15), R.gte(18)), R.always(3)], | |
[R.both(R.lte(19), R.gte(23)), R.always(4)], | |
[R.T, R.always(5)], | |
]), | |
)), | |
), | |
R.map(R.pipe( | |
x => R.nth(parseInt(Math.random(0, x.length)), x), | |
)), | |
)), | |
R.unnest, | |
sortByDate, | |
R.map( | |
R.converge(R.unapply(R.identity), [ | |
R.pipe(R.nth(0), R.invoker(0, 'toLocaleString'), R.replace(',', '')), | |
R.nth(1), | |
]), | |
), | |
R.join('\n'), | |
R.tap(console.log), | |
)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment