find_deals 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +13 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +117 -0
- data/LICENSE.txt +21 -0
- data/NOTES.MD +56 -0
- data/README.md +43 -0
- data/Rakefile +15 -0
- data/bin/console +18 -0
- data/bin/find_deals +6 -0
- data/bin/setup +9 -0
- data/config/database.yml +5 -0
- data/config/environment.rb +25 -0
- data/db/migrate/01_save_deals.rb +17 -0
- data/db/migrate/02_categories.rb +16 -0
- data/db/migrate/03_cities.rb +8 -0
- data/db/migrate/04_users.rb +11 -0
- data/db/migrate/05_add_user_to_deals.rb +8 -0
- data/db/migrate/06_add_city_to_deals.rb +6 -0
- data/db/migrate/07_add_category_to_deals.rb +6 -0
- data/db/saved_deals.sqlite3 +0 -0
- data/db/schema.rb +39 -0
- data/db/seeds.rb +15 -0
- data/find_deals.gemspec +42 -0
- data/lib/find_deals.rb +13 -0
- data/lib/find_deals/categories.rb +3 -0
- data/lib/find_deals/cities.rb +3 -0
- data/lib/find_deals/cli.rb +353 -0
- data/lib/find_deals/deals.rb +59 -0
- data/lib/find_deals/saved_deals.rb +22 -0
- data/lib/find_deals/scraper.rb +59 -0
- data/lib/find_deals/users.rb +4 -0
- data/lib/find_deals/version.rb +5 -0
- metadata +196 -0
data/config/database.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "require_all"
|
3
|
+
|
4
|
+
require "nokogiri"
|
5
|
+
require "open-uri"
|
6
|
+
require "rake"
|
7
|
+
require "pry"
|
8
|
+
require 'active_record'
|
9
|
+
require 'sinatra/activerecord'
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
require_all "lib" #load up all files in the lib directory and its subdirectories
|
14
|
+
|
15
|
+
# connection to sqlite database here. creates the deals.sqlite database when running migrate
|
16
|
+
# We havew active record installed
|
17
|
+
connection_details = YAML::load(File.open('config/database.yml'))
|
18
|
+
ActiveRecord::Base.establish_connection(:development)
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class SaveDeals < ActiveRecord::Migration[5.2]
|
2
|
+
|
3
|
+
def change
|
4
|
+
create_table :saved_deals do |d|
|
5
|
+
d.string :title
|
6
|
+
d.string :url
|
7
|
+
d.string :location
|
8
|
+
d.integer :price
|
9
|
+
d.integer :promotion
|
10
|
+
d.string :about
|
11
|
+
end
|
12
|
+
add_foreign_key :saved_deals, :users
|
13
|
+
add_foreign_key :saved_deals, :categories
|
14
|
+
add_foreign_key :saved_deals, :cities
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Categories < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
create_table :categories do |c|
|
4
|
+
c.string :name
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
# FindDeals::Cities.create(name: nil)
|
9
|
+
# FindDeals::Cities.create(name: "dining")
|
10
|
+
# FindDeals::Cities.create(name: "wellness-beauty")
|
11
|
+
# FindDeals::Cities.create(name: "activities")
|
12
|
+
# FindDeals::Cities.create(name: "shopping")
|
13
|
+
# FindDeals::Cities.create(name: "services")
|
14
|
+
# FindDeals::Cities.create(name: "wine")
|
15
|
+
# FindDeals::Cities.create(name: "personalised-gifts")
|
16
|
+
end
|
Binary file
|
data/db/schema.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
4
|
+
#
|
5
|
+
# Note that this schema.rb definition is the authoritative source for your
|
6
|
+
# database schema. If you need to create the application database on another
|
7
|
+
# system, you should be using db:schema:load, not running all the migrations
|
8
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
9
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
10
|
+
#
|
11
|
+
# It's strongly recommended that you check this file into your version control system.
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define(version: 7) do
|
14
|
+
|
15
|
+
create_table "categories", force: :cascade do |t|
|
16
|
+
t.string "name"
|
17
|
+
end
|
18
|
+
|
19
|
+
create_table "cities", force: :cascade do |t|
|
20
|
+
t.string "name"
|
21
|
+
end
|
22
|
+
|
23
|
+
create_table "saved_deals", force: :cascade do |t|
|
24
|
+
t.string "title"
|
25
|
+
t.string "url"
|
26
|
+
t.string "location"
|
27
|
+
t.integer "price"
|
28
|
+
t.integer "promotion"
|
29
|
+
t.string "about"
|
30
|
+
t.integer "user_id"
|
31
|
+
t.integer "city_id"
|
32
|
+
t.integer "category_id"
|
33
|
+
end
|
34
|
+
|
35
|
+
create_table "users", force: :cascade do |t|
|
36
|
+
t.string "name"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/db/seeds.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Cities.find_or_create_by(name: "sydney")
|
2
|
+
Cities.find_or_create_by(name: "melbourne")
|
3
|
+
Cities.find_or_create_by(name: "perth")
|
4
|
+
Cities.find_or_create_by(name: "brisbane")
|
5
|
+
Cities.find_or_create_by(name: "adelaide")
|
6
|
+
Cities.find_or_create_by(name: "gold-coast")
|
7
|
+
|
8
|
+
Categories.find_or_create_by(name: nil)
|
9
|
+
Categories.find_or_create_by(name: "dining")
|
10
|
+
Categories.find_or_create_by(name: "wellness-beauty")
|
11
|
+
Categories.find_or_create_by(name: "activities")
|
12
|
+
Categories.find_or_create_by(name: "shopping")
|
13
|
+
Categories.find_or_create_by(name: "services")
|
14
|
+
Categories.find_or_create_by(name: "wine")
|
15
|
+
Categories.find_or_create_by(name: "personalised-gifts")
|
data/find_deals.gemspec
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/find_deals/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "find_deals"
|
7
|
+
spec.version = FindDeals::VERSION
|
8
|
+
spec.authors = ["nils-vanderwerf"]
|
9
|
+
spec.email = ["n.vanderw.92@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "A Web scraper for Scoopon to find deals and promotions"
|
12
|
+
spec.description = "Based on the users city and category input, they scrape a list of deals from Scoopon.com. They have they chhoice to save to the database and view their saved deals."
|
13
|
+
spec.homepage = "https://github.com/nils-vanderwerf/find_deals/"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/nils-vanderwerf/find_deals"
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/nils-vanderwerf/find_deals/blob/master/CHANGELOG.md"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_dependency "nokogiri"
|
31
|
+
spec.add_dependency "require_all"
|
32
|
+
spec.add_dependency "activerecord"
|
33
|
+
spec.add_dependency "sinatra-activerecord"
|
34
|
+
spec.add_dependency "sqlite3"
|
35
|
+
|
36
|
+
|
37
|
+
spec.add_development_dependency "bundler", "~> 2.2.11"
|
38
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
39
|
+
|
40
|
+
spec.add_development_dependency "pry"
|
41
|
+
|
42
|
+
end
|
data/lib/find_deals.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative "./find_deals/version"
|
2
|
+
|
3
|
+
module FindDeals
|
4
|
+
class Error < StandardError; end
|
5
|
+
|
6
|
+
# def print
|
7
|
+
# puts "===================================================================="
|
8
|
+
# puts "#{self.title.upcase}"
|
9
|
+
# puts "#{self.location}"
|
10
|
+
# puts "#{self.price} - #{self.promotion.upcase}"
|
11
|
+
# puts "===================================================================="
|
12
|
+
# end
|
13
|
+
end
|
@@ -0,0 +1,353 @@
|
|
1
|
+
|
2
|
+
class FindDeals::CLI
|
3
|
+
attr_accessor :city_input, :category_input, :input, :user_name, :selected_deal
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
# @deals = FindDeals::SavedDeals.all
|
7
|
+
@user_name = ""
|
8
|
+
@input = ""
|
9
|
+
@city_input = ""
|
10
|
+
@category_input = ""
|
11
|
+
@selected_deal
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
puts "--------------------------------------------------------------------"
|
16
|
+
puts ""
|
17
|
+
puts "Welcome to this amazing promo finder!"
|
18
|
+
puts ""
|
19
|
+
start
|
20
|
+
end
|
21
|
+
|
22
|
+
def start
|
23
|
+
#-----LIST OF METHODS---#
|
24
|
+
prompt_user_city
|
25
|
+
prompt_user_category
|
26
|
+
if FindDeals::Deal.all.length != 0
|
27
|
+
print_deals
|
28
|
+
print_more_info
|
29
|
+
prompt_to_save_deal
|
30
|
+
prompt_to_show_saved_deals
|
31
|
+
next_steps
|
32
|
+
else
|
33
|
+
start
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def prompt_user_city
|
38
|
+
puts "--------------------------------------------------------------------"
|
39
|
+
puts ""
|
40
|
+
puts "Select a city (type in corresponding number)"
|
41
|
+
puts ""
|
42
|
+
puts <<-DOC
|
43
|
+
1. Sydney
|
44
|
+
2. Melbourne
|
45
|
+
3. Perth
|
46
|
+
4. Brisbane
|
47
|
+
5. Adelaide
|
48
|
+
6. Gold Coast
|
49
|
+
DOC
|
50
|
+
|
51
|
+
puts ""
|
52
|
+
get_city_input
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_city_input
|
56
|
+
@input = gets.strip
|
57
|
+
@input != 'quit' ? @city_input = select_city_from_input : goodbye
|
58
|
+
end
|
59
|
+
|
60
|
+
def select_city_from_input
|
61
|
+
while @input.to_i == 0 || @input.to_i > Cities.all.size
|
62
|
+
invalid_input
|
63
|
+
prompt_user_city
|
64
|
+
end
|
65
|
+
Cities.find(@input).name # Collects it from the database
|
66
|
+
end
|
67
|
+
|
68
|
+
def select_category_from_input
|
69
|
+
while @input.to_i == 0 || @input.to_i > Categories.all.size
|
70
|
+
invalid_input
|
71
|
+
prompt_user_category
|
72
|
+
end
|
73
|
+
Categories.find(@input).name ## Collects it from the database
|
74
|
+
end
|
75
|
+
|
76
|
+
def prompt_user_category
|
77
|
+
puts "----------------------------------------------------------------"
|
78
|
+
puts ""
|
79
|
+
puts "Select a category (type in corresponding number)"
|
80
|
+
puts "Type quit to exit the program"
|
81
|
+
puts <<-DOC
|
82
|
+
1. Anything
|
83
|
+
2. Dining
|
84
|
+
3. Wellness & Beauty
|
85
|
+
4. Activities
|
86
|
+
5. Shopping
|
87
|
+
6. Services
|
88
|
+
7. Wine
|
89
|
+
8. Personalised Gifts
|
90
|
+
DOC
|
91
|
+
puts ""
|
92
|
+
get_category_input
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_category_input
|
96
|
+
@input = gets.strip
|
97
|
+
@category_input = select_category_from_input
|
98
|
+
if @input == 'quit'
|
99
|
+
goodbye
|
100
|
+
end
|
101
|
+
|
102
|
+
if @input.to_i == 0 || @input.to_i > Categories.all.length
|
103
|
+
invalid_input
|
104
|
+
get_category_input
|
105
|
+
end
|
106
|
+
@category_input = Categories.find(input).name
|
107
|
+
site_scraper = FindDeals::Scraper.new(@city_input, @category_input)
|
108
|
+
if FindDeals::Deal.all.length == 0
|
109
|
+
puts "--------------------------------------------------------------------"
|
110
|
+
puts ""
|
111
|
+
puts "Sorry! No deals for this selection today. Please try another selection."
|
112
|
+
puts ""
|
113
|
+
puts "--------------------------------------------------------------------"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def print_deals
|
118
|
+
puts "--------------------------------------------------------------------"
|
119
|
+
puts ""
|
120
|
+
puts "DEALS FOR THIS INPUT"
|
121
|
+
puts ""
|
122
|
+
FindDeals::Deal.all.each.with_index(1) do |deal, index|
|
123
|
+
puts "#{index}."
|
124
|
+
puts deal.print
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def print_more_info
|
129
|
+
if FindDeals::Deal.all.length != 0
|
130
|
+
puts "--------------------------------------------------------------------"
|
131
|
+
puts ""
|
132
|
+
puts "Please enter the number of the deal you'd like to see more about. Type in quit to exit"
|
133
|
+
puts ""
|
134
|
+
@input = gets.strip.to_i
|
135
|
+
while @input == 0 || @input > FindDeals::Deal.all.size
|
136
|
+
invalid_input
|
137
|
+
@input = gets.strip.to_i
|
138
|
+
end
|
139
|
+
FindDeals::Deal.all[@input - 1].print_about_details
|
140
|
+
@selected_deal = FindDeals::Deal.all[@input - 1]
|
141
|
+
else
|
142
|
+
puts "--------------------------------------------------------------------"
|
143
|
+
puts ""
|
144
|
+
puts "Sorry! No deals for this selection today. Please try another selection."
|
145
|
+
puts ""
|
146
|
+
puts "--------------------------------------------------------------------"
|
147
|
+
end
|
148
|
+
|
149
|
+
if @input == 'quit'
|
150
|
+
goodbye
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def prompt_to_save_deal
|
155
|
+
puts ""
|
156
|
+
puts "Would you like to save this deal? Y or N"
|
157
|
+
@input = gets.strip.downcase
|
158
|
+
puts ""
|
159
|
+
puts "--------------------------------------------------------------------"
|
160
|
+
if @input == "y"
|
161
|
+
user = get_user
|
162
|
+
puts "Saving deal..."
|
163
|
+
puts ""
|
164
|
+
puts "--------------------------------------------------------------------"
|
165
|
+
|
166
|
+
@selected_deal.save(user.id) ##save to Saved Deals, with the user id as the User_id
|
167
|
+
elsif @input == "n"
|
168
|
+
next_steps
|
169
|
+
elsif @input == 'quit'
|
170
|
+
goodbye
|
171
|
+
else
|
172
|
+
invalid_input
|
173
|
+
prompt_to_save_deal
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def get_user
|
178
|
+
puts "--------------------------------------------------------------------"
|
179
|
+
puts ""
|
180
|
+
puts "We need to be able to associate this deal with you."
|
181
|
+
puts "Please enter a username"
|
182
|
+
@input = gets.strip
|
183
|
+
if @input == 'quit'
|
184
|
+
goodbye
|
185
|
+
else
|
186
|
+
puts "--------------------------------------------------------------------"
|
187
|
+
@user_name = input
|
188
|
+
Users.find_or_create_by(name: @user_name)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def prompt_to_show_saved_deals
|
193
|
+
puts ""
|
194
|
+
puts "Would you like to see your saved deals? Y or N"
|
195
|
+
|
196
|
+
@input = gets.strip.downcase
|
197
|
+
puts ""
|
198
|
+
puts "--------------------------------------------------------------------"
|
199
|
+
|
200
|
+
if @input == "y"
|
201
|
+
show_saved_deals
|
202
|
+
elsif @input == "n"
|
203
|
+
next_steps
|
204
|
+
elsif @input == 'quit'
|
205
|
+
goodbye
|
206
|
+
else
|
207
|
+
invalid_input
|
208
|
+
prompt_to_show_saved_deals
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
def show_saved_deals
|
214
|
+
puts ""
|
215
|
+
puts "--------------------------------------------------------------------"
|
216
|
+
puts ""
|
217
|
+
puts "YOUR SAVED DEALS"
|
218
|
+
puts ""
|
219
|
+
puts "--------------------------------------------------------------------"
|
220
|
+
#get id of selected_user
|
221
|
+
user = Users.find_by(name: @user_name)
|
222
|
+
deals_from_user = SavedDeals.select {|deal| deal.user_id == user.id}
|
223
|
+
deals_from_user.each.with_index(1) do |deal, index|
|
224
|
+
puts "#{index}."
|
225
|
+
puts deal.print
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def filter_by_city
|
230
|
+
puts ""
|
231
|
+
puts "--------------------------------------------------------------------"
|
232
|
+
puts ""
|
233
|
+
puts "YOUR SAVED DEALS IN #{city_input.upcase.split('-').join(' ')}"
|
234
|
+
puts ""
|
235
|
+
puts "--------------------------------------------------------------------"
|
236
|
+
#get id of selected_user
|
237
|
+
user = Users.find_by(name: @user_name)
|
238
|
+
deals_from_city = SavedDeals.select {|deal| deal.user_id == user.id && deal.city_id == @input.to_i}
|
239
|
+
if deals_from_city.length == 0
|
240
|
+
puts "Sorry! No saved deals for this section. Please try another selection."
|
241
|
+
next_steps
|
242
|
+
end
|
243
|
+
deals_from_city.each.with_index(1) do |deal, index|
|
244
|
+
puts "#{index}."
|
245
|
+
puts deal.print
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def filter_by_category
|
250
|
+
puts ""
|
251
|
+
puts "--------------------------------------------------------------------"
|
252
|
+
puts ""
|
253
|
+
puts "YOUR SAVED DEALS IN THE #{@category_input == nil ? 'ALL DEALS' : @category_input.upcase.split('-').join(' ')} CATEGORY"
|
254
|
+
puts ""
|
255
|
+
puts "--------------------------------------------------------------------"
|
256
|
+
#get id of selected_user
|
257
|
+
user = Users.find_by(name: @user_name)
|
258
|
+
deals_from_category = SavedDeals.select {|deal| deal.user_id == user.id && deal.category_id == @input.to_i}
|
259
|
+
if deals_from_category.length == 0
|
260
|
+
puts "Sorry! No saved deals for this section. Please try another selection."
|
261
|
+
next_steps
|
262
|
+
end
|
263
|
+
deals_from_category.each.with_index(1) do |deal, index|
|
264
|
+
puts "#{index}."
|
265
|
+
puts deal.print
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
|
270
|
+
def next_steps
|
271
|
+
puts "--------------------------------------------------------------------"
|
272
|
+
puts ""
|
273
|
+
puts "What would you like to do now"
|
274
|
+
puts "- To view more deals, type 'MORE'"
|
275
|
+
puts "- To filter your saved deals by city, type in 'CITY'"
|
276
|
+
puts "- To filter your saved deals by category, type in 'CATEGORY'"
|
277
|
+
puts "- To delete a saved deal type 'DELETE'"
|
278
|
+
puts "- To quit, type in quit"
|
279
|
+
@input = gets.strip.downcase
|
280
|
+
|
281
|
+
if @input == "more"
|
282
|
+
puts ""
|
283
|
+
puts "--------------------------------------------------------------------"
|
284
|
+
# start program again
|
285
|
+
start #
|
286
|
+
elsif @input == 'city'
|
287
|
+
puts ""
|
288
|
+
puts "--------------------------------------------------------------------"
|
289
|
+
prompt_user_city
|
290
|
+
filter_by_city
|
291
|
+
next_steps
|
292
|
+
elsif @input == 'category'
|
293
|
+
prompt_user_category
|
294
|
+
filter_by_category
|
295
|
+
next_steps
|
296
|
+
elsif @input == "delete"
|
297
|
+
delete_record
|
298
|
+
next_steps
|
299
|
+
elsif @input == "quit"
|
300
|
+
goodbye
|
301
|
+
else
|
302
|
+
invalid_input
|
303
|
+
next_steps
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def delete_record
|
308
|
+
user = get_user
|
309
|
+
show_saved_deals
|
310
|
+
puts "--------------------------------------------------------------------"
|
311
|
+
puts ""
|
312
|
+
puts "Type in the number of the deal you would like to delete"
|
313
|
+
puts ""
|
314
|
+
puts "--------------------------------------------------------------------"
|
315
|
+
@input = gets.strip.downcase
|
316
|
+
|
317
|
+
while @input.to_i == 0 || @input.to_i >= SavedDeals.select {|deal| deal.user_id == user.id}.length
|
318
|
+
invalid_input
|
319
|
+
puts "--------------------------------------------------------------------"
|
320
|
+
puts ""
|
321
|
+
puts "Type in the number of the deal you would like to delete"
|
322
|
+
puts ""
|
323
|
+
puts "--------------------------------------------------------------------"
|
324
|
+
@input = gets.strip.downcase
|
325
|
+
|
326
|
+
if @input == 'quit'
|
327
|
+
goodbye
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
SavedDeals.all.delete_from_db(@input.to_i)
|
332
|
+
prompt_to_show_saved_deals
|
333
|
+
next_steps
|
334
|
+
|
335
|
+
end
|
336
|
+
|
337
|
+
def invalid_input
|
338
|
+
puts "--------------------------------------------------------------------"
|
339
|
+
puts ""
|
340
|
+
puts "Invalid input. Please try again"
|
341
|
+
puts ""
|
342
|
+
puts "--------------------------------------------------------------------"
|
343
|
+
end
|
344
|
+
|
345
|
+
def goodbye
|
346
|
+
puts "--------------------------------------------------------------------"
|
347
|
+
puts ""
|
348
|
+
puts "Hope to see you again soon for more deals!"
|
349
|
+
puts ""
|
350
|
+
puts "--------------------------------------------------------------------"
|
351
|
+
exit
|
352
|
+
end
|
353
|
+
end
|