For some reason, this Ruby script is not working - ruby

I'm new to ruby, and I'm trying to recreate a script I made in python, in ruby, to learn. So far, I feel like this is pretty simple, but the program simply will not run. I'm getting this error
"syntax error, unexpected end-of-input, expecting keyword_end"
I'm not sure why, I ended my loop with an end
This is the code
#ruby version of work script
a = 0
b = 0
c = 0
i = " "
puts "Hello, please input the 3 character code."
i = gets.chomp
while i != "END"
if i == "RA1"
a += 1
if i == "RS1"
b += 1
if i == "RF4"
c += 1
if i == "END"
print "Complete"
else
puts "Please enter the 3 character code"
end
print "RA1: " + "#{a}" + "RS1: " + "#{b}" + "RF4: " + "#{c}"`

There are multiple issues with your code:
You have syntax errors. You need end after each of your if and else statements unlike python.
From your code it looks like you are looking for the if-elsif statement and not the multiple if statements because the else statement will be of the last if.
You need to put i = gets.chomp inside the while loop so that you don't go into an infinite loop.
Try something like this:
#ruby version of work script
a = 0
b = 0
c = 0
i = " "
puts "Hello, please input the 3 character code."
while i != "END"
i = gets.chomp
if i == "RA1"
a += 1
elsif i == "RS1"
b += 1
elsif i == "RF4"
c += 1
elsif i == "END"
print "Complete"
else
puts "Please enter the 3 character code"
end
end
print "RA1: " + "#{a}" + "RS1: " + "#{b}" + "RF4: " + "#{c}"

Related

Ruby - How to Execute something and then Break inside IF block?

EDIT: Someone pointed out that I needed to break correctly so I am editing the question
Scenario:
Please see following code:
print "UserID: "
uid = $stdin.gets.chomp
print "Password: "
pwd = $stdin.gets.chomp
usr_inp = "#{uid};#{pwd}"
login_status = -1
# login_info.txt - "#{userid};#{password}" - format
File.open(File.join(File.dirname(__FILE__), 'login_info.txt'), "r") do |f|
f.each_line do |line|
puts line
if (line.chomp == usr_inp)
login_status = 1
elsif (line.chomp != usr_inp && line.include?(uid)) #case a person inputs invalid password
login_status = 0
elsif (line.chomp != usr_inp && !(line.include?(uid))) #case a person inputs an invalid id
login_status = 2
end
end
end
if (login_status == 1)
puts "\nLogged in successfully: #{uid}"
elsif (login_status == 2)
puts "\nSorry, that Employee does not exist."
elsif (login_status == 0)
puts "\nLogin failed.\nPlease check credentials."
end
Problem:
break if (condition) exists in Ruby. But I don't waht that.
I want to do something like:
if (condition x)
(do something)
break
elsif (condition y)
(do something else)
break
else
(whatever)
end
Maybe I am not understanding how ruby code works. Whenever I try to put the break as I want to use it, it associates with the next elsif.
Please help.
It depends on what you need and where you need it.
A script like this:
condition = 1
case condition
when 1
puts 'one'
break
when 2
puts 'two'
else
puts 'Other %s' % condition
end
puts 'end'
has a syntax error. break leaves a loop and there is no loop.
But with a loop, this works:
[1,2,3].each{|condition|
case condition
when 1
puts 'one'
break
when 2
puts 'two'
else
puts 'Other %s' % condition
end
puts 'end'
}
puts 'very end'
The output is:
one
very end
You see, the loop is stopped.
If you want to continue the loop with the next element, you need next (sorry, I'm just not aware what break is doing really in Java - it's been a long time since my last Java program):
[1,2,3].each{|condition|
case condition
when 1
puts 'one'
next
when 2
puts 'two'
else
puts 'Other %s' % condition
end
puts 'end %s' % condition
}
puts 'very end'
The result:
one
two
end 2
Other 3
end 3
very end
When you are not inside a loop (like in your code snippet), you may use exit (leave the program) or return (leave a method).

Ruby program for searching words in a file

I started with Ruby yesterday, I only have some experience with C.
Now I'm trying to write a program that gets a file and a word to search in that file from ARGV, and prints how many times the word appeared. Got rid of any error, but it prints 0 anyway when I test it.
if ARGV.size !=2
puts "INSERT A FILE AND A WORD OR A CHAR TO SEARCH FOR"
exit 1
else
file = File.open(ARGV[0], mode = "r")
word = ARGV[1]
if !file
puts "ERROR: INVALID INPUT FILE"
exit 1
end
while true
begin
i = 0
count_word = 0
string = []
string[i] = file.readline
if string[i].upcase.include? word.upcase
count_word += 1
end
i += 1
rescue EOFError
break
end
end
print "The word searched is ", word, " Frequency: ", count_word, "\n"
end
I hope you could tell me what's wrong (I believe I do something wrong when counting), thanks in advance.
A great thing about Ruby it that it operates on a way higher level of abstraction. Here is a snippet that does what you want:
if ARGV.size != 2
puts "Provide file to be searched in and word to be found"
exit 1
end
file = ARGV[0]
word = ARGV[1]
count = 0
File.open(file, 'r').each { |line| count += 1 if line.downcase.include? word.downcase }
puts "The word searched is #{word} Frequency: #{count}"
As you can see, the language provides a lot of features like string interpolation, enumeration of the file contents, etc.
There is a handful of problems with the code you provided. From styling issues like indentation, to incorrect assumptions about the language like the if !file check and strange decisions overall - like why do you use a list if you want only the current line.
I suggest you to look at http://tryruby.org/ . It is very short and will get you a feel of the Ruby way to do things. Also it covers your question (processing files).
As a general note when you post a question on stackoverflow, please include the code in the question, rather than link to an external page. This way people can read through it faster, edit it and the code wont be lost if the other site goes down. You can still link to external pages if you want to show the snippet in action.
Hope this will help you, the error that you did is that you included this part:
i = 0
count_word = 0
string = []
into the while loop, which every time resets your counter to zero even if it found the word, so to correct this error here what you should do:
if ARGV.size !=2
puts "INSERT A FILE AND A WORD OR A CHAR TO SEARCH FOR"
exit 1
else
file = File.open(ARGV[0], mode = "r")
word = ARGV[1]
if !file
puts "ERROR: INVALID INPUT FILE"
exit 1
end
i = 0
count_word = 0
string = []
while true
begin
string[i] = file.readline
if string[i].upcase.include? word.upcase
count_word += 1
end
i += 1
rescue EOFError
break
end
end
print "The word searched is ", word, " Frequency: ", count_word, "\n"
end

Getting an "unexpected keyword_end" for if/else statements

def load x
#maze_string = x
#maze_string_split = x.chars.to_a
string_counter = 0
y=#height
x=#width
(0..(y*2+1)).each do |n|
if #maze_string_split[counter] !=1
puts "Error in given string, wall expected"
else
#maze_array[n] = #maze_string_split[counter]
counter++
end
(0..(x*2)).each do |m|
if n==0 || n==(y*2+1) || m==(x*2)
if #maze_string_split[counter] != 1
puts "Error in given string"
else
#maze_array[n][m] = #maze_string_split[counter]
counter++
end
else
#maze_array[n][m] = #maze_string_split[counter]
counter++
end
end
end
end
I am getting the error in the title on the "end" statements at the conclusion of each if/else block. All seems well, but the errors remain. I tried looking to see if anyone else had this problem, but I can't find anything specific to my problem
Ruby does not have a ++ or -- operator.
Ruby will not parse these out correctly in that is the reason you're getting an unexpected keyword_end, it is expecting another operand.
Replace the
counter++ with counter += 1
Also, note that your variable is not called counter but string_counter

Replace string with ruby code

I worte an simple programm to replace text within (( )) with the user input:
If i have for example this this text:
i hab an terrible ((userinput1)) last ((userinput2)) in a horrible ((userinput3))
I tried first to replace the (( with #{ and the )) with }
str1 = gets.chomp
str2 = str1.clone
a = 0
begin
s = str2.index('((', a)
str2[s..s+1] = '#{'
a = a + s + 1
end until str2.length < a
b = 0
begin
s = str2.index('))', b)
str2[s..s+1] = '}'
b = b + s + 1
end until str2.length < b
userinput1 = gets.chomp
userinput2 = gets.chomp
userinput3 = gets.chomp
puts str2
But somehow ruby dont validates the userinputs, instead i get:
i hab an terrible #{userinput1} last #{userinput2} in a horrible #{userinput}
I think the problem is that in my code i wrote:
str2[s..s+1] = '#{'
instead of
str2[s..s+1] = "#{"
because so all my remaining code is an object until it is closed with }. SO what can i do ? I hope you understood my issue?
str1 = gets.chomp
word = str1.scan(/\(\(\w+\)\)/)
word.each do |word|
str1.gsub(word, "what the fuck")
end
puts str1
Nice try. But there's a simpler way. Much simpler :) Basically, you just have to collect user inputs. There are methods for replacing string parts already.
userinput1 = gets.chomp
userinput2 = gets.chomp
userinput3 = gets.chomp
template = "i had a terrible ((userinput1)) last ((userinput2)) in a horrible ((userinput3)"
result = template.gsub('((userinput1))', userinput1).
gsub('((userinput2))', userinput2).
gsub('((userinput3))', userinput3)
# ^^ replacing happens here
puts result

Basic High/Low Program Ruby Input Request

I have been trying to figure out how to make it so that the user can only enter a positive whole number between 1 and 100 for this simple High/Low guess game. I would like it so anything other then a whole number between 1 and 100 will inform the user they can't do that for all inputs. Is there a simple way to do this?
What I have now:
count=0
play = true
while play == true
print "Give me a random number between 1 and 100: "
max= gets.to_i
num= rand(max)
puts "Now guess between 1 and " + max.to_s +
"."
print "What is your guess?: "
guess=gets.to_i
while guess != num && play != false
if guess > num
print "Too high! "
guess=gets.to_i
count+=1
elsif guess < num
print "Too low! "
guess=gets.to_i
count+=1
else
break
end
end
puts "Good Job! You figured it out in " + count.to_s + " attempts!"
print "Want to try again? y/n "
answer=gets.chomp!
if answer == 'n'
play = false
break
end
if
answer == 'y'
play = true
end
end
puts "Maybe next time..."
The easiest way to do that is to use a regular expression and a range.
guess = gets.chomp
if(guess =~ /\A\d+\Z/ && (1..100) === guess.to_i)
#do stuff
else
puts "Please enter a valid number"
end
The regular expression ensures that we get an input composed only of digits (a whole number) and the ranged checks to see if it is between 1 and 100.
if (1..100).include?(guess) && 0 == guess % 1
# ...
end

Resources