mailr18714 - in /branches/frame_order_testing: ./ lib/text/table.py test_suite/unit_tests/_lib/_text/test_table.py


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by edward on March 08, 2013 - 18:21:
Author: bugman
Date: Fri Mar  8 18:21:37 2013
New Revision: 18714

URL: http://svn.gna.org/viewcvs/relax?rev=18714&view=rev
Log:
Merged revisions 18709-18713 via svnmerge from 
svn+ssh://bugman@xxxxxxxxxxx/svn/relax/trunk

........
  r18709 | bugman | 2013-03-08 16:09:49 +0100 (Fri, 08 Mar 2013) | 3 lines
  
  Added column number checks for the data input into 
lib.text.table.format_table().
........
  r18710 | bugman | 2013-03-08 17:28:30 +0100 (Fri, 08 Mar 2013) | 6 lines
  
  Created the test_format_table6() unit test for 
lib.text.table.format_table().
  
  This test shows a problem with more than one multi-column cells defined, as 
well as problems when a
  multi-column cell is wider than the sum of the widths of the columns it 
spans.
........
  r18711 | bugman | 2013-03-08 17:30:20 +0100 (Fri, 08 Mar 2013) | 6 lines
  
  Fix for lib.text.table.format_table() when more than one multi-column cell 
per row is encountered.
  
  The algorithm for determining the total width of the multi-column cell in 
_table_line() was not
  checking if the end of the span was being reached.
........
  r18712 | bugman | 2013-03-08 18:15:27 +0100 (Fri, 08 Mar 2013) | 5 lines
  
  Fix for the test_format_table6() unit test of lib.text.table.format_table().
  
  The numbers of the last column were not properly right justified.
........
  r18713 | bugman | 2013-03-08 18:17:45 +0100 (Fri, 08 Mar 2013) | 7 lines
  
  The lib.text.table.format_table() function now handles overfull 
multi-column cells.
  
  The _determine_widths() private function has been created to better handle 
the determination of the
  table column widths.  It will now extend the width of the last column to 
allow overfull multi-column
  cells to fit.
........

Modified:
    branches/frame_order_testing/   (props changed)
    branches/frame_order_testing/lib/text/table.py
    
branches/frame_order_testing/test_suite/unit_tests/_lib/_text/test_table.py

Propchange: branches/frame_order_testing/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Mar  8 18:21:37 2013
@@ -1,1 +1,1 @@
-/trunk:1-18707
+/trunk:1-18713

Modified: branches/frame_order_testing/lib/text/table.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/frame_order_testing/lib/text/table.py?rev=18714&r1=18713&r2=18714&view=diff
==============================================================================
--- branches/frame_order_testing/lib/text/table.py (original)
+++ branches/frame_order_testing/lib/text/table.py Fri Mar  8 18:21:37 2013
@@ -28,6 +28,7 @@
 
 # relax module imports.
 from check_types import is_float
+from relax_errors import RelaxError
 
 
 # Special variables.
@@ -66,6 +67,10 @@
     for i in range(len(data)):
         # Loop over the columns.
         for j in range(len(data[i])):
+            # Skip multi-columns.
+            if data[i][j] == MULTI_COL:
+                continue
+
             # Default left justification.
             justification[i][j] = 'l'
 
@@ -95,6 +100,64 @@
             # All other non-string types.
             elif not isinstance(data[i][j], str):
                 data[i][j] = "%s" % data[i][j]
+
+
+def _determine_widths(data=None, widths=None, separator=None):
+    """Determine the maximum column widths needed given the data.
+
+    @keyword data:      Either the headings or content converted to strings 
to check the widths of.
+    @type data:         list of lists of str
+    @keyword widths:    The list of widths to start with.  If data is found 
to be wider than this list, then the width of that column will be expanded.
+    @type widths:       list of int
+    @keyword separator: The column separation string.
+    @type separator:    str
+    """
+
+    # The number of rows and columns.
+    num_rows = len(data)
+    num_cols = len(data[0])
+
+    # Determine the maximum column widths.
+    multi_col = False
+    for i in range(num_rows):
+        for j in range(num_cols):
+            # Switch the flag.
+            if data[i][j] == MULTI_COL:
+                multi_col = True
+
+            # Skip multicolumn entries.
+            if data[i][j] == MULTI_COL or (j < num_cols-1 and data[i][j+1] 
== MULTI_COL):
+                continue
+
+            # The element is larger than the previous.
+            if len(data[i][j]) > widths[j]:
+                widths[j] = len(data[i][j])
+
+    # Handle overfull multi-column cells.
+    if multi_col:
+        for i in range(num_rows):
+            for j in range(num_cols):
+                # End of multicolumn cell.
+                if data[i][j] == MULTI_COL and (j == num_cols-1 or (j < 
num_cols-1 and data[i][j+1] != MULTI_COL)):
+                    col_sum_width = widths[j]
+                    while 1:
+                        # Walk back.
+                        for k in range(j-1, -1, -1):
+                            col_sum_width += len(separator) + widths[k]
+
+                            # Out of the cell.
+                            if data[i][k] != MULTI_COL:
+                                break
+
+                        # Nothing more to do.
+                        break
+
+                    # The multicolumn width.
+                    multi_col_width = len(data[i][k])
+
+                    # The multicolumn cell is wider than the columns it 
spans, so expand the last column.
+                    if multi_col_width > col_sum_width:
+                        widths[j] += multi_col_width - col_sum_width
 
 
 def _rule(width=None, prefix=' ', postfix=' '):
