If type is character I want to puts error - ruby

puts "Let's sum many numbers"
sum = 0
num = 0
while(num != 'x')
puts "Press a number and then Enter if you exit press 'x'"
num = gets.chomp
if num != 'x'
num = num.to_i
print "#{sum} + #{num} = "
sum += num
puts "#{sum}"
elsif num == 'x'
puts "Total sum is #{sum}"
break
else
puts "error!"
end
end
I want to make code to show error If user press char except 'x'.
How should I do?

Change your first if to a condition that checks if the input is a number, e.g.
if num =~ /\A[0..9]+\z/ # or /\A\d+\z/
The way your code is currently, all strings except 'x' are treated as number -- with value 0 in case they aren't really numbers:
'foobar'.to_i # => 0

Related

How to get rid of a nested loop to make an arithmetic series more efficient?

I am pretty new to programming so bear with me, please.
So this is the code I have right now, I would like to know how to combine the two loops in the middle without changing the function of the program.
entry = " "
while entry != "q"
print "enter a number: "
num = gets.to_i
for x in 1..num
sum = 0
end
for y in 1..x
sum = sum + y
puts sum
end
print "press any key to continue (q to quit): "
entry = gets.chomp
end
Any help would be greatly appreciated!
Thank you!
Edit:
I guess I should clarify the function of this program; the user types in a number and then it calculates the value of each arithmetic series up to and including the number that the user put in.
So it if I type in 3 the result should display like this:
1
3
6
Sorry for the confusion!
Assuming that you want to calculate and puts a sum of numbers from 1 to the input number, I suggest following:
while entry != "q"
print "enter a number: "
num = gets.to_i
puts (1..num).sum
print "press any key to continue (q to quit): "
entry = gets.chomp
end
For edited question solution could be:
while entry != "q"
print "enter a number: "
num = gets.to_i
(1..num).inject(0) do |res, e|
res += e
p res
end
print "press any key to continue (q to quit): "
entry = gets.chomp
end

"Already initialized constant" warning [duplicate]

This question already has answers here:
What is the difference between a constant and a variable in Ruby?
(3 answers)
Closed 6 years ago.
Here's my code:
puts "Input a number."
Divisor = 2
inputNumber = gets.chomp
if inputNumber.to_i == 1 || inputNumber.to_i == 2
if inputNumber.to_i == 1
puts inputNumber + " is not a prime."
else
puts inputNumber + " is a prime."
end
else
while Divisor.to_i < inputNumber.to_i
if inputNumber.to_i%Divisor.to_i == 0
puts inputNumber + " is not a Prime as " + Divisor.to_s + " is a factor."
break
else
Divisor = Divisor.to_i + 1
end
end
puts inputNumber + " is a prime!"
end
I got the following error:
test1.rb:30: warning: already initialized constant Divisor
test1.rb:3: warning: previous definition of Divisor was here
What is wrong?
Constants and variables
Divisor is a constant. You want a variable : divisor. See this answer.
Notes
puts inputNumber + " is a prime!" is always called.
You could replace break by exit, or use a boolean variable.
Since you work with numbers, you could also call .to_i once, do your calculation, and just use .to_s to display results
You only have to check for factors in the range (2..Math.sqrt(inputNumber))
You don't have to check twice if inputNumber == 1
puts 'Input a number.'
divisor = 2
inputNumber = gets.chomp.to_i
prime = true
if inputNumber == 1
puts inputNumber.to_s + ' is not a prime.'
else
while divisor <= Math.sqrt(inputNumber)
if inputNumber % divisor == 0
puts inputNumber.to_s + ' is not a Prime as ' + divisor.to_s + ' is a factor.'
prime = false
break
else
divisor += 1
end
end
puts inputNumber.to_s + ' is a prime!' if prime
end
Alternative
A shorter alternative can be written with Enumerable#find. It executes the block with every element, stops as soon as the code in block returns a truthy value, and returns the element for which the block is truthy. If no element is found, it returns nil :
puts 'Input a number.'
number = gets.chomp.to_i
divisor = (2..Math.sqrt(number)).find { |i| number % i == 0 }
if number == 1
puts '1 is not a prime.'
elsif divisor
puts format('%d is not a prime as %d is a factor.', number, divisor)
else
puts format('%d is a prime!', number)
end

Ruby looping program gives error

Here's what I wrote to check if a number is prime or not
print "Enter number : "
num = gets.chomp
i = 1
boo = true
while (i<num)
if (i%num==0)
boo=true
end
i++
end
if (boo==true)
puts (num+"is a prime number")
else
puts (num+"is not a prime number")
end
This gives an error, how can I fix it?
The output from cmd prompt:
Some problems:
++ operator doesn't exist in Ruby, you can use += 1 instead
your num is a string, you can make it a number with to_i method, like num.to_i
if the reminder of your number divided by a precedent number is zero you should set to false, not true
if you start at 1 your number will result always prime
Anyway, in a more idiomatic Ruby you can write this code something like
print "Enter number : "
num = gets.chomp.to_i
prime = (2..num - 1).all? { |i| num % i != 0 }
if prime
puts "#{num} is prime"
else
puts "#{num} is not prime"
end

