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.
- checksums.yaml +5 -5
- data/.gitignore +3 -0
- data/.rubocop.yml +3 -0
- data/.travis.yml +7 -2
- data/.yardopts +5 -1
- data/README.org +271 -251
- data/README.rdoc +4 -4
- data/TODO.org +7 -0
- data/bin/ft_console +82 -79
- data/fat_table.gemspec +47 -46
- data/lib/fat_table.rb +11 -2
- data/lib/fat_table/column.rb +41 -29
- data/lib/fat_table/db_handle.rb +31 -50
- data/lib/fat_table/evaluator.rb +26 -24
- data/lib/fat_table/formatters/aoa_formatter.rb +5 -6
- data/lib/fat_table/formatters/aoh_formatter.rb +6 -7
- data/lib/fat_table/formatters/formatter.rb +67 -48
- data/lib/fat_table/formatters/latex_formatter.rb +9 -7
- data/lib/fat_table/formatters/org_formatter.rb +8 -9
- data/lib/fat_table/formatters/term_formatter.rb +19 -18
- data/lib/fat_table/formatters/text_formatter.rb +6 -7
- data/lib/fat_table/patches.rb +30 -1
- data/lib/fat_table/table.rb +143 -117
- data/lib/fat_table/version.rb +1 -1
- data/md/README.md +2167 -0
- metadata +78 -84
data/README.rdoc
CHANGED
@@ -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.
|
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 +.
|
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 +.
|
504
|
-
creates will be used for all subsequent +.from_sql+ calls until +.
|
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
|
data/bin/ft_console
CHANGED
@@ -4,22 +4,23 @@ require 'bundler/setup'
|
|
4
4
|
require 'fat_table'
|
5
5
|
require 'pry'
|
6
6
|
|
7
|
-
@data =
|
8
|
-
[
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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 =
|
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
|
-
|
34
|
+
TABLE
|
34
35
|
|
35
|
-
@tab_b_str =
|
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
|
-
|
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 =
|
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
|
-
|
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 =
|
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
|
-
|
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 = [
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
data/fat_table.gemspec
CHANGED
@@ -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 =
|
6
|
+
spec.name = 'fat_table'
|
9
7
|
spec.version = FatTable::VERSION
|
10
|
-
spec.authors = [
|
11
|
-
spec.email = [
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
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
|
-
|
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
|
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 '
|
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 '
|
76
|
-
spec.add_runtime_dependency '
|
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 '
|
80
|
-
spec.add_runtime_dependency 'sqlite3'
|
81
|
-
spec.add_runtime_dependency 'mysql2'
|
82
|
+
spec.add_runtime_dependency 'gem-path'
|
82
83
|
end
|
data/lib/fat_table.rb
CHANGED
@@ -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 = [
|
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.
|
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)
|
data/lib/fat_table/column.rb
CHANGED
@@ -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
|
-
#
|
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
|
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
|
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
|
-
#
|
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
|
-
|
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 [](
|
107
|
-
items[
|
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 =
|
236
|
+
avg_jd = itms.map(&:jd).sum / size
|
234
237
|
DateTime.jd(avg_jd)
|
235
238
|
else
|
236
|
-
sum /
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
479
|
+
if val.match?(/\A(false|f|n|no)\z/i)
|
470
480
|
false
|
471
|
-
elsif val
|
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*
|
477
|
-
|
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
|
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
|
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
|
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
|
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}
|