@@ -158,6 +221,8 @@
             for j in range(i+1, num_col):
                 if text[j] == MULTI_COL:
                     width += len(separator) + widths[j]
+                else:
+                    break
 
             # Add the padded text.
             if justification[i] == 'l':
@@ -220,6 +285,18 @@
     if headings != None:
         num_head_rows = len(headings)
 
+    # Column number checks.
+    if custom_format != None and len(custom_format) != num_cols:
+        raise RelaxError("The number of columns is %s but the number of 
elements in custom_format is %s." % (num_cols, len(custom_format)))
+    if headings != None:
+        for i in range(num_head_rows):
+            if len(headings[i]) != num_cols:
+                raise RelaxError("The %s columns does not match the %s 
elements in the heading row %s." % (num_cols, len(headings[i]), headings[i]))
+    for i in range(num_rows):
+        if len(contents[i]) != num_cols:
+            raise RelaxError("The %s columns does not match the %s elements 
in the contents row %s." % (num_cols, len(contents[i]), contents[i]))
+
+
     # Deepcopy so that modifications to the data are not seen.
     if headings != None:
         headings = deepcopy(headings)
@@ -235,31 +312,13 @@
         _convert_to_string(data=headings, 
justification=justification_headings, custom_format=custom_format)
     _convert_to_string(data=contents, justification=justification_contents, 
custom_format=custom_format)
 
-    # Initialise the pre-wrapping column widths.
+    # Determine the pre-wrapping column widths.
     prewrap_widths = [0] * num_cols
-
-    # Determine the maximum column widths from the headers.
-    if headings != None:
-        for i in range(num_head_rows):
-            for j in range(num_cols):
-                # Skip multicolumn entries.
-                if headings[i][j] == MULTI_COL or (j < num_cols-1 and 
headings[i][j+1] == MULTI_COL):
-                    continue
-
-                # The element is larger than the previous.
-                if len(headings[i][j]) > prewrap_widths[j]:
-                    prewrap_widths[j] = len(headings[i][j])
-
-    # Determine the maximum column widths from the content.
-    for i in range(num_rows):
-        for j in range(num_cols):
-            # Skip multicolumn entries.
-            if contents[i][j] == MULTI_COL or (j < num_cols-1 and 
contents[i][j+1] == MULTI_COL):
-                continue
-
-            # The element is larger than the previous.
-            if len(contents[i][j]) > prewrap_widths[j]:
-                prewrap_widths[j] = len(contents[i][j])
+    if headings != None:
+        data = headings + contents
+    else:
+        data = contents
+    _determine_widths(data=data, widths=prewrap_widths, separator=separator)
 
     # The free space for the text (subtracting the space used for the 
formatting).
     used = len(pad_left)

Modified: 
branches/frame_order_testing/test_suite/unit_tests/_lib/_text/test_table.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/frame_order_testing/test_suite/unit_tests/_lib/_text/test_table.py?rev=18714&r1=18713&r2=18714&view=diff
==============================================================================
--- 
branches/frame_order_testing/test_suite/unit_tests/_lib/_text/test_table.py 
(original)
+++ 
branches/frame_order_testing/test_suite/unit_tests/_lib/_text/test_table.py 
Fri Mar  8 18:21:37 2013
@@ -250,3 +250,47 @@
         self.assertEqual(len(true_table), len(table_lines))
         for i in range(len(table_lines)):
             self.assertEqual(true_table[i], table_lines[i])
+
+
+    def test_format_table6(self):
+        """Test 6 of the lib.text.table.format_table() function - no 
headings."""
+
+        # The table data.
+        headings = [['Model', 'k', 'chi2', 'AIC', 'Average position', 
MULTI_COL, MULTI_COL, 'Motional eigenframe', MULTI_COL, MULTI_COL, 'Order 
parameters (deg)', MULTI_COL, MULTI_COL], [None, None, None, None, 'a', 'b', 
'g', 'a', 'b/th', 'g/ph', 'thx', 'thy', 'smax']]
+        contents = [['Rigid', 6, 1611.0583844357488, 1623.0583844357488, 
2.7928187044509789, 6.241673451655573, 3.3350126302921255, None, None, None, 
None, None, None], ['Rotor', 9, 1393.0628812874404, 1411.0628812874404, 
2.3720778521835015, 6.2511294411496241, 3.7347870727084764, None, 
1.3782156252713658, 5.5998324326753401, None, None, 36.651271107544183], 
['Iso cone, torsionless', 9, 1407.9014811061686, 1425.9014811061686, 
2.2550248034078395, 6.2368882019396619, 3.891108977360032, None, 
0.25090427716293384, 1.590485101074278, 21.287274572663485, None, None], 
['Iso cone', 10, 1400.3558737738815, 1420.3558737738815, 2.8146957276396858, 
6.2597080483925627, 3.2956149488567879, None, 1.3956123975976844, 
5.5817149266639987, 10.300677006193942, None, 32.387495822632452], ['Pseudo 
ellipse, torsionless', 11, 1386.6214759007082, 1408.6214759007082, 
2.6253119819082835, 6.2528446735668872, 3.4989380500907097, 
2.692632830571366, 0.43833843941243616, 1.3038063115520346, 
33.512494725673051, 15.888178532164503, None], ['Pseudo ellipse', 12, 
1378.8893702060313, 1402.8893702060313, 2.7403158840045716, 
6.259192518336242, 3.3759530521363121, 6.1651101516049849, 
1.3600775439064279, 5.5851511636460813, 13.646328409458231, 
0.74265383200964785, 31.027675419200627]]
+
+        # Create the table.
+        table = format_table(headings=headings, contents=contents, 
custom_format=[None, None, "%.2f", "%.2f", "%.3f", "%.3f", "%.3f", "%.3f", 
"%.3f", "%.3f", "%.2f", "%.2f", "%.2f"])
+        table_lines = table.split('\n')
+
+        # The true table.
+        true_table = [
+            " 
_______________________________________________________________________________________________________________________________
 ",
+            "                                                                
                                                                 ",
+            "  Model                         k    chi2      AIC       
Average position        Motional eigenframe     Order parameters (deg)  ",
+            "                                                         a      
 b       g       a       b/th    g/ph    thx     thy     smax    ",
+            " 
_______________________________________________________________________________________________________________________________
 ",
+            "                                                                
                                                                 ",
+            "  Rigid                          6   1611.06   1623.06   2.793  
 6.242   3.335                                                   ",
+            "  Rotor                          9   1393.06   1411.06   2.372  
 6.251   3.735           1.378   5.600                    36.65  ",
+            "  Iso cone, torsionless          9   1407.90   1425.90   2.255  
 6.237   3.891           0.251   1.590   21.29                   ",
+            "  Iso cone                      10   1400.36   1420.36   2.815  
 6.260   3.296           1.396   5.582   10.30            32.39  ",
+            "  Pseudo ellipse, torsionless   11   1386.62   1408.62   2.625  
 6.253   3.499   2.693   0.438   1.304   33.51   15.89           ",
+            "  Pseudo ellipse                12   1378.89   1402.89   2.740  
 6.259   3.376   6.165   1.360   5.585   13.65    0.74    31.03  ",
+            " 
_______________________________________________________________________________________________________________________________
 ",
+            "                                                                
                                                                 ",
+            ""    # This is because split combined with a final \n character.
+        ]
+
+        # Printout.
+        print("The formatted table:")
+        for i in range(len(table_lines)):
+            print("'%s'" % table_lines[i])
+        print("\nWhat the table should look like:")
+        for i in range(len(true_table)):
+            print("'%s'" % true_table[i])
+
+        # Check the table.
+        self.assertEqual(len(true_table), len(table_lines))
+        for i in range(len(table_lines)):
+            self.assertEqual(true_table[i], table_lines[i])




Related Messages


Powered by MHonArc, Updated Fri Mar 08 18:40:02 2013