mirror of
https://github.com/edcommonwealth/sqm-dashboards.git
synced 2026-03-07 13:38:18 -08:00
Modify score calculations. Ignore any survey item scores of 0.
Never include zero when performing calculations for scores.
This commit is contained in:
parent
0e85370b90
commit
c475744939
5 changed files with 99 additions and 32 deletions
|
|
@ -50,20 +50,17 @@ class Measure < ActiveRecord::Base
|
|||
meets_student_threshold = sufficient_student_data?(school:, academic_year:)
|
||||
meets_teacher_threshold = sufficient_teacher_data?(school:, academic_year:)
|
||||
meets_admin_data_threshold = all_admin_data_collected?(school:, academic_year:)
|
||||
lacks_sufficient_data = !meets_student_threshold && !meets_teacher_threshold && !includes_admin_data_items?
|
||||
lacks_sufficient_survey_data = !meets_student_threshold && !meets_teacher_threshold
|
||||
incalculable_score = lacks_sufficient_survey_data && !includes_admin_data_items?
|
||||
|
||||
next Score.new(nil, false, false, false) if lacks_sufficient_data
|
||||
next Score.new(nil, false, false, false) if incalculable_score
|
||||
|
||||
scores = []
|
||||
scores << teacher_scales.map { |scale| scale.score(school:, academic_year:) }.average if meets_teacher_threshold
|
||||
scores << student_scales.map { |scale| scale.score(school:, academic_year:) }.average if meets_student_threshold
|
||||
if includes_admin_data_items?
|
||||
scores << admin_data_items.map do |admin_data_item|
|
||||
admin_value = admin_data_item.admin_data_values.where(school:, academic_year:).first
|
||||
admin_value.likert_score if admin_value.present?
|
||||
end
|
||||
end
|
||||
average = scores.flatten.compact.average
|
||||
scores << collect_survey_scale_average(teacher_scales, school, academic_year) if meets_teacher_threshold
|
||||
scores << collect_survey_scale_average(student_scales, school, academic_year) if meets_student_threshold
|
||||
scores << collect_admin_scale_average(admin_data_items, school, academic_year) if includes_admin_data_items?
|
||||
|
||||
average = scores.flatten.compact.remove_zeros.average
|
||||
|
||||
next Score.new(nil, false, false, false) if average.nan?
|
||||
|
||||
|
|
@ -122,6 +119,17 @@ class Measure < ActiveRecord::Base
|
|||
|
||||
private
|
||||
|
||||
def collect_survey_scale_average(scales, school, academic_year)
|
||||
scales.map { |scale| scale.score(school:, academic_year:) }.average
|
||||
end
|
||||
|
||||
def collect_admin_scale_average(scales, school, academic_year)
|
||||
scales.map do |admin_data_item|
|
||||
admin_value = admin_data_item.admin_data_values.where(school:, academic_year:).first
|
||||
admin_value.likert_score if admin_value.present?
|
||||
end
|
||||
end
|
||||
|
||||
def benchmark(name)
|
||||
averages = []
|
||||
averages << student_survey_items.first.send(name) if includes_student_survey_items?
|
||||
|
|
|
|||
|
|
@ -8,12 +8,10 @@ class Scale < ApplicationRecord
|
|||
@score ||= Hash.new do |memo|
|
||||
memo[[school, academic_year]] = begin
|
||||
items = []
|
||||
items << student_survey_items(school:, academic_year:)
|
||||
items << teacher_survey_items
|
||||
items << collect_survey_item_average(student_survey_items(school:, academic_year:), school, academic_year)
|
||||
items << collect_survey_item_average(teacher_survey_items, school, academic_year)
|
||||
|
||||
items.flatten.map do |survey_item|
|
||||
survey_item.score(school:, academic_year:)
|
||||
end.average
|
||||
items.remove_zeros.average
|
||||
end
|
||||
end
|
||||
@score[[school, academic_year]]
|
||||
|
|
@ -28,6 +26,12 @@ class Scale < ApplicationRecord
|
|||
|
||||
private
|
||||
|
||||
def collect_survey_item_average(survey_items, school, academic_year)
|
||||
survey_items.map do |survey_item|
|
||||
survey_item.score(school:, academic_year:)
|
||||
end.remove_zeros.average
|
||||
end
|
||||
|
||||
def teacher_survey_items
|
||||
survey_items.teacher_survey_items
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ module ArrayMonkeyPatches
|
|||
def average
|
||||
sum.to_f / size
|
||||
end
|
||||
|
||||
def remove_zeros
|
||||
reject { |item| item == 0 || item.to_f.nan? }
|
||||
end
|
||||
end
|
||||
|
||||
Array.include ArrayMonkeyPatches
|
||||
|
|
|
|||
19
doc/architectural_decision_records/9.md
Normal file
19
doc/architectural_decision_records/9.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Decision record 9
|
||||
|
||||
# Modify score calculations so that a survey item score of 0 is never included in the average
|
||||
|
||||
## Status
|
||||
|
||||
Completed
|
||||
|
||||
## Context
|
||||
|
||||
Some scores were artificially low because survey items that lacked survey item responses returned a score of 0. 0 did not represent the average likert_scores of survey item responses, only the lack of responses. 0 was incorrectly being averaged with other survey items and artificially dragging down the score.
|
||||
|
||||
## Decision
|
||||
|
||||
Survey item scores of 0 should be ignored and filtered out when performing score calculations.
|
||||
|
||||
## Consequences
|
||||
|
||||
Some average scores have increased.
|
||||
|
|
@ -12,32 +12,64 @@ RSpec.describe Scale, type: :model do
|
|||
let(:teacher_survey_item_1) { create(:teacher_survey_item, scale:) }
|
||||
let(:teacher_survey_item_2) { create(:teacher_survey_item, scale:) }
|
||||
let(:teacher_survey_item_3) { create(:teacher_survey_item, scale:) }
|
||||
let(:student_survey_item_1) { create(:student_survey_item, scale:) }
|
||||
|
||||
before :each do
|
||||
context 'when only teacher survey items exist' do
|
||||
before :each do
|
||||
create(:survey_item_response,
|
||||
survey_item: teacher_survey_item_1, academic_year:, school:, likert_score: 3)
|
||||
create(:survey_item_response,
|
||||
survey_item: teacher_survey_item_2, academic_year:, school:, likert_score: 4)
|
||||
create(:survey_item_response,
|
||||
survey_item: teacher_survey_item_3, academic_year:, school:, likert_score: 5)
|
||||
end
|
||||
it 'returns the average of the likert scores of the survey items' do
|
||||
expect(scale.score(school:, academic_year:)).to eq 4
|
||||
end
|
||||
|
||||
context 'when other scales exist' do
|
||||
before :each do
|
||||
create(:survey_item_response,
|
||||
academic_year:, school:, likert_score: 1)
|
||||
create(:survey_item_response,
|
||||
academic_year:, school:, likert_score: 1)
|
||||
create(:survey_item_response,
|
||||
academic_year:, school:, likert_score: 1)
|
||||
end
|
||||
|
||||
it 'does not affect the score for the original scale' do
|
||||
expect(scale.score(school:, academic_year:)).to eq 4
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when both teacher and student survey items exist' do
|
||||
before :each do
|
||||
create(:survey_item_response,
|
||||
survey_item: teacher_survey_item_1, academic_year:, school:, likert_score: 3)
|
||||
create(:survey_item_response,
|
||||
survey_item: teacher_survey_item_2, academic_year:, school:, likert_score: 4)
|
||||
create(:survey_item_response,
|
||||
survey_item: teacher_survey_item_3, academic_year:, school:, likert_score: 5)
|
||||
end
|
||||
end
|
||||
context 'but no survey item responses are linked to student survey items' do
|
||||
before :each do
|
||||
student_survey_item_1
|
||||
end
|
||||
|
||||
it 'returns the average of the likert scores of the survey items' do
|
||||
expect(scale.score(school:, academic_year:)).to eq 4
|
||||
end
|
||||
|
||||
context 'when other scales exist' do
|
||||
before :each do
|
||||
create(:survey_item_response,
|
||||
academic_year:, school:, likert_score: 1)
|
||||
create(:survey_item_response,
|
||||
academic_year:, school:, likert_score: 1)
|
||||
create(:survey_item_response,
|
||||
academic_year:, school:, likert_score: 1)
|
||||
it 'returns a score that only averages teacher survey items' do
|
||||
expect(scale.score(school:, academic_year:)).to eq 4
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not affect the score for the original scale' do
|
||||
expect(scale.score(school:, academic_year:)).to eq 4
|
||||
context 'and some survey item responses exist for a student survey item' do
|
||||
before :each do
|
||||
create(:survey_item_response,
|
||||
survey_item: student_survey_item_1, academic_year:, school:, likert_score: 2)
|
||||
end
|
||||
it 'returns a score that gives equal weight to student and teacher survey items' do
|
||||
expect(scale.score(school:, academic_year:)).to eq 3
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue