Build the now_serving method which should call out (i.e. puts) the next person in line and then remove them from the front. If there is nobody in line, it should call out (puts) that "There is nobody waiting to be served!". When I try to use the shift method to get rid of the first element in the array. I end up with the wrong output. Here is the Ruby code:
def now_serving(array)
while array.length != 0
array.each do |name|
puts "Currently serving #{name}."
array.shift
end
end
puts "There is nobody waiting to be served!"
end
But the array.shift is only working once, How do I get it to drop the first element of an array continuously. Here is the code for the Rspec:
describe "#now_serving" do
context "there are no people in line" do
it "should say that the line is empty" do
expect($stdout).to receive(:puts).with("There is nobody waiting to be served!")
now_serving(katz_deli)
end
end
context "there are people in line" do
it "should serve the first person in line and remove them from the queue" do
expect($stdout).to receive(:puts).with("Currently serving Logan.")
now_serving(other_deli)
expect(other_deli).to eq(%w(Avi Spencer))
end
end
end
end
It is a bad idea to shift an array at the same time you loop through it.
def now_serving(array)
while name = array.shift
puts "Currently serving #{name}."
end
puts "There is nobody waiting to be served!"
end
So this fixed my bug
def now_serving(array)
queue = Queue.new
queue = array
if array.length > 0
puts "Currently serving #{array[0]}."
array.shift
else
puts "There is nobody waiting to be served!"
end
end
Related
class Game
def start
#player1 = Player.new("don")
#player2 = Player.new("tum")
end
def player_turn
if #turn.even?
puts "this is #{#player2.name}'s turn"
else
puts "this is #{#player1.name}'s turn"
end
end
end
I think first you are going to have to define the instance variable #turn, and how it is incremented. Additionally I would recommend changing the Game#start to #initialize, the test below assumes this.
Then you can check what is output to stdout.
RSpec.describe Game do
describe "#player_turn" do
context 'when the turn is even' do
let(:game) { Game.new }
it "tells you it is player 2's turn" do
expect do
game.player_turn
end.to output("this is tum's turn\n").to_stdout
end
end
end
end
In the code below, break exits the program totally and returns to irb, while I want to get back to the line where the print statement is.
def f1()
do_something
end
def f2()
do_something
end
def f1()
print "I want to get back here."
while true
choice = gets.chomp
if choice == "exit"
break
else
f2()
end
end
end
How do you break just one level up?
Add another loop outside. It may also be simpler to use loop than while true:
def f1()
loop do
print "I want to get back here."
loop do
choice = gets.chomp
if choice == "exit"
break
else
f2()
end
end
end
end
I have created an array of objects containing information on the Oscars using a text file with all the category names, winners and nominees (winners appear in nominees list as well). I now want to be able to ask a user. Of which category would you like to know the winner? Once the question is asked it would return the answer. I can only get it to work on the last object of the array(best visual effects returns gravity). Can someone explain why this is happening?
class AwardCategory
attr_accessor :winner, :name, :nominees
def initialize(name)
#name = name
#nominees = []
end
end
class Nominee
attr_accessor :name
def initialize(name)
#name = name
end
end
file = File.open('oscar_noms.txt', 'r')
oscars = []
begin
while true do
award_category = AwardCategory.new(file.readline.downcase)
award_category.winner = file.readline.downcase
nominee = Nominee.new(file.readline.downcase)
award_category.nominees << nominee
next_nominee = Nominee.new(file.readline.downcase)
until next_nominee.name == "\n"
award_category.nominees << next_nominee
next_nominee = Nominee.new(file.readline.downcase)
end
oscars << award_category
end
rescue EOFError => e
puts 'rescued'
end
#puts oscars.inspect
#Read input here
puts "What category do you want to know the winner for?"
answer = gets
oscars.each
if answer.downcase == award_category.name
puts award_category.winner
else
puts "That is not a category"
end
That piece of code
puts "What category do you want to know the winner for?"
answer = gets
oscars.each
if answer.downcase == award_category.name
puts award_category.winner
else
puts "That is not a category"
end
Now with correct indentation
puts "What category do you want to know the winner for?"
answer = gets
oscars.each
if answer.downcase == award_category.name
puts award_category.winner
else
puts "That is not a category"
end
Note that the part below oscars.each is not indented, because each needs a do/end block which it will execute once for every element. What you probably want is this
puts "What category do you want to know the winner for?"
answer = gets
oscars.each do |award_category|
if answer.downcase == award_category.name
puts award_category.winner
else
puts "That is not a category"
end
end
Although I suggest you leave off the else, because you will get the message "That is not a category" for every answer that did not match. Also, you should use gets.chomp to remove the newline from the user input and do downcase outside of the each loop. As a last note, some of your variables are poorly named. For example, why should a list of award categories be named oscars? It should be award_categories instead.
I've read my code up and down for about 30 mins now. I can't for the life of me see where user_response is undefined. I'm very new to coding so I don't know how much of the code would be appropriate to paste in here. I figure that launch and get_action are essential but the rest couldn't hurt?
error => rb:32:in `launch!': undefined local variable or method `user_response' for
<Guide:0x007fb019984718> (NameError)
class Guide
class Config
##actions = ['list', 'find', 'add', 'quit']
def self.actions
##actions
end
end
def initialize(path=nil)
# locate the restaurant text file at path
Restaurant.filepath = path
if Restaurant.file_usable?
puts "Found restaurant file."
# or IF a new text file can't be created, create a new file
elsif Restaurant.create_file
puts "Created restaurant file."
# exit if create fails
else
puts "Exiting"
exit!
end
end
def launch! #! means that it is a strong powerful method!
introduction
# action loop
result = nil
until result == :quit
action = get_action
result = do_action(user_response)
end
conclusion
end
def get_action
action = nil
# Keep asking for user input until we get a valid action
until Guide::Config.actions.include?(action)
puts "Actions: " + Guide::Config.actions.join(", ") if action
print "> "
user_response = gets.chomp
action = user_response.downcase.strip
end
return action
end
def do_action(action)
case action
when 'list'
puts "Listing..."
when 'find'
puts "Finding..."
when 'add'
puts "Adding..."
when 'quit'
return :quit
else puts " I don't understand that command."
end
end
def introduction
puts "<<< Welcome to the Food Finder >>>"
puts "This is an interactive guide to help you find the food you crave."
end
def conclusion
puts "<<< Goodbye and Bon Appetit! >>>>"
end
end
I think you want to do this :
def launch! #! means that it is a strong powerful method!
introduction
# action loop
result = nil
until result == :quit
result = do_action(get_action)
end
conclusion
end
The only time you define a variable called user_response is in your get_action method.
The way you define it there makes it a local variable and it will not be accessible from anywhere but inside the get_action method.
Greetings,
I've a ruby script thats opening files and inserting the data inside the file into a database. Some of the files are missing so when the script attempts to open the file it throws a file not found exception.
Can anyone tell me how I can continue the process instead of the whole thing coming to an abrupt end. Please note this is the first thing I've ever done with ruby so be gentle! :-)
The code I'm using is as follows
def insertData
for i in (1..93)
puts "now looking at #{i}"
file = File.new("callspan/#{i}", "r")
while(line = file.gets)
with_db do |db|
db.query(line)
end
end
end
Either wrap the opening of the file with a call to File.exists?, or rescue from the exception. I prefer the former, if you expect it to be a common case (exceptions are for "exceptional" problems).
def insertData
for i in (1..93)
puts "now looking at #{i}"
next if !File.exists?("callspan/#{1}")
file = File.new("callspan/#{i}", "r")
while(line = file.gets)
with_db do |db|
db.query(line)
end
end
end
end
Simple one line exception handling:
10 / 0 rescue nil
Rescue only file not found exceptions:
def insert_data
(1..93).each do |i|
puts "now looking at #{i}"
begin
file = File.new("callspan/#{i}", 'r')
while(line = file.gets)
with_db do |db|
db.query(line)
end
end
rescue Errno::ENOENT
puts "skipping #{i}"
end
end
end
Use rescue nil to catch exceptions, like this:
def insertData
for i in (1..93)
puts "now looking at #{i}"
File.open("callspan/#{i}", "r").each_line do |line|
with_db do |db|
db.query(line)
end
end rescue nil
end
end
(i'd also put with_db around the cycle, it's probably more efficient)