feat: create a parents by language graph

Update demographics table with lanugage options

Create a lanugage table to hold the new languages

Update the demographic loader to input languages into the database

Update the cleaner to read the language column

Update the parent table to hold a reference to a language

Update the data uploader script to read the language from the csv and update the language information for any parent items that already exist (or create database entries if none already exist)

update the analyze interface to add controls for selecting ‘parents by group’ and a dropdown for ‘parent by language’

Update the analyze controller to read the parent-by-group parameter

Create a graph for the parent-by-group view

Bubble up averages for language calculations.

Make sure n-size only counts responses for a given measure.
This commit is contained in:
rebuilt 2025-04-11 14:37:18 -07:00
parent bedab713af
commit 0f457becf0
31 changed files with 413 additions and 109 deletions

View file

@ -1,4 +1,13 @@
FactoryBot.define do
factory :parent_language do
parent { nil }
language { nil }
end
factory :language do
designation { "MyString" }
end
factory :housing do
designation { "MyString" }
end

View file

@ -1,21 +1,24 @@
ELL Value,ELL Type,ELL Headers,Sped Value,Sped Type,Sped Headers,Income Value,Income Type,Income Headers
EL student not 1st year,ELL,EL Student First Year,A,Special Education,Special Ed Status,Free Lunch,Economically Disadvantaged Y,Low Income
"EL student, not 1st year",ELL,Raw ELL,active,Special Education,Raw SPED,Reduced Lunch,Economically Disadvantaged Y,Raw Income
EL student 1st year,ELL,ELL- SIS,1,Special Education,SPED- SIS,LowIncome,Economically Disadvantaged Y,SES- SIS
"EL student, 1st year",ELL,DirectCert,Special Education,Special Education,SPED,Low Income,Economically Disadvantaged Y,EconDisadvantaged
EL - Early Child. or PK,ELL,ELL,Referred,Not Special Education,,Reduced price lunch,Economically Disadvantaged Y,Income SIS
1,ELL,English Learner,Ineligible,Not Special Education,,TRUE,Economically Disadvantaged Y,SES
lep student 1st year,ELL,,I,Not Special Education,,1,Economically Disadvantaged Y,DirectCert
lep student not 1st year,ELL,,exited,Not Special Education,,Not Eligible,Economically Disadvantaged N,
LEP Not1stYr,ELL,,0,Not Special Education,,FALSE,Economically Disadvantaged N,
LEP1stYr US Sch,ELL,,Not Special Education,Not Special Education,,0,Economically Disadvantaged N,
Does not apply,Not ELL,,Does not apply,Not Special Education,,[blanks],Economically Disadvantaged N,
0,Not ELL,,[blanks],Not Special Education,,#NA,Unknown,
2,Not ELL,,#NA,Unknown,,NA,Unknown,
3,Not ELL,,NA,Unknown,,N/A,Unknown,
[blanks],Not ELL,,N/A,Unknown,,#N/A,Unknown,
#NA,Unknown,,#N/A,Unknown,,Income,Unknown,
NA,Unknown,,SPED,Unknown,,Yes,Economically Disadvantaged Y,
N/A,Unknown,,No special needs,Not Special Education,,No,Economically Disadvantaged N,
#N/A,Unknown,,,,,,,
ELL,ELL,,,,,,,
ELL Value,ELL Type,ELL Headers,Sped Value,Sped Type,Sped Headers,Income Value,Income Type,Income Headers,Language Value,Language Type
EL student not 1st year,ELL,EL Student First Year,A,Special Education,Special Ed Status,Free Lunch,Economically Disadvantaged Y,Low Income,1,English
"EL student, not 1st year",ELL,Raw ELL,active,Special Education,Raw SPED,Reduced Lunch,Economically Disadvantaged Y,Raw Income,2,Portuguese
EL student 1st year,ELL,ELL- SIS,1,Special Education,SPED- SIS,LowIncome,Economically Disadvantaged Y,SES- SIS,3,Spanish
"EL student, 1st year",ELL,DirectCert,Special Education,Special Education,SPED,Low Income,Economically Disadvantaged Y,EconDisadvantaged,99,Prefer not to disclose
EL - Early Child. or PK,ELL,ELL,Referred,Not Special Education,,Reduced price lunch,Economically Disadvantaged Y,Income SIS,100,Prefer to self-describe
1,ELL,English Learner,Ineligible,Not Special Education,,TRUE,Economically Disadvantaged Y,SES ,,
lep student 1st year,ELL,ELL Status- SIS,I,Not Special Education,,1,Economically Disadvantaged Y,DirectCert,,
lep student not 1st year,ELL,,exited,Not Special Education,,Not Eligible,Economically Disadvantaged N,,,
LEP Not1stYr,ELL,,0,Not Special Education,,FALSE,Economically Disadvantaged N,,,
LEP1stYr US Sch,ELL,,Not Special Education,Not Special Education,,0,Economically Disadvantaged N,,,
Does not apply,Not ELL,,Does not apply,Not Special Education,,[blanks],Economically Disadvantaged N,,,
0,Not ELL,,[blanks],Unknown,,#NA,Unknown,,,
2,Not ELL,,#NA,Unknown,,NA,Unknown,,,
3,Not ELL,,NA,Unknown,,N/A,Unknown,,,
[blanks],Not ELL,,N/A,Unknown,,#N/A,Unknown,,,
#NA,Unknown,,#N/A,Unknown,,Income,Unknown,,,
NA,Unknown,,SPED,Unknown,,Yes,Economically Disadvantaged Y,,,
N/A,Unknown,,No special needs,Not Special Education,,No,Economically Disadvantaged N,,,
#N/A,Unknown,,Not SPED,Not Special Education,,,,,,
ELL,ELL,,,,,,,,,
LEP Not 1st Year,ELL,,,,,,,,,
Yes,ELL,,,,,,,,,
No,Not ELL,,,,,,,,,

