Ruby hash.new error undefined local variable or method ... for main:Object - ruby

I'm trying to create a new hash (group) to which I'll pass values for name, groceries, fuel_and_accommodations and recreational_activities. Actually, eventually I'll need a hash nested within the group hash (for each traveler). My issue right now is that I get this message:
undefined local variable or method `group' for main:Object
(repl):5:in `user_name'
(repl):18:in `block in enter_expenses'
(repl):15:in `times'
(repl):15:in `enter_expenses'
(repl):34:in `'
I'm just learning Ruby. Any help would be greatly appreciated!
group = Hash.new
def user_name
puts "What is the name of this traveler?"
group["name"]= gets.chomp.capitalize
end
def enter_expenses
puts "Welcome to the Expense Tracker System!\n".upcase
puts "__________________________________________"
puts "\nUse this system to track your group's expenses when traveling."
print "Ready to get started? Enter yes to continue"
ready_to_expense = gets.chomp.downcase
4.times do
if ready_to_expense == "yes"
puts "Welcome #{user_name}! Enter your expenses below:\n"
puts "Amount spent on groceries:"
group["groceries"]= gets.chomp.to_f
puts "Amount spent on fuel & accommodations:"
group["fuel_and_accommodations"]= gets.chomp.to_f
puts "Amount spent recreational activities:"
group["recreational_activities"] = gets.chomp.to_f
elsif "Please come back when ready to enter your expenses."
end
end
end
enter_expenses
create_travelers
puts "__________________________________________"
puts "Thanks for using the expense tracker system!".upcase

Local variables in Ruby does not get into methods; methods declare their own scope, they don’t act like closures. You might use instance variable instead:
#group = Hash.new # NOTE #
...
def enter_expenses
...
4.times do
if ready_to_expense == "yes"
#group["groceries"]= gets.chomp.to_f # NOTE #
...
end
end
end

Related

No Method Errors in Ruby

