Public
Edited
May 16, 2023
Importers
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Every ratio between every whole number 1...32
quartermaster(plusOne(32))
Insert cell
// Every ratio within a given array
// only keeps numbers
quartermaster([2, 3, 5, 23, 59, "foo", 33, [99, 100]])
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Quartermaster
// rations out any given array of numbers

// requires: factorial, round, ratioToCents, ratioToSavarts
// inputs an array of numbers
// outputs an array of objects, 5 properties

quartermaster = (arr) => {

var rations = []
var unclean = arr
var denominator = unclean.filter(x => typeof x === 'number')
var numerator = unclean.filter(x => typeof x === 'number')
var ratio = []
var fraction = []
var cents = []
var savarts = []
var centsStd = []
var combined = []
var obj = {Ratio: "", Fraction: "", Cents: "", CentsStd: "", RatioStd: "", Savarts: "", Viz: [], Notes: ""}
var uniqueFractions = []
var uniqueCentsStd = []
var counter = 0
var output = Array(counter)
function modulo (a) {return ((a%1200)+1200)%1200} // cents[i]%1200 gives remainder, we want modulo

// creates a list of unique fractions and their text representations
for (var n=0; n < numerator.length; n++){
for (var d=0; d < denominator.length; d++){
// creates array with the division of n by d
fraction.push(round(numerator[n]/denominator[d],3))
// Text ratio concatenation
var textfrac = numerator[n]+"/"+denominator[d]
ratio.push(textfrac)
}
}

// unit conversions
cents = fraction.map(ratioToCents)
savarts = fraction.map(ratioToSavarts)
centsStd = cents.map(modulo) // ensure all values are within 0-1200 range
// combine each array using only unique values for fraction
for (var i=0; i < fraction.length; i++){
// skip repeated values
if (Object.values(uniqueFractions).includes(fraction[i])) {continue} // check whether fraction is repeated
if (Object.values(uniqueCentsStd).includes(centsStd[i])) {continue} // check whether centsStd is repeated
if (fraction[i]<1) {continue} // skip fractions smaller than 1:1
// skip fractions over 1 if needed
//if (fraction[i] > 1) { continue }
// for new unique values, adds properties
var key = ratio[i]
combined[key] = Object.create(obj)
combined[key].Ratio = ratio[i]
combined[key].Fraction = fraction[i]
combined[key].Cents = Math.abs(round(cents[i],3))
combined[key].Savarts = Math.abs(round(savarts[i],3))
//combined[key].Cents = Math.abs(round(ratioToCents(combined[key].Fraction),3))
if (combined[key].Cents > 1200) {continue}; // skip ratios with cents over 1200
//combined[key].Savarts = Math.abs(round(ratioToSavarts(combined[key].Fraction),3))
combined[key].CentsStd = round(centsStd[i],3)
if (combined[key].CentsStd < 1) {continue}; // skip fractions where mod is 0
//combined[key].RatioStd = Math.floor(cents[i]/1200) + " + " +
combined[key].Viz = [{Blue: centsStd[i], Pink: 1200-centsStd[i]}]
uniqueFractions.push(fraction[i])
uniqueCentsStd.push(centsStd[i])
counter++
output.push(combined[key])
}

return output
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more