HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Python code to weave rows

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
coderowsweavepython

Problem

I want to write a cleaner version of the code shown below. It's about two different rows consisting of numbers that have to be weaved.

It's for an assignment for a course i'm currently following. This is the assignment:

Traveler, if riches are to be achieved, the solution only has to be weaved.    
5,4 4,5 8,7
Weave 6,3 3,2 9,6 4,3
Weave 7,6
Weave 9,8
Weave 5,5 7,8 6,5 6,4


I have to start with the coordinates on the first row, weave the coordinates of the second row through the first row, then weave the coordinates of the third row through the resulting row etc. Note, if two rows of unequal length have to be woven, the two rows are woven as far as possible. After the elements of the shortest row have been exhausted, the row is completed by adding the remaining elements of the longest row.

The input is this:

5,4 4,5 8,7=6,3 3,2 9,6 4,3=7,6=9,8=5,5 7,8 6,5 6,4


The output has to be like this:

6,4
6,5
10,8
8,8
8,6
7,5
7,3
7,4
5,5
4,2
9,7
10,6
5,3


My code is in three files.

Coordinaat.py

class Coordinaat:
    def __init__(self, x_coordinaat, y_coordinaat):
        self.x_coordinaat = x_coordinaat
        self.y_coordinaat = y_coordinaat

    def bereken_nieuw_coordinaat(self):
        self.x_coordinaat += 1
        self.y_coordinaat += 0 
        return self.x_coordinaat, self.y_coordinaat


CoordinaatRij.py

class CoordinaatRij:
    def __init__(self, rij):
        self.rij = rij

    def voeg_toe(self,coordinaat):
        self.rij += [coordinaat]

    def breid_uit(self, rij):
        for coordinaat1 in rij:
            self.rij += [coordinaat1]

    def weave(self, weef_rij):
        resultaat = CoordinaatRij([])

        for i in range(len(self.rij)):
            if i  len(self.rij):
            resultaat.breid_uit(weef_rij.rij[len(self.rij):])
        return resultaat


Excerpt of the main code

```
file_input = file.read()
strip_file = file_input.strip()
invoer = strip_file.split("=")

from Coordinaat import Coordinaa

Solution

English code reads better, since the Python standard library is English. If you use Dutch, though, please do so consistently. Don't mix file_input and invoer, or def weave(self, weef_rij).

It's hard to understand what the task to be performed is, and what this code does. Docstrings and doctests would be a good idea.

It is awkward how you do parts of the parsing all over the place:

  • strip_file = file_input.strip() and strip_file.split('=') in the main code. It's especially bad that this snippet is placed before the imports, and before the next line of code (geweefde_rijen = nieuwe_rijen(invoer)).



  • invoer[i].split() within nieuwe_rijen().



  • int(coordinaat1[0]), int(coordinaat1[2]) within nieuwe_coordinaten().



It would be better to get the parsing done all at once, into a list of pairs of integers. Not only would the code be easier to understand, it would also let the program fail earlier if the input is invalid.

I think you have overdone the OOP here. There is not much point in defining a Coordinaat class, which is basically just a tuple, or CoordinaatRij, which is basically just a list. All you need for this job is a few functions.

Specifically, it would be useful to take advantage of itertools.izip_longest(), which is the core of what you are trying to do. Then, to transform the result repeatedly for subsequent rows, use the reduce() function.

from itertools import chain, izip_longest

def coordinaatrijen_parsen(tekenreeks, rij_scheidingsteken='\n'):
    """
    Yield each row of coordinates as a list of (int, int).

    >>> list(coordinaatrijen_parsen('1,2 3,4=  5,6 ', '='))
    [[(1, 2), (3, 4)], [(5, 6)]]
    """
    for rij in tekenreeks.split(rij_scheidingsteken):
        yield [
            tuple(int(c) for c in coord.split(','))
            for coord in rij.split()
        ]

def weven(*rijen):
    """
    Interleave elements from the parameters.

    >>> weven('Geeogn', 'odmre')
    ['G', 'o', 'e', 'd', 'e', 'm', 'o', 'r', 'g', 'e', 'n']
    >>> weven('Gee', 'odmorgen')
    ['G', 'o', 'e', 'd', 'e', 'm', 'o', 'r', 'g', 'e', 'n']
    >>> weven('Gd', 'o', 'eemorgen')
    ['G', 'o', 'e', 'd', 'e', 'm', 'o', 'r', 'g', 'e', 'n']
    """
    return filter(None, chain(*izip_longest(*rijen)))

if __name__ == '__main__':
    with open(...) as f:
        rijen = coordinaatrijen_parsen(f.read(), '=')
    resultaat = [(x + 1, y) for x, y in reduce(weven, rijen, [])]
    for coord in resultaat:
        print '%d, %d' % coord

Code Snippets

from itertools import chain, izip_longest

def coordinaatrijen_parsen(tekenreeks, rij_scheidingsteken='\n'):
    """
    Yield each row of coordinates as a list of (int, int).

    >>> list(coordinaatrijen_parsen('1,2 3,4=  5,6 ', '='))
    [[(1, 2), (3, 4)], [(5, 6)]]
    """
    for rij in tekenreeks.split(rij_scheidingsteken):
        yield [
            tuple(int(c) for c in coord.split(','))
            for coord in rij.split()
        ]

def weven(*rijen):
    """
    Interleave elements from the parameters.

    >>> weven('Geeogn', 'odmre')
    ['G', 'o', 'e', 'd', 'e', 'm', 'o', 'r', 'g', 'e', 'n']
    >>> weven('Gee', 'odmorgen')
    ['G', 'o', 'e', 'd', 'e', 'm', 'o', 'r', 'g', 'e', 'n']
    >>> weven('Gd', 'o', 'eemorgen')
    ['G', 'o', 'e', 'd', 'e', 'm', 'o', 'r', 'g', 'e', 'n']
    """
    return filter(None, chain(*izip_longest(*rijen)))

if __name__ == '__main__':
    with open(...) as f:
        rijen = coordinaatrijen_parsen(f.read(), '=')
    resultaat = [(x + 1, y) for x, y in reduce(weven, rijen, [])]
    for coord in resultaat:
        print '%d, %d' % coord

Context

StackExchange Code Review Q#148758, answer score: 5

Revisions (0)

No revisions yet.