Total newb here and other fizzbuzz issue

I'm trying to write a looping fizzbuzz code that ends with the user_input's number. So far the code works, but it loops the number of times you put in for the user_input, not end at the user_input's limit. For example, if I type in 25, it will loop 25 times, and not end at 25. How do I set the parameters/range?
Here is my code:
puts("Please select a number that is at least 25. This is the limit for the fizzbuzz game.")
user_input = gets().chomp().to_i
if
user_input < 25
puts("Please select a larger number.")
else
user_input >= 25
user_input = user_input
counter = 1
while counter < user_input
puts(counter)
counter = counter + 1
(1..user_input).step do |i|
if i % 3 == 0 && i % 5 == 0
puts("fizzbuzz")
elsif i % 3 == 0
puts("fizz")
elsif i % 5 == 0
puts("buzz")
else
puts(i)
end
end
end
end
It is optional to write () when you send no parameters to a method and usually discouraged
You shouldn't use else user_input >= 25, else is enough
user_input = user_input is totally useless line
while cycles with counters isn't the way rubists code, prefer iterators. Moreover, you shouldn't have while here at all
puts 'Please select a number that is at least 25. This is the limit for the fizzbuzz game.'
user_input = gets.chomp.to_i
if user_input < 25
puts 'Please select a larger number.'
else
1.upto(user_input) do |i|
if i % 3 == 0 && i % 5 == 0
puts 'fizzbuzz'
elsif i % 3 == 0
puts 'fizz'
elsif i % 5 == 0
puts 'buzz'
else
puts i
end
end
end
optionally, you can use case-when instead of multiple elsif statements:
puts 'Please select a number that is at least 25. This is the limit for the fizzbuzz game.'
user_input = gets.chomp.to_i
if user_input < 25
puts 'Please select a larger number.'
else
1.upto(user_input) do |i|
case
when [3, 5].all? { |n| i % n == 0 }; puts 'fizzbuzz'
when i % 3 == 0; puts 'fizz'
when i % 5 == 0; puts 'buzz'
else; puts i
end
end
end

While loop continues despite conditions not being met?

