tablestakes 0.8.3 → 0.8.4

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