简体   繁体   中英

Ruby - calculations with gets.chomp in a loop

I'm very new to Ruby. I've been trying to find a way to do calculations with user inputs. There are two things that I wanted to do:

  1. Output which friend has the most dinosaurs or jellyfish.
  2. Output which friend has the most dinosaurs and jellyfish combined.

I only have this loop requesting for user inputs so far:

f = "yes"

while f == "yes"
print "Enter your name: "
n = gets.chomp.to_f
print "Enter the number of dinosaurs you have: "
d = gets.chomp.to_f
print "Enter the number of jellyfish you have: "
j = gets.chomp.to_f
print "Another friend? (yes/no)"
f = gets.chomp
end

Any help is appreciated. Thank you so much!

UPDATES: Thank you so much for you all's help. I've realized that I was not specific enough. I'll try to clarify that here.

The output that I want looks something like this (things in ~ ~ are user inputs):

Enter your name: ~ Bob~
Enter the number of dinosaur you have: ~3~
Enter the number of jellyfish you have: ~6~
Another friend? (yes/no) ~yes~
Enter your name: ~ Sally~
Enter the number of dinosaur you have: ~2~
Enter the number of jellyfish you have: ~8~
Another friend? (yes/no) ~no~
Friend who has the most dinosaurs: Bob
Friend who has the most jellyfish: Sally
Friend who has the most dinosaurs and jellyfish combined: Sally

So far, the codes that I wrote only gets me to "Another friend? (yes/no)" but I'm not sure how to ask Ruby to output the last three lines that I want. Can you folks shed some light on this, please?

Thank you very much!

MORE UPDATES: Thanks for all of your help! Got it figured out with Hash and Array. Thank you!

The answer to your question is three-fold.

Collecting user input

gets returns a line from stdin, including the newline. If the user enters B o b enter then gets returns "Bob\\n" .

To strip the newline you use String#chomp :

"Bob\n".chomp #=> "Bob"

To convert an input like "3\\n" to an integer 3 , you can use String#to_i :

"3\n".to_i #=> 3

Note that to_i ignores extraneous characters (including newline), so you can avoid chomp .

Storing data

You probably want to store a user's data in one place. In an object-oriented programming language like Ruby, such "place" is often a class. It can be as simple as:

class User
  attr_accessor :name, :dinosaurs, :jellyfish
end

attr_accessor creates getters and setters, so you can read and write a user's attributes via:

user = User.new
user.name = 'Bob'
user.name #=> "Bob"

Since you don't want just one user, you need another place to store the users.

An Array would work just fine:

users = []

user = User.new
user.name = 'Bob'
user.dinosaurs = 3

users << user

users
#=> [#<User @name="Bob", @dinosaurs=3>]

Adding a second user:

user = User.new     # <- same variable name, but new object
user.name = 'Sally'
user.dinosaurs = 2

users << user

users
#=> [#<User @name="Bob", @dinosaurs=3>, #<User @name="Sally", @dinosaurs=2>]

Retrieving the users (or their attributes) from the array:

users[0]      #=> #<User @name="Bob">
users[0].name #=> "Bob"
users[1].name #=> "Sally"

Calculating with data

Array includes many useful methods from the Enumerable mixin.

To get an element with a maximum value there's max_by – it passes each element (ie user) to a block and the block has to return the value you are interested in (eg dinosaurs ). max_by then returns the user with the highest dinosaurs value:

users.max_by { |u| u.dinosaurs }
#=> #<User @name="Bob">

You can also calculate the value:

users.max_by { |u| u.dinosaurs + u.jellyfish }

But that would currently result in an exception, because we did not set jellyfish above.

Right now you're trying to turn the name into a float (number) by calling to_f on it. It's already a string when it's coming in from the user, and should probably stay a string.

Also, you're currently overwriting each of your variables in every iteration of your loop. So if Bob fills this out, and wants to add a friend, Sally, all of Bob's information is overwritten by Sally's.

Instead, you'll need to create a Hash or Array, then add each user to it one by one from your loop.

continue = "yes"
users = {}

while continue == "yes"
print "Enter your name: "
name = gets.chomp.to_f
print "Enter the number of dinosaurs you have: "
dinosaursCount = gets.chomp.to_f
print "Enter the number of jellyfish you have: "
jellyfishCount = gets.chomp.to_f

users[name] = {dinosaurs: dinosaursCount, jellyfish: jellyfishCount}

print "Another friend? (yes/no)"
continue = gets.chomp
end

Now if Bob and Sally have both been added through the command line, you can get their data by doing:

users.Bob #{dinosaurs: 10, jellyfish: 10}
users.Bob.dinosaurs #10
users.Bob.jellyfish #10

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM