1. generic coding problem
Hi
As much to write this down, as to ask for help.
I create a 2d table, with an unknown number of columns, and an unknown number
of rows
Each of the columns has an unknown, but uniform number of characters (ie each
cell in the column has the same length)
I want to print the table on a printer using fixed fonts.
The printer can either support 80 or 124 characters. Printing switches from
80 to 124 if the total character count (with spaces) is greater than 80.
When printing the row title must always be shown, but the column title does
not need to be shown, except as a first row
All the data must be printed, word wrapping is not allowed.
I started with the concept of a 'page' onto which I place the characters of
each cell, but my brain is exploding.
Has anyone done anything like this before. BTW this is not windows or
wxEuphoria programming, just raw stuff.
Cheers in advance
Chris
2. Re: generic coding problem
> Each of the columns has an unknown, but uniform number of characters (ie each
> cell in the column has the same length)
Do all columns have the same length, or is each column a different length?
~Greg
3. Re: generic coding problem
Hi
All the columns can have different lengths, but all the cells in the same
column have the same length.
Chris
http://members.aol.com/chriscrylex/euphoria.htm
http://uboard.proboards32.com/
http://members.aol.com/chriscrylex/EUSQLite/eusql.html
4. Re: generic coding problem
On Mon, 07 Aug 2006 11:46:54 -0700, ChrisBurch2
<guest at RapidEuphoria.com> wrote:
>As much to write this down, as to ask for help.
Understood.
>
>I create a 2d table, with an unknown number of columns, and an unknown number
>of rows
>
>Each of the columns has an unknown, but uniform number of characters (ie each
>cell in the column has the same length)
So during/after creation of the 2d table are you checking down every
column in the table to get the maxwidth?
>
>I want to print the table on a printer using fixed fonts.
>
>The printer can either support 80 or 124 characters. Printing switches from
>80 to 124 if the total character count (with spaces) is greater than 80.
>
>When printing the row title must always be shown, but the column title does
>not need to be shown, except as a first row
>
>All the data must be printed, word wrapping is not allowed.
So after adding all the column maxwidths and finding it greater than
124, what are you doing? Do you want to find the column(s) which
mini-wrap to give shortest overall report, eg:
kernel32.dll OpenFile Some fairly long description which is probably
the best thing to wordwrap...
kernel32.dll ReadFile
kernel32.dll WriteFile
kernel32.dll CloseFile
rather than:
kernel32 Open Some fairly long description which is ...
.dll File
kernel32 Read
.dll File
kernel32 Write
.dll File
kernel32 Close
.dll File
Or is >124 an error, or just truncated?
>
>I started with the concept of a 'page' onto which I place the characters of
>each cell, but my brain is exploding.
I'd analyse everything, then build a format string (or two), then
print in one pass at the end, possibly under control of some table I
built in the analysis phase.
>Has anyone done anything like this before. BTW this is not windows or
>wxEuphoria programming, just raw stuff.
The only thing which springs to mind for me is my common code analysis
routine (now part of edita [eacca.e]) which outputs eg:
-- 9095 9105 styleMask = xor_bits...
-- 9096 | style = and_bits( style...
-- 9097 9107 9159 9168 if style != curStyle then
-- 9098 9160 VOID = w32Func...
Now I know this is probably not relevant, but 9105..9107 (length 3) as
the longest matching group gets prime position in column 1, then
9159..1960 (length 2) is next but since it can't all go in column 1 it
all goes in column 2, and lastly 9168 (length 1) goes in the next
available column, 3. So it is playing with columns, first calculating
what needs to be printed, then where, but is unlikely to be the sort
of thing you mean.
Regards,
Pete
PS thanks for the startup monitor link.
5. Re: generic coding problem
Pete Lomax wrote:
>
> On Mon, 07 Aug 2006 11:46:54 -0700, ChrisBurch2
> <guest at RapidEuphoria.com> wrote:
>
> >As much to write this down, as to ask for help.
> Understood.
> >
> >I create a 2d table, with an unknown number of columns, and an unknown number
> >of rows
> >
> >Each of the columns has an unknown, but uniform number of characters (ie each
> >cell in the column has the same length)
> So during/after creation of the 2d table are you checking down every
> column in the table to get the maxwidth?
Thats not requirement, but yes it could be an optional extra. One of the
function defs was for the table to have been preformatted so that the title
lengths were the same as the rest of each of the column for each column title
> >
> >I want to print the table on a printer using fixed fonts.
> >
> >The printer can either support 80 or 124 characters. Printing switches from
> >80 to 124 if the total character count (with spaces) is greater than 80.
> >
> >When printing the row title must always be shown, but the column title does
> >not need to be shown, except as a first row
> >
> >All the data must be printed, word wrapping is not allowed.
> So after adding all the column maxwidths and finding it greater than
> 124, what are you doing? Do you want to find the column(s) which
> mini-wrap to give shortest overall report, eg:
>
> kernel32.dll OpenFile Some fairly long description which is probably
> the best thing to wordwrap...
> kernel32.dll ReadFile
> kernel32.dll WriteFile
> kernel32.dll CloseFile
>
> rather than:
>
> kernel32 Open Some fairly long description which is ...
> .dll File
> kernel32 Read
> .dll File
> kernel32 Write
> .dll File
> kernel32 Close
> .dll File
>
> Or is >124 an error, or just truncated?
No wrapping. The columns left over would be printed on the next page, as would
columns left over from that. Imagine a very large spreadsheet, printed over
several pages.
> >
> >I started with the concept of a 'page' onto which I place the characters of
> >each cell, but my brain is exploding.
> I'd analyse everything, then build a format string (or two), then
> print in one pass at the end, possibly under control of some table I
> built in the analysis phase.
>
> >Has anyone done anything like this before. BTW this is not windows or
> >wxEuphoria programming, just raw stuff.
>
> The only thing which springs to mind for me is my common code analysis
> routine (now part of edita [eacca.e]) which outputs eg:
>
> -- 9095 9105 styleMask = xor_bits...
> -- 9096 | style = and_bits( style...
> -- 9097 9107 9159 9168 if style != curStyle then
> -- 9098 9160 VOID = w32Func...
>
ooh, windows, and way too complicated for me brine.
> Now I know this is probably not relevant, but 9105..9107 (length 3) as
> the longest matching group gets prime position in column 1, then
> 9159..1960 (length 2) is next but since it can't all go in column 1 it
> all goes in column 2, and lastly 9168 (length 1) goes in the next
> available column, 3. So it is playing with columns, first calculating
> what needs to be printed, then where, but is unlikely to be the sort
> of thing you mean.
Actually not that far off. When I conceptualise it, I see a rectangular window
no bigger than the printable page, which takes data from the table, puts it into
a file to print, and then moves the window to the next spot. The columns need
to remain in order presented to the function.
Note the length of the table doesn't matter, because enscript takes care of
that. Enscript will also split large files, but not cleanly on spaces, and
you have to specify the section.
>
> Regards,
> Pete
> PS thanks for the startup monitor link.
Mike Lin was 16 when he wrote that several years. He will go far.
>
>
6. Re: generic coding problem
- Posted by Pete Lomax <petelomax at blueyonder.co.uk>
Aug 08, 2006
-
Last edited Aug 09, 2006
On Tue, 08 Aug 2006 07:38:15 -0700, ChrisBurch2
<guest at RapidEuphoria.com> wrote:
>No wrapping. The columns left over would be printed on the next page, as would
>columns left over from that. Imagine a very large spreadsheet, printed over
>several pages.
I see. I walked down the market today and started mulling this over in
my head. By the time I got back I just had to try my ideas out.
Note that my use of rand() is unimpressive; you may need to run this a
few times before it needs >1 sheet widthwise. I didn't figure out a
way to calculate how many sheets wide it will be without actually
printing it. Also, I allowed text columns to split between sheets,
erm, my texts are max 9 chars, so it looks worse in the demo than it
will on live data, I think, - but there is a constant to turn it off.
Anyway, hope you enjoy:
--
-- column printing demo (console display only).
--
-- Note constants are set for console demo:
--
constant maxwid=24, -- characters across page
lpp=15, -- lines per page
colsep=2, -- space between cols
split_text_cols=1 -- 0 to stop text splits
include get.e -- wait_key()
sequence colwidths, colfmts, colsplit, coltitles
sequence data, oneline
procedure generateData()
integer k
colwidths = repeat(0,rand(10))
colfmts = repeat(0,length(colwidths))
colsplit = repeat(0,length(colwidths))
coltitles = repeat(0,length(colwidths))
k = rand(3)
for i=1 to length(colfmts) do
-- k = rand(3)
if k=1 then
colwidths[i] = 5
colfmts[i] = "%5d"
coltitles[i] = "-ref-"
k = 2
elsif k=2 then
colwidths[i] = 9
colfmts[i] = "%-9s"
colsplit[i] = split_text_cols
coltitles[i] = "-- txt --"
k = 3
elsif k=3 then
colwidths[i] = 7
colfmts[i] = "%7.2f"
coltitles[i] = " amount"
k = 1
end if
end for
data = repeat(0,rand(45))
for i=1 to length(data) do
oneline = repeat(0,length(colfmts))
for j=1 to length(colfmts) do
k = colwidths[j]
if k=5 then
oneline[j]=rand(99999)
elsif k=9 then
k=rand(9)
oneline[j]=repeat('0'+k,k)
else
oneline[j]=rand(999999)/100
end if
end for
data[i]=oneline
end for
end procedure
integer fromcol, tocol, splitfirst, splitlast
procedure printSheet(integer line)
sequence onefield
integer c
oneline = repeat(' ',maxwid+1)
printf(1,"Columns %d..%d:\n",{fromcol,tocol})
onefield = coltitles[fromcol]
puts(1,onefield[splitfirst+1..length(onefield)])
for j=fromcol+1 to tocol do
puts(1," ")
puts(1,coltitles[j])
end for
puts(1,"\n")
for i=line to line+lpp do
if i>length(data) then
oneline = repeat(' ',maxwid+1)
else
c=1
for j=fromcol to tocol do
onefield = sprintf(colfmts[j],{data[i][j]})
if splitfirst and j=fromcol then
onefield =
onefield[splitfirst+1..length(onefield)]
elsif splitlast and j=tocol then
onefield = onefield[1..splitlast]
end if
oneline[c..c+length(onefield)-1]=onefield
c+=length(onefield)+colsep
end for
end if
oneline[maxwid+1]='\n'
puts(1,oneline)
end for
puts(1,"Next sheet?")
if find(wait_key(),"nN") then abort(0) end if
puts(1,"\n")
end procedure
procedure printPage(integer line)
integer thiswidth, k
fromcol=1
splitfirst=0
while fromcol<=length(colwidths) do
thiswidth=colwidths[fromcol]-splitfirst
tocol = fromcol
splitlast=0
while 1 do
if tocol=length(colwidths) then exit end if
k = colsep+colwidths[tocol+1]
if thiswidth+k>maxwid then
if colsplit[tocol+1] and thiswidth<maxwid-colsep then
tocol+=1
splitlast=maxwid-colsep-thiswidth
end if
exit
end if
thiswidth += k
tocol += 1
end while
printSheet(line)
splitfirst=splitlast
if splitlast then
fromcol=tocol
else
fromcol=tocol+1
end if
end while
end procedure
procedure printReport()
integer page
page=1
for i=1 to length(data) by lpp do
printf(1,"Page %d: ",{page})
printPage(i)
page+=1
end for
end procedure
generateData()
printf(1,"Columns:%d, Lines:%d, Pages(down):%d\n",
{length(colwidths),length(data),-floor(-length(data)/lpp)})
--include builtins\ppp.e
--pp(coltitles)
--pp(data)
--if getc(0) then end if
printReport()
Regards,
Pete
7. Re: generic coding problem
- Posted by Chris Burch <chriscrylex at aol.com>
Aug 08, 2006
-
Last edited Aug 09, 2006
Hi
Thats very good. You type faster than I think. Definitely given me some more
clarifying ideas.
Cheers
Chris
http://members.aol.com/chriscrylex/euphoria.htm
http://uboard.proboards32.com/
http://members.aol.com/chriscrylex/EUSQLite/eusql.html
8. Re: generic coding problem
- Posted by Pete Lomax <petelomax at blueyonder.co.uk>
Aug 09, 2006
-
Last edited Aug 10, 2006
On Tue, 08 Aug 2006 17:16:49 -0700, Chris Burch
<guest at RapidEuphoria.com> wrote:
>Hi
>
>Thats very good. You type faster than I think. Definitely given me some more
>clarifying ideas.
btw, that demo is much better with
constant maxwid=79, -- characters across page
split_text_cols=0 -- 0 to stop text splits
...
colwidths = repeat(0,10+rand(20))
...
-- k = rand(3)
for i=1 to length(colfmts) do
k = rand(3)
Regards,
Pete
9. Re: generic coding problem
Pete Lomax wrote:
>
> On Tue, 08 Aug 2006 17:16:49 -0700, Chris Burch
> <guest at RapidEuphoria.com> wrote:
>
> >Hi
> >
> >Thats very good. You type faster than I think. Definitely given me some more
> clarifying ideas.</font></i>
> btw, that demo is much better with
> }}}
<eucode>
> constant maxwid=79, -- characters across page
> split_text_cols=0 -- 0 to stop text splits
> ...
> colwidths = repeat(0,10+rand(20))
> ...
> -- k = rand(3)
> for i=1 to length(colfmts) do
> k = rand(3)
> </eucode>
{{{
>
> Regards,
> Pete
>
>
Hi Pete, this is what I came up with (debugging stops still present)
------------------------------------------------------------------------------------------------------------------
global function printers_reports_table(sequence tbl, sequence tbl_title)
--takes a formatted table of strings, and works out the best way of printing it
on paper.
--Rules
-- cells must be pre formatted strings
-- cells in each column must all have same width, but
-- different columns do not need to be same width
-- table must be uniform - eg, 3 * 9, all rows and columns must be the same
count
--paper rows and columns for printers hard coded here, but may not apply to all
printers
--seem we can use the enscript slice function for this!
------------------------------------------------------------------------------------------------------------------
sequence orientation
integer row, col, max_row, max_col
integer landscape_cols, portrait_cols, char_cols, char_count, r_loc
sequence print_command, line, line_new
integer fp
integer col_start, col_end, cur_column, cur_row, cur_char_pos
portrait_cols = 79 --actually 80
landscape_cols = 124 --125
--define maximumum row and column numbers
max_row = length(tbl)
max_col = length(tbl[1])
review_data(tbl)
--find the length of characters required to print one row
char_count = 0
for i = 1 to max_col do
char_count += length(tbl[1][i]) + 1
end for
--can only really do this if using enscript to process the text files, so check
this
if match("enscript", printers[PR_REPORTS]) = 0 then
VOID = get_yn_box("No enscript match")
return 0
end if
--decide on orientation, and create page to print on
if char_count <= portrait_cols then
orientation = "-R"
char_cols = portrait_cols
--line = repeat(' ', 80)
else
orientation = "-r"
char_cols = landscape_cols
--line = repeat(' ', 125)
end if
--paper = line
--find the position of the "-r" or "-R" in the printer string,
--and replace it with the above one
--if not present, just add it.
r_loc = find("-R", upper(printers[PR_REPORTS]))
if r_loc = 0 then
print_command = printers[PR_REPORTS] & " " & orientation
else
print_command = printers[PR_REPORTS][1..r_loc-1] & " " & orientation &
printers[PR_REPORTS][r_loc+3..$]
end if
VOID = get_yn_box(print_command)
--first copy as much of the row across onto the paper,
--marking where have to stop - next one for next 'sheet'
--now create the file to print
cur_column = 2 --header count
col_start = 2
cur_row = 1
cur_char_pos = 1
line = ""
line_new = ""
fp = open("report.txt", "w")
puts(fp, tbl_title & "\n")
for i = 1 to length(tbl_title) do
puts(fp, "=")
end for
puts(fp, "\n\n")
while 1 do
line_new = ""
while 1 do
if cur_column = col_start then
--put the row title on
line_new = tbl[cur_row][1] & " "
line = line_new
if length(line) > char_cols then
VOID = get_yn_box("The row title is wider than
the page!")
return 0
end if
end if
--line_new = append(line_new, tbl[cur_row][cur_column] & " ")
line_new = line_new & tbl[cur_row][cur_column] & " "
if length(line_new) < char_cols then
line = line_new
cur_column += 1
if cur_column > length(tbl[1]) then
--have we gone past the end of the table?
exit
end if
else
--line_new is of greater length than the page
--write out the line, exit from this loop
puts(fp, line & "\n")
exit
end if
end while
--advance the row
cur_row += 1
--have we gone past the end of the table?
if cur_row > length(tbl) then
--restart table, with new start of column chunk
cur_row = 1
col_start = cur_column + 1
puts(fp, "\n\n")
else
--otherwise just put it back to the start of the chunk
cur_column = col_start
end if
if col_start > length(tbl[1]) then
--have gone past col count
exit
end if
end while
close(fp)
system_view_file("report.txt")
return 1
end function
It took me a lot longer to get here, than you did,
but you cleared things in my head, as much as anything else, and its mostly,
but not fully, tested yet.
Cheers,
Chris