trials 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5033fea5530e8edaef0c0bbf7fcf40870f18fb032fc4ee7100b61207f20961e6
4
+ data.tar.gz: e7f712dd6dced3906afce0a9c7e3e6a9b1f3bb0c4e03b02ef5a98ee2d734a73c
5
+ SHA512:
6
+ metadata.gz: f476adf71a5922beed446d915bd435b403687890ded4e0fe740cfa496a92ac43280cd9b7072462468a9f8e3c3258069b9d3e643f1422472af1c99174a5b465cf
7
+ data.tar.gz: 3e9bf00009e10d1845761992cdd9db5ff1b5e698454be13b6053e80ee803f994b11f4cf302765c212829251e41ab20fcd17953119514971bb85548acca593bea
data/bin/trial ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/trial'
4
+
5
+ # env
6
+ START_TIME = Time.now
7
+ SCRIPT_NAME = ARGV[0].gsub('.rb', '')
8
+ RUN = "#{START_TIME.strftime("%Y%m%dT%H%M%S")}_#{SCRIPT_NAME}"
9
+ ROOT = Dir.pwd
10
+ SECRETS = begin
11
+ if File.exists?('secrets.yml')
12
+ JSON.parse(
13
+ YAML.load_file('secrets.yml').to_json,
14
+ object_class: OpenStruct,
15
+ )
16
+ else
17
+ {}
18
+ end
19
+ end
20
+
21
+ # init standard dirs
22
+ FileUtils.mkdir_p("seeds")
23
+ FileUtils.mkdir_p("results/#{RUN}")
24
+ FileUtils.mkdir_p("tmp")
25
+
26
+ # log start
27
+ log "starting #{SCRIPT_NAME} at #{START_TIME.iso8601}"
28
+ log nil
29
+
30
+ # run script
31
+ load "#{SCRIPT_NAME}.rb"
32
+
33
+ # log end
34
+ END_TIME = Time.now
35
+ log nil
36
+ log "done at #{END_TIME.iso8601}, took #{(END_TIME - START_TIME).round(4)}s"
@@ -0,0 +1,37 @@
1
+ # normal format <number> <STREET NAME>, <CITY>, <STATE> <postal>
2
+
3
+ def normalize_address(address)
4
+ return if address.blank?
5
+
6
+ cleaner_string = if address.respond_to?(:address1)
7
+ "#{address.address1}, #{address.city}, #{address.state} #{address.postal_code}"
8
+ else
9
+ address
10
+ end
11
+
12
+ cleaner_string = cleaner_string.gsub('#', ' #').squish
13
+ parsed = StreetAddress::US.parse(cleaner_string)
14
+
15
+ return if parsed.blank?
16
+ return if parsed.number.blank?
17
+ return if parsed.street.blank?
18
+ return if parsed.city.blank?
19
+ return if parsed.state.blank?
20
+ return if parsed.postal_code.blank?
21
+
22
+ parsed.prefix = nil
23
+ parsed.suffix = nil
24
+ parsed.unit_prefix = nil
25
+ parsed.unit = nil
26
+ parsed.postal_code_ext = nil
27
+
28
+ parsed.to_s.upcase
29
+ end
30
+
31
+ def parse_address(address_string)
32
+ StreetAddress::US.parse(address_string)
33
+ end
34
+
35
+ def normalize_and_parse_address(address_string)
36
+ StreetAddress::US.parse(normalize_address(address_string))
37
+ end
@@ -0,0 +1,84 @@
1
+ # normal <FIRST> <LAST>
2
+
3
+ Name = Struct.new(:first_name, :middle_name, :last_name)
4
+
5
+ class NamePartsParser
6
+ def initialize(name_string)
7
+ @namae = Namae.parse((name_string || '').upcase).first
8
+ end
9
+
10
+ def first
11
+ normalize_name(split_first_and_middle(given).first)
12
+ end
13
+
14
+ def middle
15
+ normalize_name(split_first_and_middle(given).last)
16
+ end
17
+
18
+ def last
19
+ normalize_name(family)
20
+ end
21
+
22
+ private
23
+
24
+ def given
25
+ @namae&.given || ''
26
+ end
27
+
28
+ def family
29
+ @namae&.family || ''
30
+ end
31
+
32
+ def split_first_and_middle(first_and_middle)
33
+ names = first_and_middle.split(' ', 2)
34
+ names.length == 1 ? names + [''] : names
35
+ end
36
+ end
37
+
38
+ def normalize_name(name)
39
+ return if name.blank?
40
+
41
+ name = name_from_parts(name) if name.respond_to?(:first_name)
42
+
43
+ name.strip.upcase.delete('^A-Z\ \-').squeeze(" ")
44
+ end
45
+
46
+ def normalize_full_names(names)
47
+ Array.wrap(names)
48
+ .map { |n| normalize_full_name(n) }
49
+ .map(&:to_s)
50
+ .map(&:presence)
51
+ .compact
52
+ .uniq
53
+ end
54
+
55
+ def normalize_full_name(name)
56
+ return if name.blank?
57
+
58
+ name.strip.upcase.delete('^A-Z\ \-').squeeze(" ")
59
+ end
60
+
61
+ def parse_name(name)
62
+ NamePartsParser.new(name)
63
+ end
64
+
65
+ def normalize_and_parse_name(name)
66
+ NamePartsParser.new(normalize_name(name))
67
+ end
68
+
69
+ # private
70
+
71
+ def name_from_parts(name)
72
+ first = normalize_name_part(name.first_name)
73
+ last = normalize_name_part(name.last_name)
74
+
75
+ [first, last].join(' ')
76
+ end
77
+
78
+ def full_name_from_parts(name)
79
+ first = normalize_name_part(name.first_name)
80
+ middle = normalize_name_part(name.middle_name)
81
+ last = normalize_name_part(name.last_name)
82
+
83
+ [first, middle, last].join(' ')
84
+ end
@@ -0,0 +1,67 @@
1
+ def ddb_connection
2
+ @connection ||= Aws::DynamoDB::Client.new(
3
+ access_key_id: secrets.aws.key,
4
+ secret_access_key: secrets.aws.secret,
5
+ region: secrets.aws.region,
6
+ )
7
+ end
8
+
9
+ def cached_ddb_scan(query)
10
+ json_cache(query.dig(:table_name)) { ddb_scan(query) }
11
+ end
12
+
13
+ def ddb_scan(query)
14
+ segmentation = query.delete(:segmentation) || 4
15
+
16
+ threads = (0..segmentation - 1).map do |segment|
17
+ Thread.new do
18
+ Thread.current[:output] = ddb_scan_without_segmentation(
19
+ query.merge(
20
+ total_segments: segmentation,
21
+ segment: segment,
22
+ ),
23
+ )
24
+ end
25
+ end
26
+
27
+ threads.each(&:join)
28
+
29
+ threads.map { |t| t[:output] }.flatten
30
+ end
31
+
32
+ def ddb_scan_without_segmentation(query)
33
+ result = nil
34
+ requests = 0
35
+ items = []
36
+
37
+ loop do
38
+ break unless result.blank? || result.last_evaluated_key.present?
39
+
40
+ result = ddb_connection.scan(query.merge(exclusive_start_key: result&.last_evaluated_key))
41
+ items += result.items.compact.map(&:symbolize_keys)
42
+ end
43
+
44
+ items
45
+ end
46
+
47
+ def ddb_upload_items(table, all_items)
48
+ all_items.each_slice(25).with_index do |items, i|
49
+ next unless items.any?
50
+
51
+ begin
52
+ ddb_connection.batch_write_item(
53
+ request_items: {
54
+ table => items.compact.map do |item|
55
+ {
56
+ put_request: {
57
+ item: item
58
+ }
59
+ }
60
+ end
61
+ }
62
+ )
63
+ end
64
+
65
+ yield(items, i * 25) if block_given?
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ def timeit
2
+ log(Benchmark.measure { yield }.to_s)
3
+ end
@@ -0,0 +1,19 @@
1
+ def read_csv(filename)
2
+ CSV
3
+ .foreach(seeds_path(filename), headers: true)
4
+ .map(&:to_h)
5
+ .map(&:symbolize_keys)
6
+ .select { |i| i.values.any?(&:present?) }
7
+ end
8
+
9
+ def write_csv_from_hashes(file, hash_set, attrs: nil)
10
+ attrs ||= uniq_hash_keys(hash_set)
11
+
12
+ CSV.open(results_path(file), 'w') do |csv|
13
+ csv << attrs
14
+
15
+ hash_set.each do |c|
16
+ csv << attrs.map { |a| c.send(:dig, a) }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,110 @@
1
+ # paths
2
+
3
+ def seeds_path(name)
4
+ "#{ROOT}/seeds/#{name}"
5
+ end
6
+
7
+ alias seed_path seeds_path
8
+
9
+ def seed_exists?(name)
10
+ File.exist?(seed_path(name))
11
+ end
12
+
13
+ alias seeds_exist? seed_exists?
14
+
15
+ def results_path(name)
16
+ "#{ROOT}/results/#{RUN}/#{name}"
17
+ end
18
+
19
+ alias result_path results_path
20
+
21
+ def result_exists?(name)
22
+ File.exist?(result_path(name))
23
+ end
24
+
25
+ alias results_exist? result_exists?
26
+
27
+ def tmp_path(name)
28
+ "#{ROOT}/tmp/#{name}"
29
+ end
30
+
31
+ def tmp_exists?(name)
32
+ File.exist?(tmp_path(name))
33
+ end
34
+
35
+ def list_dir(dir)
36
+ Dir["#{seeds_path(dir)}/**/*"]
37
+ end
38
+
39
+ # reading
40
+
41
+ def read(file)
42
+ return unless seed_exists?(file)
43
+ File.read(seeds_path(file))
44
+ end
45
+
46
+ alias read_seed read
47
+ alias read_seeds read
48
+
49
+ def read_tmp(file)
50
+ return unless tmp_exists?(file)
51
+ File.read(tmp_path(file))
52
+ end
53
+
54
+ def readlines(file)
55
+ File.read(seeds_path(file)).split("\n")
56
+ end
57
+
58
+ # writing
59
+
60
+ def write(file, content)
61
+ FileUtils.mkdir_p(File.dirname(results_path(file)))
62
+ File.open(results_path(file), 'w') { |f| f << content }
63
+ end
64
+
65
+ alias write_result write
66
+ alias write_results write
67
+
68
+ def write_tmp(file, content)
69
+ FileUtils.mkdir_p(File.dirname(tmp_path(file)))
70
+ File.open(tmp_path(file), 'w') { |f| f << content }
71
+ end
72
+
73
+ def append(file, content)
74
+ File.open(results_path(file), 'a') { |f| f << content }
75
+ end
76
+
77
+ alias append_result append
78
+ alias append_results append
79
+
80
+ # deleting
81
+
82
+ def delete(file)
83
+ return unless result_exists?(file)
84
+ FileUtils.rm_r(results_path(file))
85
+ end
86
+
87
+ alias delete_result delete
88
+ alias delete_results delete
89
+
90
+ def delete_tmp(file)
91
+ return unless tmp_exists?(file)
92
+ FileUtils.rm_r(tmp_path(file))
93
+ end
94
+
95
+ def delete_seeds(file)
96
+ return unless seed_exists?(file)
97
+ FileUtils.rm_r(seeds_path(file))
98
+ end
99
+
100
+ alias delete_seed delete_seeds
101
+
102
+ # other
103
+
104
+ def make_seed(file)
105
+ FileUtils.cp(results_path(file), seeds_path(file))
106
+ end
107
+
108
+ def make_tmp(file)
109
+ FileUtils.cp(results_path(file), tmp_path(file))
110
+ end
@@ -0,0 +1,8 @@
1
+ def gd_session
2
+ @gd_session ||= begin
3
+ write('config.json', secrets.google.drive_config_json)
4
+ session = GoogleDrive::Session.from_config(results_path("config.json"))
5
+ delete('config.json')
6
+ session
7
+ end
8
+ end
@@ -0,0 +1,90 @@
1
+ def uniq_hash_keys(hashes)
2
+ hashes.flat_map(&:keys).uniq.compact
3
+ end
4
+
5
+ def sanitize_hash_value(hash, key:, type:, date_format: '%Y-%m-%d')
6
+ hash.merge(
7
+ key => or_nil do
8
+ case type
9
+ when :date
10
+ Date.strptime(hash.dig(key), date_format)
11
+ when :datetime
12
+ DateTime.parse(hash.dig(key))
13
+ when :integer, :int
14
+ hash.dig(key).to_i
15
+ when :float
16
+ hash.dig(key).to_f
17
+ when :string
18
+ hash.dig(key).to_s
19
+ when :alphanum
20
+ string_to_alphanum(hash.dig(key))
21
+ when :present?
22
+ hash.dig(key).present?
23
+ end
24
+ end
25
+ )
26
+ end
27
+
28
+ def sanitize_hash_values(hash, scheme = {})
29
+ scheme.each do |k, v|
30
+ hash = sanitize_hash_value(hash, key: k, type: v)
31
+ end
32
+
33
+ hash
34
+ end
35
+
36
+ def rename_hash_key(hash, from:, to:)
37
+ hash[to] = hash.delete(from)
38
+ hash
39
+ end
40
+
41
+ def rename_hash_keys(hash, scheme = {})
42
+ scheme.each do |k, v|
43
+ hash = rename_hash_key(hash, from: k, to: v)
44
+ end
45
+
46
+ hash
47
+ end
48
+
49
+ def merge_hash_groups(*groups, key:, join_type: :inner)
50
+ groups = groups.map { |group| group.map { |g| [g.dig(key), g] }.to_h }
51
+
52
+ keys = begin
53
+ case join_type
54
+ when :inner
55
+ groups.map(&:keys).reduce(&:&)
56
+ when :all
57
+ groups.flat_map(&:keys).uniq
58
+ when :first
59
+ groups.first.keys
60
+ end
61
+ end
62
+
63
+ keys.map { |key| groups.map { |g| g.dig(key) }.compact.reduce(&:merge) }
64
+ end
65
+
66
+ def count_for_group_by(batch, &block)
67
+ batch
68
+ .group_by(&block)
69
+ .map { |k, v| [k, v.length] }
70
+ .to_h
71
+ end
72
+
73
+ def array_to_count_hash(list)
74
+ list.uniq.reduce({}) do |h, i|
75
+ h[i] = list.count(i)
76
+ h
77
+ end
78
+ end
79
+
80
+ def update_counts_hash(counts, update)
81
+ update.each do |k, v|
82
+ if counts.key?(k)
83
+ counts[k] += v
84
+ else
85
+ counts[k] = v
86
+ end
87
+ end
88
+
89
+ counts
90
+ end
@@ -0,0 +1,22 @@
1
+ def read_json(filename)
2
+ result = JSON.parse(read(filename))
3
+
4
+ aggressive_deep_symbolize_keys(result)
5
+ end
6
+
7
+ def write_hashes_to_json(file, hashes)
8
+ write(file, hashes.to_json)
9
+ end
10
+
11
+ def json_cache(key)
12
+ name = "json/#{key}.json"
13
+
14
+ return aggressive_deep_symbolize_keys(JSON.parse(read_tmp(name))) if tmp_exists?(name)
15
+
16
+ write_tmp(name, yield.to_json)
17
+ json_cache(key)
18
+ end
19
+
20
+ def invalidate_json_cache
21
+ delete_tmp("json")
22
+ end
@@ -0,0 +1,42 @@
1
+ def render_table_from_hashes(hash_set, sort: true, headers: nil)
2
+ return 'no data' if hash_set.blank?
3
+
4
+ headers = headers || uniq_hash_keys(hash_set)
5
+
6
+ headers.sort! if sort
7
+
8
+ content = hash_set
9
+ .map { |h| h.select { |k, v| v.present? }.to_h }
10
+ .map { |hash| headers.map { |h| hash.dig(h) } }
11
+ .map { |r| r.map(&:to_s) }
12
+
13
+ TTY::Table.new(header: headers, rows: content).render(:unicode).to_s
14
+ end
15
+
16
+ def log(item, nl: true, quiet: false, each: true)
17
+ item ||= ''
18
+
19
+ if each && item.is_a?(Array)
20
+ item.each { |i| log(i, nl: nl, quiet: quiet, each: false) }
21
+ return
22
+ end
23
+
24
+ File.open(results_path('log.txt'), 'a') do |f|
25
+ f << begin
26
+ if item.is_a?(String) || item.is_a?(Numeric)
27
+ item.to_s
28
+ else
29
+ PP.pp(item, '').chomp
30
+ end
31
+ end
32
+
33
+ f << "\n" if nl
34
+ end
35
+
36
+ print item unless quiet
37
+ puts '' if nl
38
+ end
39
+
40
+ def l(item, nl: true, quiet: false)
41
+ log(item, nl: nl, quiet: quiet, each: false)
42
+ end
@@ -0,0 +1,4 @@
1
+ def pdf_to_text(path)
2
+ `pdftotext "#{seeds_path(path)}" #{tmp_path('tmp_pdf.txt')}; \
3
+ cat #{tmp_path('tmp_pdf.txt')}`
4
+ end
@@ -0,0 +1,26 @@
1
+ def get_single_rollbar_items_page(token:, page:, status: 'active')
2
+ url = URI("https://api.rollbar.com/api/1/instances/?access_token=#{token}&page=#{page}&status=#{status}")
3
+ http = Net::HTTP.new(url.host, url.port)
4
+ http.use_ssl = true
5
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
6
+ request = Net::HTTP::Get.new(url)
7
+ JSON.parse(http.request(request).body).deep_symbolize_keys.dig(:result, :instances)
8
+ end
9
+
10
+ def get_rollbar_items(token:, status: 'active')
11
+ current_page = 0
12
+ items = []
13
+
14
+ loop do
15
+ single_page_of_items = get_single_rollbar_items_page(token: token, page: current_page, status: status)
16
+
17
+ items += single_page_of_items
18
+
19
+ break if single_page_of_items.empty?
20
+ break if yield(current_page, items)
21
+
22
+ current_page += 1
23
+ end
24
+
25
+ items.compact.uniq
26
+ end
@@ -0,0 +1,70 @@
1
+ def hashes_to_sql_temp_table(hashes)
2
+ attrs = uniq_hash_keys(hashes)
3
+
4
+ attr_chars = attrs
5
+ .map { |a| "#{a} varchar" }
6
+ .join(', ')
7
+
8
+ value_tuples = hashes
9
+ .map { |s| '(' + attrs.map { |a| "'#{s.dig(a) }'" }.join(', ') + ')' }
10
+ .join(",\n")
11
+
12
+ <<~SQL
13
+ create temp table seed_data (
14
+ #{attr_chars}
15
+ );
16
+
17
+ insert into seed_data values
18
+ #{value_tuples};
19
+ SQL
20
+ end
21
+
22
+ def create_db(name)
23
+ db_loc = results_path("#{name}.db")
24
+
25
+ raise 'db already exists' if File.exist?(db_loc)
26
+
27
+ db = SQLite3::Database.new(db_loc)
28
+ db.results_as_hash = true
29
+ db
30
+ end
31
+
32
+ def use_db(name)
33
+ db_loc = seeds_path("#{name}.db")
34
+
35
+ raise 'no db exists' unless File.exist?(db_loc)
36
+
37
+ db = SQLite3::Database.new(db_loc)
38
+ db.results_as_hash = true
39
+ db
40
+ end
41
+
42
+ def create_table(db, table, **attrs)
43
+ should_log = attrs.delete(:log)
44
+ attrs = attrs.map { |k, v| " #{k} #{v}" }.join(",\n")
45
+ sql = <<~SQL
46
+ create table #{table} (
47
+ #{attrs}
48
+ );
49
+ SQL
50
+
51
+ log sql if should_log
52
+ db.execute sql
53
+ end
54
+
55
+ def insert_into_db(db, table, **attrs)
56
+ should_log = attrs.delete(:log)
57
+ keys_group = "(#{attrs.keys.join(', ')})"
58
+ values_group = "(#{(['?'] * attrs.values.length).join(', ')})"
59
+ sql = <<~SQL
60
+ insert into #{table} #{keys_group}
61
+ values #{values_group}
62
+ SQL
63
+
64
+ log sql if should_log
65
+ db.execute sql, attrs.values
66
+ end
67
+
68
+ def query_db(db, query)
69
+ db.execute(query)
70
+ end
@@ -0,0 +1,11 @@
1
+ def normalize_string(string)
2
+ string.chomp.strip.squish
3
+ end
4
+
5
+ def string_to_alphanum(string)
6
+ string.gsub(/[^A-Za-z0-9]/, '')
7
+ end
8
+
9
+ def string_encode_utf_8(string)
10
+ string.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
11
+ end
@@ -0,0 +1,21 @@
1
+ def secrets
2
+ SECRETS
3
+ end
4
+
5
+ def or_nil
6
+ val = yield
7
+ raise if val.blank? || val == 0
8
+ val
9
+ rescue StandardError
10
+ end
11
+
12
+ def float?(string)
13
+ true if Float(string) rescue false
14
+ end
15
+
16
+ def aggressive_deep_symbolize_keys(maybe)
17
+ return maybe.deep_symbolize_keys if maybe.respond_to?(:deep_symbolize_keys)
18
+ return maybe.map { |i| aggressive_deep_symbolize_keys(i) } if maybe.respond_to?(:each)
19
+
20
+ maybe
21
+ end
@@ -0,0 +1,11 @@
1
+ def hash_from_xml(str)
2
+ Hash.from_xml(clean_xml(str)).deep_symbolize_keys
3
+ end
4
+
5
+ def prettify_xml(str)
6
+ Nokogiri::XML(str) { |c| c.default_xml.noblanks }.to_xml(indent: 2)
7
+ end
8
+
9
+ def clean_xml(str)
10
+ Nokogiri::XML(str.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')).to_xml
11
+ end
data/lib/trial.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'active_support/all'
2
+ require 'benchmark'
3
+ require 'csv'
4
+ require 'pp'
5
+ require 'set'
6
+ require 'yaml'
7
+
8
+ require_relative 'trial/utils/various'
9
+ require_relative 'trial/utils/csvs'
10
+ require_relative 'trial/utils/hashes'
11
+ require_relative 'trial/utils/logging'
12
+ require_relative 'trial/utils/strings'
13
+ require_relative 'trial/utils/files'
14
+ require_relative 'trial/utils/jsons'
15
+ require_relative 'trial/utils/sqls'
16
+ require_relative 'trial/utils/pdfs'
17
+ require_relative 'trial/utils/xmls'
18
+ require_relative 'trial/utils/benchmarking'
19
+ require_relative 'trial/utils/rollbar'
20
+ require_relative 'trial/utils/aws'
21
+ require_relative 'trial/utils/google_drive'
22
+ require_relative 'trial/data_handling/addresses'
23
+ require_relative 'trial/data_handling/names'
metadata ADDED
@@ -0,0 +1,327 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trials
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - grahamotte
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-01-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: benchmark
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fileutils
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: csv
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: namae
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: nokogiri
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rest-client
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: street_address
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: tty-table
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: sqlite3
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: ostruct
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: google_drive
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: aws-sdk-dynamodb
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: fuzzy_match
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: minitest
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: rake
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ - !ruby/object:Gem::Dependency
252
+ name: pry
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ type: :runtime
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: smalltext
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ version: '0'
272
+ type: :runtime
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - ">="
277
+ - !ruby/object:Gem::Version
278
+ version: '0'
279
+ description:
280
+ email:
281
+ executables:
282
+ - trial
283
+ extensions: []
284
+ extra_rdoc_files: []
285
+ files:
286
+ - bin/trial
287
+ - lib/trial.rb
288
+ - lib/trial/data_handling/addresses.rb
289
+ - lib/trial/data_handling/names.rb
290
+ - lib/trial/utils/aws.rb
291
+ - lib/trial/utils/benchmarking.rb
292
+ - lib/trial/utils/csvs.rb
293
+ - lib/trial/utils/files.rb
294
+ - lib/trial/utils/google_drive.rb
295
+ - lib/trial/utils/hashes.rb
296
+ - lib/trial/utils/jsons.rb
297
+ - lib/trial/utils/logging.rb
298
+ - lib/trial/utils/pdfs.rb
299
+ - lib/trial/utils/rollbar.rb
300
+ - lib/trial/utils/sqls.rb
301
+ - lib/trial/utils/strings.rb
302
+ - lib/trial/utils/various.rb
303
+ - lib/trial/utils/xmls.rb
304
+ homepage:
305
+ licenses:
306
+ - MIT
307
+ metadata: {}
308
+ post_install_message:
309
+ rdoc_options: []
310
+ require_paths:
311
+ - lib
312
+ required_ruby_version: !ruby/object:Gem::Requirement
313
+ requirements:
314
+ - - ">="
315
+ - !ruby/object:Gem::Version
316
+ version: '0'
317
+ required_rubygems_version: !ruby/object:Gem::Requirement
318
+ requirements:
319
+ - - ">="
320
+ - !ruby/object:Gem::Version
321
+ version: '0'
322
+ requirements: []
323
+ rubygems_version: 3.0.3
324
+ signing_key:
325
+ specification_version: 4
326
+ summary: gem for testing out ideas quickly
327
+ test_files: []