Gruff is not working well. What to do? - ruby

I`m facing a problem with Gruff and Rails.
Examples on the site fail with:
ZeroDivisionError: divided by 0
from /home/prikha/.rvm/gems/ruby-1.9.3-p194#rubymine/gems/gruff-0.3.6/lib/gruff/base.rb:1066:in `label'
from /home/prikha/.rvm/gems/ruby-1.9.3-p194#rubymine/gems/gruff-0.3.6/lib/gruff/base.rb:590:in `setup_graph_measurements'
from /home/prikha/.rvm/gems/ruby-1.9.3-p194#rubymine/gems/gruff-0.3.6/lib/gruff/base.rb:532:in `setup_drawing'
from /home/prikha/.rvm/gems/ruby-1.9.3-p194#rubymine/gems/gruff-0.3.6/lib/gruff/base.rb:508:in `draw'
from /home/prikha/.rvm/gems/ruby-1.9.3-p194#rubymine/gems/gruff-0.3.6/lib/gruff/line.rb:53:in `draw'
from /home/prikha/.rvm/gems/ruby-1.9.3-p194#rubymine/gems/gruff-0.3.6/lib/gruff/base.rb:487:in `write'
from (irb):8
from /home/prikha/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'

I had the same problem.
The way i solve it is the following:
ZeroDivisionError appears in 1066 line of gruff/base.rb
Let's look at this file closer
label = if (#spread.to_f % #marker_count.to_f == 0) || !#y_axis_increment.nil?
So, ZeroDivisionError was caused by the fact that #marker_count property was equal to zero. I know, it's not the best solution, but i've added an explicit assignment
#marker_count = <non-zero value> before drawing graph.
So, now example from site looks like:
#!/usr/bin/ruby
require 'rubygems'
require 'gruff'
g = Gruff::Line.new
g.title = "My Graph"
g.data("Apples", [1, 2, 3, 4, 4, 3])
g.data("Oranges", [4, 8, 7, 9, 8, 9])
g.data("Watermelon", [2, 3, 1, 5, 6, 8])
g.data("Peaches", [9, 9, 10, 8, 7, 9])
g.marker_count = 4 #explicitly assign value to #marker_count
g.labels = {0 => '2003', 2 => '2004', 4 => '2005'}
g.write('my_fruity_graph.png')
It works fine for me. I know that it's not the general solution for the problem, but this hack can help you to deal with that library up until this error will be fixed by developers.
ADD
#market_count is a count of markers on vertical axis. So you can play with this property to prettify your graph.

Related

What's the reason the second code won't return what the first code successfully returns

I was doing a quick read up on arrays and some basic methods. And one of the exercise questions at the end of the reading gave me an array and asked to get the following output
=> [10, 8, 4, 2]
Here's the array:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
solution:1
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers = numbers.select { |number| number.even? }.reverse
numbers.delete(6)
p numbers
But my question to you is why would the above code return the correct output but the following code won't?
solution: 2
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers = numbers.select { |number| number.even? }
numbers.delete(6)
numbers.reverse
p numbers
I understand it's not the most fluent, but when I try to solve these exercises it's easier for me to separate everything and then clean up the code.
I expected it to pull the even numbers delete 6 from them and then print the reversed array.
Instead it pulls the even numbers, deletes 6, and prints the even numbers. Completely skips the .reverse
As max says, .reverse doesn't change the array. Try, instead:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers = numbers.select { |number| number.even? }
numbers.delete(6)
numbers.reverse!
p numbers
=> [10, 8, 4, 2]
As other commenters have mentioned, .reverse doesn't change the array.
You either have to declare numbers.reverse as a new variable (i.e. reversed_numbers = numbers.reverse) or use numbers.reverse! (as demonstrated by jvillian) to change the value of the numbers variable itself at invocation.
Between the two, the latter method is more suitable.
Hope this helped!

Ruby loop through each element in an array n times

I've had a tough time finding an exact example of this.
If I have an array that contains 5 elements. E.g.
list = [5, 8, 10, 11, 15]
I would like to fetch what would be the 8th (for example) element of that array if it were to be looped. I don't want to just duplicate the array and fetch the 8th element because the nth element may change
Essentially the 8th element should be the number 10.
Any clean way to do this?
Math to the rescue
list[(8 % list.length) - 1]
A link about this modulo operator that we love
This should do:
def fetch_cycled_at_position(ary, num)
ary[(num % ary.length) - 1]
end
ary = _
=> [5, 8, 10, 11, 15]
fetch_cycled_at_position(ary, 1) # Fetch first element
=> 5
fetch_cycled_at_position(ary, 5) # Fetch 5th element
=> 15
fetch_cycled_at_position(ary, 8) # Fetch 8th element
=> 10
You could use rotate:
[5, 8, 10, 11, 15].rotate(7).first
#=> 10
It's 7 because arrays are zero based.
Just out of curiosity using Array#cycle:
[5, 8, 10, 11, 15].cycle.take(8).last
This is quite inefficient but fancy.
I ran these in my irb to get the output,
irb(main):006:0> list = [5, 8, 10, 11, 15]
=> [5, 8, 10, 11, 15]
irb(main):007:0> list[(8 % list.length) - 1]
=> 10
hope it will help you.

Can I have a ruby block inside another ruby block?

I have a hash whose keys are a range of integers (lets say [1..5]) and its corresponding 5 values are all nil. I have also an array of integers (lets say [1,2,3,4,5]. What I want to do is very specific: I want to take every single key and add it to every single of the array elements, giving me a hash that has the original keys, but has now for values the entire shifted array.
After spending a few hours I have concluded that this is impossible through a really laconic expression, because it is leading to .each shadowing statements.
I think that the only way to go through with this is to create 5 almost identical methods and call them separately.
def a1
array.each do |x|
x+1
end
end
def a2
array.each do |x|
x+2
end
end
and so on..
The end product I want to achieve is this:
{1=>[2,3,4,5,6],2=>[3,4,5,6,7],3=>[4,5,6,7,8],4=>[5,6,7,8,9],5=>[6,7,8,9,10]}
It feels like there should be a more DRY way to achieve this. Any ideas?
Assuming these initial conditions:
h = {1=>nil, 2=>nil, 3=>nil, 4=>nil, 5=>nil}
arr = [1,2,3,4,5]
...it's pretty straightforward:
h.keys.each do |key|
h[key] = arr.map {|i| i+key}
end
# h is now: {1=>[2, 3, 4, 5, 6], 2=>[3, 4, 5, 6, 7], 3=>[4, 5, 6, 7, 8], 4=>[5, 6, 7, 8, 9], 5=>[6, 7, 8, 9, 10]}
(However, it may be that your question is about achieving the initial conditions. If so, I didn't grasp that, and I didn't worry about it; I just started with what I took to be your initial conditions and ended up with your desired result.)
Why don't you do this
h = {}
rng.each{|i| h[i] = ary.map{|j| j + i}}
That should work where rng is the range and ary is the array.
For example
h = {}
(1..5).each{|i| h[i] = [1,2,3,4,5].map{|j| j+i}}
results in
h = {1=>[2, 3, 4, 5, 6], 2=>[3, 4, 5, 6, 7], 3=>[4, 5, 6, 7, 8], 4=>[5, 6, 7, 8, 9], 5=>[6, 7, 8, 9, 10]}

ruby method chaining

var.split('/').delete_at(0)
upon inspection returns
""
no matter what the string, however....
var.split('/')
var.delete_at(0)
gives me no trouble. this is probably a stupid question, but are there some sort of restrictions/limitations regarding method chaining like this?
thanks,
brandon
The delete_at method deletes the element but returns the deleted element not the new array.
If you want to always return the object, you can use the tap method (available since Ruby 1.8.7).
a = [1, 2, 3, 4, 5, 6, 7]
a.delete_at(0) # => 1
a # => [2, 3, 4, 5, 6, 7]
a = [1, 2, 3, 4, 5, 6, 7]
a.tap { |a| a.delete_at(0) } # => returns [2, 3, 4, 5, 6, 7]
a # => [2, 3, 4, 5, 6, 7]
literally the first thing I tried to do was:
var.split('/').delete_at(0)
which upon inspection returned
""
no matter what the string
Are you sure? Try the string 'a/b':
irb(main):001:0> var = 'a/b'
=> "a/b"
irb(main):003:0> var.split('/').delete_at(0)
=> "a"
Note that the return value is the element deleted, not the array. The array which you created by performing the split was not stored anywhere and now you have no reference to it. You probably want to do this instead:
a = var.split('/')
a.delete_at(0)
If you always need to delete the first element, you can use other methods that return the object itself, such as slice!, for example:
s = 'foo/bar/baz'
#=> "foo/bar/baz"
s.split('/').slice!(1..-1)
#=> ["bar", "baz"]

Correct way to populate an Array with a Range in Ruby

I am working through a book which gives examples of Ranges being converted to equivalent arrays using their "to_a" methods
When i run the code in irb I get the following warning
warning: default `to_a' will be obsolete
What is the the correct alternative to using to_a?
are there alternate ways to populate an array with a Range?
You can create an array with a range using splat,
>> a=*(1..10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
using Kernel Array method,
Array (1..10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
or using to_a
(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
This works for me in irb:
irb> (1..4).to_a
=> [1, 2, 3, 4]
I notice that:
irb> 1..4.to_a
(irb):1: warning: default `to_a' will be obsolete
ArgumentError: bad value for range
from (irb):1
So perhaps you are missing the parentheses?
(I am running Ruby 1.8.6 patchlevel 114)
Sounds like you're doing this:
0..10.to_a
The warning is from Fixnum#to_a, not from Range#to_a. Try this instead:
(0..10).to_a
Check this:
a = [*(1..10), :top, *10.downto( 1 )]
This is another way:
irb> [*1..10]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I just tried to use ranges from bigger to smaller amount and got the result I didn't expect:
irb(main):007:0> Array(1..5)
=> [1, 2, 3, 4, 5]
irb(main):008:0> Array(5..1)
=> []
That's because of ranges implementations.
So I had to use the following option:
(1..5).to_a.reverse

Resources