[Tutor] text processing lines variable content

Peter Otten __peter__ at web.de
Thu Feb 7 05:08:46 EST 2019


ingo janssen wrote:

> 
> On 07/02/2019 09:29, Peter Otten wrote:
>> Where will you get the order from?
> 
> Peter,
> 
> the order comes from the command line. 

Then my one-function-per-format approach won't work.

> I intend to call the python
> program with the same command line options as the Voro++ program. Make
> the python program call the Voro++ and process its output.
> 
> one command line option contains a string for formatting the output.
> That is what I use for order.
> 
> #all output formatting options
> order = "%i %q %r %w %p %P %o %m %g %E %s %e %F %a %A %f %t %l %n %v %c
> %C" order = re.findall("%[a-z]",order,re.M|re.I)
> for i, line in enumerate(open("vorodat.vol",'r')):
>    points = i
>    line = line.strip()
>    line = line.split(" ")
>    for action in order:
>      if action == "%i":
>        try:
>          lbl = f_label(label)
>        except NameError as e:
>           lbl = f_number(label)
>           label=[lbl]

Personally I would avoid the NameError and start with empty lists. If you 
manage to wrap all branches into functions with the same signature you can 
replace the sequence of tests with dictionary lookups. Here's a sketch:


# the f_...() functions take a parsed line and return a value and the
# as yet unused rest of the parsed line

labels = []
points = []
...
def add_label(parts):
   label, rest = f_label(parts)
   labels.append(label)
   return rest

def add_point(parts):
    point, rest = f_vector(parts)
    points.append(point)
    return rest

def add_point(parts):
    global width
    width, rest = f_width(parts)
    return rest

lookup_actions = {
    "%i": add_label,
    "%q": add_point,
    "%w": set_width,
    ...
}

actions = [lookup_actions[action] for action in order]

with open("vorodat.vol") as instream:
    for points, line in enumerate(instream, 1):  # as per Mark's advice
        width = None  # dummy value to provoke error when width
                      # is not explicitly set
        parts = line.split()
        for action in actions:
            parts = actions(parts)


>      elif action == "%q":
>        try:
>          f_vector(point)
>        except NameError as e:
>            point = [f_vector(point)]
>      elif action == "%r":
>        try:
>          f_value(radius)
>        except NameError as e:
>          radius=[f_value(radius)]
> etc.
> 
> order is important as %w tells me how long %p, %P and %o will be. This
> varies per line.
> 
> I'll look into what you wrote,



More information about the Tutor mailing list