fixedwidth icon indicating copy to clipboard operation
fixedwidth copied to clipboard

[Suggestion] mapping type?

Open gnudiff opened this issue 7 years ago • 1 comments

Hello and thanks again for implementing this, very useful! It turns out there are plenty of organisations still using fixed width files, especially older ERP systems.

I was wondering, if you could possibly consider improving your module even further with an additional data type, which would allow for seamless translation of key values between formats, such as frequently are needed? It would allow these conversions happen more transparently and keep the config of data type in one place.

Let us suppose that you have format A, in which certain field ORDER_TYPE can (only) contain certain codes, for example: ["SALE", "PRCH", "XFER"], and you need to convert it to another format B, in which the same codes are called [ "SELL", "BUY", "TRANSFER"]. It seems to me it would be elegant if it were possible to do something like this:

config={
    "ORDER_TYPE": {
      "required" : True,
       "type": "mapping",
       "start_pos": 1,
       "length": 4,
       "values" : dict( SALE="SELL", PRCH="BUY", XFER="TRANSFER")
    }
}

and the effect would be this:

proc=FixedWidth(config)
proc.line="XFER"
proc.data: 
{ 'ORDER_TYPE' : 'TRANSFER'}
proc.line='NONE'
    ValueError: Key not found in mapping data type!'

I would be glad to implement it myself, but I am not certain enough of my Python skills.

gnudiff avatar Jan 29 '19 14:01 gnudiff

Hey @gnudiff. Thanks for the feedback. This could be useful, and I can see how it may have already been implemented privately by some users. I think I'd like to see more use cases before allowing an implementation into the library. For example, we'd have to consider cases where people need to convert date and numeric formats, as well as strings.

If you'd like to begin working on a branch, I will help you. I don't use the library anymore, and don't have extra time to work on it. To get you started, here's some working sample code you can build on.

#!/usr/bin/env python
"""
Example conversion code.
"""

from __future__ import unicode_literals

def to_dict(trans, lookup):
    reverse = {b: a for a, b in lookup.items()}
    trans["type"] = reverse[trans["type"]]
    return trans


def to_fw(trans, lookup):
    trans["type"] = lookup[trans["type"]]
    return trans


def main():
    """
    Declare mapping, then do conversion.
    """
    lookup = {"SALE": "SELL", "PRCH": "BUY", "XFER": "TRANSFER"}
    samples = [
        {"id": 01, "type": "SALE"},
        {"id": 02, "type": "PRCH"},
        {"id": 03, "type": "XFER"},
    ]

    for sample in samples:
        print "Original: {0}".format(sample)
        print "Converted: {0}".format(to_fw(sample, lookup))
        print "Restored: {0}".format(to_dict(sample, lookup))
        print
        

if __name__ == '__main__':
    main()

ShawnMilo avatar Feb 01 '19 15:02 ShawnMilo