fat_table 0.2.6 → 0.3.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.
@@ -485,7 +485,7 @@ Another way to initialize a +FatTable+ table is with the results of a SQL query.
485
485
  database parameters to be used for the queries.
486
486
 
487
487
  require 'fat_table'
488
- FatTable.set_db(driver: 'Pg',
488
+ FatTable.connect(driver: 'Pg',
489
489
  database: 'XXX_development',
490
490
  user: 'dtd',
491
491
  password: 'slflpowert',
@@ -493,15 +493,15 @@ database parameters to be used for the queries.
493
493
  socket: '/tmp/.s.PGSQL.5432')
494
494
  tab = FatTable.from_sql('select * from trades;')
495
495
 
496
- Some of the parameters to the +.set_db+ function have defaults. The driver
496
+ Some of the parameters to the +.connect+ function have defaults. The driver
497
497
  defaults to 'Pg' for postgresql and the socket defaults to +/tmp/.s.PGSQL.5432+
498
498
  if the host is 'localhost', which it is by default. If the host is not
499
499
  'localhost', the dsn uses a port rather than a socket and defaults to port
500
500
  '5432'. While user and password default to nil, the database parameter is
501
501
  required.
502
502
 
503
- The +.set_db+ function need only be called once, and the database handle it
504
- creates will be used for all subsequent +.from_sql+ calls until +.set_db+ is
503
+ The +.connect+ function need only be called once, and the database handle it
504
+ creates will be used for all subsequent +.from_sql+ calls until +.connect+ is
505
505
  called again.
506
506
 
507
507
  === Marking Groups in Input
data/TODO.org CHANGED
@@ -1,3 +1,10 @@
1
+ * DONE Ensure that columns resulting from aggregates have proper type
2
+ CLOSED: [2017-12-29 Fri 05:34]
3
+ - State "WAIT" from "TODO" [2017-12-29 Fri 05:34]
4
+ - State "TODO" from [2017-11-27 Mon 04:46]
5
+ After applying avg, does the column have the proper Numeric or Date, or DateTime
6
+ type. How about Boolean aggregates?
7
+
1
8
  * TODO Conversion to Spreadsheets
2
9
  - State "TODO" from [2017-04-21 Fri 10:36]
3
10
  This is a [[https://github.com/westonganger/spreadsheet_architect][gem]] that I can include into the Table model to convert a table into
@@ -4,22 +4,23 @@ require 'bundler/setup'
4
4
  require 'fat_table'
5
5
  require 'pry'
6
6
 
7
- @data =
8
- [['Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Ok'],
9
- ['2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ENTITY3', 'F'],
10
- ['2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ENTITY1', 'T'],
11
- ['2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ENTITY3', 'F'],
12
- ['2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ENTITY3', 'T'],
13
- ['2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ENTITY3', 'T'],
14
- ['2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ENTITY3', 'T'],
15
- ['2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ENTITY1', 'T'],
16
- ['2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ENTITY3', 'T'],
17
- ['2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ENTITY3', 'T'],
18
- ['2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ENTITY3', 'T'],
19
- ['2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ENTITY3', 'T'],
20
- ['2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ENTITY3', 'F']]
7
+ @data = [
8
+ %w[Date Code Raw Shares Price Info Ok],
9
+ ['2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ENTITY3', 'F'],
10
+ ['2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ENTITY1', 'T'],
11
+ ['2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ENTITY3', 'F'],
12
+ ['2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ENTITY3', 'T'],
13
+ ['2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ENTITY3', 'T'],
14
+ ['2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ENTITY3', 'T'],
15
+ ['2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ENTITY1', 'T'],
16
+ ['2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ENTITY3', 'T'],
17
+ ['2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ENTITY3', 'T'],
18
+ ['2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ENTITY3', 'T'],
19
+ ['2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ENTITY3', 'T'],
20
+ ['2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ENTITY3', 'F']
21
+ ]
21
22
 
22
- @tab_a_str = <<-EOS
23
+ @tab_a_str = <<~TABLE
23
24
  | Id | Name | Age | Address | Salary | Join Date |
24
25
  |----+-------+-----+------------+--------+------------|
25
26
  | 1 | Paul | 32 | California | 20000 | 2001-07-13 |
@@ -30,85 +31,87 @@ require 'pry'
30
31
  | 8 | Paul | 24 | Houston | 20000 | 2005-07-13 |
31
32
  | 9 | James | 44 | Norway | 5000 | 2005-07-13 |
32
33
  | 10 | James | 45 | Texas | 5000 | |
33
- EOS
34
+ TABLE
34
35
 
35
- @tab_b_str = <<-EOS
36
+ @tab_b_str = <<~TABLE
36
37
  | Id | Dept | Emp Id |
37
38
  |----+-------------+--------|
38
39
  | 1 | IT Billing | 1 |
39
40
  | 2 | Engineering | 2 |
40
41
  | 3 | Finance | 7 |
41
- EOS
42
+ TABLE
42
43
 
43
44
  @tab_a = FatTable.from_org_string(@tab_a_str)
44
45
  @tab_b = FatTable.from_org_string(@tab_b_str)
45
46
 
46
- @tab1_str = <<-EOS
47
- | Ref | Date | Code | Price | G10 | QP10 | Shares | LP | QP | IPLP | IPQP |
48
- |------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
49
- | T001 | [2016-11-01 Tue] | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
50
- | T002 | [2016-11-01 Tue] | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
51
- | T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
52
- | T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
53
- |------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
54
- | T004 | [2016-11-01 Tue] | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
55
- | T005 | [2016-11-01 Tue] | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
56
- | T006 | [2016-11-01 Tue] | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
57
- | T006 | [2016-11-01 Tue] | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
58
- | T007 | [2016-11-01 Tue] | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
59
- | T008 | [2016-11-01 Tue] | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
60
- | T009 | [2016-11-01 Tue] | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
61
- |------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
62
- | T010 | [2016-11-01 Tue] | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
63
- | T011 | [2016-11-02 Wed] | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
64
- | T012 | [2016-11-02 Wed] | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
65
- | T012 | [2016-11-02 Wed] | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
66
- | T013 | [2016-11-02 Wed] | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
67
- |------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
68
- | T014 | [2016-11-02 Wed] | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
69
- | T015 | [2016-11-02 Wed] | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
70
- | T016 | [2016-11-02 Wed] | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
71
- EOS
47
+ @tab1_str = <<~TABLE
48
+ | Ref | Date | Code | Price | G10 | QP10 | Shares | LP | QP | IPLP | IPQP |
49
+ |------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
50
+ | T001 | [2016-11-01 Tue] | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
51
+ | T002 | [2016-11-01 Tue] | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
52
+ | T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
53
+ | T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
54
+ |------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
55
+ | T004 | [2016-11-01 Tue] | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
56
+ | T005 | [2016-11-01 Tue] | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
57
+ | T006 | [2016-11-01 Tue] | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
58
+ | T006 | [2016-11-01 Tue] | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
59
+ | T007 | [2016-11-01 Tue] | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
60
+ | T008 | [2016-11-01 Tue] | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
61
+ | T009 | [2016-11-01 Tue] | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
62
+ |------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
63
+ | T010 | [2016-11-01 Tue] | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
64
+ | T011 | [2016-11-02 Wed] | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
65
+ | T012 | [2016-11-02 Wed] | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
66
+ | T012 | [2016-11-02 Wed] | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
67
+ | T013 | [2016-11-02 Wed] | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
68
+ |------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
69
+ | T014 | [2016-11-02 Wed] | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
70
+ | T015 | [2016-11-02 Wed] | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
71
+ | T016 | [2016-11-02 Wed] | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
72
+ TABLE
72
73
 
73
- @tab2_str = <<-EOS
74
- | Ref | Date | Code | Price | G10 | QP10 | Shares | LP | QP | IPLP | IPQP |
75
- |------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
76
- | T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
77
- | T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
78
- | T017 | [2016-11-01 Tue] | P | 8.3 | F | T | 1801 | 1201 | 600 | 0.2453 | 0.1924 |
79
- |------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
80
- | T018 | [2016-11-01 Tue] | S | 7.152 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
81
- | T018 | [2016-11-01 Tue] | S | 7.152 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
82
- | T006 | [2016-11-01 Tue] | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
83
- | T007 | [2016-11-01 Tue] | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
84
- |------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
85
- | T014 | [2016-11-02 Wed] | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
86
- | T015 | [2016-11-02 Wed] | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
87
- | T015 | [2016-11-02 Wed] | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
88
- | T016 | [2016-11-02 Wed] | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
89
- |------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
90
- | T019 | [2017-01-15 Sun] | S | 8.75 | T | F | 300 | 175 | 125 | 0.2453 | 0.1924 |
91
- | T020 | [2017-01-19 Thu] | S | 8.25 | F | T | 700 | 615 | 85 | 0.2453 | 0.1924 |
92
- | T021 | [2017-01-23 Mon] | P | 7.16 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
93
- | T021 | [2017-01-23 Mon] | P | 7.16 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
94
- EOS
74
+ @tab2_str = <<~TABLE
75
+ | Ref | Date | Code | Price | G10 | QP10 | Shares | LP | QP | IPLP | IPQP |
76
+ |------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
77
+ | T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
78
+ | T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
79
+ | T017 | [2016-11-01 Tue] | P | 8.3 | F | T | 1801 | 1201 | 600 | 0.2453 | 0.1924 |
80
+ |------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
81
+ | T018 | [2016-11-01 Tue] | S | 7.152 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
82
+ | T018 | [2016-11-01 Tue] | S | 7.152 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
83
+ | T006 | [2016-11-01 Tue] | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
84
+ | T007 | [2016-11-01 Tue] | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
85
+ |------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
86
+ | T014 | [2016-11-02 Wed] | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
87
+ | T015 | [2016-11-02 Wed] | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
88
+ | T015 | [2016-11-02 Wed] | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
89
+ | T016 | [2016-11-02 Wed] | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
90
+ |------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
91
+ | T019 | [2017-01-15 Sun] | S | 8.75 | T | F | 300 | 175 | 125 | 0.2453 | 0.1924 |
92
+ | T020 | [2017-01-19 Thu] | S | 8.25 | F | T | 700 | 615 | 85 | 0.2453 | 0.1924 |
93
+ | T021 | [2017-01-23 Mon] | P | 7.16 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
94
+ | T021 | [2017-01-23 Mon] | P | 7.16 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
95
+ TABLE
95
96
 
96
97
  @tab1 = FatTable.from_org_string(@tab1_str)
97
98
  @tab2 = FatTable.from_org_string(@tab2_str)
98
99
 
99
- @aoa = [['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
100
- [1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'YLPEF1', 'T'],
101
- [2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'YLPEF1', 'T'],
102
- [7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'YLEAC', 'F'],
103
- [8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'YLEAC', 'T'],
104
- [9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'YLEAC', 'T'],
105
- [10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'YLEAC', 'T'],
106
- [11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'YLEAC', 'F'],
107
- [12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'YLEAC', 'T'],
108
- [13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'YLEAC', 'T'],
109
- [14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'YLEAC', 'F'],
110
- [15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'YLEAC', 'T'],
111
- [16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'YLEAC', 'T']]
100
+ @aoa = [
101
+ %w[Ref Date Code Raw Shares Price Info Bool],
102
+ [1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'YLPEF1', 'T'],
103
+ [2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'YLPEF1', 'T'],
104
+ [7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'YLEAC', 'F'],
105
+ [8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'YLEAC', 'T'],
106
+ [9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'YLEAC', 'T'],
107
+ [10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'YLEAC', 'T'],
108
+ [11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'YLEAC', 'F'],
109
+ [12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'YLEAC', 'T'],
110
+ [13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'YLEAC', 'T'],
111
+ [14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'YLEAC', 'F'],
112
+ [15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'YLEAC', 'T'],
113
+ [16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'YLEAC', 'T']
114
+ ]
112
115
  @tt = FatTable.from_aoa(@aoa)
113
116
 
114
117
  Pry.start
@@ -1,48 +1,49 @@
1
- # coding: utf-8
2
-
3
1
  lib = File.expand_path('../lib', __FILE__)
4
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
3
  require 'fat_table/version'
6
4
 
7
5
  Gem::Specification.new do |spec|
8
- spec.name = "fat_table"
6
+ spec.name = 'fat_table'
9
7
  spec.version = FatTable::VERSION
10
- spec.authors = ["Daniel E. Doherty"]
11
- spec.email = ["ded-law@ddoherty.net"]
8
+ spec.authors = ['Daniel E. Doherty']
9
+ spec.email = ['ded-law@ddoherty.net']
10
+
11
+ spec.summary = 'Provides tools for working with tables as a data type.'
12
+ spec.description = <<-DESC
13
+ FatTable is a gem that treats tables as a data type. It provides methods for
14
+ constructing tables from a variety of sources, building them row-by-row,
15
+ extracting rows, columns, and cells, and performing aggregate operations on
16
+ columns. It also provides as set of SQL-esque methods for manipulating table
17
+ objects: select for filtering by columns or for creating new columns, where
18
+ for filtering by rows, order_by for sorting rows, distinct for eliminating
19
+ duplicate rows, group_by for aggregating multiple rows into single rows and
20
+ applying column aggregate methods to ungrouped columns, a collection of join
21
+ methods for combining tables, and more.
12
22
 
13
- spec.summary = %q{Provides tools for working with tables as a data type.}
14
- spec.description = %q{
15
- FatTable is a gem that treats tables as a data type. It provides methods for
16
- constructing tables from a variety of sources, building them row-by-row,
17
- extracting rows, columns, and cells, and performing aggregate operations on
18
- columns. It also provides as set of SQL-esque methods for manipulating table
19
- objects: select for filtering by columns or for creating new columns, where
20
- for filtering by rows, order_by for sorting rows, distinct for eliminating
21
- duplicate rows, group_by for aggregating multiple rows into single rows and
22
- applying column aggregate methods to ungrouped columns, a collection of join
23
- methods for combining tables, and more.
23
+ Furthermore, FatTable provides methods for formatting tables and producing
24
+ output that targets various output media: text, ANSI terminals, ruby data
25
+ structures, LaTeX tables, Emacs org-mode tables, and more. The formatting
26
+ methods can specify cell formatting in a way that is uniform across all the
27
+ output methods and can also decorate the output with any number of footers,
28
+ including group footers. FatTable applies formatting directives to the extent
29
+ they makes sense for the output medium and treats other formatting directives as
30
+ no-ops.
24
31
 
25
- Furthermore, FatTable provides methods for formatting tables and producing
26
- output that targets various output media: text, ANSI terminals, ruby data
27
- structures, LaTeX tables, Emacs org-mode tables, and more. The formatting
28
- methods can specify cell formatting in a way that is uniform across all the
29
- output methods and can also decorate the output with any number of footers,
30
- including group footers. FatTable applies formatting directives to the extent
31
- they makes sense for the output medium and treats other formatting directives as
32
- no-ops.
32
+ FatTable can be used to perform operations on data that are naturally best
33
+ conceived of as tables, which in my experience is quite often. It can also serve
34
+ as a foundation for providing reporting functions where flexibility about the
35
+ output medium can be quite useful. Finally FatTable can be used within Emacs
36
+ org-mode files in code blocks targeting the Ruby language. Org mode tables are
37
+ presented to a ruby code block as an array of arrays, so FatTable can read
38
+ them in with its .from_aoa constructor. A FatTable table can output as an
39
+ array of arrays with its .to_aoa output function and will be rendered in an
40
+ org-mode buffer as an org-table, ready for processing by other code blocks.
41
+ DESC
33
42
 
34
- FatTable can be used to perform operations on data that are naturally best
35
- conceived of as tables, which in my experience is quite often. It can also serve
36
- as a foundation for providing reporting functions where flexibility about the
37
- output medium can be quite useful. Finally FatTable can be used within Emacs
38
- org-mode files in code blocks targeting the Ruby language. Org mode tables are
39
- presented to a ruby code block as an array of arrays, so FatTable can read
40
- them in with its .from_aoa constructor. A FatTable table can output as an
41
- array of arrays with its .to_aoa output function and will be rendered in an
42
- org-mode buffer as an org-table, ready for processing by other code blocks.
43
- }
43
+ spec.homepage = 'https://github.com/ddoherty03/fat_table'
44
44
 
45
- spec.homepage = 'https://github.com/ddoherty03/fat_table'
45
+ # Use of squiggle heredocs knocks out older versions.
46
+ spec.required_ruby_version = '>= 2.2.2'
46
47
 
47
48
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the
48
49
  # 'allowed_push_host' to allow pushing to a single host or delete this section
@@ -54,7 +55,7 @@ org-mode buffer as an org-table, ready for processing by other code blocks.
54
55
  'public gem pushes.'
55
56
  end
56
57
 
57
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
58
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
58
59
  f.match(%r{^(test|spec|features)/})
59
60
  end
60
61
  spec.bindir = 'bin'
@@ -62,21 +63,21 @@ org-mode buffer as an org-table, ready for processing by other code blocks.
62
63
  spec.require_paths = ['lib']
63
64
  spec.metadata['yard.run'] = 'yri' # use "yard" to build full HTML docs.
64
65
 
65
- spec.add_development_dependency 'simplecov'
66
- spec.add_development_dependency 'bundler', '~> 1.14'
67
- spec.add_development_dependency 'rake', '~> 10.0'
68
- spec.add_development_dependency 'rspec', '~> 3.0'
66
+ spec.add_development_dependency 'bundler'
69
67
  spec.add_development_dependency 'byebug'
70
68
  spec.add_development_dependency 'pry'
71
- spec.add_development_dependency 'pry-doc'
72
69
  spec.add_development_dependency 'pry-byebug'
70
+ spec.add_development_dependency 'pry-doc'
71
+ spec.add_development_dependency 'rake', '~> 13.0'
73
72
  spec.add_development_dependency 'redcarpet'
73
+ spec.add_development_dependency 'rspec', '~> 3.0'
74
+ spec.add_development_dependency 'rubocop-rspec'
75
+ spec.add_development_dependency 'rubocop-performance'
76
+ spec.add_development_dependency 'simplecov'
74
77
 
75
- spec.add_runtime_dependency 'fat_core', '~> 4.0', '>= 4.1'
76
- spec.add_runtime_dependency 'activesupport'
78
+ spec.add_runtime_dependency 'activesupport', '>3.0'
79
+ spec.add_runtime_dependency 'fat_core', '>= 4.1'
77
80
  spec.add_runtime_dependency 'rainbow'
78
81
  spec.add_runtime_dependency 'sequel'
79
- spec.add_runtime_dependency 'pg'
80
- spec.add_runtime_dependency 'sqlite3'
81
- spec.add_runtime_dependency 'mysql2'
82
+ spec.add_runtime_dependency 'gem-path'
82
83
  end
@@ -24,8 +24,17 @@ module FatTable
24
24
  require 'fat_table/db_handle'
25
25
  require 'fat_table/errors'
26
26
 
27
+ # Add paths for common db gems to the load paths
28
+ %w[pg mysql2 sqlite].each do |gem_name|
29
+ path = Dir.glob("#{ENV['GEM_HOME']}/gems/#{gem_name}*").sort.last
30
+ if path
31
+ path = File.join(path, 'lib')
32
+ $: << path unless $:.include?(path)
33
+ end
34
+ end
35
+
27
36
  # Valid output formats as symbols.
28
- FORMATS = [:psv, :aoa, :aoh, :latex, :org, :term, :text].freeze
37
+ FORMATS = %i[psv aoa aoh latex org term text].freeze
29
38
 
30
39
  class << self
31
40
  # Set a default output format to use when FatTable.to_format is invoked.
@@ -114,7 +123,7 @@ module FatTable
114
123
  end
115
124
 
116
125
  # Construct a Table by running a SQL query against the database set up with
117
- # FatTable.set_db. Return the Table with the query results as rows and the
126
+ # FatTable.connect. Return the Table with the query results as rows and the
118
127
  # headers from the query, converted to symbols, as headers.
119
128
  def self.from_sql(query)
120
129
  Table.from_sql(query)
@@ -21,14 +21,14 @@ module FatTable
21
21
  attr_reader :type
22
22
 
23
23
  # An Array of the items of this Column, all of which must be values of the
24
- # Columns type or a nil. This Array contains the value of the item after
24
+ # Column's type or a nil. This Array contains the value of the item after
25
25
  # conversion to a native Ruby type, such as TrueClass, Date, DateTime,
26
26
  # Integer, String, etc. Thus, you can perform operations on the items,
27
27
  # perhaps after removing nils with +.items.compact+.
28
28
  attr_reader :items
29
29
 
30
30
  # Valid Column types as strings.
31
- TYPES = %w(NilClass Boolean DateTime Numeric String).freeze
31
+ TYPES = %w[NilClass Boolean DateTime Numeric String].freeze
32
32
 
33
33
  # :category: Constructors
34
34
 
@@ -36,8 +36,8 @@ module FatTable
36
36
  # +items+, as an array of either strings or ruby objects that are one of the
37
37
  # permissible types or strings parsable as one of the permissible types. If
38
38
  # no +items+ are passed, returns an empty Column to which items may be added
39
- # with the Column#<< method. The item types must be one of the following types or
40
- # strings parseable as one of them:
39
+ # with the Column#<< method. The item types must be one of the following
40
+ # types or strings parseable as one of them:
41
41
  #
42
42
  # Boolean::
43
43
  # an object of type TrueClass or FalseClass or a string that is either
@@ -48,9 +48,8 @@ module FatTable
48
48
  # an object of class Date, DateTime, or a string that matches
49
49
  # +/\d\d\d\d[-\/]\d\d?[-\/]\d\d?/+ and is parseable by DateTime.parse.
50
50
  #
51
- # Numeric::
52
- # on object that is of class Numeric, or a string that looks
53
- # like a number after removing '+$+', '+,+', and '+_+' as well as Rationals
51
+ # Numeric:: on object that is of class Numeric, or a string that looks like
52
+ # a number after removing '+$+', '+,+', and '+_+' as well as Rationals
54
53
  # in the form /<number>:<number>/ or <number>/<number>, where <number>
55
54
  # is an integer.
56
55
  #
@@ -91,7 +90,9 @@ module FatTable
91
90
  @raw_header.to_s.as_sym
92
91
  end
93
92
  @type = 'NilClass'
94
- raise UserError, "Unknown column type '#{type}" unless TYPES.include?(@type.to_s)
93
+ msg = "unknown column type '#{type}"
94
+ raise UserError, msg unless TYPES.include?(@type.to_s)
95
+
95
96
  @items = []
96
97
  items.each { |i| self << i }
97
98
  end
@@ -103,8 +104,8 @@ module FatTable
103
104
  # :category: Attributes
104
105
 
105
106
  # Return the item of the Column at the given index.
106
- def [](k)
107
- items[k]
107
+ def [](idx)
108
+ items[idx]
108
109
  end
109
110
 
110
111
  # :category: Attributes
@@ -229,11 +230,13 @@ module FatTable
229
230
  # average back to a DateTime.
230
231
  def avg
231
232
  only_with('avg', 'DateTime', 'Numeric')
233
+ itms = items.compact
234
+ size = itms.size.to_d
232
235
  if type == 'DateTime'
233
- avg_jd = items.compact.map(&:jd).sum / items.compact.size.to_d
236
+ avg_jd = itms.map(&:jd).sum / size
234
237
  DateTime.jd(avg_jd)
235
238
  else
236
- sum / items.compact.size.to_d
239
+ itms.sum / size
237
240
  end
238
241
  end
239
242
 
@@ -342,7 +345,8 @@ module FatTable
342
345
 
343
346
  def only_with(agg, *valid_types)
344
347
  return self if valid_types.include?(type)
345
- raise UserError, "Aggregate '#{agg}' cannot be applied to a #{type} column"
348
+ msg = "aggregate '#{agg}' cannot be applied to a #{type} column"
349
+ raise UserError, msg
346
350
  end
347
351
 
348
352
  public
@@ -366,7 +370,8 @@ module FatTable
366
370
  # checking for type compatibility. Use the header of this Column as the
367
371
  # header of the new Column.
368
372
  def +(other)
369
- raise UserError, 'Cannot combine columns with different types' unless type == other.type
373
+ msg = 'cannot combine columns with different types'
374
+ raise UserError, msg unless type == other.type
370
375
  Column.new(header: header, items: items + other.items)
371
376
  end
372
377
 
@@ -401,7 +406,7 @@ module FatTable
401
406
  bool_val
402
407
  end
403
408
  @type =
404
- if new_val == true || new_val == false
409
+ if [true, false].include?(new_val)
405
410
  'Boolean'
406
411
  elsif new_val.is_a?(Date) || new_val.is_a?(DateTime)
407
412
  'DateTime'
@@ -410,17 +415,19 @@ module FatTable
410
415
  elsif new_val.is_a?(String)
411
416
  'String'
412
417
  else
413
- raise UserError, "Cannot add #{val} of type #{new_val.class.name} to a column"
418
+ msg = "can't add #{val} of type #{new_val.class.name} to a column"
419
+ raise UserError, msg
414
420
  end
415
421
  end
416
422
  new_val
417
423
  when 'Boolean'
418
- if (val.is_a?(String) && val.blank? || val.nil?)
424
+ if val.is_a?(String) && val.blank? || val.nil?
419
425
  nil
420
426
  else
421
427
  new_val = convert_to_boolean(val)
422
428
  if new_val.nil?
423
- raise UserError, "Attempt to add '#{val}' to a column already typed as #{type}"
429
+ msg = "attempt to add '#{val}' to a column already typed as #{type}"
430
+ raise UserError, msg
424
431
  end
425
432
  new_val
426
433
  end
@@ -430,7 +437,8 @@ module FatTable
430
437
  else
431
438
  new_val = convert_to_date_time(val)
432
439
  if new_val.nil?
433
- raise UserError, "Attempt to add '#{val}' to a column already typed as #{type}"
440
+ msg = "attempt to add '#{val}' to a column already typed as #{type}"
441
+ raise UserError, msg
434
442
  end
435
443
  new_val
436
444
  end
@@ -440,7 +448,8 @@ module FatTable
440
448
  else
441
449
  new_val = convert_to_numeric(val)
442
450
  if new_val.nil?
443
- raise UserError, "Attempt to add '#{val}' to a column already typed as #{type}"
451
+ msg = "attempt to add '#{val}' to a column already typed as #{type}"
452
+ raise UserError, msg
444
453
  end
445
454
  new_val
446
455
  end
@@ -450,7 +459,8 @@ module FatTable
450
459
  else
451
460
  new_val = convert_to_string(val)
452
461
  if new_val.nil?
453
- raise UserError, "Attempt to add '#{val}' to a column already typed as #{type}"
462
+ msg = "attempt to add '#{val}' to a column already typed as #{type}"
463
+ raise UserError, msg
454
464
  end
455
465
  new_val
456
466
  end
@@ -466,15 +476,17 @@ module FatTable
466
476
  return val if val.is_a?(TrueClass) || val.is_a?(FalseClass)
467
477
  val = val.to_s.clean
468
478
  return nil if val.blank?
469
- if val =~ /\A(false|f|n|no)\z/i
479
+ if val.match?(/\A(false|f|n|no)\z/i)
470
480
  false
471
- elsif val =~ /\A(true|t|y|yes)\z/i
481
+ elsif val.match?(/\A(true|t|y|yes)\z/i)
472
482
  true
473
483
  end
474
484
  end
475
485
 
476
- IS0_DATE_RE = %r{\b(\d\d\d\d)[-/](\d\d?)[-/](\d\d?)\s*(T\d\d:\d\d:\d\d(\+\d\d:\d\d)?)?\b}
477
- AMR_DATE_RE = %r{\b(\d\d?)[-/](\d\d?)[-/](\d\d\d\d)\s*(T\d\d:\d\d:\d\d(\+\d\d:\d\d)?)?\b}
486
+ IS0_DATE_RE = %r{\b(\d\d\d\d)[-/](\d\d?)[-/](\d\d?)\s*
487
+ (T\d\d:\d\d:\d\d(\+\d\d:\d\d)?)?\b}x
488
+ AMR_DATE_RE = %r{\b(\d\d?)[-/](\d\d?)[-/](\d\d\d\d)\s*
489
+ (T\d\d:\d\d:\d\d(\+\d\d:\d\d)?)?\b}x
478
490
 
479
491
  # Convert the val to a DateTime if it is either a DateTime, a Date, or a
480
492
  # String that can be parsed as a DateTime, otherwise return nil. It only
@@ -488,7 +500,7 @@ module FatTable
488
500
  begin
489
501
  val = val.to_s.clean
490
502
  return nil if val.blank?
491
- if val =~ IS0_DATE_RE
503
+ if val.match?(IS0_DATE_RE)
492
504
  val = DateTime.parse(val)
493
505
  elsif val =~ AMR_DATE_RE
494
506
  val = DateTime.new($3.to_i, $1.to_i, $2.to_i)
@@ -502,11 +514,11 @@ module FatTable
502
514
  end
503
515
  end
504
516
 
505
- # Convert the val to a Numeric if is already a Numberic or is a String that
517
+ # Convert the val to a Numeric if is already a Numeric or is a String that
506
518
  # looks like one. Any Float is promoted to a BigDecimal. Otherwise return
507
519
  # nil.
508
520
  def convert_to_numeric(val)
509
- return BigDecimal.new(val, Float::DIG) if val.is_a?(Float)
521
+ return BigDecimal(val, Float::DIG) if val.is_a?(Float)
510
522
  return val if val.is_a?(Numeric)
511
523
  # Eliminate any commas, $'s (or other currency symbol), or _'s.
512
524
  cursym = Regexp.quote(FatTable.currency_symbol)
@@ -515,7 +527,7 @@ module FatTable
515
527
  return nil if val.blank?
516
528
  case val
517
529
  when /(\A[-+]?\d+\.\d*\z)|(\A[-+]?\d*\.\d+\z)/
518
- BigDecimal.new(val.to_s.clean)
530
+ BigDecimal(val.to_s.clean)
519
531
  when /\A[-+]?[\d]+\z/
520
532
  val.to_i
521
533
  when %r{\A([-+]?\d+)\s*[:/]\s*([-+]?\d+)\z}