I was able to get a menu and pull up names of cat breeds, however when I continue to learn about the cat's breed I get this error down below. Not sure where to go from here. Am I suppose to delete something off? or perhaps try another api? really running out of ideas here.
Error below:
Traceback (most recent call last):
4: from bin/run.rb:5:in `<main>'
3: from /Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:9:in `call'
2: from /Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:24:in `menu'
1: from /Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:44:in `list_of_breeds' /Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:54:in `breed_selection': undefined method `get_metric_weight' for
#<CatBreed:0x00007fc581afc488> (NoMethodError)
in my cli.rb file
class CLI
def initialize
API.new.get_breed_data
end
def call
greeting
menu
end
def greeting
puts "Welcome! Start searching for Cat breeds"
puts ""
puts "--To search for cat breeds, enter 'breeds'"
puts ""
puts "--If there is nothing you would like to do at the moment, enter 'exit'"
end
def menu
input = gets.strip.downcase
if input == "breeds"
list_of_breeds
elsif input == "exit"
goodbye
else
invalid_entry
end
end
def goodbye
puts "Goodbye!"
end
def list_of_breeds
puts "Select which breed you would like to know about:"
CatBreed.all.each_with_index do |breed, index|
puts "#{index + 1}. #{breed.name}"
end
input = gets.strip.downcase
breed_selection(input)
end
def breed_selection(breed)
input = gets.strip.downcase
breed = CatBreed.find_by_name(breed)
if breed
puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
puts "Name of Breed: #{breed.name}"
puts "Approximate Weight: #{breed.get_metric_weight}"
puts "Approximate Height: #{breed.get_metric_height}"
puts "Bred For: #{breed.bred_for}"
puts "Breed Group: #{breed.breed_group}"
puts "Average Life Span: #{breed.life_span}"
puts "Temperament: #{breed.temperament}"
puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
puts ""
puts "To continue searching for breeds, enter 'breeds'."
puts "If there is nothing else you would like to do, enter 'exit'."
puts ""
puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
menu
else
incorrect_breed_name
end
end
def incorrect_breed_name
puts "The breed name that you entered may have been spelled incorrectly."
puts "Please enter 'breeds' to pull up the list and try again."
menu
end
def invalid_entry
puts ""
puts "Hmmmmmm, I'm not understanding, please try again."
puts ""
menu
end
#binding.pry
end
something I'm doing wrong here? If you need more info let me know..
The error message says:
/Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:54:in `breed_selection':
undefined method `get_metric_weight' for #<CatBreed:0x00007fc581afc488> (NoMethodError)
This error has got nothing to do with VSCode. It says that your CatBreed instance does not respond to a get_metric_weight method.
However, you have not shown the CatBreed class definition above, so I cannot comment further on the resolution.
Your code also assumes it has methods such as get_metric_height, bred_for and breed_group. If these methods aren't defined either, then I would expect a similar error to be raised once this issue is fixed.

Get ruby dungeon to repeat back player name

I'm trying to expand upon Peter Cooper's dungeon game in Beginning Ruby and I want the game to address the player by name at each room and then ask them where they will go to make the game more interactive. I keep getting this error though:
dungeon.rb:82:in <main>': undefined methodname' for nil:NilClass (NoMethodError)
So the main parts I've added to try to make this work are Dungeon initialize (lines 4-13)
def initialize
player_name = ""
until !player_name.empty?
puts "Enter your name!"
player_name = gets.chomp
end
#player = Player.new(player_name)
#player.name = player_name
#rooms = []
end
The line in question that creates the error is this:
my_dungeon.add_room(:largecave, "Large Cave", "#{#player.name}, you find yourself in a large cavernous cave. To the west is a small aperture", {:west => :smallcave})
Full code is here:
Ruby Dungeon Code
What's going on here?
You probably wanted to use
my_dungeon.player.name
instead of
#player.name
in rooms addition method calls(since player has been defined for Dungeon instance).
So just use these lines instead of ones you currently have:
my_dungeon.add_room(:largecave, "Large Cave", "#{my_dungeon.player.name}, you find yourself in a large cavernous cave. To the west is a small aperture", {:west => :smallcave})
my_dungeon.add_room(:smallcave, "Small Cave", "#{my_dungeon.player.name}, you find yourself in a small, claustrophopic cave. To the east is a small aperture", {:east => :largecave}
By the way, you set name in initialize method, so there is no need for #player.name = player_name. And it is simpler to read while player_name.empty? instead of until !player_name.empty?, consider following refactoring:
def initialize
player_name = ""
while player_name.empty?
puts "Enter your name!"
player_name = gets.chomp
end
#player = Player.new(player_name)
#rooms = []
end

Ruby: Chatterbot can't load bot data

I'm picking up ruby language and get stuck at playing with the chatterbot i have developed. Similar issue has been asked here Click here , I did what they suggested to change the rescue in order to see the full message.But it doesn't seem right, I was running basic_client.rb at rubybot directory and fred.bot is also generated at that directory . Please see the error message below: Your help very be very much appreciated.
Snailwalkers-MacBook-Pro:~ snailwalker$ cd rubybot
Snailwalkers-MacBook-Pro:rubybot snailwalker$ ruby basic_client.rb
/Users/snailwalker/rubybot/bot.rb:12:in `rescue in initialize': Can't load bot data because: No such file or directory - bot_data (RuntimeError)
from /Users/snailwalker/rubybot/bot.rb:9:in `initialize'
from basic_client.rb:3:in `new'
from basic_client.rb:3:in `<main>'
basic_client.rb
require_relative 'bot.rb'
bot = Bot.new(:name => 'Fred', :data_file => 'fred.bot')
puts bot.greeting
while input = gets and input.chomp != 'end'
puts '>> ' + bot.response_to(input)
end
puts bot.farewell
bot.rb:
require 'yaml'
require './wordplay'
class Bot
attr_reader :name
def initialize(options)
#name = options[:name] || "Unnamed Bot"
begin
#data = YAML.load(File.read('bot_data'))
rescue => e
raise "Can't load bot data because: #{e}"
end
end
def greeting
random_response :greeting
end
def farewell
random_response :farewell
end
def response_to(input)
prepared_input = preprocess(input).downcase
sentence = best_sentence(prepared_input)
reversed_sentence = WordPlay.switch_pronouns(sentence)
responses = possible_responses(sentence)
responses[rand(responses.length)]
end
private
def possible_responses(sentence)
responses = []
#data[:responses].keys.each do |pattern|
next unless pattern.is_a?(String)
if sentence.match('\b' + pattern.gsub(/\*/, '') + '\b')
if pattern.include?('*')
responses << #data[:responses][pattern].collect do |phrase|
matching_section = sentence.sub(/^.*#{pattern}\s+/, '')
phrase.sub('*', WordPlay.switch_pronouns(matching_section))
end
else
responses << #data[:responses][pattern]
end
end
end
responses << #data[:responses][:default] if responses.empty?
responses.flatten
end
def preprocess(input)
perform_substitutions input
end
def perform_substitutions(input)
#data[:presubs].each {|s| input.gsub!(s[0], s[1])}
input
end
# select best_sentence by looking at longest sentence
def best_sentence(input)
hot_words = #data[:responses].keys.select do |k|
k.class == String && k =~ /^\w+$/
end
WordPlay.best_sentence(input.sentences, hot_words)
end
def random_response(key)
random_index = rand(#data[:responses][key].length)
#data[:responses][key][random_index].gsub(/\[name\]/, #name)
end
end
I'm assuming that you are trying to load the :data_file passed into Bot.new, but right now you are statically loading a bot_data file everytime. You never mentioned about bot_data in the question. So if I'm right it should be like this :
#data = YAML.load(File.read(options[:data_file]))
Instead of :
#data = YAML.load(File.read('bot_data'))

Undefined local variable or method 'product'

I am doing a task that requires me add some products together and give a 10% discount providing the total is above £60. I have done the following:
class Checkout
def initialize (rules)
#rules = rules
#cart = []
end
def scan (item)
if product == Product.find(item)
#cart << product.clone
#Clone preserves frozen state whereas .dup() doesn't if use would raise a
#NoMethodError
end
end
def total
#cart = #rules.apply #cart
end
def self.find item
[item]
end
co = Checkout.new(Promotional_Rules.new)
co.empty_cart
co.scan(1)
co.scan(2)
co.scan(3)
puts "Total price: #{co.total}"
puts
co.empty_cart
co.scan(1)
co.scan(3)
co.scan(1)
puts "Total price: #{co.total}"
puts
co.empty_cart
co.scan(1)
co.scan(2)
co.scan(1)
co.scan(3)
puts "Total price: #{co.total}"
puts
However when I run this in irb I get undefined variable or method product. Sounds a bit daft but this should work.
You're using one too many equal signs
def scan (item)
# if product == Product.find(item)
if product = Product.find(item) # <--- should be this
#cart << product.clone
#Clone preserves frozen state whereas .dup() doesn't if use would raise a
#NoMethodError
end
end
Of course, then you'll get a different error since find doesn't exist on Product yet... which I think you're trying to define here:
def self.find item # self should be changed to Product
[item]
end
Then you're going to get an error for apply not existing for Promotional_Rules ...
One of the best ways to debug these errors is follow the stack traces. So for the last error I get the following message:
test.rb:53:in `total': undefined method `apply' for #<Promotional_Rules:0x007f94f48bc7a8> (NoMethodError)
from test.rb:72:in `<main>'
That's basically saying that at line 53 you'll find apply hasn't been defined for #rules which is an instance of Promotional_Rules. Looking at the Promotional_Rules class you've clearly defined that method as apply_to_item and not apply. If you keep following and fixing the rabbit trails like this for stack traces you'll be able to debug your program with ease!

can i read the deleted statuses on twitter with ruby?

I would like to read the deleted statuses on twitter since i can already have the user_id and status_id of the deleted tatus using "on_delete" method.
here is my code:
require 'rubygems'
require 'tweetstream'
TweetStream::Client.new(USER,PASS).follow(3331681,15846407,30592818,21249843,1367531,428333, 196218494,82158673, :delete => Proc.new{ |status_id, user_id| puts "#{status_id}, #{user_id}"}) do |status|
#is it a retweet
rt=!defined?(status.method_missing("retweeted_status",status.id).class).nil?
puts "retweet?:"
puts rt.inspect
if status.in_reply_to_screen_name.nil?
if rt
puts "Retweeted by :#{status.user.screen_name}"
else
puts "Screen name :#{status.user.screen_name}"
end
else
puts "From :#{status.user.screen_name} to #{status.in_reply_to_screen_name}"
end
puts "Text:#{status.text}"
puts "#{status.created_at}"
puts '*' * 7
puts "user id:#{status.user.id}"
puts "to :#{status.in_reply_to_user_id}"
puts '--' * 25
end
No, you can't. This is a constraint of the Twitter API rather than any Ruby library. It used to be possible but has since been fixed, breaking tweet recovery services such as tweleted.com in the process.

Resources