londi-finding-matching.js
unknown
plain_text
3 years ago
6.2 kB
7
Indexable
import {
diagnosticResults,
testTimes,
categories,
education,
} from "./londi-constants.js";
import {
getTestCategory,
londiSubtests,
londiData,
} from "./londi-suggestions.js";
import _ from "lodash";
export const fundingData =
require("../assets/LONDI Förderalgorithmus aktuell.json").Foerderalgorithmus_MC_korrigier;
const COLUMN_HEADER_ID = "C";
/*
this method calculates the child inputs + test results and returns a list of funding options
*/
const dummy = {
schoolGrade: 1,
testTime: 2, //see enum testTimes
germanSecondaryLanguage: true,
screenResultsEstimated: false, //false to use blue/yellow/green results, or true if using true/false results (1 or 0)
screeningResults: [
{ category: categories.Reading, result: 1 }, //result value is either from diagnosticResults or (1 / 0)
{ category: categories.Writing, result: 2 },
{ category: categories.Math, result: 3 },
],
selectedTests: [
{
category: categories.Reading,
testId: 61,
results: [
{ competenceLevel: 1, title: "Mengenerfassung", result: 20 },
{ competenceLevel: 1, title: "Zahlerfassung ", result: 20 },
{ competenceLevel: 1, title: "Mengenerfassung", result: 20 },
{ competenceLevel: 3, title: "Addition/Subtraktion", result: 20 },
],
},
{
category: categories.Math,
testId: 29,
results: [{ competenceLevel: 1, title: "Summe DEMAT 5+", result: 20 }],
},
],
};
export const getFundingMatching = (data) => {
console.log("getFundingMatching", data);
const categoriesResult = [];
const results = [];
if (
data.screeningResults.find(
(x) => x.testId && x.category === categories.Reading
)
) {
categoriesResult.push(categories.Reading);
}
if (
data.screeningResults.find(
(x) => x.testId && x.category === categories.Writing
)
) {
categoriesResult.push(categories.Writing);
}
if (
data.screeningResults.find(
(x) => x.testId && x.category === categories.Math
)
) {
categoriesResult.push(categories.Math);
}
categoriesResult.forEach((category) => {
//calculate the profile for each category
//const fundingProfiles = getFundingProfiles(data.selectedTests);
//filter the funding data
let filterEducationColumn = "";
switch (data.education) {
case education.Elementary:
filterEducationColumn = "CN";
break;
case education.Middle:
filterEducationColumn = "CO";
break;
case education.High:
filterEducationColumn = "CP";
break;
default:
throw new Error("invalid education area");
}
//filter by areas
const categoryFilterColumns = [];
switch (category) {
case categories.Reading:
categoryFilterColumns.push("BZ");
break;
case categories.Writing:
categoryFilterColumns.push("CA");
break;
case categories.Math:
categoryFilterColumns.push("CB");
break;
default:
throw new Error("invalid category");
}
const educationFilter = fundingData.filter(
(x) => x[filterEducationColumn] === "ja"
);
const filteredFundingData = [];
categoryFilterColumns.forEach((col) => {
filteredFundingData.push(
...educationFilter.filter(
(x) =>
x[col] === "ja" &&
!_.some(
filteredFundingData,
(y) => y[COLUMN_HEADER_ID] === x[COLUMN_HEADER_ID]
) //don't add duplicates
)
);
});
//format the results
const catResults = filteredFundingData.map((x) => {
return {
title: x["G"],
subtitle: x["H"],
publisher: x["X"],
year: x["V"],
authors: getAuthors(x),
link: x["Z"],
};
});
results.push({ category, results: catResults });
});
return results;
};
const getAuthors = (x) => {
const authors = [];
for (let idx = "I"; idx < "U"; idx = stepOneLetter(stepOneLetter(idx))) {
if (x[idx]?.trim().length > 0) {
authors.push(`${x[idx]} ${x[stepOneLetter(idx)]}`);
}
}
return authors;
};
const stepOneLetter = (letter) => {
return String.fromCharCode(letter.charCodeAt(0) + 1);
};
const levelWeight = (level) => {
switch (level) {
case 1:
return 4;
case 2:
return 3;
case 3:
return 2;
case 4:
return 1;
default:
throw new Error("invalid level");
}
};
const getFundingProfiles = (data) => {
const fundingProfiles = {};
const results = {};
data.selectedTests.forEach((test) => {
const category = test.category;
if (!fundingProfiles[category]) {
fundingProfiles[category] = {};
results[category] = {};
}
//get the funding profile for the test, first get recodedPR
for (let level = 1; level <= 4; level++) {
const resultsPerLevel = test.results.filter(
(x) => x.competenceLevel === level
);
if (resultsPerLevel.length > 0) {
const resultsAverage = _.meanBy(resultsPerLevel, "result"); //find the average result for this level
const recodedPR = recodePR(resultsAverage);
fundingProfiles[category][level].recodedPR = recodedPR;
}
}
//calculate for leve 2 if missing values
if (!fundingProfiles[category][2]) {
const pr1and3 =
fundingProfiles[category][1]?.recodedPR +
fundingProfiles[category][3]?.recodedPR;
if (pr1and3 > 0) {
fundingProfiles[category][2].recodedPR = pr1and3 / 2;
}
}
//calculate the weight
for (let level = 1; level <= 4; level++) {
const weight = levelWeight(level);
const weightedPR = fundingProfiles[category][level].recodedPR * weight;
fundingProfiles[category][level].weightedPR = weightedPR;
}
//caculate the sum profile
//get weightedPR for all levels
const allWeightedPR = _.sumBy(fundingProfiles[category], "weightedPR");
results[category] = allWeightedPR;
});
return results;
};
const recodePR = (pr) => {
if (pr < 11) {
return 3;
}
if (pr < 21) {
return 2;
}
if (pr < 31) {
return 1;
}
return 0;
};
Editor is loading...