dinosaur_catalog 2.0
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 +7 -0
- data/LICENSE +21 -0
- data/README +28 -0
- data/bin/african_dinosaur_export.csv +8 -0
- data/bin/dinodex.csv +10 -0
- data/bin/dinosaur_catalog +18 -0
- data/lib/dinosaur_catalog/app.rb +75 -0
- data/lib/dinosaur_catalog/catalog.rb +32 -0
- data/lib/dinosaur_catalog/csv_modifier.rb +47 -0
- data/lib/dinosaur_catalog/dinosaur.rb +36 -0
- data/lib/dinosaur_catalog/display.rb +60 -0
- data/lib/dinosaur_catalog/filters.rb +23 -0
- data/lib/dinosaur_catalog/json_export.rb +12 -0
- data/lib/dinosaur_catalog/user_processing.rb +63 -0
- data/lib/dinosaur_catalog/user_prompts.rb +23 -0
- metadata +87 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 2e8c3738a3da8042fa643bcbdd469f8c2d3f4567
|
|
4
|
+
data.tar.gz: f5d7b0201d267965829d3ae474b7a0da1651aee3
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7021420ac33bea265830a6dcb236700d44b1beb9ea85fe67bccba97cd399a376f3d4958d8fbcf5de96ed3bdba86e0d29f8ff58a9cb680c20c14cc8cbed6cd8cc
|
|
7
|
+
data.tar.gz: 1575cb4e41f70234de9dcf037c1018a70ab3297e6d931e930ae9e87d8725210d69a66de320a6c63c0bc317e9663be6addd9fef32e247a119222486e02a5c23ae
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) <year> <copyright holders>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Dinosaur Catalog
|
|
2
|
+
|
|
3
|
+
It may not be immediately evident, but I am a huge fan of dinosaurs. They're huge and dangerous and have cool names like Giganotosaurus (not to be confused with Gigantosaurus).
|
|
4
|
+
|
|
5
|
+
...
|
|
6
|
+
|
|
7
|
+
Anyway. I need to catalog some dinosaurs for my newest project, DinoDex. I've got a CSV file for the dinosaur facts, and I need the code to read all the dinosaur facts and do some basic manipulations with the data.
|
|
8
|
+
|
|
9
|
+
### Requirements
|
|
10
|
+
|
|
11
|
+
Go check out the CSVs and come back. Done? Cool, I've just got a few features I need:
|
|
12
|
+
|
|
13
|
+
1. I loaded my favorite dinosaurs into a CSV file you'll need to parse. I don't know a lot about African Dinosaurs though, so I downloaded one from The Pirate Bay. It isn't formatted as well as mine, but please try to parse it anyway.
|
|
14
|
+
2. I have friends who ask me a lot of questions about dinosaurs (I'm kind of a big deal). Please make sure the dinodex is able to answer these things for me:
|
|
15
|
+
* Grab all the dinosaurs that were bipeds.
|
|
16
|
+
* Grab all the dinosaurs that were carnivores (fish and insects count).
|
|
17
|
+
* Grab dinosaurs for specific periods (no need to differentiate between Early and Late Cretaceous, btw).
|
|
18
|
+
* Grab only big (> 2 tons) or small dinosaurs.
|
|
19
|
+
* Just to be sure, I'd love to be able to combine criteria at will, even better if I can chain filter calls together.
|
|
20
|
+
3. For a given dino, I'd like to be able to print all the known facts about that dinosaur. If there are facts missing, please don't print empty values, just skip that heading. Make sure to print Early / Late etc for the periods.
|
|
21
|
+
4. Also, I'll probably want to print all the dinosaurs in a given collection (after filtering, etc).
|
|
22
|
+
|
|
23
|
+
#### Extra Credit
|
|
24
|
+
|
|
25
|
+
1. I would love to have a way to do (and chain) generic search by parameters. I can pass in a hash, and I'd like to get the proper list of dinos back out.
|
|
26
|
+
2. CSV isn't may favorite format in the world. Can you implement a JSON export feature?
|
|
27
|
+
|
|
28
|
+
Happy Hunting. (Giganotosaurus was the largest hunting dinosaur, at 46 feet long and up to 8 tons! Suh-weet.)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Genus,Period,Carnivore,Weight,Walking
|
|
2
|
+
Abrictosaurus,Jurassic,No,100,Biped
|
|
3
|
+
Afrovenator,Jurassic,Yes,,Biped
|
|
4
|
+
Carcharodontosaurus,Albian,Yes,3000,Biped
|
|
5
|
+
Giraffatitan,Jurassic,No,6600,Quadruped
|
|
6
|
+
Paralititan,Cretaceous,No,120000,Quadruped
|
|
7
|
+
Suchomimus,Cretaceous,Yes,10400,Biped
|
|
8
|
+
Melanorosaurus,Triassic,No,2400,Quadruped
|
data/bin/dinodex.csv
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
NAME,PERIOD,CONTINENT,DIET,WEIGHT_IN_LBS,WALKING,DESCRIPTION
|
|
2
|
+
Albertosaurus,Late Cretaceous,North America,Carnivore,2000,Biped,Like a T-Rex but smaller.
|
|
3
|
+
Albertonykus,Early Cretaceous,North America,Insectivore,,Biped,Earliest known Alvarezsaurid.
|
|
4
|
+
Baryonyx,Early Cretaceous,Europe,Piscivore,6000,Biped,One of the only known dinosaurs with a fish-only diet.
|
|
5
|
+
Deinonychus,Early Cretaceous,North America,Carnivore,150,Biped,
|
|
6
|
+
Diplocaulus,Late Permian,North America,Carnivore,,Quadruped,They actually had fins on the side of their body.
|
|
7
|
+
Megalosaurus,Jurassic,Europe,Carnivore,2200,Biped,Originally thought to be a Quadruped. First dinosaur to be named.
|
|
8
|
+
Giganotosaurus,Late Cretaceous,South America,Carnivore,30420,Biped,Largest hunter and also the coolest ever.
|
|
9
|
+
Quetzalcoatlus,Late Cretaceous,North America,Carnivore,440,Quadruped,Largest known flying animal of all time.
|
|
10
|
+
Yangchuanosaurus,Oxfordian,Asia,Carnivore,7200,Biped,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative '../lib/dinosaur_catalog/catalog'
|
|
4
|
+
require_relative '../lib/dinosaur_catalog/app'
|
|
5
|
+
|
|
6
|
+
app = DinosaurCatalog::App.new("dinosaur_catalog")
|
|
7
|
+
|
|
8
|
+
USER_FILE_IMPORT = %Q%\nPlease enter the filename of the CSV to import\n\n\
|
|
9
|
+
Enter 'quit' or 'exit' to leave the program.\n\n>> %
|
|
10
|
+
|
|
11
|
+
if ARGV.size == 1
|
|
12
|
+
csv_file = ARGV.shift
|
|
13
|
+
app.launch_app!(File.join(File.dirname(__FILE__), csv_file))
|
|
14
|
+
else
|
|
15
|
+
print USER_FILE_IMPORT
|
|
16
|
+
user_file = gets.chomp
|
|
17
|
+
app.create_app(File.join(File.dirname(__FILE__), user_file))
|
|
18
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'pry'
|
|
2
|
+
require 'active_support'
|
|
3
|
+
require 'active_support/core_ext'
|
|
4
|
+
require 'active_support/inflector/inflections'
|
|
5
|
+
require_relative 'display'
|
|
6
|
+
require_relative 'json_export'
|
|
7
|
+
require_relative 'csv_modifier'
|
|
8
|
+
require_relative 'user_prompts'
|
|
9
|
+
require_relative 'user_processing'
|
|
10
|
+
|
|
11
|
+
module DinosaurCatalog
|
|
12
|
+
class App
|
|
13
|
+
include CsvModifier
|
|
14
|
+
include Filters
|
|
15
|
+
include Display
|
|
16
|
+
include JsonExport
|
|
17
|
+
include UserProcessing
|
|
18
|
+
|
|
19
|
+
EXIT_TERMS = ['quit', 'exit']
|
|
20
|
+
|
|
21
|
+
def initialize(name)
|
|
22
|
+
@app_name = name
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def create_app(file)
|
|
26
|
+
if EXIT_TERMS.include?(file)
|
|
27
|
+
puts "\n\nExiting.\n\n"
|
|
28
|
+
exit!
|
|
29
|
+
else
|
|
30
|
+
puts "\nFile Found!\n"
|
|
31
|
+
launch_app!(file)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def launch_app!(csv_filename=nil)
|
|
36
|
+
@csv_filename = csv_filename
|
|
37
|
+
new_csv_file = normalize_csv_file(csv_filename)
|
|
38
|
+
@catalog = create_catalog(new_csv_file)
|
|
39
|
+
obtain_user_filters
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def create_catalog(filepath)
|
|
43
|
+
@catalog = Catalog.new(filepath)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def perform_search(input)
|
|
47
|
+
exit! if EXIT_TERMS.include? input
|
|
48
|
+
search_terms = get_user_search_terms(input)
|
|
49
|
+
search_dinosaurs(search_terms)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def search_dinosaurs(terms)
|
|
53
|
+
@filtered_dinosaurs = nil
|
|
54
|
+
@filtered_dinosaurs = filter_dinosaur_results(@catalog, terms)
|
|
55
|
+
puts "\nYour search resulted in #{@filtered_dinosaurs.size} dinosaurs:"
|
|
56
|
+
print_search_summary(@filtered_dinosaurs)
|
|
57
|
+
user_processing
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def filter_dinosaur_results(catalog, filters)
|
|
61
|
+
filtered_dinosaur_listings = catalog.dinosaurs
|
|
62
|
+
filters.each do |search_type, criteria|
|
|
63
|
+
filter_function = "filter_#{search_type}".to_sym
|
|
64
|
+
filtered_dinosaur_listings = Catalog.from_array(filtered_dinosaur_listings).send(filter_function, criteria)
|
|
65
|
+
end
|
|
66
|
+
filtered_dinosaur_listings
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def print_search_summary(search_results)
|
|
70
|
+
puts "\n"
|
|
71
|
+
search_results.each { |dinosaur| puts "#{dinosaur.name}" }
|
|
72
|
+
puts "\n"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require_relative 'dinosaur'
|
|
2
|
+
require_relative 'filters'
|
|
3
|
+
|
|
4
|
+
module DinosaurCatalog
|
|
5
|
+
class Catalog
|
|
6
|
+
include Filters
|
|
7
|
+
|
|
8
|
+
attr_reader :dinosaurs
|
|
9
|
+
|
|
10
|
+
def initialize(csv_object=nil)
|
|
11
|
+
#@path = path
|
|
12
|
+
@dinosaurs = []
|
|
13
|
+
build_catalog_entries(csv_object) unless csv_object.nil?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def build_catalog_entries(csv_file)
|
|
17
|
+
CSV.parse(csv_file, headers: true, header_converters: :symbol).each do |data|
|
|
18
|
+
@dinosaurs << create_dinosaur_entry(data[:name], data)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def create_dinosaur_entry(name, attributes)
|
|
23
|
+
Dinosaur.new(name, attributes)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.from_array(array)
|
|
27
|
+
catalog = Catalog.new
|
|
28
|
+
catalog.instance_variable_set(:@dinosaurs, array)
|
|
29
|
+
catalog
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'csv'
|
|
2
|
+
|
|
3
|
+
module DinosaurCatalog
|
|
4
|
+
module CsvModifier
|
|
5
|
+
NORMALIZED_CSV_FILENAME = "normalized_csv_file.csv"
|
|
6
|
+
|
|
7
|
+
ALIAS_TABLE = {
|
|
8
|
+
'Genus' => 'Name',
|
|
9
|
+
'Carnivore' => 'Diet',
|
|
10
|
+
'Weight' => 'Weight_in_lbs',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
def normalize_csv_file(filename)
|
|
14
|
+
new_header_names = replace_header_with_alias(filename)
|
|
15
|
+
normalize_csv_body(filename, new_header_names)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def normalize_csv_body(old_csv_file, header_row)
|
|
19
|
+
new_headers = replace_header_with_alias(old_csv_file)
|
|
20
|
+
#CSV.open(NORMALIZED_CSV_FILENAME, 'w') do |csv|
|
|
21
|
+
new_csv_file = CSV.generate do |csv|
|
|
22
|
+
csv << header_row
|
|
23
|
+
CSV.read(old_csv_file, headers: true).each do |row|
|
|
24
|
+
row['Carnivore'] = 'Carnivore' if row['Carnivore'] == 'Yes'
|
|
25
|
+
row['Carnivore'] = 'No' if row['Carnivore'] == 'No'
|
|
26
|
+
csv.puts row
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
new_csv_file
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def replace_header_with_alias(csv_file)
|
|
33
|
+
header_row = CSV.read(csv_file, headers: true).headers
|
|
34
|
+
build_table_body(header_row)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def build_table_body(header)
|
|
38
|
+
header.inject([]) do |new_header, column_name|
|
|
39
|
+
if ALIAS_TABLE[column_name]
|
|
40
|
+
new_header << ALIAS_TABLE[column_name]
|
|
41
|
+
else
|
|
42
|
+
new_header << column_name
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module DinosaurCatalog
|
|
2
|
+
class Dinosaur
|
|
3
|
+
BIG_DINOSAUR_LBS = 2
|
|
4
|
+
POUNDS_PER_TON = 2000.0
|
|
5
|
+
|
|
6
|
+
attr_reader :name, :period, :continent, :diet, :weight_in_lbs, :walking, :description
|
|
7
|
+
|
|
8
|
+
def initialize(name, options = {})
|
|
9
|
+
@name = name
|
|
10
|
+
@period = options[:period]
|
|
11
|
+
@continent = options[:continent]
|
|
12
|
+
@diet = options[:diet]
|
|
13
|
+
@weight_in_lbs = options[:weight_in_lbs]
|
|
14
|
+
@walking = options[:walking]
|
|
15
|
+
@description = options[:description]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def big?
|
|
19
|
+
weight_in_tons > BIG_DINOSAUR_LBS
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def small?
|
|
23
|
+
weight_in_tons > 0 && weight_in_tons <= BIG_DINOSAUR_LBS
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def weight_in_tons
|
|
27
|
+
@weight_in_lbs.to_i / POUNDS_PER_TON
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_hash
|
|
31
|
+
hash = {}
|
|
32
|
+
instance_variables.each {|var| hash[var.to_s.delete("@")] = instance_variable_get(var) }
|
|
33
|
+
hash
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module DinosaurCatalog
|
|
2
|
+
module Display
|
|
3
|
+
PADDING = 20
|
|
4
|
+
|
|
5
|
+
HEADER_NAMES = ["Name", "Period", "Continent", "Diet", "Weight (lbs)", "Walking", "Description"]
|
|
6
|
+
|
|
7
|
+
def print_dinosaur_set(set)
|
|
8
|
+
print_summary_header
|
|
9
|
+
set.each do |entry|
|
|
10
|
+
print_attribute(entry.name, PADDING)
|
|
11
|
+
print_attribute(entry.period, PADDING)
|
|
12
|
+
print_attribute(entry.continent, PADDING)
|
|
13
|
+
print_attribute(entry.diet, PADDING)
|
|
14
|
+
print_attribute(entry.weight_in_lbs, PADDING)
|
|
15
|
+
print_attribute(entry.walking, PADDING)
|
|
16
|
+
print_attribute(entry.description, PADDING)
|
|
17
|
+
puts
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def print_dinosaur_instance(set, name)
|
|
22
|
+
entry = set.detect { |dinosaur| dinosaur.name.downcase =~ /#{name}/ }
|
|
23
|
+
if entry
|
|
24
|
+
puts "\nBelow is information on the dinosaur you entered:\n\n"
|
|
25
|
+
print "Name".center(PADDING) if entry.name
|
|
26
|
+
print "Period".center(PADDING) if entry.period
|
|
27
|
+
print "Continent".center(PADDING) if entry.continent
|
|
28
|
+
print "Diet".center(PADDING) if entry.diet
|
|
29
|
+
print "Weight (lbs)".center(PADDING) if entry.weight_in_lbs
|
|
30
|
+
print "Walking".center(PADDING) if entry.walking
|
|
31
|
+
print "Description".center(PADDING) if entry.description
|
|
32
|
+
puts ''
|
|
33
|
+
print_attribute(entry.name, PADDING) if entry.name
|
|
34
|
+
print_attribute(entry.period, PADDING) if entry.period
|
|
35
|
+
print_attribute(entry.continent, PADDING) if entry.continent
|
|
36
|
+
print_attribute(entry.diet, PADDING) if entry.diet
|
|
37
|
+
print_attribute(entry.weight_in_lbs, PADDING) if entry.weight_in_lbs
|
|
38
|
+
print_attribute(entry.walking, PADDING) if entry.walking
|
|
39
|
+
print_attribute(entry.description, PADDING) if entry.description
|
|
40
|
+
puts
|
|
41
|
+
else
|
|
42
|
+
puts "\nSorry, but I did not recognize that dinosaur name.\n"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def print_attribute(attribute, padding)
|
|
47
|
+
if attribute
|
|
48
|
+
print attribute.center(padding)
|
|
49
|
+
else
|
|
50
|
+
print "---".center(padding)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def print_summary_header
|
|
55
|
+
puts "\n\n"
|
|
56
|
+
HEADER_NAMES.each { |header| print header.center(PADDING) }
|
|
57
|
+
puts ''
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module DinosaurCatalog
|
|
2
|
+
module Filters
|
|
3
|
+
def filter_bipeds(biped_terms)
|
|
4
|
+
dinosaurs.select { |dinosaur| biped_terms.include?(dinosaur.walking.downcase) }
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def filter_carnivores(carnivore_terms)
|
|
8
|
+
dinosaurs.select { |dinosaur| carnivore_terms.include?(dinosaur.diet.downcase) }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def filter_periods(period_terms)
|
|
12
|
+
periods_in_regex_array = Regexp.union(period_terms)
|
|
13
|
+
dinosaurs.select { |dinosaur| dinosaur.period.downcase.match(periods_in_regex_array) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def filter_sizes(size_terms)
|
|
17
|
+
case
|
|
18
|
+
when size_terms.include?('big') then dinosaurs.select(&:big?)
|
|
19
|
+
when size_terms.include?('small') then dinosaurs.select(&:small?)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module DinosaurCatalog
|
|
2
|
+
module JsonExport
|
|
3
|
+
def convert_to_json(ruby_object)
|
|
4
|
+
array_of_objects = convert_object_to_array(ruby_object)
|
|
5
|
+
File.open("json_export.json", "w") { |f| f.puts JSON.generate(array_of_objects) }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def convert_object_to_array(object)
|
|
9
|
+
object.inject([]) { |array, attribute| array << attribute.to_hash }
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module DinosaurCatalog
|
|
2
|
+
module UserProcessing
|
|
3
|
+
SEARCH_REGEX = {
|
|
4
|
+
bipeds: /biped/,
|
|
5
|
+
carnivores: /carnivore|insectivore|piscivore/,
|
|
6
|
+
periods: /cretaceous|permian|jurassic|oxfordian|albian|triassic/,
|
|
7
|
+
sizes: /big|small/,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
EXIT_TERMS = ['quit', 'exit']
|
|
11
|
+
|
|
12
|
+
def obtain_user_filters
|
|
13
|
+
print UserPrompts::USER_SEARCH_PROMPT
|
|
14
|
+
print '> '
|
|
15
|
+
user_input = gets.chomp.downcase
|
|
16
|
+
puts
|
|
17
|
+
perform_search(user_input)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def get_user_search_terms(phrase)
|
|
21
|
+
search_terms = {}
|
|
22
|
+
SEARCH_REGEX.each do |term, regex|
|
|
23
|
+
search_terms[term] = phrase.scan(regex) unless phrase.scan(regex).empty? # use inject?
|
|
24
|
+
end
|
|
25
|
+
search_terms
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def user_processing
|
|
29
|
+
print UserPrompts::USER_PROCESSING_PROMPT
|
|
30
|
+
print '> '
|
|
31
|
+
user_input = gets.chomp.downcase
|
|
32
|
+
user_actions(user_input)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def user_actions(user_input)
|
|
36
|
+
exit! if EXIT_TERMS.include? user_input
|
|
37
|
+
return print_results if user_input == 'print'
|
|
38
|
+
return new_search if user_input == 'search'
|
|
39
|
+
return json if user_input == 'json'
|
|
40
|
+
return search_dinosaur(user_input)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def print_results
|
|
44
|
+
print_dinosaur_set(@filtered_dinosaurs)
|
|
45
|
+
user_processing
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def new_search
|
|
49
|
+
launch_app!(@csv_filename)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def json
|
|
53
|
+
convert_to_json(@filtered_dinosaurs)
|
|
54
|
+
puts "\nYour JSON file has been saved as json_export.json in the main directory."
|
|
55
|
+
user_processing
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def search_dinosaur(input)
|
|
59
|
+
print_dinosaur_instance(@filtered_dinosaurs, input)
|
|
60
|
+
user_processing
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module DinosaurCatalog
|
|
2
|
+
module UserPrompts
|
|
3
|
+
USER_SEARCH_PROMPT = <<-HEREDOC.strip_heredoc
|
|
4
|
+
|
|
5
|
+
What would you like to do?\n
|
|
6
|
+
You can enter a phrase that includes the keywords you want to filter the dinosaur catalog by.\n
|
|
7
|
+
For example:\n
|
|
8
|
+
Carnivores Big Triassic Bipeds\n
|
|
9
|
+
Which will return all dinosaurs that meet the four criteria.\n
|
|
10
|
+
Otherwise, to exit this program, enter 'quit'.\n
|
|
11
|
+
HEREDOC
|
|
12
|
+
|
|
13
|
+
USER_PROCESSING_PROMPT = <<-HEREDOC.strip_heredoc
|
|
14
|
+
|
|
15
|
+
You may perform the following action on the search results\n
|
|
16
|
+
Enter 'Print' to list the dinosaurs that met your search criteria.\n
|
|
17
|
+
Enter the dinosaur's name to list information on an individual dinosaur.\n
|
|
18
|
+
Enter 'json' to export the search results as a JSON file.\n
|
|
19
|
+
Enter 'Search' to perform another search.\n
|
|
20
|
+
Otherwise, to exit this program, enter 'quit'.\n
|
|
21
|
+
HEREDOC
|
|
22
|
+
end
|
|
23
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dinosaur_catalog
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: '2.0'
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Paul Haddad
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-11-07 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: |
|
|
14
|
+
## Dinosaur Catalog
|
|
15
|
+
|
|
16
|
+
It may not be immediately evident, but I am a huge fan of dinosaurs. They're huge and dangerous and have cool names like Giganotosaurus (not to be confused with Gigantosaurus).
|
|
17
|
+
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
Anyway. I need to catalog some dinosaurs for my newest project, DinoDex. I've got a CSV file for the dinosaur facts, and I need the code to read all the dinosaur facts and do some basic manipulations with the data.
|
|
21
|
+
|
|
22
|
+
### Requirements
|
|
23
|
+
|
|
24
|
+
Go check out the CSVs and come back. Done? Cool, I've just got a few features I need:
|
|
25
|
+
|
|
26
|
+
1. I loaded my favorite dinosaurs into a CSV file you'll need to parse. I don't know a lot about African Dinosaurs though, so I downloaded one from The Pirate Bay. It isn't formatted as well as mine, but please try to parse it anyway.
|
|
27
|
+
2. I have friends who ask me a lot of questions about dinosaurs (I'm kind of a big deal). Please make sure the dinodex is able to answer these things for me:
|
|
28
|
+
* Grab all the dinosaurs that were bipeds.
|
|
29
|
+
* Grab all the dinosaurs that were carnivores (fish and insects count).
|
|
30
|
+
* Grab dinosaurs for specific periods (no need to differentiate between Early and Late Cretaceous, btw).
|
|
31
|
+
* Grab only big (> 2 tons) or small dinosaurs.
|
|
32
|
+
* Just to be sure, I'd love to be able to combine criteria at will, even better if I can chain filter calls together.
|
|
33
|
+
3. For a given dino, I'd like to be able to print all the known facts about that dinosaur. If there are facts missing, please don't print empty values, just skip that heading. Make sure to print Early / Late etc for the periods.
|
|
34
|
+
4. Also, I'll probably want to print all the dinosaurs in a given collection (after filtering, etc).
|
|
35
|
+
|
|
36
|
+
#### Extra Credit
|
|
37
|
+
|
|
38
|
+
1. I would love to have a way to do (and chain) generic search by parameters. I can pass in a hash, and I'd like to get the proper list of dinos back out.
|
|
39
|
+
2. CSV isn't may favorite format in the world. Can you implement a JSON export feature?
|
|
40
|
+
|
|
41
|
+
Happy Hunting. (Giganotosaurus was the largest hunting dinosaur, at 46 feet long and up to 8 tons! Suh-weet.)
|
|
42
|
+
email: paul.g.haddad@gmail.com
|
|
43
|
+
executables:
|
|
44
|
+
- dinosaur_catalog
|
|
45
|
+
extensions: []
|
|
46
|
+
extra_rdoc_files: []
|
|
47
|
+
files:
|
|
48
|
+
- LICENSE
|
|
49
|
+
- README
|
|
50
|
+
- bin/african_dinosaur_export.csv
|
|
51
|
+
- bin/dinodex.csv
|
|
52
|
+
- bin/dinosaur_catalog
|
|
53
|
+
- lib/dinosaur_catalog/app.rb
|
|
54
|
+
- lib/dinosaur_catalog/catalog.rb
|
|
55
|
+
- lib/dinosaur_catalog/csv_modifier.rb
|
|
56
|
+
- lib/dinosaur_catalog/dinosaur.rb
|
|
57
|
+
- lib/dinosaur_catalog/display.rb
|
|
58
|
+
- lib/dinosaur_catalog/filters.rb
|
|
59
|
+
- lib/dinosaur_catalog/json_export.rb
|
|
60
|
+
- lib/dinosaur_catalog/user_processing.rb
|
|
61
|
+
- lib/dinosaur_catalog/user_prompts.rb
|
|
62
|
+
homepage:
|
|
63
|
+
licenses:
|
|
64
|
+
- MIT
|
|
65
|
+
metadata: {}
|
|
66
|
+
post_install_message:
|
|
67
|
+
rdoc_options: []
|
|
68
|
+
require_paths:
|
|
69
|
+
- lib
|
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '2.0'
|
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '0'
|
|
80
|
+
requirements: []
|
|
81
|
+
rubyforge_project:
|
|
82
|
+
rubygems_version: 2.2.2
|
|
83
|
+
signing_key:
|
|
84
|
+
specification_version: 4
|
|
85
|
+
summary: Ruby program for the Dino Catalog Exercise as part of the Level Up Program.
|
|
86
|
+
test_files: []
|
|
87
|
+
has_rdoc:
|