You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sqm-dashboards/app/models/report/survey_item_response.rb

121 lines
6.0 KiB

# 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