copycats 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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