Class: EwsDataReader
- Inherits:
-
Object
- Object
- EwsDataReader
- Defined in:
- lib/udise_school_report_reader/ews_data_reader.rb
Constant Summary collapse
- GRADES =
[ 'Pre-Pri.', 'Class I', 'Class II', 'Class III', 'Class IV', 'Class V', 'Class VI', 'Class VII', 'Class VIII', 'Class IX', 'Class X', 'Class XI', 'Class XII' ]
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(csv_path) ⇒ EwsDataReader
constructor
A new instance of EwsDataReader.
- #read ⇒ Object
Constructor Details
#initialize(csv_path) ⇒ EwsDataReader
Returns a new instance of EwsDataReader.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/udise_school_report_reader/ews_data_reader.rb', line 9 def initialize(csv_path) @csv_path = csv_path @rows = Hash.new { |h, k| h[k] = [] } # Group cells by rect_y and rect_x CSV.foreach(@csv_path, headers: true) do |cell| next unless cell['page'] == '1' rect_y = cell['rect_y'].to_f @rows[rect_y] << cell end # Find the title row @title_row = @rows.find { |_, cells| cells.any? { |cell| cell&.dig('text')&.include?('Total no. of Economically Weaker Section*(EWS) students Enrolled in Schools') } } title_y = @title_row&.first return unless title_y # Get all rows below title in descending order rows_after_title = @rows.select { |y, _| y < title_y.to_f } .sort_by(&:first) .reverse # Get the next 3 rows after title return unless rows_after_title.size >= 3 @grades_row = rows_after_title[0].last @bg_row = rows_after_title[1].last @values_row = rows_after_title[2].last # Sort cells within each row by x coordinate [@grades_row, @bg_row].each do |row| next unless row row.sort_by! { |cell| cell['text_x'].to_f } end # For values row, ensure we have a value for each B/G pair if @values_row && @bg_row sorted_values = [] @bg_row.each_slice(2) do |b, g| b_x = b['text_x'].to_f g_x = g['text_x'].to_f # Find or create value for boys b_val = @values_row.find { |cell| (cell['text_x'].to_f - b_x).abs < 10.0 } b_val ||= { 'text' => '-', 'text_x' => b_x } sorted_values << b_val # Find or create value for girls g_val = @values_row.find { |cell| (cell['text_x'].to_f - g_x).abs < 10.0 } g_val ||= { 'text' => '-', 'text_x' => g_x } sorted_values << g_val end @values_row = sorted_values end # Normalize empty values to "-" @values_row&.each { |cell| cell['text'] = '-' if cell['text'].strip.empty? } # Ensure we have all grades found_grades = @grades_row.map { |cell| cell['text'] } missing_grades = GRADES - found_grades if missing_grades.any? # Removed puts statement end end |
Class Method Details
.read(csv_path) ⇒ Object
7 |
# File 'lib/udise_school_report_reader/ews_data_reader.rb', line 7 def self.read(csv_path) = new(csv_path).read |
Instance Method Details
#read ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/udise_school_report_reader/ews_data_reader.rb', line 76 def read return nil unless @grades_row && @bg_row && @values_row # Group B,G pairs, ensuring we have complete pairs bg_pairs = {} @bg_row.each_slice(2) do |pair| next unless pair.size == 2 && pair[0] && pair[1] # Skip incomplete pairs b, g = pair x_mid = (b['text_x'].to_f + g['text_x'].to_f) / 2 bg_pairs[x_mid] = [b, g] end # Match numbers to pairs { grade_rows: @grades_row, bg_pairs: bg_pairs, ews_numbers: match_numbers_to_pairs(@values_row, bg_pairs), } end |