I am creating a quiz-maker program in Ruby. It opens and reads a text file, and is able to make a quiz of of the questions and answers in the text file. I am trying to let the user know how many question they got wrong after they complete the quiz.
The error I am getting is:
quiz.rb:180:in `+': can't convert Fixnum into String (TypeError)
from quiz.rb:180:in `<main>'
I get this error after it goes through all the questions.
Here is my code. correct_count is where I try to subtract 1 from the starting 10 everytime someone gets a question wrong. Let me know if you would like to see the text file.
questions = File.open("question.txt","r+")
array = {}
contents = questions.readlines
questions.close
contents.collect! do |x|
x.chomp
end
contents.collect! do |x|
x.split(',')
end
contents.each do |x|
array[x[0]] = x
end
correct_count = 10
question1 = contents[0][1]
choice11 = contents[0][2]
choice12 = contents[0][3]
answer11 = contents[0][4]
question2 = contents[1][1]
choice21 = contents[1][2]
choice22 = contents[1][3]
answer21 = contents[1][4]
question3 = contents[2][1]
choice31 = contents[2][2]
choice32 = contents[2][3]
answer31 = contents[2][4]
question4 = contents[3][1]
choice41 = contents[3][2]
choice42 = contents[3][3]
answer41 = contents[3][4]
question5 = contents[4][1]
choice51 = contents[4][2]
choice52 = contents[4][3]
answer51 = contents[4][4]
question6 = contents[5][1]
choice61 = contents[5][2]
choice62 = contents[5][3]
answer61 = contents[5][4]
question7 = contents[6][1]
choice71 = contents[6][2]
choice72 = contents[6][3]
answer71 = contents[6][4]
question8 = contents[7][1]
choice81 = contents[7][2]
choice82 = contents[7][3]
answer81 = contents[7][4]
question9 = contents[8][1]
choice91 = contents[8][2]
choice92 = contents[8][3]
answer91 = contents[8][4]
question10 = contents[9][1]
choice101 = contents[9][2]
choice102 = contents[9][3]
answer101 = contents[9][4]
topic = contents[11][1]
puts "Welcome to this " + topic + " quiz. Please spell the answers exactly right to get them correct (don't worry about caps). Good Luck!"
puts question1
puts choice11 + " or " + choice12 + "?"
user1 = gets.chomp
if user1.downcase == answer11.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
puts "Next question: " + question2
puts choice21.downcase + " or " + choice22 + "?"
user2 = gets.chomp
if user2.downcase == answer21.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
puts "Next question: " + question3
puts choice31.downcase + " or " + choice32.downcase + "?"
user3 = gets.chomp
if user3.downcase == answer31.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
puts "Next question: " + question4
puts choice41.downcase + " or " + choice42.downcase + "?"
user4 = gets.chomp
if user4.downcase == answer41.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
puts "Next question: " + question5
puts choice51.downcase + " or " + choice52.downcase + "?"
user5 = gets.chomp
if user5.downcase == answer51.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
puts "Next question: " + question6
puts choice61.downcase + " or " + choice62.downcase + "?"
user6 = gets.chomp
if user6.downcase == answer61.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
puts "Next question: " + question7
puts choice71.downcase + " or " + choice72.downcase + "?"
user7 = gets.chomp
if user7.downcase == answer71.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
puts "Next question: " + question8
puts choice81.downcase + " or " + choice82.downcase + "?"
user8 = gets.chomp
if user8.downcase == answer81.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
if user9.downcase == answer91.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
puts "Next question: " + question10
puts choice101.downcase + " or " + choice102.downcase + "?"
user10 = gets.chomp
if user10.downcase == answer101.downcase
puts "correct"
else
puts "incorrect" and correct_count -1
end
puts "you got" + correct_count + "out of 10 correct"
Change:
puts "you got" + correct_count + "out of 10 correct"
to:
puts "you got" + correct_count.to_s + "out of 10 correct"
or:
puts "you got #{correct_count} out of 10 correct"
NOTE:
correct_count = 10
puts "incorrect" and correct_count -1
correct_count # => 10
# >> incorrect
correct_count still evaluates to 10.
You should be doing:
if user6.downcase == answer61.downcase
puts "correct"
else
puts "incorrect"
correct_count -= 1
end
Related
I am working through Chris Pine's Chapter 6 Deaf Grandman challenge. It looks very readable however I wonder if this is violating the DRY principle. If so, how can I refactor it?
puts "WHAT DID YOU SAY??"
said = gets.chomp
x = 0
bye_counter = 0
while bye_counter < 3
if said != said.upcase
puts "HUH?! SPEAK UP, SONNY!"
said = gets.chomp
bye_counter = 0
elsif said == said.upcase && said != "BYE"
puts "NO, NOT SINCE " + rand(1930..1950).to_s + "!"
bye_counter = 0
said = gets.chomp
elsif said == "BYE"
puts "HUH??"
bye_counter += 1
break if bye_counter == 3
said = gets.chomp
end
end
puts "OH.. OK!"
My solution:
message = "WHAT DID YOU SAY??"
bye_counter = 0
puts message
while bye_counter < 3
said = gets.chomp
if said == "BYE"
message = "HUH??"
bye_counter += 1
else
if said == said.upcase
message = "NO, NOT SINCE " + rand(1930..1950).to_s + "!"
else
message = "HUH?! SPEAK UP, SONNY!"
end
bye_counter = 0
end
break if bye_counter == 3
puts message
end
puts "OH.. OK!"
Having some trouble checking for multiple sets of values.
loop do
turns(player1,player2)
break puts "you win!" if #entries.values[0..2].all?{|move| move == "X"}
end
I wanted to use a multi-dimensional hash like this. Is my syntax wrong or is this just something you cannot do?
loop do
turns(player1,player2)
break puts "you win!" if #entries.values[[0..2][3..5]].all?{|move| move =="X"}
end
another problem is when values[0..2] are already equal to "x" the loop doesn't break until the next turn.
Here is the repl
https://repl.it/JrQe/57
Source code
#entries = {1=>" ", 2=>" ", 3=>" ", 4=>" ", 5=>" ", 6=>" ", 7=>" ", 8=>" ", 9=>" "}
puts "###########################################"
puts " tic-tac-toe"
puts "\t\t 1 | 2 | 3 "
puts "\t\t-----------"
puts "\t\t 4 | 5 | 6 "
puts "\t\t-----------"
puts "\t\t 7 | 8 | 9 "
puts" ###########################################"
class Players
attr_accessor :name, :piece
end
puts "Player one, what is your name?"
player1 = Players.new
player1.name = gets.chomp
player1.piece = "X"
puts "Hello #{player1.name}, you have been assigned #{player1.piece}."
puts "Player two, what is your name?"
player2 = Players.new
player2.name = gets.chomp
player2.piece = "O"
puts "Hello #{player2.name}, you have been assigned #{player2.piece}."
def grid
puts "\t\t #{#entries[1]} | #{#entries[2]} | #{#entries[3]} "
puts "\t\t-----------"
puts "\t\t #{#entries[4]} | #{#entries[5]} | #{#entries[6]} "
puts "\t\t-----------"
puts "\t\t #{#entries[7]} | #{#entries[8]} | #{#entries[9]} "
end
def choice(grid)
name = gets.chomp
name2 = name.to_i
#entries.each do |key,value|
if name2 == key
#entries[key]= "X"
end
end
end
def choice2(grid)
name = gets.chomp
name2 = name.to_i
#entries.each do |key,value|
if name2 == key
#entries[key]= "O"
end
end
end
def turns(player1,player2)
puts "#{player1.name} make your move"
player1 = choice(grid)
puts "#{player2.name} make your move"
player2 = choice2(grid)
end
def win
loop do
turns(player1,player2)
break puts "you win!" if #entries.values[0..2].all?{|move| move == "X"}
end
I think the specific question you're asking is answered like this:
rows = [[0..2],[3..5],[6..8]]
cols = [[0,3,6],[1,4,7],[2,5,8]]
diag = [[0,4,8],[2,4,6]]
(rows + cols + diag).any?{ |line| line.all?{ |cell| #entries[cell] == "X"} }
Also, you can't have two expressions, break and puts before a trailing if statement. Try this:
if ...
puts "You win!"
break
end
I'm a total beginner in ruby but I can't get out of this issue
I get these when I run the code, it all works well until the end:
INPUT TEXT: It all works well until
INPUT SUBTEXT: ll
TEXT: It all works well until SUBTEXT: ll
OUTPUT:
4
15
undefined method +' for nil:NilClass
(repl):18:ininitialize'
puts "\nINPUT TEXT:"
#text = gets.chomp
puts "\nINPUT SUBTEXT:"
#subtext = gets.chomp
puts "\nTEXT: " + #text
puts "SUBTEXT: " + #subtext
puts "\n"
i = #text.index (#subtext)
puts "OUTPUT:"
while i != -1
puts i.to_s + ' '
i = #text.index #subtext, i+1
end
In Ruby, String#index doesn't return -1 when the substring is not found; it returns nil. Change your condition from while i != -1 to while i. (This works because, unlike some other languages, Ruby considers the value 0 to be true; only false and nil are false.)
Index return nil if substrings doesn't exist. So this should solve this issue
#text = gets.chomp
puts "\nINPUT SUBTEXT:"
#subtext = gets.chomp
puts "\nTEXT: " + #text
puts "SUBTEXT: " + #subtext
puts "\n"
i = #text.index (#subtext)
puts "OUTPUT:"
while i
puts i.to_s + ' '
i = #text.index #subtext, i+1
end
I hope I'm not too annoying . I started ruby 2 weeks ago.
I'm trying to put my calculator in a loop so it restart after calculation ends. Something like "Would you like to try again?"
def add(a, b)
puts "ADDING #{a} + #{b}"
puts "The result is #{a + b}"
end
def arg1()
puts "You chose option 1"
print "please enter first entry "
first_number = gets.to_i
print "Please enter second entry "
second_number = gets.to_i
add(first_number,second_number)
end
def selection()
puts "please enter your option : "
puts "For Adding : 1 "
puts "For Subtacting : 2 "
print "> "
end
selection
options_of_choice = gets.to_i
if options_of_choice == 1
arg1()
elsif options_of_choice == 2
arg2()
else
puts " Restarting"
end
calculator_on = true
while calculator_on
selection
options_of_choice = gets.to_i
if options_of_choice == 1
arg1()
elsif options_of_choice == 2
arg2()
else
puts " Restarting"
end
puts "do you want to try again?"
calculator_on = gets.chomp.downcase == 'y'
end
I am attempting to write a game. In the following code, it keeps skipping to the bottom else even if a valid integer is entered. Why?
puts 'You will be O\'s and I will be X\'s'
puts
puts '1,2,X'
puts '4,5,6'
puts '7,8,9'
puts
puts 'Your move...'
puts
moveOne = gets.chomp
if moveOne == 5
puts = '1,2,X'
puts = '4,O,6'
puts = 'X,8,9'
elsif moveOne == 1
puts = 'O,2,X'
puts = '4,5,6'
puts = 'X,8,9'
elsif moveOne == 7
puts = 'X,2,X'
puts = '4,5,6'
puts = 'O,8,9'
elsif moveOne == 9
puts = 'X,2,X'
puts = '4,5,6'
puts = '7,8,O'
elsif moveOne == 2
puts = '1,O,X'
puts = '4,X,6'
puts = '7,8,9'
elsif moveOne == 4
puts = '1,2,X'
puts = 'O,X,6'
puts = '7,8,9'
elsif moveOne == 6
puts = '1,2,X'
puts = '4,X,O'
puts = '7,8,9'
elsif moveOne == 8
puts = '1,2,X'
puts = '4,X,6'
puts = '7,O,9'
else
puts'please enter a number!'
end
puts
puts 'Your move again'
Because chomp is giving you a string, not an integer.
moveOne = gets.chomp.to_i
This is happening because gets.chomp returns a String, not an Integer. if you do:
"a".to_i --> 0 , Which your program might think the user has actually entered a 0.
So, first, you want to make sure that what the user has entered is a number character, even though it's of class String.
Here is what you could do:
1 - Create a method that will check if a String is number-like:
def is_a_number?(s)
s.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end
2 - If it is number like, just cast it to integer using .to_i
So, your code would look like:
moveOne = gets.chomp
if is_a_number?(moveOne)
number_entered = moveOne.to_i
if number_entered == 5
...
elsif number_entered == 1
...
else
puts "enter a number..."
end