Skip to main content
Question

Passing comma-separated numbers to Python function


redgeographics
Celebrity
Forum|alt.badge.img+48

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_MacroValues['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 18in input

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/fractions.py", line 25in 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?

5 replies

david_r
Evangelist
  • August 16, 2017

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(xfor 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.


redgeographics
Celebrity
Forum|alt.badge.img+48
david_r wrote:

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(xfor 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

 

 


takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • August 16, 2017

The eval function could also be an option.

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


david_r
Evangelist
  • August 16, 2017
takashi wrote:

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

takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • August 16, 2017
david_r wrote:
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


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