Created
January 28, 2019 23:02
-
-
Save bogkyu/d38ac810eeee7ecb52d0072f3b0dfcbb to your computer and use it in GitHub Desktop.
JS Bin // source https://jsbin.com/wihuhoc
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<script id="jsbin-javascript"> | |
//KJS HA5 | |
// function generator, returns list of | |
// boolean (check ok) and | |
// string (current type, used if boolean were false) | |
'use strict'; | |
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); | |
var checktemplate = function checktemplate(ss) { | |
return function (v) { | |
return [typeof v == ss, typeof v, ss]; | |
}; | |
}; | |
var checkNumber = checktemplate('number'); // doesn't sense Nan-s | |
var checkString = checktemplate('string'); | |
/* | |
// TEST BED #1 see results from checking types | |
[ | |
'string', 4, {}, '', undefined, NaN, true, [], | |
].forEach(x => { | |
console.log(x + ': ' + checkString(x)); | |
console.log(x + ': ' + checkString(x)); | |
}); | |
*/ | |
// declared order is important, strictly from largest to smallest | |
var VALID_UNITS = ["day", "hour", "minute", "second"]; | |
// pure fun :) | |
function checkPlurals(val, lab) { | |
var startstop = ['^', '$']; | |
var grouping = ['(', ')']; | |
var re = new RegExp(startstop.join(grouping.join(VALID_UNITS.join("|")) + (Math.abs(val) == 1 ? "" : "s"))); | |
return re.exec(lab) == null ? [val, lab] : null; | |
} | |
/* | |
// TEST BED #2 see results from checking types | |
[ | |
[3, 'minutes'], | |
[1, 'year'], | |
[1, 'second'], | |
[44, 'hours'], | |
[44, 'hour'], | |
].forEach(([x, s]) => { | |
console.log(x + ' ' + s + ": " + (checkPlurals(x, s) == null ? "OK" : "FAILED")); | |
}); | |
*/ | |
function checkTypes(val1, lab1, val2, lab2) { | |
var error = ''; | |
[[val1, checkNumber], [lab1, checkString], [val2, checkNumber], [lab2, checkString]].forEach(function (_ref) { | |
var _ref2 = _slicedToArray(_ref, 2); | |
var v = _ref2[0]; | |
var f = _ref2[1]; | |
var _f = f(v); | |
var _f2 = _slicedToArray(_f, 3); | |
var isOk = _f2[0]; | |
var actualType = _f2[1]; | |
var requiredType = _f2[2]; | |
if (!isOk) { | |
error += (error ? '\n' : '') + ' wrong type for value: ' + v + ', found ' + actualType + ', required ' + requiredType; | |
} | |
return error; | |
}); | |
} | |
/* | |
// TEST BED #3 checkTypes | |
[ | |
[[3, 'seconds', 5, 'minutes'], true], | |
[[4555, 'second', 423, 'sedconde'], true], | |
[[{}, 'seconds', 5, null], false], | |
[[3,4,5,6], false], | |
[['3','4','5','6'], false], | |
].forEach(([params, rightResult]) => { | |
const [ v1, l1, v2, l2] = params; | |
const realResult = checkTypes(v1, l1, v2, l2) == null ; | |
console.log((realResult === rightResult ? "OK " : "FAILED" ) + ' testing value set:' + JSON.stringify(params)); | |
}); | |
*/ | |
// HA5 Time adder. | |
// Takes four mandatory parameters, grouped by pairs of time | |
// descrpitors to be added, explained as below: | |
// val1, val2 - the amounts of time | |
// lab1, lab2 - the time units | |
// time unit should be one of the following strings: | |
// "seconds", "minutes", "hours", "days", "second", "minute", "hour", "day" | |
// return value is the time we got by adding the two parameters, maintaining | |
// or false if wrong parameters | |
// extra credit for returning the largest label that can be used with | |
// an integer value | |
function timeAdder(val1, lab1, val2, lab2) { | |
var retval = false; | |
var error = checkTypes(val1, lab1, val2, lab2) || checkPlurals(val1, lab1) || checkPlurals(val2, lab2); | |
if (!error) { | |
// calculus and result | |
var time1 = normalize(val1, lab1); | |
var time2 = normalize(val2, lab2); | |
var timef = time1 + time2; | |
for (x in VALID_UNITS) { | |
var unit = VALID_UNITS[x]; | |
var mult = multiplier(VALID_UNITS[x]); | |
if (timef % mult === 0) { | |
var newval = timef / multiplier(unit); | |
retval = [newval, unit + (Math.abs(newval) === 1 ? "" : "s")]; | |
break; | |
} | |
} | |
} else { | |
console.log("Error: unexpected or incorrect parameters: " + error); | |
} | |
return retval; | |
} | |
// get the normalized (_in seconds_) time value | |
function normalize(val, lab) { | |
return val * multiplier(lab); | |
} | |
// returns the multiplier to seconds | |
// Pirple require a switch statement | |
// otherwise I would have implemented the functionality | |
// augmenting the VALID_UNITS | |
function multiplier(lab) { | |
switch (lab) { | |
case 'day': | |
case 'days': | |
return 60 * 60 * 24; | |
case 'hour': | |
case 'hours': | |
return 60 * 60; | |
case 'minute': | |
case 'minutes': | |
return 60; | |
// assumes default seconds | |
default: | |
return 1; | |
} | |
} | |
// TEST BED #4 | |
[[[23, 'minutes', 1, 'minute'], [24, 'minutes']], [[23, 'hours', 1, 'hour'], [1, 'day']], [[59, 'minutes', 2, 'minutes'], [61, 'minutes']], [[59, 'minutes', 2, 'seconds'], [3542, 'seconds']], [[3, 'days', 1, 'hour'], [73, 'hours']], [[0, 'hours', 0, 'hours'], [0, 'days']], [[23, 'seconds', -1, 'minute'], [-37, 'seconds']], [[23, 'second', -1, 'minute'], [-37, 'seconds']], // illustrates a failed test | |
[[23, {}, -1, 'minute'], [-37, 'seconds']]]. // illustrates a failed test | |
forEach(function (_ref3) { | |
var _ref32 = _slicedToArray(_ref3, 2); | |
var param = _ref32[0]; | |
var expectedResult = _ref32[1]; | |
function formatOutput(result, val1, lab1, val2, lab2, valf, labf) { | |
var eqop = result ? '===' : '!=='; | |
return val1 + ' ' + lab1 + ' + ' + val2 + ' ' + lab2 + ' ' + eqop + ' ' + valf + ' ' + labf; | |
} | |
var _param = _slicedToArray(param, 4); | |
var val1 = _param[0]; | |
var lab1 = _param[1]; | |
var val2 = _param[2]; | |
var lab2 = _param[3]; | |
var actualResult = timeAdder(val1, lab1, val2, lab2); | |
if (actualResult) { | |
var _actualResult = _slicedToArray(actualResult, 2); | |
var actval = _actualResult[0]; | |
var actlab = _actualResult[1]; | |
var _expectedResult = _slicedToArray(expectedResult, 2); | |
var expval = _expectedResult[0]; | |
var explab = _expectedResult[1]; | |
var testOK = actval === expval && actlab == explab; | |
console.log("TEST " + (testOK ? 'OK: ' : 'FAILED:') + formatOutput(true, val1, lab1, val2, lab2, expval, explab)); | |
} else { | |
console.log("TEST FAILED: incorrect input values"); | |
} | |
}); | |
</script> | |
<script id="jsbin-source-javascript" type="text/javascript">//KJS HA5 | |
// function generator, returns list of | |
// boolean (check ok) and | |
// string (current type, used if boolean were false) | |
let checktemplate = ss => (v) => [typeof v == ss, typeof v, ss]; | |
let checkNumber = checktemplate('number'); // doesn't sense Nan-s | |
let checkString = checktemplate('string'); | |
/* | |
// TEST BED #1 see results from checking types | |
[ | |
'string', 4, {}, '', undefined, NaN, true, [], | |
].forEach(x => { | |
console.log(x + ': ' + checkString(x)); | |
console.log(x + ': ' + checkString(x)); | |
}); | |
*/ | |
// declared order is important, strictly from largest to smallest | |
const VALID_UNITS = [ | |
"day", | |
"hour", | |
"minute", | |
"second", | |
]; | |
// pure fun :) | |
function checkPlurals(val, lab) { | |
const startstop = ['^', '$']; | |
const grouping = ['(', ')']; | |
const re = new RegExp( | |
startstop.join( | |
grouping.join( | |
VALID_UNITS.join("|") | |
) | |
+ (Math.abs(val) == 1 ? "" : "s") | |
) | |
); | |
return re.exec(lab) == null ? [val, lab] : null; | |
} | |
/* | |
// TEST BED #2 see results from checking types | |
[ | |
[3, 'minutes'], | |
[1, 'year'], | |
[1, 'second'], | |
[44, 'hours'], | |
[44, 'hour'], | |
].forEach(([x, s]) => { | |
console.log(x + ' ' + s + ": " + (checkPlurals(x, s) == null ? "OK" : "FAILED")); | |
}); | |
*/ | |
function checkTypes(val1, lab1, val2, lab2) { | |
let error = '' ; | |
[[val1, checkNumber], | |
[lab1, checkString], | |
[val2, checkNumber], | |
[lab2, checkString], | |
].forEach(([v, f]) => { | |
const [isOk, actualType, requiredType] = f(v); | |
if( ! isOk ) { | |
error += (error ? '\n' : '' ) | |
+ ' wrong type for value: ' + v | |
+ ', found ' + actualType | |
+ ', required ' + requiredType; | |
} | |
return error; | |
}); | |
} | |
/* | |
// TEST BED #3 checkTypes | |
[ | |
[[3, 'seconds', 5, 'minutes'], true], | |
[[4555, 'second', 423, 'sedconde'], true], | |
[[{}, 'seconds', 5, null], false], | |
[[3,4,5,6], false], | |
[['3','4','5','6'], false], | |
].forEach(([params, rightResult]) => { | |
const [ v1, l1, v2, l2] = params; | |
const realResult = checkTypes(v1, l1, v2, l2) == null ; | |
console.log((realResult === rightResult ? "OK " : "FAILED" ) + ' testing value set:' + JSON.stringify(params)); | |
}); | |
*/ | |
// HA5 Time adder. | |
// Takes four mandatory parameters, grouped by pairs of time | |
// descrpitors to be added, explained as below: | |
// val1, val2 - the amounts of time | |
// lab1, lab2 - the time units | |
// time unit should be one of the following strings: | |
// "seconds", "minutes", "hours", "days", "second", "minute", "hour", "day" | |
// return value is the time we got by adding the two parameters, maintaining | |
// or false if wrong parameters | |
// extra credit for returning the largest label that can be used with | |
// an integer value | |
function timeAdder(val1, lab1, val2, lab2){ | |
let retval = false; | |
let error = | |
checkTypes(val1, lab1, val2, lab2) | |
|| checkPlurals(val1, lab1) | |
|| checkPlurals(val2, lab2) ; | |
if( !error ) { | |
// calculus and result | |
let time1 = normalize(val1, lab1); | |
let time2 = normalize(val2, lab2); | |
let timef = time1 + time2; | |
for( x in VALID_UNITS) { | |
let [unit, mult] = [VALID_UNITS[x], multiplier(VALID_UNITS[x])] ; | |
if( timef % mult === 0 ) { | |
const newval = timef / multiplier(unit); | |
retval = [newval, unit + (Math.abs(newval) === 1 ? "" : "s") ]; | |
break; | |
} | |
} | |
} else { | |
console.log("Error: unexpected or incorrect parameters: " + error); | |
} | |
return retval; | |
} | |
// get the normalized (_in seconds_) time value | |
function normalize(val, lab) { | |
return val * multiplier(lab); | |
} | |
// returns the multiplier to seconds | |
// Pirple require a switch statement | |
// otherwise I would have implemented the functionality | |
// augmenting the VALID_UNITS | |
function multiplier(lab) { | |
switch(lab) { | |
case 'day': | |
case 'days': | |
return 60 * 60 * 24 ; | |
case 'hour': | |
case 'hours': | |
return 60 * 60; | |
case 'minute': | |
case 'minutes': | |
return 60; | |
// assumes default seconds | |
default: | |
return 1; | |
} | |
} | |
// TEST BED #4 | |
[ | |
[[23, 'minutes', 1, 'minute'], [24, 'minutes']], | |
[[23, 'hours', 1, 'hour' ], [ 1, 'day']], | |
[[59, 'minutes', 2, 'minutes'], [61, 'minutes']], | |
[[59, 'minutes', 2, 'seconds'], [3542, 'seconds']], | |
[[ 3, 'days', 1, 'hour'], [73, 'hours']], | |
[[ 0, 'hours', 0, 'hours'], [0, 'days']], | |
[[23, 'seconds',-1, 'minute'], [-37, 'seconds']], | |
[[23, 'second',-1, 'minute'], [-37, 'seconds']], // illustrates a failed test | |
[[23, {}, -1, 'minute'], [-37, 'seconds']], // illustrates a failed test | |
].forEach( ([param, expectedResult]) => { | |
function formatOutput(result, val1, lab1, val2, lab2, valf, labf) { | |
const eqop = result ? '===' : '!=='; | |
return val1 + ' ' + lab1 | |
+ ' + ' + val2 + ' ' + lab2 | |
+ ' ' + eqop | |
+ ' ' + valf + ' ' + labf; | |
} | |
const [val1, lab1, val2, lab2] = param; | |
const actualResult = timeAdder(val1, lab1, val2, lab2); | |
if( actualResult ) { | |
const [actval, actlab] = actualResult; | |
const [expval, explab] = expectedResult; | |
const testOK = actval === expval && actlab == explab; | |
console.log("TEST " + (testOK ? 'OK: ' : 'FAILED:') | |
+ formatOutput(true, val1, lab1, val2, lab2, expval, explab) ); | |
} else { | |
console.log("TEST FAILED: incorrect input values"); | |
} | |
}); | |
</script></body> | |
</html> |
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
//KJS HA5 | |
// function generator, returns list of | |
// boolean (check ok) and | |
// string (current type, used if boolean were false) | |
'use strict'; | |
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); | |
var checktemplate = function checktemplate(ss) { | |
return function (v) { | |
return [typeof v == ss, typeof v, ss]; | |
}; | |
}; | |
var checkNumber = checktemplate('number'); // doesn't sense Nan-s | |
var checkString = checktemplate('string'); | |
/* | |
// TEST BED #1 see results from checking types | |
[ | |
'string', 4, {}, '', undefined, NaN, true, [], | |
].forEach(x => { | |
console.log(x + ': ' + checkString(x)); | |
console.log(x + ': ' + checkString(x)); | |
}); | |
*/ | |
// declared order is important, strictly from largest to smallest | |
var VALID_UNITS = ["day", "hour", "minute", "second"]; | |
// pure fun :) | |
function checkPlurals(val, lab) { | |
var startstop = ['^', '$']; | |
var grouping = ['(', ')']; | |
var re = new RegExp(startstop.join(grouping.join(VALID_UNITS.join("|")) + (Math.abs(val) == 1 ? "" : "s"))); | |
return re.exec(lab) == null ? [val, lab] : null; | |
} | |
/* | |
// TEST BED #2 see results from checking types | |
[ | |
[3, 'minutes'], | |
[1, 'year'], | |
[1, 'second'], | |
[44, 'hours'], | |
[44, 'hour'], | |
].forEach(([x, s]) => { | |
console.log(x + ' ' + s + ": " + (checkPlurals(x, s) == null ? "OK" : "FAILED")); | |
}); | |
*/ | |
function checkTypes(val1, lab1, val2, lab2) { | |
var error = ''; | |
[[val1, checkNumber], [lab1, checkString], [val2, checkNumber], [lab2, checkString]].forEach(function (_ref) { | |
var _ref2 = _slicedToArray(_ref, 2); | |
var v = _ref2[0]; | |
var f = _ref2[1]; | |
var _f = f(v); | |
var _f2 = _slicedToArray(_f, 3); | |
var isOk = _f2[0]; | |
var actualType = _f2[1]; | |
var requiredType = _f2[2]; | |
if (!isOk) { | |
error += (error ? '\n' : '') + ' wrong type for value: ' + v + ', found ' + actualType + ', required ' + requiredType; | |
} | |
return error; | |
}); | |
} | |
/* | |
// TEST BED #3 checkTypes | |
[ | |
[[3, 'seconds', 5, 'minutes'], true], | |
[[4555, 'second', 423, 'sedconde'], true], | |
[[{}, 'seconds', 5, null], false], | |
[[3,4,5,6], false], | |
[['3','4','5','6'], false], | |
].forEach(([params, rightResult]) => { | |
const [ v1, l1, v2, l2] = params; | |
const realResult = checkTypes(v1, l1, v2, l2) == null ; | |
console.log((realResult === rightResult ? "OK " : "FAILED" ) + ' testing value set:' + JSON.stringify(params)); | |
}); | |
*/ | |
// HA5 Time adder. | |
// Takes four mandatory parameters, grouped by pairs of time | |
// descrpitors to be added, explained as below: | |
// val1, val2 - the amounts of time | |
// lab1, lab2 - the time units | |
// time unit should be one of the following strings: | |
// "seconds", "minutes", "hours", "days", "second", "minute", "hour", "day" | |
// return value is the time we got by adding the two parameters, maintaining | |
// or false if wrong parameters | |
// extra credit for returning the largest label that can be used with | |
// an integer value | |
function timeAdder(val1, lab1, val2, lab2) { | |
var retval = false; | |
var error = checkTypes(val1, lab1, val2, lab2) || checkPlurals(val1, lab1) || checkPlurals(val2, lab2); | |
if (!error) { | |
// calculus and result | |
var time1 = normalize(val1, lab1); | |
var time2 = normalize(val2, lab2); | |
var timef = time1 + time2; | |
for (x in VALID_UNITS) { | |
var unit = VALID_UNITS[x]; | |
var mult = multiplier(VALID_UNITS[x]); | |
if (timef % mult === 0) { | |
var newval = timef / multiplier(unit); | |
retval = [newval, unit + (Math.abs(newval) === 1 ? "" : "s")]; | |
break; | |
} | |
} | |
} else { | |
console.log("Error: unexpected or incorrect parameters: " + error); | |
} | |
return retval; | |
} | |
// get the normalized (_in seconds_) time value | |
function normalize(val, lab) { | |
return val * multiplier(lab); | |
} | |
// returns the multiplier to seconds | |
// Pirple require a switch statement | |
// otherwise I would have implemented the functionality | |
// augmenting the VALID_UNITS | |
function multiplier(lab) { | |
switch (lab) { | |
case 'day': | |
case 'days': | |
return 60 * 60 * 24; | |
case 'hour': | |
case 'hours': | |
return 60 * 60; | |
case 'minute': | |
case 'minutes': | |
return 60; | |
// assumes default seconds | |
default: | |
return 1; | |
} | |
} | |
// TEST BED #4 | |
[[[23, 'minutes', 1, 'minute'], [24, 'minutes']], [[23, 'hours', 1, 'hour'], [1, 'day']], [[59, 'minutes', 2, 'minutes'], [61, 'minutes']], [[59, 'minutes', 2, 'seconds'], [3542, 'seconds']], [[3, 'days', 1, 'hour'], [73, 'hours']], [[0, 'hours', 0, 'hours'], [0, 'days']], [[23, 'seconds', -1, 'minute'], [-37, 'seconds']], [[23, 'second', -1, 'minute'], [-37, 'seconds']], // illustrates a failed test | |
[[23, {}, -1, 'minute'], [-37, 'seconds']]]. // illustrates a failed test | |
forEach(function (_ref3) { | |
var _ref32 = _slicedToArray(_ref3, 2); | |
var param = _ref32[0]; | |
var expectedResult = _ref32[1]; | |
function formatOutput(result, val1, lab1, val2, lab2, valf, labf) { | |
var eqop = result ? '===' : '!=='; | |
return val1 + ' ' + lab1 + ' + ' + val2 + ' ' + lab2 + ' ' + eqop + ' ' + valf + ' ' + labf; | |
} | |
var _param = _slicedToArray(param, 4); | |
var val1 = _param[0]; | |
var lab1 = _param[1]; | |
var val2 = _param[2]; | |
var lab2 = _param[3]; | |
var actualResult = timeAdder(val1, lab1, val2, lab2); | |
if (actualResult) { | |
var _actualResult = _slicedToArray(actualResult, 2); | |
var actval = _actualResult[0]; | |
var actlab = _actualResult[1]; | |
var _expectedResult = _slicedToArray(expectedResult, 2); | |
var expval = _expectedResult[0]; | |
var explab = _expectedResult[1]; | |
var testOK = actval === expval && actlab == explab; | |
console.log("TEST " + (testOK ? 'OK: ' : 'FAILED:') + formatOutput(true, val1, lab1, val2, lab2, expval, explab)); | |
} else { | |
console.log("TEST FAILED: incorrect input values"); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment