Columns for students by group graph change when corresponding race checkboxes are clicked

pull/1/head
rebuilt 3 years ago
parent e8f4773c65
commit 50b3bc678c

@ -74,7 +74,7 @@ class AnalyzeController < SqmApplicationController
end end
def graphs def graphs
@graphs ||= [Analyze::Graph::StudentsAndTeachers.new, Analyze::Graph::StudentsByGroup.new] @graphs ||= [Analyze::Graph::StudentsAndTeachers.new, Analyze::Graph::StudentsByGroup.new(races: selected_races)]
end end
def background def background

@ -1,6 +1,12 @@
module Analyze module Analyze
module Graph module Graph
class StudentsByGroup class StudentsByGroup
attr_reader :races
def initialize(races:)
@races = races
end
def to_s def to_s
'Students by Group' 'Students by Group'
end end
@ -10,15 +16,30 @@ module Analyze
end end
def columns def columns
[Analyze::Graph::Column::AmericanIndian, [].tap do |array|
Analyze::Graph::Column::Asian, races.each do |race|
Analyze::Graph::Column::Black, array << column_for_race_code(code: race.qualtrics_code)
Analyze::Graph::Column::Hispanic, end
Analyze::Graph::Column::MiddleEastern, array << Analyze::Graph::Column::AllStudent
Analyze::Graph::Column::Unknown, end
Analyze::Graph::Column::White,
Analyze::Graph::Column::AllStudent]
end end
private
def column_for_race_code(code:)
CFR[code.to_s]
end
CFR = {
'1' => Analyze::Graph::Column::AmericanIndian,
'2' => Analyze::Graph::Column::Asian,
'3' => Analyze::Graph::Column::Black,
'4' => Analyze::Graph::Column::Hispanic,
'5' => Analyze::Graph::Column::White,
'8' => Analyze::Graph::Column::MiddleEastern,
'99' => Analyze::Graph::Column::Unknown,
'100' => Analyze::Graph::Column::Multiracial
}
end end
end end
end end

@ -0,0 +1,37 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
class Multiracial < GroupedBarColumnPresenter
include Analyze::Graph::Column::RaceScore
def label
# TODO: offset labels so they don't overlap
'Multiracial'
end
def basis
'student'
end
def show_irrelevancy_message?
!measure.includes_student_survey_items?
end
def show_insufficient_data_message?
# TODO: implement this logic. Resize messages so they are bound to their column
false
end
def score(year_index)
# TODO: make sure the score calculation bubble up instead of just average
race_score(measure:, school:, academic_year: academic_years[year_index], race:)
end
def race
Race.find_by_qualtrics_code 100
end
end
end
end
end

@ -4,10 +4,11 @@ module Analyze
module RaceScore module RaceScore
def race_score(measure:, school:, academic_year:, race:) def race_score(measure:, school:, academic_year:, race:)
survey_items = measure.student_survey_items survey_items = measure.student_survey_items
students = StudentRace.where(race:).pluck(:student_id)
average = SurveyItemResponse.where(school:, average = SurveyItemResponse.where(school:,
academic_year:, academic_year:,
survey_item: survey_items, survey_item: survey_items,
student: StudentRace.where(race:)) student: students)
.average(:likert_score) .average(:likert_score)
Score.new(average, true, true, true) Score.new(average, true, true, true)
end end

@ -31,7 +31,7 @@ class StudentLoader
lasid = row['LASID'] || row['lasid'] lasid = row['LASID'] || row['lasid']
# return nil if student_exists?(response_id:) # return nil if student_exists?(response_id:)
student = create_student(response_id:, lasid:, races:) student = find_or_create_student(response_id:, lasid:, races:)
assign_student_to_responses(response_id:, student:) assign_student_to_responses(response_id:, student:)
student student
@ -51,7 +51,7 @@ class StudentLoader
# SurveyItemResponse.import survey_responses, on_duplicate_key_update: { conflict_target: [:id], columns: [:student] } # SurveyItemResponse.import survey_responses, on_duplicate_key_update: { conflict_target: [:id], columns: [:student] }
end end
def self.create_student(response_id:, lasid:, races:) def self.find_or_create_student(response_id:, lasid:, races:)
student = Student.find_or_create_by(response_id:) student = Student.find_or_create_by(response_id:)
student.races = [] student.races = []
races.each do |race| races.each do |race|
@ -67,11 +67,17 @@ class StudentLoader
code = 99 if [6, 7].include?(code) code = 99 if [6, 7].include?(code)
Race.find_by_qualtrics_code(code) Race.find_by_qualtrics_code(code)
end end
remove_unknown_race_if_other_races_present(races: codes.to_set) races = remove_unknown_race_if_other_races_present(races: codes.uniq)
add_multiracial_designation(races:)
end end
def self.remove_unknown_race_if_other_races_present(races:) def self.remove_unknown_race_if_other_races_present(races:)
races.delete(Race.find_by_qualtrics_code(99)) if races.length > 1 races.delete(Race.find_by_qualtrics_code(99)) if races.length > 1
races races
end end
def self.add_multiracial_designation(races:)
races << Race.find_by_qualtrics_code(100) if races.length > 1
races
end
end end

@ -67,7 +67,7 @@ namespace :data do
end end
desc 'load students' desc 'load students'
task load_students: :environment do task load_students: :environment do
Dir.glob(Rails.root.join('data', 'survey_responses', '*student*.csv')).each do |file| Dir.glob(Rails.root.join('data', 'survey_responses', '2021-22*student*.csv')).each do |file|
puts "=====================> Loading student data from csv at path: #{file}" puts "=====================> Loading student data from csv at path: #{file}"
StudentLoader.load_data filepath: file StudentLoader.load_data filepath: file
end end

@ -5,7 +5,7 @@ FactoryBot.define do
end end
factory :race do factory :race do
designation { "MyString" } designation { "Race#{rand}" }
qualtrics_code { 1 } qualtrics_code { 1 }
end end

@ -0,0 +1,22 @@
require 'rails_helper'
include Analyze::Graph
include Analyze::Graph::Column
describe StudentsByGroup do
let(:american_indian) { create(:race, qualtrics_code: 1) }
let(:asian) { create(:race, qualtrics_code: 2) }
let(:black) { create(:race, qualtrics_code: 3) }
let(:hispanic) { create(:race, qualtrics_code: 4) }
let(:white) { create(:race, qualtrics_code: 5) }
let(:unknown) { create(:race, qualtrics_code: 99) }
let(:multiracial) { create(:race, qualtrics_code: 100) }
context 'when initialized with a list of races' do
it 'generates corresponding race columns' do
races = [american_indian]
expect(StudentsByGroup.new(races:).columns).to eq [AmericanIndian, AllStudent]
races = [american_indian, asian]
expect(StudentsByGroup.new(races:).columns).to eq [AmericanIndian, Asian, AllStudent]
races = [black, hispanic, multiracial]
expect(StudentsByGroup.new(races:).columns).to eq [Black, Hispanic, Multiracial, AllStudent]
end
end
end

