mirror of
https://github.com/edcommonwealth/sqm-dashboards.git
synced 2026-03-07 21:48:16 -08:00
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.
151 lines
5.6 KiB
Ruby
151 lines
5.6 KiB
Ruby
module Report
|
|
class MeasureSummary
|
|
def self.create_report(schools:, academic_years: AcademicYear.all, measures: ::Measure.all.order(measure_id: :ASC), filename: "measure_summary.csv")
|
|
data = to_csv(schools:, academic_years:, measures:)
|
|
FileUtils.mkdir_p Rails.root.join("tmp", "reports")
|
|
filepath = Rails.root.join("tmp", "reports", filename)
|
|
write_csv(data:, filepath:)
|
|
data
|
|
end
|
|
|
|
def self.to_csv(schools:, academic_years:, measures:)
|
|
data = []
|
|
mutex = Thread::Mutex.new
|
|
data << ["Measure Name", "Measure ID", "District", "Academic Year", "Recorded Date Range", "Grades", "Student Score", "Student Zone", "Teacher Score",
|
|
"Teacher Zone", "Admin Score", "Admin Zone", "All Score (Average)", "All Score Zone"]
|
|
pool_size = 2
|
|
jobs = Queue.new
|
|
measures.each { |measure| jobs << measure }
|
|
|
|
workers = pool_size.times.map do
|
|
Thread.new do
|
|
while measure = jobs.pop(true)
|
|
academic_years.each do |academic_year|
|
|
respondents = Respondent.where(school: schools, academic_year:)
|
|
|
|
enrollment = respondents.map do | respondent| respondent.enrollment_by_grade.keys end.flatten.compact.uniq.sort
|
|
grades_with_responses = ::SurveyItemResponse.where(school: schools, academic_year:).where.not(grade: nil).pluck(:grade).uniq.sort
|
|
all_grades = (enrollment & grades_with_responses).sort
|
|
grades = "#{all_grades.first}-#{all_grades.last}"
|
|
|
|
begin_date = ::SurveyItemResponse.where(school: schools,
|
|
academic_year:).where.not(recorded_date: nil).order(:recorded_date).first&.recorded_date&.to_date
|
|
end_date = ::SurveyItemResponse.where(school: schools,
|
|
academic_year:).where.not(recorded_date: nil).order(:recorded_date).last&.recorded_date&.to_date
|
|
date_range = "#{begin_date} - #{end_date}"
|
|
|
|
district = schools.first.district
|
|
row = [measure, district, academic_year]
|
|
|
|
mutex.synchronize do
|
|
data << [measure.name,
|
|
measure.measure_id,
|
|
district.name,
|
|
academic_year.range,
|
|
date_range,
|
|
grades,
|
|
student_score(row:),
|
|
student_zone(row:),
|
|
teacher_score(row:),
|
|
teacher_zone(row:),
|
|
admin_score(row:),
|
|
admin_zone(row:),
|
|
all_data_score(row:),
|
|
all_data_zone(row:)]
|
|
end
|
|
end
|
|
end
|
|
rescue ThreadError
|
|
end
|
|
end
|
|
|
|
workers.each(&:join)
|
|
|
|
CSV.generate do |csv|
|
|
data.each do |row|
|
|
csv << row
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.write_csv(data:, filepath:)
|
|
File.write(filepath, csv)
|
|
end
|
|
|
|
def self.all_data_score(row:)
|
|
row in [ measure, district, academic_year]
|
|
score = district.schools.map do |school|
|
|
score = measure.score(school:, academic_year:).average
|
|
end.remove_blanks.average
|
|
score || "N/A"
|
|
end
|
|
|
|
def self.all_data_zone(row:)
|
|
row in [ measure, district, academic_year]
|
|
|
|
average = all_data_score(row:)
|
|
score = Score.new(average:, meets_teacher_threshold: true, meets_student_threshold: true,
|
|
meets_admin_data_threshold: true)
|
|
student_zone = measure.zone_for_score(score:).type.to_s
|
|
|
|
student_zone || "N/A"
|
|
end
|
|
|
|
def self.student_score(row:)
|
|
row in [ measure, district, academic_year]
|
|
student_score = district.schools.map do |school|
|
|
student_score = measure.student_score(school:, academic_year:).average
|
|
end.remove_blanks.average
|
|
student_score || "N/A"
|
|
end
|
|
|
|
def self.student_zone(row:)
|
|
row in [ measure, district, academic_year]
|
|
average = student_score(row:)
|
|
score = Score.new(average:, meets_teacher_threshold: true, meets_student_threshold: true,
|
|
meets_admin_data_threshold: true)
|
|
student_zone = measure.zone_for_score(score:).type.to_s
|
|
|
|
student_zone || "N/A"
|
|
end
|
|
|
|
def self.teacher_score(row:)
|
|
row in [ measure, district, academic_year]
|
|
teacher_score = district.schools.map do |school|
|
|
measure.teacher_score(school:, academic_year:).average
|
|
end.remove_blanks.average
|
|
|
|
teacher_score || "N/A"
|
|
end
|
|
|
|
def self.teacher_zone(row:)
|
|
row in [ measure, district, academic_year]
|
|
average = teacher_score(row:)
|
|
score = Score.new(average:, meets_teacher_threshold: true, meets_student_threshold: true,
|
|
meets_admin_data_threshold: true)
|
|
teacher_zone = measure.zone_for_score(score:).type.to_s
|
|
|
|
teacher_zone || "N/A"
|
|
end
|
|
|
|
def self.admin_score(row:)
|
|
row in [ measure, district, academic_year]
|
|
admin_score = district.schools.map do |school|
|
|
measure.admin_score(school:, academic_year:).average
|
|
end.remove_blanks.average
|
|
|
|
admin_score = "N/A" unless admin_score.present? && admin_score >= 0
|
|
admin_score
|
|
end
|
|
|
|
def self.admin_zone(row:)
|
|
row in [ measure, district, academic_year]
|
|
average = admin_score(row:)
|
|
score = Score.new(average:, meets_teacher_threshold: true, meets_student_threshold: true,
|
|
meets_admin_data_threshold: true)
|
|
|
|
tmp_zone = measure.zone_for_score(score:).type.to_s
|
|
tmp_zone == :insufficient_data ? "N/A" : tmp_zone.to_s.capitalize
|
|
end
|
|
end
|
|
end
|