Skip to content

Instantly share code, notes, and snippets.

@jah2488
Created June 4, 2010 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jah2488/425544 to your computer and use it in GitHub Desktop.
Save jah2488/425544 to your computer and use it in GitHub Desktop.
require 'restaurant'
require 'support/string_extend'
class Guide
class Config
@@actions = ['list', 'find', 'add', 'quit']
def self.actions; @@actions; end #the semicolons make it all stay on one line
end
def initialize(path=nil)
# locate the restaurant text file at path
Restaurant.filepath = path
if Restaurant.file_usable?
puts "... Found Restaurant File."
# or create a new file
elsif Restaurant.create_file
puts "... Unable to Locate Restaurant File, Creating new File."
# exit if create fails
else
puts "Exiting upon Error.\n\n"
exit!
end
end
def launch!
introduction
#action loop
result = nil
until result == :quit do
action, args = get_action
result = do_action(action, args)
end
conclusion
end
def get_action
action = nil
# Keep asking for user input until we get a valid response/action
until Guide::Config.actions.include?(action)
puts "Actions Available : " + Guide::Config.actions.join(", ") if action
print "> "
user_response = gets.chomp
args = user_response.downcase.strip.split(' ')
action = args.shift
end
return action, args
end
def do_action(action, args=[])
case action
when 'list'
list(args)
when 'find'
keyword = args.shift
find(keyword)
when 'add'
add
when 'quit'
puts "quitting..."
return :quit
else
puts "\n I do not understand, try again.\n"
end
end
def list(args=[])
sort_order = args.shift
sort_order = "name" unless ['name','cuisine','price'].include?(sort_order)
output_action_header("Listing Restaurants")
restaurants = Restaurant.saved_restaurants
restaurants.sort! do |r1, r2|
case sort_order
when 'name'
r1.name.downcase <=> r2.name.downcase
when 'cuisine'
r1.cuisine.downcase <=> r2.cuisine.downcase
when 'price'
r1.price.to_i <=> r2.price.to_i
end
end
output_restaurant_table(restaurants)
puts "Sort Using : Name, Cuisine, or Price"
end
def find(keyword="")
output_action_header("Find a Restaurant")
if keyword
restaurants = Restaurant.saved_restaurants
found = restaurants.select do |rest|
rest.name.downcase.include?(keyword.downcase) ||
rest.cuisine.downcase.include?(keyword.downcase) ||
rest.price.to_i <= keyword.to_i
end
output_restaurant_table(found)
else
puts "Find using a keyphrase to search the restaurant list."
puts "Examples: 'find tamale', find 'mcdonalds', find 'sandwhich'\n\n"
end
end
def add
puts "\Add a Restaurant\n\n".upcase
restaurant = Restaurant.build_from_questions
if restaurant.save
puts "\nRestaurant Added to Database\n\n"
else
puts "\n Error Occured. Restaurant not saved!"
end
end
def introduction
puts "\n\n ---===== Welcome to Justin\'s Food Finder ====--- \n\n"
puts "This is an interactive guide to help you find the food you crave now. \n\n"
end
def conclusion
puts "\n\n ==== end of program ==== \n\n"
end
def output_action_header(text)
puts "\n#{text.upcase.center(60)}\n\n"
end
def output_restaurant_table(restaurants=[])
print " " + "Name".ljust(30)
print " " + "Cusine".ljust(20)
print " " + "Price".rjust(6) + "\n"
puts "-" * 60
restaurants.each do |rest|
line = " " << rest.name.titleize.ljust(30)
line << " " + rest.cuisine.titleize.ljust(2)
line << " " + rest.formatted_price.titleize.rjust(15)
puts line
end
puts "No Listings found" if restaurants.empty?
puts "-" * 60
end
end
### Food Finder ###
##
## Launch this ruby file from the command line
## to get started.
##
#
APP_ROOT = File.dirname(__FILE__)
#
# - All These Do The Same thing.
#require "#{APP_ROOT}/lib/guide"
#
#require File.join(APP_ROOT, 'lib', 'guide.rb')
#
#
$:.unshift( File.join(APP_ROOT, 'lib') )
require "guide"
guide = Guide.new('restaurants.txt')
guide.launch!
module NumberHelper
def number_to_currency(number,options={})
unit = options[:unit] || '$'
precision = options[:precision] || 2
delimiter = options[:delimiter] || ','
separator = options[:separator] || '.'
separator = '' if precision == 0
integer, decimal = number.to_s.split('.')
i = integer.length
until i<=3
i -= 3
integer = integer.insert(i,delimiter)
end
if precision == 0
precise_decimal = ''
else
decimal ||= "0"
decimal = decimal[0, precision-1]
precise_decimal = decimal.ljust(precision, "0")
end
return (unit + integer + separator + precise_decimal)
end
end
require 'support/number_helper'
class Restaurant
include NumberHelper ## It has been mixed in
@@filepath = nil
def self.filepath=(path=nil)
@@filepath = File.join(APP_ROOT, path)
end
attr_accessor :name, :cuisine, :price
def self.file_exists?
# class should know if the restaurant file exists
if @@filepath && File.exists?(@@filepath)
return true
else
return false
end
end
def self.file_usable?
return false unless @@filepath
return false unless File.exists?(@@filepath)
return false unless File.readable?(@@filepath)
return false unless File.writable?(@@filepath)
return true
end
def self.create_file
#create teh restaurant file
File.open(@@filepath, 'w') unless file_exists?
return file_usable?
end
def self.saved_restaurants
# Do we want to go back and retrieve these each time? or do we wish to only do it once and
# cache the info from then on
if @restaurants = []
if file_usable?
file= File.new(@@filepath, 'r')
file.each_line do |line|
@restaurants << Restaurant.new.import_line(line.chomp)
end
file.close
end
end
return @restaurants
end
def self.build_from_questions
args = {}
print "Restaurant Name: "
args[:name] = gets.chomp.strip
print "Restaurant Cuisine Type: "
args[:cuisine] = gets.chomp.strip
print "Restaurant Avg Price: "
args[:price] = gets.chomp.strip
return self.new(args)
end
def initialize(args={})
@name = args[:name] || ""
@cuisine = args[:cuisine] || ""
@price = args[:price] || ""
end
def import_line(line)
line_array = line.split("\t")
@name, @cuisine, @price = line_array
return self
end
def save
return false unless Restaurant.file_usable?
File.open(@@filepath, 'a') do |file|
file.puts "#{[@name, @cuisine, @price].join("\t")}\n"
end
return true
end
def formatted_price
number_to_currency(@price)
end
end
class String
def titleize
self.split(' ').collect {|word| word.capitalize}.join(" ")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment