@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
253 lines (223 loc) • 5.05 kB
JavaScript
/*
TODO: Update mathjs to newer version that exports as ES modules.
*/
import combinations from 'mathjs/lib/function/probability/combinations'
import cot from 'mathjs/lib/function/trigonometry/cot'
import csc from 'mathjs/lib/function/trigonometry/csc'
import divide from 'mathjs/lib/function/arithmetic/divide'
import factorial from 'mathjs/lib/function/probability/factorial'
import log from 'mathjs/lib/function/arithmetic/log'
import log10 from 'mathjs/lib/function/arithmetic/log10'
import permutations from 'mathjs/lib/function/probability/permutations'
import random from 'mathjs/lib/function/probability/random'
import Decimal from 'decimal.js'
/* TRIGONOMETRY */
function cosecFactory(type, config, load, typed) {
return load(csc)
}
function cotanFactory(type, config, load, typed) {
return load(cot)
}
function degToRadFactory(type, config, load, typed) {
return typed('deg_to_rad', {
number: x => x * (Math.PI / 180),
})
}
function radToDegFactory(type, config, load, typed) {
return typed('rad_to_deg', {
number: x => x * (180 / Math.PI),
})
}
/* PROBABILITY */
function combFactory(type, config, load, typed) {
const combinationsL = load(combinations)
return typed('fact', {
'number, number': (n, k) => {
if (n >= 0 && k >= 0 && n >= k) {
return combinationsL(n, k)
} else {
return NaN
}
},
})
}
function permFactory(type, config, load, typed) {
const permutationsL = load(permutations)
return typed('fact', {
'number, number': (n, k) => {
if (n >= 0 && k >= 0 && n >= k) {
return permutationsL(n, k)
} else {
return NaN
}
},
})
}
function factFactory(type, config, load, typed) {
const factorialL = load(factorial)
return typed('fact', {
number: x => {
if (x >= 0) {
return factorialL(x)
} else {
return NaN
}
},
})
}
function randFactory(type, config, load, typed) {
return load(random)
}
/* LIST FUNCTIONS */
function atFactory(type, config, load, typed) {
return typed('at', {
'Array, number': (arr, i) => {
return i >= 0 && i < arr.length ? arr[i] : NaN
},
'...number': args => {
const i = args[args.length - 1]
return i >= 0 && i < args.length - 1 ? args[i] : NaN
},
})
}
function firstFactory(type, config, load, typed) {
return typed('first', {
Array: arr => arr[0],
'...any': args => args[0],
})
}
function lastFactory(type, config, load, typed) {
return typed('last', {
Array: arr => arr[arr.length - 1],
'...any': args => args[args.length - 1],
})
}
function lengthFactory(type, config, load, typed) {
return typed('length', {
Array: arr => arr.length,
'...any': args => args.length,
})
}
function rangeFactory(type, config, load, typed) {
// max - min value
const range = arr => {
arr.sort((a, b) => a - b) // sort ascending
return arr[arr.length - 1] - arr[0]
}
return typed('range', {
Array: range,
'...any': range,
})
}
function reverseFactory(type, config, load, typed) {
return typed('reverse', {
Array: arr => arr.reverse(),
'...any': args => args.reverse(),
})
}
/* LOGICAL */
function ifFactory(type, config, load, typed) {
return (cond, success, fail) => {
if (cond.constructor == Decimal) return !cond.isZero() ? success : fail
else return cond ? success : fail
}
}
/* LOGARITHMIC */
function lnFactory(type, config, load, typed) {
return load(log)
}
function logFactory(type, config, load, typed) {
const logL = load(log)
const log10L = load(log10)
return typed('log', {
any: x => log10L(x),
'any, any': (x, base) => logL(x, base),
})
}
/* ARITHMETIC */
/* mathjs.divide returns 0 in some cases where we want
to return NaN. See QUIZ-9824 for more information. */
function divideFactory(type, config, load, typed) {
const divideL = load(divide)
return (a, b) => {
if (!isFinite(a) || !isFinite(b)) {
return NaN
}
return divideL(a, b)
}
}
/* EXPORTS */
export default [
{
name: 'cosec',
factory: cosecFactory,
},
{
name: 'cotan',
factory: cotanFactory,
},
{
name: 'deg_to_rad',
factory: degToRadFactory,
},
{
name: 'rad_to_deg',
factory: radToDegFactory,
},
{
name: 'comb',
factory: combFactory,
},
{
name: 'perm',
factory: permFactory,
},
{
name: 'fact',
factory: factFactory,
},
{
name: 'rand',
factory: randFactory,
},
{
name: 'at',
factory: atFactory,
},
{
name: 'first',
factory: firstFactory,
},
{
name: 'last',
factory: lastFactory,
},
{
name: 'length',
factory: lengthFactory,
},
{
name: 'range',
factory: rangeFactory,
},
{
name: 'reverse',
factory: reverseFactory,
},
{
name: 'if',
factory: ifFactory,
},
{
name: 'ln',
factory: lnFactory,
},
{
name: 'log',
factory: logFactory,
},
{
name: 'divide',
factory: divideFactory,
},
]