Skip to main content

Hi All,

 

I'm trying to use PythonCaller for a few more complex date calculations that I couldn't find how to easily do with other FME transforms. One of the things I need to do is some standard if/else testing to set a variable based on two other feature attribute values for further processing down the chain, however the results are not returning correctly.

 

I've split out what i'm trying to do into a simple PythonCaller:

 

import fme
import fmeobjects
# Template Function interface:
# When using this function, make sure its name is set as the value of
# the 'Class or Function to Process Features' transformer parameter
 
def processFeature(feature):
    #Define vars
    completionDate = feature.getAttribute('PREREQ_COMPLETE_DATE')
    notRequiredDate = feature.getAttribute('PREREQ_NOTREQUIRED_DATE')
    useDate = None
    
#Test if completionDate is null and fill with notRequiredDate if so
 
    if completionDate is None:
        useDate = notRequiredDate
    else:
        useDate = completionDate
 
#Set new attributes to expose in FME
 
    feature.setAttribute("useDate", useDate)
    pass

useDate will fill with the completionDate when available, however, the features that have notRequiredDate only do not fill useDate as intended.

 

 

I'm by no means a python expert, but any help would be appreciated.

Result outputs as such:fme_python_fail


There is no need to use python here, you can do this with a conditional statement in an attributecreator

CaptureThe reason your python isn't working is because fetching the date attribute into the variable is actually an empty string not None so your test for None doesn't work.

 

If you use this test instead, your python would work, but I think there is no need to resort to python for this

if completionDate =="":

 


There is no need to use python here, you can do this with a conditional statement in an attributecreator

CaptureThe reason your python isn't working is because fetching the date attribute into the variable is actually an empty string not None so your test for None doesn't work.

 

If you use this test instead, your python would work, but I think there is no need to resort to python for this

if completionDate =="":

 

There is additional processing happening within the PythonCaller. I've split out this one part of it that is not functioning as intended to figure out why the if/else statement isn't working.


There is additional processing happening within the PythonCaller. I've split out this one part of it that is not functioning as intended to figure out why the if/else statement isn't working.

I've updated the answer with the change you need to make if you want the python to work. It might be worth posting what you are trying to do to see if it can be achieved without a python caller


There is additional processing happening within the PythonCaller. I've split out this one part of it that is not functioning as intended to figure out why the if/else statement isn't working.

Alternatively, if you use the nullattributemapper to map your null attributes to missing your original code should work


There is additional processing happening within the PythonCaller. I've split out this one part of it that is not functioning as intended to figure out why the if/else statement isn't working.

The useDate variable is only used in the local context of the PythonCaller for processing within that transformer, it is nothing that is or needs to be exposed in the wider workbench.


There is additional processing happening within the PythonCaller. I've split out this one part of it that is not functioning as intended to figure out why the if/else statement isn't working.

I'm not sure i understand.

 

If you want the useDate variable within your python script to be populated correctly then you either need to alter the if statement to test for an empty string rather than None or manipulate your attributes prior to the pythoncaller to turn null values into missing values so that when you fetch the attributevalue into the variable it is set as None. Your original python if statement will then execute correctly.

 

The key thing is that if you read the value of an attribute into a pythoncaller and that value is null this is interpreted as an empty string and not None. Therefore a null value will not pass a test for is None


There is additional processing happening within the PythonCaller. I've split out this one part of it that is not functioning as intended to figure out why the if/else statement isn't working.

Sorry ebygomm,

 

As context, i'm using this variable to process date calculations for week ranges that I could not find how to do using other FME transforms. If there are other ways to accomplish some of the date calculations using transforms, I wouldn't mind being pointed in the right direction to read up on them. I didn't want to have to reinvent the wheel in this particular case and was just kind of bashing my head against the wall trying to make Python function.

 

I assumed the data was null and not empty (as that's what data inspector calls it out as) -- but I can see that it's not actually null in this case. Attached is the updated codeblock that functions, with your fix, as intended. Thank you for your help.

 

import fme
import fmeobjects
from datetime import datetime, date, timedelta
#import datetime
# Template Function interface:
# When using this function, make sure its name is set as the value of
# the 'Class or Function to Process Features' transformer parameter
 
def processFeature(feature):
    #Set vars to split PREREQ_COMPLETE_DATE field for month/day/year/week number
    completionDate = feature.getAttribute('PREREQ_COMPLETE_DATE')
    notRequiredDate = feature.getAttribute('PREREQ_NOTREQUIRED_DATE')
    useDate = None
    if completionDate == "":
        useDate = str(notRequiredDateu0:8])
    else:
        useDate = str(completionDatee0:8])
 
#Set new attributes to expose in FME
    feature.setAttribute("weekRange", getWeekRange(useDate))
    feature.setAttribute("weekRangeISO", getWeekRangeISO(useDate))
    feature.setAttribute("weekNumber", getWeekNum(useDate))
    pass
 
 
 
#Define functions here
 
def getWeekRange(featureDate):
    dt = datetime.strptime(featureDate, '%Y%m%d')
    start = dt - timedelta(days=dt.weekday())
    end = start + timedelta(days=6)
    returnRange = str(start.strftime('%m-%d-%Y') + ' - ' + end.strftime('%m-%d-%Y'))
    #return str(start) +' - ' + str(end)
    return returnRange
 
def getWeekRangeISO(featureDate):
    dt = datetime.strptime(featureDate, '%Y%m%d')
    start = dt - timedelta(days=dt.weekday())
    end = start + timedelta(days=6)
    returnRange = str(start.strftime('%Y%m%d'))
    return returnRange
 
def getWeekNum(featureDate):
    dateYear = int(featureDateb0:4])
    dateMonth = int(featureDate/4:6])
    dateDay = int(featureDatee6:8])
    dt = datetime.strptime(featureDate, '%Y%m%d')
    returnDate = dt.isocalendar()a1]
    #print(returnDate)
    return returnDate

 


Reply