Skip to content

Instantly share code, notes, and snippets.

@LoganBarnett
Created November 15, 2019 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LoganBarnett/b949bef193e2a28389e3d1613cd85737 to your computer and use it in GitHub Desktop.
Save LoganBarnett/b949bef193e2a28389e3d1613cd85737 to your computer and use it in GitHub Desktop.
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