Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
The to_chr function is supposed to return the encrypted array but converted to characters. I have tried many things and commented out the ones that didn't work.
class Encrypt
def initialize(code, string)
#code = code
#string = string
#encrypted = []
end
def to_byte
#string.each_byte do |c|
#encrypted.push(c + #code)
end
print #encrypted
end
def to_chr
n = #encrypted.length
# n.times do |i|
# #encrypted.push(i.chr)
# end
print #encrypted[0].chr
# #encrypted.each do |x|
# #encrypted.push(x.chr)
# end
# print #encrypted
end
end
goop = Encrypt.new(2, "hello")
goop.to_chr
#=> in `to_chr': undefined method `chr' for nil:NilClass (NoMethodError)
You create instance of Encrypted method, but you set #code = 2, #string = "Hello" and #encrypted = []. So if you call #encrypted[0], ruby return nil.
So you can modify your class like this:
class Encrypt
def initialize(code, string)
#code, #string, #encrypted = code, string, []
end
def to_byte
#string.each_byte { |c| #encrypted << c + #code }
end
def to_chr
to_byte if #encrypted.empty?
#encrypted.map(&:chr)
end
end
goop = Encrypt.new(2, "hello")
p goop.to_chr
# => ["j", "g", "n", "n", "q"]
I hope this helps
def to_chr
#encrypted.each do |i|
print i.chr
end
print "\n"
end
Make sure to call to_byte prior to to_chr
goop = Encrypt.new(2, "hello")
goop.to_byte
goop.to_chr
returns:
jgnnq
Related
This question already has answers here:
Ruby: dynamically generate attribute_accessor
(3 answers)
Closed 6 years ago.
Hi I would like to initialize the attributes of an instance of a ruby object dinamically via some config file, I can do that pretty fast using the following code:
class ApiTester
def initialize(path= "api_test")
h = eval(File.open("#{path}/config.hash","r").read)
h.each do |k,v|
eval("##{k}=#{v.class == String ? "\"#{v}\"" : v }" )
end
end
end
How do I give the attribute "##{k}" the property attr_accessor?
class ApiTester
def initialize(path= "api_test")
h = { a: 1, b: 2 }
h.each do |k,v|
instance_variable_set("##{k}", v)
self.class.send(:attr_accessor, k)
end
end
end
api_tester = ApiTester.new
puts api_tester.a # => 1
puts api_tester.b # => 2
api_tester.a = 3
puts api_tester.a # => 3
By the way, you should probably create a .yaml file and use YAML::load_file, it is best practice to avoid eval if you can.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
So I have a CSV that looks like this;
This is a test file
,,,,,,,,,,,
1122,Foo,Bar,FooBar
22321,Bar,Bar,Foo
11223,Foo,Foo,Foo,,,,,,,,,
12312/2423/1245,Foo,Foo,,,,,,,,
I want to parse it and have the following result in my array;
1122,Foo,Bar,FooBar
11223,Foo,Foo,Foo
22321,Bar,Bar,Foo
12312/2423/1245,Foo,Foo
My code;
class ReadCSVToArray
def initialize(file)
#array = CSV.read(file)
end
def compact_multi
y = []
#array.each { |i| i.compact! ; y << i unless i.blank? }
end
def item_rows
y = []
#array.each { |o|
if o[0].include? '/'; y << o ; end
if o[0].is_number? ; y << o ; end
}
end
end
the_list = ReadCSVToArray.new('/Users/davidteren/Desktop/read_test.csv')
the_list.compact_multi.item_rows.sort.each { |i| p i }
So as per above I'd like to chain several methods to get my results.
I have tried various things like;
class ReadCSVToArray
def initialize(file)
#array = CSV.read(file)
end
def compact_multi
y = []
#array.each { |i| i.compact! ; y << i unless i.blank? }
self
end
def item_rows
y = []
#array.each { |o|
if o[0].include? '/'; y << o ; end
if o[0].is_number? ; y << o ; end
}
self
end
end
No matter what I try I can't get it to work.
There's a problem with this line:
the_list.compact_multi.item_rows.sort.each { |i| p i }
This chain breaks down to 4 method calls:
the_list.compact_multi
the_list.item_rows
the_list.sort
the_list.each { |i| p i }
By returning self in your compact_multi and item_rows methods, you're ensuring that the next method in the chain is sent to your ReadCSVToArray instance. But there are no ReadCVSToArray#sort or ReadCSVToArray#each methods. You probably want to call them on instance variable #array.
result = CSV.parse 'This is a test file
,,,,,,,,,,,
1122,Foo,Bar,FooBar
22321,Bar,Bar,Foo
11223,Foo,Foo,Foo,,,,,,,,,
12312/2423/1245,Foo,Foo,,,,,,,,'
result.map(&:compact).reject { |l| l.size < 2 }
#⇒ [["1122", "Foo", "Bar", "FooBar"], ["22321", "Bar", "Bar", "Foo"],
# ["11223", "Foo", "Foo", "Foo"], ["12312/2423/1245", "Foo", "Foo"]]
Please note, that rejecting empties probably should be done more accurate. Hope it helps.
To get this:
the_list.compact_multi.item_rows.sort.each { |i| p i }
to work, compact_multi should return self and item_rows should return #array.
You seem to have two issues, the method chaining and getting the right result...
Your right result issue seems to be that you're assigning and building out this y array but you're not doing anything with it in any of those methods...
def compact_multi
y = []
#array.each { |i| i.compact! ; y << i unless i.blank? }
self
end
def item_rows
y = []
#array.each { |o|
if o[0].include? '/'; y << o ; end
if o[0].is_number? ; y << o ; end
}
self
end
what exactly is your goal? if its to maintain a result through the y array then make that an instance variable and initialize it in the initialize method...
As far as your chaining method issue if it's what I think you're trying to do which is unclear by your question then your methods should look like this...
class ReadCSVToArray
def initialize(file)
#result = []
#csv = CSV.read(file)
end
def compact_multi
#csv.each { |i| i.compact! ; #result << i unless i.blank? }
self
end
def item_rows
#csv.each { |o|
if o[0].include? '/'; #result << o ; end
if o[0].is_number? ; #result << o ; end
}
#result
end
end
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have the following code:
class A
end
class B
end
a1 = A.new
a2 = A.new
b1 = B.new
b2 = B.new
array = [a1, a2, b1, b2]
hash = {}
array.each do |obj|
if hash[obj.class] = nil
hash[obj.class] = []
else
hash[obj.class] << obj
end
end
I want hash to be equal to
{ A => [a1,a2], B => [b1,b2] }
but it's telling me I can't use the << operator.
Let's sum it up.
if hash[obj.class] = nil
↑ you are resetting your pair every time your condition runs because of the unique equal that set hash[obj.class] to nil instead of testing its nillity. Use == instead.
Then, you are doing
array.each do |obj|
if hash[obj.class] == nil
hash[obj.class] = [] # if nil, initialize to new array
else # but because of the else, you are not...
hash[obj.class] << obj # doing this so you don't register the first object of each class.
end
end
Conclusion
array.each do |obj|
hash[obj.class] ||= [] # set hash[obj.class] to [] if nil (or false)
hash[obj.class] << obj
end
I think Enumerable#group_by is what you're looking for:
# ...
array = [a1, a2, b1, b2]
hash = array.group_by(&:class)
# => {A=>[#<A:0x0000000190dbb0>, #<A:0x000000018fa470>],
# B=>[#<B:0x000000018e5fe8>, #<B:0x000000018daa80>]}
(And as noted in the comments, the error you're getting is because you're setting hash[obj.class] to nil when you meant to test for equality with ==.)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to write the method group_by by myself. This is what I have so far:
module Enumerable
def group_by(&b)
solution = {}
self.each {|key,val|
b.call(var)
solution = { key=> (val) }
}
end
end
ary = [1,2,3,4,5,6,7,8,9,10]
p ary.group_by() { |i| i%3 }
I don't get it. I hope you can help me.
module Enumerable
def group_by &b; inject({}){|h, e| (h[b.call(e)] ||= []).push(e); h} end
end
[1,2,3,4,5,6,7,8,9,10].group_by{|i| i % 3}
# => {1 => [1, 4, 7, 10], 2 => [2, 5, 8], 0 => [3, 6, 9]}
I'm not really sure how I can help apart from post a solution, but maybe some description with what you find difficult might help?
Few issues I notice:
You are using passing two arguments into the block when the array only has 1, the value
You call the block with var which doesn't exist in the current scope, maybe you meant val?
You dont check to see if anything already exists in the new solution dictionary
You overwrite the solution dictionary every time you loop over a new value in the array
Here is what I came up with:
module Enumerable
def group_by
solution = {}
each do |value|
key = yield value
if solution.key?(key)
solution[key] << value
else
solution[key] = [value]
end
end
solution
end
end
ary = [1, 2, 3, 4, 5]
p ary.group_by { |i| i % 3 }
output:
{1=>[1, 4], 2=>[2, 5], 0=>[3]}
you might want to check if a block has been given incase someone tries to use the function wrong, consider using the statement unless block_given? but maybe you can try implement this yourself.
Another solution for comparison:
module Enumerable
def group_by
{}.tap do |group|
each{ |value| (group[ yield(value) ] ||= []) << value }
end
end
end
uses tap to avoid the unsightly pattern of
thing = {}
# do stuff with thing
thing # return it
uses ||= to create the new collection array of not already present
Alternatively:
module Enumerable
def group_by
Hash.new{ |h,k| h[k]=[] }.tap do |group|
each{ |value| group[ yield(value) ] << value }
group.default = nil # remove the default_proc when done
end
end
end
From my backports gem:
module Enumerable
def group_by
return to_enum(:group_by) unless block_given?
result = {}
each do |o|
key = yield(o)
ary = result.fetch(key){ result[key] = [] }
ary << o
end
result
end
end
Contrary to all solutions presented so far, it passes RubySpec.
I am very beginner in Ruby and probably the question is too easy but well, I've already spent some time on it and couldn't find a solution.
My Ruby script takes a number (ex 10) and a name (ex Vincent). What I want is to make an array looking like
Vincent0
Vincent1..
Vincent9
I can't figure a way to make it..
def arrayfy(string, number)
arr = []
0.upto(number-1) do |i|
arr << "#{string}#{i}"
end
return arr
end
Update: To add these as variables to the class
class Foo
def arrayfy(string, number)
0.upto(number-1) do |i|
var_string = "##{string}#{i}"
var_symbol = var_string.to_sym
self.instance_variable_set(var_symbol, "")
end
end
end
Array.new(10) {|i| "Vincent#{i}"}
gives you
["Vincent0", "Vincent1", "Vincent2", "Vincent3", "Vincent4", "Vincent5",
"Vincent6", "Vincent7", "Vincent8", "Vincent9"]
The documentation for Array is available at http://www.ruby-doc.org/core/classes/Array.html (googling for Array RDoc will give you the URL).
The bit in the braces ({|i| "Vincent#{i}"}) is called a block. You'll definitely want to learn about them.
Using Array.new with a block (docs):
def create_array(count, name)
Array.new(10) { |i| "#{name}#{i} }
end
Using Enumerable#reduce (docs):
def create_array(count, name)
(0...count).reduce([]) { |m,i| m << "#{name}#{i}" }
end
Or using Enumerable#each_with_object (docs):
def create_array(count, name)
(0...count).each_with_object([]) { |i,a| a << "#{name}#{i}" }
end
Using it:
# Using the array (assigning to variables)
array = create_array(10, 'Vincent') # => ['Vincent0', 'Vincent1', 'Vincent2' ...]
name = array[1] # => 'Vincent1'
Just for the record, a solution in a more functional style:
>> def arrayify(str, n)
.. ([str] * n).zip(0...n).map(&:join)
.. end
#=> nil
>> arrayify('Vincent', 10)
#=> ["Vincent0", "Vincent1", "Vincent2", "Vincent3", "Vincent4", "Vincent5", "Vincent6", "Vincent7", "Vincent8", "Vincent9"]
def array_maker(number, string)
result = []
for i in 0..number do
result << "#{string}#{i}"
end
result
end