liquery 0.1.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.
@@ -0,0 +1,414 @@
1
+ class LiquerY::CLI
2
+
3
+ def call
4
+ welcome
5
+ compile
6
+ main_menu
7
+ end
8
+
9
+ def welcome
10
+ puts <<~EOC.cyan
11
+
12
+ -- Welcome to LiquerY --
13
+
14
+ Liquery is a games-style CLI app
15
+ built to help its users better understand
16
+ their palates for cocktails & drinks.
17
+
18
+ We hope you have fun playing around with our app,
19
+ and we hope that, in the process, we can help you learn
20
+ about new & exciting beverages to enjoy,
21
+ whether you're out on the town or entertaining at home!
22
+
23
+ Please wait just a moment
24
+ as we compile our database of cocktails
25
+ and user preferences!
26
+
27
+ ----------------------------
28
+
29
+ EOC
30
+ end
31
+
32
+ def compile
33
+ spinner = ::TTY::Spinner.new(" [:spinner]".light_blue, format: :bouncing)
34
+ spinner.auto_spin
35
+ Drink.all
36
+ spinner.stop('Done!'.cyan)
37
+ end
38
+
39
+ def main_menu
40
+ if !(User.current_user)
41
+ puts "\nIt seems that you're here for the first time!".light_blue
42
+ puts "To start, we'll have you begin by taking our quiz,".light_blue
43
+ puts "so that we can get a sense for your likes & dislikes!".light_blue
44
+ self.drink_quiz
45
+ else
46
+ system "clear"
47
+ puts "Main Menu:".light_blue
48
+ puts "Now that you've completed our quiz, we have a few".cyan
49
+ puts "other services that may be helpful to you!".cyan
50
+ self.list_menu_options
51
+ end
52
+ end
53
+
54
+
55
+
56
+ ## ------------ ##
57
+ ## MENU METHODS ##
58
+ ## ------------ ##
59
+
60
+ def list_menu_options
61
+ puts "\n\t[1.] ".cyan + "See a list of your liked & recommended drinks".light_blue
62
+ puts "\t[2.] ".cyan + "Search our entire repertoire of cocktails".light_blue
63
+ puts "\t[3.] ".cyan + "Take our quiz again to update your preferences".light_blue
64
+ puts "\t...or type ".light_blue + "\'exit\'".cyan + " to leave the app.".light_blue
65
+ begin
66
+ print "\nYour selection: ".cyan
67
+ input = gets.chomp
68
+ case input
69
+ when "1"
70
+ system "clear"
71
+ self.list_liked_and_recommended
72
+ when "2"
73
+ self.list_search_options
74
+ when "3"
75
+ self.drink_quiz
76
+ when "exit"
77
+ self.exit
78
+ else
79
+ puts "Whoops, \'#{input}\' isn't an option!".light_blue
80
+ end
81
+ end until ["1", "2", "3", "exit"].include?(input)
82
+ end
83
+
84
+ def list_liked_and_recommended
85
+ puts "Liked & Recommended Drinks:".light_blue
86
+ User.current_user.list_liked_drinks
87
+ puts "\nWould you like to see...".cyan + "\n[1.]".light_blue + " the ingredients for one of these drinks or ".cyan + "\n[2.]".light_blue + " learn how to mix one of them?".cyan
88
+ begin
89
+ print "Enter ".cyan + "\"1\"".light_blue + ", ".cyan + "\"2\"".light_blue + ", or ".cyan + "\"menu\"".light_blue + " to return to menu... ".cyan
90
+ input = gets.chomp
91
+ case input
92
+ when "1"
93
+ self.user_local_ingredient_search
94
+ self.main_menu
95
+ when "2"
96
+ self.user_local_recipe_search
97
+ self.main_menu
98
+ when "menu"
99
+ self.main_menu
100
+ else
101
+ puts "Whoops, \'#{input}\' isn't an option!".light_blue
102
+ end
103
+ end until ["1", "2", "menu"].include?(input)
104
+ end
105
+
106
+ def user_local_ingredient_search
107
+ puts "\nWhich drink would you like to see the ingredients for?".light_blue
108
+ print "Type the drink name here: ".light_blue
109
+ input = gets.chomp.capitalize
110
+ Drink.find_ingredients_by_drink_name(input)
111
+ puts "\n--------------------------------------".light_blue
112
+ puts "\nPress [Enter] to return to the main menu..."
113
+ STDIN.getch
114
+ end
115
+
116
+ def user_local_recipe_search
117
+ puts "\nWhich drink would you like to see mixing instructions for?".light_blue
118
+ print "Type the drink name here: ".light_blue
119
+ input = gets.chomp.capitalize
120
+ Drink.find_recipe_by_drink_name(input)
121
+ puts "\n--------------------------------------".light_blue
122
+ puts "\nPress [Enter] to return to the main menu..."
123
+ STDIN.getch
124
+ end
125
+
126
+ def list_search_options
127
+ system "clear"
128
+ puts "Search Cocktails:".light_blue
129
+ puts "How would you like to begin your search?".cyan
130
+ puts "\n\t[1.] ".cyan + "Search by variety of alcohol or ingredient".light_blue
131
+ puts "\t[2.] ".cyan + "Search by name of drink".light_blue
132
+ puts "\t[3.] ".cyan + "Search by palate keywords\n".light_blue
133
+ begin
134
+ print "Your selection: ".cyan
135
+ input = gets.chomp
136
+ case input
137
+ when "1"
138
+ self.menu_search_by_alcohol
139
+ self.main_menu
140
+ when "2"
141
+ self.menu_search_by_drink_name
142
+ self.main_menu
143
+ when "3"
144
+ self.menu_search_by_palate_keyword
145
+ self.main_menu
146
+ else
147
+ puts "Whoops, \'#{input}\' isn't an option!".light_blue
148
+ end
149
+ end until ["1", "2", "3"].include?(input)
150
+ end
151
+
152
+ def menu_search_by_alcohol
153
+ print "\nType the alcohol or ingredient name here: ".light_blue
154
+ name = gets.chomp
155
+ drink_array = Drink.search_by_alcohol_name(name)
156
+ puts "\nHere are all the drinks we know with ".cyan + "#{name.upcase} ".light_blue + "in them:".cyan
157
+ a = drink_array.each.with_index(1) {|d, i| puts "\t#{i}. #{d.strDrink}".light_blue}
158
+ puts "Which drink would you like to know more about?".cyan
159
+ begin
160
+ print "Type the number of the drink here: ".cyan
161
+ input = gets.chomp
162
+ end until self.safe_input?(input, a) == true
163
+ self.menu_search_by_drink_name(a[input.to_i - 1].strDrink)
164
+ end
165
+
166
+ def menu_search_by_drink_name(name = nil)
167
+ if !(name)
168
+ print "\nType the drink name here: ".light_blue
169
+ name = gets.chomp
170
+ end
171
+ drink = Drink.search_by_drink_name(name)
172
+ puts "\nWould you like to see the ".cyan + "[recipe]".light_blue + " or ".cyan + "[ingredients]".light_blue + " of #{drink.strDrink.match(/^[aeiou]/i) ? "an" : "a"} #{drink.strDrink.upcase}?".cyan
173
+ puts "...or would you like to ".cyan + "[add]".light_blue + " it to your list of \'liked drinks\'?".cyan
174
+ begin
175
+ print "Your selection: ".cyan
176
+ input = gets.chomp
177
+ case input
178
+ when "recipe"
179
+ Drink.find_recipe_by_drink_name(drink.strDrink)
180
+ self.add_or_return(drink)
181
+ when "ingredients"
182
+ Drink.find_ingredients_by_drink_name(drink.strDrink)
183
+ self.add_or_return(drink)
184
+ when "add"
185
+ User.current_user.liked_drinks << drink
186
+ puts "\nAwesome! We've added ".light_blue + drink.strDrink.upcase.cyan + " to your list of \'liked drinks\'.".light_blue
187
+ puts "\nPress [Enter] to return to the main menu..."
188
+ STDIN.getch
189
+ else
190
+ puts "Whoops, \'#{input}\' isn't an option!".light_blue
191
+ end
192
+ end until input == "recipe" || input == "ingredients" || input == "add" || input == "menu"
193
+ end
194
+
195
+ def menu_search_by_palate_keyword
196
+ puts "\nWould you like to search for a ".light_blue + "dry".cyan + ", ".light_blue + "sweet".cyan + ", ".light_blue + "creamy".cyan + ", or ".light_blue + "bright ".cyan + "drink?".light_blue
197
+ begin
198
+ print "Your selection: ".cyan
199
+ input = gets.chomp
200
+ puts "Whoops, \'#{input}\' isn't an option!".light_blue unless ["dry", "sweet", "creamy", "bright"].include?(input)
201
+ end until ["dry", "sweet", "creamy", "bright"].include?(input)
202
+ drink_array = Drink.search_by_palate(input)
203
+ puts "Here are all the drinks we know with a ".cyan + "#{input.upcase} ".light_blue + "palate:".cyan
204
+ a = drink_array.each.with_index(1) {|d, i| puts "\t#{i}. #{d.strDrink}".light_blue}
205
+ puts "Which drink would you like to know more about?".cyan
206
+ begin
207
+ print "Type the number of the drink here: ".cyan
208
+ input = gets.chomp
209
+ end until self.safe_input?(input, a) == true
210
+ self.menu_search_by_drink_name(a[input.to_i - 1].strDrink)
211
+ end
212
+
213
+ def add_or_return(drink)
214
+ puts "\nType ".cyan + "[menu]".light_blue + " to return to the previous menu, or".cyan
215
+ puts "type ".cyan + "[add]".light_blue + " to add this drink to your list of \'liked drinks\'".cyan
216
+ begin
217
+ print "Your selection: ".cyan
218
+ input = gets.chomp
219
+ case input
220
+ when "add"
221
+ User.current_user.liked_drinks << drink
222
+ puts "\nAwesome! We've added ".light_blue + drink.strDrink.upcase.cyan + " to your list of \'liked drinks\'.".light_blue
223
+ puts "\nPress [Enter] to return to the main menu..."
224
+ STDIN.getch
225
+ else
226
+ puts "Whoops, \'#{input}\' isn't an option!".light_blue unless input == "menu"
227
+ end
228
+ end until input == "menu" || input == "add"
229
+ end
230
+
231
+ def exit
232
+ puts "\nThanks for stopping by! Have a great day!".cyan
233
+ end
234
+
235
+ ## ------------ ##
236
+ ## QUIZ METHODS ##
237
+ ## ------------ ##
238
+
239
+ def drink_quiz
240
+ puts "\nAre you ready to take our quiz? [Press Enter to begin]..."
241
+ STDIN.getch
242
+ system "clear"
243
+
244
+ User.current_user || User.new
245
+ self.offer_main_test
246
+ self.offer_sub_test
247
+
248
+ puts "\nDepending on your answers, we may have a few"
249
+ puts "more questions for you... [Press Enter to continue]"
250
+ STDIN.getch
251
+ system "clear"
252
+
253
+ self.test_dislikes
254
+
255
+ User.current_user.quiz_results ||= []
256
+ User.current_user.okay_drinks = (self.calculate_okay_drinks || [])
257
+ User.current_user.great_drinks = (self.calculate_great_drinks || [])
258
+
259
+ puts "\nThanks for completing our quiz!! Now give us just one second as"
260
+ puts "we find a drink you're sure to enjoy! [Press Enter to Continue...]"
261
+ STDIN.getch
262
+ system "clear"
263
+
264
+ self.return_quiz_results
265
+
266
+ puts "\nWe're ready to return to the main menu! [Press Enter to continue]..."
267
+ STDIN.getch
268
+ system "clear"
269
+ self.main_menu
270
+ end
271
+
272
+ def offer_main_test
273
+ puts "LiquerY Quiz:".light_blue
274
+ puts "Listed below are some classic cocktails. Pick the one you enjoy the most!".cyan
275
+ a = Drink.select_for_test.each.with_index(1) { |x, i| puts "#{i}. #{x.strDrink}".center(30)}
276
+ begin
277
+ print "Your favorite: ".cyan
278
+ input = gets.chomp
279
+ end until self.safe_input?(input, a) == true
280
+ User.current_user.liked_drinks << a[input.to_i - 1]
281
+ system "clear"
282
+ puts "LiquerY Quiz:".light_blue
283
+ puts "Gotcha! So of those drinks, your favorite is #{User.current_user.recent_choice.strDrink.match(/^[aeiou]/i) ? "an" : "a"} #{User.current_user.recent_choice.strDrink}?".cyan
284
+ end
285
+
286
+ def offer_sub_test
287
+ puts "\nIf you had to pick one other drink from this smaller list,".light_blue
288
+ puts "what would it be?".light_blue
289
+ b = Drink.select_for_test.each.with_object([]) do |drink, array|
290
+ User.current_user.recent_choice.all_ingredients.each do |ingredient|
291
+ array << drink if drink.all_ingredients.include?(ingredient)
292
+ end
293
+ end.uniq.reject{|d| d == User.current_user.recent_choice}
294
+ b.each.with_index(1) { |x, i| puts "#{i}. #{x.strDrink}".center(30)}
295
+ begin
296
+ print "Your choice: ".light_blue
297
+ input = gets.chomp
298
+ end until self.safe_input?(input, b) == true
299
+ User.current_user.liked_drinks << b[input.to_i - 1]
300
+ User.current_user.add_to_liked_ingredients
301
+ system "clear"
302
+ puts "LiquerY Quiz:".light_blue
303
+ puts "Super! So although your 1st choice was #{User.current_user.liked_drinks[-2].strDrink.match(/^[aeiou]/i) ? "an" : "a"} #{User.current_user.liked_drinks[-2].strDrink},".cyan
304
+ puts "you also could find yourself enjoying #{User.current_user.recent_choice.strDrink.match(/^[aeiou]/i) ? "an" : "a"} #{User.current_user.recent_choice.strDrink}.".cyan
305
+ end
306
+
307
+ def test_dislikes
308
+ bad_drinks = Drink.select_for_test.select do |drink|
309
+ User.current_user.liked_ingredients.size >= 10 ? (drink.all_ingredients & User.current_user.liked_ingredients).size < 2 : (drink.all_ingredients & User.current_user.liked_ingredients).empty?
310
+ end
311
+ bad_drinks -= User.current_user.disliked_drinks
312
+ unless bad_drinks.empty?
313
+ puts "LiquerY Quiz:".light_blue
314
+ puts "Given the cocktails you've identified so far, we're noticing".cyan #3. test for dislikes
315
+ puts "that you might not enjoy the palates of some of these drinks:".cyan
316
+ bad_drinks.each.with_index(1) { |x, i| puts "#{i}. #{x.strDrink}".center(30)}
317
+ puts "Is there one drink on this list that you absolutely cannot stand?".cyan
318
+ begin
319
+ print "If so, type that drink's number, otherwise type [none]: ".light_blue
320
+ input = gets.chomp
321
+ end until (self.safe_input?(input, bad_drinks) == true) || (input == "none")
322
+ if input == "none"
323
+ User.current_user.disliked_drinks << Drink::DUMMY_DRINK if User.current_user.disliked_drinks.empty?
324
+ system "clear"
325
+ puts "LiquerY Quiz:".light_blue
326
+ puts "Perfect! It makes our job a little easier if you have an open mind & palate!".cyan
327
+ else
328
+ User.current_user.disliked_drinks << bad_drinks[input.to_i - 1]
329
+ User.current_user.liked_drinks -= (User.current_user.liked_drinks & User.current_user.disliked_drinks)
330
+ system "clear"
331
+ puts "LiquerY Quiz:".light_blue
332
+ puts "Blech! You just do not enjoy #{User.current_user.disliked_drinks[-1].strDrink.match(/^[aeiou]/i) ? "an" : "a"} #{User.current_user.disliked_drinks[-1].strDrink}.".cyan
333
+ puts "We hear you! And that's great to know!".cyan
334
+ end
335
+ else # i.e. if bad_drinks.empty?
336
+ puts "LiquerY Quiz:".light_blue
337
+ puts "Actually, we don't think we have any further questions for you!".cyan
338
+ end
339
+ end
340
+
341
+ def calculate_okay_drinks
342
+ Drink.all.select do |drink| #4. calculate User.current_user.s "okay_drinks" array
343
+ if (User.current_user.liked_drinks + User.current_user.disliked_drinks + User.current_user.quiz_results).include?(drink)
344
+ false
345
+ elsif drink.all_ingredients.size < 4
346
+ (drink.all_ingredients & User.current_user.liked_ingredients).size > 0 && (drink.all_ingredients & User.current_user.disliked_drinks[-1].all_ingredients).size <= 1
347
+ else
348
+ (drink.all_ingredients & User.current_user.liked_ingredients).size > 1 && (drink.all_ingredients & User.current_user.disliked_drinks[-1].all_ingredients).size <= 1
349
+ end
350
+ end
351
+ end
352
+
353
+ def calculate_great_drinks
354
+ array = Drink.all.select do |drink| # 5. calculate User.current_user.s "great_drinks array"
355
+ if (User.current_user.liked_drinks + User.current_user.disliked_drinks + User.current_user.quiz_results).include?(drink)
356
+ false
357
+ elsif drink.all_ingredients.size < 4
358
+ (drink.all_ingredients & User.current_user.liked_ingredients).size > 1 && (drink.all_ingredients & User.current_user.disliked_drinks[-1].all_ingredients).size <= 1
359
+ else
360
+ (drink.all_ingredients & User.current_user.liked_ingredients).size > 2 && (drink.all_ingredients & User.current_user.disliked_drinks[-1].all_ingredients).size <= 1
361
+ end
362
+ end
363
+ end
364
+
365
+ def return_quiz_results
366
+ User.current_user.great_drinks.size > 1 ? drink = User.current_user.great_drinks.sample : drink = User.current_user.okay_drinks.sample
367
+ User.current_user.quiz_results << drink
368
+ if Drink.select_for_test.include?(drink)
369
+ puts "The answer was under our noses the entire time!".center(59).light_blue
370
+ puts "We know we've asked you about this drink in the list above,".light_blue
371
+ puts "but we're totally positive that you would love #{User.current_user.quiz_results[-1].strDrink.match(/^[aeiou]/i) ? "an" : "a"}".center(59).light_blue
372
+ puts "\n"
373
+ puts "#{drink.strDrink}!".center(59).cyan
374
+ puts "It's made with #{drink.print_ingredients}".center(59).cyan
375
+ puts "\n"
376
+ puts "Give it a whirl, if you haven't tried one before!".center(59).light_blue
377
+ puts "\n"
378
+ elsif User.current_user.great_drinks.include?(drink)
379
+ puts "So, we had to look into some of our more obscure".center(61).light_blue
380
+ puts "cocktail recipes to find something just perfect for you".center(61).light_blue
381
+ puts "but we're still totally certain that you're going to love it!".light_blue
382
+ puts "\n"
383
+ puts "The #{drink.strDrink}!".center(61).cyan
384
+ puts "It's made with #{drink.print_ingredients}".center(61).cyan
385
+ puts "\n"
386
+ puts "Be sure to give it a taste!".center(61).light_blue
387
+ puts "\n"
388
+ else
389
+ puts "We have to admit it... you nearly stumped us there!".center(64).light_blue
390
+ puts "Sometimes drink preferences aren't exactly data science,".light_blue
391
+ puts "but we're still decently confident that you'd enjoy #{drink.strDrink.match(/^[aeiou]/i) ? "an" : "a"}".center(64).light_blue
392
+ puts "\n"
393
+ puts "#{drink.strDrink}!".center(64).cyan
394
+ puts "It's made with #{drink.print_ingredients}".center(64).cyan
395
+ puts "\n"
396
+ puts "Be sure to give it a taste!".center(64).light_blue
397
+ puts "\n"
398
+ end
399
+ end
400
+
401
+ def safe_input?(input, array)
402
+ input_max_range = array.size
403
+ if (1..input_max_range).include?(input.to_i)
404
+ true
405
+ else
406
+ puts "Sorry, that selection is invalid. Mind trying again?".light_blue
407
+ false
408
+ end
409
+ end
410
+
411
+
412
+
413
+
414
+ end
@@ -0,0 +1,17 @@
1
+ class DrinkAPI
2
+ attr_reader :id_array
3
+ def initialize
4
+ data = open("https://www.thecocktaildb.com/api/json/v1/1/filter.php?c=Cocktail").read
5
+ doc = JSON.parse(data)
6
+ #key is ["drinks"] value is array of ingredients
7
+ @id_array = doc.first.last.each.with_object([]) do |id_hash, array|
8
+ array << id_hash["idDrink"]
9
+ end
10
+ end
11
+
12
+ def make_hash
13
+ self.id_array.each.with_object({}) do |id, drink_hash|
14
+ drink_hash[id] = JSON.parse(open("https://www.thecocktaildb.com/api/json/v1/1/lookup.php?i=#{id}").read).values.first[0]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,58 @@
1
+ class User
2
+ attr_accessor :liked_drinks, :liked_ingredients, :disliked_drinks, :quiz_results, :okay_drinks, :great_drinks
3
+
4
+ @@all = []
5
+
6
+ def initialize
7
+ self.liked_drinks = []
8
+ self.liked_ingredients = []
9
+ self.disliked_drinks = []
10
+ @@all << self
11
+ end
12
+
13
+ def self.all
14
+ @@all
15
+ end
16
+
17
+ def self.current_user
18
+ @@all[-1]
19
+ end
20
+
21
+ def list_liked_drinks
22
+ puts "Drinks you like:".cyan
23
+ puts "\n\t#{self.print_list(self.liked_drinks.uniq)}".light_blue
24
+ puts "\nDrinks we've recommended:".cyan
25
+ puts "\n\t#{self.print_list(self.quiz_results)}".light_blue
26
+ end
27
+
28
+ def list_disliked_drinks
29
+ "Drinks you dislike: #{self.names(disliked_drinks)}."
30
+ end
31
+
32
+ def print_list(array)
33
+ array.each.with_object("") do |drink, string|
34
+ if array.size == 1
35
+ string << drink.strDrink
36
+ elsif array.size == 2 && drink == array[0]
37
+ string << "#{drink.strDrink} "
38
+ elsif drink == array[-1]
39
+ string << "and #{drink.strDrink}"
40
+ else
41
+ string << "#{drink.strDrink}, "
42
+ end
43
+ end
44
+ end
45
+
46
+ def names(drink_array)
47
+ drink_array.map {|drink| drink.strDrink}
48
+ end
49
+
50
+ def recent_choice
51
+ self.liked_drinks[-1]
52
+ end
53
+
54
+ def add_to_liked_ingredients
55
+ @liked_ingredients.concat((self.liked_drinks.map {|d| d.all_ingredients}).flatten.uniq)
56
+ end
57
+
58
+ end