pythonfme

Making a list of streetadresses


SOLVED :-) I'm having this list, and would like to get the expected result, but no luck. Tried in python and FME

If there is more than 2 between the current and then previous number, a new line has to start

Can anybody help? Preferable in FME, but okay in python too

StreetName;HouseNumber;OddEven
Northroad;1;O
Northroad;2;E
Northroad;3;O
Northroad;4;E
Northroad;8;E
Northroad;10;E
Southroad;1;O
Southroad;2;E
Southroad;3;O
Southroad;4;E
Southroad;10;E
Southroad;12;E
Southroad;14;E

My result:

Northroad 1-3
Northroad 2-10
Southroad 1-3
Southroad 2-14

Expected result:

Northroad 1-3
Northroad 2-4
Northroad 8-10
Southroad 1-3
Southroad 2-4
Southroad 10-14

Does it make any sense?


Solution

  • It is a medium complexity parsing, processing and formatting task, so I would use classes: one for a contiguous address range on one side of one road, and one to be the container of that ranges. That way the load interface will be as simple as adding a decoded row, and the formatting interface will be as simple.

    Code could be:

    # set the filenames here:
    filename = "input.csv"
    out = output.txt
    class AddressRange:
        def __init__(self, row):
            self.road = row[0]
            self.low = self.high = int(row[1])
            self.side = row[2]
    
        def add(self, row):
            if (self.road != row[0]) or (self.side != row[2]):
                return False
            val = int(row[1])
            if val < self.low <= val+2:
                self.low = val
            elif val-2 <= self.high < val:
                self.high = val
            else:
                return False
            return True
        def __str__(self):
            return '%s %d-%d' % (self.road, self.low, self.high)
    
    class AddressList:
        def __init__(self):
            self.ranges = []
        def add(self, row):
            for ar in self.ranges:
                if ar.add(row):
                    break
            else:
                self.ranges.append(AddressRange(row))
        def print(self, fd=sys.stdout):
            for ar in self.ranges:
                print(str(ar), file=fd)
    
    
    with open(filename) as fd:
        rd = csv.reader(fd, delimiter = ';')
        lst = AddressList()
        _ = next(fd)              # skip header line
        for row in rd:
            if len(row) == 3:
                lst.add(row)
    
    with open(out, 'w') as fd:
        lst.print(out)
    

    With the sample input file, the ouput is as expected:

    Northroad 1-3
    Northroad 2-4
    Northroad 8-10
    Southroad 1-3
    Southroad 2-4
    Southroad 10-14