If Else-if in Robot Framework - python-2.7

I want get value from a Keyword by using else if.
Example:
String text = ""
If variable > 5
text = "one";
else if variable <5
text = "two";
else
text = "three";
In Robot Framework
I use the code
${txt} Set Variable
${txt}= Run Keyword If ${length} > 5 Some Keyword
\ ELSE IF ${length} < 5 Some Keyword
\ ELSE Some Keyword
Log ${txt}
ERROR !!!
In Keyword ELSE IF ; Keyword name cannot be empty

Just add THREE DOTS (...) in first cell before ELSE IF keyword
${txt} Set Variable
${txt}= Run Keyword If ${lenght} > 5 Some Keyword
... ELSE IF ${lenght} < 5 Some Keyword
... ELSE Some Keyword
Log ${txt}

An alternate way to code this with Robot Framework's version of a switch statement is:
*** Variables ***
String ${text} = ""
*** Keywords ***
${text} = Set Variable If
... ${variable} > 5 one
... ${variable} < 5 two
... ${variable} = 5 three
There may be other ways using Run Keyword If and Run Keyword Unless.

Since since robot 4.0, native IF else support is available. You can refer below example:
IF '${status}' == 'true'
${i} Set Variable 10
log to console inside if
ELSE IF '${status}' == 'false'
${i} Set Variable 20
log to console inside else if
ELSE
${i} Set Variable 30
log to console inside else
END

Related

How assign a value in a Terraform variable based on 4 variables

Hi I need to assign the value from an input variable based on 3 values that are on 3 AWS SSM parameters, and then update the value of 1 of those 3 AWS SSM parameters.
Here I explain one case in order to be more clear:
I have an input variable filename1 and 3 local variables
variable "filename1" {
type = string
}
locals {
path1 = "filevar1"
path2 = "filevar2"
path3 = "filevar3"
}
Then I get the values of 3 AWS SSM parameters
data "aws_ssm_parameter" "variable1" {
name = local.path1
}
data "aws_ssm_parameter" "variable2" {
name = local.path2
}
data "aws_ssm_parameter" "variable3" {
name = local.path3
}
Based on the values that I get if variable 1 is different from the other 2 variables I shoud assign the input variable to variable2.
Based on some research I assume that I should do it with
this
locals {
file2 = "${data.aws_ssm_parameter.variable2.value}" == "${data.aws_ssm_parameter.variable3.value}" != "${data.aws_ssm_parameter.variable1.value}" ? "${data.aws_ssm_parameter.variable2.value}" : "${var.filename1}"
then update SSM value with this
resource "aws_ssm_parameter" "variable2" {
name = local.path2
type = "String"
value = "${local.file2}"
overwrite = true
}
It doesn't work, do you have some example on how to assign a value for a any type of variable based on 3 values?
I have other different conditions, I just need to understand how to declare in order to replicate on the other conditions.
Thanks for your help!!
In your file2 definition you've written the following sub-expression:
"${data.aws_ssm_parameter.variable2.value}" == "${data.aws_ssm_parameter.variable3.value}" != "${data.aws_ssm_parameter.variable1.value}"
The == and != operators are both binary operators (that is, they take only two arguments) and both produce a boolean result. That means that Terraform will evaluate the first one first, and then compare its result to the other one.
"${data.aws_ssm_parameter.variable2.value}" == "${data.aws_ssm_parameter.variable3.value}"
In the case where both of these are equal, the result will be true. If they are non-equal, the result will be false.
If we substitute those results for the original expression, we get:
true != "${data.aws_ssm_parameter.variable1.value}"
false != "${data.aws_ssm_parameter.variable1.value}"
Both of these expressions will always return false, because a boolean value can never be equal to a string value in the Terraform language.
If I'm understanding your requirement correctly, you want to test whether the first one is equal to both of the other ones. That requires two separate tests, which you can then combine together using the && operator which means "and":
(
data.aws_ssm_parameter.variable1.value != data.aws_ssm_parameter.variable2.value &&
data.aws_ssm_parameter.variable1.value != data.aws_ssm_parameter.variable3.value
)
The above means: variable1 is different from variable2 and variable1 is different from variable 3. In other words, it will produce true only if both of those conditions are true.
Now we can incorporate that with the conditional test you showed in your example to get the full expression:
(
(
data.aws_ssm_parameter.variable1.value != data.aws_ssm_parameter.variable2.value &&
data.aws_ssm_parameter.variable1.value != data.aws_ssm_parameter.variable3.value
) ?
data.aws_ssm_parameter.variable2.value :
var.filename1
)
I wrapped this over multiple lines to make it easier to read the different parts of the expression, but those newlines are not significant and so you can lay this out differently if you wish.
Given the length of the condition here I might prefer to split it out into a separate local value and then refer to it as part of the conditional:
locals {
override_path = (
data.aws_ssm_parameter.variable1.value != data.aws_ssm_parameter.variable2.value &&
data.aws_ssm_parameter.variable1.value != data.aws_ssm_parameter.variable3.value
)
file2 = (
local.override_path ?
data.aws_ssm_parameter.variable2.value :
var.filename1
)
}

gdb how to print variable name along with variable value like "$number = variable-name = variable-value"

By default, using p variable-name will display $num = variable-value, $num is the value history, but it there a way to print the variable name along with the variable value like $num = variable-name = variable-value?
I want this since I use
define p
set $i = 0
while $i < $argc
eval "print $arg%d", $i
set $i = $i + 1
end
end
in my ~/.gdbinit, to redefine p command so I can use p var1 var2 var3... to print multiple variables at once, but the print command only output $num = variable-value, and I don't know what the exact variable is in the output, the other situation is when I print the value history using just p $num, it is not that readable, I don't know the exact variable name.
NOTE: the variable may be int/char/pointer/array/vector/...
A solution could be to first add to the display list the wanted variables and then to display all of them together. Note that, it is needed to free the display list before with undisplay, otherwise it also prints the variables of the previous executions.
define p
set confirm off
eval "undisplay"
set confirm on
set $i = 0
while $i < $argc
eval "display $arg%d", $i
set $i = $i + 1
end
display
end
The undisplay evaluation is enclosed between set confirm off/on to suppress the following message:
[answered Y; input not from terminal]
If you have already set the confirm off option in your ~/gdbinit file, you will need to remove these two lines.
Edit: Honestly, I came to know about the display command finding a solution for this question. Although this answer might be useful to print multiple variables with their respective names, after several days using display in my workflow, I discourage to use this answer since I have come to the conclusion that display itself fits better at least my needs (printing multiple variables at every stop). Here the official doc:
If you find that you want to print the value of an expression frequently (to see how it changes), you might want to add it to the automatic display list so that GDB prints its value each time your program stops. Each expression added to the list is given a number to identify it; to remove an expression from the list, you specify that number. The automatic display looks like this:
2: foo = 38
3: bar[5] = (struct hack *) 0x3804
Basically, I have started using the command like this: I add a variable with display $var to the list of variables, and every time a breakpoint is reached the listed variables are automatically printed. It makes sense to have a feature like this in gdb. Thanks #CodyChan for the motivation.
In a nutshell, we want to output
$num = variable-name = variable-value
instead of
$num = variable-value
As far as I can tell, gdb adds to the value history in only three places: the print command, the call command, and the history-append! Scheme function. Since my Scheme is rusty, we'll need to use the CLI or Python to run print and modify its output.
Using the CLI
define pp
set $i = 0
while $i < $argc
eval "pipe print $arg%d | awk -v name='$arg%d' '{ if (NR == 1 && $2 == \"=\") { $2 = \"= \" name \" =\" }; print }'", $i, $i
set $i++
end
end
Pipe is new in gdb 10.
That awk command is, after unescaping,
awk -v name='$arg%d' '{ if (NR == 1 && $2 == "=") { $2 = "= " name " =" }; print }'
which changes the = (second field) in $num = variable-value to = variable-name = . If gdb's print command outputs more than one line, the NR == 1 in the awk command makes sure the substitution is only done on the first line.
Security note: gdb's pipe command appears to parse the shell_command into tokens and uses execve to run it, rather than passing it to an actual shell. This prevents some code injection attacks (if, for instance, the $arg%d in name='$arg%d' contains single quotes), but you should be careful of running any shell command comprised of text you haven't vetted.
Using Python
class PP(gdb.Command):
"""print value history index, name, and value of each arg"""
def __init__(self):
super(PP, self).__init__("pp", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION)
def invoke(self, argstr, from_tty):
for arg in gdb.string_to_argv(argstr):
line = gdb.execute("print " + arg, from_tty=False, to_string=True)
line = line.replace("=", "= " + arg + " =", 1)
gdb.write(line)
PP()
Here, we're using a more sed-like approach, using string.replace.
Sample session:
(gdb) set args a b c
(gdb) start
Starting program: /home/mp/argprint a b c
Temporary breakpoint 2, main (argc=4, argv=0x7ffffffee278) at argprint.c:4
4 for(int i=0; i < argc; i++) {
(gdb) pp i argc argv argv[0]#argc
$1 = i = 0
$2 = argc = 4
$3 = argv = (char **) 0x7ffffffee278
$4 = argv[0]#argc = {0x7ffffffee49f "/home/mp/argprint", 0x7ffffffee4b1 "a", 0x7ffffffee4b3 "b", 0x7ffffffee4b5 "c"}

extra words after "else" clause in "if" command for TCL code

I have a tcl code where -
if { $xyz == 43 } {
# 1. Set some variables
set my_filename_log "somename_log.txt"
if {[file exists $my_filename_log ]} {
file delete -force $my_filename_log
}
} # end of xyz = 43
I am getting error as - TCLERROR: wrong # args: extra words after "else" clause in "if" command while compiling -
if { $xyz == 43 } {
# 1. Set some variables...
Not sure what is wrong with this code, checked tcl documentation didnt find anything
In Tcl, for else if condition should be written without space as elseif. Otherwise you will get the error you have mentioned.
if {$xyz==1} {
puts "Yes"
} else if {$xyz==2} {
puts "No"
}
wrong # args: extra words after "else" clause in "if" command
In your code, you have used
} # end of xyz = 43
at the last line. You have to use ; to mark the end of the statements and then you can start the comments with #.
So, your code should be written as,
if { $xyz == 43 } {
# 1. Set some variables
set my_filename_log "somename_log.txt"
if {[file exists $my_filename_log ]} {
file delete -force $my_filename_log
}
}; # end of xyz = 43

Nginx - Rewrite multiple parameters

This may or may not be possible but thought I would ask.
We had recently changed some of the query parameters and wanted to 301 redirect the old version to the new version.
The old parameter scheme was categoryX=Y where X was some number and Y was some number (an example being category56=112). The new version just drops off the X so we have category=112. Now, this seems fairly simple enough to do if there is either a known number of parameters or a single parameter. However, there can be a variable number of these parameters. For example:
http://www.example.com/some_directory/index.shtml?category56=112
http://www.example.com/some_other_directory/index.shtml?category8=52&category11=2&other_param=12
I'm guessing there isn't a way to basically "for each" through the parameters and if a regex matches category(0-9+)=(0-9+) to change it to category=(0-9+)?
You can loop through your args but you will need the 3rd party Nginx Lua module which is also part of the Openresty Bundle.
With that in place, something along these lines should do the job ...
location /foo {
rewrite_by_lua '
local new_args = "exit"
local exit = false
local m, err = nil
-- load arguments
local args = ngx.req.get_uri_args()
-- loop through arguments and rebuild
for key, val in pairs(args) do
-- stop loop if "abort" arg is found
if key == "exit" then
exit = "true"
break
end
m, err = ngx.re.match(key, "category(0-9+)")
if m then
new_args = new_args .. "&category=" .. val
else
new_args = new_args .. "&" .. key .. "=" .. val
end
end
-- redirect if we have not been here before
if exit == "false" then
return ngx.redirect(ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.request_uri .. ngx.var.isargs .. new_args)
end
';
}

Else/If statement help in swift

I'm getting an error when I try to use an if/else statement in Xcode 6 with Swift. This is what I have
} else if countElements(sender.text) == 1, 2
It's telling me:
Type 'String!' does not conform to protocol '_CollectionType'
How can I compare two values on one line?
You can use "||" = "or"
} else if countElements(sender.text) == 1 || countElements(sender.text) == 2 {
}
The other answer correctly shows the way to make 2 comparisons in Swift, but this can be done in a single statement thanks to Swift's pattern matching operator. For example:
if 1...2 ~= countElements(sender.text) {
println("count is 1 or 2")
}
Basically, the provided statement is true if the number of characters in your string is inclusively between 1 and 2.
You can also use the contains global function, providing it a range and the element to check for inclusion:
contains(1...2, countElements(sender.text))