Rails iteration math operator causes a wrong number of arguments - ruby

This iteration prints the highest index value.
It works and prints 8 eight times.
- #videos.each_with_index do |video, index|
= index.size
When I add a math operator it doesn't work and gives me this error: wrong number of arguments (1 for 0)
- #videos.each_with_index do |video, index|
= index.size - 1

index in your example is a Fixnum, the index of the element in the enumeration. Fixnum#size returns the number of bytes in the machine representation of a Fixnum. Probably not what you were looking for. It accepts zero arguments which explains the exception you got.
The fact that index.size returns 8 is because you're running on a 64bit architecture and has nothing to do with the size of #videos.

It seems like:
index.size - 1
is being interpreted as:
index.size(-1)
Try adding in parenthesis to force it to be interpreted in the correct way:
(index.size) - 1
or:
index.size() - 1

Related

`sum` function not working as expected in case of large strings

In Ruby, #sum is used to calculate
Sum of array
Sum of an array based on a function or condition
Sum of ASCII codepoints (ord) in a string (not char array) i.e. 'abcd'.sum # => 394
The problem with the third one is the following
For the string below,
AwotIJHOAIJSRoieJHOjasOIADaoiHAOHJAOIJGOIajdOIQWJTOIGJDOINCOIASORIOGIMAOIMEORIQEMOIGMEOIFMASKDJQOWJGOJOASJOIQWOGIMASOIDMOQWIROQIGJOIAMSFOAIJGIHIWUNVNZMXCNXCKJQOWRIEOGSDGSPOKSDLAMKMROQIJRDFLKMZXOIAJSQPIRKLMAdglkaSFAJOIAJFOIQWJEOIQJKAMCLKACMALKSDLAKWEQANLEIRJRQFIJAOIVAWOTIJHOAIJSROIEJHOJASOIADAOIHAOHJAOIJGOIAJDOIQWJTOIGJDOINCOIASORIOGIMAOIMEORIQEMOIGMASODLQWKEJOIFJLKMALSKQIOWELKMZLXKMFALSFJQOIWEAOISFWIDHGPSODRJAWOPIJHOIDJOIAJTGIOJAORAJWOIJHOFMAOIFMOIPDMOAIPWJTOPIJDOIFjawoiRJOIpjmaioGJIGHAIJRHQHQIUEIvnaksJDNWIORQIOPEGHIDVNAJKNASIPHRQEUITHIUHDNAJSNWIHJQIWJQEOIGOIDVNAKOSDNAOPWPJQOPIWTJQEOIPGDPJFNASPJNQWOIRQWIOTOIVNAKSFNAIOAWOTIJHOAIJSROIEJHOJASOIADAOIHAOHJAOIJGOIAJDOIQWJTOIGJDOINCOIASORIOGIMAOIMEORIQEMOIGMASODLQWKEJOIFJLKMALSKQIOWELKMZLXKMFALSFJQOIWEAOISFWIDHGPSODRJAWOPIJHOIDJoiajTGIOJAORAJWOIJHOFMAOIFMOIPDMOAIPWJTOPIJDOIFJAWOIRJOIPJMAIOGJIGHAIJRHQHQIUEIVNAKSJDNWIORQIOPEGHIDVIPNWIHJQIWJQEOIGOIDVNAKOSDNAOPWPJQOPIWTJqeoIPGDPJFNASPJNQWJQWOIRJgonasKFAWOEJQWOIJOGALKFNASLFKqeqOFIJAOISFJAOISFJAWOI
which is large, (of 1000 characters), the following program doesn't work
putc gets.upcase.sum/~/$/
It works for all other strings of lesser size. The output of the above must be K. But it shows \9
But if I do this
putc gets.upcase.chars.sum(&:ord)/~/$/
It shows K. But the former one gives the correct output for all the other string except the large ones like this.
What is wrong here?
EDIT : Try it Online link
Try it online!
Sum of ASCII codepoints (ord) in a string (not char array) i.e. 'abcd'.sum # => 394
I've actually never heard of String#sum before, despite being fairly knowledgeable in the language. So I looked it up:
Returns a basic n-bit checksum of the characters in str, where n is the optional Integer parameter, defaulting to 16. The result is simply the sum of the binary value of each byte in str modulo 2**n - 1. This is not a particularly good checksum.
And sure enough, using your example input string, that's why we get:
str.chars.map(&:ord).sum
# => 77090
str.sum
# => 11554
The values are different because 77090 > 2**15. Moreover, 77090 % 2**15 == 11554.
If you use a larger value for n, the (check)sum is what you expected:
str.sum(100)
#=> 77090

Why does my function outputting expected and unexpected values in ruby?

I have a method called fibs_rec that results in an unexpected output:
def fibs_rec(n)
if n == 1 || n == 0
return 1
else
a = fibs_rec(n-1) + fibs_rec(n-2)
puts a
return a
end
end
fibs_rec(5)
The call fibs_rec(5) should return 1,1,2,3,5 but here is the actual output:
2
3
2
5
2
3
8
Not only is the output incorrect, it lacks a number from the beginning.
Can someone explain why is this happening?
This is correct since your recursion is splitting into two sub-problems every time it recurses. If you want the series to appear properly then you should try doing this via dynamic programming for O(n) time complexity. As is, the first and second position won’t be printed because of the base case in the recursion.
As for the incorrect answer, it seems you have not accounted for the sequence starting with 0 index. Either find 4 index in the function which will give the fifth element or modify your function to work with position instead of index.

Beginner array iteration & error code interpretation

I kept getting the following error. After some research I assumed this is because my array access was throwing the error due to (mistakenly) having a NIL value.
my_solution.rb:24:in `count_between': undefined method `>=' for nil:NilClass
(NoMethodError) from my_solution.rb:35:in `<main>'
I'm new to reading error codes, so perhaps that's where I went wrong. But it got tunnel vision on line 24, as the error suggested. However I couldn't fix it, so out of desperation I wound up randomly changing the (<=) on line 23 to just (<). This fixed it.
Why did this fix it? My only guess is that originally using (<=) made it iterate "too far" and thus somehow returned NIL?
Why did the error code say it was the element on line 24 causing the issue, when it was actually the element on line 23? I'm new and am trying to be less intimated by error codes, so this was a curious experience.
Thanks for any guidance.
# count_between is a method with three arguments:
# 1. An array of integers
# 2. An integer lower bound
# 3. An integer upper bound
#
# It returns the number of integers in the array between the lower and upper
# bounds,
# including (potentially) those bounds.
#
# If +array+ is empty the method should return 0
# Your Solution Below:
def count_between(list_of_integers, lower_bound, upper_bound)
if list_of_integers.empty?
return 0
else
count = 0
index = 0
##line 23##
while index <= list_of_integers.length
##line24##
if list_of_integers[index] >= lower_bound &&
list_of_integers[index] <= upper_bound
count += 1
index += 1
else
index += 1
end
end
return count
end
end
puts count_between([1,2,3], 0, 100)
The last index that's <= list_of_integers.length is outside of the array, since the first index of an array is 0 and the last is array.length - 1.
The reason your error says line 24 is that line 23 works fine --- it just computes that the value of index is less than or equal to the the length of the array. Once you try and reference the element at that index in the array, however, it's assigned nil - and you can't perform a >= operation on nil.
One thing that might be helpful here is firing up an irb. If you try to reference an element that's out of bounds, you'll just get nil. If you try and perform an operation (that's not listed in nil.methods) on that same reference, it'll throw the error you're seeing.

`<=': comparison of String with nil failed (ArgumentError)

I am testing whether array elements are greater than or equal to elements of smaller indices.
I get the error message from the subject line if I use the following loop
return true if order.each_index {|i| order[i ] <= order[i+1]}
I understand the last element of my array(order) can't be compared to a non-existant element.
Comparing a value to nil is impossible.
I don't, however understand why the following loop doesn't return the same error
(0...(order.length - 1)).all? do |i|
order[i] <= order[i + 1]
end
It seems that at some point, i = order.length-1
This means order[i+1] is a nil value (order.length)
Apparently not?
No, because three dots ... here (0...(order.length - 1)) mean 'without last element', so last value would be order.length - 2.
You'll encounter the same error if you try (0..(order.length - 1)).
Check Range documentation:
Ranges may be constructed using the s..e and s...e literals
Those created using ... exclude the end value

How do I add a number to a hash?

In my code I have a hash, each one with a set value of 0, after running through the code, I would like it to display "1", but it only displays a 0. Can anyone help, and please explain my error and why it didn't work.
puts "Hello!, and welcome to the 'Coin Calculator V1.0', please enter a value."
coin_value = gets.to_i
coin_num = {"quarters" => 0,"dimes" => 0,"nickels" => 0,"pennies" => 0}
if coin_value>25
coin_value-25
coin_num["quarters"]+1 // **basically, how do I add an integer value to the old integer?
puts coin_num["quarters"]
end
coin_num["quarters"] = coin_num["quarters"] + 1
which can be shortened using the += operator (addition assignment):
coin_num["quarters"] += 1
Neither of your arithmetic expressions changes anything.
coin_value - 25
That evaluates to 25 less than coin_value; if you printed it out or assigned it somewhere, you would see that. But since you don't do anything with the value, it just gets thrown away and nothing happens. Certainly, coin_value doesn't change.
Similarly,
coin_num["quarters"] + 1
evaluates to one more than the current value of coin_num["quarters"], but doesn't change anything.
If you want to change the value of a variable - any variable, whether a simple scalar like coin_value or an element of a Hash or Array - you have to use an assignment statement. You need an =, and the variable you want to change has to be on the left hand side of that =:
coin_value = coin_value - 25
coin_num['quarters'] = coin_num['quarters'] + 1
Ruby does define shorthand operators for modifying a variable using a simple expression involving that same variable's previous value:
coin_value -= 25
coin_num['quarters'] += 1
But you're still using = - it's just part of a compound assignment operator now.

Resources