Skip to content

feat: weighted question scoring with deterministic tie-breaking - #2

Open
Newstrife wants to merge 1 commit into
openjung:mainfrom
Newstrife:feat/weighted-scoring
Open

feat: weighted question scoring with deterministic tie-breaking#2
Newstrife wants to merge 1 commit into
openjung:mainfrom
Newstrife:feat/weighted-scoring

Conversation

@Newstrife

Copy link
Copy Markdown

Problem

determineType uses a hard > 24 threshold. With 8 equally-weighted questions per dimension (score range 8-40, midpoint 24), an exact score of 24 is reachable and silently resolves to the left pole (E/S/F/J) — a coin-flip result for borderline users. The same issue exists in determineQuickType (threshold 6) and determineDimensionPreference (threshold 24).

Solution

  • Per-question weights (0.6-1.3) reflecting how strongly each OEJTS item discriminates its dimension (e.g. Q24 "details vs big picture" = 1.3 for SN; Q16 "fits in vs stands out" = 0.6 as a weak proxy). Weights per dimension sum to exactly 8.0, so the score range (8-40), neutral midpoint (24) and percentage mapping are all unchanged — zero downstream breakage.
  • Non-uniform weights make an exact tie at the midpoint practically unreachable.
  • Deterministic tie-breaking for the remaining exact-tie cases (e.g. all-neutral answers): breakTie examines the dimension's questions from highest to lowest weight and uses the first non-neutral answer, instead of silently defaulting to the left pole.
  • determineType / determineQuickType / determineDimensionPreference accept an optional answers param to enable tie-breaking — fully backward compatible; generateResult / generateQuickResult / generateDimensionResult pass it automatically.
  • Quick test thresholds and percentages are now derived per dimension from question weights (EI/SN: 7.2, TF: 6.9, JP: 6.75), with percentage clamping to 0-100.
  • Weighted scores are rounded to 2 decimal places to keep result URLs clean.
  • New exports: questionWeights, getQuestionWeight, dimensionWeightSums.

Tests

175 tests pass, including new coverage for:

  • Exact-tie breaking at 24, both directions + all-neutral fallback (full test)
  • Exact-tie breaking in the quick test
  • Weight integrity: every question has an explicit weight, per-dimension sums = 8.0
  • Percentage clamping for out-of-range scores

Notes

  • Weights are assigned from face validity of the OEJTS items. If real response data becomes available, they can be re-calibrated via item-total correlations.
  • Companion PR for the openmbti.org site: ya-luotao/openmbti.org#20

- Add per-question weights (0.6-1.3) reflecting how strongly each item
  discriminates its dimension; weights per dimension sum to exactly 8.0,
  so the score range (8-40) and neutral midpoint (24) are unchanged
- Non-uniform weights make an exact tie at the midpoint practically
  unreachable, removing the silent coin-flip for borderline users
- Exact ties (e.g. all-neutral answers) are broken deterministically
  using the highest-weighted non-neutral answer instead of defaulting
  to the left pole
- determineType/determineQuickType/determineDimensionPreference accept
  an optional answers param for tie-breaking (backward compatible)
- Quick test thresholds and percentages are now derived per dimension
  from question weights, with percentage clamping to 0-100
- Add tests: tie-breaking (full + quick), weight integrity, clamping
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant