fat_table 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.org +136 -67
- data/TODO.org +28 -1
- data/lib/ext/array.rb +17 -0
- data/lib/fat_table/column.rb +94 -56
- data/lib/fat_table/convert.rb +18 -9
- data/lib/fat_table/evaluator.rb +6 -8
- data/lib/fat_table/footer.rb +73 -33
- data/lib/fat_table/formatters/formatter.rb +153 -31
- data/lib/fat_table/formatters/org_formatter.rb +3 -3
- data/lib/fat_table/formatters/term_formatter.rb +3 -3
- data/lib/fat_table/formatters/text_formatter.rb +3 -3
- data/lib/fat_table/table.rb +12 -5
- data/lib/fat_table/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f348d317c061becae08890ff02cc9c08789787d966f9ed88f3a4ef22b6eddb44
|
4
|
+
data.tar.gz: bf672b4f4f4ab07df465d06904ccebb9b48507177dc88a343eb09bfb0e98bc02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c721233a04cc1664e8d8acea3cf677190aa47da30b3db7e1b9f6c13ddd56028a8ecd8b0c71915d0a1703f46fc9a22a1c3a8a3f13d6c80fb07964a22fd864ab7e
|
7
|
+
data.tar.gz: 7877d4529d8a6f2a13ee0a1518730791b4e5ed7dbadd2030367593c95ccdbd5159e711f7ffe69b9b2fa9b4812a6f49d3d1a9fce46642e4454f54ff40d769a4cb
|
data/README.org
CHANGED
@@ -31,8 +31,9 @@ The following is for org.
|
|
31
31
|
"Current version is: #{FatTable::VERSION}"
|
32
32
|
#+end_src
|
33
33
|
|
34
|
+
#+RESULTS:
|
34
35
|
#+begin_EXAMPLE
|
35
|
-
Current version is: 0.
|
36
|
+
Current version is: 0.6.0
|
36
37
|
#+end_EXAMPLE
|
37
38
|
|
38
39
|
* Introduction
|
@@ -148,6 +149,7 @@ org-mode buffer as an org-table, ready for processing by other code blocks.
|
|
148
149
|
- [[#type-and-column-priority][Type and Column priority]]
|
149
150
|
- [[#footers][Footers]]
|
150
151
|
- [[#adding-footers][Adding Footers]]
|
152
|
+
- [[#dynamic-labels][Dynamic Labels]]
|
151
153
|
- [[#aggregators][Aggregators]]
|
152
154
|
- [[#footer-objects][Footer objects]]
|
153
155
|
- [[#footer-examples][Footer Examples]]
|
@@ -442,11 +444,26 @@ or nil. There are only five permissible types for a ~Column~:
|
|
442
444
|
5. *NilClass* (for the undetermined column type).
|
443
445
|
|
444
446
|
When a ~Table~ is constructed from an external source, all ~Columns~ start out
|
445
|
-
having a type of ~NilClass~, that is, their type is as yet undetermined. When
|
446
|
-
string or object of one of the four determined types is added to a ~Column
|
447
|
-
|
448
|
-
|
449
|
-
|
447
|
+
having a type of ~NilClass~, that is, their type is as yet undetermined. When
|
448
|
+
a string or object of one of the four determined types is added to a ~Column~
|
449
|
+
and it can be converted into one of the permissible types, it fixes the type
|
450
|
+
of the column, and all further items added to the ~Column~ must either be
|
451
|
+
~nil~ (indicating no value) or be capable of being coerced to the column's
|
452
|
+
type. Otherwise, ~FatTable~ raises an exception.
|
453
|
+
|
454
|
+
The strictness of requiring all items to be of the same type can be relaxed by
|
455
|
+
declaring a column to be "tolerant." You can do so when you create the table
|
456
|
+
by adding a tolerant_columns keyword parameter. If a Column is tolerant,
|
457
|
+
~FatTable~ tries to convert new items into a type other than a ~String~ and,
|
458
|
+
if it can do so, sets /that/ as the Column's type. Any later items that
|
459
|
+
cannot be converted into the Column's type are converted to strings. These
|
460
|
+
interloper strings are treated like nils for purposes of sorting and
|
461
|
+
evaluation, but are displayed according to any string formatting on output.
|
462
|
+
See [[*Designating "Tolerant" Columns][Designating "Tolerant" Columns]] below.
|
463
|
+
|
464
|
+
It is also possible to force ~FatTable~ to treat a column as a String type,
|
465
|
+
even its items look like one of the other types. See [[*Forcing String Type][Forcing String Type]]
|
466
|
+
below.
|
450
467
|
|
451
468
|
Items of input must be either one of the permissible ruby objects or strings. If
|
452
469
|
they are strings, ~FatTable~ attempts to parse them as one of the permissible
|
@@ -519,6 +536,7 @@ You can create an empty table with ~FatTable::Table.new~ or, the shorter form,
|
|
519
536
|
in the added rows determine the names of the headers:
|
520
537
|
|
521
538
|
#+BEGIN_SRC ruby :results silent
|
539
|
+
require 'fat_table'
|
522
540
|
tab = FatTable.new
|
523
541
|
tab << { a: 1, b: 2, c: "<2017-01-21>", d: 'f', e: '' }
|
524
542
|
tab << { a: 3.14, b: 2.17, c: '[2016-01-21 Thu]', d: 'Y', e: nil }
|
@@ -603,10 +621,18 @@ columns to be created:
|
|
603
621
|
**** Forcing String Type
|
604
622
|
Occasionally, ~FatTable~'s automatic type detection can get in the way and you
|
605
623
|
just want it to treat one or more columns as Strings regardless of their
|
606
|
-
appearance. Think, for example, of zip codes.
|
607
|
-
table, you can
|
608
|
-
|
609
|
-
|
624
|
+
appearance. Think, for example, of zip codes. If headers are given when a
|
625
|
+
table is contructed, you can designate a forced-string column by appending a
|
626
|
+
~!~ to the end of the header. It will not become part of the header, it will
|
627
|
+
just mark it as a forced-string Column.
|
628
|
+
|
629
|
+
#+begin_SRC emacs-lisp :wrap EXAMPLE
|
630
|
+
tab = FatTable.new(:a, 'b', 'C!', :d, :zip!)
|
631
|
+
#+end_SRC
|
632
|
+
|
633
|
+
In addition, at any time after creating a table, you can force the String type
|
634
|
+
on any number of columns with the ~force_string!~ method. When you do so, all
|
635
|
+
exisiting items in the column are converted to strings with the #to_s method.
|
610
636
|
|
611
637
|
#+begin_src ruby :wrap EXAMPLE
|
612
638
|
tab = FatTable.new(:a, 'b', 'C', :d, :zip)
|
@@ -638,8 +664,11 @@ something that can't be parsed as a Numeric. ~FatTable~ raises an exception
|
|
638
664
|
is such cases, and that may be what you want if you can control the input.
|
639
665
|
But, especially when you cannot do so, it can be helpful to designate one or
|
640
666
|
more columns as "tolerant." This means that when a conversion problem occurs,
|
641
|
-
the column is
|
642
|
-
|
667
|
+
the column item is retained as a string type in a column that is otherwise of
|
668
|
+
one of the types Numeric, DateTime, or Boolean. Those string items are
|
669
|
+
treated as nils for purposes of sorting or evaluation in a ~select~ method.
|
670
|
+
When formatted, they participate in string formatting directive, but not those
|
671
|
+
for other types.
|
643
672
|
|
644
673
|
All of the table construction methods, allow a keyword parameter,
|
645
674
|
~tolerant_columns~, where you can designate what columns should be convert to
|
@@ -1728,8 +1757,6 @@ available in ~ft_console~ as ~@tab_a~ and ~@tab_b~:
|
|
1728
1757
|
| 2 | Engineering | 2 |
|
1729
1758
|
| 3 | Finance | 7 |
|
1730
1759
|
EOS
|
1731
|
-
|
1732
|
-
tab_b = FatTable.from_org_string(tab_b_str)
|
1733
1760
|
#+END_SRC
|
1734
1761
|
|
1735
1762
|
Here is ~tab_a~:
|
@@ -2439,7 +2466,6 @@ Finance&
|
|
2439
2466
|
{:id=>"3", :dept=>"Finance", :emp_id=>"7"}]
|
2440
2467
|
#+end_EXAMPLE
|
2441
2468
|
|
2442
|
-
|
2443
2469
|
*** Formatting Directives
|
2444
2470
|
The formatting methods explained in the next section all take formatting
|
2445
2471
|
directives as strings in which letters and other characters signify what
|
@@ -2641,9 +2667,10 @@ the table, but they can be overridden by more specific directives given in a
|
|
2641
2667
|
~format_for~ directive.
|
2642
2668
|
|
2643
2669
|
**** Type and Column priority
|
2644
|
-
A directive based
|
2645
|
-
|
2646
|
-
|
2670
|
+
A directive based the column name overrides any directive based on type. If
|
2671
|
+
any cell has both a type-based formatting and column-based, the column
|
2672
|
+
instructions prevail. In earlier versions the instuctions were "merged" but
|
2673
|
+
that is no longer the case.
|
2647
2674
|
|
2648
2675
|
However, there is a twist. Since the end result of formatting is to convert
|
2649
2676
|
all columns to strings, the formatting directives for the ~String~ type can
|
@@ -2679,12 +2706,27 @@ but not for other nils, such as in the last row of the ~:join_date~ column.
|
|
2679
2706
|
|
2680
2707
|
*** Footers
|
2681
2708
|
**** Adding Footers
|
2682
|
-
You can call the ~
|
2683
|
-
objects to add footers and group footers. Note that all of these
|
2684
|
-
return a ~Footer~ object that can be accessed to extract the computed
|
2685
|
-
All of these methods return the ~FatTable::Footer~ object so
|
2686
|
-
can be used to access the values and other attributes of the
|
2687
|
-
computed. Their signatures are:
|
2709
|
+
You can call the ~foot~, ~gfoot~, ~footer,~ or ~gfooter~, methods on
|
2710
|
+
~Formatter~ objects to add footers and group footers. Note that all of these
|
2711
|
+
methods return a ~Footer~ object that can be accessed to extract the computed
|
2712
|
+
values. All of these methods return the ~FatTable::Footer~ object so
|
2713
|
+
constructed. It can be used to access the values and other attributes of the
|
2714
|
+
footer computed. Their signatures are:
|
2715
|
+
|
2716
|
+
- ~foot(label: label, label_col: nil, **agg_cols)~ :: where ~label~ is a label
|
2717
|
+
to be placed in the column with header ~label_col~, or, if ommitted, in the
|
2718
|
+
first cell of the footer (unless that column is named as one of the
|
2719
|
+
~agg_cols~, in which case the label is ignored), and ~**agg_cols~ is zero or
|
2720
|
+
more hash-like parameters with a column symbol as a key and a valid
|
2721
|
+
aggregate as the value. This causes a table-wide header to be added at the
|
2722
|
+
bottom of the table applying ~agg~, to the ~agg_cols~. A table can have any
|
2723
|
+
number of footers attached, and they will appear at the bottom of the output
|
2724
|
+
table in the order they are given.
|
2725
|
+
|
2726
|
+
- ~gfoot(label: 'Group Total', label_col: nil, **agg_cols)~ :: where the
|
2727
|
+
parameters have the same meaning as for the ~foot~ method, but results in a
|
2728
|
+
footer for each group in the table rather than the table as a whole. These
|
2729
|
+
will appear in the output table just below each group.
|
2688
2730
|
|
2689
2731
|
- ~footer(label, *sum_cols, **agg_cols)~ :: where ~label~ is a label to be
|
2690
2732
|
placed in the first cell of the footer (unless that column is named as one
|
@@ -2697,26 +2739,11 @@ computed. Their signatures are:
|
|
2697
2739
|
number of footers attached, and they will appear at the bottom of the output
|
2698
2740
|
table in the order they are given.
|
2699
2741
|
|
2700
|
-
- ~foot(label, label_col, **agg_cols)~ :: where ~label~ is a label to be
|
2701
|
-
placed in the column with header ~label_col~, or, if ommitted, in the first
|
2702
|
-
cell of the footer (unless that column is named as one of the ~agg_cols~, in
|
2703
|
-
which case the label is ignored), and ~**agg_cols~ is zero or more hash-like
|
2704
|
-
parameters with a column symbol as a key and a valid aggregate as the
|
2705
|
-
value. This causes a table-wide header to be added at the bottom of the
|
2706
|
-
table applying ~agg~, to the ~agg_cols~. A table can have any number of
|
2707
|
-
footers attached, and they will appear at the bottom of the output table in
|
2708
|
-
the order they are given.
|
2709
|
-
|
2710
2742
|
- ~gfooter(label, *sum_cols, **agg_cols)~ :: where the parameters have the
|
2711
2743
|
same meaning as for the ~footer~ method, but results in a footer for each
|
2712
2744
|
group in the table rather than the table as a whole. These will appear in
|
2713
2745
|
the output table just below each group.
|
2714
2746
|
|
2715
|
-
- ~gfoot(label, label_col, **agg_cols)~ :: where the parameters have the same
|
2716
|
-
meaning as for the ~foot~ method, but results in a footer for each group in
|
2717
|
-
the table rather than the table as a whole. These will appear in the output
|
2718
|
-
table just below each group.
|
2719
|
-
|
2720
2747
|
There are also a number of convenience methods for adding common footers:
|
2721
2748
|
- ~sum_footer(*cols)~ :: Add a footer summing the given columns with the label
|
2722
2749
|
'Total'.
|
@@ -2735,6 +2762,39 @@ There are also a number of convenience methods for adding common footers:
|
|
2735
2762
|
- ~max_gfooter(*cols)~ :: Add a group footer showing the maximum for the given
|
2736
2763
|
columns with the label 'Group Maximum'.
|
2737
2764
|
|
2765
|
+
**** Dynamic Labels
|
2766
|
+
Most of the time, you will want a fixed string as the label. However,
|
2767
|
+
especially in the case of a group footer, you might want a dynamically
|
2768
|
+
contructed label. You can use a proc or lambda for a label, and it will be
|
2769
|
+
computed for you. In the case of non-group footers, the proc takes a single
|
2770
|
+
parameter, the footer object itself. This allows you to make the label a
|
2771
|
+
function of other footer values, for example, you could make the label
|
2772
|
+
include the most recent year from the date column:
|
2773
|
+
|
2774
|
+
#+begin_src ruby
|
2775
|
+
fmtr.foot(label: -> (f) { "Average (latest year #{f.column(:date).max.year})" },
|
2776
|
+
temp: :avg)
|
2777
|
+
#+end_src
|
2778
|
+
|
2779
|
+
In the case of a group footer, the lambda or proc may take either one or qtwo parameters.
|
2780
|
+
If it takes one, the parameter is simply the 0-based number of the group:
|
2781
|
+
|
2782
|
+
#+begin_src ruby
|
2783
|
+
fmtr.gfoot(label: -> (k) { "Group #{(k+1).to_roman} Average" }, temp: :avg)
|
2784
|
+
#+end_src
|
2785
|
+
This would format the label with a roman numeral (assuming you defined a
|
2786
|
+
method to do so) for the group number.
|
2787
|
+
|
2788
|
+
If it takes two arguments, the second argument is the footer itself, as with
|
2789
|
+
non-group footers:
|
2790
|
+
|
2791
|
+
#+begin_src ruby
|
2792
|
+
fmtr.gfoot(label: -> (k, f) { "Year #{f.column(:date, k).max.year} Group #{(k+1).to_roman} Average" },
|
2793
|
+
temp: :avg)
|
2794
|
+
#+end_src
|
2795
|
+
This would add the group's year to label, assuming the :date column of the
|
2796
|
+
footer's table had the same year for each item in the group.
|
2797
|
+
|
2738
2798
|
**** Aggregators
|
2739
2799
|
When adding a footer with the above methods, you can specify an aggregator for
|
2740
2800
|
each column named in the ~agg_cols~ parameter. There are several candidates
|
@@ -2751,6 +2811,9 @@ for what you can use for an aggregator:
|
|
2751
2811
|
In the case of datetime columns, these aggrgators convert the dates to
|
2752
2812
|
julian date numbers, perform the calculation, then convert the result back
|
2753
2813
|
to a datetime object.
|
2814
|
+
Apart from the built-in aggrgators, you could define your own by opening the
|
2815
|
+
FatTable::Column class and adding a suitable instance method. In that
|
2816
|
+
case, the symbol could also refer to the method you defined.
|
2754
2817
|
- String :: using a string as an aggrgegator can result in:
|
2755
2818
|
+ the string being converted to an object matching the type of the column
|
2756
2819
|
(for example, using '$1,888' in a numeric column puts the constant number
|
@@ -2765,11 +2828,16 @@ for what you can use for an aggregator:
|
|
2765
2828
|
- A Lambda :: finally, you can provide a lambda for performing arbitrary
|
2766
2829
|
calculations and placing the result in the footer field. The number of
|
2767
2830
|
arguments the lambda takes can vary:
|
2768
|
-
* If the lambda is used in
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2831
|
+
* If the lambda is used in an ordinary footer column, it can take 0, 1, or 2
|
2832
|
+
arguments: (1) the first argument, if given, will be set to the
|
2833
|
+
FatTable::Column object for that column and (2) the second argument, if
|
2834
|
+
given, will be set to the Footer object itself.
|
2835
|
+
* If the lambda is used in a group footer column, it can 0, 1, 2, or 3
|
2836
|
+
arguments: (1) the first argument, if given, will be set to the group's
|
2837
|
+
0-based index number, (2) the second argument, if given, will be set to a
|
2838
|
+
FatTable::Column object consisting of those items in the group's column,
|
2839
|
+
and (3) the third argument, if given, will be set to the Footer object
|
2840
|
+
itself.
|
2773
2841
|
|
2774
2842
|
**** Footer objects
|
2775
2843
|
Each of the methods for adding a footer to a ~Formatter~ returns a ~Footer~ object
|
@@ -2793,7 +2861,6 @@ their computed values. Here are the accessors available on a
|
|
2793
2861
|
to the footer value for that column, nil for unused columns. Use the index
|
2794
2862
|
~k~ to specify which group to access in the case of a group footer.
|
2795
2863
|
|
2796
|
-
|
2797
2864
|
**** Footer Examples
|
2798
2865
|
As a reminder, here is the table, ~tab_a~ defined earlier:
|
2799
2866
|
|
@@ -2954,18 +3021,20 @@ But it can be any type. Here we pick a lottery winner from the employee ids.
|
|
2954
3021
|
#+end_EXAMPLE
|
2955
3022
|
|
2956
3023
|
***** Lambdas
|
2957
|
-
Perhaps the most flexible form of aggregator is a lambda form. They
|
2958
|
-
or 3 parameters in non-group and group footers, respectively:
|
2959
|
-
|
2960
|
-
- ~->(
|
2961
|
-
paramters: the first, ~
|
2962
|
-
|
2963
|
-
lambda
|
2964
|
-
|
2965
|
-
|
2966
|
-
|
2967
|
-
|
2968
|
-
|
3024
|
+
Perhaps the most flexible form of aggregator is a lambda form. They can take
|
3025
|
+
up to 2 or up to 3 parameters in non-group and group footers, respectively:
|
3026
|
+
|
3027
|
+
- ~->(c, f) {...}~ :: in a normal, non-group footer, you may provide for up to
|
3028
|
+
two paramters: the first, ~c~, if given, will be bound to the column header
|
3029
|
+
to which the lambda is attached and and the second, ~f~, if given will be
|
3030
|
+
bound to the footer in which the lambda appears. A lambda with no
|
3031
|
+
parameters can be provided as well if none are needed.
|
3032
|
+
- ~->(k, c, f)~ :: in a group footer, you may provide for up to three
|
3033
|
+
paramters: the the first, ~k~, if provided, will be bound to the group
|
3034
|
+
number of the group being evaluated, the second, ~c~, if provided, will be
|
3035
|
+
bound to the column header to which the lambda is attached, and the third,
|
3036
|
+
~f~, will be bound to the footer in which the lambda appears. A lambda with
|
3037
|
+
no parameters can be provided as well if none are needed.
|
2969
3038
|
|
2970
3039
|
With the first argument, the footer itself becomes available and with it all
|
2971
3040
|
the things accessible with the footers, including the items in the current
|
@@ -2976,7 +3045,7 @@ Compute the summ of the squares if the items in the ~:age~ column:
|
|
2976
3045
|
tab_a.to_text do |f|
|
2977
3046
|
f.format(numeric: '0.0R,', datetime: 'd[%v]D[%v]')
|
2978
3047
|
f.footer('Average', age: :avg, salary: :avg, join_date: :avg)
|
2979
|
-
f.footer('SSQ', age: ->(
|
3048
|
+
f.footer('SSQ', age: ->(c) { sa = c.items.map {|x| x * x}.sum; Math.sqrt(sa) })
|
2980
3049
|
end
|
2981
3050
|
#+END_SRC
|
2982
3051
|
|
@@ -3005,8 +3074,8 @@ summ of the squares if the ages in each group:
|
|
3005
3074
|
tab_a.order_with('join_date.year').to_text do |f|
|
3006
3075
|
f.format(numeric: '0.0R,', datetime: 'd[%v]D[%v]', sort_key: '0.0~,')
|
3007
3076
|
f.footer('Average', age: :avg, salary: :avg, join_date: :avg)
|
3008
|
-
f.gfooter('Group SSQ', age: ->(
|
3009
|
-
f.footer('Total SSQ', age: ->(
|
3077
|
+
f.gfooter('Group SSQ', age: ->(k, c, f) { sa = c.items.map {|x| x * x}.sum; Math.sqrt(sa) })
|
3078
|
+
f.footer('Total SSQ', age: ->(c, f) { sa = c.items.map {|x| x * x}.sum; Math.sqrt(sa) })
|
3010
3079
|
end
|
3011
3080
|
#+END_SRC
|
3012
3081
|
|
@@ -3018,19 +3087,19 @@ summ of the squares if the ages in each group:
|
|
3018
3087
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
3019
3088
|
| Group SSQ | | 45 | | | | |
|
3020
3089
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
3021
|
-
| 1 | Paul | 32 | California | 20,000 | 13-JUL-2001 |
|
3090
|
+
| 1 | Paul | 32 | California | 20,000 | 13-JUL-2001 | 2001 |
|
3022
3091
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
3023
3092
|
| Group SSQ | | 32 | | | | |
|
3024
3093
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
3025
|
-
| 2 | Allen | 25 | Texas | | 13-JUL-2005 |
|
3026
|
-
| 8 | Paul | 24 | Houston | 20,000 | 13-JUL-2005 |
|
3027
|
-
| 9 | James | 44 | Norway | 5,000 | 13-JUL-2005 |
|
3094
|
+
| 2 | Allen | 25 | Texas | | 13-JUL-2005 | 2005 |
|
3095
|
+
| 8 | Paul | 24 | Houston | 20,000 | 13-JUL-2005 | 2005 |
|
3096
|
+
| 9 | James | 44 | Norway | 5,000 | 13-JUL-2005 | 2005 |
|
3028
3097
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
3029
3098
|
| Group SSQ | | 56 | | | | |
|
3030
3099
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
3031
|
-
| 3 | Teddy | 23 | Norway | 20,000 | 13-DEC-2007 |
|
3032
|
-
| 4 | Mark | 25 | Rich-Mond | 65,000 | 13-DEC-2007 |
|
3033
|
-
| 5 | David | 27 | Texas | 85,000 | 13-DEC-2007 |
|
3100
|
+
| 3 | Teddy | 23 | Norway | 20,000 | 13-DEC-2007 | 2007 |
|
3101
|
+
| 4 | Mark | 25 | Rich-Mond | 65,000 | 13-DEC-2007 | 2007 |
|
3102
|
+
| 5 | David | 27 | Texas | 85,000 | 13-DEC-2007 | 2007 |
|
3034
3103
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
3035
3104
|
| Group SSQ | | 43 | | | | |
|
3036
3105
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
data/TODO.org
CHANGED
@@ -1,10 +1,37 @@
|
|
1
|
+
|
2
|
+
* TODO Specify Column Widths
|
3
|
+
Allow a formatter to specify column widths. This could be a number of
|
4
|
+
characters, which would be interpreted as a number of "ems" for LaTeX.
|
5
|
+
Cell content larger than the width would be truncated. Any column without a
|
6
|
+
width specified would be set at the width of the longest value in that cell,
|
7
|
+
after initial formatting.
|
8
|
+
|
9
|
+
#+begin_SRC ruby
|
10
|
+
tab.to_text do |f|
|
11
|
+
f.widths(a: 13, b: 30)
|
12
|
+
end
|
13
|
+
#+end_SRC
|
14
|
+
|
15
|
+
Possible enhancements:
|
16
|
+
- specify an overall width and column widths as decimal or fractions, so that
|
17
|
+
a column's width would be that fraction of the overall width.
|
18
|
+
- specify a Range for a width, so that the column would at least min and at
|
19
|
+
most max, otherwise the width of its largest cell.
|
20
|
+
|
1
21
|
* TODO Conversion to Spreadsheets
|
2
22
|
- State "TODO" from [2017-04-21 Fri 10:36]
|
3
23
|
This is a [[https://github.com/westonganger/spreadsheet_architect][gem]] that I can include into the Table model to convert a table into
|
4
24
|
a spread-sheet, or even a sheet in a multi-sheet spreadsheet file.
|
5
25
|
|
6
|
-
* TODO Add
|
26
|
+
* TODO Add Quandl or EODDATA Queries
|
27
|
+
Possible replacements for YQL.
|
28
|
+
|
29
|
+
* CNCL Add from_yql for fetching from Yahoo
|
30
|
+
CLOSED: [2022-01-30 Sun 06:03]
|
7
31
|
- State "TODO" from [2017-04-21 Fri 10:35]
|
32
|
+
|
33
|
+
Cancelled because Yahoo shut down the YQL api service.
|
34
|
+
|
8
35
|
Add a constructor to allow fetching stock data from yql. Perhaps grab all
|
9
36
|
available fields, then allow a select of those of interest.
|
10
37
|
|
data/lib/ext/array.rb
CHANGED
@@ -12,4 +12,21 @@ class Array
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
def filter_to_type(typ)
|
17
|
+
if typ == 'Boolean'
|
18
|
+
compact.select { |i| i.is_a?(TrueClass) || i.is_a?(FalseClass) }
|
19
|
+
elsif typ == 'DateTime'
|
20
|
+
compact.select { |i| i.is_a?(Date) || i.is_a?(DateTime) || i.is_a?(Time) }
|
21
|
+
.map { |i| i.to_datetime }
|
22
|
+
elsif typ == 'Numeric'
|
23
|
+
compact.select { |i| i.is_a?(Numeric) }
|
24
|
+
elsif typ == 'String'
|
25
|
+
map { |i| i.to_s }
|
26
|
+
elsif typ == 'NilClass'
|
27
|
+
self
|
28
|
+
else
|
29
|
+
raise ArgumentError, "cannot filter_to_type for type '#{typ}'"
|
30
|
+
end
|
31
|
+
end
|
15
32
|
end
|