tablestakes 0.8.3 → 0.8.4

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -7
  3. data/lib/tablestakes.rb +54 -4
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e42269b7b60a12332a7934b8511db2fc5c60cb59
4
- data.tar.gz: d77bdc6de2bc013ba696eef36876e20e46b1d718
3
+ metadata.gz: 2c4827f9fe7583ab475c276cb8930937e51e7c42
4
+ data.tar.gz: f27a3196f816a096c8d311e3288d4ab3126005dd
5
5
  SHA512:
6
- metadata.gz: 947e1aa780b245619afbba79907e1c7a16b135b93c519e596c9649874f2e689c8d6b8f30bd184b248a17ecfe8e7ed57ee10a120261e01a611fbf17c78f4c67b1
7
- data.tar.gz: 54b58e9bfcaa18f8848a58d0c3fbc98d837e96c098a6633145b899f107ac744415584a41fcbc8ea3732d334d4801da5d09f37742fc9a10728d66c51dd31a4c20
6
+ metadata.gz: f3539e569ca9534174250d0f0a697443e3bbc2e8fa3baf19d6d4ea4787f06504b4150b8bdaf0145daf33d1ce77e5b34b0e1b4de25c312852a0b4d22e94e88206
7
+ data.tar.gz: 6513f7ef2d5ef1dbb3a696b57dae6915ce018f0a6d274b4b1572cd51192df67fd0e92e5cea0e3519339a8e97dccce068207a448d2402283d1f8890af69328990
data/README.md CHANGED
@@ -7,7 +7,7 @@ Tablestakes
7
7
  Tablestakes is a gem for processing tabular data. It is for people who would rather not meddle with
8
8
  a spreadsheet, or load their data into a SQL database. You get the instant gratification of being
9
9
  able to read a tab-delimited file, with header values, and then do field counts, field modifications,
10
- selections, joins, and sorts to your heart's content. Tablestakes operates only in memory, so it
10
+ selections, joins to your heart's content. Tablestakes operates only in memory, so it
11
11
  is fast. Of course that also means that there are some size limitations -- very large tables
12
12
  should be processed with another library.
13
13
 
@@ -25,8 +25,6 @@ Contents
25
25
  How to Install
26
26
  --------------
27
27
 
28
- Tablestakes also does well in the IRB interactive shell, you can make use of:
29
-
30
28
  1. Install the gem
31
29
 
32
30
  ```shell
@@ -45,14 +43,13 @@ Now you're ready to start slicing and dicing your data tables!
45
43
  Philosophy and Conventions
46
44
  --------------------------
47
45
 
48
- Tablestakes is meant to be fast and easy for manipulating your data. It maintains ruby
49
- conventions, like use of Enumerators, method chaining, and mostly non-destructive methods.
46
+ Tablestakes is meant to be fast and easy for manipulating your data. It maintains Ruby
47
+ conventions, like method chaining and mostly non-destructive methods.
50
48
 
51
49
  Tablestakes tables also maintain some conventions for simplicity:
52
50
 
53
51
  * Table column names are always the values in the first row of your data file.
54
- * Fields in the table are always strings (although you can treat them as numbers or dates
55
- when needed).
52
+ * Fields in the table are always strings (conversion to numbers or dates is a potential enhancement).
56
53
  * Methods only modify one dimension at a time. So, for instance, `Table#select` only selects
57
54
  columns and `Table#where` only selects rows. Chain them together for the desired effect.
58
55
  * Tables are ordered, both columns and rows, until modified.
@@ -216,3 +213,13 @@ file.
216
213
  Some methods, such as `Table#row` and `Table#column` return Arrays, and of course these are
217
214
  readily modified using their own native methods.
218
215
 
216
+ Future Enhancements
217
+ -------------------
218
+
219
+ Some future enhancements that would make this gem better include:
220
+
221
+ 1. Implement Ruby Enumerators
222
+
223
+ 2. Include some concept of data type ... at least FixedNum and Date.
224
+
225
+ 3. `Table#sort` method -- probably requires enumerators and data types to be effective.
data/lib/tablestakes.rb CHANGED
@@ -67,6 +67,54 @@ class Table
67
67
  Array(get_row(index))
68
68
  end
69
69
 
70
+ # Add a column to the Table. Returns nil if the column name is already taken
71
+ # or there are not the correct number of values.
72
+ #
73
+ # +colname+:: +String+ to identify the name of the column
74
+ # +column_vals+:: +Array+ to hold the column values
75
+ def add_column(colname, column_vals)
76
+ # check arguments
77
+ return nil if @table.has_key?(colname)
78
+ return nil unless column_vals.length == @table[@headers.first].length
79
+
80
+ @headers << colname
81
+ @table[colname] = Array.new(column_vals)
82
+ end
83
+
84
+ # Add a row to the Table, appending it to the end. Returns nil if
85
+ # there are not the correct number of values.
86
+ #
87
+ # +row_vals+:: +Array+ to hold the row values
88
+ def add_row(row_vals)
89
+ add_rows([row_vals])
90
+ end
91
+
92
+ # Delete a column from the Table. Returns nil if the column name does not exist.
93
+ #
94
+ # +colname+:: +String+ to identify the name of the column
95
+ def del_column(colname)
96
+ # check arguments
97
+ return nil unless @table.has_key?(colname)
98
+
99
+ @headers.delete(colname)
100
+ @table.delete(colname)
101
+ end
102
+
103
+ # Delete a row from the Table. Returns nil if
104
+ # the row number is not found.
105
+ #
106
+ # +rownum+:: +FixNum+ to hold the row number
107
+ def del_row(rownum)
108
+ # check arguments
109
+ return nil unless rownum <= @table[@headers.first].length
110
+
111
+ @headers.each do |col|
112
+ @table[col].delete_at(rownum)
113
+ end
114
+
115
+ end
116
+
117
+
70
118
  # Converts a +Table+ object to a tab-delimited string.
71
119
  #
72
120
  # none
@@ -139,7 +187,7 @@ class Table
139
187
  # +num+:: OPTIONAL +String+ number of values to return
140
188
  def top(colname, num=1)
141
189
  freq = tally(colname).to_a[1..-1].sort_by {|k,v| v }.reverse
142
- return Table.new(freq[0..num-1].unshift(["State","Count"]))
190
+ return Table.new(freq[0..num-1].unshift([colname,"Count"]))
143
191
  end
144
192
 
145
193
 
@@ -151,7 +199,7 @@ class Table
151
199
  # +num+:: OPTIONAL +String+ number of values to return
152
200
  def bottom(colname, num=1)
153
201
  freq = tally(colname).to_a[1..-1].sort_by {|k,v| v }
154
- return Table.new(freq[0..num-1].unshift(["State","Count"]))
202
+ return Table.new(freq[0..num-1].unshift([colname,"Count"]))
155
203
  end
156
204
 
157
205
 
@@ -216,7 +264,7 @@ class Table
216
264
  result << @headers
217
265
  @table[colname].each_index do |index|
218
266
  if condition
219
- eval("'#{@table[colname][index]}' #{condition}") ? result << get_row(index) : nil
267
+ eval(%q["#{@table[colname][index]}"] << "#{condition}") ? result << get_row(index) : nil
220
268
  else
221
269
  result << get_row(index)
222
270
  end
@@ -343,7 +391,9 @@ class Table
343
391
  @headers.each {|col| @table.store(col, []) }
344
392
  file.each_line do |line|
345
393
  fields = line.chomp.split("\t")
346
- if fields.length != @headers.length
394
+ if fields.length < @headers.length
395
+ (@headers.length - fields.length).times { fields << "" }
396
+ elsif fields.length > @headers.length
347
397
  $stderr.write "INVALID NUMBER OF FIELDS: #{fields.join(';')}\n"
348
398
  else
349
399
  @headers.each { |col| @table[col] << fields.shift }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tablestakes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - J.B. Folkerts