Skip to main content
Question

Concatenator code


ingalla
Contributor
Forum|alt.badge.img+10

I have been given the following python code but get errors every time i try to run it, anyone know what is wrong...

import fmeobjects

def FeatureProcessor(feature): to_concatenate = ("buildingNumber", "throughfare", "dependantthroughfare")

# Modify as needed

join_string = ","

# Modify as needed

result = join_string.join([feature.getAttribute(attr) \\

for attr in to_concatenate if feature.getAttribute(attr)])

feature.setAttribute("CONCATENATED", result)

 

14 replies

takashi
Influencer
  • November 8, 2018

What error is logged?


jdh
Contributor
Forum|alt.badge.img+28
  • Contributor
  • November 8, 2018

Does it work if you separate the list comprehension into for and if components?


ingalla
Contributor
Forum|alt.badge.img+10
  • Author
  • Contributor
  • November 8, 2018

Here are the errors

Python Exception <SyntaxError>: unexpected character after line continuation character (<string>, line 7)

Error executing string `import<space>fmeobjects<space><space><space><lf>def<space>FeatureProcessor<openparen>feature<closeparen>:to_concatenate<space>=<space><openparen><quote>buildingNumber<quote><comma><space><quote>throughfare<quote><comma><space><quote>dependantthroughfare<quote><closeparen><space><lf>#<space>Modify<space>as<space>needed<space><space><space><space><space><lf>join_string<space>=<space><quote><comma><quote><space><lf>#<space>Modify<space>as<space>needed<space><space><space><space><space><lf>result<space>=<space>join_string.join<openparen><openbracket>feature.getAttribute<openparen>attr<closeparen><space><backslash><space>for<space>attr<space>in<space>to_concatenate<space>if<space>feature.getAttribute<openparen>attr<closeparen><closebracket><closeparen><space><space><space><lf>feature.setAttribute<openparen><quote>CONCATENATED<quote><comma><space>result<closeparen>'

Factory proxy not initialized

PythonCaller(PythonFactory): PythonFactory failed to process feature

A fatal error has occurred. Check the logfile above for details


takashi
Influencer
  • November 8, 2018

Could you please repost the script as-is, using a code block?


ingalla
Contributor
Forum|alt.badge.img+10
  • Author
  • Contributor
  • November 8, 2018

import fmeobjects

def FeatureProcessor(feature):to_concatenate = ("buildingNumber", "throughfare", "dependantthroughfare")

# Modify as needed

join_string = ","

# Modify as needed

result = join_string.join([feature.getAttribute(attr) \\ for attr in to_concatenate if feature.getAttribute(attr)])

feature.setAttribute("CONCATENATED", result)

 


erik_jan
Contributor
Forum|alt.badge.img+18
  • Contributor
  • November 8, 2018

Could this be solved by replacing the PythonCaller by a StringConcatenator transformer?

That seems so much easier.


jdh
Contributor
Forum|alt.badge.img+28
  • Contributor
  • November 8, 2018

I would expect the code to work with the following formatting

 

import fmeobjects

def FeatureProcessor(feature): 
  Â  to_concatenate = ("buildingNumber""throughfare""dependantthroughfare")
  Â  # Modify as needed

  Â  join_string = ","

  Â  # Modify as needed

  Â  result = join_string.join([feature.getAttribute(attr)\
    for attr in to_concatenate if feature.getAttribute(attr)])

  Â  feature.setAttribute("CONCATENATED", result)

 

 


jdh
Contributor
Forum|alt.badge.img+28
  • Contributor
  • November 8, 2018
jdh wrote:

I would expect the code to work with the following formatting

 

import fmeobjects

def FeatureProcessor(feature): 
  Â  to_concatenate = ("buildingNumber""throughfare""dependantthroughfare")
  Â  # Modify as needed

  Â  join_string = ","

  Â  # Modify as needed

  Â  result = join_string.join([feature.getAttribute(attr)\
    for attr in to_concatenate if feature.getAttribute(attr)])

  Â  feature.setAttribute("CONCATENATED", result)

 

 

ignore the Â, that's a problem with the knowledgebase upgrade.

 

Put to_concatenate on a separate (indented) line from the function definition.

Either break the list comprehension line, or don't, if you do there can be nothing after it.

result = join_string.join([feature.getAttribute(attr)\
for attr in to_concatenate if feature.getAttribute(attr)])

or

result = join_string.join([feature.getAttribute(attr)for attr in to_concatenate if feature.getAttribute(attr)])

in the second case, it's all on one line.


jdh
Contributor
Forum|alt.badge.img+28
  • Contributor
  • November 8, 2018
erik_jan wrote:

Could this be solved by replacing the PythonCaller by a StringConcatenator transformer?

That seems so much easier.

I am assuming they don't want ,, when the attribute is empty/missing.


erik_jan
Contributor
Forum|alt.badge.img+18
  • Contributor
  • November 8, 2018
jdh wrote:

I am assuming they don't want ,, when the attribute is empty/missing.

Then create an attribute for the concatenation character, like this:

And the StringConcatenator to do the magic:


geosander
Forum|alt.badge.img+7
  • November 8, 2018

You could also use this code:

import fmeobjects

def get_attributes(feature, attr_names):
  Â Â for attr_name in attr_names:
  Â  Â  Â  value = feature.getAttribute(attr_name)
  Â  Â  Â Â if value:
  Â  Â  Â  Â  Â Â yield value

def FeatureProcessor(feature): 
  Â  to_concatenate = ("buildingNumber", "throughfare", "dependantthroughfare")

  Â Â # Modify as needed
  Â  result = ",".join(get_attributes(feature, to_concatenate))

  Â Â # Modify as needed
  Â  feature.setAttribute("CONCATENATED", result)

 

I'm not a big fan of list comprehensions in this particular case, because they call feature.getAttribute() twice, which is unnecessary. This is why I created the generator function get_attributes(), which only returns the attributes with a "truthy" value.

Please be aware that if the feature attribute contains the number 0 (stored as integer or float), this value is considered to be "falsy", which means that it will not be concatenated in the result. What's worse though, is that the script will choke on the str.join() call if 1 or more attributes aren't string values (which is actually what your attribute names suggest).

To tackle both problems, you could replace the get_attributes() function with this block:

def get_attributes(feature, attr_names):
  Â Â for attr_name in attr_names:
  Â  Â  Â  value = feature.getAttribute(attr_name)
  Â  Â  Â Â if value not in ('', None):
  Â  Â  Â  Â  Â  yield format(value)

This will work as long as you don't have any non-ASCII characters in your attributes...


geosander
Forum|alt.badge.img+7
  • November 8, 2018
geosander wrote:

You could also use this code:

import fmeobjects

def get_attributes(feature, attr_names):
  Â Â for attr_name in attr_names:
  Â  Â  Â  value = feature.getAttribute(attr_name)
  Â  Â  Â Â if value:
  Â  Â  Â  Â  Â Â yield value

def FeatureProcessor(feature): 
  Â  to_concatenate = ("buildingNumber", "throughfare", "dependantthroughfare")

  Â Â # Modify as needed
  Â  result = ",".join(get_attributes(feature, to_concatenate))

  Â Â # Modify as needed
  Â  feature.setAttribute("CONCATENATED", result)

 

I'm not a big fan of list comprehensions in this particular case, because they call feature.getAttribute() twice, which is unnecessary. This is why I created the generator function get_attributes(), which only returns the attributes with a "truthy" value.

Please be aware that if the feature attribute contains the number 0 (stored as integer or float), this value is considered to be "falsy", which means that it will not be concatenated in the result. What's worse though, is that the script will choke on the str.join() call if 1 or more attributes aren't string values (which is actually what your attribute names suggest).

To tackle both problems, you could replace the get_attributes() function with this block:

def get_attributes(feature, attr_names):
  Â Â for attr_name in attr_names:
  Â  Â  Â  value = feature.getAttribute(attr_name)
  Â  Â  Â Â if value not in ('', None):
  Â  Â  Â  Â  Â  yield format(value)

This will work as long as you don't have any non-ASCII characters in your attributes...

Oh dear, this new <code> style formatting in the Knowledge Base is absolutely horrible...


david_r
Celebrity
  • November 9, 2018
geosander wrote:

Oh dear, this new <code> style formatting in the Knowledge Base is absolutely horrible...

I agree, it's really terrible. I think Safe is working on it, however...


takashi
Influencer
  • November 9, 2018

Alternatively, FME String functions might be helpful. e.g.

@ReplaceRegEx(@Trim(@CurrentAttribute(),","),",{2,}",",")

0684Q00000ArKVPQA3.png


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings