I'm a newb Ruby user using Ruby version 2.1.5p273 and below I created an Atm simulator program that takes user input of deposits and withdrawals, and then it displays the balance after. I am struggling with ifs, elses and loops. I want to put a decision making statement in the beginning, that asks if the user wants to withdraw, deposit, check balance, or end your session. I also want to put a decision making statement in the end, that asks if the user wants to continue (which would go back to the beginning, or end the session). My general idea of what I want it to look like would be below, the overall program is below the idea code. I know it's wrong but it's just what I want it to look like, so any help in making it into correct and working code would be greatly appreciated.
print "Would you like to (w)ithdraw, (d)eposit, or (c)heck your balance or (e)nd your session?
if "(w)ithdraw" # i'd like to make this do a "press w for withdraw"
bank_account.withdraw
elsif "(d)eposit" # i'd like to make this do a "press d for deposit"
bank_account.deposit
elsif "(c)heck your balance" # i'd like to make this do a "press c to check your balance"
bank_account.show_balance
elseif "(e)nd your session" # i'd like to make this do a "press e to end your session"
end
#This program is an ATM simulator, it takes user input of deposits and withdrawals, and then displays the balance after.
class BankAccount
def initialize(name)
#transations = []
#balance = 0
end
def deposit
print "How much would you like to deposit? "
amount = gets.chomp
#balance += amount.to_f
puts "$#{amount} deposited."
end
def withdraw
print "How much would you like to withdraw?"
amount = gets.chomp
#balance -= amount.to_f
puts "#{amount} withdrawn"
end
def show_balance
puts "Your balance is #{#balance}"
end
end
bank_account = BankAccount.new("Justin G")
bank_account.class # => BankAccount
print "Welcome to Jay's ATM!\n"
bank_account.deposit
bank_account.show_balance
bank_account.withdraw
`enter code here`bank_account.show_balance
puts "Thank you"
This is fairly rudimentary but should get you started. Please let me know if you have additional questions on what I'm doing in the code. For the most part it should be fairly self-explanatory if you're familiar with other object-oriented programming languages.
Here's your ATM:
# atm.rb
require './bank_account.rb'
cmd = ""
account = BankAccount.new("Justin G")
puts "***Welcome to #{account.name}'s ATM***\n\n"
while cmd != "e" do
puts "Would you like to (w)ithdraw, (d)eposit or (c)heck your balance?"
puts "You can also (e)nd your session."
cmd = gets.chomp
case cmd
when "w"
puts "How much would you like to withdraw?"
amount = gets.chomp # expect this to be a float
# handle incorrect input somehow, either here or
# preferably in the BankAccount#withdraw method
account.withdraw(amount)
when "d"
puts "How much would you like to deposit?"
amount = gets.chomp # expect this to be a float
# handle incorrect input somehow, either here or
# preferably in the BankAccount#deposit method
account.deposit(amount)
when "c"
puts "Your balance is $%.2f\n" % account.balance
else
# didn't understand the command
puts "Didn't understand your command. Try again." unless cmd == "e"
end
end
Here's the bank account code:
# bank_account.rb
class BankAccount
attr_reader :name, :balance
def initialize(name)
#name = name
#transactions = []
#balance = 0.0
end
def withdraw(amount)
# TODO: check that amount is valid, else error
#balance -= amount.to_f
# TODO: check if sufficient funds available
puts "$%.2f successfully withdrawn.\n" % amount
end
def deposit(amount)
# TODO: check that amount is valid, else error
#balance += amount.to_f
puts "$%.2f successfully deposited.\n" % amount
end
end
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.
My RNG guessing game seems to generate a new number constantly, and not save the number for the current session of the game for the player to guess.
def initialize
##answer = rand(1..100).to_s
end
def answer
##answer
end
def guessing
puts "What's your guess?"
##guess = gets.chomp.downcase
while ##guess != answer
wrong_answer
end
right_answer
end
I don't see any problem with your code, but it could be the way are initializing the class (if you are calling guessing explicitly everytime you want to make a guess).
You need to store the initialized class in a variable:
guess = Guess.new
guess.guessing
guess.guessing
Also you don't want to use class instance variables unless necessary i.e, use #guess, #answer instead of ##guess and ##answer.
Another way
def guessing
puts "What's your guess?"
#guess = gets.chomp.downcase
while #guess != answer
puts "wrong_answer"
#guess = gets.chomp.downcase
end
puts "right_answer"
end
I think if you store the random number in an attr_reader, you can then reference it and compare it to the guess. If you store the guess in an attr_accessor, you can compare the guess to the stored random number and have the User continue the game by updating their guess until it matches the random number. I can include an example that you can copy and paste right into IRB. To start the game just call PlayGame.new and you are off and running. Enter cheat for the random number and hint for a hint.
class RandomNumber
attr_reader :number
def initialize
#number = rand(1..100).to_s
end
def hint
random_number = number.to_i
puts case
when random_number >= 75
"Your number is in the range of 75 to 100"
when random_number >= 50
"Your number is in the range of 50 to 74."
when random_number >= 25
"Your number is in the range of 25 to 49"
else random_number > 0
"Your number is 24 or less."
end
end
end
class PlayGame
attr_accessor :input
attr_reader :number
def initialize
#generate_number = RandomNumber.new
#number = #generate_number.number
puts "What's your guess?"
#input = gets.chomp.downcase
validate
end
def validate
case
when input == number
puts "You win!"
when input == "cheat"
puts "The number is #{number}"
get_guess
when input == "hint"
#generate_number.hint
get_guess
else
get_guess
end
end
def get_guess
puts "Try again, what's your guess?"
#input = gets.chomp.downcase
validate
end
end
def account()
puts "ENTER ACCOUNT NUMBER"
accountnumber = gets.chomp
puts "SUCCESS"
modeselect()
end
def modeselect()
puts "WHAT WOULD YOU LIKE TO DO?"
mode = gets.chomp
mode.upcase!
case mode
when "DEPOSIT"
deposit()
else
account()
end
end
def deposit()
balance = 0
puts "ENTER DEPOSIT AMOUNT"
depositamount = gets.chomp.to_i
balance == balance + depositamount
puts "DEPOSIT SUCCESSFUL, BALANCE = #{balance}"
modeselect()
end
account()
Currently, the code completes the deposit however when the deposit method is run again the balance is reset, I'm trying to make it follow across from the last time it was run, so the balance is permanently updated after each deposit.
How can I do this? Thanks.
There are three reasons why the balance seems as though it is being reset.
The first is that the balance is being stored in a variable whose scope is contained within the the deposit functions block. This means that whatever value that variable has when the function finishes will not be retained. In fact the variable is no longer accessible. You can use an instance variable as suggested by Sergio using #balance
Secondly. The balance is being explicitly set to 0 immediately after the deposit function block is entered. An option to fix this is to only assign #balance a value of 0 if it has not already been assigned a value. You can do this using #balance ||= 0
Thirdly. The operator on the fourth line of the deposit function block == is a comparison operator not an assignment operator. I believe what you intend is to use =.
def account()
puts "ENTER ACCOUNT NUMBER"
accountnumber = gets.chomp
puts "SUCCESS"
modeselect()
end
def modeselect()
puts "WHAT WOULD YOU LIKE TO DO?"
mode = gets.chomp
mode.upcase!
case mode
when "DEPOSIT"
deposit()
else
account()
end
end
def deposit()
#balance ||= 0
puts "ENTER DEPOSIT AMOUNT"
depositamount = gets.chomp.to_i
#balance = #balance + depositamount
puts "DEPOSIT SUCCESSFUL, BALANCE = #{#balance}"
modeselect()
end
account()
If you do not want to use instance variable such as #balance, you may need to pass the variable balance when calling your methods/functions to "retain" value. Something like this (note that this code works but has severe flaws)
def account()
balance ||= 0
puts "ENTER ACCOUNT NUMBER"
accountnumber = gets.chomp
puts "SUCCESS"
modeselect(balance)
end
def modeselect(balance)
puts "WHAT WOULD YOU LIKE TO DO?"
mode = gets.chomp
mode.upcase!
case mode
when "DEPOSIT"
#balance ||= 0
deposit(balance)
else
account()
end
end
def deposit(balance)
puts "ENTER DEPOSIT AMOUNT"
depositamount = gets.chomp.to_i
balance = balance + depositamount
puts "DEPOSIT SUCCESSFUL, BALANCE = #{balance}"
modeselect(balance)
end
account()
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.