Undefined method when trying to square each element in array - ruby

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

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 Fibonacci custom function

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

NoMethodError - template.rb:38:in `<main>': undefined method `template' for main:Object (NoMethodError)

Here is my code I'm trying to run the method but it keeps on kicking out a NoMethodError: undefined method 'template' for main:Object
Can someone please help?
module Template
attr_accessor :source_template, :req_id
def initialize (source_template, req_id)
#source_template = source_template
#req_id = req_id
end
def self.template(source_template, req_id)
template = String.new(#source_template)
template_split_begin = template.index("e")
template_split_end = template_split_begin + 6
template_part_one =
String.new(self.template[0..(template_split_begin-1)])
template_part_two =
String.new(self.template[template.length..template_split_end])
code = String.new(#req_id)
final_template =
String.new(template_part_one + code + template_part_two)
template_split_begin_alt = template.index("a")
template_split_end_alt = template_split_begin_alt + 9
template_alt =
String.new(self.template[0..(template_split_begin_alt-1)])
template_part_two =
String.new(self.template[template.length..template_split_begin_alt])
altcode = code[5..7] - code[0..4]
final_alt_template =
String.new(template_part_one_alt + altcode + template_part_two_alt)
end
end
sample = "Green", 8
template("Blue", 6)
Ok, I think I need deeper explanation.
You can't get the module instance, thus your initialize method is meaningless. You should use it only with classes.
attr_accessor :source_template, :req_id makes no sense in your code
sample = "Green", 8 is unused variable
You call template("Blue", 6) on an object, not on your module, where it's defined, that's why I said you should use Template.template("Blue", 6)
If you had changed it, you would haven't got this error anymore. But from your code seems like you are missing basic knowledge of the language, so I would recommend you to read some book about Ruby, before diving into coding.

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

What's causing this Ruby "can't convert Mongo::Cursor into Integer" error?

I am using the Mongo Ruby driver and have this block of Ruby code before and after line 171 in my code, which is apparently the source of the error below it (the query.each line is line 171):
query = get_callback.call( "databases", id )
if query.count > 0
puts query.count.inspect + " results: " + query.inspect
res = {}
query.each do |result|
puts result.inspect
end
else
puts "No results" + res.inspect
res = {}
end
The error:
1 results: <Mongo::Cursor:0x3fc15642c154 namespace='myproj.databases' #selector={"_id"=>BSON::ObjectId('4fe120e4a2f9a386ed000001')} #cursor_id=>
TypeError - can't convert Mongo::Cursor into Integer:
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/bson-1.6.4/lib/bson/byte_buffer.rb:156:in `pack'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/bson-1.6.4/lib/bson/byte_buffer.rb:156:in `put_int'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:603:in `construct_query_message'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:466:in `send_initial_query'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:459:in `refresh'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:128:in `next'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:291:in `each'
/Users/myuser/Code/myproj/my_file.rb:171:in `block in initialize'
My query object: {"_id"=>BSON::ObjectId('4fe120e4a2f9a386ed000001')}
I have not the faintest idea what's causing this. I've verified the object I'm finding exists and the query.count shows that there's a result in my Mongo::Cursor.
I've not found any examples of the issue on Google and every Mongo/Ruby on the web I've found uses an each iterator just like I do. Anyone know what's the cause of this error? I notice I also get it when trying to use to_a to cast the collection to a JSON-usable object.
For what it's worth, here's the relevant part of byte_buffer.rb is below. The line with << is line 156.
def put_int(i, offset=nil)
#cursor = offset if offset
if more?
#str[#cursor, 4] = [i].pack(#int_pack_order)
else
ensure_length(#cursor)
#str << [i].pack(#int_pack_order)
end
#cursor += 4
end
This happens when you pass nil to a Ruby Mongo driver limit() method.

Resources