@ -9,6 +9,7 @@ describe StudentLoader do
let(:white) { Race.find_by_qualtrics_code(5) } let(:white) { Race.find_by_qualtrics_code(5) }
let(:middle_eastern) { Race.find_by_qualtrics_code(8) } let(:middle_eastern) { Race.find_by_qualtrics_code(8) }
let(:unknown) { Race.find_by_qualtrics_code(99) } let(:unknown) { Race.find_by_qualtrics_code(99) }
let(:multiracial) { Race.find_by_qualtrics_code(100) }
before :each do before :each do
Rails.application.load_seed Rails.application.load_seed
@ -21,21 +22,33 @@ describe StudentLoader do
context 'as a standalone function' do context 'as a standalone function' do
it 'race codes of 6 or 7 get classified as an unknown race' do it 'race codes of 6 or 7 get classified as an unknown race' do
codes = [6] codes = [6]
expect(StudentLoader.process_races(codes:)).to eq Set[unknown] expect(StudentLoader.process_races(codes:)).to eq [unknown]
codes = [7] codes = [7]
expect(StudentLoader.process_races(codes:)).to eq Set[unknown] expect(StudentLoader.process_races(codes:)).to eq [unknown]
codes = [6, 7] codes = [6, 7]
expect(StudentLoader.process_races(codes:)).to eq Set[unknown] expect(StudentLoader.process_races(codes:)).to eq [unknown]
codes = [1, 6, 7] codes = [1, 6, 7]
expect(StudentLoader.process_races(codes:)).to eq Set[american_indian] expect(StudentLoader.process_races(codes:)).to eq [american_indian]
end end
end end
end end
describe '#add_multiracial_designation' do
it 'adds the multiracial race code to the list of races' do
races = [unknown]
expect(StudentLoader.add_multiracial_designation(races:)).to eq [unknown]
races = [american_indian, asian]
expect(StudentLoader.add_multiracial_designation(races:)).to eq [american_indian, asian, multiracial]
races = [white]
expect(StudentLoader.add_multiracial_designation(races:)).to eq [white]
end
end
# This fails in CI because github does not know what the key derivation salt is. # This fails in CI because github does not know what the key derivation salt is.
# I'm not sure how to set the key derivation salt as an environment variable in CI # I'm not sure how to securely set the key derivation salt as an environment variable in CI
xdescribe 'self.load_data' do xdescribe 'self.load_data' do
context 'student survey responses' do context 'load student data' do
before :each do before :each do
SurveyResponsesDataLoader.load_data filepath: path_to_student_responses SurveyResponsesDataLoader.load_data filepath: path_to_student_responses
StudentLoader.load_data filepath: path_to_student_responses StudentLoader.load_data filepath: path_to_student_responses
@ -59,13 +72,13 @@ end
def assigns_races_to_students def assigns_races_to_students
expect(Student.find_by_response_id('student_survey_response_1').races).to eq [american_indian] expect(Student.find_by_response_id('student_survey_response_1').races).to eq [american_indian]
expect(Student.find_by_response_id('student_survey_response_2').races).to eq [asian, black, latinx] expect(Student.find_by_response_id('student_survey_response_2').races).to eq [asian, black, latinx, multiracial]
expect(Student.find_by_response_id('student_survey_response_3').races).to eq [unknown] expect(Student.find_by_response_id('student_survey_response_3').races).to eq [unknown]
expect(Student.find_by_response_id('student_survey_response_4').races).to eq [unknown] expect(Student.find_by_response_id('student_survey_response_4').races).to eq [unknown]
expect(Student.find_by_response_id('student_survey_response_5').races).to eq [american_indian, asian, black, latinx, white, expect(Student.find_by_response_id('student_survey_response_5').races).to eq [american_indian, asian, black, latinx, white,
middle_eastern] middle_eastern, multiracial]
expect(Student.find_by_response_id('student_survey_response_6').races).to eq [american_indian, asian, black, latinx, white, expect(Student.find_by_response_id('student_survey_response_6').races).to eq [american_indian, asian, black, latinx, white,
middle_eastern] middle_eastern, multiracial]
expect(Student.find_by_response_id('student_survey_response_7').races).to eq [unknown] expect(Student.find_by_response_id('student_survey_response_7').races).to eq [unknown]
end end

@ -1,4 +1,3 @@
# TODO: fix failing tests
require 'rails_helper' require 'rails_helper'
include AnalyzeHelper include AnalyzeHelper
include Analyze::Graph include Analyze::Graph
@ -14,7 +13,7 @@ describe 'analyze/index' do
end end
let(:graph) { StudentsAndTeachers.new } let(:graph) { StudentsAndTeachers.new }
let(:graphs) do let(:graphs) do
[StudentsAndTeachers.new, StudentsByGroup.new] [StudentsAndTeachers.new, StudentsByGroup.new(races:)]
end end
let(:background) { BackgroundPresenter.new(num_of_columns: graph.columns.count) } let(:background) { BackgroundPresenter.new(num_of_columns: graph.columns.count) }
let(:selected_races) { races } let(:selected_races) { races }

Loading…
Cancel
Save