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