Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8273403
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T07:28:58+00:00 2026-06-08T07:28:58+00:00

I would like to print a database-table to STDOUT. If the table-width is greater

  • 0

I would like to print a database-table to STDOUT. If the table-width is greater than the screen-width I would like to cut the column each with the same percentage (unless a table-width has reached min_width) until the table fits in the screen. I’ve tried to solve this with the posted subroutine. Does somebody know a shorter and more elegant algorithm to solve this problem?

sub cal_size {
    my ( $maxcols, $ref ) = @_;         
    # $maxcols => screen width
    # $ref => ref to an AoA; holds the table
    my ( $max ) = cal_tab( $ref );
    # $max => ref to an array; holds the length of the longest string of each column
    # $tab = 2;
    if ( $max and @$max ) {
        my $sum = sum( @$max ) + $tab * @$max; 
        $sum -= $tab;
        my @max_tmp = @$max;
        my $percent = 0;
        while ( $sum > $maxcols ) {
            $percent += 0.5;
            if ( $percent > 99 ) {
                return;
            }
            my $count = 0;

            for my $i ( 0 .. $#max_tmp ) {
                # $min_width => columns width should not be less than $min_width if possible 
                next if $min_width >= $max_tmp[$i]; 
                # no need to cut if the column width id less than min_width
                next if $min_width >= minus_x_percent( $max_tmp[$i], $percent ); 
                # don't cut if column width become less than min_width 
                $max_tmp[$i] = minus_x_percent( $max_tmp[$i], $percent );
                $count++;
                last if $sum <= $maxcols;   
            }
            $min_width-- if $count == 0 and $min_width > 1; 
            # if no cuts but $sum > $maxcols reduce $min_width
            $sum = sum( @max_tmp ) + $tab * @max_tmp; 
            $sum -= $tab;
        }
        my $rest = $maxcols - $sum;
        while ( $rest > 0 ) { # distribute the rest
            my $count = 0;
            for my $i ( 0 .. $#max_tmp ) {
                if ( $max_tmp[$i] < $max->[$i] ) {
                    $max_tmp[$i]++;
                    $rest--;
                    $count++;
                    last if $rest < 1;
                }
            } 
            last if $count == 0;
            last if $rest < 1;
        }
        $max = [ @max_tmp ] if @max_tmp;
    }
    return $max;
}


sub minus_x_percent {
    my ( $value, $percent ) = @_;
    return int $value - ( $value * 1/100 * $percent );
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T07:29:00+00:00Added an answer on June 8, 2026 at 7:29 am

    This problem would be simple if it wasn’t for the lower limit for the field widths. Once a field cannot get any smaller only the larger ones are eligible for scaling, so the calculation varies depending on whether all, none, or some of the fields have been scaled down to their limit.

    The scaling has several bands, one per unique field width. As the fields are scaled down in equal proportion the smallest of them will be the first to hit the minimum field size limit. After that only the columns bigger than the smallest size can be reduced any further until the second smallest also reaches the limit.

    This continues until all columns have reached their minimum size, after which the available space is just divided equally between the columns.

    This program implements the calculations for that algorithm, and I think does what you want.

    Note that the returned field widths are floating-point values and you must round them as you see fit.

    use strict;
    use warnings;
    
    use List::Util 'max';
    
    my $min_col_width = 10;
    my $tab = 2;
    
    my $widths = recalc_widths(80, [ 10, 15, 20, 25, 30 ]);
    print join '  ', map sprintf('%.3f', $_), @$widths;
    print "\n";
    
    sub recalc_widths {
    
      my ($target, $widths) = @_;
      $target -= (@$widths - 1) * $tab;
    
      my @sorted_widths = sort { $a <=> $b } @$widths;
    
      my $num_limited = 0;
      my $adjustable_total_width = 0;
      $adjustable_total_width += $_ for @sorted_widths;
    
      while (@sorted_widths) {
    
        my $boundary = $sorted_widths[0];
    
        my $scale = ($target - $num_limited * $min_col_width) / $adjustable_total_width;
    
        if ($boundary * $scale >= $min_col_width) {
          return [ map max($_ * $scale, $min_col_width), @$widths ];
        }
    
        while (@sorted_widths and $sorted_widths[0] == $boundary) {
          shift @sorted_widths;
          $adjustable_total_width -= $boundary;
          $num_limited++;
        }
      }
    
      return [ ($target / $num_limited) x $num_limited ];
    }
    

    output

    10.000  10.333  13.778  17.222  20.667
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I would like to print a list of items from a database table, and
I would like to print a list of items from a database table, and
I would like to be able to connect to a database with this table...
I would like to print the size of the root volume set by GetDiskFreeSpaceEx(...),
I would like to print a message if either a or b is empty.
I would like to print scrollable div as WYSWYG. Is there a way?
I would like to print an array to a file. I would like the
I would like to print the selected values of all selects using jQuery. I
I would like to print raw phone number record (31999999) as 31-999-999 (PHP). I
I would like to be able to print in the logs a message for

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.