Cannot find where end input is missing - ruby

I'm very sorry for the trivial question, i'm very new in Ruby.
It shows me
13-3.rb:32: syntax error, unexpected end-of-input, expecting keyword_then or ';' or '\n'"
But i just can't see where i should put "end" here
if File.exist?(questions) && if File.exist?(answers)
f = File.new(questions, "r:UTF-8")
question_line = f.readlines
f.close
g = File.new(answers, "r:UTF-8")
answer_line = g.readlines
g.close
right_answers = 0
position = 0
questions_amount = question_line.length
while position <= questions_amount
puts question_line[position]
user_input = gets.encode("UTF-8").chomp
if user_input == answer_line[position]
puts "Верный ответ"
right_answers += 1
else
puts "Неправильно. Верный ответ: " + answer_line[position]
end
position += 1
end
puts "У вас #{right_answers} правильных ответов из #{questions_amount}"
else
puts "Файл не найден"
end

Seems like you forgot do in while statement.
while position <= questions_amount do
# ...
end
Also, as mentioned in comments, the first line should be
if File.exist?(questions) && File.exist?(answers)
Hope this helps.

Related

Capybara / Ruby - Trying to return to the beginning of the loop when an error shows up

I'm trying to return to the loop beginnig when an error shows up as the code below.
I'm using the command "next" when a casual error occurs but it is not coming back for the loop beginning.
describe 'Test', :test do
before(:each) do
visit '/admin'
end
it 'Adding new images' do
image = 'barcelona.jpg'
#imagem = Dir.pwd + '/spec/fixtures/' + image
produto = '1'
100.times do
visit '/admin/' + produto
if page.has_no_css?('#mensagem > h1')
within_frame(:xpath, "//*[#id='app-content']/main/div/iframe") do
find('#ctl00_Conteudo_tbxNome_txtId').set 'test_name'
find('#ctl00_Conteudo_BtnSalvar').click
if page.has_no_css?('#mensagem > h1')
find('#ctl00_Conteudo_tbxIdArquivoControle_lnkInserirArquivo').click
attach_file('ctl00_Conteudo_tbxIdArquivoControle_tbxArquivo', #imagem)
find('#ctl00_Conteudo_tbxIdArquivoControle_btnEnviar').click
if page.has_no_css?('#mensagem > h1')
find('#skuTabNavigation a[href="#tabImages"]').click
expect(page).to have_content image
puts 'Test ok'
else
puts 'Error was presented, starting over..'
next
end
else
puts 'Error was presented, starting over..'
next
end
end
else
puts 'Error was presented, starting over..'
next
end
end
end
end
I would like that every time when the system goes to "else" condition, it restart the loop.
I don't think there is a direct way to move back to the initial iteration of a loop. redo exists but it only moves you back to the current iteration.
In this case, you probably want to change the way you're looping so you can more easily control when to start/stop. For example:
i = 0
while i <= 100 do
if page.has_no_css?('#mensagem > h1')
i = 0
puts 'Error'
next
end
i += 1
end
So you don't have to reset the loop index and call puts each time you could rescue an error:
class MyError < StandardError; end
i = 0
while i <= 100 do
begin
if page.has_no_css?('#mensagem > h1')
raise MyError, 'thing was missing'
end
puts i
i += 1
rescue MyError => boom
puts "Error: #{boom.message}"
i = 0
redo
end
end

Ruby - Create a class with a file as a variable - possible?

I need to create a program in which the user can take different tests. As i dont want to copy paste my code all over for every test, i have tried to setup a class for that purpose - but i have problems with this class.
Error message = undefined variables or method in 'display_test'
I have predefined som test as a .txt file
I want to choose the file in the class depending on what the user answer - is that possible?
Class code:
class Test
#correct_answers = 0
def display_question( question, options, answer )
puts question
options.each_with_index { |option, idx| puts "#{ idx + 1 }: #{ option
}" }
print 'Answer: '
reply = gets.to_i
if answer == reply
puts 'Correct!'
#correct_answers += 1
puts "#{#correct_answers}"
else
puts 'Wrong. The correct answer was: ' + answer.to_s
end
end
def display_test()
f = File.new(userinput, 'r')
while ! (f.eof?) #logikken til at splitte
line = f.gets()
question = line.split("|")
question[1] = question[1].split(";")
display_question question[0], question[1], question[2].to_i
end
end
display_test
puts "________________________________________________________"
puts "Total score:"
puts "You've got" + " #{#correct_answers}" + " correct answers!"
Before hand i have used ("geografitest.txt") instead of username in the File.new so it looked like this:
f = File.new('geografitest.txt','r')
But now i am trying to let the user decide what test to take.
I am very new to ruby, so please bear with me.
I have tried to do it this way, which obviously is not working.
puts "Which test do you want to take?"
select = 0
while (select != 3)
puts "Press 1 to take Geografi test."
puts "Press 2 to take Math test."
puts "Press 3 to take Religion test."
puts "Press 3 to exit"
select = gets.chomp.to_i
if (select == 1)
gets.chomp = userinput
userinput =`geografitest.txt`
echo $userinput
end
if (select == 2)
gets.chomp = userinput
userinput =`matematiktest.txt`
echo $userinput
end
if (select == 3)
gets.chomp = userinput
userinput =`religionstest.txt`
echo $userinput
end
if (select > 4)
puts "Not a correct selection"
elsif (select == 4)
puts "Goodbye"
end
end
abort
So my questions is now;
How can i make the user choose what test to take? Can i make a variable instead of the textfile as i have tried, but in a different way? Or is there a smarter way?
And in what way is my class wrong and how do i fix it? I know its not the way to make it, but i simple cant get my head around how to make it right.
Please help a rookie out.
Cheers!
You can pass file as dependency to you Test class based on user input with object constructor. Something like this
class Test
attr_reader :correct_answers_count
def initialize(file)
#file = file
#correct_answers_count = 0
end
#other code goes here
end
loop do
case user_input = gets.chomp
when '1'
file_name = 'some_file1'
when '2'
file_name = 'some_file1'
when '3'
break
else
puts 'wrong variant'
end
test = Test.new(File.new(file_name, 'r'))
test.display
end

How to split the strings to line by line

I have a text file which contains
1.6.0_43/opt/oracle/agent12c/core/12.1.0.4.0/jdk/bin/java
1.6.0_43/opt/oracle/agent12c/core/12.1.0.4.0/jdk/jre/bin/java
1.5.0/opt/itm/v6.2.2/JRE/lx8266/bin/java
1.7.0_72/u01/java/jdk1.7.0_72/jre/bin/java
1.7.0_72/u01/java/jdk1.7.0_72/bin/java
I am trying to read each line by line and get the result by line by line Here is my ruby code:
logfile = "/home/weblogic/javacheck.txt"
java_count = 0
log = Facter::Util::FileRead.read(logfile)
unless log.nil?
log.each_line do |line|
if line.include?('/java')
java_count += 1
val = "#{line}"
But the output is:
"1.6.0_43/opt/oracle/agent12c/core/12.1.0.4.0/jdk/bin/java\n1.6.0_43/opt/oracle/agent12c/core/12.1.0.4.0/jdk/jre/bin/java\n1.5.0/opt/itm/v6.2.2/JRE/lx8266/bin/java\n1.7.0_72/u01/java/jdk1.7.0_72/jre/bin/java\n1.7.0_72/u01/java/jdk1.7.0_72/bin/java\n1.7.0_65/u01/java/jdk1.7.0_65/jre/bin/java\n1.7.0_65/u01/java/jdk1.7.0_65/bin/java\n
How can I convert this string into line by line?
Here is the fix code.
#!/usr/bin/env ruby
logfile = "/home/weblogic/javacheck.txt"
java_count = 0
log = File.open(logfile,"r")
unless log.nil?
log.each_line do |line|
if line.include?('/java')
puts "#{line}"
java_count += 1
end
end
end
puts "#{java_count}"

How can I do readline arguments completion?

I have a Ruby app which uses readline with command completion.
After the first string (the command) was typed, I would like to be able to complete its arguments. The arguments list should be based on the chosen command.
Does someone have a quick example?
These are the commands:
COMMANDS = [
'collect', 'watch'
].sort
COLLECT = [
'stuff', 'otherstuff'
].sort
comp = proc do |s|
COMMANDS.grep( /^#{Regexp.escape(s)}/ )
end
Readline.completion_proc = comp
Each time I press TAB, the proc block is executed and a command from the COMMANDS array is matched.
After one of the commands was fully matched I would like to start searching for the argument only in the COLLECT array.
Since your question popped up first every time I looked for something like this I want to share my code for any one else.
#!/usr/bin/env ruby
require 'readline'
module Shell
PROMPT = "shell> "
module InputCompletor
CORE_WORDS = %w[ clear help show exit export]
SHOW_ARGS = %w[ list user ]
EXPORT_ARGS = %w[ file ]
COMPLETION_PROC = proc { |input|
case input
when /^(show|export) (.*)/
command = $1
receiver = $2
DISPATCH_TABLE[$1].call($2)
when /^(h|s|c|e.*)/
receiver = $1
CORE_WORDS.grep(/^#{Regexp.quote(receiver)}/)
when /^\s*$/
puts
CORE_WORDS.map{|d| print "#{d}\t"}
puts
print PROMPT
end
}
def self.show(receiver)
if SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/).length > 1
SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/)
elsif SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/).length == 1
"show #{SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/).join}"
end
end
def self.export(receiver)
if EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/).length > 1
EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/)
elsif EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/).length == 1
"export #{EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/).join}"
end
end
DISPATCH_TABLE = {'show' => lambda {|x| show(x)} ,
'export' => lambda {|x| export(x)}}
end
class CLI
Readline.completion_append_character = ' '
Readline.completer_word_break_characters = "\x00"
Readline.completion_proc = Shell::InputCompletor::COMPLETION_PROC
def initialize
while line = Readline.readline("#{PROMPT}",true)
Readline::HISTORY.pop if /^\s*$/ =~ line
begin
if Readline::HISTORY[-2] == line
Readline::HISTORY.pop
end
rescue IndexError
end
cmd = line.chomp
case cmd
when /^clear/
system('clear')
when /^help/
puts 'no help here'
when /show list/
puts 'nothing to show'
when /^show\s$/
puts 'missing args'
when /export file/
puts 'nothing to export'
when /^export\s$/
puts 'missing args'
when /^exit/
exit
end
end
end
end
end
Shell::CLI.new
After thinking a while, the solution was very simple:
comp = proc do |s|
if Readline.line_buffer =~ /^.* /
COLLECT.grep( /^#{Regexp.escape(s)}/ )
else
COMMANDS.grep( /^#{Regexp.escape(s)}/ )
end
end
Now I just need to turn it into something more flexible/usable.

While loop in Ruby Shoes GUI ToolKit

I have only been using Shoes for a few days now so maybe I am missing something. I wrote my son an little program to help him learn his multiplication tables. When he gets ten correct he's done. I can not seem to get the while loop right using SHOES.
Would some please show me a while statement. When I try; it either wipes out my flow and stack statements or Shoe crashes.
thanks in advance.
Sam
I don't know how you're using a while loop. Most likely you're trying to recreate the stack each iteration through the while loop, which is a bad idea. The two solutions that spring immediately to mind are to handle the logic on a button click and keep track of the number correct in a row, like this:
Shoes.app do
num_correct = 0
first_num = 1 + rand(10)
second_num = 1 + rand(10)
answer = first_num * second_num
stack do
#info = para 'Hi, Timmy! This program will test your ',
'multiplication tables. When you get 10 ',
'correct, you get to stop, and you get your ',
'pet hamster back!'
#question = para "What is #{first_num} x #{second_num}?"
#response = edit_line :width => 100
btn = button 'OK' do
if #response.text == ''
alert('You need to put an answer in the box, Timmy.')
elsif #response.text.to_i == answer
num_correct += 1
if num_correct == 10
#info.text = "Good job! That's #{num_correct} in a row!"
alert('You did it, Timmy! You can have your ' \
'hamster back... for now.')
exit
else
#info.text = "Good job! That's #{num_correct} in a row!"
first_num = 1 + rand(10)
second_num = 1 + rand(10)
answer = first_num * second_num
#question.text = "What is #{first_num} x #{second_num}?"
#response.text = ''
end
else
num_correct = 0
#info.text = "Wrong, Timmy. The answer is #{answer}."
first_num = 1 + rand(10)
second_num = 1 + rand(10)
answer = first_num * second_num
#question.text = "What is #{first_num} x #{second_num}?"
#response.text = ''
end
end
end
end
Or, the solution which I think is much more interesting, using url and visit:
class MyTest < Shoes
url '/', :index
url '/correct/(\d+)', :correct
url '/wrong/(\d+)', :wrong
url '/question', :question
url '/question/(\d+)', :question
url '/done', :done
def index
stack do
para 'Hi, Timmy! This program will test your ' \
'multiplication tables. When you get 10 ' \
'correct, you get to stop, and you get your ' \
'pet hamster back!'
button 'OK' do
visit '/question'
end
end
end
def question(num_correct = 0)
num_correct = num_correct.to_i
first_num = 1 + rand(10)
second_num = 1 + rand(10)
answer = first_num * second_num
stack do
para "What is #{first_num} x #{second_num}?"
flow do
response = edit_line :width => 100
button 'Answer' do
if response.text.to_i == answer
num_correct += 1
if num_correct == 10
visit '/done'
else
visit "/correct/#{num_correct}"
end
else
visit "/wrong/#{answer}"
end
end
end
end
end
def correct(num_correct)
stack do
para "Good job! That's #{num_correct} in a row!"
button "Next Question" do
visit "/question/#{num_correct}"
end
end
end
def wrong(answer)
#num_correct = 0
stack do
para "Wrong! The correct answer is #{answer}."
button "Next Question" do
visit '/question'
end
end
end
def done
stack do
para 'You did it, Timmy! You can have your ' \
'hamster back... for now.'
button 'OK' do
exit
end
end
end
end
Shoes.app

Resources