1 ELL Value ELL Type ELL Headers Sped Value Sped Type Sped Headers Income Value Income Type Income Headers Language Value Language Type
2 EL student not 1st year ELL EL Student First Year A Special Education Special Ed Status Free Lunch Economically Disadvantaged – Y Low Income 1 English
3 EL student, not 1st year ELL Raw ELL active Special Education Raw SPED Reduced Lunch Economically Disadvantaged – Y Raw Income 2 Portuguese
4 EL student 1st year ELL ELL- SIS 1 Special Education SPED- SIS LowIncome Economically Disadvantaged – Y SES- SIS 3 Spanish
5 EL student, 1st year ELL DirectCert Special Education Special Education SPED Low Income Economically Disadvantaged – Y EconDisadvantaged 99 Prefer not to disclose
6 EL - Early Child. or PK ELL ELL Referred Not Special Education Reduced price lunch Economically Disadvantaged – Y Income SIS 100 Prefer to self-describe
7 1 ELL English Learner Ineligible Not Special Education TRUE Economically Disadvantaged – Y SES
8 lep student 1st year ELL ELL Status- SIS I Not Special Education 1 Economically Disadvantaged – Y DirectCert
9 lep student not 1st year ELL exited Not Special Education Not Eligible Economically Disadvantaged – N
10 LEP Not1stYr ELL 0 Not Special Education FALSE Economically Disadvantaged – N
11 LEP1stYr US Sch ELL Not Special Education Not Special Education 0 Economically Disadvantaged – N
12 Does not apply Not ELL Does not apply Not Special Education [blanks] Economically Disadvantaged – N
13 0 Not ELL [blanks] Not Special Education Unknown #NA Unknown
14 2 Not ELL #NA Unknown NA Unknown
15 3 Not ELL NA Unknown N/A Unknown
16 [blanks] Not ELL N/A Unknown #N/A Unknown
17 #NA Unknown #N/A Unknown Income Unknown
18 NA Unknown SPED Unknown Yes Economically Disadvantaged – Y
19 N/A Unknown No special needs Not Special Education No Economically Disadvantaged – N
20 #N/A Unknown Not SPED Not Special Education
21 ELL ELL
22 LEP Not 1st Year ELL
23 Yes ELL
24 No Not ELL

View file

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Language, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View file

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe ParentLanguage, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View file

@ -366,38 +366,37 @@ describe Analyze::Presenter do
context ".group" do
context "when no parameters are provided" do
it "returns the first item in the list of groups" do
params = {}
presenter = Analyze::Presenter.new(params:, school:, academic_year:)
expect(presenter.group.slug).to eq presenter.groups.first.slug
it "returns no groups when no params are defined" do
presenter = Analyze::Presenter.new(params: {}, school:, academic_year:)
expect(presenter.groups).to eq []
end
end
context "when a group is provided in the params hash" do
it "returns the group with the given slug" do
params = { group: "gender" }
params = { group: "gender", graph: "students-by-gender" }
presenter = Analyze::Presenter.new(params:, school:, academic_year:)
expect(presenter.group.slug).to eq "gender"
params = { group: "grade" }
params = { group: "grade", graph: "students-by-grade" }
presenter = Analyze::Presenter.new(params:, school:, academic_year:)
expect(presenter.group.slug).to eq "grade"
params = { group: "race" }
params = { group: "race", graph: "students-by-race" }
presenter = Analyze::Presenter.new(params:, school:, academic_year:)
expect(presenter.group.slug).to eq "race"
params = { group: "income" }
params = { group: "income", graph: "students-by-income" }
presenter = Analyze::Presenter.new(params:, school:, academic_year:)
expect(presenter.group.slug).to eq "income"
end
end
context "when a parameter that does not match a group is provided" do
it "returns the first item in the list of groups" do
params = { group: "invalid group" }
it "returns nil when invalid parameters are given" do
params = { group: "invalid group", graph: "invalid graph" }
presenter = Analyze::Presenter.new(params:, school:, academic_year:)
expect(presenter.group.slug).to eq presenter.groups.first.slug
expect(presenter.group).to eq nil
end
end
end

View file

@ -301,6 +301,7 @@ end
def reads_headers_from_raw_csv(processed_data)
processed_data in [headers, clean_csv, log_csv, data]
expect(headers.to_set.sort).to eq ["StartDate", "EndDate", "Status", "IPAddress", "Progress", "Duration (in seconds)",
"Finished", "RecordedDate", "ResponseId", "District", "School",
"LASID", "Gender", "Race", "What grade are you in?", "s-tint-q1",
@ -314,7 +315,7 @@ def reads_headers_from_raw_csv(processed_data)
"s-grit-q1", "s-grit-q2", "s-grit-q3", "s-grit-q4", "s-expa-q1", "s-poaf-q1", "s-poaf-q2", "s-poaf-q3",
"s-poaf-q4", "s-tint-q1-1", "s-tint-q2-1", "s-tint-q3-1", "s-tint-q4-1", "s-tint-q5-1", "s-acpr-q1-1",
"s-acpr-q2-1", "s-acpr-q3-1", "s-acpr-q4-1", "s-peff-q1-1", "s-peff-q2-1", "s-peff-q3-1", "s-peff-q4-1",
"s-peff-q5-1", "s-peff-q6-1", "Raw Income", "Income", "Raw ELL", "ELL", "Raw SpEd", "SpEd", "Progress Count", "Housing Status", "Raw Housing Status"].to_set.sort
"s-peff-q5-1", "s-peff-q6-1", "Raw Income", "Income", "Raw ELL", "ELL", "Raw SpEd", "SpEd", "Progress Count", "Housing Status", "Raw Housing Status", "Home Language", "Home Languages"].to_set.sort
end
def invalid_rows_are_rejected_for_the_correct_reasons(data)

View file

@ -414,7 +414,7 @@ RSpec.describe SurveyItemValues, type: :model do
end
context "when there are multiple races" do
it "returns the gender that maps to the gender provided" do
it "returns the race that maps to the race provided" do
row = { "Race" => "1,2,3" }
values = SurveyItemValues.new(row:, headers:, survey_items:, schools:, academic_years:)
expect(values.races).to eq [1, 2, 3, 100]
@ -452,7 +452,7 @@ RSpec.describe SurveyItemValues, type: :model do
headers.push("HispanicLatino")
headers.push("Race- SIS")
values = SurveyItemValues.new(row:, headers:, survey_items:, schools:, academic_years:)
expect(values.races).to eq [5, 2, 3, 4, 100]
expect(values.races).to eq [2, 3, 4, 100]
end
end
end
@ -567,6 +567,22 @@ RSpec.describe SurveyItemValues, type: :model do
# end
end
context ".language" do
before :each do
attleboro
ay_2022_23
end
it "validates the code matches the expectations defined in the demographic_glossary" do
list = read(demographic_filepath, "Language Value", "Language Type")
list.each do |target, result|
compare("Language", target, [result], :languages)
end
end
end
context ".ell" do
before :each do
attleboro

View file

@ -91,6 +91,12 @@ describe SurveyResponsesDataLoader do
]
end
let(:housings) do
create(:housing, designation: "Own")
create(:housing, designation: "Rent")
create(:housing, designation: "Unknown")
end
let(:t_pcom_q3) { create(:survey_item, survey_item_id: "t-pcom-q3") }
let(:t_pcom_q2) { create(:survey_item, survey_item_id: "t-pcom-q2") }
let(:t_coll_q1) { create(:survey_item, survey_item_id: "t-coll-q1") }
@ -123,12 +129,20 @@ describe SurveyResponsesDataLoader do
let(:unknown_race) { create(:race, qualtrics_code: 99) }
let(:multiracial) { create(:race, qualtrics_code: 100) }
let(:languages){
create(:language, designation: "English")
create(:language, designation: "Spanish")
create(:language, designation: "Portuguese")
create(:language, designation: "Unknown")
}
let(:setup) do
ay_2020_21
ay_2022_23
school
second_school
butler_school
housings
t_pcom_q3
t_pcom_q2
t_coll_q1
@ -161,6 +175,8 @@ describe SurveyResponsesDataLoader do
middle_eastern
unknown_race
multiracial
languages
end
before :each do