Question

Padright an int value

  • 24 February 2015
  • 16 replies
  • 28 views

Hi, I have some troubles with the following expression in expression evaluator.

 

 

@FindString(@Value(_IDENT),R)  ?  @PadRight((@int(@TrimRight(@Value(_IDENT), [R,L]))+18),3,[L]) : @PadRight((@int(@TrimRight(@Value(_IDENT),[R, L]))+18),3,[R])

 

 

I test if an attribute contains the letter R, 

 

if yes, remove letters L|R, add 18, then add the letter L to the end

 

else , remove all letters L|R, add 18, then add the letter R to the end

 

 

Problem is, all i get is the calucated value and no final alpha character.

 

 

What is wrong with my syntax?

 

 

Thanks.

16 replies

Userlevel 2
Badge +17
Hi,

 

 

The ExpressionEvaluator is designed for evaluating a math expression, it may not work for string operations.

 

Consider using the AttributeCreator with Conditional Value setting.

 

 

Note:

 

@FindString function returns -1, if the target string doesn't contain specified string. If you intend to determine whether the string contains "R", the test clause should be:

 

0 <= @FindString(@Value(_IDENT),R)

 

And it's not necessary to quote arguments by [].

 

@TrimRight(@Value(_IDENT),RL)

 

@PadRight(<a string>,3,L)

 

 

String Functions (http://docs.safe.com/fme/html/FME_Transformers/FME_Transformers.htm#transformer_parameters/StringFunctions.htm)

 

 

Takashi
Badge
Hi,

 

Personally I'm of the view that the "simplest" solution is usually the best. While it can probably all be done with a single very-complex expression, doing this makes it less maintainable. When you (or a colleague) next come to it you'll have to decipher what's going on within it.

 

 

Instead, I'd do it with transformers. A combination of the following should do it:

 

- Tester

 

- AttributeTrimmer

 

- StringConcatenator

 

- StringFormatter

 

 

Cheers,

 

Jonathan
Badge +3
It also functions as bolean Takashi, try it out.

 

 

Bu the expression is incorrect. The @int needs a float as input, and is illogically used. Remove it.

 

Also the 3 suggest you only want 3 characters returned??? This should be ofcourse Original stringlength +1.

 

 

This works in the Expressionevaluator.:

 

 

@Evaluate(@Evaluate(@FindString(@Value(tst),R,0,T))?"@PadRight(@TrimRight(@Value(tst),[R,L])+18,@StringLength(@TrimRight(@Value(tst),[R,L])+18)+1,L)":"@PadRight(@TrimRight(@Value(tst),[R,L])+18,@StringLength(@TrimRight(@Value(tst),[R,L])+18)+1,R)")

 

 

The @Evaluate is mandatory to ..well have it evaluate

 

 

this results in:

 

 

 

 
Badge +3
..should be Original stringlengt + 2 (for the number "18") +1 wich is same as

 

 
Hi Gio,

 

 

As an example value, 18R , I need to first add 18 to this, so i must remove letters, then perform the math 18+18=36, then apply the letter L. My final results needs to be 36R from original 18R.  The result I get from your expression is "17+18L" . 

 

 

My explanation probably wasn't clear about that. 
Userlevel 2
Badge +17
I agree with Jonathan. It's better to use existing transformers to make the workspace have higher understandability and maintainability, unless there is a special reason or the purpose is to learn more about FME functions.

 

 

If there were a reason for doing that within one transformer, I would use an AttributeCreator with Conditional Value setting, like this.

 

Based on the transformers suggested, I made it work. Although I did use a lot of transformers to do it. 

 

Thanks Takashi for your help. Your answer was most helpful. Just a small modification 

 

 

@Evaluate(@int(@TrimRight(@Value(_IDENT),R))+18)L

 

 

I have to include @int because occasionally the _IDENT has a value 08 for example, the zero infront causes errors. 

 

 

I guess for the amount of time spent figuring this out, I did the alternative method in a fraction of the time. But its nice to have a single transformer solution.
Userlevel 2
Badge +17
Possibly these 3 transformers do that.

 

Modify appropriately the math expresion and the replacement character for 'C' according to your actual requirement.

 

 

StringSearcher

 

 

 

AttributeCreator

 

 

 

StringConcatenator

 

Userlevel 2
Badge +17
correction for the AttributeCreator setting.

 

Userlevel 2
Badge +17
In FME 2014 or earlier, there are cases where digits starting with '0' will be interpreted as an octal number in a math expression.  '08' and '09', for example, are invalid as octal number representation. Probably that's the reason for the error.

 

In FME 2015, digits always will be interpreted as a decimal number.

 

 

If you are using FME 2014, consider trimming leading '0's before calculation.
Userlevel 2
Badge +17
Sorry, correction again.

 

Thanks once again Takashi. That conditional value is quite convenient plus the regex. For my workflow I have to split them up to do the feature merge, but the process is overall much better to modify in the future I think. 

 

 

Userlevel 2
Badge +17
Yes. The "Conditional Value" could reduce the number of transformers drastically in some cases, without using advanced function such as FME String Functions. I frequently use it.

 

It has been introduced in FME 2013 SP1. FYI.

 

FME 2013-SP1: Conditional Processing in FME (http://blog.safe.com/2013/03/fmeevangelist113/)
Badge +3
I understand now, the IDENT format is integer plus a letter. Thats why u used a @INT().

 

I just surmised you were talking about a arbitrary string of arbitrary length.

 

 

I always prefer single transformer over a bunch of cumbersome transformers.

 

I only use conditional attribute creator for low count attributes (lik 2 or max 3) and then only sometimes, when im in a hurry.

 

 

I totaly disagree on  using existing transformers (note the plural..;0) in favor of the power of tcl.

 

 

"Time figuring it out" is a matter of experience and savvy.
Badge +3
In that case the expression should be:

 

 

@Evaluate(@Evaluate(@FindString(@Value(tst),R))==-1?"@PadRight(@Evaluate(@Evaluate(@int(@TrimRight(@Value(tst),[R,L])))+18),3,L)":"@PadRight(@Evaluate(@Evaluate(@int(@TrimRight(@Value(tst),[R,L])))+18),3,R)")

 

 

resullts in

 

0 18R  36R

 

0 18L  36L

 

 

..i concede.. with that amount of @Evaluate() calls..6x .one might reconsider torturing oneself..

 

better do it in a tcl caller instead.. ;)

 

 

 

Im testing fme package..

 

and look wt# safe did!

 

 

fme_expression_warnings{0}.message (string): Failed to evaluate numeric expression '@real64(36L)'.  Result is set to null.

 

 

The result is correct as is the expressionstring and it gets processed as ususal, but it insists to intepret it as a number...?!??@#?? That is so lame!

 

 

Reply