copycats 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 193a7fca413f909c49b164c401c759c59558b588
4
- data.tar.gz: d17d5bfcdc7b4a33326bae50f242e63d6a9cd3f5
3
+ metadata.gz: 30ab48ee0c735efb58576dbe0a5d3551bf75cf8b
4
+ data.tar.gz: 36b71fec5e5d77dcef7b7fd6bdfe49a9eac0faf4
5
5
  SHA512:
6
- metadata.gz: 38214f3ca5802623507c017de1301aeba073fa7a2f2a69305ca999a5202531f4fa2936069e5fabe1f8602ae60092d710f7606644b50862590d336f9b50c1e1a1
7
- data.tar.gz: c24978227a5dfe9b53010b66cc9cbf25b0798df20398865ee69982a61b886bb62f7db4c0eb34e3fc70c12c9e47aa12fa6b23e9d5d94cccede5ead4b841f183ee
6
+ metadata.gz: 6c4d1b2aa013871c099267ad5f37ea487c659c5863b4a00410b85a66b6b1095309386143d073f73f2e675248db6902a7b136217f0102fa3478be247f6a9ddae1
7
+ data.tar.gz: 77670aa204f204e0a82a3eb122d0a3b9ef4009d111af67fa37b2407b10a8606a530dda12619097131fb298a79938da12b596e965792335ba8d686ae085dd260a
data/README.md CHANGED
@@ -33,7 +33,6 @@ get (auto-)read. Use the `-i/--include` option to change the data directory.
33
33
 
34
34
 
35
35
 
36
-
37
36
  ### Kitty Genes Reader / Report
38
37
 
39
38
  Pass in the id (e.g. `1`, `43`, etc.) of the kitty to print a genes report.
@@ -239,6 +238,137 @@ Mouth (Genes 32-35)
239
238
 
240
239
 
241
240
 
241
+ ## Database Tables
242
+
243
+ Table Diagram
244
+
245
+ ![](copycats-tables.png)
246
+
247
+
248
+ ## Database Queries
249
+
250
+ ### SQL
251
+
252
+ #### Find all kitties with a trait
253
+
254
+ Let's use the trait savannah (fur) with the id 0:
255
+
256
+ ``` sql
257
+ SELECT id FROM kitties WHERE body_id = 0
258
+ ```
259
+
260
+ #### Find all kitties with two traits
261
+
262
+ Let's use the trait savannah (fur) with the id 0
263
+ and the trait tiger (pattern) with the id 33:
264
+
265
+ ``` sql
266
+ SELECT id FROM kitties
267
+ WHERE body_id = 0 AND pattern_id = 33
268
+ ```
269
+
270
+
271
+ #### Find all kitties with a trait (in any gene d/r1/r2/r3)
272
+
273
+ Note: All traits (12 x 32 = 384) are numbered with ids from 0 to 383 in the traits database table.
274
+ Let's use the trait savannah (fur) with the id 0:
275
+
276
+ ``` sql
277
+ SELECT kitty_id FROM genes WHERE trait_id = 0
278
+ ```
279
+
280
+
281
+ #### Find all kitties with a dominant (visible) trait
282
+
283
+ Note: Use `gene` column (`d`/`r1`/`r2`/`r3`) or the numeric `gene_n`
284
+ column (0/1/2/3): Let's use the trait savannah (fur) with the id 0
285
+ and a dominant (d) gene:
286
+
287
+
288
+ ``` sql
289
+ SELECT kitty_id FROM genes
290
+ WHERE trait_id = 0 AND gene='d'
291
+ ```
292
+
293
+
294
+ #### Find all kitties with two traits (in any gene d/r1/r2/r3)
295
+
296
+ Use two query with "intersect" the result. Let's
297
+ use the trait savannah (fur) with the id 0
298
+ and the trait tiger (pattern) with the id 33:
299
+
300
+ ``` sql
301
+ SELECT kitty_id FROM genes WHERE trait_id = 0
302
+ INTERSECT
303
+ SELECT kitty_id FROM genes WHERE trait_id = 33
304
+ ```
305
+
306
+
307
+ ### Using Models w/ ActiveRecord in Ruby
308
+
309
+
310
+ #### Find all kitties with a trait
311
+
312
+ Let's use the trait savannah (fur) with the id 0:
313
+
314
+ ``` ruby
315
+ Kitty.find_by( body: Trait.find_by( name: 'savannah' ))
316
+ # -or -
317
+ Kitty.find_by( body_id: 0)
318
+ ```
319
+
320
+ #### Find all kitties with two traits
321
+
322
+ Let's use the trait savannah (fur) with the id 0
323
+ and the trait tiger (pattern) with the id 33:
324
+
325
+ ``` ruby
326
+ Kitty.find_by( body: Trait.find_by( name: 'savannah' ),
327
+ pattern: Trait.find_by( name: 'tiger' ))
328
+ # -or -
329
+ Kitty.find_by( body_id: 0, pattern_id: 33 )
330
+ ```
331
+
332
+
333
+ #### Find all kitties with a trait (in any gene d/r1/r2/r3)
334
+
335
+ Let's use the trait savannah (fur) with the id 0:
336
+
337
+ ``` ruby
338
+ genes = Gene.find_by( trait: Trait.find_by( name: 'savannah' )) # query
339
+ #-or-
340
+ genes = Gene.find_by( trait_id: 0 )
341
+ genes.map { |gene| gene.kitty } # get kitties (from gene)
342
+ ```
343
+
344
+
345
+ #### Find all kitties with a dominant (visible) trait
346
+
347
+ Let's use the trait savannah (fur) with the id 0 and a dominant (d) gene:
348
+
349
+
350
+ ``` ruby
351
+ genes = Gene.find_by( trait: Trait.find_by( name: 'savannah' ),
352
+ d: 'd' ) #query
353
+ #-or-
354
+ genes = Gene.find_by( trait_id: 0, d: 'd' )
355
+ genes.map { |gene| gene.kitty } # get kitties (from gene)
356
+ ```
357
+
358
+
359
+ #### Find all kitties with two traits
360
+
361
+ Use two query with "intersect" the result. Let's
362
+ use the trait savannah (fur)
363
+ and the trait tiger (pattern):
364
+
365
+ ``` ruby
366
+ genes = Gene.select('kitty_id').where( trait: Trait.find_by( name: 'savannah' )).intersect(
367
+ Gene.select('kitty_id').where( trait: Trait.find_by( name: 'pattern' )))
368
+ genes.map { |gene| gene.kitty } # get kitties (from gene)
369
+ ```
370
+
371
+
242
372
 
243
373
  ## Quick References / Cheat Sheets
244
374
 
data/lib/copycats/data.rb CHANGED
@@ -32,46 +32,95 @@ def connect( config={} )
32
32
  database: db.path[1..-1],
33
33
  encoding: 'utf8'
34
34
  }
35
- else # assume sqlite3
35
+ else # assume sqlite3
36
36
  config = {
37
37
  adapter: db.scheme, # sqlite3
38
38
  database: db.path[1..-1] # world.db (NB: cut off leading /, thus 1..-1)
39
- }
40
- end
39
+ }
41
40
  end
42
-
43
- puts "Connecting to db using settings: "
44
- pp config
45
- ActiveRecord::Base.establish_connection( config )
46
- # ActiveRecord::Base.logger = Logger.new( STDOUT )
47
41
  end
48
42
 
49
43
 
50
- def setup_in_memory_db
51
- # Database Setup & Config
52
-
53
- ## ActiveRecord::Base.logger = Logger.new( STDOUT )
44
+ puts "Connecting to db using settings: "
45
+ pp config
46
+ ActiveRecord::Base.establish_connection( config )
47
+ ActiveRecord::Base.logger = Logger.new( STDOUT )
54
48
  ## ActiveRecord::Base.colorize_logging = false - no longer exists - check new api/config setting?
55
49
 
56
- connect( adapter: 'sqlite3',
57
- database: ':memory:' )
50
+ ## if sqlite3 add (use) some pragmas for speedups
51
+ if config[:adapter] == 'sqlite3'
52
+ ## check/todo: if in memory e.g. ':memory:' no pragma needed!!
53
+ con = ActiveRecord::Base.connection
54
+ con.execute( 'PRAGMA synchronous=OFF;' )
55
+ con.execute( 'PRAGMA journal_mode=OFF;' )
56
+ con.execute( 'PRAGMA temp_store=MEMORY;' )
57
+ end
58
+ end ## method connect
59
+
58
60
 
61
+ def setup_db
59
62
  ## build schema
60
63
  CreateDb.new.up
61
- end # setup_in_memory_db (using SQLite :memory:)
64
+ end
65
+
66
+
67
+
68
+ ### todo/fix:
69
+ ## make trait_ids_cache more (re)usable - fix global!!!!
70
+ TRAIT_IDS_CACHE = {}
71
+
72
+
73
+ def setup_traits
74
+ ## for speed - turn off logging for info/debug/etc. levels
75
+ ActiveRecord::Base.logger.level = :warn
76
+
77
+ ### add traits
78
+ TRAITS.each do |trait_key, trait_hash|
79
+
80
+ trait_t = Copycats::Model::TraitType.new
81
+ trait_t.name = trait_hash[:name]
82
+ trait_t.key = trait_key.to_s
83
+ trait_t.save!
84
+
85
+ cache = {}
86
+
87
+ Kai::ALPHABET.each_char.with_index do |kai,n|
88
+ name = trait_hash[:kai][kai]
89
+ name = '?' if name.nil? || name.empty?
62
90
 
91
+ tier = Kai::TIER[kai]
63
92
 
93
+ puts "Kai: #{kai} (#{n}) /#{tier}, Cattribute: #{name}"
94
+ trait = Copycats::Model::Trait.new
95
+ trait.name = name
96
+ trait.kai = kai
97
+ trait.n = n
98
+ trait.tier = tier
99
+ trait.trait_type_id = trait_t.id
100
+ trait.save!
64
101
 
65
- def setup( data_dir: './data' )
102
+ cache[ kai ] = trait.id
103
+ end
104
+
105
+ TRAIT_IDS_CACHE[ trait_key ] = { id: trait_t.id,
106
+ kai: cache }
107
+ end
108
+ end
109
+
110
+
111
+ def read_datafiles( data_dir: './data' )
66
112
  files = find_datafiles( data_dir )
67
113
  pp files
68
114
 
69
- ## check if files found
115
+ ## todo: check if files found
116
+
70
117
 
71
- ## setup sqlite in-memory db
72
- setup_in_memory_db()
118
+ ## for speed - turn off logging for info/debug/etc. levels
119
+ ActiveRecord::Base.logger.level = :warn
73
120
 
74
121
 
122
+ ## pp TRAIT_IDS_CACHE
123
+
75
124
  ## add / read / load all datafiles
76
125
  files.each_with_index do |file,i|
77
126
 
@@ -82,17 +131,90 @@ def setup( data_dir: './data' )
82
131
 
83
132
  ## note: for now use first 5 rows for testing
84
133
  ## kitties[0..4].each do |row|
134
+
135
+ ## start of kitties blockchain / genesis
136
+ genesisdate = Date.new( 2017, 11, 23) ## 2017-11-23
137
+
85
138
  kitties.each do |row|
86
139
  ## puts row['id'] + '|' + row['gen'] + '|' + row['genes_kai']
87
140
  k = Copycats::Model::Kitty.new
88
- k.id = row['id'].to_i
89
- k.gen = row['gen'].to_i
90
- k.genes = (row['genes'] || row['genes_kai'] || '').gsub( ' ', '' ) ## remove all spaces - why? why not?
141
+ k.id = row['id'].to_i
142
+ k.gen = row['gen'].to_i
143
+ k.matron_id = row['matron_id'] unless row['matron_id'].blank?
144
+ k.sire_id = row['sire_id'] unless row['sire_id'].blank?
145
+ k.name = row['name'] unless row['name'].blank?
146
+
147
+ ## todo: pretty print (format genes_kai !!!!)
148
+ k.genes_kai = row['genes'] || row['genes_kai'] ### .gsub( ' ', '' ) ## remove all spaces - why? why not?
149
+
150
+ ## pp row['birthdate']
151
+ birthdate = DateTime.strptime( row['birthdate'], '%Y-%m-%d %H:%M:%S' )
152
+ k.birthdate = birthdate
153
+ k.day_count = (birthdate.to_date.jd - genesisdate.jd)+1
154
+
155
+
156
+ genome = Genome.new( k.genes_kai )
157
+ genes = genome.genes
158
+
159
+ k.body_id = TRAIT_IDS_CACHE[:body][:kai][genes[:body].d]
160
+ k.pattern_id = TRAIT_IDS_CACHE[:pattern][:kai][genes[:pattern].d]
161
+ k.coloreyes_id = TRAIT_IDS_CACHE[:coloreyes][:kai][genes[:coloreyes].d]
162
+ k.eyes_id = TRAIT_IDS_CACHE[:eyes][:kai][genes[:eyes].d]
163
+ k.color1_id = TRAIT_IDS_CACHE[:color1][:kai][genes[:color1].d]
164
+ k.color2_id = TRAIT_IDS_CACHE[:color2][:kai][genes[:color2].d]
165
+ k.color3_id = TRAIT_IDS_CACHE[:color3][:kai][genes[:color3].d]
166
+ k.wild_id = TRAIT_IDS_CACHE[:wild][:kai][genes[:wild].d]
167
+ k.mouth_id = TRAIT_IDS_CACHE[:mouth][:kai][genes[:mouth].d]
168
+
91
169
  ## pp k
92
170
 
93
171
  ## print ids for progress report - why? why not?
94
172
  print "#{k.id}."
95
173
  k.save!
174
+
175
+ ## add genes
176
+ TRAITS.each_with_index do |(trait_key, trait_hash),i|
177
+ gene = genes[trait_key]
178
+ next if gene.nil? ## skip future_1, future_2, etc. for now - add - why? why not?
179
+
180
+ ## puts "#{trait_hash[:name]} (Genes #{trait_hash[:genes]})\n\n"
181
+
182
+ ## note: start counting for d.n with 1 (NOT 0)
183
+ ## use idx for zero-based counting - why? why not?
184
+
185
+ d = Copycats::Model::Gene.new
186
+ d.kitty_id = k.id
187
+ d.n = (i*4) # gene number/pos 0-47 (start w/ 1 why? why not?)
188
+ d.gene = 'd' # d (0), r1 (1), r2 (2), r3 (3)
189
+ d.gene_n = 0 # 0-3 (0=d,1=r1,2=r2,3=r3)
190
+ d.trait_id = TRAIT_IDS_CACHE[trait_key][:kai][gene.d]
191
+ d.save!
192
+
193
+ r1 = Copycats::Model::Gene.new
194
+ r1.kitty_id = k.id
195
+ r1.n = (i*4)+1 # gene number/pos 0-47 (start w/ 1 why? why not?)
196
+ r1.gene = 'r1' # d (0), r1 (1), r2 (2), r3 (3)
197
+ r1.gene_n = 1 # 0-3 (0=d,1=r1,2=r2,3=r3)
198
+ r1.trait_id = TRAIT_IDS_CACHE[trait_key][:kai][gene.r1]
199
+ r1.save!
200
+
201
+ r2 = Copycats::Model::Gene.new
202
+ r2.kitty_id = k.id
203
+ r2.n = (i*4)+2 # gene number/pos 0-47 (start w/ 1 why? why not?)
204
+ r2.gene = 'r2' # d (0), r1 (1), r2 (2), r3 (3)
205
+ r2.gene_n = 2 # 0-3 (0=d,1=r1,2=r2,3=r3)
206
+ r2.trait_id = TRAIT_IDS_CACHE[trait_key][:kai][gene.r2]
207
+ r2.save!
208
+
209
+ r3 = Copycats::Model::Gene.new
210
+ r3.kitty_id = k.id
211
+ r3.n = (i*4)+3 # gene number/pos 0-47 (start w/ 1 why? why not?)
212
+ r3.gene = 'r3' # d (0), r1 (1), r2 (2), r3 (3)
213
+ r3.gene_n = 3 # 0-3 (0=d,1=r1,2=r2,3=r3)
214
+ r3.trait_id = TRAIT_IDS_CACHE[trait_key][:kai][gene.r3]
215
+ r3.save!
216
+ end
217
+
96
218
  end
97
219
  print "\n"
98
220
  end
data/lib/copycats/gene.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  # encoding: utf-8
2
2
 
3
+
4
+ ### todo/check:
5
+ ## find a better name for Gene (incl.4 genes)
6
+ ## e.g. GeneFour, Gene4, GeneGroup, GeneSlice,TraitGenes,... -why? why not?
7
+
3
8
  class Gene
4
9
 
5
10
  attr_reader :d, :r1, :r2, :r3
@@ -1,13 +1,59 @@
1
1
  # encoding: utf-8
2
2
 
3
+ ##
4
+ # todo: rename file from kitty.rb to models.rb - why? why not?
5
+ # keep all models together in a single file? - why? why not?
6
+
7
+
3
8
  module Copycats
4
9
  module Model
5
10
 
6
11
  class Kitty < ActiveRecord::Base
7
- self.table_name = 'kitties'
12
+ ## self.table_name = 'kitties'
13
+
14
+ has_many :genes
15
+
16
+ belongs_to :sire, class_name: 'Kitty', foreign_key: 'sire_id'
17
+ belongs_to :matron, class_name: 'Kitty', foreign_key: 'matron_id'
8
18
 
19
+ ## convenience shortcuts for gene (d) traits
20
+ belongs_to :body, class_name: 'Trait', foreign_key: 'body_id'
21
+ belongs_to :pattern, class_name: 'Trait', foreign_key: 'pattern_id'
22
+ belongs_to :coloreyes, class_name: 'Trait', foreign_key: 'coloreyes_id'
23
+ belongs_to :eyes, class_name: 'Trait', foreign_key: 'eyes_id'
24
+ belongs_to :color1, class_name: 'Trait', foreign_key: 'color1_id'
25
+ belongs_to :color2, class_name: 'Trait', foreign_key: 'color2_id'
26
+ belongs_to :color3, class_name: 'Trait', foreign_key: 'color3_id'
27
+ belongs_to :wild, class_name: 'Trait', foreign_key: 'wild_id'
28
+ belongs_to :mouth, class_name: 'Trait', foreign_key: 'mouth_id'
29
+
30
+ ## todo: add more genes convenience shortcuts
31
+ ## has_many :genes_body
32
+ ## has_many :genes_pattern
9
33
  end # class Kitty
10
34
 
11
35
 
36
+ class TraitType < ActiveRecord::Base
37
+ ## self.table_name = 'trait_types'
38
+
39
+ has_many :traits
40
+ end # class TraitType
41
+
42
+
43
+ class Trait < ActiveRecord::Base
44
+ ## self.table_name = 'traits'
45
+
46
+ belongs_to :trait_types
47
+ end # class Trait
48
+
49
+
50
+ class Gene < ActiveRecord::Base
51
+ ## self.table_name = 'genes'
52
+
53
+ belongs_to :kitty
54
+ end # class Gene
55
+
56
+
57
+
12
58
  end # module Model
13
59
  end # module Copycats
@@ -11,7 +11,7 @@ class KittyReport
11
11
  ## for now alsways assume ActiveRecord - Kitty::Model
12
12
  kitty = args[0]
13
13
  @id = kitty.id
14
- @kai = fmt_kai( kitty.genes ) ## pretty print in groups of four (4)
14
+ @kai = fmt_kai( kitty.genes_kai ) ## pretty print in groups of four (4)
15
15
  end
16
16
  end
17
17
 
@@ -5,8 +5,8 @@ class MixReport
5
5
  def initialize( matron, sire )
6
6
  @matron_id = matron.id
7
7
  @sire_id = sire.id
8
- @matron_kai = fmt_kai( matron.genes ) ## pretty print in groups of four (4)
9
- @sire_kai = fmt_kai( sire.genes )
8
+ @matron_kai = fmt_kai( matron.genes_kai ) ## pretty print in groups of four (4)
9
+ @sire_kai = fmt_kai( sire.genes_kai )
10
10
  end
11
11
 
12
12
 
@@ -1,5 +1,18 @@
1
1
  # encoding: utf-8
2
2
 
3
+ #######################
4
+ ## yuml.me diagram:
5
+
6
+ =begin
7
+ [Kitties|id;gen;birthdate;day_count;genes_kai;name]1-<>48 (12x4)[Genes|n;gene;gene_n],
8
+ [Genes]0..*<>-1[Traits|n;kai;tier;name],
9
+ [Traits]32<>-1[Trait Types|name;key],
10
+ [Kitties]<-parents (matron x sire) [Kitties],
11
+ =end
12
+
13
+
14
+
15
+
3
16
  class CreateDb
4
17
 
5
18
  def up
@@ -9,10 +22,51 @@ ActiveRecord::Schema.define do
9
22
  create_table :kitties do |t|
10
23
  ### t.integer :ref, null: false ## reference id - todo - find a better name e.g. uid (for unique id?) or gid?
11
24
  ## note: use built-in id for id!!!!
12
-
13
- t.string :name ## optional name e.g. Genesis, Galaxy Cat, etc.
14
- t.string :genes ## genes in kai format
15
- t.integer :gen ## generation e.g. 0,1,2,etc.
25
+
26
+ t.string :name ## optional name e.g. Genesis, Galaxy Cat, etc.
27
+ t.string :genes_kai, null: false ## genes in kai format
28
+ t.integer :gen, null: false ## generation e.g. 0,1,2,etc.
29
+ t.datetime :birthdate, null: false
30
+ t.integer :day_count, null: false ## day 1, day 2, running day counter since 2017-11-23
31
+
32
+ t.references :matron ## optional references kitty (with matron id)
33
+ t.references :sire ## optional references kitty (with sire id)
34
+
35
+ ## for easy queries add convenience gene-d for all traits
36
+ t.references :body, null: false ## gene 0 (d)
37
+ t.references :pattern, null: false ## gene 4 (d)
38
+ t.references :coloreyes, null: false ## gene 8 (d)
39
+ t.references :eyes, null: false ## gene 12 (d)
40
+ t.references :color1, null: false ## gene 16 (d)
41
+ t.references :color2, null: false ## gene 20 (d)
42
+ t.references :color3, null: false ## gene 24 (d)
43
+ t.references :wild, null: false ## gene 28 (d)
44
+ t.references :mouth, null: false ## gene 32 (d)
45
+ end
46
+
47
+
48
+ create_table :genes do |t|
49
+ t.references :kitty, null: false
50
+ t.integer :n, null: false # gene number/pos 0-47 (start w/ 1 why? why not?)
51
+
52
+ t.string :gene, null: false # d, r1, r2, r3
53
+ t.integer :gene_n, null: false # 0-3 (0=d,1=r1,2=r2,3=r3 - start w/ 1 why? why not?)
54
+
55
+ t.references :trait, null: false
56
+ end
57
+
58
+
59
+ create_table :traits do |t|
60
+ t.references :trait_type, null: false
61
+ t.string :name, null: false
62
+ t.integer :n, null: false # 0-31 (decimal/base10)
63
+ t.string :kai, null: false # 1-x (kai/base32)
64
+ t.integer :tier # 1,2,3,4 - note: is nil (for x/31) for now (thus, optinal)
65
+ end
66
+
67
+ create_table :trait_types do |t|
68
+ t.string :name, null: false # use "pretty" name e.g. fur, highlight color, etc.
69
+ t.string :key, null: false # use key/ lowercase name from "official json api"
16
70
  end
17
71
 
18
72
 
data/lib/copycats/tool.rb CHANGED
@@ -10,10 +10,21 @@ def run( args )
10
10
  parser = OptionParser.new do |cmd|
11
11
  cmd.banner = "Usage: kitty [options]"
12
12
 
13
+ cmd.separator ""
14
+ cmd.separator " Database options:"
15
+
16
+ cmd.on("-n", "--dbname=NAME", "Database name (default: kitties.db)") do |name|
17
+ opts[:db_name] = name
18
+ end
19
+
20
+ cmd.on("-d", "--dbpath=PATH", "Database path (default: .)") do |path|
21
+ opts[:db_path] = path
22
+ end
23
+
13
24
  cmd.separator ""
14
25
  cmd.separator " Data options:"
15
26
 
16
- cmd.on("-i", "--include=DIR", "Data directory (default: ./data)") do |name|
27
+ cmd.on("-i", "--include=DIR", "Data directory (default: ./data for in-memory queries and . for setup)") do |name|
17
28
  opts[:data_dir] = name
18
29
  end
19
30
 
@@ -28,35 +39,69 @@ def run( args )
28
39
 
29
40
  parser.parse!( args )
30
41
  pp opts
42
+ pp args
31
43
 
32
44
 
33
- data_dir = opts[:data_dir] || './data'
45
+ db_path = opts[:db_path] || '.'
46
+ db_name = opts[:db_name] || 'kitties.db'
47
+ database = "#{db_path}/#{db_name}"
34
48
 
35
- setup( data_dir: data_dir )
36
49
 
37
- pp args
50
+ if args.size == 1 && args[0] == 'setup' ## setup database
51
+ connect( adapter: 'sqlite3',
52
+ database: database )
38
53
 
39
- if args.size == 1
40
- id = args[0].to_i
41
- kitty = Copycats::Model::Kitty.find( id )
42
- ## pp k
54
+ setup_db
55
+ setup_traits # note: also builds TRAIT_IDS_CACHE for read_datafiles for now
43
56
 
44
- buf = KittyReport.new( kitty ).build
57
+ data_dir = opts[:data_dir] || '.' ## for setup assume local dir for data
58
+ read_datafiles( data_dir: data_dir )
59
+ else
60
+ ## check if (local) database exists?
61
+ if File.exist?( database ) ## if yes, use "cached" local database
62
+ connect( adapter: 'sqlite3',
63
+ database: database )
64
+ else ## otherwise use (new) on-demand in-memory database
65
+ puts "note: database >#{database}<; setting up in-memory database"
66
+ connect( adapter: 'sqlite3',
67
+ database: ':memory:' )
68
+
69
+ setup_db
70
+ setup_traits # note: also builds TRAIT_IDS_CACHE for read_datafiles for now
71
+
72
+ data_dir = opts[:data_dir] || './data'
73
+ read_datafiles( data_dir: data_dir )
74
+ end
45
75
 
46
- puts buf
47
- elsif args.size == 2
48
- matron_id = args[0].to_i
49
- sire_id = args[1].to_i
50
76
 
51
- matron = Copycats::Model::Kitty.find( matron_id )
52
- sire = Copycats::Model::Kitty.find( sire_id )
53
- ## pp matron
54
77
 
55
- buf = MixReport.new( matron, sire ).build
78
+ if args.size == 1
79
+ id = args[0].to_i
80
+ kitty = Copycats::Model::Kitty.find( id )
56
81
 
57
- puts buf
58
- else
59
- puts "error: too many arguments (expected one or two kitty ids / names / genes)"
82
+ ## pp kitty
83
+ ## pp kitty.genes
84
+ ## pp kitty.body
85
+ ## pp kitty.pattern
86
+ ## pp kitty.genes.to_a
87
+
88
+ buf = KittyReport.new( kitty ).build
89
+
90
+ puts buf
91
+ elsif args.size == 2
92
+ matron_id = args[0].to_i
93
+ sire_id = args[1].to_i
94
+
95
+ matron = Copycats::Model::Kitty.find( matron_id )
96
+ sire = Copycats::Model::Kitty.find( sire_id )
97
+ ## pp matron
98
+
99
+ buf = MixReport.new( matron, sire ).build
100
+
101
+ puts buf
102
+ else
103
+ puts "error: too many arguments (expected setup or one or two kitty ids / names / genes)"
104
+ end
60
105
  end
61
106
  end ## method run
62
107
 
@@ -5,9 +5,11 @@
5
5
  # see https://cryptokittydex.com/kaittributes
6
6
  # https://docs.google.com/spreadsheets/d/1ShiBKSglFAB2vJe4Uow3iF09FBVq6ZAaOzTCIECf4iA
7
7
  # http://www.rolldice.club/cryptokitties/wkt_tree.php
8
+ # https://www.cryptokitties.co/cattributes (official cattributes list)
8
9
  #
9
-
10
-
10
+ #
11
+ # for latest updates on new cattributes see:
12
+ # https://updates.cryptokitties.co (official latest updates/timeline)
11
13
 
12
14
  ## ordered by gene position (0,1,3.4,5,... etc.)
13
15
  ## 12 traits (4 genes each)
@@ -4,8 +4,8 @@
4
4
  module Copycats
5
5
 
6
6
  MAJOR = 0
7
- MINOR = 5
8
- PATCH = 1
7
+ MINOR = 6
8
+ PATCH = 0
9
9
  VERSION = [MAJOR,MINOR,PATCH].join('.')
10
10
 
11
11
  def self.version
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: copycats
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-10 00:00:00.000000000 Z
11
+ date: 2018-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord