Ruby gets/puts only for strings? - ruby

I'm new to Ruby and am currently working on some practice code which looks like the following:
puts 'Hello there, Can you tell me your favourite number?'
num = gets.chomp
puts 'Your favourite number is ' + num + '?'
puts 'Well its not bad but ' + num * 10 + ' is literally 10 times better!'
This code however just puts ten copies of the num variable and doesn't actually multiply the number so I assume I need to make the 'num' variable an integer? I've had no success with this so can anyone show me where I'm going wrong please?

If you are using to_i, then chomp before that is redundant. So you can do:
puts 'Hello there, Can you tell me your favourite number?'
num = gets.to_i
puts 'Your favourite number is ' + num.to_s + '?'
puts 'Well its not bad but ' + (num * 10).to_s + ' is literally 10 times better!'
But generally, using "#{}" is better since you do not have to care about to_s, and it runs faster, and is easier to see. The method String#+ is particularly very slow.
puts 'Hello there, Can you tell me your favourite number?'
num = gets.to_i
puts "Your favourite number is #{num}?"
puts "Well its not bad but #{num * 10} is literally 10 times better!"

Use the to_i method to convert it to an integer. In other words, change this:
num = gets.chomp
To this:
num = gets.chomp.to_i

you can also make sure the number that the user is using is an integer this way:
num = Integer(gets.chomp)
but you have to create a way to catch the error in case the user input otherwise like a char, or string so; it is must better to use:
num = gets.chomp.to_i
In case the user put another type of data, num will be equal to 0 like you can see in this test example:
puts "give me a number:"
num = gets.chomp.to_i
if num >3
puts "#{num} es mayor a 3 "
else
puts "#{num} es menor a 3 o 3"
end
This a example of the interaction with that script:
give me a number:
sggd
0 es menor a 3 o 3
nil
I hope this clarify better your point.

I wrote a similar program as yours. Here is how I finally got it to work properly! I had to assign the favorite number to be an integer. Then, in the next line I set the new_fav_num with the value of fav_num +1 and then converted it to string. After that, you can just plug your code into the return statement that you want to say to the user, only you have to convert the first fav_num to a string.
puts "What is your favorite number?"
fav_num = gets.chomp.to_i
new_fav_num = (fav_num + 1).to_s
puts "Your favorite number is " + fav_num.to_s + ". That's not bad, but " +
new_fav_num + " is bigger and better!"
Hope this helps.

Related

How do I add one more year to the given input?

I want to get an output so that it adds one more year to an age input.
This is my code:
print "Age: "
age = gets.chomp.to_i
def age_next_year(int)
age.each do |int|
int += 1
end
puts "Next year I’ll be " + age_next_year(age)
I can't seem to get the correct output.
You don’t need to call each since it’s designed to iterate arrays and you have an integer. Also, you don’t need to reassign the value back to int local variable, just return it from the method:
def age_next_year(int)
int + 1
end
Another issue is you are trying to + what age_next_year method returns (integer) to the string. The explicit conversion is required there:
puts "Next year I’ll be " + age_next_year(age).to_s
I'm just asking, but why don't you do something like this:
print "Age: "
age = gets.chomp.to_i + 1
printf "Next year I'll be %d\n", age
# OR
puts "Next year I'll be " + age.to_s
It works fine for me, and it's smaller and quicker than what you did.

Loop error for multiple conditions

I have this loop:
puts "Welcome to the Loop Practice Problems"
puts " Write a number between 1 and 10, but not 5 or else...."
ans = gets.chomp!
if ans < 1
puts "Tf bruh bruh"
elsif ans > 10
puts "Now you just playin"
elsif x == 5
print "You wildin B"
else
puts "Fosho that's all I require"
end
It doesn't run properly, and I'm trying to understand why. If you can help me with this, I'd appreciate it.
If you know a good site for practice problems, I'd love to try it. I checked out Coderbyte and Code Kata, but the way they're set up doesn't look right, and they don't have questions to solve for fundamentals.
The issue here is that you're not converting ans to a number, but you're comparing it to one. ans is going to be a string.
In Ruby, when you compare a number to a string, Ruby says that the two aren't equal:
"1" == 1
=> false
You can reproduce the problem with this code:
puts "Welcome to the Loop Practice Problems"
puts " Write a number between 1 and 10, but not 5 or else...."
ans=gets.chomp!
p ans
The p method will output an "inspected" version of that object, (it's the same as doing puts ans.inspect). This will show it wrapped in quotes, which indicates that it's a string.
You probably want to do this:
ans = gets.chomp!.to_i
The to_i method here will convert the number to an integer, and then your comparisons will work correctly.
You have to convert input string type object into integer type
ans = gets.chomp!.to_i #input string convert into integer.
if ans < 1
puts "Tf bruh bruh"
elsif ans > 10
puts "Now you just playin"
elsif x == 5
print "You wildin B"
else
puts "Fosho that's all I require"
end

Calculator program in ruby, taking "2+3" and giving output 6, issues with more than 2 digit numbers

First post, excuse if I break any etiquette. I am beginning, so this might be simple.
Trying to code in ruby, a calculator, where user inputs arithmetic sentence (only binary, PEMDAS/BIDMAS will do later) and the answer comes out.
Here is my code, by only works for single digit numbers.
class Calculator
def initializer (a,b)
#a = a,
#b = b
end
def add(a, b)
a+b
end
def subtract(a, b)
a-b
end
def multiply(a,b)
a*b
end
def divide (a,b)
a/b
end
def powers (a,b)
a**b
end
end
puts "Enter an expression to be evaluated"
a = gets.chomp.gsub(/\s+/, "")
puts case a[1]
when "+"
"#{a[0]} + #{a[2]} = #{Calculator.new.add(a[0].to_f,a[2].to_f)}"
when "-"
"#{a[0]} - #{a[2]} = #{Calculator.new.subtract(a[0].to_f,a[2].to_f)}"
when "*" || "x" || "X"
"#{a[0]} x #{a[2]} = #{Calculator.new.multiply(a[0].to_f,a[2].to_f)}"
when "/"
"#{a[0]} / #{a[2]} = #{Calculator.new.divide(a[0].to_f,a[2].to_f)}"
when "^"
"#{a[0]} to the power #{a[2]} = #Calculator.new.powers(a[0].to_f,a[2].to_f)}"
else
"Not valid"
end
I was thinking of trying to split a string like "234+342" (234 and 342 can be any sized length numbers) into an array such as ["234","+","342"].
But I am stuck on how to do this??? Or is there another way??
Help will be appreciated, just a personal challenge.
Thanks
As you already realized the issue is with the way you are carrying operations over input string.
The simplest way to proceed can be to ask users for two numbers and then ask them to enter the operation needed. Something like:
puts "Enter first number"
a = gets.chomp
puts "Enter second number"
b = gets.chomp
puts "Enter required operation [+, -, *, /]"
c = gets.chomp
You can do this all in one shot too, the way you are already trying, however I would advice against it as you never know what user will enter. Eg:
puts "Enter an expression to be evaluated"
a = gets.chomp # user enters: 123 + 457
# => "123 + 457"
Now extracting number:
numbers = a.scan(/\d+/)
#=> ["123", "457"]
operator = a[/\W+/]
#=> " + "
You can then proceed with your switch case.

How can I create a program to accept ten numbers from a user?

I am creating a program that accepts ten numbers from a user. Then, it displays the total of the ten numbers, their average, and the smallest and largest numbers. Finally, it is supposed to display the word 'Jackpot!' for every number entered that is of the same or greater value than 100, and 'Tough Luck.' for every number less than 100.
My code does not seem to be working and will not run in Ruby.
puts 'Please enter 10 numbers one at a time.'
num1=gets.chomp
num2=gets.chomp
num3=gets.chomp
num4=gets.chomp
num5=gets.chomp
num6=gets.chomp
num7=gets.chomp
num8=gets.chomp
num9=gets.chomp
num10=gets.chomp
value_list=[num1, num2, num3, num4, num5, num6, num7, num8, num9, num10]
subtotal=0
for x in 0..9
subtotal=subtotal+value_list[x]
puts 'Total: ' + subtotal
average=subtotal/10.to_f
average=sprintf("%.2f",average)
puts 'Average: ' + average
puts 'Smallest value: ' + sprintf("%.2f",value_list.min.to_s)
puts 'Largest value: ' + sprintf("%.2f",value_list.min.to_s)
if num1..num10 >=100
puts 'Jackpot!'
else
puts 'Tough Luck.'
sleep 120
A few things:
You need to end your blocks: for ... end, if ... else ... end, etc. This is the main reason it won't run, i.e. the parser doesn't recognize it as valid syntax.
gets.chomp returns a string, but you are looking for integers. Try gets.chomp.to_i to force integer types.
'Total: ' + subtotal: you would be adding an integer to a string, which is not allowed. Ruby string interpolation goes like this (double quotes required): "Total: #{subtotal}". This will transform the subtotal variable into a string and insert it into the other string on the fly.
I'm not sure what you're trying to do here: if num1..num10 >= 100. Is this if any member of the range is greater than 100, or if the sum is greater than 100?
There's also a lot of optimization you can do here. One good opportunity is when you have a lot of repeated code, as in num1 = gets.chomp.to_i; num2 = gets ... etc.
Here's a version of your program that (I think) does what you want it to. If you're serious about learning Ruby, go look up the documentation for some of these methods (<<, inject, .times etc):
puts 'Please enter 10 numbers one at a time.'
value_list = []
10.times do
value_list << gets.chomp.to_i
end
subtotal = value_list.inject(:+)
puts "Total: #{subtotal}"
puts "Average: #{(subtotal/10.0).round(2)}"
puts "Smallest value: #{value_list.min}"
puts "Largest value: #{value_list.max}"
if subtotal >= 100
puts 'Jackpot!'
else
puts 'Tough Luck.'
end
Hope this helps.
Your code need some end statements, and you need to convert the input to numbers before calculation.
You also need to close the for at the end and the if before the 'Jackpot!'.
You can convert all of the strings input using map:
value_list = value_list.map(&:to_i)
Where you calculate the subtotal you need to covert its data to a string, or just interpolate the data:
puts "Total: #{subtotal}"
After this you need to redo if num1..num10 >=100. It compares 100 to a Range which is wrong.

Misbehaving Case Statement

I'm messing around in Ruby some more. I have a file containing a class with two methods and the following code:
if __FILE__ == $0
seq = NumericSequence.new
puts "\n1. Fibonacci Sequence"
puts "\n2. Pascal\'s Triangle"
puts "\nEnter your selection: "
choice = gets
puts "\nExcellent choice."
choice = case
when 1
puts "\n\nHow many fibonacci numbers would you like? "
limit = gets.to_i
seq.fibo(limit) { |x| puts "Fibonacci number: #{x}\n" }
when 2
puts "\n\nHow many rows of Pascal's Triangle would you like?"
n = gets.to_i
(0..n).each {|num| seq.pascal_triangle_row(num) \
{|row| puts "#{row} "}; puts "\n"}
end
end
How come if I run the code and supply option 2, it still runs the first case?
Your case syntax is wrong. Should be like this:
case choice
when '1'
some code
when '2'
some other code
end
Take a look here.
You also need to compare your variable against strings, as gets reads and returns user input as a string.
Your bug is this: choice = case should be case choice.
You're providing a case statement with no "default" object, so the first clause, when 1, always returns true.
Effectively, you've written: choice = if 1 then ... elsif 2 then ... end
And, as Mladen mentioned, compare strings to strings or convert to int: choice = gets.to_i

Resources