When I run the game and type either "yes" or "no" at the end, it always reverts back to the start of the while loop at line 41, when the conditions for both that and the containing loop are not met.
replay = true
while replay
#Pre-var
print "What difficulty? (1 for easy, 2 for medium, or 3 for hard): "
difficulty = gets.chomp.to_i
until difficulty == 1 || difficulty == 2 || difficulty == 3 do
print "Please type either 1, 2, or 3: "
difficulty = gets.chomp.to_i
end
#Variables
if difficulty == 1
r = Random.new
number = r.rand(100..1000)
puts "You have 15 guesses. "
print "Guess a number with three digits: "
within_num = 50
elsif difficulty == 2
r = Random.new
number = r.rand(1000..10000)
puts "You have 15 guesses. "
print "Guess a number with four digits: "
within_num = 500
elsif difficulty == 3
r = Random.new
number = r.rand(10000..100000)
puts "You have 15 guesses. "
print "Guess a number with five digits: "
within_num = 5000
end
guess = ""
num_guess = 0
guess_array = Array.new
array_location = 0
count_through = 0
array_print = count_through - 1
replay_inner = true
#Body
puts number
while num_guess <= 14 || replay_inner == true #Keeping as <= 14 as to avoid unnecessarily rewriting code, still gives 15 guesses
guess = gets.chomp.to_i
if guess > number * 2
print "That is more than double the number. Guess again: "
elsif guess < number / 2
print "That is less than half the number. Guess again: "
elsif guess > number && guess < number + within_num #within_num: 50 for easy, 500 for medium, 5000 for hard
print "You are close. That is too big. Guess again: "
elsif guess < number && guess > number - within_num
print "You are close. That is too small. Guess again: "
elsif guess < number
print "That is too small. Guess again: " #Hinting the user to how close they are.
elsif guess > number
print "That is too big. Guess again: "
elsif guess == number
puts "Congragulations! You win!"
print "Your "
print guess_array.length
print " incorrect guesses were: "
if num_guess == 0
sleep(0.5)
print "... Oh."
else
while count_through < num_guess #Loop to relay user's guesses with a delay of 0.5 seconds
print guess_array[count_through]
if count_through == num_guess - 2
print ", and "
elsif count_through == num_guess - 1
puts ". "
else
print ", "
end
count_through += 1
sleep(0.5)
end
puts "Would you like to play again? (yes/no)"
replay_answer = gets.chomp
until replay_answer == "yes" || replay_answer == "y" || replay_answer == "no" || replay_answer == "n" do
print "Please answer with yes, y, no, or n: "
replay_answer = gets.chomp
end
if replay_answer == "yes" || replay_answer == "y"
replay = true
puts "yes"
elsif replay_answer == "no" || replay_answer == "n" #Determining whether or not to replay
replay = false
puts "no"
end
end
end
guess_array.push guess
num_guess += 1
#puts num_guess
#puts guess_array[array_location]
array_location += 1
if num_guess >= 15 && guess != number
puts "Sorry, you lost. "
print "Your "
print guess_array.size
print " guesses were: "
while count_through < num_guess
print guess_array[count_through] #Same as loop above; for when player fails to guess correctly
if count_through == num_guess - 2
print ", and "
elsif count_through == num_guess - 1
puts ". "
else
print ", "
end
count_through += 1
sleep(0.5)
end
puts "Would you like to play again? (yes/no)"
replay_answer = gets.chomp
until replay_answer == "yes" || replay_answer == "y" || replay_answer == "no" || replay_answer == "n" do
print "Please answer with yes, y, no, or n: "
replay_answer = gets.chomp
end
if replay_answer == "yes" || replay_answer == "y"
replay = true
replay_inner = true
puts "yes"
elsif replay_answer == "no" || replay_answer == "n" #Determining whether or not to replay
replay = false
replay_inner = false
puts "no"
end
end
end
I think the condition in the while should be:
numberGuess<=14 && replay_inner == true
The way you and especially your fellow programmers will find this and future bugs is by properly commenting your code, e.g.:
# ask the user about an optional replay
replay_answer = gets.chomp
# only accept yes/y/no/n
until replay_answer == "yes" || replay_answer == "y" || replay_answer == "no" || replay_answer == "n" do
print "Please answer with yes, y, no, or n: "
replay_answer = gets.chomp
end
## recoded this to a case, as I think it's much nicer :)
# determining whether to replay or to stop the loop
case replay_answer
when "yes", "y"
replay = true
puts "yes"
when "no", "n"
replay = false
puts "no"
replay_inner = false
end
I've modified a little your code, you should really use some decent editor with at least syntax errors highlighting. I've changed OR to AND condition in inner loop (comment in code) and added way of breaking from it when guessed number. I've also removed second occurence of code responsible of playing again, remember, DRY yourself.
replay = true
while replay
p replay
#Pre-var
print "What difficulty? (1 for easy, 2 for medium, or 3 for hard): "
difficulty = gets.chomp.to_i
until difficulty == 1 || difficulty == 2 || difficulty == 3 do
print "Please type either 1, 2, or 3: "
difficulty = gets.chomp.to_i
end
#Variables
if difficulty == 1
r = Random.new
number = r.rand(100..1000)
puts "You have 15 guesses. "
print "Guess a number with three digits: "
within_num = 50
elsif difficulty == 2
r = Random.new
number = r.rand(1000..10000)
puts "You have 15 guesses. "
print "Guess a number with four digits: "
within_num = 500
elsif difficulty == 3
r = Random.new
number = r.rand(10000..100000)
puts "You have 15 guesses. "
print "Guess a number with five digits: "
within_num = 5000
end
guess = ""
num_guess = 0
guess_array = Array.new
array_location = 0
count_through = 0
array_print = count_through - 1
replay_inner = true
#Body
puts number
while num_guess <= 14 && replay_inner == true #Keeping as <= 14 as to avoid unnecessarily rewriting code, still gives 15 guesses
guess = gets.chomp.to_i
if guess > number * 2
print "That is more than double the number. Guess again: "
elsif guess < number / 2
print "That is less than half the number. Guess again: "
elsif guess > number && guess < number + within_num #within_num: 50 for easy, 500 for medium, 5000 for hard
print "You are close. That is too big. Guess again: "
elsif guess < number && guess > number - within_num
print "You are close. That is too small. Guess again: "
elsif guess < number
print "That is too small. Guess again: " #Hinting the user to how close they are.
elsif guess > number
print "That is too big. Guess again: "
elsif guess == number
puts "Congragulations! You win!"
print "Your "
print guess_array.length
print " incorrect guesses were: "
if num_guess == 0
sleep(0.5)
print "... Oh."
else
while count_through < num_guess #Loop to relay user's guesses with a delay of 0.5 seconds
print guess_array[count_through]
if count_through == num_guess - 2
print ", and "
elsif count_through == num_guess - 1
puts ". "
else
print ", "
end
count_through += 1
sleep(0.5)
end
end
replay_inner = false # or just `break`, you have to break somehow from inner loop here
end
guess_array.push guess
num_guess += 1
#puts num_guess
#puts guess_array[array_location]
array_location += 1
if num_guess >= 15 && guess != number
puts "Sorry, you lost. "
print "Your "
print guess_array.size
print " guesses were: "
while count_through < num_guess
print guess_array[count_through] #Same as loop above; for when player fails to guess correctly
if count_through == num_guess - 2
print ", and "
elsif count_through == num_guess - 1
puts ". "
else
print ", "
end
count_through += 1
sleep(0.5)
end
end
end
puts "\nWould you like to play again? (yes/no)"
replay_answer = gets.chomp
until replay_answer == "yes" || replay_answer == "y" || replay_answer == "no" || replay_answer == "n" do
print "Please answer with yes, y, no, or n: "
replay_answer = gets.chomp
end
if replay_answer == "yes" || replay_answer == "y"
replay = true
replay_inner = true
puts "yes"
elsif replay_answer == "no" || replay_answer == "n" #Determining whether or not to replay
replay = false
replay_inner = false
puts "no"
end
end

Resources