Finishes #183092367. Adds ui and graphs to show grade level disaggregations
parent
6ed405d16d
commit
89a7f27b88
@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Eight < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 8'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
8
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Eleven < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 11'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
11
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Five < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 5'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
5
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Four < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 4'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
4
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Nine < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 9'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
9
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class One < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 1'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,27 @@
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
module ScoreForGrade
|
||||
def score(year_index)
|
||||
averages = SurveyItemResponse.averages_for_grade(measure.student_survey_items, school, academic_years[year_index], grade)
|
||||
average = bubble_up_averages(averages:)
|
||||
|
||||
Score.new(average:,
|
||||
meets_teacher_threshold: false,
|
||||
meets_student_threshold: true,
|
||||
meets_admin_data_threshold: false)
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Seven < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 7'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
7
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Six < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 6'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
6
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Ten < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 10'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
10
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Three < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 3'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
3
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Twelve < GroupedBarColumnPresenter
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 12'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
12
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Analyze
|
||||
module Graph
|
||||
module Column
|
||||
module Grade
|
||||
class Two < GroupedBarColumnPresenter
|
||||
attr_reader :sufficient_responses
|
||||
|
||||
include Analyze::Graph::Column::Grade::ScoreForGrade
|
||||
def label
|
||||
'Grade 2'
|
||||
end
|
||||
|
||||
def basis
|
||||
'student'
|
||||
end
|
||||
|
||||
def show_irrelevancy_message?
|
||||
false
|
||||
end
|
||||
|
||||
def show_insufficient_data_message?
|
||||
false
|
||||
end
|
||||
|
||||
def grade
|
||||
2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,50 @@
|
||||
module Analyze
|
||||
module Graph
|
||||
class StudentsByGrade
|
||||
include Analyze::Graph::Column::Grade
|
||||
attr_reader :grades
|
||||
|
||||
def initialize(grades:)
|
||||
@grades = grades
|
||||
end
|
||||
|
||||
def to_s
|
||||
'Students by Grade'
|
||||
end
|
||||
|
||||
def slug
|
||||
'students-by-grade'
|
||||
end
|
||||
|
||||
def columns
|
||||
[].tap do |array|
|
||||
grades.each do |grade|
|
||||
array << column_for_grade_code(code: grade)
|
||||
end
|
||||
array << Analyze::Graph::Column::AllStudent
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def column_for_grade_code(code:)
|
||||
CFR[code]
|
||||
end
|
||||
|
||||
CFR = {
|
||||
1 => One,
|
||||
2 => Two,
|
||||
3 => Three,
|
||||
4 => Four,
|
||||
5 => Five,
|
||||
6 => Six,
|
||||
7 => Seven,
|
||||
8 => Eight,
|
||||
9 => Nine,
|
||||
10 => Ten,
|
||||
11 => Eleven,
|
||||
12 => Twelve,
|
||||
}.freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,13 @@
|
||||
module Analyze
|
||||
module Group
|
||||
class Grade
|
||||
def name
|
||||
'Grade'
|
||||
end
|
||||
|
||||
def slug
|
||||
'grade'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,13 @@
|
||||
module Analyze
|
||||
module Group
|
||||
class Race
|
||||
def name
|
||||
'Race'
|
||||
end
|
||||
|
||||
def slug
|
||||
'race'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,17 @@
|
||||
module Analyze
|
||||
module Slice
|
||||
class StudentsAndTeachers
|
||||
def to_s
|
||||
'Students & Teachers'
|
||||
end
|
||||
|
||||
def slug
|
||||
'students-and-teachers'
|
||||
end
|
||||
|
||||
def graphs
|
||||
[Analyze::Graph::StudentsAndTeachers.new]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,24 @@
|
||||
module Analyze
|
||||
module Slice
|
||||
class StudentsByGroup
|
||||
attr_reader :races, :grades
|
||||
|
||||
def initialize(races:, grades:)
|
||||
@races = races
|
||||
@grades = grades
|
||||
end
|
||||
|
||||
def to_s
|
||||
'Students by Group'
|
||||
end
|
||||
|
||||
def slug
|
||||
'students-by-group'
|
||||
end
|
||||
|
||||
def graphs
|
||||
[Analyze::Graph::StudentsByRace.new(races:), Analyze::Graph::StudentsByGrade.new(grades:)]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,20 @@
|
||||
module Analyze
|
||||
module Source
|
||||
class SurveyData
|
||||
attr_reader :slices
|
||||
|
||||
include Analyze::Slice
|
||||
|
||||
def initialize(slices:)
|
||||
@slices = slices
|
||||
end
|
||||
# def to_s
|
||||
# 'Survey Data Only'
|
||||
# end
|
||||
|
||||
# def value
|
||||
# 'survey-data-only'
|
||||
# end
|
||||
end
|
||||
end
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,5 @@
|
||||
class AddGradeToSurveyItemResponse < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_column :survey_item_responses, :grade, :integer
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,18 @@
|
||||
class CreateScores < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
create_table :scores do |t|
|
||||
t.float :average
|
||||
t.boolean :meets_teacher_threshold
|
||||
t.boolean :meets_student_threshold
|
||||
t.boolean :meets_admin_data_threshold
|
||||
t.integer :group
|
||||
t.references :measure, null: false, foreign_key: true
|
||||
t.references :school, null: false, foreign_key: true
|
||||
t.references :academic_year, null: false, foreign_key: true
|
||||
t.integer :grade
|
||||
t.references :race, null: false, foreign_key: true
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,5 @@
|
||||
class AddGradeIndexToSurveyItemResponse < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_index :survey_item_responses, [:school_id, :survey_item_id, :academic_year_id, :grade], name: "index_survey_responses_on_grade"
|
||||
end
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,58 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Score, type: :model do
|
||||
let(:zones) do
|
||||
Zones.new(watch_low_benchmark: 1.5, growth_low_benchmark: 2, approval_low_benchmark: 3,
|
||||
ideal_low_benchmark: 4)
|
||||
end
|
||||
|
||||
let(:warning) do
|
||||
zones.warning_zone
|
||||
end
|
||||
let(:watch) do
|
||||
zones.watch_zone
|
||||
end
|
||||
let(:growth) do
|
||||
zones.growth_zone
|
||||
end
|
||||
let(:approval) do
|
||||
zones.approval_zone
|
||||
end
|
||||
let(:ideal) do
|
||||
zones.ideal_zone
|
||||
end
|
||||
|
||||
context '.in_zone?' do
|
||||
it('returns true if the score is in the warning zone') do
|
||||
score = Score.new(average: 1)
|
||||
expect(score.in_zone?(zone: warning)).to eq true
|
||||
expect(score.in_zone?(zone: watch)).to eq false
|
||||
expect(score.in_zone?(zone: growth)).to eq false
|
||||
expect(score.in_zone?(zone: approval)).to eq false
|
||||
expect(score.in_zone?(zone: ideal)).to eq false
|
||||
end
|
||||
|
||||
it('returns true if the score is in the watch zone') do
|
||||
score = Score.new(average: 1.5)
|
||||
expect(score.in_zone?(zone: warning)).to eq true
|
||||
expect(score.in_zone?(zone: watch)).to eq true
|
||||
expect(score.in_zone?(zone: growth)).to eq false
|
||||
expect(score.in_zone?(zone: approval)).to eq false
|
||||
expect(score.in_zone?(zone: ideal)).to eq false
|
||||
end
|
||||
end
|
||||
context '.blank?' do
|
||||
it 'returns true if the average is nil zero or not a number' do
|
||||
expect(Score.new(average: 0).blank?).to eq true
|
||||
expect(Score.new(average: nil).blank?).to eq true
|
||||
nan = Float::NAN
|
||||
expect(Score.new(average: nan).blank?).to eq true
|
||||
end
|
||||
|
||||
it 'returns false if the average is a non-zero float' do
|
||||
expect(Score.new(average: 1).blank?).to eq false
|
||||
expect(Score.new(average: 0.1).blank?).to eq false
|
||||
expect(Score.new(average: -0.1).blank?).to eq false
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in new issue