fat_table 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f35f99181e39d7569ce7df958ae92742617826e54b8ed2c6352b73c5723a3d44
4
- data.tar.gz: d37acb3f0be27191bafa17ae30b51dfd2db2c4a5d97e6c80fa5399f2618ea98b
3
+ metadata.gz: fa339300269582eedb57d26138bd3fa2de68d526ed4cc94e4c3a369a67989ddb
4
+ data.tar.gz: b35cc4785b208b670d6f039de8ef12351ea0533c37d8802fbf89f57763e63330
5
5
  SHA512:
6
- metadata.gz: eafd2077939c57673358a680490ccbe48218e8b290540790f3526b5945337e53c9366369c255adcc85e01916ad012cbad12132593def15350fd3993304bc5a30
7
- data.tar.gz: e7a542986752ac4f632e7344c49080786e0e52ecbe224a0644a6da7b4ec65dd8ca2b9abe842ee295ad7cf19a7a0ccd0e93b22632716c95533665a21d14b5cc83
6
+ metadata.gz: 49fbab273c609035f9c2a179b0b97cdca067a8a30db754916e7b17d03a435b4d3a4eefb89ddb326ef07c6e5b91632f764ce101de0acbc79fcf6bd876741da4cf
7
+ data.tar.gz: 76f87e5b342da743ea3e0c2000273de35d081ad4835c2423d6342278ebbced67d3a34bd11526c7f32185ac19e0b225356baa02fbcb8b7b630868739a944f0ecb
data/README.org CHANGED
@@ -25,6 +25,16 @@ The following is for org.
25
25
 
26
26
  [[https://travis-ci.org/ddoherty03/fat_table.svg?branch=master]]
27
27
 
28
+ * Version
29
+ #+begin_src ruby :wrap EXAMPLE
30
+ require 'fat_table'
31
+ "Current version is: #{FatTable::VERSION}"
32
+ #+end_src
33
+
34
+ #+begin_EXAMPLE
35
+ Current version is: 0.5.3
36
+ #+end_EXAMPLE
37
+
28
38
  * Introduction
29
39
 
30
40
  ~FatTable~ is a gem that treats tables as a data type. It provides methods for
@@ -57,6 +67,7 @@ array of arrays with its ~.to_aoa~ output function will be rendered in an
57
67
  org-mode buffer as an org-table, ready for processing by other code blocks.
58
68
 
59
69
  * Table of Contents :toc:noexport:
70
+ - [[#version][Version]]
60
71
  - [[#introduction][Introduction]]
61
72
  - [[#installation][Installation]]
62
73
  - [[#using-in-a-gem][Using in a gem]]
@@ -74,6 +85,7 @@ org-mode buffer as an org-table, ready for processing by other code blocks.
74
85
  - [[#without-headers][Without Headers]]
75
86
  - [[#with-headers][With Headers]]
76
87
  - [[#forcing-string-type][Forcing String Type]]
88
+ - [[#designating-tolerant-columns][Designating "Tolerant" Columns]]
77
89
  - [[#from-csv-or-org-mode-files-or-strings][From CSV or Org Mode files or strings]]
78
90
  - [[#from-arrays-of-arrays][From Arrays of Arrays]]
79
91
  - [[#in-ruby-code][In Ruby Code]]
@@ -619,8 +631,80 @@ converted to strings with the #to_s method.
619
631
  +======+======+============+===+=======+===+
620
632
  #+end_EXAMPLE
621
633
 
634
+ **** Designating "Tolerant" Columns
635
+ Related to the problem just discussed is the problem of reading files in from
636
+ the wild where a column may get typed as, say Numeric, but then contain
637
+ something that can't be parsed as a Numeric. ~FatTable~ raises an exception
638
+ is such cases, and that may be what you want if you can control the input.
639
+ But, especially when you cannot do so, it can be helpful to designate one or
640
+ more columns as "tolerant." This means that when a conversion problem occurs,
641
+ the column is forced to String type instead of throwing an exception, and the
642
+ table can continue to be read.
643
+
644
+ All of the table construction methods, allow a keyword parameter,
645
+ ~tolerant_columns~, where you can designate what columns should be convert to
646
+ String type when conversion to the auto-typed column type is not possible.
647
+ The parameter should be an array of headers, in either string or symbol form,
648
+ for which this behavior is desired. In addition, it can be set to the special
649
+ string '*' or symbol ~:*~ to indicate that all the columns should be made
650
+ tolerant.
651
+
652
+ #+begin_src ruby :wrap EXAMPLE
653
+ require 'fat_table'
654
+ tab = FatTable.new(:a, 'b', 'C', :d, :zip, tolerant_columns: [:zip])
655
+ tab << { a: 1, b: 2, c: "<2017-01-21>", d: 'f', e: '', zip: 18552 }
656
+ tab << { a: 3.14, b: 2.17, c: '[2016-01-21 Thu]', d: 'Y', e: nil }
657
+ tab << { zip: '01879--7884' }
658
+ tab << { zip: '66210' }
659
+ tab << { zip: '90210' }
660
+ tab.to_text
661
+ #+end_src
662
+
663
+ #+RESULTS:
664
+ #+begin_EXAMPLE
665
+ +======+======+============+===+=============+===+
666
+ | A | B | C | D | Zip | E |
667
+ +------+------+------------+---+-------------+---+
668
+ | 1 | 2 | 2017-01-21 | F | 18552 | |
669
+ | 3.14 | 2.17 | 2016-01-21 | T | | |
670
+ | | | | | 01879--7884 | |
671
+ | | | | | 66210 | |
672
+ | | | | | 90210 | |
673
+ +======+======+============+===+=============+===+
674
+ #+end_EXAMPLE
675
+
676
+ Another way to designate a column as tolerant is to end a column you want to
677
+ designate as tolerant with a ~!~. The ~!~ will be stripped from the header,
678
+ but it will be marked as tolerant.
679
+ #+begin_src ruby :wrap EXAMPLE
680
+ require 'fat_table'
681
+ tab = FatTable.new(:a, 'b!', 'C', :d, :zip!)
682
+ tab << { a: 1, b: 2, c: "<2017-01-21>", d: 'f', e: '', zip: 18552 }
683
+ tab << { a: 3.14, b: 2.17, c: '[2016-01-21 Thu]', d: 'Y', e: nil }
684
+ tab << { zip: '01879--7884' }
685
+ tab << { zip: '66210', b: 'Not a Number' }
686
+ tab << { zip: '90210' }
687
+ tab.to_text
688
+ #+end_src
689
+
690
+ #+RESULTS:
691
+ #+begin_EXAMPLE
692
+ +======+==============+============+===+=============+===+
693
+ | A | B | C | D | Zip | E |
694
+ +------+--------------+------------+---+-------------+---+
695
+ | 1 | 2 | 2017-01-21 | F | 18552 | |
696
+ | 3.14 | 2.17 | 2016-01-21 | T | | |
697
+ | | | | | 01879--7884 | |
698
+ | | Not a Number | | | 66210 | |
699
+ | | | | | 90210 | |
700
+ +======+==============+============+===+=============+===+
701
+ #+end_EXAMPLE
702
+
622
703
  *** From CSV or Org Mode files or strings
623
- Tables can also be read from ~.csv~ files or files containing ~org-mode~ tables.
704
+ Tables can also be read from ~.csv~ files or files containing ~org-mode~
705
+ tables. Remember that you can make any column tolerant with a
706
+ ~tolerant_columns:~ keyword argument or make them all tolerant by designating
707
+ the pseudo-column ~:*~ as tolerant.
624
708
 
625
709
  In the case of org-mode files, ~FatTable~ skips through the file until it finds
626
710
  a line that look like a table, that is, it begins with any number of spaces
@@ -677,8 +761,10 @@ header row, and the headers are converted to symbols as described above.
677
761
 
678
762
  *** From Arrays of Arrays
679
763
  **** In Ruby Code
680
- You can also initialize a table directly from ruby data structures. You can, for
681
- example, build a table from an array of arrays:
764
+ You can also initialize a table directly from ruby data structures. You can,
765
+ for example, build a table from an array of arrays. Remember that you can
766
+ make any column tolerant with a ~tolerant_columns:~ keyword argument or make
767
+ them all tolerant by designating the pseudo-column ~:*~ as tolerant.
682
768
 
683
769
  #+BEGIN_SRC ruby
684
770
  aoa = [
@@ -772,8 +858,10 @@ This example illustrates several things:
772
858
 
773
859
  A second ruby data structure that can be used to initialize a ~FatTable~ table
774
860
  is an array of ruby Hashes. Each hash represents a row of the table, and the
775
- headers of the table are taken from the keys of the hashes. Accordingly, all the
776
- hashes must have the same keys.
861
+ headers of the table are taken from the keys of the hashes. Accordingly, all
862
+ the hashes must have the same keys. Remember that you can make any column
863
+ tolerant with a ~tolerant_columns:~ keyword argument or make them all tolerant
864
+ by designating the pseudo-column ~:*~ as tolerant.
777
865
 
778
866
  This same method can in fact take an array of any objects that can be converted
779
867
  to a Hash with the ~#to_h~ method, so you can use an array of your own objects
@@ -862,6 +950,10 @@ The ~.connect~ function need only be called once, and the database handle it
862
950
  creates will be used for all subsequent ~.from_sql~ calls until ~.connect~ is
863
951
  called again.
864
952
 
953
+ Remember that you can make any column tolerant with a ~tolerant_columns:~
954
+ keyword argument or make them all tolerant by designating the pseudo-column
955
+ ~:*~ as tolerant.
956
+
865
957
  *** Marking Groups in Input
866
958
  **** Manually
867
959
  At any point, you can add a boundary to a table by invokong the
@@ -83,7 +83,7 @@ module FatTable
83
83
  # col.type #=> 'Numeric'
84
84
  # col.header #=> :prices
85
85
  # col.sum #=> 18376.75
86
- def initialize(header:, items: [], type: 'NilClass')
86
+ def initialize(header:, items: [], type: 'NilClass', tolerant: false)
87
87
  @raw_header = header
88
88
  @header =
89
89
  if @raw_header.is_a?(Symbol)
@@ -92,6 +92,7 @@ module FatTable
92
92
  @raw_header.to_s.as_sym
93
93
  end
94
94
  @type = type
95
+ @tolerant = tolerant
95
96
  msg = "unknown column type '#{type}"
96
97
  raise UserError, msg unless TYPES.include?(@type.to_s)
97
98
 
@@ -141,6 +142,14 @@ module FatTable
141
142
 
142
143
  # :category: Attributes
143
144
 
145
+ # Is this column tolerant of type incompatibilities? If so, the Column
146
+ # type will be forced to String if an incompatible type is found.
147
+ def tolerant?
148
+ @tolerant
149
+ end
150
+
151
+ # :category: Attributes
152
+
144
153
  # Force the column to have String type and then convert all items to
145
154
  # strings.
146
155
  def force_string!
@@ -400,9 +409,18 @@ module FatTable
400
409
 
401
410
  # Append +itm+ to end of the Column after converting it to the Column's
402
411
  # type. If the Column's type is still open, i.e. NilClass, attempt to fix
403
- # the Column's type based on the type of +itm+ as with Column.new.
412
+ # the Column's type based on the type of +itm+ as with Column.new. If its
413
+ # a tolerant column, respond to type errors by converting the column to a
414
+ # String type.
404
415
  def <<(itm)
405
416
  items << convert_to_type(itm)
417
+ rescue IncompatibleTypeError => ex
418
+ if tolerant?
419
+ force_string!
420
+ retry
421
+ else
422
+ raise ex
423
+ end
406
424
  end
407
425
 
408
426
  # :category: Constructors
@@ -37,7 +37,7 @@ module FatTable
37
37
  new_val = convert_to_boolean(val)
38
38
  if new_val.nil?
39
39
  msg = "attempt to add '#{val}' to a column already typed as #{type}"
40
- raise UserError, msg
40
+ raise IncompatibleTypeError, msg
41
41
  end
42
42
  new_val
43
43
  end
@@ -48,7 +48,7 @@ module FatTable
48
48
  new_val = convert_to_date_time(val)
49
49
  if new_val.nil?
50
50
  msg = "attempt to add '#{val}' to a column already typed as #{type}"
51
- raise UserError, msg
51
+ raise IncompatibleTypeError, msg
52
52
  end
53
53
  new_val
54
54
  end
@@ -59,7 +59,7 @@ module FatTable
59
59
  new_val = convert_to_numeric(val)
60
60
  if new_val.nil?
61
61
  msg = "attempt to add '#{val}' to a column already typed as #{type}"
62
- raise UserError, msg
62
+ raise IncompatibleTypeError, msg
63
63
  end
64
64
  new_val
65
65
  end
@@ -70,12 +70,12 @@ module FatTable
70
70
  new_val = convert_to_string(val)
71
71
  if new_val.nil?
72
72
  msg = "attempt to add '#{val}' to a column already typed as #{type}"
73
- raise UserError, msg
73
+ raise IncompatibleTypeError, msg
74
74
  end
75
75
  new_val
76
76
  end
77
77
  else
78
- raise UserError, "Mysteriously, column has unknown type '#{type}'"
78
+ raise LogicError, "Mysteriously, column has unknown type '#{type}'"
79
79
  end
80
80
  end
81
81
 
@@ -121,6 +121,7 @@ module FatTable
121
121
  return val if val.is_a?(DateTime)
122
122
  return val if val.is_a?(Date)
123
123
  return val.to_datetime if val.is_a?(Time)
124
+
124
125
  begin
125
126
  str = val.to_s.clean
126
127
  return nil if str.blank?
@@ -9,6 +9,10 @@ module FatTable
9
9
  # cannot correct.
10
10
  class LogicError < StandardError; end
11
11
 
12
+ # Raised when attempting to add an incompatible type to an already-typed
13
+ # Column.
14
+ class IncompatibleTypeError < UserError; end
15
+
12
16
  # Raised when an external resource is not available due to caller or
13
17
  # programmer error or some failure of the external resource to be available.
14
18
  class TransientError < StandardError; end
@@ -62,19 +62,53 @@ module FatTable
62
62
  # method call.
63
63
  attr_accessor :explicit_boundaries
64
64
 
65
+ # An Array of FatTable::Columns that should be tolerant.
66
+ attr_reader :tolerant_columns
67
+
65
68
  ###########################################################################
66
69
  # Constructors
67
70
  ###########################################################################
68
71
 
69
72
  # :category: Constructors
70
73
 
71
- # Return an empty FatTable::Table object.
72
- def initialize(*heads)
74
+ # Return an empty FatTable::Table object. Specifying headers is optional.
75
+ # Any headers ending with a ! are marked as tolerant, in that, if an
76
+ # incompatible type is added to it, the column is re-typed as a String
77
+ # column, and construction proceeds. The ! is stripped from the header to
78
+ # form the column key, though. You can also provide the names of columns
79
+ # that should be tolerant by using the +tolerant_columns key-word to
80
+ # provide an array of headers that should be tolerant. The special string
81
+ # '*' or the symbol :* indicates that all columns should be created
82
+ # tolerant.
83
+ def initialize(*heads, tolerant_columns: [])
73
84
  @columns = []
74
85
  @explicit_boundaries = []
86
+ @tolerant_columns =
87
+ case tolerant_columns
88
+ when Array
89
+ tolerant_columns.map { |h| h.to_s.as_sym }
90
+ when String
91
+ if tolerant_columns.strip == '*'
92
+ ['*'.to_sym]
93
+ else
94
+ [tolerant_columns.as_sym]
95
+ end
96
+ when Symbol
97
+ if tolerant_columns.to_s.strip == '*'
98
+ ['*'.to_sym]
99
+ else
100
+ [tolerant_columns.to_s.as_sym]
101
+ end
102
+ else
103
+ raise ArgumentError, "set tolerant_columns to String, Symbol, or an Array of either"
104
+ end
75
105
  unless heads.empty?
76
106
  heads.each do |h|
77
- @columns << Column.new(header: h)
107
+ if h.to_s.end_with?('!') || @tolerant_columns.include?(h)
108
+ @columns << Column.new(header: h.to_s.sub(/!\s*\z/, ''), tolerant: true)
109
+ else
110
+ @columns << Column.new(header: h)
111
+ end
78
112
  end
79
113
  end
80
114
  end
@@ -99,9 +133,9 @@ module FatTable
99
133
 
100
134
  # Construct a Table from the contents of a CSV file named +fname+. Headers
101
135
  # will be taken from the first CSV row and converted to symbols.
102
- def self.from_csv_file(fname)
136
+ def self.from_csv_file(fname, tolerant_columns: [])
103
137
  File.open(fname, 'r') do |io|
104
- from_csv_io(io)
138
+ from_csv_io(io, tolerant_columns: tolerant_columns)
105
139
  end
106
140
  end
107
141
 
@@ -109,8 +143,8 @@ module FatTable
109
143
 
110
144
  # Construct a Table from a CSV string +str+, treated in the same manner as
111
145
  # the input from a CSV file in ::from_org_file.
112
- def self.from_csv_string(str)
113
- from_csv_io(StringIO.new(str))
146
+ def self.from_csv_string(str, tolerant_columns: [])
147
+ from_csv_io(StringIO.new(str), tolerant_columns: tolerant_columns)
114
148
  end
115
149
 
116
150
  # :category: Constructors
@@ -119,9 +153,9 @@ module FatTable
119
153
  # file named +fname+. Headers are taken from the first row if the second row
120
154
  # is an hrule. Otherwise, synthetic headers of the form +:col_1+, +:col_2+,
121
155
  # etc. are created.
122
- def self.from_org_file(fname)
156
+ def self.from_org_file(fname, tolerant_columns: [])
123
157
  File.open(fname, 'r') do |io|
124
- from_org_io(io)
158
+ from_org_io(io, tolerant_columns: tolerant_columns)
125
159
  end
126
160
  end
127
161
 
@@ -129,8 +163,8 @@ module FatTable
129
163
 
130
164
  # Construct a Table from a string +str+, treated in the same manner as the
131
165
  # contents of an org-mode file in ::from_org_file.
132
- def self.from_org_string(str)
133
- from_org_io(StringIO.new(str))
166
+ def self.from_org_string(str, tolerant_columns: [])
167
+ from_org_io(StringIO.new(str), tolerant_columns: tolerant_columns)
134
168
  end
135
169
 
136
170
  # :category: Constructors
@@ -149,8 +183,8 @@ module FatTable
149
183
  # :hlines no +) org-mode strips all hrules from the table; otherwise (+
150
184
  # HEADER: :hlines yes +) they are indicated with nil elements in the outer
151
185
  # array.
152
- def self.from_aoa(aoa, hlines: false)
153
- from_array_of_arrays(aoa, hlines: hlines)
186
+ def self.from_aoa(aoa, hlines: false, tolerant_columns: [])
187
+ from_array_of_arrays(aoa, hlines: hlines, tolerant_columns: tolerant_columns)
154
188
  end
155
189
 
156
190
  # :category: Constructors
@@ -160,9 +194,9 @@ module FatTable
160
194
  # keys, which, when converted to symbols will become the headers for the
161
195
  # Table. If hlines is set true, mark a group boundary whenever a nil, rather
162
196
  # than a hash appears in the outer array.
163
- def self.from_aoh(aoh, hlines: false)
197
+ def self.from_aoh(aoh, hlines: false, tolerant_columns: [])
164
198
  if aoh.first.respond_to?(:to_h)
165
- from_array_of_hashes(aoh, hlines: hlines)
199
+ from_array_of_hashes(aoh, hlines: hlines, tolerant_columns: tolerant_columns)
166
200
  else
167
201
  raise UserError,
168
202
  "Cannot initialize Table with an array of #{input[0].class}"
@@ -181,7 +215,7 @@ module FatTable
181
215
 
182
216
  # Construct a Table by running a SQL +query+ against the database set up
183
217
  # with FatTable.connect, with the rows of the query result as rows.
184
- def self.from_sql(query)
218
+ def self.from_sql(query, tolerant_columns: [])
185
219
  msg = 'FatTable.db must be set with FatTable.connect'
186
220
  raise UserError, msg if FatTable.db.nil?
187
221
 
@@ -203,8 +237,8 @@ module FatTable
203
237
  # Construct table from an array of hashes or an array of any object that
204
238
  # can respond to #to_h. If an array element is a nil, mark it as a group
205
239
  # boundary in the Table.
206
- def from_array_of_hashes(hashes, hlines: false)
207
- result = new
240
+ def from_array_of_hashes(hashes, hlines: false, tolerant_columns: [])
241
+ result = new(tolerant_columns: tolerant_columns)
208
242
  hashes.each do |hsh|
209
243
  if hsh.nil?
210
244
  unless hlines
@@ -232,8 +266,8 @@ module FatTable
232
266
  # hlines are stripped from the table, otherwise (:hlines yes) they are
233
267
  # indicated with nil elements in the outer array as expected by this
234
268
  # method when hlines is set true.
235
- def from_array_of_arrays(rows, hlines: false)
236
- result = new
269
+ def from_array_of_arrays(rows, hlines: false, tolerant_columns: [])
270
+ result = new(tolerant_columns: tolerant_columns)
237
271
  headers = []
238
272
  if !hlines
239
273
  # Take the first row as headers
@@ -269,8 +303,8 @@ module FatTable
269
303
  result
270
304
  end
271
305
 
272
- def from_csv_io(io)
273
- result = new
306
+ def from_csv_io(io, tolerant_columns: [])
307
+ result = new(tolerant_columns: tolerant_columns)
274
308
  ::CSV.new(io, headers: true, header_converters: :symbol,
275
309
  skip_blanks: true).each do |row|
276
310
  result << row.to_h
@@ -283,7 +317,7 @@ module FatTable
283
317
  # header row must be marked with an hline (i.e, a row that looks like
284
318
  # '|---+--...--|') and groups of rows may be marked with hlines to
285
319
  # indicate group boundaries.
286
- def from_org_io(io)
320
+ def from_org_io(io, tolerant_columns: [])
287
321
  table_re = /\A\s*\|/
288
322
  hrule_re = /\A\s*\|[-+]+/
289
323
  rows = []
@@ -318,7 +352,7 @@ module FatTable
318
352
  rows << line.split('|').map(&:clean)
319
353
  end
320
354
  end
321
- from_array_of_arrays(rows, hlines: true)
355
+ from_array_of_arrays(rows, hlines: true, tolerant_columns: tolerant_columns)
322
356
  end
323
357
  end
324
358
 
@@ -412,6 +446,15 @@ module FatTable
412
446
 
413
447
  # :category: Attributes
414
448
 
449
+ # Return whether the column with the given head should be made tolerant.
450
+ def tolerant_col?(h)
451
+ return true if tolerant_columns.include?(:'*')
452
+
453
+ tolerant_columns.include?(h)
454
+ end
455
+
456
+ # :category: Attributes
457
+
415
458
  # Return the number of rows in the Table.
416
459
  def size
417
460
  return 0 if columns.empty?
@@ -571,7 +614,8 @@ module FatTable
571
614
  range = group_row_range(k)
572
615
  tab_col = column(col)
573
616
  gitems = tab_col.items[range]
574
- cols << Column.new(header: col, items: gitems, type: tab_col.type)
617
+ cols << Column.new(header: col, items: gitems,
618
+ type: tab_col.type, tolerant: tab_col.tolerant?)
575
619
  end
576
620
  cols
577
621
  end
@@ -941,7 +985,12 @@ module FatTable
941
985
  expr = expr.to_s
942
986
  result = empty_dup
943
987
  headers.each do |h|
944
- col = Column.new(header: h)
988
+ col =
989
+ if tolerant_col?(h)
990
+ Column.new(header: h, tolerant: true)
991
+ else
992
+ Column.new(header: h)
993
+ end
945
994
  result.add_column(col)
946
995
  end
947
996
  ev = Evaluator.new(ivars: { row: 0, group: 0 })
@@ -1406,6 +1455,9 @@ module FatTable
1406
1455
 
1407
1456
  private
1408
1457
 
1458
+ # Collapse a group of rows to a single row by applying the aggregator from
1459
+ # the +agg_cols+ to the items in that column and the presumably identical
1460
+ # value in the +grp_cols to those columns.
1409
1461
  def row_from_group(rows, grp_cols, agg_cols)
1410
1462
  new_row = {}
1411
1463
  grp_cols.each do |h|
@@ -1440,7 +1492,7 @@ module FatTable
1440
1492
  # This column is new, so it needs nil items for all prior rows lest
1441
1493
  # the value be added to a prior row.
1442
1494
  items = Array.new(size, nil)
1443
- columns << Column.new(header: h, items: items)
1495
+ columns << Column.new(header: h, items: items, tolerant: tolerant_col?(h))
1444
1496
  end
1445
1497
  headers.each do |h|
1446
1498
  # NB: This adds a nil if h is not in row.
@@ -2,5 +2,5 @@
2
2
 
3
3
  module FatTable
4
4
  # The current version of FatTable
5
- VERSION = '0.5.2'
5
+ VERSION = '0.5.3'
6
6
  end
data/lib/fat_table.rb CHANGED
@@ -61,22 +61,22 @@ module FatTable
61
61
 
62
62
  # Return an empty FatTable::Table object. You can use FatTable::Table#add_row
63
63
  # or FatTable::Table#add_column to populate the table with data.
64
- def self.new(*args)
65
- Table.new(*args)
64
+ def self.new(*args, tolerant_columns: [])
65
+ Table.new(*args, tolerant_columns: tolerant_columns)
66
66
  end
67
67
 
68
68
  # Construct a FatTable::Table from the contents of a CSV file given by the
69
69
  # file name +fname+. Headers will be taken from the first row and converted to
70
70
  # symbols.
71
- def self.from_csv_file(fname)
72
- Table.from_csv_file(fname)
71
+ def self.from_csv_file(fname, tolerant_columns: [])
72
+ Table.from_csv_file(fname, tolerant_columns: tolerant_columns)
73
73
  end
74
74
 
75
75
  # Construct a FatTable::Table from the string +str+, treated in the same
76
76
  # manner as if read the input from a CSV file. Headers will be taken from the
77
77
  # first row and converted to symbols.
78
- def self.from_csv_string(str)
79
- Table.from_csv_string(str)
78
+ def self.from_csv_string(str, tolerant_columns: [])
79
+ Table.from_csv_string(str, tolerant_columns: tolerant_columns)
80
80
  end
81
81
 
82
82
  # Construct a FatTable::Table from the first table found in the Emacs org-mode
@@ -84,8 +84,8 @@ module FatTable
84
84
  # is an hline. Otherwise, synthetic headers of the form +:col_1+, +:col_2+,
85
85
  # etc. are created. Any other hlines will be treated as marking a boundary in
86
86
  # the table.
87
- def self.from_org_file(fname)
88
- Table.from_org_file(fname)
87
+ def self.from_org_file(fname, tolerant_columns: [])
88
+ Table.from_org_file(fname, tolerant_columns: tolerant_columns)
89
89
  end
90
90
 
91
91
  # Construct a FatTable::Table from the first table found in the string +str+,
@@ -93,8 +93,8 @@ module FatTable
93
93
  # are taken from the first row if the second row is an hrule. Otherwise,
94
94
  # synthetic headers of the form :col_1, :col_2, etc. are created. Any other
95
95
  # hlines will be treated as marking a boundary in the table.
96
- def self.from_org_string(str)
97
- Table.from_org_string(str)
96
+ def self.from_org_string(str, tolerant_columns: [])
97
+ Table.from_org_string(str, tolerant_columns: tolerant_columns)
98
98
  end
99
99
 
100
100
  # Construct a FatTable::Table from the array of arrays +aoa+. By default, with
@@ -108,8 +108,8 @@ module FatTable
108
108
  # org-mode code blocks, by default (+:hlines no+) all hlines are stripped from
109
109
  # the table, otherwise (+:hlines yes+) they are indicated with nil elements in
110
110
  # the outer array.
111
- def self.from_aoa(aoa, hlines: false)
112
- Table.from_aoa(aoa, hlines: hlines)
111
+ def self.from_aoa(aoa, hlines: false, tolerant_columns: [])
112
+ Table.from_aoa(aoa, hlines: hlines, tolerant_columns: tolerant_columns)
113
113
  end
114
114
 
115
115
  # Construct a FatTable::Table from the array of hashes +aoh+, which can be an
@@ -117,8 +117,8 @@ module FatTable
117
117
  # interpret nil separators as marking boundaries in the new Table. All hashes
118
118
  # must have the same keys, which, converted to symbols, become the headers for
119
119
  # the new Table.
120
- def self.from_aoh(aoh, hlines: false)
121
- Table.from_aoh(aoh, hlines: hlines)
120
+ def self.from_aoh(aoh, hlines: false, tolerant_columns: [])
121
+ Table.from_aoh(aoh, hlines: hlines, tolerant_columns: tolerant_columns)
122
122
  end
123
123
 
124
124
  # Construct a FatTable::Table from another FatTable::Table. Inherit any group
@@ -130,8 +130,8 @@ module FatTable
130
130
  # Construct a Table by running a SQL query against the database set up with
131
131
  # FatTable.connect. Return the Table with the query results as rows and the
132
132
  # headers from the query, converted to symbols, as headers.
133
- def self.from_sql(query)
134
- Table.from_sql(query)
133
+ def self.from_sql(query, tolerant_columns: [])
134
+ Table.from_sql(query, tolerant_columns: tolerant_columns)
135
135
  end
136
136
 
137
137
  ########################################################################
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat_table
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel E. Doherty
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-22 00:00:00.000000000 Z
11
+ date: 2022-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -332,7 +332,7 @@ licenses: []
332
332
  metadata:
333
333
  allowed_push_host: https://rubygems.org
334
334
  yard.run: yri
335
- post_install_message:
335
+ post_install_message:
336
336
  rdoc_options: []
337
337
  require_paths:
338
338
  - lib
@@ -348,7 +348,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
348
348
  version: '0'
349
349
  requirements: []
350
350
  rubygems_version: 3.3.3
351
- signing_key:
351
+ signing_key:
352
352
  specification_version: 4
353
353
  summary: Provides tools for working with tables as a data type.
354
354
  test_files: []