Add gender disagreggation

pull/1/head
rebuilt 3 years ago
parent 7f0faf8917
commit 7d7bee6498

@ -3,7 +3,7 @@
class AnalyzeController < SqmApplicationController
before_action :assign_categories, :assign_subcategories, :assign_measures, :assign_academic_years,
:response_rate_timestamp, :races, :selected_races, :graph, :graphs, :background, :race_score_timestamp,
:sources, :group, :groups, :selected_grades, :grades, :slice, :genders, only: [:index]
:sources, :group, :groups, :selected_grades, :grades, :slice, :selected_genders, :genders, only: [:index]
def index; end
private
@ -76,7 +76,7 @@ class AnalyzeController < SqmApplicationController
def graphs
@graphs ||= [Analyze::Graph::StudentsAndTeachers.new, Analyze::Graph::StudentsByRace.new(races: selected_races),
Analyze::Graph::StudentsByGrade.new(grades: selected_grades)]
Analyze::Graph::StudentsByGrade.new(grades: selected_grades), Analyze::Graph::StudentsByGender.new(genders: selected_genders)]
end
def background
@ -148,6 +148,21 @@ class AnalyzeController < SqmApplicationController
end.keys
end
def selected_genders
@selected_genders ||= begin
gender_params = params[:genders]
return @selected_genders = genders unless gender_params
gender_list = gender_params.split(',') if gender_params
if gender_list
gender_list = gender_list.map do |gender|
Gender.find_by_designation(gender)
end
end
gender_list
end
end
def genders
@genders ||= Gender.all
end

@ -18,6 +18,8 @@ export default class extends Controller {
this.selected_graph() +
"&races=" +
this.selected_races().join(",") +
"&genders=" +
this.selected_genders().join(",") +
"&grades=" +
this.selected_grades().join(",");
@ -79,10 +81,10 @@ export default class extends Controller {
})[0];
if (selected_graph === 'students-and-teachers') {
return selected_graph;
}
if (this.selected_group() === 'race') {
} else if (this.selected_group() === 'race') {
return 'students-by-race'
} else if (this.selected_group() === 'gender'){
return 'students-by-gender'
} else {
return 'students-by-grade'
}
@ -113,4 +115,17 @@ export default class extends Controller {
return grades;
}
selected_genders() {
let gender_checkboxes = [...document.getElementsByName("gender-checkbox")]
let genders = gender_checkboxes
.filter((item) => {
return item.checked;
})
.map((item) => {
return item.id.replace('gender-', '');
});
return genders;
}
}

@ -22,4 +22,8 @@ class SurveyItemResponse < ActiveRecord::Base
academic_year: , grade:).group(:survey_item).average(:likert_score)
}
scope :averages_for_gender, ->(survey_items, school, academic_year, gender) {
SurveyItemResponse.where(survey_item: survey_items, school:,
academic_year: , gender:).group(:survey_item).average(:likert_score)
}
end

@ -0,0 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Gender
class Female < GroupedBarColumnPresenter
include Analyze::Graph::Column::Gender::ScoreForGender
def label
'Female'
end
def basis
'student'
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def gender
::Gender.find_by_qualtrics_code 1
end
end
end
end
end
end

@ -0,0 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Gender
class Male < GroupedBarColumnPresenter
include Analyze::Graph::Column::Gender::ScoreForGender
def label
'Male'
end
def basis
'student'
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def gender
::Gender.find_by_qualtrics_code 2
end
end
end
end
end
end

@ -0,0 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Gender
class NonBinary < GroupedBarColumnPresenter
include Analyze::Graph::Column::Gender::ScoreForGender
def label
'Non-Binary'
end
def basis
'student'
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def gender
::Gender.find_by_qualtrics_code 4
end
end
end
end
end
end

@ -0,0 +1,39 @@
module Analyze
module Graph
module Column
module Gender
module ScoreForGender
def score(year_index)
academic_year = academic_years[year_index]
averages = SurveyItemResponse.averages_for_gender(measure.student_survey_items, school, academic_year, gender)
average = bubble_up_averages(averages:)
scorify(average:, meets_student_threshold: sufficient_student_responses?(academic_year:))
end
def bubble_up_averages(averages:)
measure.student_scales.map do |scale|
scale.survey_items.map do |survey_item|
averages[survey_item]
end.remove_blanks.average
end.remove_blanks.average
end
def scorify(average:, meets_student_threshold:)
return Score::NIL_SCORE unless meets_student_threshold
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold: true,
meets_admin_data_threshold: false)
end
def sufficient_student_responses?(academic_year:)
yearly_counts = SurveyItemResponse.where(school: , academic_year: , gender:).group(:gender).select(:response_id).distinct(:response_id).count
yearly_counts.first[1] >= 10
end
end
end
end
end
end

@ -0,0 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Gender
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::Gender::ScoreForGender
def label
'Unknown'
end
def basis
'student'
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def gender
::Gender.find_by_qualtrics_code 99
end
end
end
end
end
end

@ -0,0 +1,42 @@
module Analyze
module Graph
class StudentsByGender
include Analyze::Graph::Column::Gender
attr_reader :genders
def initialize(genders:)
@genders = genders
end
def to_s
'Students by Gender'
end
def slug
'students-by-gender'
end
def columns
[].tap do |array|
genders.each do |gender|
array << column_for_gender_code(code: gender.qualtrics_code)
end
array << Analyze::Graph::Column::AllStudent
end
end
private
def column_for_gender_code(code:)
CFR[code]
end
CFR = {
1 => Analyze::Graph::Column::Gender::Female,
2 => Analyze::Graph::Column::Gender::Male,
4 => Analyze::Graph::Column::Gender::NonBinary,
99 => Analyze::Graph::Column::Gender::Unknown
}.freeze
end
end
end

@ -114,6 +114,7 @@ class Values
def gender
gender_code = row['gender'] || row['Gender'] || 99
gender_code = gender_code.to_i
gender_code = 4 if gender_code == 3
gender_code = 99 if gender_code.zero?
Gender.find_by_qualtrics_code gender_code
end

@ -64,13 +64,13 @@
<% @genders.each do |gender| %>
<div class="d-flex align-items-center">
<input
id="gender-<%= gender %>"
id="gender-<%= gender.designation %>"
class="m-3 gender-checkbox form-check-input"
type="checkbox"
name="gender-checkbox"
value="<%= base_url %>"
data-action="click->analyze#refresh"
<%# <%= @selected_genders.include?(gender) ? "checked" : "" %1> %>
<%= @selected_genders.include?(gender) ? "checked" : "" %>
<%= @graph.slug == 'students-and-teachers' ? "disabled" : "" %>
<%= @group.slug == 'gender' ? "" : "hidden" %>>

@ -18,7 +18,7 @@
<%= render partial: "data_filters", locals: {district: @district, school: @school, academic_year: @academic_year, category: @category, subcategory: @subcategory} %>
</div>
<% cache [@subcategory, @school, @selected_academic_years, @response_rate_timestamp, @graph, @selected_races, @race_score_timestamp, @selected_grades, @grades] do %>
<% cache [@subcategory, @school, @selected_academic_years, @response_rate_timestamp, @graph, @selected_races, @race_score_timestamp, @selected_grades, @grades, @selected_genders, @genders] do %>
<div class="bg-color-white flex-grow-1 col-9">
<% @measures.each do |measure| %>
<section class="mb-6">

@ -1,9 +1,9 @@
Race Qualtrics Code,Race/Ethnicity,Gender Qualtrics Code,Sex/Gender
1,American Indian or Alaskan Native,2,Male
2,Asian or Pacific Islander,1,Female
3,Black or African American,3,Another gender or gender identity not listed above
4,Hispanic or Latinx,4,Non-Binary
5,White or Caucasian,99,Unknown
3,Black or African American,4,Non-Binary
4,Hispanic or Latinx,99,Unknown
5,White or Caucasian,,
6,Prefer not to disclose,,
7,Prefer to self-describe,,
8,Middle Eastern,,

1 Race Qualtrics Code Race/Ethnicity Gender Qualtrics Code Sex/Gender
2 1 American Indian or Alaskan Native 2 Male
3 2 Asian or Pacific Islander 1 Female
4 3 Black or African American 3 4 Another gender or gender identity not listed above Non-Binary
5 4 Hispanic or Latinx 4 99 Non-Binary Unknown
6 5 White or Caucasian 99 Unknown
7 6 Prefer not to disclose
8 7 Prefer to self-describe
9 8 Middle Eastern

@ -1,9 +1,9 @@
Race Qualtrics Code,Race/Ethnicity,Gender Qualtrics Code,Sex/Gender
1,American Indian or Alaskan Native,2,Male
2,Asian or Pacific Islander,1,Female
3,Black or African American,3,Another gender or gender identity not listed above
4,Hispanic or Latinx,4,Non-Binary
5,White or Caucasian,99,Unknown
3,Black or African American,4,Non-Binary
4,Hispanic or Latinx,99,Unknown
5,White or Caucasian,,
6,Prefer not to disclose,,
7,Prefer to self-describe,,
8,Middle Eastern,,

1 Race Qualtrics Code Race/Ethnicity Gender Qualtrics Code Sex/Gender
2 1 American Indian or Alaskan Native 2 Male
3 2 Asian or Pacific Islander 1 Female
4 3 Black or African American 3 4 Another gender or gender identity not listed above Non-Binary
5 4 Hispanic or Latinx 4 99 Non-Binary Unknown
6 5 White or Caucasian 99 Unknown
7 6 Prefer not to disclose
8 7 Prefer to self-describe
9 8 Middle Eastern

@ -0,0 +1,45 @@
require 'rails_helper'
include Analyze::Graph
include Analyze::Graph::Column::Gender
describe StudentsByRace do
let(:female) { create(:gender, qualtrics_code: 1, designation: 'Female') }
let(:school) { create(:school) }
let(:academic_year) { create(:academic_year, range: '1900-01') }
let(:academic_years) { [academic_year] }
let(:year_index) { academic_years.find_index(academic_year) }
let(:measure_with_student_survey_items) { create(:measure, name: 'Student measure') }
let(:scale_with_student_survey_item) { create(:student_scale, measure: measure_with_student_survey_items) }
let(:student_survey_item) do
create(:student_survey_item, scale: scale_with_student_survey_item)
end
before do
create_list(:survey_item_response, 1, survey_item: student_survey_item, school:, academic_year:, gender: female)
end
context '.gender' do
it 'returns female gender' do
expect(Female.new(measure: measure_with_student_survey_items, school:, academic_years:, position: year_index,
number_of_columns: 1).gender).to eq female
end
it 'returns the count of survey items for females for that school and academic_year ' do
female_column = Female.new(measure: measure_with_student_survey_items, school:, academic_years:, position: year_index,
number_of_columns: 1)
expect(female_column.sufficient_student_responses?(academic_year:)).to eq false
end
context 'when there are more than 10 students who responded' do
before do
create_list(:survey_item_response, 10, survey_item: student_survey_item, school:, academic_year:,
gender: female)
end
it 'returns the count of survey items for females for that school and academic_year ' do
female_column = Female.new(measure: measure_with_student_survey_items, school:, academic_years:, position: year_index,
number_of_columns: 1)
expect(female_column.sufficient_student_responses?(academic_year:)).to eq true
end
end
end
end

@ -9,7 +9,7 @@ describe DemographicLoader do
let(:gender_codes) do
{
'Female' => 1, 'Male' => 2, 'Another gender or gender identity not listed above' => 3, 'Non-Binary' => 4, 'Unknown' => 99
'Female' => 1, 'Male' => 2, 'Non-Binary' => 4, 'Unknown' => 99
}
end
@ -37,7 +37,7 @@ describe DemographicLoader do
end
it 'loads all gender designations' do
expect(Gender.all.count).to eq 5
expect(Gender.all.count).to eq 4
gender_codes.each do |key, value|
expect(Gender.find_by_qualtrics_code(value)).not_to eq nil

@ -187,7 +187,7 @@ end
def assigns_gender_to_responses
results = { 'student_survey_response_1' => female,
'student_survey_response_3' => male,
'student_survey_response_4' => another_gender,
'student_survey_response_4' => non_binary,
'student_survey_response_5' => non_binary,
'student_survey_response_6' => unknown_gender,
'student_survey_response_7' => unknown_gender }

@ -80,6 +80,15 @@ describe 'analyze/index' do
(1..12).to_a
end
let(:genders) do
DemographicLoader.load_data(filepath: 'spec/fixtures/sample_demographics.csv')
Gender.all
end
let(:selected_genders) do
genders
end
let(:selected_grades) do
grades
end
@ -106,6 +115,8 @@ describe 'analyze/index' do
assign :slice, slice
assign :grades, grades
assign :selected_grades, selected_grades
assign :genders, genders
assign :selected_genders, selected_genders
create(:respondent, school:, academic_year:)
create(:survey, school:, academic_year:)
end

Loading…
Cancel
Save