fat_core 1.4.0 → 1.5.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: b85c4931e6e06fcb0b7bf0359f67242fa06034b0
4
- data.tar.gz: fc263e3393af22aae09423a94430461f1c07d476
3
+ metadata.gz: d8f9197b29ac69c96409642ef86bb5a5bf3fdace
4
+ data.tar.gz: 6aeb17344e346ebfc21030523929036934eee6a4
5
5
  SHA512:
6
- metadata.gz: a69a5d129cc9135c87b628f45e1ca32869fca906bab23986ac4b0e93fb2bc75d52aaaf7b1da93828971b7d9fc9a5b8606c6daf45b22bcf3de976c5e68c90b639
7
- data.tar.gz: 15f2a2de60a73586a8c6c0b60f919a66dfd523f58a72adf55a995d93e2b13b52427b190e21a76ad3002567e47167ca44b88d162c04371c0a6f8613bbaafa60a1
6
+ metadata.gz: 3800832b0339a3c9deca6450bece102d33dc0a7912b18e9a0c743b85b438ba076bf1b290f70b0bd3a8d0fb48f65780be8375175d54aa50bd48fdf8dee89b05b3
7
+ data.tar.gz: 914b7895346e3a07422027e54b3ae11bdd5bed6297b3281488a93bd3e9a8d2b29efd7550b6510f32ec47c2bd5cd174762595f3f22b055ea0245f63de1de9d065
data/TODO.org CHANGED
@@ -1,10 +1,19 @@
1
1
  * Conversion to Spreadsheets
2
2
  This is a [[https://github.com/westonganger/spreadsheet_architect][gem]] that I can include into the Table model to convert a table into
3
3
  a spread-sheet, or even a sheet in a multi-sheet spreadsheet file.
4
+
4
5
  * Formatters
5
6
  Need to think about ways to define formatters for Table for different output
6
7
  types, including tty, color-tty, latex, csv, spreadsheet?
8
+
7
9
  * Add a Group Boundary concept
8
10
  If I want a table to perform sub-totals at various break points, need to have a
9
11
  way for a table to record its grouping boundaries. Maybe an array of row
10
12
  numbers? Automatically injected by the group-by method?
13
+
14
+ * DONE Add uniq method and set operations
15
+ CLOSED: [2017-03-02 Thu 15:54]
16
+ - State "WAIT" from "TODO" [2017-03-02 Thu 15:54]
17
+ - State "TODO" from [2017-03-02 Thu 15:54]
18
+ For tables, add a method that eliminates any duplicate rows. Perhaps just
19
+ apply Array#uniq to the columns?
@@ -2,4 +2,26 @@ class Array
2
2
  def last_i
3
3
  self.size - 1
4
4
  end
5
+
6
+ # Return a new array that is the intersection of this Array with other, but
7
+ # without removing duplicates as the :& method does.
8
+ def intersect(other)
9
+ result = []
10
+ each do |itm|
11
+ result << itm if other.include?(itm)
12
+ end
13
+ result
14
+ end
15
+
16
+ # Return an array that is the difference between this Array and the other, but
17
+ # without removing duplicates as the :- method does.
18
+ def difference(other)
19
+ result = deep_dup
20
+ other.each do |itm|
21
+ if (k = result.index(itm))
22
+ result.delete_at(k)
23
+ end
24
+ end
25
+ result
26
+ end
5
27
  end
data/lib/fat_core/hash.rb CHANGED
@@ -20,6 +20,7 @@ class Hash
20
20
  self
21
21
  end
22
22
 
23
+ # Change each key of this Hash to its value in key_map
23
24
  def remap_keys(key_map = {})
24
25
  new_hash = {}
25
26
  each_pair do |key, val|
@@ -31,4 +32,12 @@ class Hash
31
32
  end
32
33
  new_hash
33
34
  end
35
+
36
+ # Change the keys of this Hash to new_keys, an array of keys
37
+ def replace_keys(new_keys)
38
+ unless keys.size == new_keys.size
39
+ raise ArgumentError, 'replace_keys: new keys size differs from key size'
40
+ end
41
+ to_a.each_with_index.map { |(_k, v), i| [new_keys[i], v] }.to_h
42
+ end
34
43
  end
@@ -304,7 +304,7 @@ module FatCore
304
304
  # have N and M rows respectively, the joined table will have N * M
305
305
  # rows.
306
306
  #
307
- JOIN_TYPES = [ :inner, :left, :right, :full, :cross ]
307
+ JOIN_TYPES = [:inner, :left, :right, :full, :cross]
308
308
 
309
309
  def join(other, *exps, join_type: :inner)
310
310
  raise ArgumentError, 'need other table as first argument to join' unless other.is_a?(Table)
@@ -1,6 +1,6 @@
1
1
  module FatCore
2
2
  MAJOR = 1
3
- MINOR = 4
3
+ MINOR = 5
4
4
  PATCH = 0
5
5
 
6
6
  VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
@@ -5,4 +5,20 @@ describe Array do
5
5
  letters = ('a'..'z').to_a
6
6
  expect(letters.last_i).to eq(25)
7
7
  end
8
+
9
+ it 'intersection' do
10
+ expect(%w(A A B A C A B).intersect(%w(A B A))).to eq(%w(A A B A A B))
11
+ expect(%w(A A B A C A B).intersect(%w(A B))).to eq(%w(A A B A A B))
12
+ expect(%w(A A B A C A B).intersect(%w(A))).to eq(%w(A A A A))
13
+ expect(%w(A A B A C A B).intersect(%w(B))).to eq(%w(B B))
14
+ expect(%w(A A B A C A B).intersect(%w(C))).to eq(%w(C))
15
+ end
16
+
17
+ it 'difference' do
18
+ expect(%w(A A B A C A B).difference(%w(A B A))).to eq(%w(A C A B))
19
+ expect(%w(A A B A C A B).difference(%w(A B))).to eq(%w(A A C A B))
20
+ expect(%w(A A B A C A B).difference(%w(A))).to eq(%w(A B A C A B))
21
+ expect(%w(A A B A C A B).difference(%w(B))).to eq(%w(A A A C A B))
22
+ expect(%w(A A B A C A B).difference(%w(C))).to eq(%w(A A B A A B))
23
+ end
8
24
  end
@@ -519,61 +519,6 @@ EOS
519
519
  end
520
520
  end
521
521
 
522
- describe 'union' do
523
- it 'should be able to union with a compatible table' do
524
- aoh = [
525
- { a: '5', 'Two words' => '20', c: '3,123', d: 'apple' },
526
- { a: '4', 'Two words' => '5', c: 6412, d: 'orange' },
527
- { a: '7', 'Two words' => '8', c: '$1,888', d: 'apple' }
528
- ]
529
- tab1 = Table.new(aoh)
530
- aoh2 = [
531
- { t: '8', 'Two worlds' => '65', s: '5,143', u: 'kiwi' },
532
- { t: '87', 'Two worlds' => '12', s: 412, u: 'banana' },
533
- { t: '13', 'Two worlds' => '11', s: '$1,821', u: 'grape' }
534
- ]
535
- tab2 = Table.new(aoh2)
536
- utab = tab1.union(tab2)
537
- expect(utab.rows.size).to eq(6)
538
- end
539
-
540
- it 'should throw an exception for union with different sized tables' do
541
- aoh = [
542
- { a: '5', 'Two words' => '20', c: '3,123' },
543
- { a: '4', 'Two words' => '5', c: 6412 },
544
- { a: '7', 'Two words' => '8', c: '$1,888' }
545
- ]
546
- tab1 = Table.new(aoh)
547
- aoh2 = [
548
- { t: '8', 'Two worlds' => '65', s: '5,143', u: 'kiwi' },
549
- { t: '87', 'Two worlds' => '12', s: 412, u: 'banana' },
550
- { t: '13', 'Two worlds' => '11', s: '$1,821', u: 'grape' }
551
- ]
552
- tab2 = Table.new(aoh2)
553
- expect {
554
- tab1.union(tab2)
555
- }.to raise_error(/different number of columns/)
556
- end
557
-
558
- it 'should throw an exception for union with different types' do
559
- aoh = [
560
- { a: '5', 'Two words' => '20', s: '5143', c: '3123' },
561
- { a: '4', 'Two words' => '5', s: 412, c: 6412 },
562
- { a: '7', 'Two words' => '8', s: '$1821', c: '$1888' }
563
- ]
564
- tab1 = Table.new(aoh)
565
- aoh2 = [
566
- { t: '8', 'Two worlds' => '65', s: '2016-01-17', u: 'kiwi' },
567
- { t: '87', 'Two worlds' => '12', s: Date.today, u: 'banana' },
568
- { t: '13', 'Two worlds' => '11', s: '[2015-05-21]', u: 'grape' }
569
- ]
570
- tab2 = Table.new(aoh2)
571
- expect {
572
- tab1.union(tab2)
573
- }.to raise_error(/different types/)
574
- end
575
- end
576
-
577
522
  describe 'select' do
578
523
  it 'should be able to select by column names' do
579
524
  aoh = [
@@ -669,6 +614,7 @@ EOS
669
614
  end
670
615
 
671
616
  describe 'join' do
617
+ # These tests are taken from https://www.tutorialspoint.com/postgresql/postgresql_using_joins.htm
672
618
  before :all do
673
619
  @tab_a = Table.new([
674
620
  { id: 1, name: 'Paul', age: 32, address: 'California', salary: 20000, join_date: '2001-07-13' },
@@ -769,6 +715,93 @@ EOS
769
715
  end
770
716
  end
771
717
 
718
+ describe 'set operations' do
719
+ before :all do
720
+ aoh = [
721
+ { a: '5', 'Two words' => '20', c: '3,123', d: 'apple' },
722
+ { a: '4', 'Two words' => '5', c: 6412, d: 'orange' },
723
+ { a: '4', 'Two words' => '5', c: 6412, d: 'orange' },
724
+ { a: '7', 'Two words' => '8', c: '$1,888', d: 'apple' }
725
+ ]
726
+ @tab1 = Table.new(aoh)
727
+ aoh2 = [
728
+ { t: '8', 'Two worlds' => '65', s: '5,143', u: 'kiwi' },
729
+ { t: '87', 'Two worlds' => '12', s: 412, u: 'banana' },
730
+ { t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
731
+ { t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
732
+ { t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
733
+ { t: '13', 'Two worlds' => '11', s: '$1,821', u: 'grape' }
734
+ ]
735
+ @tab2 = Table.new(aoh2)
736
+ aoh2e = [
737
+ { t: '8', 'Two worlds' => '65', s: '5,143', u: 'kiwi' },
738
+ { t: '87', 'Two worlds' => '12', s: 412, u: 'banana' },
739
+ { t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
740
+ { t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
741
+ { t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
742
+ { t: '4', 'Two worlds' => '5', s: 6412, u: 'orange' },
743
+ { t: '13', 'Two worlds' => '11', s: '$1,821', u: 'grape' }
744
+ ]
745
+ @tab2e = Table.new(aoh2e)
746
+ # Fewer columns
747
+ aoh3 = [
748
+ { a: '5', 'Two words' => '20', c: '3,123' },
749
+ { a: '4', 'Two words' => '5', c: 6412 },
750
+ { a: '7', 'Two words' => '8', c: '$1,888' }
751
+ ]
752
+ @tab3 = Table.new(aoh3)
753
+ # Different types
754
+ aoh4 = [
755
+ { t: '8', 'Two worlds' => '65', s: '2016-01-17', u: 'kiwi' },
756
+ { t: '87', 'Two worlds' => '12', s: Date.today, u: 'banana' },
757
+ { t: '13', 'Two worlds' => '11', s: '[2015-05-21]', u: 'grape' }
758
+ ]
759
+ @tab4 = Table.new(aoh4)
760
+ end
761
+
762
+ it 'union' do
763
+ utab = @tab1.union(@tab2)
764
+ expect(utab.size).to eq(6)
765
+ end
766
+
767
+ it 'union_all' do
768
+ utab = @tab1.union_all(@tab2)
769
+ expect(utab.size).to eq(10)
770
+ end
771
+
772
+ it 'intersect' do
773
+ utab = @tab1.intersect(@tab2)
774
+ expect(utab.size).to eq(1)
775
+ end
776
+
777
+ it 'intersect_all' do
778
+ utab = @tab1.intersect_all(@tab2)
779
+ expect(utab.size).to eq(2)
780
+ end
781
+
782
+ it 'except' do
783
+ utab = @tab2.except(@tab1)
784
+ expect(utab.size).to eq(4)
785
+ end
786
+
787
+ it 'except_all' do
788
+ utab = @tab2e.except_all(@tab1)
789
+ expect(utab.size).to eq(5)
790
+ end
791
+
792
+ it 'should throw an exception for union with different sized tables' do
793
+ expect {
794
+ @tab1.union(@tab3)
795
+ }.to raise_error(/different number of columns/)
796
+ end
797
+
798
+ it 'should throw an exception for union with different types' do
799
+ expect {
800
+ @tab1.union(@tab4)
801
+ }.to raise_error(/different column types/)
802
+ end
803
+ end
804
+
772
805
  describe 'output' do
773
806
  it 'should be able to return itself as an array of arrays' do
774
807
  aoh = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel E. Doherty