⚙️ Nouveau mécanisme barème continu
parent
7394730fe3
commit
398595b8cc
|
@ -136,6 +136,13 @@ barème linéaire:
|
|||
Il est composé de tranches qui se suivent. Il suffit de trouver l'assiette qui correspond à la tranche, et de multiplier le taux associé avec l'assiette.
|
||||
Un montant fixe pour chaque tranche peut aussi remplacer le taux, rendant le barème encore plus simple, mais moins "juste", car moins continu.
|
||||
|
||||
barème continu:
|
||||
type: numeric
|
||||
description: |
|
||||
Ce barème définit des points A(x1, y1) B(x2, y2) C(x3, y3) etc. On trace alors une droite entre ces points. x correspond à l'assiette du barème, et y au taux qui va être appliqué à l'assiette pour déterminer le montant du calcul.
|
||||
Les x1, x2, peuvent éventuellement être des unités d'un multiplicateur.
|
||||
|
||||
|
||||
complément:
|
||||
type: numeric
|
||||
description: |
|
||||
|
|
|
@ -3,7 +3,6 @@ import {
|
|||
path,
|
||||
mergeWith,
|
||||
objOf,
|
||||
toPairs,
|
||||
dissoc,
|
||||
add,
|
||||
find,
|
||||
|
@ -27,7 +26,12 @@ import {
|
|||
subtract,
|
||||
sum,
|
||||
isNil,
|
||||
reject
|
||||
reject,
|
||||
aperture,
|
||||
sort,
|
||||
toPairs,
|
||||
reduced,
|
||||
last
|
||||
} from 'ramda'
|
||||
import React from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
|
@ -779,6 +783,57 @@ export let mecanismScale = (recurse, k, v) => {
|
|||
}
|
||||
}
|
||||
|
||||
export let mecanismContinuousScale = (recurse, k, v) => {
|
||||
let objectShape = {
|
||||
assiette: false,
|
||||
multiplicateur: constantNode(1)
|
||||
}
|
||||
let effect = ({ assiette, multiplicateur, points }) => {
|
||||
if (anyNull([assiette, multiplicateur])) return null
|
||||
//We'll build a linear function given the two constraints that must be respected
|
||||
return pipe(
|
||||
toPairs,
|
||||
// we don't rely on the sorting of objects
|
||||
sort(([k1], [k2]) => k1 - k2),
|
||||
points => [...points, [Infinity, last(points)[1]]],
|
||||
aperture(2),
|
||||
reduce((_, [[lowerLimit, lowerRate], [upperLimit, upperRate]]) => {
|
||||
let x1 = val(multiplicateur) * lowerLimit,
|
||||
x2 = val(multiplicateur) * upperLimit,
|
||||
y1 = val(assiette) * val(recurse(lowerRate)),
|
||||
y2 = val(assiette) * val(recurse(upperRate))
|
||||
if (val(assiette) > x1 && val(assiette) <= x2) {
|
||||
// Outside of these 2 limits, it's a linear function a * x + b
|
||||
let a = (y2 - y1) / (x2 - x1),
|
||||
b = y1 - x1 * a
|
||||
return reduced(a * val(assiette) + b)
|
||||
}
|
||||
}, 0)
|
||||
)(points)
|
||||
}
|
||||
let explanation = {
|
||||
...parseObject(recurse, objectShape, v),
|
||||
points: v.points
|
||||
},
|
||||
evaluate = evaluateObject(objectShape, effect)
|
||||
let jsx = (nodeValue, explanation) => (
|
||||
<Node
|
||||
classes="mecanism réductionLinéaire"
|
||||
name="réductionLinéaire"
|
||||
value={nodeValue}
|
||||
child={<div> Réduction linéaire </div>}
|
||||
/>
|
||||
)
|
||||
return {
|
||||
evaluate,
|
||||
jsx,
|
||||
explanation,
|
||||
category: 'mecanism',
|
||||
name: 'réduction linéaire',
|
||||
type: 'numeric'
|
||||
}
|
||||
}
|
||||
|
||||
export let mecanismMax = (recurse, k, v) => {
|
||||
let explanation = v.map(recurse)
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ import {
|
|||
mecanismProduct,
|
||||
mecanismScale,
|
||||
mecanismLinearScale,
|
||||
mecanismContinuousScale,
|
||||
mecanismMax,
|
||||
mecanismMin,
|
||||
mecanismError,
|
||||
|
@ -252,6 +253,7 @@ export let treatObject = (rules, rule, treatOptions) => rawNode => {
|
|||
multiplication: mecanismProduct,
|
||||
barème: mecanismScale,
|
||||
'barème linéaire': mecanismLinearScale,
|
||||
'barème continu': mecanismContinuousScale,
|
||||
'le maximum de': mecanismMax,
|
||||
'le minimum de': mecanismMin,
|
||||
complément: mecanismComplement,
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
- nom: base
|
||||
format: nombre
|
||||
formule: 300
|
||||
|
||||
- nom: assiette
|
||||
format: nombre
|
||||
|
||||
- test: Simple
|
||||
formule:
|
||||
barème continu:
|
||||
assiette: assiette
|
||||
multiplicateur: base
|
||||
points:
|
||||
0: 0%
|
||||
0.4: 3.16%
|
||||
1.1: 6.35%
|
||||
|
||||
exemples:
|
||||
- nom: Premier intervale
|
||||
situation:
|
||||
assiette: 10
|
||||
valeur attendue: 0.026
|
||||
- nom: Deuxième intervale
|
||||
situation:
|
||||
assiette: 120
|
||||
valeur attendue: 3.792
|
||||
- nom: Premier point
|
||||
situation:
|
||||
assiette: 150
|
||||
valeur attendue: 5.423
|
||||
- nom: Deuxième point
|
||||
situation:
|
||||
assiette: 330
|
||||
valeur attendue: 20.955
|
||||
- nom: Au-delà
|
||||
situation:
|
||||
assiette: 1000
|
||||
valeur attendue: 63.5
|
||||
|
||||
|
Loading…
Reference in New Issue