Arithmetic with string value

Greetings,

I have many situations where I’m using index to refer to an element, which is passed as an embedded keyword argument. This index is then also used in a list to access test data for comparison.

The issue here is that index passed as keyword argument is stored as a string variable, which needs to be decremented to access a list (because indexing starts with 0).

What I do now is

${list_index}=    Evaluate    ${index} - 1

It works, just it adds an extra line of code in many places and is repetitive.
Doing ${index-1} of course did not work in this case.
Is there a similar simple solution, that would be alternative to Evaluating and would save lines of code and repetition?

Thank you and best regards,
JC

Hi Josh,

There’s a couple of ways you can approach this problem:

  • you could use Convert To Number first
  • but since you are already using Evaluate and since Evaluate executes python code you can use python’s inbuilt int() function like this
${list_index}=    Evaluate    int(${index}) - 1

Dave.

1 Like

Hi Dave,
Thank you for your reply. My hope was to find a way to avoid using an extra line of code (Evaluate or Convert to number). You gave the idea to try the following:

${list_of_items}[int(${index})-1]

and it worked! So I can use it instead of having the repetitive Evaluate all over the place. Thank you.
JC

1 Like

I celebrated too quickly, the success was short lived.

The solution in previous post works when used inside a python function appended to variable (e.g. “replace”):

"${list_of_items[int(${index})-1]}"

I am not yet having success with indexing a variable though:

${list_of_items}[int(${index})-1]

Here I get an error

List ‘${list_of_items}’ used with invalid index ‘int(1)-1’. To use ‘[int(1)-1]’ as a literal value, it needs to be escaped like ‘[int(1)-1]’.

Any further ideas are welcome, to help avoid the need for another line of code (Evaluate or Convert). Thank you!

Hi Josh,

Look at the placement of the closing curly brace (}) between these two lines:

I believe this is because stuff between the curly braces gets evaluated as python, stuff in the square braces outside the curly braces is evaluated as a literal string

but you probably could save yourself a lot of pain by just doing:this first

${index}=    Evaluate    len(${list_of_items}) - 1

If nothing else doing the Evaluate once will save a few (dozens?) of cpu cycles and may even speed your test case up by a few milliseconds (that’s the performance tester in me comming out :rofl:

Dave.

Hi Dave,
Hah, that’s a good one :smiley: I am glad you shared your performance tester perspective.
I didn’t quite give up, I came up with this, which does what I wanted:

${list_of_items.__getitem__(int(${index})-1)}

If anyone can figure a way around this without the need for getitem or additional lines of code, I will greatly appreciate it.

Another idea was to put a placeholder element in 0 position of the list, so indexing other elements would work fine. I’m just not very sure whether it could backfire in places, where this behaviour is not expected.

Best,
JC

Hi

Could you just not make a helper function that does what you need and just call it when needed? You’d only have one instance then, reducing duplication, given the repetitiveness you mention in your first post.

In terms of the what ifs,“backfires” just add some error handling within, and you could even return a pretty message on exception, or just let it fail and handle it as of when that was to happen, and extend if needed when/if it ever happens…

Maybe this has already been considered, but the reptition you speak of does hint towards it. But in terms of casting, converting, and what not, Dave looks to have covered that, as well as yourself in the many approaches, so I don’t think I can add much there. I will leave the below:

So we could consider what some speak of as the “pie” syntax, so something like this:

def ensure_int(fn):
    def wrapper(num):
        return fn(int(num))
    return wrapper

@ensure_int
def get_list_index(num):
    return num - 1

But I guess both helper function / keyword can be done within python or as a keyword in robot framework

Thanks,
Daryl

1 Like

Have you tried the inline python evaluation syntax?

Ex.
${list_of_items}[${{${index}-1}}]

Note the extra curly braces.

1 Like

Hi @Silken
Thank you very much for the suggestion. I have tried the inline Python evaluation, just not in correct way to get the desired result. Your example does what I was hoping to achieve. Thank you!

2 Likes