Skip to main content

Hi everybody,

First time trying to get something done in Python so please bear with me...

I'm trying to find the greatest common divisor of a set of numbers, supplied as a comma-separated string through a User Parameter. Python has a function (gcd) that does just that (originally for 2 numbers, but through the reduce function it can iterate)

However, I can't seem to pass my numbers into the function.

class FeatureProcessor(object):
    def __init__(self):
        pass
    def input(self,feature):
        # divisor = reduce(fractions.gcd, (10,15,25,50))  
        divisor = reduce(fractions.gcd, (FME_MacroValuesc'Contours']))
        feature.setAttribute("divisor", divisor)
        self.pyoutput(feature)
    def close(self):
        pass

The line that's commented out works, but if I pass those same numbers through the parameter I get an error message:

Python Exception <TypeError>: not all arguments converted during string formatting

Traceback (most recent call last):

  File "<string>", line 18, in input

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/fractions.py", line 25, in gcd

    a, b = b, a%b

TypeError: not all arguments converted during string formatting

Error encountered while calling method `input'

f_11(PythonFactory): PythonFactory failed to process feature

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

I'm pretty sure it has something to do with how I'm passing the parameter, but I can't figure it out. Any suggestions?

The problem is that FME_MacroValues always returns a string, so what you're actually saying is:

divisor = reduce(fractions.gcd, ("10,15,25,50"))

Which of course won't work. Try the following to convert your string into a list of integers:

values = (int(x) for x in FME_MacroValues='Contours'].split(','))
divisor = reduce(fractions.gcd, values)

If the syntax for generating 'values' is unfamiliar to you, look up "python generator comprehension" on google for tutorials, etc.


The problem is that FME_MacroValues always returns a string, so what you're actually saying is:

divisor = reduce(fractions.gcd, ("10,15,25,50"))

Which of course won't work. Try the following to convert your string into a list of integers:

values = (int(x) for x in FME_MacroValues='Contours'].split(','))
divisor = reduce(fractions.gcd, values)

If the syntax for generating 'values' is unfamiliar to you, look up "python generator comprehension" on google for tutorials, etc.

Thanks David, that did the trick

 

 


The eval function could also be an option.

divisor = reduce(fractions.gcd, eval('(%s)' % FME_MacroValues_'Contours']))


The eval function could also be an option.

divisor = reduce(fractions.gcd, eval('(%s)' % FME_MacroValues_'Contours']))

Technically I agree, but I'm not a fan of using eval() and particularly not on user specified input. See https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
Technically I agree, but I'm not a fan of using eval() and particularly not on user specified input. See https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
@david_r, you are right. Really dangerous. The eval function would not be recommended to use unless the parameter is private.

 

Thanks for the alert.

Reply