I am trying to evaluate below expression in Robot framework
Run Keyword If '${buttondisplayed}' == 'PASS' and '${ReturnedInfo}' ==
' PASS', Some Keyword,
else if, '${buttondisplayed}' ==
'PASS' and '${ReturnedInfo}' == 'FAIL', Some Keyword ,
else if, '${buttondisplayed}' == 'FAIL' and '${ReturnedInfo}' == 'PASS',
Some Keyword,
else, Some Keyword
Where the value of both ${buttondisplayed} and ${ReturnedInfo} = FAIL.
Based on above condition, else part mentioned, in the end, should be executed however in Log output I am getting the following result
Documentation:
Runs the given keyword with the given arguments, if the condition is true.
Start / End / Elapsed: 20170806 11:15:14.448 / 20170806 11:15:14.448 / 00:00:00.000
So basically none of the conditions is executed here.
Could anyone please indicate what is wrong here in this expression?
There are at least four problems with the code you've posted:
there's only one space after the first "if"
"else if" is lowercase. It must be all uppercase (ELSE IF)
you have commas in your code. robot syntax doesn't support commas as field separators
your code seems to span multiple lines but you aren't using the robot line continuation characters ...
Run Keyword If '${buttondisplayed}'=='PASS' and '${ReturnedInfo}'=='PASS' Some Keyword
... ELSE IF '${buttondisplayed}'=='PASS' and '${ReturnedInfo}'=='FAIL' Some Keyword
... ELSE IF '${buttondisplayed}'=='FAIL' and '${ReturnedInfo}'=='PASS' Some Keyword
... ELSE Some Keyword
Related
Very new to the world of programming and just starting to learn, working through Flatiron School prework and have been doing ok but unable to understand "if" and "else" statements for some reason. The problem is similiar to Chris Pine 'deaf grandma' problem but without saying "BYE!" three times.
~The method should take in a string argument containing a phrase and check to see if the phrase is written in all uppercase: if it isn't, then grandma can't hear you. She should then respond with (return) HUH?! SPEAK UP, SONNY!.
~However, if you shout at her (i.e. call the method with a string argument containing a phrase that is all uppercase, then she can hear you (or at least she thinks that she can) and should respond with (return) NO, NOT SINCE 1938!
I have so far:
def speak_to_grandma
puts "Hi Nana, how are you?".upcase
if false
puts "HUH?! SPEAK UP, SONNY!"
else
puts "NO, NOT SINCE 1938!"
end
end
but am getting wrong number of arguments...how am I supposed to add argument while using the if/else statements? This is probably a very easy and basic question but can't seem to get my head around this (overthinking probably).
Any help and clarity would be greatly appreciated.
input_phrase = "Hi Nana, how are you?"
def speak_to_grandma(phrase)
# Check if string equals same phrase all upper case letters, which means string is all uppercase
if phrase == phrase.upcase
# return this string if condition is true
puts "NO, NOT SINCE 1938!"
else
# return this string if condition is false
puts "HUH?! SPEAK UP, SONNY!"
end
end
# execute function passing input_phrase variable as argument
speak_to_grandma(input_phrase)
how am I supposed to add argument while using the if/else statements?
This is probably a very easy and basic question but can't seem to get
my head around this (overthinking probably).
Your mistake was that function was not accepting any arguments, here it accepts "phrase" variable as argument and processes it:
def speak_to_grandma(phrase)
You had
if false
but did not check what exactly is false.. To rewrite my version with "false" :
input_phrase = "Hi Nana, how are you?"
def speak_to_grandma(phrase)
# Check if it is false that string is all upper case
if (phrase == phrase.upcase) == false
# return this string if condition is false
puts "HUH?! SPEAK UP, SONNY!"
else
# return this string if condition is true
puts "NO, NOT SINCE 1938!"
end
end
speak_to_grandma(input_phrase)
Here I am evaluating
if (phrase == phrase.upcase) == false
Basically means "if expression that phrase equals phrase all uppercase is false"
I am pretty new to Perl. I have the following code fragment that works just fine, but I don't fully understand it:
for ($i = 1; $i <= $pop->Count(); $i++) {
foreach ( $pop->Head( $i ) ) {
/^(From|Subject):\s+/i and print $_, "\n";
}
}
$pop->Head is a string or an array of strings returned by the function Mail::POP3Client, and it is the headers of a bunch of emails. Line 3 is some kind of regular expression that extracts the FROM and the SUBJECT from the header.
My question is how does the print function only print the From and the Subject without all the other stuff in the header? What does "and" mean - this surely can't be a boolean and can it? Most important, I want to put the From string into its own variable (my $fromline). How do I do this?
I am hoping that this will be easy for some Perl professional, it has got me baffled!
Thanks in advance.
ARGHHH... The question was edited while I was typing the answer. OK, throwing out the part of my answer that's no longer relevant, and focusing on the specific questions:
The outer loop iterates over all the messages in the mailbox.
The inner loop doesn't specify a loop variable, so the special variable $_ is used.
In each iteration through the inner loop, $_ is one header line from message number $i.
/^(From|Subject):\s+/i and print $_, "\n";
The first part of this line, up to the and is a pattern. We didn't specify what to do with the pattern, so it's implicitly matched against $_. (That's one of the things that makes $_ special.) This gives us a yes/no test: does the pattern match the header line or not?
The pattern tests whether that item begins with (<) either of the words "From" or "Subject", followed immediately by a colon and one or more whitespace characters. (This not the correct pattern to match an RFC 822 header. Whitespace is optional on both sides of the colon. The pattern should more properly be /^(From|Subject)\s*:\s*/i. But that's a separate issue.) the i at the end of the pattern says to ignore case, so from or SUBJECT would be OK.
The and says to continue evaluating (i.e., executing) the expression if there is a match. If there's no match, whatever follows and is ignored.
The rest of the expression prints the header line ($_) and a newline ("\n").
In perl, and and or are boolean operators. They're synonyms for && and ||, except that they have much lower precedence, making it easier to write short-ciruit expressions without clutter from lots of parentheses.
The smallest change that captures the From line into a separate variable would be to add the following line to the inner loop:
/^From\s*:\s*(.*)$/i and $fromline = $1;
You should probably also put
$fromline = undef
before the loop so you can test, after the loop, whether there was a From: line.
There are other ways to do it. In fact, that's one of the mantras of perl: "There's more than one way to do it." I've stripped out the "From: " from the beginning of the line before storing the balance in $fromline, but I don't know your needs.
It's a logical and with short-circuiting. If the left side evaluates to true -- say, if that regular expression matches -- it'll evaluate the right side, the print.
If the expression on the left is false, it doesn't need to evaluate the right hand side, because the net result would still be false, so it skips it.
See also: perldoc perlop
Perhaps I'm missing something, but it annoys me that VBScript seems to read all OR condtions. For example, I'd like to do something like this:
If (oFS.FileExists(sFileLoc) = False) Or (sNewText <> oFS.OpenTextFile(sFileLoc).ReadAll) Then
Now I get an error that the file doesn't exist because of the second condition. I was hoping that if the file doesn't exist VBScript would skip immediately to the result, and if it does, it checks the second condition.
Am I right and is this normal behavior?
As M. Harris already said in 2003 and the docs for the logical operators (e.g. Or) state explicitly, VBScript does not short-circuit the evaluation of conditionals. You must use nested Ifs or a slightly fancy Select Case
You can use inline nested IF's to achieve short-circuiting in VBScript. For example, you could rewrite your statement like this:
If oFS.FileExists(sFileLoc) Then If sNewText = oFS.OpenTextFile(sFileLoc).ReadAll Then
But your Then condition must be specified on the same line as this statement. So if you need to perform multiple operations as a result of this condition, you must separate the statements with a colon (:), which is the single-line statement separator in VBScript.
If oFS.FileExists(sFileLoc) Then If sNewText = oFS.OpenTextFile(sFileLoc).ReadAll Then x = 1 : y = 2
You could also just move your logic into a Sub or Function and make a call instead:
If oFS.FileExists(sFileLoc) Then If sNewText = oFS.OpenTextFile(sFileLoc).ReadAll Then DoStuff
Note, too, that if you need to specify an Else clause, it must be specified on this line as well.
If oFS.FileExists(sFileLoc) Then If sNewText = oFS.OpenTextFile(sFileLoc).ReadAll Then x = 1 Else x = 2
By matrix style, I mean having n variables, each with some number of inputs, and having to handle all possible values. The simplest case of this is multiple boolean values and having to handle every combination of true/false. This is easy if the returned values follow certain patterns, but otherwise it seems quite difficult.
(If there is a better name than 'matrix style', please comment and tell me so I can update the title.)
The ugly way to handle this is an if else chain.
IF self.A = 'N' THEN
IF self.B = 'N' THEN
...
ELSE
...
END IF;
ELSE
IF self.B = 'N' THEN
...
ELSE
...
END IF;
END IF;
Good luck keeping track of that mess, especially with more than 4 variables.
A slightly more readable way of doing this is to do all the checks together.
IF self.A = 'N' AND ... self.Y = 'N' AND self.Z = 'N' THEN
returnValue := 'Bob';
END IF;
If self.A = 'N' AND ... self.Y = 'N' AND self.Z = 'Y' THEN
returnValue := 'Birthday Party';
END IF;
...
If self.A = 'Y' AND ... self.Y = 'N' AND self.Z = 'N' THEN
returnValue := 'What did I ever do to deserve this?';
END IF;
...
If self.A = 'Y' AND ... self.Y = 'Y' AND self.Z = 'Y' THEN
returnValue := 'Thank God I am done!';
END IF;
You can make that a little better if you do a CASE statement instead of a bunch of if/elses, but that is still very hard to maintain. Imagine accidentally putting a Y instead of an N some place and having to go find it. Considering the chance for errors grows exponentially with each new variable added (as you at least double the amount of code you need to write), there is a good chance for errors in any significant sized problem like this.
You can potentially do some interesting text replacement to try to reduce errors. I recently did this with 5 variables. I started with...
NNNNN
NNNNY
...
YYYYN
YYYYY
Then I ran some find and replace over them using Notepad++ to try to reduce the chance of mistyping a N or Y. But the end product still looks nasty to maintain. So I'm wondering if there are any better ways to handle this (mostly in terms of maintainability, though any efficiency boost without loosing maintainability are also welcome suggestions). While I'm looking specifically for PL/SQL solutions, any solutions in other languages are still welcome because they might be able to be translated to PL/SQL.
Edit: In case anyone is trying to solve this problem and wants to use my current solution, here is the find and replace.
Find: ([Y,N]) repeated as many times as you have variables.
Replace: \t\t\tWHEN self.valueName = '\1' THEN\r\n\t\t\t\treturnValue := '' where the self.valueName = '\1' is repeated once for each variable you have, with the \1 incremented each time. You'll also need to set the correct number of \t's so that it matches however much indented it should be. This works in Notepad++, regex mode.
Why do you have that problem? I assume that this is a variable of a type consisting out of variables from A-Z. So how do you populate this in the first place? Can't you simplify right there?
But if there is no alternative you can first check if there is only 'Y' and 'N' in the single fields and convert to 1 and 0 and make numbers out of it and check against the numbers. E.g. NNNNY becomes one and NNNYN becomes 2 etc. Then it is IF r=1 then .. elsif r=2 ..
A probably even better alternative is to generate the code. You can form a string that has the "create or replace functionX as ..." and do an execute immediate on it.
Try to concatenate to one value (self.A || self.B || .. || self.Z) and then use case on values like 'NNNNN', 'NNNNY', 'NNNYN, etc.
EDIT:
I made assumtions that:
you have large set of one-char variables that...
...you want to translate to single return value...
...covering all-or-many possibile sets.
What you gain is a view of all combinations, one per line, one key under other, in each single-char column having same self.variable. If number of variables is really big, to avoid options like YNNYYYNYNNYNYYYNNY you can improve readability to put space every 3-rd or 5-th or n-th char:
when 'NNN NNN NNN' then '1st choice'
when 'NNN NNN NNY' then '2nd choice'
when 'NNN NNN NYN' then '3rd choice'
... ... ...
As #hol in answer below suggested generating code is a very good choice in that case.
But you, as developer, should know if m-th choice is YYY YNY YY or YYY NYY YY, no other way to be sure whether you get correct results than to check/test code.
I need to write a regular expression to verify that a string contains { } but not { or }.Can someone shine some light on this please?
Thanks for all the help , here are some examples.
e.g.
valid : {abc}, as09{02}dd, {sdjafkl}sdjk, sfdsjakl,00{00}00, aaaaa{d}
invalid: {sdsf , sdfadf},sdf{Sdfs ,333}333
*********Update*******************
^[a-zA-Z0-9_-. ](?:{[a-zA-Z0-9_-.]+})?[a-zA-Z0-9_-. ]$ is what I need,thanks for all your help :)
/.*\{.*\}.*/
This would ensure that the string contains an opening curly bracket somewhere before a closing curly bracket, occurring anywhere in the string. However, it wouldn't be able to ensure that there's only one opening and closing curly bracket -- to do that, the .* patterns would have to be changed to something more restrictive.
If you want to experiment and test these regexes out, here's a good site.
What flavor of regex? In JavaScript, for instance, this'll do it:
var re = /\{.*\}/;
alert("A: " + re.test("This {is} a match"));
alert("B: " + re.test("This {is not a match"));
alert("C: " + re.test("This } is not a match"));
Alerts A: true, B: false, and C: false.
Most other flavors will be similar.
For this problem regex-based solution is way too heavy.
If you have the opportunity of NOT using regexes - don't, simpler statement(s) can handle it just fine.
Even much general problem - checking, if the use of (potentially nested) parentheses is correct - is solvable using simple one-pass loop.
I.e. this is correct
{}{{{}{}}}
while this isn't
{{}
Solution in python (easy to translate to other language):
def check(s):
counter = 0
for character in s:
if character == "{":
counter += 1
elif character == "}":
counter -= 1
if counter < 0:
# not valid
return False
if counter == 0:
# valid
return True
else:
return False
There is exactly one opening brace and exactly one closing brace in the string, and the closing brace follows the opening brace:
^[^\{\}]\{[^\{\}]\}[^\{\}]$
There any number of braces in the string, but they are not nested (there is never another opening brace before the previous one has been closed), and they are always balanced:
^[^\{\}](\{[^\{\}]\})*[^\{\}]$
Nesting cannot be generally solved by regular expressions.