Converting arrarys in Python to arrays in C

Discussion in 'Python' started by Simon Foster, Dec 17, 2003.

  1. Simon Foster

    Simon Foster Guest

    I have some code which attempts to convert Python arrays (tuples of
    tuples of tuples...) etc. into C arrays with equivalent contents.

    The prototype code is shown below.

    My only question is, is there some way of doing this without repeating
    the try..except blocks ad-infinitum to handle 3D, 4D arrays etc.

    I can see there is a pattern here but I can't seem to turn it into a
    loop. Would a recursive solution do the trick?


    cdata0 = 0

    cdata1 = ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 )

    cdata2 = (( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ))

    if __name__ == '__main__':

    import sys
    sys.stdout = file( 'cdata.log', 'w' )

    def arrayLine( s ):
    return ', '.join( [ '0x%04X' % t for t in s ] )

    def array0D( data ):
    print 'unsigned char = 0x%04X;' % data

    def array1D( data ):
    print 'unsigned char[] = { %s };' % arrayLine( data )

    def array2D( data ):
    array = [ 'unsigned char[][] = {' ]
    for i in data:
    array.append( '\t{ %s },' % arrayLine( i ))
    array.append( '};' )
    print '\n'.join( array )

    for cdata in cdata0, cdata1, cdata2:
    declare = []
    try:
    iter(cdata)
    try:
    iter(cdata[0])
    try:
    iter(cdata[0][0])
    except TypeError:
    array2D( cdata )
    except TypeError:
    array1D( cdata )
    except TypeError:
    array0D( cdata )
    Simon Foster, Dec 17, 2003
    #1
    1. Advertising

  2. Simon Foster <> wrote:

    >I have some code which attempts to convert Python arrays (tuples of
    >tuples of tuples...) etc. into C arrays with equivalent contents.
    >
    >The prototype code is shown below.
    >
    >My only question is, is there some way of doing this without repeating
    >the try..except blocks ad-infinitum to handle 3D, 4D arrays etc.
    >
    >I can see there is a pattern here but I can't seem to turn it into a
    >loop. Would a recursive solution do the trick?


    Probably yes, but why reinvent the wheel? Numeric does what you want
    already and allows for efficient conversions too [1].

    Anton


    [1] For example, using your code as a basis:

    import Numeric

    def test():
    cdata0 = 0

    cdata1 = ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 )

    cdata2 = (( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ))

    for cdata in cdata0, cdata1, cdata2:
    a = Numeric.array(cdata)
    print a.shape
    print a
    print

    if __name__=='__main__':
    test()
    Anton Vredegoor, Dec 17, 2003
    #2
    1. Advertising

  3. Simon Foster wrote in message
    <3fe06b14$0$25662$>...
    >I have some code which attempts to convert Python arrays (tuples of
    >tuples of tuples...) etc. into C arrays with equivalent contents.
    >
    >The prototype code is shown below.


    This doesn't generate legal C.

    It also does no bounds checking, so you may end up with a Python int that
    doesn't fit into a C char. (Which is most certainly 1 byte, so why do you
    use 4 hex digits to represent it?)

    >My only question is, is there some way of doing this without repeating
    >the try..except blocks ad-infinitum to handle 3D, 4D arrays etc.


    Of course. This approach you used is in fact very unusual, especially with
    the print statements. You've simply made a special purpose function for
    each depth of array.

    >I can see there is a pattern here but I can't seem to turn it into a
    >loop. Would a recursive solution do the trick?


    The recursive solution is more natural here, I think, but iterative is
    possible, too.

    The pattern is ', '.join(<elements>), where <elements> is {<arrayORint>}.
    The rest is just fluff.

    You seem to have gotten hung up on the type declaration. You can't declare
    the type until you know the depth of the array, so generate the array first,
    *then* get construct the declaration.

    Now for homework, convert the hackish solution below into a recursive
    generator. ;)

    def seqtobrace(seq, depth=0):
    """Return a comma- and brace-delimited version of seq, and the depth of
    seq."""
    depth += 1
    if isinstance(seq[0], (tuple, list)):
    subelem, depths = zip(*[seqtobrace(s, depth) for s in seq])
    delim = ',\n' + ' '*2*depth
    depth = depths[0]
    elements = delim.join(subelem)
    elif isinstance(seq[0], (int, long)):
    elements = ', '.join(map(hex, seq))
    else:
    raise TypeError, "seq must be list or tuple with int or long
    leaves."
    return '{ %s }' % elements, depth

    def toCarray(seq, name):
    """Return an unsigned char C array declaration of name from seq."""
    assert isinstance(name, basestring)
    if isinstance(seq, (int, long)):
    return 'unsigned char %s = 0x%X;' % (name, seq)
    else:
    array, depth = seqtobrace(seq)
    ad = '[]'*depth
    typedec = 'unsigned char%s %s = \n' % (ad, name)
    return typedec + array + ';'
    --
    Francis Avila
    Francis Avila, Dec 17, 2003
    #3
  4. It doesn't look to me like Numeric does what you want to do;
    it looks more like you want to print out C code that initializes
    a big array.

    Try writing a function that counts the number of dimensions
    you're working with:

    import types

    # quick and dirty, assumes you've only got tuples and integers
    def dimensions(obj):
    if not isinstance(obj, types.TupleType):
    return 0
    else:
    return 1 + dimensions(obj[0])


    # Now you don't need array0D, array1D, etc..

    def write_array(data):
    dims = dimensions(data)
    print "unsigned char%s = " % "[]" * dims
    ...

    I've gotta run (no time to finish this post), but hopefully that helps...




    Simon Foster <> wrote in message news:<3fe06b14$0$25662$>...
    > I have some code which attempts to convert Python arrays (tuples of
    > tuples of tuples...) etc. into C arrays with equivalent contents.
    >
    > The prototype code is shown below.
    >
    > My only question is, is there some way of doing this without repeating
    > the try..except blocks ad-infinitum to handle 3D, 4D arrays etc.
    >
    > I can see there is a pattern here but I can't seem to turn it into a
    > loop. Would a recursive solution do the trick?
    >
    >
    > cdata0 = 0
    >
    > cdata1 = ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 )
    >
    > cdata2 = (( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    > ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    > ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    > ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    > ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    > ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    > ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    > ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    > ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
    > ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ))
    >
    > if __name__ == '__main__':
    >
    > import sys
    > sys.stdout = file( 'cdata.log', 'w' )
    >
    > def arrayLine( s ):
    > return ', '.join( [ '0x%04X' % t for t in s ] )
    >
    > def array0D( data ):
    > print 'unsigned char = 0x%04X;' % data
    >
    > def array1D( data ):
    > print 'unsigned char[] = { %s };' % arrayLine( data )
    >
    > def array2D( data ):
    > array = [ 'unsigned char[][] = {' ]
    > for i in data:
    > array.append( '\t{ %s },' % arrayLine( i ))
    > array.append( '};' )
    > print '\n'.join( array )
    >
    > for cdata in cdata0, cdata1, cdata2:
    > declare = []
    > try:
    > iter(cdata)
    > try:
    > iter(cdata[0])
    > try:
    > iter(cdata[0][0])
    > except TypeError:
    > array2D( cdata )
    > except TypeError:
    > array1D( cdata )
    > except TypeError:
    > array0D( cdata )
    Lonnie Princehouse, Dec 18, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sanjay Tibrewal

    Converting DataColumn to Arrays

    Sanjay Tibrewal, Mar 18, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    457
    Sanjay Tibrewal
    Mar 18, 2006
  2. Tim Clacy

    Arrarys of reference

    Tim Clacy, Oct 31, 2003, in forum: C++
    Replies:
    7
    Views:
    416
    Troll_King
    Nov 2, 2003
  3. Foxy Kav
    Replies:
    1
    Views:
    459
    John Carson
    Apr 25, 2004
  4. Philipp
    Replies:
    21
    Views:
    1,109
    Philipp
    Jan 20, 2009
  5. Javier Montoya

    numpy arrays to python compatible arrays

    Javier Montoya, Jun 10, 2010, in forum: Python
    Replies:
    3
    Views:
    440
    Javier Montoya
    Jun 12, 2010
Loading...

Share This Page