Class: Artbase::Base
- Inherits:
-
Object
- Object
- Artbase::Base
- Defined in:
- lib/artbase/collection/base.rb
Overview
“abstract” Base collection - check -use a different name - why? why not?
Direct Known Subclasses
Instance Method Summary collapse
-
#_normalize_trait_type(trait_type) ⇒ Object
“private” helpers.
- #_normalize_trait_value(trait_value) ⇒ Object
-
#calc_attribute_counters ⇒ Object
todo/check: use a different name _counts/_stats etc - why? why not?.
- #dump_attributes ⇒ Object
-
#export_attributes(order: [], renames: {}) ⇒ Object
order - allow “custom” attribute order export renames - allow renames of attributes.
- #make_composite ⇒ Object
Instance Method Details
#_normalize_trait_type(trait_type) ⇒ Object
“private” helpers
248 249 250 251 252 253 254 |
# File 'lib/artbase/collection/base.rb', line 248 def _normalize_trait_type( trait_type ) if @patch && @patch[:trait_types] @patch[:trait_types][ trait_type ] || trait_type else trait_type end end |
#_normalize_trait_value(trait_value) ⇒ Object
256 257 258 259 260 261 262 |
# File 'lib/artbase/collection/base.rb', line 256 def _normalize_trait_value( trait_value ) if @patch && @patch[:trait_values] @patch[:trait_values][ trait_value ] || trait_value else trait_value end end |
#calc_attribute_counters ⇒ Object
todo/check: use a different name _counts/_stats etc - why? why not?
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/artbase/collection/base.rb', line 52 def calc_attribute_counters ## todo/check: use a different name _counts/_stats etc - why? why not? attributes_by_count = { count: 0, by_count: Hash.new(0) } counter = {} do |, id| ## todo/fix: change id to index traits = .traits # print "#{traits.size} - " # pp traits print "#{id}.." if id % 100 == 0 ## print progress report attributes_by_count[ :count ] +=1 attributes_by_count[ :by_count ][ traits.size ] += 1 traits.each do |trait_type, trait_value| trait_type = _normalize_trait_type( trait_type ) trait_value = _normalize_trait_value( trait_value ) rec = counter[ trait_type ] ||= { count: 0, by_type: Hash.new(0) } rec[ :count ] +=1 rec[ :by_type ][ trait_value ] += 1 end end print "\n" puts ## return all-in-one hash { total: attributes_by_count, traits: counter, } end |
#dump_attributes ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/artbase/collection/base.rb', line 94 def dump_attributes stats = calc_attribute_counters total = stats[:total] counter = stats[:traits] puts puts "attribute usage / counts:" pp total puts puts "#{counter.size} attribute(s):" counter.each do |trait_name, trait_rec| puts " #{trait_name} #{trait_rec[:count]} (#{trait_rec[:by_type].size} uniques)" end puts pp counter end |
#export_attributes(order: [], renames: {}) ⇒ Object
order - allow “custom” attribute order export
renames - allow renames of attributes
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/artbase/collection/base.rb', line 119 def export_attributes( order: [], renames: {} ) ## step 1: get counters stats = calc_attribute_counters total = stats[:total] counter = stats[:traits] puts puts "attribute usage / counts:" pp total puts puts "#{counter.size} attribute(s):" counter.each do |trait_name, trait_rec| puts " #{trait_name} #{trait_rec[:count]} (#{trait_rec[:by_type].size} uniques)" end trait_names = [] trait_names += order ## get attributes if any in pre-defined order counter.each do |trait_name, _| if trait_names.include?( trait_name ) next ## skip already included else trait_names << trait_name end end recs = [] ## step 2: get tabular data do |, id| ## todo/fix: change id to index traits = .traits # print "#{traits.size} - " # pp traits print "#{id}.." if id % 100 == 0 ## print progress report ## setup empty hash table (with all attributes) rec = {} ## note: use __Slug__& __Name__ ## to avoid conflict with attribute names ## e.g. attribute with "Name" will overwrite built-in and so on rec['__Slug__'] = if respond_to?( :_meta_slugify ) ( , id ) else ## default to id (six digits) as string with leading zeros ## for easy sorting using strings ## e.g. 1 => '000001' ## 2 => '000002' '%06d' % id end rec['__Name__'] = .name ## add all attributes/traits names/keys trait_names.reduce( rec ) { |h,value| h[value] = []; h } ## pp rec ## note: use an array (to allow multiple values for attributes) traits.each do |trait_type, trait_value| trait_type = _normalize_trait_type( trait_type ) trait_value = _normalize_trait_value( trait_value ) values = rec[ trait_type ] values << trait_value end recs << rec end print "\n" ## pp recs ## flatten recs data = [] recs.each do |rec| row = rec.values.map do |value| if value.is_a?( Array ) value.join( ' / ' ) else value end end data << row end ## sort by slug data = data.sort {|l,r| l[0] <=> r[0] } pp data ### save dataset ## note: change first colum Slug to ID - only used for "internal" sort etc. headers = ['ID', 'Name'] headers += trait_names.map do |trait_name| ## check for renames renames[trait_name] || trait_name end path = "./#{@slug}/tmp/#{@slug}.csv" dirname = File.dirname( path ) FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname ) File.open( path, 'w:utf-8' ) do |f| f.write( headers.join( ', ' )) f.write( "\n" ) ## note: replace ID with our own internal running (zero-based) counter data.each_with_index do |row,i| f.write( ([i]+row[1..-1]).join( ', ')) f.write( "\n" ) end end end |
#make_composite ⇒ Object
7 8 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 |
# File 'lib/artbase/collection/base.rb', line 7 def make_composite ### use well-known / pre-defined (default) grids ## (cols x rows) for now - why? why not? composite_count = @count - @excludes.size cols, rows = case composite_count when 99 then [10, 10] when 100 then [10, 10] when 150 then [15, 10] when 314 then [15, 21] when 500 then [25, 20] when 1000 then [25, 40] when 3000 then [100, 30] ## or use 50*60 - why? why not? when 3500 then [100, 35] ## or use 50*x ?? when 3979 then [100, 40] when 4000 then [100, 40] ## or use 50x80 - why? why not? when 5000 then [100, 50] ## or use 50x100 - why? why not? when 5555 then [100, 56] # 5600 (45 left empty) when 6969 then [100, 70] # 7000 (31 left empty) when 10000 then [100, 100] else raise ArgumentError, "sorry - unknown composite count #{composite_count}/#{@count} for now" end composite = ImageComposite.new( cols, rows, width: @width, height: @height ) each_image do |img, id| puts "==> #{id}" composite << img end composite.save( "./#{@slug}/tmp/#{@slug}-#{@width}x#{@height}.png" ) if composite_count < 1000 composite.zoom(2).save( "./#{@slug}/tmp/#{@slug}-#{@width}x#{@height}@2x.png" ) end end |