I'm working on Chris Pine's Ruby tutorial. I have to write a cheat method that allows me to set which side of the die I want to show: https://pine.fm/LearnToProgram/?Chapter=09
I have two instance variables: #numberShowing and #numberCheat. #numberCheat receives an input from the user and I want to set #numberShowing to take the value of #numberCheat. However, #numberShowing always outputs some random number. Any tips?
Here's my code so far:
class Die
def initialize
roll
end
def roll
#numberShowing = 1 + rand(6)
end
def showing
#numberShowing
end
def cheat
puts "cheat by selecting your die number between 1 and 6"
#numberCheat = gets.chomp
end
#numberShowing = #numberCheat
end
puts Die.new.cheat
puts Die.new.showing
Thanks!
Move #numberShowing = #numberCheat into the cheat method. But your test is not going to prove it worked. Try something like:
die = Die.new
puts "Currently showing #{die.showing}"
puts "Cheating to change showing number to #{die.cheat}"
Related
I am making a ruby cli that outputs a list of game deals scraped from a site.
The list prints out promptly using
def games_sales
Deal.all.each_with_index do |deal, index|
puts "#{index + 1}. #{deal.title}"
end
puts "What game do you want to see?"
input = gets.strip
game_selection(input.to_i)
end
My problem comes when asking the user to select an item from the list.
def game_selection(input)
deal = Deal.find_by_index(input)
#binding.pry
deal.each do |deal|
puts "#{deal.index}"
puts " Name: #{deal.title}"
puts " Price: #{deal.price}"
puts " Store: #{deal.store}"
puts " Expiration: #{deal.expiration}"
end
deal
end
It returns the int input but only the first item on the list every time.
I forgot my find_by_index method:
def self.find_by_index(input)
all.select do |deal|
end
end
which is incomplete
Not 100% sure if I got your question right and if you're using Rails, but Deals.all let me think of this.
I had to replace Deals.all with DEALS for testing as I haven't got a rails app running. So I used an Array of OpenStructs to fake your Model result.
# this fakes Deals.all
require 'ostruct'
DEALS = [
# add any more properties the same way as title, separated by comma
OpenStruct.new(title: 123),
OpenStruct.new(title: 456)
]
def games_sales
DEALS.each_with_index do |deal, index|
puts "#{index + 1}. #{deal.title}"
end
puts "What game do you want to see?"
input = gets.strip
game_selection(input.to_i)
end
def game_selection(input)
deal = DEALS.at(input-1)
p deal[:title]
end
def self.find_by_index(input)
all.select do |deal|
deal.index == input
end
end
games_sales
Result when choosing 1 is 123, choosing 2 you'll get 456, due to p deal[:title] above in the code.
I think your find_by_index need to get the right index and in my example I had to use at(index) as at(input-1) in order to get the right result.
I really hope this helps somehow and I suggest that you add the expected result to your question, in case my answer does not help you.
So I've been messing around with Ruby for the first time after finishing the codecademy course up to "Object Oriented Programming, Part I" and I decided to start making a calculator. For some reason though, I get this error:
calc.rb:13:in `addition': undefined local variable or method `user_input' for main:Object (NameError)
from calc.rb:21:in `<main>'
I'm confused why it doesn't see my "user_input" array. Is it out of the scope of the method? Did I initialize it wrong?
Here's the code so you can see for yourself, it's obviously nothing sophisticated and it's not finished. I'm just trying to test for addition right now.
#!/usr/bin/env ruby
user_input = Array.new
puts "Would you like to [a]dd, [s]ubtract, [m]ultiply, or [d]ivide? "
type_of_math = gets.chomp
def addition
operator = :+
puts "Please enter the numbers you want to add (enter \"=\" to stop adding numbers): "
until gets.chomp == "="
user_input << gets.chomp.to_i
end
sum = user_input.inject(operator)
return sum
end
case type_of_math
when "a"
addition
when "s"
puts "Test for subtraction"
when "m"
puts "Test for multiplication"
when "d"
puts "Test for division"
else
puts "Wrong"
end
Consider this untested variation on your code. It's more idiomatic:
def addition
user_input = []
puts 'Please enter the numbers you want to add (enter "=" to stop adding numbers): '
loop do
input = gets.chomp
break if input == '='
user_input << input
end
user_input.map(&:to_i).inject(:+)
end
Notice that it puts user_input into the method. It also uses the normal [] direct assignment of an empty array to initialize it. Rather than chomp.to_i each value as it's entered it waits to do that until after the loop exits.
Instead of while loops, consider using loop do. They tend to be more easily seen when scanning code.
Also notice there's no return at the end of the method. Ruby automatically returns the last value seen.
I have some code that won't add two numbers. What have I done wrong?
class Add
##starting_value = 5
def self.Adding
puts "How much do you want to add? "
user_choice = gets.to_i
user_choice + ##starting_value
puts "new value is"
puts ##starting_value
end
end
The problem is this line:
user_choice + ##starting_value
That adds the two values and then throws out the answer. You need to store the answer in a variable:
##starting_value = user_choice + ##starting_value
Ruby has a special shortcut for this
##starting_value += user_choice
I highly recommend reading the Pickaxe book. I assume you already have a Ruby implementation installed on your computer.
Create a file called, say, add.rb. I would try to keep things as simple as possible:
class Add
#amount = 5
def self.add
puts "How much do you want to add?"
puts "New value is #{#amount + gets.to_i}"
end
end
Add.add # add is a class method
Then run it with ruby app.rb. The output should be something like:
How much do you want to add?
100
New value is 105
am learning ruby and i had come across this particular issue.
I have method which reads the user input data into an array and i have another method which displays the values in the same array to the user with some processing.
However this doesnt seem to be the correct way as the system always throws a
Arraypass.rb:23:in <main>': undefined local variable or methodnames' for main:Object (NameError)
Appreciate if someone can show a way forward in this,
for example:
class School
def askdetails
print "How many students are there"
n=(gets.chomp.to_i - 1)
print "Enter names one by one"
names=Array.new(n)
for i in (0..n)
names[i]=gets.chomp
end
return names,n
end
def showdetails(names,n)
for i in (0..n)
puts names[i]
end
end
end
stud=School.new
stud.askdetails
stud.showdetails(names,n)
Write the code as
#!/usr/bin/env ruby
class School
def askdetails
print "How many students are there"
n = gets.chomp.to_i - 1
print "Enter names one by one"
names = Array.new(n)
for i in (0..n)
names[i]=gets.chomp
end
return names,n
end
def showdetails(names,n)
for i in (0..n)
puts names[i]
end
end
end
stud = School.new
names, n = stud.askdetails
stud.showdetails(names,n)
The thing, you missed is #askdetails methods returning an Array, which you didn't assign any where before using those.
Read Array Decomposition, this is what I did here :
names, n = stud.askdetails
here is your answer:
names,n = stud.askdetails
stud.showdetails(names,n)
I've been sifting through the prior questions and answers on stackoverflow, and I have gotten most of my question figured out. I figured out that I can't place a function call within a hash, without placing it within a proc, or a similar container.
What I'm ultimately trying to do is have a menu displayed, grab user input, and then iterate through the hash, and run the specified function:
def Main()
menu_titles = {"Answer1" => Proc.new{Choice1()}}
Menu(menu_titles)
end
def Choice1()
puts "Response answer"
end
def Menu(menu_titles)
menu_titles.each_with_index do |(key, value),index|
puts "#{index+1}. #{key}"
end
user_input = 0
menu_titles.each_with_index do |(key, value), index|
if index.eql?(user_input)
menu_titles[value]
break
end
end
end
Main()
The issue I'm having right now is that I'm not entering the functions that my hash calls for. Whether I use a return or a "puts", I either get a blank line or nothing at all. If anyone has other recommendations about my code, I'm all ears also. To be honest, I don't like using procs, but that's mostly because I don't entirely know how they work and where to use them.
Right now for my menus I have:
user_input = 1
if user_input == 1
Choice1()
...
end
Here's how I would refactor this:
class Menu
attr_reader :titles
# initialize sets up a hard-coded titles instance variable,
# but it could easily take an argument.
def initialize
#titles = {
"Answer1" => Proc.new{ puts "choice 1" },
"Answer2" => Proc.new{ puts "choice 2" }
}
end
# This is the only public instance method in your class,
# which should give some idea about what the class is for
# to whoever reads your code
def choose
proc_for_index(display_for_choice)
end
private
# returns the index of the proc.
def display_for_choice
titles.each_with_index { |(key,value), index| puts "#{index + 1}. #{key}" }
gets.chomp.to_i - 1 # gets will return the string value of user input (try it in IRB)
end
# first finds the key for the selected index, then
# performs the hash lookup.
def proc_for_index(index)
titles[titles.keys[index]]
end
end
If you're serious about Ruby (or object-oriented programming in general), I would highly recommend learning about the advantages of packaging your code into behavior-specific classes. This example allows you to do this:
menu = Menu.new
proc = menu.choose
#=> 1. Answer1
#=> 2. Answer2
2 #(user input)
proc.call
#=> choice 2
And you could actually run it on one line:
Menu.new.choose.call