A Ruby class to compare the characters in two strings - ruby

I'm trying to complete an exercism.io test file which compares two strings and adds one to a counter each time there is a difference between the two strings. I've written my class, but for some reason it won't run in terminal. I've compared my code with several examples of syntax online and don't see why it won't run. Any help would be much appreciated.
Here's my class:
class Hamming
def compute(str1, str2)
distance = 0
length = str1.length
for i in 0..length
if str1[i] != str2[i] then
distance++
end
end
return distance
end
end
And here's a relevant bit of test file:
class HammingTest < Minitest::Test
def test_identical_strands
assert_equal 0, Hamming.compute('A', 'A')
end
end
Lastly, here's the error I'm getting:
hamming_test.rb:4:in `require_relative': /Users/Jack/exercism/ruby/hamming/hamming.rb:8: syntax error, unexpected keyword_end (SyntaxError)
/Users/Jack/exercism/ruby/hamming/hamming.rb:12: syntax error, unexpected end-of-input, expecting keyword_end
from hamming_test.rb:4:in `<main>'

You don't need then after condition in if statement.
Use two spaces instead of four for indentation in Ruby.
(Direct cause of your error) there's no ++ operator in Ruby. You should have
distance += 1

Related

ruby optionnal argument unexpected *

I have this very simple piece of code (using Ruby 3)
def eat(main, dessert*)
if dessert.empty?
puts "I eat #{main}"
else
puts "I eat #{main} than #{dessert}."
end
end
Wher I run eat("mushrooms") that provokes errors:
argu.rb:1: syntax error, unexpected '*', expecting ')'
def manger(plat, dessert*)
argu.rb:7: syntax error, unexpected `end', expecting end-of-input
I don't see why.
Splat operator should put before parameters so your signature should be
def eat(main, *dessert)
Not sure where you got the idea from using dessert*, but you could define your method as
def eat(main, dessert = [])
to provide a default argument (of course it must be one which can respond to empty?).
Of course it is up to you to justify, why "main" can be anything (i.e. a String), but dessert must be a collection. I would test for dessert as
if dessert.nil?
and hence provide nil as default value for the dessert.

How to avoid unexpected end of input error when adding extra method argument [duplicate]

This question already has answers here:
Why does white-space affect ruby function calls?
(2 answers)
Closed 6 years ago.
I am testing a method with multiple arguments. For some reason, Ruby will run fine if I have just one argument to the calculate() method, but when I add a second, it causes an unexpected end of input error.
This is the code:
def set_weights
actual_weight = #desired_weight.to_i - 45
calculate (actual_weight, 65)
end
def calculate (remaining_weight, plate_weight)
end
The error message is:
weights.rb:31: syntax error, unexpected ',', expecting ')'
calculate (actual_weight, 45)
^
If I remove the second argument, I get no errors.
def set_weights
actual_weight = #desired_weight.to_i - 45
calculate (actual_weight)
end
def calculate (remaining_weight)
end
Define a function:
irb(main):012:0> def add(x, y) x+y end
`=> nil
If you call it without a space between the arguments and the function:
irb(main):013:0> add(5,6)
=> 11
With the space:
irb(main):014:0> add (5,6)
SyntaxError: (irb):14: syntax error, unexpected ',', expecting ')'
add (5,6)
^
from /usr/bin/irb:12:in `<main>'
The extra space before the argument list causes the interpreter to throw a SyntaxError. Since ruby functions can be run with or without parens, including a space makes the interpreter think it is about to receive arguments for the function - instead it receives a tuple (5,6).
Remove the space and your code will run correctly.
Remove the extra space before the method call, like this:
def set_weights
actual_weight = #desired_weight.to_i - 45
calculate(actual_weight, 65)
end
def calculate (remaining_weight, plate_weight)
end

Ruby: unexpected end-of-input, expecting keyword_end for if statement

I was working with Java for a few months and am transitioning back to Ruby now. I am getting a weird error from the following code:
def count_divisors
divisor_hash = {}
25.times do |i|
divisor_hash[i] = find_dividends(i)
end
puts divisor_hash
end
def find_dividends(i)
count = 0
1000.times do |k|
if i % ( k + 1 ) == 0
count++
end
end
count
end
count_divisors()
This code is generating the following error:
test.rb:14: syntax error, unexpected keyword_end
test.rb:19: syntax error, unexpected end-of-input, expecting keyword_end
This error does not occur when I remove the if statement. I am not sure why. I know every if statement needs an end statement, for some reason it seems upset by the placement of that end statement though.
Change the count++ to count += 1 Ruby does not support incremental operator.

Ruby '{x}' block works, but 'do |x|' block does not?

I'm writing a method and for some reason it's throwing an error whenever I run an each block like this:
array.each do |i|
something_on_i
end
But, it's not throwing an error when I do the same thing like this:
array.each {|i| something_on_i}
Why? I thought the two were identical.
Here's the full code:
Working:
def factor(num)
i=2
factors=[1]
while i<=num
if (num % i == 0)
factors << i
end
i+=1
end
return factors
end
def Division(num1,num2)
facs1=factor(num1)
facs2=factor(num2)
common=[]
***facs2.each {|i| common << i if facs1.include?i}***
return common.max
end
# keep this function call here
# to see how to enter arguments in Ruby scroll down
Division(STDIN.gets)
Not working:
def factor(num)
i=2
factors=[1]
while i<=num
if (num % i == 0)
factors << i
end
i+=1
end
return factors
end
def Division(num1,num2)
facs1=factor(num1)
facs2=factor(num2)
common=[]
***facs2.each do |i|
if facs1.include?(i)
common << i
end
end***
return common.max
end
# keep this function call here
# to see how to enter arguments in Ruby scroll down
Division(STDIN.gets)
The error I get is:
(eval):334: (eval):334: compile error (SyntaxError)
(eval):323: syntax error, unexpected kDO_COND, expecting kEND
facs2.each do |i|
^
(eval):324: syntax error, unexpected tIDENTIFIER, expecting kDO or '{' or '('
(eval):334: syntax error, unexpected kEND, expecting $end
Thanks to the great help in the comments from everyone, it appears this is just an issue with Coderbyte and Repl.it, rather than an issue with the code itself. The code runs just fine in irb. #Darek Nedza pointed out that Coderbyte and Repl.it are only running Ruby 1.8.7, which is likely the problem.
Solution:
For strange errors on Repl.it or Coderbyte, just double check in irb

repl.it Ruby interpreter : error when defining multiple functions containing loops

I'm relatively new to programming and even newer to Ruby, and I've been using the repl.it Ruby interpreter to test code. However, I've run into the same problem multiple times now whenever I try to enter in multiple function definitions that contain loops -- I inevitably get an error message that looks like this:
(eval):350: (eval):350: compile error (SyntaxError)
(eval):344: syntax error, unexpected kDO_COND, expecting kEND
(eval):350: syntax error, unexpected kEND, expecting $end
Does anyone know what the problem is and how to avoid this? It doesn't look like a code error per se, since my code seems to run fine with codepad. But I've been told to use this specific interpreter to test code for a program I'm applying to.
Here's my code (I'm testing two different methods I wrote to reverse a string, one in place and the other using a new output list):
def reverse(s)
#start by breaking the string into words
words = s.split
#initialize an output list
reversed = []
# make a loop that executes until there are no more words to reverse
until words.empty?
reversed << words.pop.reverse
end
# return a string of the reversed words joined by spaces
return reversed = reversed.join(' ')
end
def reverse_string(s)
# create an array of words and get the length of that array
words = s.split
count = words.count #note - must be .length for codepad's older Ruby version
#For each word, pop it from the end and insert the reversed version at the beginning
count.times do
reverse_word = words.pop.reverse
words.unshift(reverse_word)
end
#flip the resulting word list and convert it to a string
return words.reverse.join(' ')
end
a = "This is an example string"
puts reverse(a)
puts reverse_string(a)
Your code is fine; their interpreter is old. If you change the block syntax that you use with times, e.g.
count.times {
reverse_word = words.pop.reverse
words.unshift(reverse_word)
}
...suddenly it works.

Resources