storing user input to an empty hash - ruby

I'm writing a basic program. I am starting out with an empty hash, and using gets.chomp and want to store the info into the hash so that it can be recalled later (in the same session).
runs = {}
puts "how many miles did you run?"
miles = gets.chomp
puts "how long did it take you?"
time = gets.chomp
... program continues
Later I would like to have the user enter 'review' to display this (and any others that were entered) as information:
runs.each do |miles, time|
puts "#{miles} miles in #{time} minutes."
end
I know I am missing something before/after the "gets.chomp". Any suggestions?

To add a key value pair to a hash, you would use runs[miles] = time.
So your code would look something like this:
runs = {}
puts "How many miles did you run?"
miles = gets.chomp
puts "How long did it take you?"
time = gets.chomp
runs[miles] = time
# When user enters `review`
runs.each do |miles, time|
p "#{miles} miles in #{times} minutes."
end
That's not the only way to add a key/value pair to a hash, so you can look at all the methods available over in the rubydoc.

As your program is written, if a user ran the same distance twice (with different times) only the last result will be recorded, as a hash cannot store duplicate keys. A better way would be to store it in an array of tuples (== array with two values):
runs = []
puts "How many miles did you run?"
miles = gets.chomp
puts "How long did it take you?"
time = gets.chomp
runs << [miles, time]
# ...
runs.each do |miles, time|
puts "#{miles} miles in #{time} minutes."
end

runs = Hash.new
puts "How many miles did you run?"
runs ["miles"] = gets.chomp
puts "How long did it take you?"
runs ["time"] = gets.chomp
# When user enters `review`
runs.each do |miles, time|
p "#{miles} miles in #{times} minutes."
end

Related

Not able to iterate properly over hash in my continuous input program (Ruby)

I am trying to see if I can create a list of user input requests with a hash in this program I am trying to create. Whats the best way to go about this?
print "would you like to begin a changeover? (y/n) "
input = gets.chomp
tracking = {
"start time" => input.Time.now,
"Type?" => input,
"shift?" => input,
"standard hrs?" => input,
"actual hrs?" => input,
"end time" => input = gets.chomp.Time.now
}
tracking.each do |key, value|
puts "great please answer the following: #{tracking}"
end
thanks in advance!
You have to remember that the evaluation is sequential, going from top to bottom (unless you are defining functions/methods). In your code:
You ask the user about a changeover
You get user input (say, y) into the variable input
You make a hash, with six values; four of them will contain y, two of them will contain current time
You iterate over the hash, printing its values (and asking the user nothing).
Or at least it would if gets.chomp.Time.now was not an error.
So, taking care about the timing:
print "would you like to begin a changeover? (y/n) "
unless gets.chomp.tolower == 'n'
puts "great please answer the following:"
tracking = {
"start time" => Time.now
}
[
"Type?",
"shift?",
"standard hrs?",
"actual hrs?"
].each do |question|
print question
tracking[question] = gets.chomp
}
tracking["end_time"] = Time.now
end
Thanks Alot! This set me on the right track. However, was not time stamping the beginning and end of the questionnaire the way I wanted. After playing with the code a bit on my own however, I was able to make it work.
print "would you like to begin a changeover? (y/n) "
unless gets.chomp. == "n"
puts Time.now
puts "great please answer the following: "
end
questionnaire = ["Type", "Shift?", "Standard hrs?", "Actual hrs?"]
.each do |question|
puts question
questionnaire = gets.chomp
end
puts "Please type 'done' when change over complete"
input = gets.chomp
puts Time.now

Trouble summing an array in vanilla Ruby

I'm having trouble summing an array. Here's my existing code:
pageArray = Array.new
puts "How many pages long is the book you're reading?"
pageArray << gets.chomp
puts "Are you reading any other books right now?"
yn = gets.chomp
while yn != "no" do
puts "How many pages long is your next book?"
pageArray << gets.chomp
puts "Are you reading any other books right now?"
yn = gets.chomp
end
pageSum = pageArray.reduce(:+)
puts pageSum
When I go through and enter the values 100 and 50, the final return is "10050," rather than "150." Am I missing something obvious?
The code could be written more clearly, and more Ruby-like. Here's some untested code that is more idiomatic:
page_array = []
puts "How many pages long is the book you're reading?"
page_array << gets.chomp
loop do
puts 'Are you reading any other books right now?'
yn = gets.chomp.downcase
break if yn == 'no'
puts 'How many pages long is your next book?'
page_array << gets.chomp.to_i
end
page_sum = page_array.reduce(:+)
puts page_sum
Notice:
variables in Ruby are in snake_case, notInCamelCase.
loop do will loop forever. Simply break when you've received the break value.
you should fold the case of the value used as a break to catch variations in 'y' and 'Y'.
take the time to format your code so it's easily read, even for quick tests. It's amazing how often code we think is just a test actually gets put into production, so do it right the first time.
You are entering strings and concatenating them.
Use gets.chomp.to_i
You need to change the string you get from gets to an int.
pageArray << gets.chomp.to_i

rounding off to the nearest number ruby

def percent_more
puts "What is the biggest number?"
biggest_number = gets.chomp
puts "What is the smallest number?"
smallest_number = gets.chomp
difference = biggest_number.to_i - smallest_number.to_i
total_percent_more = difference / smallest_number.to_f
puts "Your biggest number is #{total_percent_more}% bigger then your smallest number. Don't forget to round off to the nearest whole percent!"
end
Now that code will tell you what percent more biggest_number is than smallest_number. But the problem is it prints out a long list of decimals, which are a pain to sort through. So if I wanted the code to only show say the first 3 numbers what would I do??
What you want to use is total_percent_more.round like so:
puts "What is the biggest number?"
biggest_number = gets.chomp
puts "What is the smallest number?"
smallest_number = gets.chomp
difference = biggest_number.to_i - smallest_number.to_i
total_percent_more = difference / smallest_number.to_f
puts "Your biggest number is #{total_percent_more.round}% bigger then your smallest number. Don't forget to round off to the nearest whole percent!"
See the docs for more info :
http://www.ruby-doc.org/core-2.1.2/Float.html#method-i-round
in ruby versions earlier than 1.9 you'll need to use sprintf like so:
puts "Your biggest number is #{sprintf('%.2f', total_percent_more)}% bigger then your smallest number. Don't forget to round off to the nearest whole percent!"
You can change the amount of decimal places by changing the number.
See docs for more details:
http://www.ruby-doc.org/core-1.8.7/Kernel.html#method-i-sprintf
result = 10/6.0
puts result
printf("%.3f\n", result)
--output:--
1.66666666666667
1.667
Here is an example how to round to 2 decimal places
amount = 342
puts amount.round(2)
If you wanted to round to the nearest 3 decimal places then something like:
puts amount.round(3)

Ruby - Random Number is the Same Random Number, Every Time

wordList = ['1930', '1931', '1932', '1933', '1934', '1935', '1936', '1937', '1938', '1939', '1940']
wordLen = wordList.length
wordRand = rand(wordLen)
year = wordList[wordRand]
Very much a newb here... The behavior of year is such that every time I run the program, it selects a random string from wordList. The problem is that it takes that particular randomly-selected number and sets it as equal to year. So, for every instance of the program, year is the same string from the list each time I call it. How can I get it to select a different number each time?
puts 'Why hello there, dear! Grandma is, SO, happy to see you!'
response = gets.chomp
while response != 'BYE'
if response == response.upcase
puts 'NO, NOT SINCE ' + year + '!'
response = gets.chomp
else
puts 'WHAT? SPEAK UP, SONNY!'
response = gets.chomp
end
end
if response == 'BYE'
puts 'OKAY, BYE DEAR!!'
end
edit: added context
You appear to only be generating one value for year, then repeatedly using it in your loop. If you want different numbers, put the call to rand within the loop.

How do I capitalize the first letter in an array of strings using method capitalize?

I created a simple program to ask a sports fan about some info. Here is the code I have so far:
puts "What's your favorite pro sport?"
favorite_sport = gets.chomp
puts "Who's your favorite team in the #{favorite_sport}?"
favorite_team = gets.chomp
puts "What city are they from?"
team_city = gets.chomp
puts "Who's your favorite player in the #{favorite_team} roster?"
favorite_player = gets.chomp
puts "What position does #{favorite_player} play?"
player_position = gets.chomp
puts "How many years has #{favorite_player} played in the #{favorite_sport}"
years_experience = gets.chomp
fan_info = [favorite_sport, favorite_team, team_city, favorite_player, player_position, years_experience]
puts fan_info
I want to have the program output the fan_info with the first letter of the string capitalized. How do I do this? I know I have to use the method capitalize but I am having trouble implementing this.
Here is an example of the input and output:
What's your favorite pro sport?
NFL
Who's your favorite team in the NFL?
Seahawks
What city are they from?
seattle
Who's your favorite player in the Seahawks roster?
wilson
What position does wilson play?
qb
How many years has wilson played in the NFL
1
NFL
Seahawks
seattle
wilson
qb
1
Try this:
puts fan_info.map(&:capitalize)
This calls #capitalize on every string, builds a new array of all the results, and prints that out instead.
It's equivalent to something like this:
fan_info_capitalized = []
fan_info.each do |inf|
fan_info_capitalized << inf.capitalize
end
puts fan_info_capitalized
Only much more compact.
If your intention is to capitalize the first letter keeping the other letters intact (i.e., "NFL" stays to be "NFL", and does not become "Nfl"), then do:
favorite_sport = gets.chomp.sub(/./, &:upcase)
...

Resources