feat: create a report at the survey item response level that shows averages by student to selected measures
parent
7f0b52029d
commit
82bdc076de
@ -0,0 +1,120 @@
|
|||||||
|
# Report::SurveyItemResponse.create(schools: District.find_by_name("Lee Public Schools").schools, academic_years: AcademicYear.where(range: "2023-24 Spring"), filename: "test.csv")
|
||||||
|
module Report
|
||||||
|
class SurveyItemResponse
|
||||||
|
def self.create(schools:, academic_years:, filename:)
|
||||||
|
data = []
|
||||||
|
data << ["Response ID", "Race", "Gender", "Grade", "School ID", "District", "Academic Year", "Student Physical Safety",
|
||||||
|
"Student Emotional Safety", "Student Sense of Belonging", "Student-Teacher Relationships", "Valuing of Learning", "Academic Challenge", "Content Specialists & Support Staff", "Cultural Responsiveness", "Engagement In School", "Appreciation For Diversity", "Civic Participation", "Perseverance & Determination", "Growth Mindset", "Participation In Creative & Performing Arts", "Valuing Creative & Performing Arts", "Social & Emotional Health"]
|
||||||
|
|
||||||
|
mutex = Thread::Mutex.new
|
||||||
|
pool_size = 2
|
||||||
|
jobs = Queue.new
|
||||||
|
schools.each { |school| jobs << school }
|
||||||
|
|
||||||
|
workers = pool_size.times.map do
|
||||||
|
Thread.new do
|
||||||
|
while school = jobs.pop(true)
|
||||||
|
academic_years.each do |academic_year|
|
||||||
|
response_hash = {}
|
||||||
|
survey_item_responses = ::SurveyItemResponse
|
||||||
|
.includes([student: :races])
|
||||||
|
.includes([school: :district])
|
||||||
|
.includes([:gender])
|
||||||
|
.where(school:, academic_year:, survey_item: student_survey_items_with_sufficient_responses(school:,
|
||||||
|
academic_year:))
|
||||||
|
survey_item_responses.each do |sir|
|
||||||
|
response_hash[sir.response_id] = if response_hash[sir.response_id].nil?
|
||||||
|
[sir]
|
||||||
|
else
|
||||||
|
response_hash[sir.response_id] << sir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
respondents = Respondent.by_school_and_year(school:, academic_year:)
|
||||||
|
next if respondents.nil?
|
||||||
|
|
||||||
|
response_hash.each do |_key, responses|
|
||||||
|
mutex.synchronize do
|
||||||
|
row = []
|
||||||
|
info = responses.first
|
||||||
|
response_id = info.response_id
|
||||||
|
row << [response_id,
|
||||||
|
info.student.races.map { |race| race.designation }.join("\n"),
|
||||||
|
info.gender.designation,
|
||||||
|
info.grade,
|
||||||
|
info.school.name,
|
||||||
|
info.school.district.name,
|
||||||
|
academic_year.range,
|
||||||
|
average_for_measure("2A-i", responses),
|
||||||
|
average_for_measure("2A-ii", responses),
|
||||||
|
average_for_measure("2B-i", responses),
|
||||||
|
average_for_measure("2B-ii", responses),
|
||||||
|
average_for_measure("2C-i", responses),
|
||||||
|
average_for_measure("2C-ii", responses),
|
||||||
|
average_for_measure("3A-ii", responses),
|
||||||
|
average_for_measure("3B-ii", responses),
|
||||||
|
average_for_measure("4B-i", responses),
|
||||||
|
average_for_measure("5A-i", responses),
|
||||||
|
average_for_measure("5A-ii", responses),
|
||||||
|
average_for_measure("5C-i", responses),
|
||||||
|
average_for_measure("5C-ii", responses),
|
||||||
|
average_for_measure("5D-i", responses)]
|
||||||
|
|
||||||
|
data.concat(row)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue ThreadError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
workers.each(&:join)
|
||||||
|
FileUtils.mkdir_p Rails.root.join("tmp", "reports")
|
||||||
|
filepath = Rails.root.join("tmp", "reports", filename)
|
||||||
|
write_csv(data:, filepath:)
|
||||||
|
data
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.average_for_measure(measure_id, responses)
|
||||||
|
selected_responses = responses.select do |response|
|
||||||
|
student_survey_items_for_measure(measure_id).include?(response.survey_item_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
average = selected_responses.map(&:likert_score).average
|
||||||
|
average = average.round(2) unless average.nil?
|
||||||
|
average = "" if average.nan?
|
||||||
|
average
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.student_survey_items_for_measure(measure_id)
|
||||||
|
@student_survey_items_for_measure ||= Hash.new do |memo, measure_id|
|
||||||
|
memo[measure_id] = ::Measure.find_by_measure_id(measure_id).student_survey_items.map(&:id)
|
||||||
|
end
|
||||||
|
@student_survey_items_for_measure[measure_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.write_csv(data:, filepath:)
|
||||||
|
csv = CSV.generate do |csv|
|
||||||
|
data.each do |row|
|
||||||
|
csv << row
|
||||||
|
end
|
||||||
|
end
|
||||||
|
File.write(filepath, csv)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.student_survey_items_with_sufficient_responses(school:, academic_year:)
|
||||||
|
@student_survey_items_with_sufficient_responses ||= Hash.new do |memo, (school, academic_year)|
|
||||||
|
memo[[school, academic_year]] = ::SurveyItem.where(id: ::SurveyItem.joins("inner join survey_item_responses on survey_item_responses.survey_item_id = survey_items.id")
|
||||||
|
.student_survey_items
|
||||||
|
.where("survey_item_responses.school": school,
|
||||||
|
"survey_item_responses.academic_year": academic_year,
|
||||||
|
"survey_item_responses.survey_item_id": ::SurveyItem.student_survey_items,
|
||||||
|
"survey_item_responses.grade": school.grades(academic_year:))
|
||||||
|
.group("survey_items.id")
|
||||||
|
.having("count(*) >= 10")
|
||||||
|
.count.keys)
|
||||||
|
end
|
||||||
|
@student_survey_items_with_sufficient_responses[[school, academic_year]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in new issue