fat_table 0.5.2 → 0.5.3

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 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: []