mirror of
https://github.com/edcommonwealth/sqm-dashboards.git
synced 2026-03-07 21:48:16 -08:00
finish up adding socio economic disag filter
This commit is contained in:
parent
a258b32b39
commit
cab0a3955e
11 changed files with 139 additions and 12 deletions
|
|
@ -17,7 +17,7 @@ class Benefit < ApplicationRecord
|
||||||
puts "************************************"
|
puts "************************************"
|
||||||
puts "******** ERROR **********"
|
puts "******** ERROR **********"
|
||||||
puts ""
|
puts ""
|
||||||
puts "Error parsing Income column. '#{benefits}' is not a known value. Halting execution"
|
puts "Error parsing benefits column. '#{benefits}' is not a known value. Halting execution"
|
||||||
puts ""
|
puts ""
|
||||||
puts "************************************"
|
puts "************************************"
|
||||||
exit
|
exit
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class Education < ApplicationRecord
|
||||||
puts "************************************"
|
puts "************************************"
|
||||||
puts "******** ERROR **********"
|
puts "******** ERROR **********"
|
||||||
puts ""
|
puts ""
|
||||||
puts "Error parsing Income column. '#{education}' is not a known value. Halting execution"
|
puts "Error parsing Education column. '#{education}' is not a known value. Halting execution"
|
||||||
puts ""
|
puts ""
|
||||||
puts "************************************"
|
puts "************************************"
|
||||||
exit
|
exit
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,23 @@ class Employment < ApplicationRecord
|
||||||
return "Unknown" if employment.blank? or employment.nil?
|
return "Unknown" if employment.blank? or employment.nil?
|
||||||
|
|
||||||
case employment
|
case employment
|
||||||
in /^1$/i
|
in /^1$|^1100$/i
|
||||||
"Two adults with full-time employment"
|
"Two adults with full-time employment"
|
||||||
in /^2$/i
|
in /^2$|^2100$/i
|
||||||
"One adult with full-time employment"
|
"One adult with full-time employment"
|
||||||
in /^3$/i
|
in /^3$|^3100$/i
|
||||||
"Two adults with part-time employment"
|
"Two adults with part-time employment"
|
||||||
in /^4$/i
|
in /^4$|^4100$/i
|
||||||
"One adult with part-time employment"
|
"One adult with part-time employment"
|
||||||
in /^5$/i
|
in /^5$|^5100$/i
|
||||||
"No full-time or part-time employment"
|
"No full-time or part-time employment"
|
||||||
in /^99$|^100$/i
|
in /^99$|^100$|^99100$/i
|
||||||
"Unknown"
|
"Unknown"
|
||||||
else
|
else
|
||||||
puts "************************************"
|
puts "************************************"
|
||||||
puts "******** ERROR **********"
|
puts "******** ERROR **********"
|
||||||
puts ""
|
puts ""
|
||||||
puts "Error parsing Income column. '#{employment}' is not a known value. Halting execution"
|
puts "Error parsing Employment column. '#{employment}' is not a known value. Halting execution"
|
||||||
puts ""
|
puts ""
|
||||||
puts "************************************"
|
puts "************************************"
|
||||||
exit
|
exit
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,10 @@ class SurveyItemResponse < ActiveRecord::Base
|
||||||
SurveyItemResponse.joins([parent: :languages]).where(languages: { designation: designations }, survey_item: survey_items, school:, academic_year:).group(:survey_item).average(:likert_score)
|
SurveyItemResponse.joins([parent: :languages]).where(languages: { designation: designations }, survey_item: survey_items, school:, academic_year:).group(:survey_item).average(:likert_score)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope :averages_for_socio_economic_status, lambda { |survey_items, school, academic_year, socio_economic_status|
|
||||||
|
SurveyItemResponse.joins(:parent).where(parent: { socio_economic_status: }, survey_item: survey_items, school:, academic_year:).group(:survey_item).average(:likert_score)
|
||||||
|
}
|
||||||
|
|
||||||
def self.grouped_responses(school:, academic_year:)
|
def self.grouped_responses(school:, academic_year:)
|
||||||
@grouped_responses ||= Hash.new do |memo, (school, academic_year)|
|
@grouped_responses ||= Hash.new do |memo, (school, academic_year)|
|
||||||
memo[[school, academic_year]] =
|
memo[[school, academic_year]] =
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Analyze
|
||||||
|
module Graph
|
||||||
|
module Column
|
||||||
|
module Parent
|
||||||
|
class SocioEconomicStatus < Base
|
||||||
|
attr_reader :socio_economic_status, :label
|
||||||
|
|
||||||
|
def initialize(socio_economic_status:, label:, show_irrelevancy_message:)
|
||||||
|
@socio_economic_status = socio_economic_status
|
||||||
|
@label = label
|
||||||
|
@show_irrelevancy_message = show_irrelevancy_message
|
||||||
|
end
|
||||||
|
|
||||||
|
def n_size(construct:, school:, academic_year:)
|
||||||
|
SurveyItemResponse.joins(:parent).where(parent: { socio_economic_status: }, survey_item: construct.parent_survey_items, school:, academic_year:).select(:parent_id).distinct.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def score(construct:, school:, academic_year:)
|
||||||
|
return Score::NIL_SCORE if n_size(construct:, school:, academic_year:) < 10
|
||||||
|
|
||||||
|
averages = SurveyItemResponse.averages_for_socio_economic_status(construct.parent_survey_items, school, academic_year,
|
||||||
|
socio_economic_status)
|
||||||
|
average = bubble_up_averages(construct:, averages:).round(2)
|
||||||
|
Score.new(average:,
|
||||||
|
meets_teacher_threshold: false,
|
||||||
|
meets_student_threshold: true,
|
||||||
|
meets_admin_data_threshold: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
def designations
|
||||||
|
language.map(&:designation)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Analyze
|
||||||
|
module Graph
|
||||||
|
class ParentsBySocioEconomicStatus
|
||||||
|
def to_s
|
||||||
|
"Parents by Socio-Economic Status"
|
||||||
|
end
|
||||||
|
|
||||||
|
def slug
|
||||||
|
"parents-by-socio-economic-status"
|
||||||
|
end
|
||||||
|
|
||||||
|
def columns
|
||||||
|
[].tap do |array|
|
||||||
|
array << Analyze::Graph::Column::Parent::SocioEconomicStatus.new(socio_economic_status: 0, label: ["No Advantage"], show_irrelevancy_message: false)
|
||||||
|
array << Analyze::Graph::Column::Parent::SocioEconomicStatus.new(socio_economic_status: 1, label: ["Low Advantage"], show_irrelevancy_message: false)
|
||||||
|
array << Analyze::Graph::Column::Parent::SocioEconomicStatus.new(socio_economic_status: 2, label: ["Mediumn Advantage"], show_irrelevancy_message: false)
|
||||||
|
array << Analyze::Graph::Column::Parent::SocioEconomicStatus.new(socio_economic_status: 3, label: ["High Advantage"], show_irrelevancy_message: false)
|
||||||
|
|
||||||
|
array << Analyze::Graph::Column::Parent::SocioEconomicStatus.new(socio_economic_status: [0, 1, 2, 3, nil], label: ["All Students"], show_irrelevancy_message: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def source
|
||||||
|
Analyze::Source::SurveyData.new(slices: nil, graph: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def slice
|
||||||
|
Analyze::Slice::ParentsByGroup.new(graph: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def group
|
||||||
|
Analyze::Group::Base.new(name: "Parents By Socio-Economic Status", slug: "parents-by-socio-economic-status", graph: self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -167,7 +167,8 @@ module Analyze
|
||||||
"students-by-ell" => Analyze::Graph::StudentsByEll.new(ells: selected_ells),
|
"students-by-ell" => Analyze::Graph::StudentsByEll.new(ells: selected_ells),
|
||||||
"parents-by-race" => Analyze::Graph::ParentsByRace.new,
|
"parents-by-race" => Analyze::Graph::ParentsByRace.new,
|
||||||
"parents-by-language" => Analyze::Graph::ParentsByLanguage.new,
|
"parents-by-language" => Analyze::Graph::ParentsByLanguage.new,
|
||||||
"parents-by-gender" => Analyze::Graph::ParentsByGender.new }
|
"parents-by-gender" => Analyze::Graph::ParentsByGender.new,
|
||||||
|
"parents-by-socio-economic-status" => Analyze::Graph::ParentsBySocioEconomicStatus.new }
|
||||||
end
|
end
|
||||||
|
|
||||||
# The last item will per slice type will be selected as the default slice
|
# The last item will per slice type will be selected as the default slice
|
||||||
|
|
@ -185,7 +186,9 @@ module Analyze
|
||||||
"students-by-ell" => nil,
|
"students-by-ell" => nil,
|
||||||
"parents-by-race" => Analyze::Graph::ParentsByRace.new,
|
"parents-by-race" => Analyze::Graph::ParentsByRace.new,
|
||||||
"parents-by-language" => Analyze::Graph::ParentsByLanguage.new,
|
"parents-by-language" => Analyze::Graph::ParentsByLanguage.new,
|
||||||
"parents-by-gender" => Analyze::Graph::ParentsByGender.new }
|
"parents-by-gender" => Analyze::Graph::ParentsByGender.new,
|
||||||
|
|
||||||
|
"parents-by-socio-economic-status" => Analyze::Graph::ParentsBySocioEconomicStatus.new }
|
||||||
end
|
end
|
||||||
|
|
||||||
def graphs
|
def graphs
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,13 @@ class SurveyResponsesDataLoader
|
||||||
SurveyItemResponse.import(survey_item_responses.compact.flatten, batch_size:, on_duplicate_key_update: :all)
|
SurveyItemResponse.import(survey_item_responses.compact.flatten, batch_size:, on_duplicate_key_update: :all)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def socio_economic_score(education, benefits, employment)
|
||||||
|
employment_points = employment.map(&:points).sum.clamp(0, 1)
|
||||||
|
ed_points = education&.points || 0
|
||||||
|
benefits_points = benefits&.points || 0
|
||||||
|
ed_points + benefits_points + employment_points
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def schools
|
def schools
|
||||||
|
|
@ -141,7 +148,9 @@ class SurveyResponsesDataLoader
|
||||||
tmp_employments = row.employments.map { |employment| employments[employment] }.reject(&:nil?)
|
tmp_employments = row.employments.map { |employment| employments[employment] }.reject(&:nil?)
|
||||||
parent.employments.concat(tmp_employments)
|
parent.employments.concat(tmp_employments)
|
||||||
|
|
||||||
|
parent.socio_economic_status = socio_economic_score(educations[row.education], benefits[row.benefits], tmp_employments)
|
||||||
parent.housing = housings[row.housing] if row.housing.present?
|
parent.housing = housings[row.housing] if row.housing.present?
|
||||||
|
|
||||||
parent.save
|
parent.save
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddSocioEconomicStatusToParent < ActiveRecord::Migration[8.0]
|
||||||
|
def change
|
||||||
|
add_column :parents, :socio_economic_status, :integer, default: nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[8.0].define(version: 2025_06_24_230522) do
|
ActiveRecord::Schema[8.0].define(version: 2025_06_25_201425) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_catalog.plpgsql"
|
enable_extension "pg_catalog.plpgsql"
|
||||||
|
|
||||||
|
|
@ -399,6 +399,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_06_24_230522) do
|
||||||
t.bigint "housing_id"
|
t.bigint "housing_id"
|
||||||
t.bigint "education_id"
|
t.bigint "education_id"
|
||||||
t.bigint "benefits_id"
|
t.bigint "benefits_id"
|
||||||
|
t.integer "socio_economic_status"
|
||||||
t.index ["benefits_id"], name: "index_parents_on_benefits_id"
|
t.index ["benefits_id"], name: "index_parents_on_benefits_id"
|
||||||
t.index ["education_id"], name: "index_parents_on_education_id"
|
t.index ["education_id"], name: "index_parents_on_education_id"
|
||||||
t.index ["housing_id"], name: "index_parents_on_housing_id"
|
t.index ["housing_id"], name: "index_parents_on_housing_id"
|
||||||
|
|
|
||||||
|
|
@ -341,6 +341,34 @@ describe SurveyResponsesDataLoader do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe ".socio_economic_score" do
|
||||||
|
it "returns 0 when none of the rubrics meet the standard for higher advantage" do
|
||||||
|
score = SurveyResponsesDataLoader.new.socio_economic_score(Education.new(designation: "No formal schooling completed"), Benefit.new(designation: "No"), [Employment.new(designation: "No full-time or part-time employment")])
|
||||||
|
expect(score).to eq 0
|
||||||
|
|
||||||
|
score = SurveyResponsesDataLoader.new.socio_economic_score(Education.new(designation: "Unknown"), Benefit.new(designation: "Unknown"), [Employment.new(designation: "Unknown")])
|
||||||
|
expect(score).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns 1 when one of the rubrics meets the standard for higher advantage" do
|
||||||
|
score = SurveyResponsesDataLoader.new.socio_economic_score(Education.new(designation: "Associates Degree"), Benefit.new(designation: "No"), [Employment.new(designation: "No full-time or part-time employment")])
|
||||||
|
expect(score).to eq 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns 2 when two of the rubrics meet the standard for higher advantage" do
|
||||||
|
score = SurveyResponsesDataLoader.new.socio_economic_score(Education.new(designation: "Associates Degree"), Benefit.new(designation: "Yes"), [Employment.new(designation: "No full-time or part-time employment")])
|
||||||
|
expect(score).to eq 2
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns 3 when all three of the rubrics meet the standard for higher advantage" do
|
||||||
|
score = SurveyResponsesDataLoader.new.socio_economic_score(Education.new(designation: "Associates Degree"), Benefit.new(designation: "Yes"), [Employment.new(designation: "Two adults with full-time employment")])
|
||||||
|
expect(score).to eq 3
|
||||||
|
|
||||||
|
score = SurveyResponsesDataLoader.new.socio_economic_score(Education.new(designation: "Associates Degree"), Benefit.new(designation: "Yes"), [Employment.new(designation: "One adult with full-time employment"), Employment.new(designation: "Two adults with full-time employment")])
|
||||||
|
expect(score).to eq 3
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def assigns_academic_year_to_survey_item_responses
|
def assigns_academic_year_to_survey_item_responses
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue