[census][pl] aggregates

This commit is contained in:
Andrea 2022-02-28 15:18:54 +01:00
parent 802995bff2
commit 27dcf4df73
3 changed files with 124 additions and 1 deletions

View File

@ -1473,6 +1473,24 @@ census:
- ['liczba mnoga, rodzaj neutralny', '„byłośmy zmęczone”']
- ['liczba mnoga, rodzaj postpłciowy', '„byłuśmy zmęczone”']
- ['unikanie form nacechowanych płciowo', '„dopadło mnie zmęczenie”']
aggregates:
binarne:
operation: 'OR'
values: ['rodzaj męski', 'rodzaj żeński']
binarne_zamiennie:
operation: 'AND'
values: ['rodzaj męski', 'rodzaj żeński']
wyłącznie_binarne:
operation: 'OR'
values: ['rodzaj męski', 'rodzaj żeński']
exclusive: true
wyłącznie_niebinarne:
operation: 'OR'
values: ['rodzaj neutralny', 'liczba mnoga, rodzaj męskoosobowy', 'liczba mnoga, rodzaj niemęskoosobowy', 'liczba mnoga, rodzaj neutralny', 'liczba mnoga, rodzaj postpłciowy', 'unikanie form nacechowanych płciowo']
exclusive: true
mnogie:
operation: 'OR'
values: ['liczba mnoga, rodzaj męskoosobowy', 'liczba mnoga, rodzaj niemęskoosobowy', 'liczba mnoga, rodzaj neutralny', 'liczba mnoga, rodzaj postpłciowy']
-
type: 'checkbox'
question: 'Jak piszesz o sobie / chcesz, by pisano o Tobie?'
@ -1517,6 +1535,29 @@ census:
'n'/je'
- >
„'n' jest fajn'”, „lubię je' zwierzątko”
aggregates:
binarne:
operation: 'OR'
values: ['on/jego', 'ona/jej']
binarne_zamiennie:
operation: 'AND'
values: ['on/jego', 'ona/jej']
wyłącznie_binarne:
operation: 'OR'
values: ['on/jego', 'ona/jej']
exclusive: true
neutralne:
operation: 'OR'
values: ['ono/jego', 'ono/jej', 'ono/jejgo', 'ono/jeno', 'ono/jenu', 'vono/vego', 'ono/eno']
postpłciowe:
operation: 'OR'
values: ['onu/jenu', 'onu/jejo', 'ne/nego']
mnogie:
operation: 'OR'
values: ['oni/ich', 'one/ich', 'oni/e/ich', 'ona/ich', 'ony/ich', 'onie/ich']
graficzne:
operation: 'OR'
values: ['onæ/jæ', 'on/a/jego/jej', 'onx/jex', 'on_/je_', 'on*/je*', 'onø/jenø']
-
type: 'checkbox'
question: 'Jakich form rzeczownikowych używasz wobec siebie?'
@ -1549,6 +1590,11 @@ census:
- ['państwo (l. mn.)', '„czy chcieliby państwo…”']
- ['pań']
- ['panu']
aggregates:
wyłącznie_ty:
operation: 'OR'
values: ['„per ty”']
exclusive: true
-
type: 'checkbox'
question: >
@ -1632,6 +1678,10 @@ census:
optionsLast:
- ['nie mam preferencji po angielsku']
- ['bez użycia zaimków (nounself, emojiself, …)']
aggregates:
neozaimki:
operation: 'OR'
values: ['ae/aer', 'co/cos', 'e/em/eir', 'e/em/es', 'ey/em', 'fae/faer', 'hu/hum', 'ne/nem', 'ne/nir', 'per/per', 's/he/hir', 'thon/thons', 've/ver', 'vi/vir', 'xe/xem', 'ze/hir', 'ze/zir', 'zhe/zher']
-
type: 'checkbox'
question: 'Jakimi słowami opisujesz swoją płeć?'

View File

@ -4,6 +4,7 @@ import sha1 from 'sha1';
import {ulid} from "ulid";
import Papa from 'papaparse';
import {handleErrorAsync} from "../../src/helpers";
import {intersection, difference} from "../../src/sets";
const getIp = req => {
try {
@ -126,6 +127,21 @@ router.get('/census/count', handleErrorAsync(async (req, res) => {
});
}));
const calculateAggregate = (config, answer) => {
const expected = new Set(config.values);
if (config.exclusive && difference(answer, expected).size > 0) {
return false;
}
switch (config.operation) {
case 'OR':
return intersection(expected, answer).size > 0;
case 'AND':
return intersection(expected, answer).size === expected.size;
default:
throw new Exception(`Operation "${config.operation} not supported"`);
}
}
router.get('/census/export', handleErrorAsync(async (req, res) => {
if (!req.isGranted('census')) {
return res.status(401).json({error: 'Unauthorised'});
@ -146,8 +162,17 @@ router.get('/census/export', handleErrorAsync(async (req, res) => {
let i = 0;
for (let question of config.census.questions) {
if (question.type === 'checkbox') {
const answerForAggregate = new Set();
for (let [option, comment] of question.options) {
answer[`${i}_${option}`] = (answers[i.toString()] || []).includes(option) ? 1 : '';
const checked = (answers[i.toString()] || []).includes(option);
answer[`${i}_${option}`] = checked ? 1 : '';
if (checked) {
answerForAggregate.add(option);
}
}
for (let aggr in question.aggregates || {}) {
if (!question.aggregates.hasOwnProperty(aggr)) { continue; }
answer[`${i}_aggr_${aggr}`] = calculateAggregate(question.aggregates[aggr], answerForAggregate) ? 1 : '';
}
} else {
answer[`${i}_`] = answers[i.toString()] || '';

48
src/sets.js Normal file
View File

@ -0,0 +1,48 @@
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
module.exports.isSuperset = (set, subset) => {
for (let elem of subset) {
if (!set.has(elem)) {
return false
}
}
return true
}
module.exports.union = (setA, setB) => {
let _union = new Set(setA)
for (let elem of setB) {
_union.add(elem)
}
return _union
}
module.exports.intersection = (setA, setB) => {
let _intersection = new Set()
for (let elem of setB) {
if (setA.has(elem)) {
_intersection.add(elem)
}
}
return _intersection
}
module.exports.symmetricDifference = (setA, setB) => {
let _difference = new Set(setA)
for (let elem of setB) {
if (_difference.has(elem)) {
_difference.delete(elem)
} else {
_difference.add(elem)
}
}
return _difference
}
module.exports.difference = (setA, setB) => {
let _difference = new Set(setA)
for (let elem of setB) {
_difference.delete(elem)
}
return _difference
}