UNPKG

ecclesia

Version:

Framework for political and electoral simulations

46 lines 2.3 kB
import { NumberCounter } from "@gouvernathor/python/collections"; import { AttributionFailure } from "../attribution"; /** * Transforms a standard proportional attribution method into one that requires a certain threshold * (percentage of the total votes) to be reached by the parties in order to receive seats. * Mostly useful for proportional attribution methods - * but works for any simple-ballot-based attribution method. * * Replaces the Proportional class implementation. * * If the attribution implements a certain type * that extends Attribution<Party, Simple<Party>> * without adding any new method or property, * such as Proportional, * and if the contingency implements the same type, null, or undefined / not passed, * then it can be considered that the returned value implements that type too. * * @param threshold The threshold, between 0 and 1 * @param contingency The fallback attribution in case the threshold is not reached by any party. * It takes an Attribution, or undefined (the default), or null. * Null in this case has the specific behavior that if no party reaches the threshold, * an AttributionFailure error will be raised. * If undefined (or nothing is passed), the contingency will default to running * the same attribution method without the threshold. * @param attribution The votes passed to this attribution method are guaranteed to be above the threshold, * except if the contingency is undefined and no party reached the threshold * (in that case, all parties will be passed). */ export function addThresholdToSimpleAttribution({ threshold, attribution, contingency = attribution }) { const attrib = (votes, rest = {}) => { if (threshold > 0) { const original_votes = votes; const votes_threshold = threshold * votes.total; votes = NumberCounter.fromEntries([...votes.entries()].filter(([_, v]) => v >= votes_threshold)); if (votes.size === 0) { if (contingency === null) { throw new AttributionFailure("No party reached the threshold"); } return contingency(original_votes, rest); } } return attribution(votes, rest); }; return attrib; } //# sourceMappingURL=transform.js.map