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.
Related
Have a problem, when run a code allways have error.
Expect: for the user add win or reduce his balance.
undefined method `balance=' for #<Dice:0x0000563d4d4dfd88 #name="foo", #balance=600, #bet=300>
Did you mean? balance
(repl):22:in `increase_decrease_cash'
(repl):62:in `<class:Game>'
(repl):29:in `<main>'
This error always comes out, retried everything I could guess, but nothing came of it and I don’t understand how it can be googled
class Dice
attr_accessor :name, :bet
attr_reader :balance
def initialize(name, balance, bet)
#name = name
#balance = balance
#bet = bet
end
def self.roll
#roll_dice = rand(1..2)
end
def self.check_bet
if #player.bet > #player.balance
puts "Enter number from 1 to #{#player.balance}"
end
end
def self.increase_decrease_cash
if #roll == #my_number
#player.balance += #player.bet
else
#player.balance -= #player.bet
end
end
end
class Game < Dice
#player = Dice.new("foo", 600, 0)
puts "Hello #{#player.name} your balance is: #{#player.balance}"
puts "Bones throwing count times"
a = 2 #gets.chomp.to_i
while a > 0 do
puts ""
puts "Enter your bet !!!"
# PLAYER BET
#player.bet = 300 #gets.chomp.to_i
check_bet
puts "Respected #{#player.name} your bet is: #{#player.bet}"
puts "Now select number 1-2"
# BONES ROLL
#my_number = roll # gets.chomp.to_i
puts "###################"
puts "Now we throw bones"
#roll = roll
puts "Nuber is #{roll}"
if #roll == #my_number
puts "Your win, you get #{#player.bet}"
else
puts "You lose #{#player.bet}"
end
p "$$$$"
p #player.balance
p "$$$$"
a -= 1
increase_decrease_cash
end
end
This error always comes out, retried everything I could guess, but nothing came of it and I don’t understand how it can be googled
attr_reader creates only the get method for balance. You need both get and set method for balance. Because you set balance in the initialize method. So, you should use attr_accessor instead of attr_reader.
attr_accessor :balance
class Account
attr_reader :name
attr_reader :balance
def initialize(name, balance=100)
#name = name
#balance = balance
end
public
def display_balance(pin_number)
if pin_number == pin
puts "Balance: $#{#balance}."
else
puts pin_error
end
end
def withdraw(pin_number,amount)
if pin_number == #pin
#balance -= amount
puts "Withdrew #{amount}."
else
puts pin_error
end
end
def deposit(pin_number,amount)
if pin_number ==#pin
#balance+=amount
puts"Deposited"
else
puts pin_error
end
end
private
def pin
#pin = 1
end
def pin_error
return "Access denied: incorrect PIN."
end
end
checking_account=Account.new("bob",200)
checking_account.deposit(1,20)
When i try deposit i get an error on pin, but when i remove the # in the pin checks and treat it as a normal variable it works. In codeacademy it shows that the correct way to check the pin is with
if pin_number==#pin
yet it doesn't work, even though it should, why is that?
pin_number==#pin will return false, because you never set #pin - so it will still be nil.
Instead of using a private method, you could do something like this:
def initialize(name, pin, balance=100)
#name = name
#pin = pin
#balance = balance
end
# ...
checking_account=Account.new("bob", 1, 200)
checking_account.deposit(1, 20)
yet it doesn't work, even though it should, why is that?
Because your #pin is never initialized. Something must be different between your code and what they have at codecademy (they likely initialize #pin in the initializer, which you do not).
but when i remove the # in the pin checks and treat it as a normal variable
Wrong.. This is not a variable. When you make it pin instead of #pin, it starts pointing to that private method of yours. Which returns a pin number. That's why it works.
Note that your code will work as-is, if you simply display_balance before making a deposit. This is called "call order dependency" and it's bad.
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.
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
I have the following code:
class Person
attr_reader :name, :balance
def initialize(name, balance=0)
#name = name
#balance = balance
puts "Hi, #{name}. You have $#{balance}!"
end
end
class Bank
attr_reader :bank_name
def initialize(bank_name)
#bank_name = bank_name
puts "#{bank_name} bank was just created."
end
def open_account(name)
puts "#{name}, thanks for opening an account at #{bank_name}!"
end
end
chase = Bank.new("JP Morgan Chase")
wells_fargo = Bank.new("Wells Fargo")
me = Person.new("Shehzan", 500)
friend1 = Person.new("John", 1000)
chase.open_account(me)
chase.open_account(friend1)
wells_fargo.open_account(me)
wells_fargo.open_account(friend1)
When I call chase.open_account(me) I get the result Person:0x000001030854e0, thanks for opening an account at JP Morgan Chase!. I seem to be getting the unique_id (?) and not the name I assigned to #name when I created me = Person.new("Shehzan", 500),. I've read a lot about class / instance variables and just can't seem to figure it out.
This is because you are passing an instance object assigned to the name variable. You have to do:
def open_account(person)
puts "#{person.name}, thanks for opening an account at #{bank_name}!"
end
Or:
wells_fargo.open_account(friend1.name)
Here you are passing an instance of Person, not a string.
chase.open_account(me)
You have to either pass me.name or modify open_account method to call Person#name like this
def open_account(person)
puts "#{person.name}, thanks for opening an account at #{bank_name}!"
end
You passing an object to the open_account method
You need to do
def open_account(person)
puts "#{person.name}, thanks for opening an account at #{bank_name}!"
end