Do you have any recommended standards for ...

4 views
Skip to first unread message

dkmd_nielsen

unread,
Dec 26, 2007, 5:15:42 PM12/26/07
to Ruby Reports
typical business type of stuff? If you have any recommendations for
the following, can the recommendations make it into your book as a
cheat sheet? It would really lead the way for standardizing some of
the code across multiple developers.

(1) Producing a totals row for a table.
(2) Totaling multiple columns to create a new column
(3) Formatting numbers in a column

These are typical business things that I simply don't know what the
community standard should be. For example, I do the following to
create a totals row:

def segment_listing
seglist = @segtbl.sub_table(
[:iid,:ssid,:desc,:grossin,:sel,:net_output,
:hdpkg_elig,:regpkg_elig,:a5dpkg_elig,
:hdpkg_fill,:regpkg_fill,:a5dpkg_fill
]
)
seglist.sort_rows_by!([:ssid])
seglist << {
:iid => '',
:ssid => '',
:desc => 'Total',
:rank => '',
:hd => '',
:reg => '',
:a5d => '',
:grossin => seglist.sum(:grossin),
:hdpkg_elig => seglist.sum(:hdpkg_elig),
:hdpkg_fill => seglist.sum(:hdpkg_fill),
:regpkg_elig => seglist.sum(:regpkg_elig),
:regpkg_fill => seglist.sum(:regpkg_fill),
:a5dpkg_elig => seglist.sum(:a5dpkg_elig),
:a5dpkg_fill => seglist.sum(:a5dpkg_fill),
:net_output => seglist.sum(:net_output)
}
puts seglist.to_text(:table_width => 250)

end

(1) Is the above the correct way to accomplish it? Is there a better
way?

(2) What is the proper way to add two columns together to produce a
row total column?

And (3), after all the calculations are done, how can one tell the
formatter to format the values in a given column. For example, I have
this method:

# Augment the Integer class with a method to format
# a number with commas.
class Integer
def to_fmt(num)
num.to_s.strip.gsub(/(.)(?=.{3}+$)/, %q(\1,))
end
end

When is the proper time and method to implement it such that the
format of numbers is produced with commas.

dvn

dkmd_nielsen

unread,
Dec 26, 2007, 5:18:55 PM12/26/07
to Ruby Reports
Here is a sample of the above report. Columns :rank, :hd, :reg,
and :a5d have been cut out so the report looks nicer in here.

+--------------------------------------------------------------------+
| Int ID | Seg ID | Description | Input | Eligible | Adds | Output |
+--------------------------------------------------------------------+
| 0 | 001 | GOBADGERS | 56386 | 56296 | 200 | 56586 |
| 2 | 002 | NEWYORK | 338961 | 338554 | 1966 | 340927 |
| 1 | 003 | PENNSYLVANIA | 172087 | 171847 | 388 | 172475 |
| | | Total | 567434 | 566697 | 2554 | 569988 |
+--------------------------------------------------------------------+

dkmd_nielsen

unread,
Dec 26, 2007, 5:21:44 PM12/26/07
to Ruby Reports
And here is how I would like the report to look:

+------------------------------------------------------------------------
+
| Int ID | Seg ID | Description | Input | Eligible | Adds |
Output |
+------------------------------------------------------------------------
+
| 0 | 001 | GOBADGERS | 56,386 | 56,296 | 200 |
56,586 |
| 2 | 002 | NEWYORK | 338,961 | 338,554 | 1,966 |
340,927 |
| 1 | 003 | PENNSYLVANIA | 172,087 | 171,847 | 388 |
172,475 |
| | | Total | 567,434 | 566,697 | 2,554 |
569,988 |
+------------------------------------------------------------------------
+

Gregory Brown

unread,
Dec 27, 2007, 3:00:33 PM12/27/07
to ruby-r...@googlegroups.com
On Dec 26, 2007 5:15 PM, dkmd_nielsen <do...@cmscms.com> wrote:
>
> typical business type of stuff? If you have any recommendations for
> the following, can the recommendations make it into your book as a
> cheat sheet? It would really lead the way for standardizing some of
> the code across multiple developers.
>
> (1) Producing a totals row for a table.
> (2) Totaling multiple columns to create a new column
> (3) Formatting numbers in a column

We don't really have a standard way of doing things. It always
depends on the situation,
but I'll see what I can do to help here.

Looks mostly okay to me, I do roughly the same thing. We really
should create an abstraction on this, perhaps in ruport-util, because
it's not pretty.

One note:

> :rank => '',
> :hd => '',
> :reg => '',
> :a5d => '',

These should not be necessary. Nil fields should work, and if they
don't, it's a bug.

> (2) What is the proper way to add two columns together to produce a
> row total column?

Hmm... well, if subtable allowed filters and transforms, it might be
something like:

seglist = @segtbl.sub_table(["a","b","total"]) do |t|
t.transform { |r| r.total = r.a + r.b }
end

This isn't the case right now, but that looks kind of neat. It'd mean
that you'd need to explicitly use t.filter { ... } for filtering your
rows though...

What do folks thinks?


> And (3), after all the calculations are done, how can one tell the
> formatter to format the values in a given column. For example, I have
> this method:
>
> # Augment the Integer class with a method to format
> # a number with commas.
> class Integer
> def to_fmt(num)
> num.to_s.strip.gsub(/(.)(?=.{3}+$)/, %q(\1,))
> end
> end

Doesn't this read?

2.to_fmt(2)

Why not just def to_fmt

and then self.to_s

allowing

2.to_fmt

> When is the proper time and method to implement it such that the
> format of numbers is produced with commas.

If performance is a concern, you really need to wire this somewhere in
a custom renderer on a row by row basis.

However, if you can afford to pass through the data twice, there are a
couple choices.

If you know the column names specifically which need formatting, you
can do something like this:

table.replace_column("foo") { |r| r.foo.to_fmt }

You can of course iterate over an array of column names there, but ugh, slow.

Also slow, but only does one extra pass, is this:


with_commas = lambda do |r|
r.each_with_index do |e,i|
if Integer === e
r[i] = e.to_fmt
end
end
end

Table(table.column_names, table.data, :transforms => with_commas)

Hope that helps.

-greg

dkmd_nielsen

unread,
Dec 27, 2007, 4:16:57 PM12/27/07
to Ruby Reports
OF COURSE I sent you a syntax error in the to_fmt method. The method
does not accept a parameter.

# Augment the Integer class with a method to format
# a number with commas.
class Integer
def to_fmt
self.to_s.strip.gsub(/(.)(?=.{3}+$)/, %q(\1,))
end
end

I implemented this in my renderer setup:

def setup
self.data << {
:desc => 'Total',
:grossin => data.sum(:grossin),
:elig => data.sum(:elig),
:sel => data.sum(:sel),
:net_output => data.sum(:net_output)
}

self.data = Table(data.column_names, :transforms =>
options.transforms) {|t|
data.each {|r|
r.grossin = r.grossin.to_fmt.rjust(10)
r.elig = r.elig.to_fmt.rjust(10)
r.sel = r.sel.to_fmt.rjust(10)
r.net_output = r.net_output.to_fmt.rjust(10)
t << r
}
}

self.data.rename_columns(
:iid => "Int ID",
:ssid => "Seg ID",
:desc => "Description",
:rank => "Rank",
:hd => "HD",
:reg => "Reg",
:a5d => "A5d",
:grossin => "Input",
:elig => "Eligible",
:sel => "Adds",
:net_output => "Output"
)
end

And this brings us to one more topic, related to this and that of
another discussion. Above the columns are renamed (for to_text
purposes) to create prettier column headings. (I'm really not too
keen on renaming columns for this purpose. Heading text should be
relatable to a column without affecting column names.) Would it make
sense to implement the following api for headings? I know it is
probably ugly, but it makes sense:

draw_table(data,
:column_options => {
:desc => {:width => ::PDF::Write.in2pts(2.5),
:justification => :left,
:heading => {title =>
"Description", :justification => :left, :bold => true}
}
}

Here is my justification. Headings are nothing more than column
attributes. By combining them with the column_options (which really
are column attributes), we get more of the column level details
definable in one place. The above basically reads -- draw the table,
applying the defined attributes to the specified columns, where :desc
will have a width of 2.5 inches, the data is left justified, and will
have the heading "Description", which is left justified and bold.

With text alignment, it isn't that ugly.

What do you think? Draw table may not be the correct place for the
implementation.

Gregory Brown

unread,
Dec 27, 2007, 4:22:00 PM12/27/07
to ruby-r...@googlegroups.com
On Dec 27, 2007 4:16 PM, dkmd_nielsen <do...@cmscms.com> wrote:

> And this brings us to one more topic, related to this and that of
> another discussion. Above the columns are renamed (for to_text
> purposes) to create prettier column headings. (I'm really not too
> keen on renaming columns for this purpose. Heading text should be
> relatable to a column without affecting column names.)

If you do this in your renderer, it only effects the column names on
render, not your original data. If it effects your original data,
we're in trouble. :)

This issue has come up before. I don't think of column names as being
independent of 'heading names', but many people do.

Perhaps it'd be helpful if we made the table renderer set
options.column_headings to data.column_names by default, but allow
this to be overridden as needed.

We can then use options.column_headings in the formatters instead of
data.column_names.

What do you think?

-greg

Michael Milner

unread,
Dec 27, 2007, 4:35:07 PM12/27/07
to ruby-r...@googlegroups.com
On Dec 27, 2007 4:16 PM, dkmd_nielsen <do...@cmscms.com> wrote:
>
> And this brings us to one more topic, related to this and that of
> another discussion. Above the columns are renamed (for to_text
> purposes) to create prettier column headings. (I'm really not too
> keen on renaming columns for this purpose. Heading text should be
> relatable to a column without affecting column names.) Would it make
> sense to implement the following api for headings? I know it is
> probably ugly, but it makes sense:
>
> draw_table(data,
> :column_options => {
> :desc => {:width => ::PDF::Write.in2pts(2.5),
> :justification => :left,
> :heading => {title =>
> "Description", :justification => :left, :bold => true}
> }
> }
>

Have you tried this? I haven't tested it myself, but can't see
anything here that wouldn't work currently as it is. Maybe I'm
missing something?

Mike

Reply all
Reply to author
Forward
0 new messages