table_puts 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 39cd50a5295a935701a614576d76a68c0190df8f
4
+ data.tar.gz: 82837ec0ae6cf45a7262ae47c7022084a02ae97e
5
+ SHA512:
6
+ metadata.gz: 7a48a404a9e4cdbc03997648bb92b59591b172761cdce18b767fcdefb7237012dca804238732333dab93d8cdebf2bf812eaa1f7dec4a484a9419c0e690c619db
7
+ data.tar.gz: c085e01e392e6eb961b5379bfd6deb4ed3d37f44b92c4968d141b7b2b4869e30b34e515f6a04840ebd685caa4cece60471fe0ad9805a092a118354a87fa9c316
@@ -0,0 +1,28 @@
1
+ # from https://www.viget.com/articles/easy-gem-configuration-variables-with-defaults
2
+
3
+ module Configuration
4
+
5
+ def configuration
6
+ yield self
7
+ end
8
+
9
+ def define_setting(name, default = nil)
10
+ class_variable_set("@@#{name}", default)
11
+
12
+ define_class_method "#{name}=" do |value|
13
+ class_variable_set("@@#{name}", value)
14
+ end
15
+
16
+ define_class_method name do
17
+ class_variable_get("@@#{name}")
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def define_class_method(name, &block)
24
+ (class << self; self; end).instance_eval do
25
+ define_method name, &block
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ module TablePuts
2
+ require 'helpers/configuration'
3
+ require 'table_puts/printer'
4
+ require 'csv'
5
+ extend Configuration
6
+
7
+ # Set defaults for column width
8
+ #
9
+ # Can be changed by doing:
10
+ # TablePuts.configuration do |config|
11
+ # config.min_column_width = 10
12
+ # end
13
+ define_setting(:min_column_width, 0)
14
+ define_setting(:max_column_width, 20)
15
+
16
+ # Takes in data in the form of an array of hashes all with the same keys
17
+ # and prints a nice looking table
18
+ def self.call(data, min_width: self.min_column_width, max_width: self.max_column_width)
19
+ Printer.new(data, min_width, max_width).call
20
+ end
21
+
22
+ # Takes in the file path of a CSV and prints a nice looking table
23
+ def self.csv(path, min_width: self.min_column_width, max_width: self.max_column_width)
24
+ Printer.new(read_csv(path), min_width, max_width).call
25
+ end
26
+
27
+ private
28
+
29
+ # Transforms CSV into an array of hashes
30
+ def self.read_csv(path)
31
+ csv_data = CSV.open(path).read
32
+ keys = csv_data.shift
33
+ csv_data.map { |items| items.map.with_index { |item, i| [keys[i], item] }.to_h }
34
+ end
35
+ end
@@ -0,0 +1,97 @@
1
+ class TablePuts::Printer
2
+ attr_reader :data, :transposed, :min_width, :max_width
3
+
4
+ def initialize(data, min_width, max_width)
5
+ @data = data
6
+ @transposed = transpose_data
7
+ @min_width = min_width
8
+ @max_width = max_width
9
+ check_widths(min_width, max_width)
10
+ end
11
+
12
+ def call
13
+ puts break_string
14
+ puts header
15
+ puts break_string
16
+ puts rows
17
+ puts break_string
18
+ end
19
+
20
+ # Transforms data into a single hash with each value containing an array of
21
+ # the values from each hash - for example:
22
+ #
23
+ # [ { x: 1, y: 2 }, { x: 3 }, { y: 4 } ]
24
+ # becomes
25
+ # { x: [1, 3], y: [2, 4] }
26
+ #
27
+ def transpose_data
28
+ transposed_data = {}
29
+ data.first.keys.map { |key| transposed_data[key] = [] }
30
+
31
+ data.each do |hash|
32
+ hash.each do |key,value|
33
+ transposed_data[key] << value
34
+ end
35
+ end
36
+ transposed_data
37
+ end
38
+
39
+ def header
40
+ transposed.keys.map.with_index do |key, i|
41
+ key_string = abbreviate(key.to_s).ljust(column_widths[i])
42
+
43
+ "| #{ key_string } "
44
+ end.join + "|"
45
+ end
46
+
47
+ def rows
48
+ justification = calculate_column_justification
49
+ data.map do |row|
50
+ row.map.with_index do |(key, value), i|
51
+ justify = "#{ justification[i] }just".to_sym
52
+ value_string = abbreviate(value.to_s).send(justify, (column_widths[i]))
53
+
54
+ "| #{ value_string } "
55
+ end.join + "|"
56
+ end
57
+ end
58
+
59
+ def break_string
60
+ @break_string ||= column_widths.map { |size| "+-#{ '-'*size }-" }.join + "+"
61
+ end
62
+
63
+ # An array of how many characters wide each column should be
64
+ #
65
+ # You can set a minimum and maximum width for all columns
66
+ # by passing in min_width and max_width
67
+ def column_widths
68
+ @column_widths ||= transposed.map do |value_array|
69
+ largest_width_in_column = value_array.flatten.map { |entry| entry.to_s.length }.max
70
+ [[largest_width_in_column, max_width].min, min_width].max
71
+ end
72
+ end
73
+
74
+ # Computes how we should justify the values in each column
75
+ #
76
+ # If all values in a column contain a number or are nil, then we right justify
77
+ # Otherwise, left justify
78
+ #
79
+ # Returns an array of 'r's and 'l's for each column
80
+ def calculate_column_justification
81
+ transposed.map do |(key, values)|
82
+ values.all? { |entry| entry.to_s.match(/\d/) || entry.nil? } ? 'r' : 'l'
83
+ end
84
+ end
85
+
86
+ def abbreviate(string)
87
+ string == string[0...max_width] ? string : string[0...max_width-3] + "..."
88
+ end
89
+
90
+ def check_widths(min, max)
91
+ if min > max
92
+ puts "WARNING: max_width is greater than min_width"
93
+ puts " This may cause unexpected output"
94
+ puts " min_width: #{ min_width }\tmax_width: #{ max_width }"
95
+ end
96
+ end
97
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: table_puts
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Fauver
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: ryan.fauver@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/helpers/configuration.rb
20
+ - lib/table_puts.rb
21
+ - lib/table_puts/printer.rb
22
+ homepage: https://github.com/rfauver/TablePuts
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.5.1
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Print nice tables in a ruby console
46
+ test_files: []