Changeset 6415


Ignore:
Timestamp:
Feb 25, 2009, 11:44:06 AM (15 years ago)
Author:
rwilson
Message:

Added routines to encode/decode arrays of strings (and test).

Location:
branches/numpy/anuga/utilities
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/numpy/anuga/utilities/system_tools.py

    r6411 r6415  
    66import sys
    77import os
     8import string
    89
    910def log_to_file(filename, s, verbose=False):
     
    260261
    261262
     263################################################################################
     264# The following two functions are used to get around a problem with numpy and
     265# NetCDF files.  Previously, using Numeric, we could take a list of strings and
     266# convert to a Numeric array resulting in this:
     267#     Numeric.array(['abc', 'xy']) -> [['a', 'b', 'c'],
     268#                                      ['x', 'y', ' ']]
     269#
     270# However, under numpy we get:
     271#     numpy.array(['abc', 'xy']) -> ['abc',
     272#                                    'xy']
     273#
     274# And writing *strings* to a NetCDF file is problematic.
     275#
     276# The solution is to use these two routines to convert a 1-D list of strings
     277# to the 2-D list of chars form and back.  The 2-D form can be written to a
     278# NetCDF file as before.
     279#
     280# The other option, of inverting a list of tag strings into a dictionary with
     281# keys being the unique tag strings and the key value a list of indices of where
     282# the tag string was in the original list was rejected because:
     283#    1. It's a lot of work
     284#    2. We'd have to rewite the I/O code a bit (extra variables instead of one)
     285#    3. The code below is fast enough in an I/O scenario
     286################################################################################
     287
     288##
     289# @brief Convert 1-D list of strings to 2-D list of chars.
     290# @param l 1-dimensional list of strings.
     291# @return A 2-D list of 'characters' (1 char strings).
     292# @note No checking that we supply a 1-D list.
     293def string_to_char(l):
     294    '''Convert 1-D list of strings to 2-D list of chars.'''
     295
     296    maxlen = reduce(max, map(len, l))
     297    ll = [x.ljust(maxlen) for x in l]
     298    result = []
     299    for s in ll:
     300        result.append([x for x in s])
     301    return result
     302
     303
     304##
     305# @brief Convert 2-D list of chars to 1-D list of strings.
     306# @param ll 2-dimensional list of 'characters' (1 char strings).
     307# @return A 1-dimensional list of strings.
     308# @note Each string has had right-end spaces removed.
     309def char_to_string(ll):
     310    '''Convert 2-D list of chars to 1-D list of strings.'''
     311
     312    return map(string.rstrip, [''.join(x) for x in ll])
     313
     314
  • branches/numpy/anuga/utilities/test_system_tools.py

    r6410 r6415  
    183183
    184184################################################################################
     185# Test the string_to_char() and char_to_string() utility functions.
     186################################################################################
     187
     188    def test_string_to_char(self):
     189        import random
     190
     191        MAX_CHARS = 10
     192        MAX_ENTRIES = 100000
     193        A_INT = ord('a')
     194        Z_INT = ord('z')
     195
     196        # generate some random strings in a list, with guaranteed lengths
     197        str_list = ['x' * MAX_CHARS]        # make first maximum length
     198        for entry in xrange(MAX_ENTRIES):
     199            length = random.randint(1, MAX_CHARS)
     200            s = ''
     201            for c in range(length):
     202                s += chr(random.randint(A_INT, Z_INT))
     203            str_list.append(s)
     204
     205        x = string_to_char(str_list)
     206        new_str_list = char_to_string(x)
     207
     208        self.failUnlessEqual(new_str_list, str_list)
     209
     210
     211################################################################################
     212# Test the raw I/O to NetCDF files of string data encoded/decoded with
     213# string_to_char() and char_to_string().
     214################################################################################
     215
     216################################################################################
    185217
    186218if __name__ == "__main__":
    187     suite = unittest.makeSuite(Test_system_tools, 'test')
     219    #suite = unittest.makeSuite(Test_system_tools, 'test')
     220    suite = unittest.makeSuite(Test_system_tools, 'test_string_to_char')
    188221    runner = unittest.TextTestRunner()
    189222    runner.run(suite)
Note: See TracChangeset for help on using the changeset viewer.