ruby NoMethodError undefined method `balance' for nil:NilClass - ruby

Here is my code and this is the error I am receiving:
NoMethodError
undefined method 'balance' for nil:NilClass
I am new to programming and can't seem to figure out the problem.
class CheckingAccount < BankAccount
attr_reader :number_of_withdrawals
MAX_FREE_WITHDRAWALS = 3
def initialize(balance)
balance = balance
super(balance)
#number_of_withdrawals = 0
end
def get_free_withdrawal_limit
MAX_FREE_WITHDRAWALS
end
def transfer(account, amount)
#other_account = CheckingAccount.new(amount)
current_balance = #account.balance
other_balance = #other_account.balance
if current_balance > amount
current_balance = #balance - amount
other_balance = #balance + amount
elsif
current_balance < amount
"not enought funds available for transfer"
end

The error is within transfer method, in this line:
current_balance = #account.balance
#account has not been set anywhere, so it is nil and you get a NoMethodError when you call balance on it.
Maybe you meant account, since you are passing it as an argument.

Related

nil can't be coerced into Integer (TypeError)

I'm new to ruby and I'm taking a course on it and got a bit stuck. I'm trying to create a class to represent a vending machine and several classes to represent items within it, which inherit from the vending machine.
Here's the code for the vending machine class and I've included a comment on the line throwing an error:
class VendorFood
##total_sales = 0
def initialize(name, price, vending_number)
#name = name
#price = price
#vending_number = vending_number
#supply = 0
end
def stock_item(num)
#supply += num
end
def vend_item
if #supply >= 1
#supply -= 1
self.update_sales(#cost) #getting error here
end
end
def update_sales(cost)
##total_sales += cost
end
def to_s
puts "Total Sales: #{##total_sales}\nName: #{#name}\nPrice: #{#price}\nSupply: #{#supply}"
end
attr_reader :name
attr_writer :name
attr_reader :price
attr_writer :price
attr_reader :vending_number
attr_writer :vending_number
def sales
##total_sales
end
end
class CandyBar < VendorFood
end
So essentially what I'm trying to do is be able to instantiate items without storing an instance of VendorFood. So this works if I remove the problematic line:
myBar = CandyBar.new("Hershey", 1.99, 101)
myBar.stock_item(17)
myBar.vend_item
myBar.to_s
But I want vend_item to then call update sales and increment it by the cost of the item.
This is the exact error message I get:
Traceback (most recent call last):
3: from main.rb:8:in <main>
2: from /mnt/c/users/price/onedrive/desktop/VendorFood.rb:17:in vend_item
1: from /mnt/c/users/price/onedrive/desktop/VendorFood.rb:22:in update_sales
/mnt/c/users/price/onedrive/desktop/VendorFood.rb:22:in `+': nil can't be coerced into Integer (TypeError)
Any help is appreciated.

Can I instantiate a class from a method within another class? (Ruby)

I've redone the question and included the full code for both files. In the touch_in method I am trying to instantiate a Journey class in the variable called 'journey'.
require_relative 'journey'
class Oystercard
MAXIMUM_BALANCE = 90
MINIMUM_BALANCE = 1
MINIMUM_CHARGE = 1
def initialize
#balance = 0
#journeys = {}
end
def top_up(amount)
fail 'Maximum balance of #{maximum_balance} exceeded' if amount + balance > MAXIMUM_BALANCE
#balance += amount
end
def in_journey?
#in_journey
end
def touch_out(station)
deduct(MINIMUM_CHARGE)
#exit_station = station
#in_journey = false
#journeys.merge!(entry_station => exit_station)
end
def touch_in(station)
fail "Insufficient balance to touch in" if balance < MINIMUM_BALANCE
journey = Journey.new
#in_journey = true
#entry_station = station
end
attr_reader :journeys
attr_reader :balance
attr_reader :entry_station
attr_reader :exit_station
private
def deduct(amount)
#balance -= amount
end
end
The Journey file is as follows:
class Journey
PENALTY_FARE = 6
MINIMUM_CHARGE = 1
def initialize(station = "No entry station")
#previous_journeys = {}
end
def active?
#active
end
def begin(station = "No entry station")
#active = true
#fare = PENALTY_FARE
#entry_station = station
end
def finish(station = "No exit station")
#active = false
#fare = MINIMUM_CHARGE
#exit_station = station
#previous_journeys.merge!(entry_station => exit_station)
end
attr_reader :fare
attr_reader :previous_journeys
attr_reader :entry_station
attr_reader :exit_station
end
I think that the 'touch_in' method should create a 'journey' variable that I called methods on, such as 'finish(station)' or 'active?' etc. When I attempt to do this in IRB I am given the following error:
2.6.3 :007 > journey
Traceback (most recent call last):
4: from /Users/jamesmac/.rvm/rubies/ruby-2.6.3/bin/irb:23:in `<main>'
3: from /Users/jamesmac/.rvm/rubies/ruby-2.6.3/bin/irb:23:in `load'
2: from /Users/jamesmac/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
1: from (irb):7
NameError (undefined local variable or method `journey' for main:Object)
I'm aware that much of the code above is sloppily written and there are probably other bits, beside the 'journey' issue, where it's just incorrect. Please let me know if this is the case, the more I'm told the better.
Apologies to anyone who attempted to help me on my first attempt, as I say I'm still getting used to SO and was trying to make the post easier to read.
class Journey
# ...
def initialize
puts "Journey initialized"
# ...
end
# ...
end
require_relative 'journey'
class Oystercard
def initialize
end
# ...
def touch_in(station)
journey = Journey.new
# ...
end
end
Oystercard.new.touch_in("station")
stack_question$ ruby oystercard.rb
Journey initialized
It works fine - are you having some issue with this that is beyond the scope of the question?

Cannot get a method instance to function; How to use an Each Do method in ruby?

I have an specific method that I would like to call so that I can see the balances for 'accounts'. The method is;
def report_balances(accounts)
accounts.each do |account|
puts account.balance
end
end
I am not sure but I have either built the above method incorrectly or I am calling it incorrectly or maybe I have placed the method correctly in my code.
class BankAccount
attr_reader :balance
def initialize(balance)
#balance = balance
end
def deposit(amount)
#balance += amount if amount >= 0
end
def withdraw(amount)
#balance -= amount if #balance >= amount
end
end
class SavingsAccount < BankAccount
attr_reader :number_of_withdrawals
APY = 0.0017
def initialize(balance)
super(balance) # calls the parent method
#number_of_withdrawals = 0 # then continues here
end
def end_of_month_closeout
if #balance > 0
interest_gained = (#balance * APY) / 12
#balance += interest_gained
end
#number_of_withdrawals = 0
end
def report_balances(accounts)
accounts.each do |account|
puts account.balance
end
end
end
I would like to see the balances of the objects:
my_account = SavingsAccount.new(100)
and
account = BankAccount.new(2500)
by calling
'report_balances(accounts)'
How would this be accomplished?
Think of my_account = SavingsAccount.new(100) as creating a new account, but what you're asking is I want to see all the balances of a list of accounts. Since each account has a balance, you can do:
[my_account, other_account].each do |account|
puts account.balance
end
I'd recommend moving your report_balances method to a class method or out of that class all together but that's a topic for a different discussion.

Having trouble with this exercise

I am working on Head First Ruby. Here is my code:
class Employee
attr_reader :name
def name=(name)
end
def print_name
puts "Name: #{name}"
end
end
class SalariedEmployee < Employee
attr_reader :salary
def salary=(salary)
# code to validate and set #salary
end
def print_pay_stub
print_name
pay_for_period = (salary / 365.0) * 14
formatted_pay = format("$%.2f", pay_for_period)
puts "Pay this period: #{formatted_pay}"
end
end
class HourlyEmployee < Employee
attr_reader :hourly_wage, :hours_per_week
def hourly_wage=(hourly_wage)
# code to validate and set #hourly_wage
end
def hours_per_week=(hours_per_week)
# code to validate and set #hours_per_week
end
def print_pay_stub
print_name
pay_for_period = hourly_wage * hours_per_week * 2
formatted_pay = format("$%.2f", pay_for_period)
puts "pay This Period: #{formatted_pay}"
end
end
I cannot get this exercise to work. I get this error:
employee.rb:42:in `print_pay_stub': undefined method `*' for nil:NilClass (NoMethodError)
from employee.rb:56:in `<main>'
Could someone look over this code and tell what is going wrong?
Edit: My mistake -- either hourly_wage or hours_per_week is nil. Make sure those are set.
It looks like salary is nil -- at least, that's the only line there with an *. You need to make sure salary is set
Edit: clarification
Edit 2: correction

Ruby: issues with an undefined method error

I am working on a ruby banking problem and I keep coming across this error when trying to write the code for the deposit method. I would like the deposit method to put out a puts statement saying this person has enough cash to make this deposit and state amount, or it states they do not have enough cash to deposit. It says this error in my irb:
NoMethodError: undefined method `<' for nil:NilClass
from banking2.rb:30:in `deposit'
from banking2.rb:59:in `<top (required)>'
Can someone please help me find my error? I've tried several options but am not able to figure it out.
class Person
attr_accessor :name, :cash_amount
def initialize(name, cash_amount)
#name = name
#cash_amount = #cash_amount
puts "Hi, #{#name}. You have #{cash_amount}!"
end
end
class Bank
attr_accessor :balance, :bank_name
def initialize(bank_name)
#bank_name = bank_name
#balance = {} #creates a hash that will have the person's account balances
puts "#{bank_name} bank was just created."
end
def open_account(person)
#balance[person.name]=0 #adds the person to the balance hash and gives their balance 0 starting off.
puts "#{person.name}, thanks for opening an account at #{bank_name}."
end
def deposit(person, amount)
#deposit section I can't get to work
if person.cash_amount < amount
puts "You do not have enough funds to deposit this #{amount}."
else
puts "#{person.name} deposited #{amount} to #{bank_name}. #{person.name} has #{person.cash_amount}. #{person.name}'s account has #{#balance}."
end
end
def withdraw(person, amount)
#yet to write this code
# expected sentence puts "#{person.name} withdrew $#{amount} from #{bank_name}. #{person.name} has #{person.cash_amount} cash remaining. #{person.name}'s account has #{#balance}. "
end
def transfer(bank_name)
end
end
chase = Bank.new("JP Morgan Chase")
wells_fargo = Bank.new("Wells Fargo")
person1 = Person.new("Chris", 500)
chase.open_account(person1)
wells_fargo.open_account(person1)
chase.deposit(person1, 200)
chase.withdraw(person1, 1000)
Change this in your initialize method on Person:
#cash_amount = #cash_amount
To this:
#cash_amount = cash_amount
You added an extra # sign, so you set #cash_amount to #cash_amount. The default value for an uninitialized instance variable is nil in Ruby.
The only place you have a < is in person.cash_amount < amount, so the error is coming from there - person.cash_amount is nil.
Look at where cash_amount is being defined in your Person initializer - you are passing in def initialize(name, cash_amount) but then you are calling #cash_amount = #cash_amount!
Remove the second # so you are actually assigning #cash_amount with the value you are passing in in cash_amount.

Resources