Class: Rust::GoogleForm
Constant Summary collapse
- ALLOWED_TYPES =
[:multiple, :checkbox, :scale, :text]
Class Method Summary collapse
-
.read(filename, schema, mappings = {}, **options) ⇒ Object
Reads the CSV at
filenameand returns a GoogleForm.
Instance Method Summary collapse
- #answer(i) ⇒ Object
- #answers ⇒ Object
- #answers_to(question) ⇒ Object
- #data_frame ⇒ Object
- #each_answer ⇒ Object
- #filter ⇒ Object
-
#initialize(data_frame, schema, mappings = {}) ⇒ GoogleForm
constructor
A new instance of GoogleForm.
- #mapped_data_frame ⇒ Object
- #percentual_answers_to(question, exclude = []) ⇒ Object
- #percentual_textual_answers_to(question, &block) ⇒ Object
- #raw_answers_to(question) ⇒ Object
- #rows ⇒ Object
- #textual_answers_to(question) ⇒ Object
Constructor Details
#initialize(data_frame, schema, mappings = {}) ⇒ GoogleForm
Returns a new instance of GoogleForm.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/rust/forms/google_forms.rb', line 87 def initialize(data_frame, schema, mappings={}) raise TypeError, "Expected Rust::DataFrame" unless data_frame.is_a?(Rust::DataFrame) raise TypeError, "Expected Hash or Array" if !schema.is_a?(Hash) && !schema.is_a?(Array) raise TypeError, "Schema keys must all be numbers or strings" if schema.is_a?(Hash) && !schema.keys.all? { |k| k.is_a?(String) } raise TypeError, "Mappings should be an hash [String, Integer] -> GoogleFormMapping" if !mappings.is_a?(Hash) || !mappings.keys.all? { |k| k.is_a?(String) || k.is_a?(Integer) } || !mappings.values.all? { |v| v.is_a?(GoogleFormMapping) } if schema.is_a?(Array) new_schema = {} for i in 0...schema.size new_schema[index_to_title(i+1, data_frame)] = schema[i] end schema = new_schema end raise TypeError, "Schema values must all be #{ALLOWED_TYPES}; #{schema.values.uniq - ALLOWED_TYPES} given instead" if !schema.values.all? { |v| ALLOWED_TYPES.include?(v)} raise TypeError, "Schema must include types for all the questions" if schema.size != (data_frame.columns - 1) @data_frame = data_frame @questions = data_frame.colnames @schema = schema mappings.each do |question, mapping| raise "Mappings can not be defined for :scale questions" if schema[title_to_index(question)] == :scale end @mappings = mappings end |
Class Method Details
.read(filename, schema, mappings = {}, **options) ⇒ Object
Reads the CSV at filename and returns a GoogleForm. The schema must be a hash that contains, for each question number or name, the type of answer (:multiple, :checkbox, :scale, or :text). For the other options, see Rust::CSV.read.
81 82 83 84 85 |
# File 'lib/rust/forms/google_forms.rb', line 81 def self.read(filename, schema, mappings={}, **) data_frame = Rust::CSV.read(filename, **) return GoogleForm.new(data_frame, schema, mappings) end |
Instance Method Details
#answer(i) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/rust/forms/google_forms.rb', line 128 def answer(i) row = @data_frame.row(i) @questions.each_with_index do |colname, i| if i == 0 row[colname] = Time.parse(row[colname]) else row[colname] = get_value(row[colname], colname) end end return row end |
#answers ⇒ Object
148 149 150 151 152 153 154 |
# File 'lib/rust/forms/google_forms.rb', line 148 def answers answers = [] for i in 0...@data_frame.rows answers << self.answer(i) end return answers end |
#answers_to(question) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/rust/forms/google_forms.rb', line 178 def answers_to(question) question = index_to_title(question) if question.is_a?(Integer) results = {} (@data_frame|question).each do |value| value = get_value(value, question) if value.is_a?(Array) value.each do |v| results[v] = 0 unless results[v] results[v] += 1 end else results[value] = 0 unless results[value] results[value] += 1 end end results.delete(nil) return results end |
#data_frame ⇒ Object
112 113 114 |
# File 'lib/rust/forms/google_forms.rb', line 112 def data_frame @data_frame end |
#each_answer ⇒ Object
142 143 144 145 146 |
# File 'lib/rust/forms/google_forms.rb', line 142 def each_answer for i in 0...@data_frame.rows yield(self.answer(i)) end end |
#filter ⇒ Object
156 157 158 159 160 161 162 163 164 |
# File 'lib/rust/forms/google_forms.rb', line 156 def filter matching = Rust::DataFrame.new(@questions) for i in 0...@data_frame.rows matching << @data_frame.row(i) if yield(self.answer(i)) end return GoogleForm.new(matching, @schema, @mappings) end |
#mapped_data_frame ⇒ Object
116 117 118 119 120 121 122 |
# File 'lib/rust/forms/google_forms.rb', line 116 def mapped_data_frame df = Rust::DataFrame.new(@data_frame.colnames) self.each_answer do |a| df << a end return df end |
#percentual_answers_to(question, exclude = []) ⇒ Object
218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/rust/forms/google_forms.rb', line 218 def percentual_answers_to(question, exclude=[]) answers = answers_to(question) exclude.each do |ex| answers.delete(ex) end tot = answers.values.sum answers = answers.map { |k, v| [k, v.to_f/tot] }.to_h return answers end |
#percentual_textual_answers_to(question, &block) ⇒ Object
230 231 232 233 234 235 236 |
# File 'lib/rust/forms/google_forms.rb', line 230 def percentual_textual_answers_to(question, &block) answers = textual_answers_to(question, &block) tot = answers.values.sum answers = answers.map { |k, v| [k, v.to_f/tot] }.to_h return answers end |
#raw_answers_to(question) ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/rust/forms/google_forms.rb', line 166 def raw_answers_to(question) question = index_to_title(question) if question.is_a?(Integer) results = [] (@data_frame|question).each do |value| value = get_value(value, question) results << value end return results end |
#rows ⇒ Object
124 125 126 |
# File 'lib/rust/forms/google_forms.rb', line 124 def rows @data_frame.rows end |
#textual_answers_to(question) ⇒ Object
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/rust/forms/google_forms.rb', line 200 def textual_answers_to(question) question = index_to_title(question) if question.is_a?(Integer) raise TypeError, "Expected textual question, #{@schema[question]} instead" if @schema[question] != :text results = {} (@data_frame|question).each do |value| value = get_value(value, question) next if value == nil category = yield(value) results[category] = 0 unless results[category] results[category] += 1 end return results end |