Ruby Fibonacci custom function - ruby

I am trying to write a simple custom function for fibonacci, But i am getting a error:
My code :
class Fibonacci
def fib(num)
#num = num.to_i
series = Array.new
series[0] = 0
series[1] = 1
for i in 0..series[#num]
series[#num+2] = series[#num] + series[#num+1]
end
return series
end
end
obj = Fibonacci.new
obj.fib(8)
Error :
ruby fibonacci.rb
fibonacci.rb:9:in `fib': bad value for range (ArgumentError)
from fibonacci.rb:19:in `<main>'

You're getting ArgumentError from 0..series[#num], where series[#num] will be nil at that point.
I think you meant to have:
for i in 0..#num
series[i+2] = series[i] + series[i+1]
end

Related

Ruby - no implicit conversion of Array into String

I am getting an error when executing my test.
Failure/Error: expect(industry_sic_code).to include page.sic_code
TypeError:
no implicit conversion of Array into String
# ./spec/os/bal/company/company_filter_clean_harbors_industries_stub.rb:62:in `block (2 levels) in <top (required)>'
The Method:
def sic_code
subtables = #b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
subtables.each do |subtable|
if subtable.tbody.h4.text == "US SIC 1987:"
subtable.tr.next_siblings.each do |tr|
codes = tr.cell
puts codes.text.to_s
end
end
end
end
The Test:
it 'Given I search for a random Clean Harbors Industry' do
#Pick a random clean industry from the file
data = CSV.foreach(file_path, headers: true).map{ |row| row.to_h }
random = data.sample
random_industry = random["Class"]
industry_sic_code = random["SIC Code"]
end
it 'Then the result has the expected SIC code' do
page = DetailPage.new(#b)
page.view
expect(industry_sic_code).to include page.sic_code
end
I have tried to implicitly change each variable to a string but it still complain about the array issue.
When I include some puts statments, I get some really wonky responses. The method itself returns the expected result.
When I used the method in the test I end up with the code gibberish below.
here are the sic codes from the method
5511
Here are the codes from the test
#<Watir::Table:0x00007fa3cb23f020>
#<Watir::Table:0x00007fa3cb23ee40>
#<Watir::Table:0x00007fa3cb23ec88>
#<Watir::Table:0x00007fa3cb23ead0>
#<Watir::Table:0x00007fa3cb23e918>
#<Watir::Table:0x00007fa3cb23e738>
#<Watir::Table:0x00007fa3cb23e580>
Your sic_code method returns subtables array, that's why you have this error. It doesn't matter that the method puts something, every method in ruby implicitly returns result of its last line, in your case it is subtables.each do ... end, so you have an array.
You need to explicitly return needed value. Not sure if I correctly understood what are you doing in your code, but try something like this:
def sic_code
subtables = #b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
result = [] # you need to collect result somewhere to return it later
subtables.each do |subtable|
if subtable.tbody.h4.text == "US SIC 1987:"
subtable.tr.next_siblings.each do |tr|
codes = tr.cell
result << codes.text.to_s
end
end
end
result.join(', ')
end

Ruby return with double quotes

Hi I have a string passed back from rspec.
It should show
"alias/public_html/ab1/ab2/"
but I am getting "\"alias/public_html/ab1/ab2/\""
I am getting the rspec error below:
WebServer::HttpdConf#alias_path returns the aliased path
Failure/Error: expect(httpd_file.alias_path('/ab/')).to eq 'alias/public_html/ab1/ab2/'
expected: "alias/public_html/ab1/ab2/"
got: "\"alias/public_html/ab1/ab2/\""
(compared using ==)
# ./spec/lib/config/httpd_conf_spec.rb:90:in `(root)'
And here is my actual program file
def alias_path(path)
#hash_httpd['Alias'][path]
end
Please help
EDIT
Sorry, I am new to RUby, here is the httpd_file
def initialize(httpd_file_content)
#hash_httpd = Hash.new
httpd_file_content.each_line do | line |
#commands = line.split
if #commands.length == 2
#hash_httpd[#commands[0]] = #commands[1]
else
if !#hash_httpd.has_key?(#commands[0])
al = Hash.new
#hash_httpd[#commands[0]] = al
else
al = #hash_httpd[#commands[0]]
end
al[#commands[1]] = #commands[2]
end
end
end
If you are sure that your alias_path output will be "alias/public_html/ab1/ab2/", then you can just modify your alias_path method definition by removing the quotes (if any) from the returned path:
def alias_path(path)
#hash_httpd['Alias'][path].gsub('"', '')
end

Ruby: Undefined Method `<'

As a way to learn the ins and outs of ruby, I decided to make a (relatively simple) text-based RPG. Everything so far has gone well, except recently I've hit a roadblock that I haven't seen before.
My goal is: if any stat (str, def, agi, man) is < 0, I want to make it = 0. For some reason though, ruby doesn't seem to like the `<'.
Here's the code ruby hangs up on:
def self.compile
#str = ProfileData.load['g_str']
#def = ProfileData.load['g_def']
#agi = ProfileData.load['g_agi']
#man = ProfileData.load['g_man']
#smin = 1
#dmin = 1
#amin = 1
#mmin = 1
if #str < #smin
#str = 0
end
if #def < #dmin
#def = 0
end
if #agi < #amin
#agi = 0
end
if #man < #mmin
#man = 0
end
#str.round!
#def.round!
#agi.round!
#man.round!
d = YAML::load_file('./profile')
d['mstr'] = #str
File.open('./profile', 'w') {|f| f.write d.to_yaml}
d = YAML::load_file('./profile')
d['mdef'] = #def
File.open('./profile', 'w') {|f| f.write d.to_yaml}
d = YAML::load_file('./profile')
d['magi'] = #agi
File.open('./profile', 'w') {|f| f.write d.to_yaml}
d = YAML::load_file('./profile')
d['mman'] = #man
File.open('./profile', 'w') {|f| f.write d.to_yaml}
end
Now when I run through my program, I get this error code when it finally runs "compile":
start.rb:734:in `compile': undefined method `<' for []:Array (NoMethodError)
And that's it. Have any clue what's happened or how I can fix it? Any help is very much appreciated!
It means your variables (at leas one per compared pair) is of Array type.
Check what each of these
#str = ProfileData.load['g_str']
#ddef = ProfileData.load['g_def']
#agi = ProfileData.load['g_agi']
#man = ProfileData.load['g_man']
returns and make sure it is Comparable (integers, for example).
The load method seems to assume that would be a collection of variables, even you having just one.
If you grant to be always one, select just the first and as it may be a string you should make it a int.
#str = ProfileData.load['g_str'].first.to_i

Undefined method when trying to square each element in array

I am trying to write a method called square_digits that squares every digit in a given number. I wrote:
def square_digits(num)
number_array = num.to_s.split("")
num_to_int = number_array.to_i
num_squared = num_to_int.each{|n| n**2}
return num_squared.join("")
end
When trying to run square_digits(3212), which should return 9414, I get the following error message:
`block in square_digits': undefined method `**' for "3":String (NoMethodError)
from `each'
from `square_digits'
from `
'
I'm not quite sure what I should do to fix it; any suggestions?
Hmm there are a few problems here:
With the input 123 it should error on:
num_to_int = number_array.to_i
With:
NoMethodError: undefined method 'to_i' for ["1","2","3"]:Array
You want:
num_to_int = number_array.map(&:to_i)
Also
num_squared = num_to_int.each{|n| n**2}
doesn't return the results of each just the original array.
So with the first fix it will just return "123"
you want:
num_squared = num_to_int.map{|n| n**2}
So the final function looks like:
def square_digits(num)
number_array = num.to_s.split("")
num_to_int = number_array.map(&:to_i)
num_squared = num_to_int.map{|n| n**2}
return num_squared.join("")
end
Although i'm confused about what you are trying to achieve.
You can also try this ;)
def square_digits(num)
num.to_s.split('').map { |n| n.to_i ** 2 }.join("")
end
Or
def square_digits(num)
num.to_s.chars.map { |n| n.to_i ** 2 }.join("")
end

Dynamically check if a field in JSON is nil without using eval

Here's an extract of the code that I am using:
def retrieve(user_token, quote_id, check="quotes")
end_time = Time.now + 15
match = false
until Time.now > end_time || match
#response = http_request.get(quote_get_url(quote_id, user_token))
eval("match = !JSON.parse(#response.body)#{field(check)}.nil?")
end
match.eql?(false) ? nil : #response
end
private
def field (check)
hash = {"quotes" => '["quotes"][0]',
"transaction-items" => '["quotes"][0]["links"]["transactionItems"]'
}
hash[check]
end
I was informed that using eval in this manner is not good practice. Could anyone suggest a better way of dynamically checking the existence of a JSON node (field?). I want this to do:
psudo: match = !JSON.parse(#response.body) + dynamic-path + .nil?
Store paths as arrays of path elements (['quotes', 0]). With a little helper function you'll be able to avoid eval. It is, indeed, completely inappropriate here.
Something along these lines:
class Hash
def deep_get(path)
path.reduce(self) do |memo, path_element|
return unless memo
memo[path_element]
end
end
end
path = ['quotes', 0]
hash = JSON.parse(response.body)
match = !hash.deep_get(path).nil?

Resources