What I am trying to do is tell the your how many years they have left till there 21. I have been trying to think of it but nothing.
Here is my code:
#!/usr/bin/env ruby
under_age = 21
print "What is your first name? "
first_name = gets.chomp
print "What is your last name? "
last_name = gets.chomp
print "What is your age? "
user_age = Integer(gets.chomp)
if user_age < legal_age
print "You may not continue"
else if > 21
print "Welcome!"
You set this at the beginning:
under_age = 21
But then you don't use it, you use legal_age I think if you change the first line to
legal_age = 21
and then drop the last less-than like:
if user_age < legal_age
years_to_wait = 21 - user_age
print "You may not continue, come back in #{years_to_wait} year#{years_to_wait > 1? 's' : ''} "
else
print "Welcome!"
end
I added a little bit there that you may have not covered being new to Ruby. Just to be clear:
#{years_to_wait} inside of a double quote string (" vs ') prints out as the value of the variable. If the variable is 1, then the response would be the singular "year", if greater than 1 it would be plural "years". I used the very compact version of if/then/else to make it clean (called the Ternary operator).
The first part is the comparison followed by the ? for an implied "if"
years_to_wait > 1?
followed by the return value if true which is the character 's' then a ":" and the return value if false, no character ''. That gets us the correct version of the word "year(s)" when the interpolation happens.
Your variable names are all over the place. But I think you just want
legal_age - user_age
Also your last if is unnessary
You miss the variable in the elsif statement in ruby it should look:
if user_age < 21
print "You may not continue"
elsif user_age > 21
print "Welcome!"
end
the legal_age variable is also not assigned, maybe you mean the under_age variable instead.
your if..else syntax is not proper. for more info
if user_age < under_age
print "You may not continue, come back after #{under_age - user_age} years"
else
print "Welcome!"
end
Note: legal_age is also not assigned, you can replace it with under_age or change under_age to legal_age
Related
I want to do something like that.
puts "Please write your age: "
age = gets.chomp
if #{age}<18
puts "you are illegal"
else #{age}>18
puts "You are legal"
end
the output i get is:
"Please write your age"
15.
you are illegal
you are legal"
and this
"Please write your age
20
you are illegal
you are legal"
Why?
And what is the solution please?
What I expect is this
If I write 19 or older, it will say "you are legal"
And if I write 17
or any number below
It will tell me "You are illegal"
Welcome to StackOverflow.
#{} is used for string interpolation, you don't need it there, and else statements don't work like this (elsif does). You also need to convert the string to an integer. You could write it like this:
puts "Please write your age: "
age = gets.chomp.to_i
if age > 18 # Since you want 19 or older. You could use age > 17 or age >= 18 if you actually meant 18 or older.
puts "You are of legal age"
else
puts "You are not of legal age"
end
See
The problem is that your code is equivalent to:
puts "Please write your age: "
age = gets.chomp
if
puts "you are illegal"
else
puts "You are legal"
end
Because # starts a comment, that makes the interpreter ignore everything after it on that line.
You can use any of the suggestions in the other answers to fix the code.
age = gets.chomp.to_i
if age<18
... to get integer-to-integer comparison.
You should first convert the input type to Integer and then make your logic. Note that is also important to check if the string input is numeric (since to_i returns 0 on cases like 'a'.to_i). You can do that like so:
puts 'Please write your age: '
# strip removes leading and trailing whitespaces / newlines / tabs
age = gets.strip
unless age.to_i.to_s == age
puts 'Age must be a number'
exit
end
age = age.to_i
if age < 18
puts 'you are illegal'
else
puts 'You are legal'
end
I am trying to loop until user inputs an integer. When user inputs a letter, the following code should print "Think of a number":
print "Think of a number "
while user_input = gets.to_i
if user_input.is_a? Integer
puts "your number is #{user_input}"
break
else
print "Think of a number "
end
end
I succeeded with my code when user inputs an integer. However when user inputs a string, the to_i method returns 0, and does not execute the else statement because it is a number.
The main issue with your code is String#to_i method is omnivorous.
"0".to_i #⇒ 0
"0.1".to_i #⇒ 0
"foo".to_i #⇒ 0
That said, user_input in your code is always integer.
What you probably want is to accept digits only (and maybe a leading minus for negatives.) The only concise way to accept a subset of characters is a regular expression.
# chomp to strip out trailing carriage return
user_input = gets.chomp
if user_input =~ /\A-?\d+\z/
...
The regular expression above means nothing save for digits with optional leading minus.
Or, even better (credits to #Stefan)
if gets =~ /\A-?\d+\Z/
If you only want to accept postive digits, you can use a range:
user_input = gets.chomp
if ('0'..'9').cover? user_input
let check below one used Integer(gets.chomp) rescue ''
print "Think of a number "
while user_input = Integer(gets.chomp) rescue ''
if user_input.is_a? Integer
puts "your number is #{user_input}"
break
else
print "Think of a number "
end
end
I came across a similar problem. I ended up doing this:
if user_input.strip == user_input.to_i.to_s
# More code here!
end
Testing for float would be:
if user_input.strip == user_input.to_f.to_s
# More code here!
end
Solved my issue. See if it helps.
So as I ask for in the title. How do I make a loop that breaks when the user has entered some values that contain only number, and if not it will say try again.
prompt = "> "
puts "What is the salary for the accountant: "
print prompt
while accountant = gets.chomp
if accountant == (0..9)
puts "Nice"
break
else
"try again"
print prompt
end
end
end
A simple solution with no regex would be:
accountant.chars.all?{|n| ("0".."9") === n}
You may want to read about the "===" operator in Ruby if you don't how it works yet as it may be confusing if you come from PHP or Javascript.
What does the "===" operator do in Ruby?
Your problem is in this line:
if accountant == (0..9)
This is checking whether the value is equal to a range - which is not what you wanted.
Since the input from gets.chomp will always be a string, you need to check whether it only contains the characters: "0", "1", "2", ... and "9".
One way to do this is with a regular expression:
if accountant =~ /\A\d+\z/
\A means "start of string"
\z means "end of string"
\d+ means "one or more digit" (0-9)
Note that the solution you suggested in the comments, /^-?[0-9]+$/, is flawed since:
^ means "start of line" (so it would be possible to insert arbitrary other characters before a newline)
$ means "end of line" (so it would be possible to insert arbitrary other characters after a newline)
-? also allows an optional hyphen character. Which is presumably not what you want in this context, since the input is a salary - which surely cannot be negative!
This is my first programming language so please bear with me!
I can't quite figure out where it's going wrong. I'm not necessarily asking for a solution as this is a learning exercise; I just need a helping hand as to where I should be looking.
#Calculate the sum of two numbers and an optional third
#get first number
print "Please enter your first digit: "
value_1 = gets.chomp
print value_1
#get second number
print "Please enter your second digit: "
value_2 = gets.chomp
#get the additional number
print "Do you want to add an additional number?"
add_num_req = gets.chomp
#calculate result and put
if gets.chomp = "yes" || "Yes" || "YES"
print "Please enter the additional digit: "
add_num_1 = gets.chomp
#print sum of three values
print "Answer: " , (value_1.to_i + value_2.to_i + add_num_1.to_i), "\n";
else
#print value_1 + value_2
print "Answer: " , (value_1.to_i + value_2.to_i), "\n";
end
But this produces a blank return after putting in the response to the get.chomp for an additional digit. Any help?
As a fourth alternative (and what I usually use) ...
if gets.chomp.downcase == "yes"
As with the regex match, it also accepts unexpected case arrangements (e.g. "yEs", "yES", "YeS" and so on)
In Ruby you can't compare a variable to many options as you have there. You have to do something like this:
if add_num_req == "yes" || add_num_req == "Yes" || add_num_req == "YES"
Another way to do it is to take advantage of the Enumerable module. But this is a little more advanced, although you will find it useful as you continue to use Ruby.
answers = ["yes", "Yes", "YES"]
if answers.any? { |e| add_num_req == e }
change:
if gets.chomp = "yes" || "Yes" || "YES" #you are using = instead of == which is equality
to:
if gets.chomp.match(/yes/i) #This is a case-insensitive regex to match "yes", "Yes" or "YES"
A third alternative:
if ( ['yes','Yes','YES'].include?(add_num_req) )
...
Here's a more Ruby-like way to write your program:
def doit
value_1 = obtain_entry("Please enter your first digit: ").to_i
value_2 = obtain_entry("Please enter your second digit: ").to_i
loop do
case obtain_entry("Do you want to add an additional digit?: ")
when "yes", "Yes", "YES"
print "Please enter the additional digit: "
puts "Answer: #{value_1 + value_2 + gets.to_i}"
break
when "no", "No", "NO"
puts "Answer: #{value_1 + value_2}"
break
end
end
end
def obtain_entry(str)
print str
gets.chomp
end
doit
A few points:
Since you are getting a response from the user more than once, put that in a method to which you pass the question to be asked (here, obtain_entry). For answers that are to be treated as integers, you may as well convert them to integers when they are returned. (In a real application you would of course want to make various checks on the type and reasonableness of answers.)
Do not define variables when it is not necessary to do so. For example, I've not created a variable for the reply to either of the questions "Do you want to add an additional digit?: " and "Please enter the additional digit: ".
I've added an endless loop that ensures that an acceptable "yes" or "no" answer is given to the question "Do you want to add an additional digit?. If an acceptable answer is given, we break out of the loop; if not, the question is repeated and the user is given another opportunity to answer.
It is often convenient to use a case statement in the way I have done when several replies result in the same action being taken.
When displaying output, I've used the more conventional way of forming a string, using string interpolation (e.g., #{variable_x}), as in puts "Answer: #{value_1 + value_2 + gets.to_i}". You must use double quotes for string interpolation to work.
When using IO#gets to obtain a string that is to be converted to an integer, String#chomp is not needed; gets.to_i is sufficient.
My guess is your problem is happening here:
#get the additional number
print "Do you want to add an additional number?"
add_num_req = gets.chomp
#calculate result and put
if gets.chomp = "yes" || "Yes" || "YES"
Since you are calling gets.chomp twice for the same input and using an assignment operator = in place of comparison operator ==. Also, as someone else has pointed out, each || operator should evaluate a Boolean expression, e.g. add_num_req == 'yes' || add_num_req == 'YES'. Without modifying your code too much, I think you want something like this:
print "Do you want to add an additional number? "
add_num_req = gets.chomp
#calculate results and put
if add_num_req.downcase == 'yes'
# ...
On that note, if you plan to be evaluating a lot of strings, regular expressions are invaluable. I still can't write a decent regexp without checking a reference, but even so they make a world of difference!
Just started working through the Ruby chapter in Mr. Tate's "Seven Language in Seven Weeks".
For the bonus question in Day 1, I am to generate a "random" number, read a user's guess from the input, and compare the guess to my "random" number, then prompt the user to continue guessing with the begin loop. However, the loop seems to terminate regardless of what the value of the string the user inputs.
# file : day1_bonus.rb
# Seven Languages In Seven Weeks
#
# Guess a random number!
again = "y"
begin
print "Enter a number between 0 and 9: "
number = gets.to_i
randNum = rand(10)
if number == randNum
puts 'You guessed correctly!'
else
puts 'You guessed incorrectly.'
end
print "Play again? (y/n): "
again = gets
again.chomp # remove carriage return
end while again == "y"
Output:
Enter a number between 0 and 9: 3
You guessed incorrectly.
Play again? (y/n): y
nil
There are two versions of chomp. The regular chomp and bang chomp!. The difference being: regular returns modified string (and leaves source alone) while the bang version modifies original string in-place.
So, in your code you chomp the carriage return and throw away this work. Either do this
again = again.chomp
or this
again.chomp!