Descendent Relations + Indexing in Selenium - xpath

I'm testing a web page using selenium. I want to get all the 'leaf elements and elements which contain text'. I use the following working XPath.
//*[. != '' or not(*)]
This works great.
But now I want to loop through each of these elements and run some command on them. I actually want to get their Position, but I illustrate my problem by using GetXpathCount.
int elementCount = this.selenium.GetXpathCount("//*[. != '' or not(*)]");
for (int i = 1; i <= elementCount; ++i)
{
Console.WriteLine(this.selenium.GetXpathCount("//*[. != '' or not(*)][" + i + "]"));
}
The value of elementCount is 242.
And the console output is 142 45 30 13 4 4 1 1 1 1 0 0 0 0 0 0 ... [200 other zeros]
The numbers on the console always sum to elementCount, but are always zero after ~10.
It became obvious to me that my XPath
//*[. != '' or not(*)][1]
Does not have my intended meaning. And instead returns "all leaf elements and all elements containing text which are the first child of their parent" and is equivalent to
//*[(. != '' or not(*)) and position() = 1]
So, I use brackets to correct this mistake:
(//*[(. != '' or not(*))])[1]
Yay. The console output is now 1 1 1 1 1 1 1 1 1 1 1 1 1 1 for all elements. But let's update my looping code to actually perform an operation on the element # path.
int elementCount = this.selenium.GetXpathCount("//*[. != '' or not(*)]");
for (int i = 1; i <= elementCount; ++i)
{
Console.WriteLine(this.selenium.GetElementPositionLeft("(//*[. != '' or not(*)])[" + i + "]"));
}
NO!!! GetXpathCount works but GetElementPositionLeft (and others) all fail. What gives? How can I work around this?
Here's the Selenium Exception:
{"ERROR: Element (//[. != '' or not()])[1] not found"}
[Selenium.SeleniumException]: {"ERROR: Element (//[. != '' or not()])[1] not found"}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
InnerException: null
Message: "ERROR: Element (//[. != '' or not()])[1] not found"
Source: "ThoughtWorks.Selenium.Core"

Selenium doesn't know what location strategy to use for (//*[. != '' or not(*)])[1]. Try preceding it with xpath=
As an alternative locator, I got this to work with the following (in Java):
int elementCount = selenium.getXpathCount("/descendant::*[. != '' or not(*)]").intValue();
for (int i = 1; i <= elementCount; ++i) {
System.out.println(i + ": " + selenium.getElementPositionLeft("xpath=/descendant::*[. != '' or not(*)][" + i + "]"));
}

Related

How not get out of bound in Kotlin?

I got the code that compare current element with the next element in array. But it crashes with out of bound because I guess when its on the last element there is no next element to compare with so it crashes.How to handle this to avoid crash and stop comparing on the last element? Here is my code
fun myFunction(arr: Array<Int>): Int{
if (arr.isEmpty()) return 0
var result = 0
for (item in arr.indices) {
if (arr[item] > 0 && arr[item + 1] < 0){
result ++
}
if (arr[item] < 0 && arr[item + 1] > 0){
result ++
}
}
return result
}
The direct answer to your question:
Instead of
for (item in arr.indices)
you should write
for (item in 0..(arr.lastIndex - 1))
Explanation: arr.indices returns the range 0..arr.lastIndex but in the loop you are checking the element after the current index; therefore you should only go up to arr.lastIndex - 1.
Some further advice:
IntArray is more efficient than Array<Int>
You can combine the two if statements into one using the || (or) operator.
If you are counting the number of sign changes, you need to consider how to interpret 0. In your code, an input of [1,-1] would give a result of 1 sign change, but [1,0,-1] would give 0, which seems wrong. To fix that, treat 0 as positive:
if ((arr[item] >= 0 && arr[item + 1] < 0) || arr[item] < 0 && arr[item + 1] >= 0) {
result++
}
You don't need to check if the array is empty; just remove that line. The loop won't be entered if the array is empty or if it has only 1 element.
Finally, you can use some cool features of the standard libray (look them up in the documentation to learn them) which can make your function succinct:
fun myFunction(arr: IntArray): Int {
var result = 0
arr.asList().zipWithNext().forEach { (a, b) ->
if ((a >= 0 && b < 0) || (a < 0 && b >= 0))
result++
}
return result
}
and even more succinct still:
fun myFunction(arr: IntArray) =
arr.asList().zipWithNext().count { (a, b) -> (a >= 0) != (b >= 0) }
References: single-expression functions, zipWithNext, count, destructuring.

Level Order Insertion in Binary Tree C#

Suppose we are given an array [20,8,22,5,3,4,25,null,null,10,14,null,null,null,null] and we want to construct a Binary Tree from it using Level Order , how can we do this in c# since it doesn't allow null int.
A simple pseudo-code:
function create_node(index, arr)
node n = node()
if 2*index + 1 < arr.size and arr[2*index + 1] != null
n.left = create_node(2*index + 1, arr)
if 2*index + 2 < arr.size and arr[2*index + 1] != null
n.right = create_node(2*index + 2, arr)
As you say, there is the issue of null. You can simply use some value outside of the range you expect - perhaps -1.

What is the least number of brackets you can delete to make sequence of brackets balanced

For example: we have sequence "(()(()))", then the answer is 0 (well, it is balanced brackets sequence)
Let's say that we have such sequence: "))(((", then optimal number to delete would be 5 (there is no other way to make it balanced apart from deleting all of them)
If we have such sequence: "())(()", then the answer is gonna be 2 (let's delete the third and the fourth ones)
here you are one possible solution:
start from the begin with a variable count = 0 that counts the "open" brackets and needed = 0 that are the number of brackets you need to balance
every time you find a ( add 1 to count
every time you find ):
if count == 0 then you need an open brackets before, so you do needed = needed += 1
else, decrease the number of open brackets found count = count - 1;
at the end, add the number of remaining open brackets, to the needed, because you need count final closing brackets: needed = needed + count
at the end:
count(string)
count = needed = 0
for i = 0 to string.length
if string[i] == '('
count = count + 1
else if string[i] == ')'
if count == 0
needed = needed + 1
else
count = count - 1
return count + needed
You can push open characters into the stack and when you encounter a closed character, if the stack is not empty pop an element from the stack if balanced, else increase count. After iterating, add the remaining chars present in the stack.
private static int getCount(String input) {
char open = '(';
int charsToDelete = 0;
Stack<Character> characterStack = new Stack<>();
for (int i=0;i<input.length();i++) {
char ch = input.charAt(i);
if (ch == open) {
characterStack.push(ch);
} else {
if (!characterStack.isEmpty()) {
char pop = characterStack.peek();
if (pop == '(') {
characterStack.pop();
} else {
charsToDelete++;
}
} else {
charsToDelete++;
}
}
}
while (!characterStack.isEmpty()) {
characterStack.pop();
charsToDelete++;
}
return charsToDelete;
}

How to find internal nodes in binary tree?

I already got the method to find external nodes but I have no idea about to count internal nodes so someone please help.
You could convert the following pseudocode to any language as per your preference.
function count_internal_nodes(curr):
if curr == null: return 0
else if curr is leaf: return 0
else: return 1 + count_internal_node(curr.left) +
count_internal_nodes(curr.right)
You can try this algo
getInteriorNodes(self)
count = 0
hasLeft, hasRight = self.left<>null, self.right <>null
if (hasLeft)
count += self.left.getInteriorNodes()
else if (hasRight)
count += self.right.getInteriorNodes()
else if ((hasLeft || hasRight) && self.parent)
count += 1
return count

Remove redundant parentheses from an arithmetic expression

This is an interview question, for which I did not find any satisfactory answers on stackoverflow or outside. Problem statement:
Given an arithmetic expression, remove redundant parentheses. E.g.
((a*b)+c) should become a*b+c
I can think of an obvious way of converting the infix expression to post fix and converting it back to infix - but is there a better way to do this?
A pair of parentheses is necessary if and only if they enclose an unparenthesized expression of the form X % X % ... % X where X are either parenthesized expressions or atoms, and % are binary operators, and if at least one of the operators % has lower precedence than an operator attached directly to the parenthesized expression on either side of it; or if it is the whole expression. So e.g. in
q * (a * b * c * d) + c
the surrounding operators are {+, *} and the lowest precedence operator inside the parentheses is *, so the parentheses are unnecessary. On the other hand, in
q * (a * b + c * d) + c
there is a lower precedence operator + inside the parentheses than the surrounding operator *, so they are necessary. However, in
z * q + (a * b + c * d) + c
the parentheses are not necessary because the outer * is not attached to the parenthesized expression.
Why this is true is that if all the operators inside an expression (X % X % ... % X) have higher priority than a surrounding operator, then the inner operators are anyway calculated out first even if the parentheses are removed.
So, you can check any pair of matching parentheses directly for redundancy by this algorithm:
Let L be operator immediately left of the left parenthesis, or nil
Let R be operator immediately right of the right parenthesis, or nil
If L is nil and R is nil:
Redundant
Else:
Scan the unparenthesized operators between the parentheses
Let X be the lowest priority operator
If X has lower priority than L or R:
Not redundant
Else:
Redundant
You can iterate this, removing redundant pairs until all remaining pairs are non-redundant.
Example:
((a * b) + c * (e + f))
(Processing pairs from left to right):
((a * b) + c * (e + f)) L = nil R = nil --> Redundant
^ ^
(a * b) + c * (e + f) L = nil R = nil --> Redundant
^ ^ L = nil R = + X = * --> Redundant
a * b + c * (e + f) L = * R = nil X = + --> Not redundant
^ ^
Final result:
a * b + c * (e + f)
I just figured out an answer:
the premises are:
1. the expression has been tokenized
2. no syntax error
3. there are only binary operators
input:
list of the tokens, for example:
(, (, a, *, b, ), +, c, )
output:
set of the redundant parentheses pairs (the orders of the pairs are not important),
for example,
0, 8
1, 5
please be aware of that : the set is not unique, for instance, ((a+b))*c, we can remove outer parentheses or inner one, but the final expression is unique
the data structure:
a stack, each item records information in each parenthese pair
the struct is:
left_pa: records the position of the left parenthese
min_op: records the operator in the parentheses with minimum priority
left_op: records current operator
the algorithm
1.push one empty item in the stack
2.scan the token list
2.1 if the token is operand, ignore
2.2 if the token is operator, records the operator in the left_op,
if min_op is nil, set the min_op = this operator, if the min_op
is not nil, compare the min_op with this operator, set min_op as
one of the two operators with less priority
2.3 if the token is left parenthese, push one item in the stack,
with left_pa = position of the parenthese
2.4 if the token is right parenthese,
2.4.1 we have the pair of the parentheses(left_pa and the
right parenthese)
2.4.2 pop the item
2.4.3 pre-read next token, if it is an operator, set it
as right operator
2.4.4 compare min_op of the item with left_op and right operator
(if any of them exists), we can easily get to know if the pair
of the parentheses is redundant, and output it(if the min_op
< any of left_op and right operator, the parentheses are necessary,
if min_op = left_op, the parentheses are necessary, otherwise
redundant)
2.4.5 if there is no left_op and no right operator(which also means
min_op = nil) and the stack is not empty, set the min_op of top
item as the min_op of the popped-up item
examples
example one
((a*b)+c)
after scanning to b, we have stack:
index left_pa min_op left_op
0
1 0
2 1 * * <-stack top
now we meet the first ')'(at pos 5), we pop the item
left_pa = 1
min_op = *
left_op = *
and pre-read operator '+', since min_op priority '*' > '+', so the pair(1,5) is redundant, so output it.
then scan till we meet last ')', at the moment, we have stack
index left_pa min_op left_op
0
1 0 + +
we pop this item(since we meet ')' at pos 8), and pre-read next operator, since there is no operator and at index 0, there is no left_op, so output the pair(0, 8)
example two
a*(b+c)
when we meet the ')', the stack is like:
index left_pa min_op left_op
0 * *
1 2 + +
now, we pop the item at index = 1, compare the min_op '+' with the left_op '*' at index 0, we can find out the '(',')' are necessary
This solutions works if the expression is a valid. We need mapping of the operators to priority values.
a. Traverse from two ends of the array to figure out matching parenthesis from both ends.
Let the indexes be i and j respectively.
b. Now traverse from i to j and find out the lowest precedence operator which is not contained inside any parentheses.
c. Compare the priority of this operator with the operators to left of open parenthesis and right of closing parenthesis. If no such operator exists, treat its priority as -1. If the priority of the operator is higher than these two, remove the parenthesis at i and j.
d. Continue the steps a to c until i<=j.
Push one empty item in the stack
Scan the token list
2.1 if the token is operand, ignore.
2.2 if the token is operator, records the operator in the left_op,
if min_op is nil, set the min_op = this operator, if the min_op
is not nil, compare the min_op with this operator, set min_op as
one of the two operators with less priority.
2.3 if the token is left parenthese, push one item in the stack,
with left_pa = position of the parenthesis.
2.4 if the token is right parenthesis:
2.4.1 we have the pair of the parentheses(left_pa and the
right parenthesis)
2.4.2 pop the item
2.4.3 pre-read next token, if it is an operator, set it
as right operator
2.4.4 compare min_op of the item with left_op and right operator
(if any of them exists), we can easily get to know if the pair
of the parentheses is redundant, and output it(if the min_op
< any of left_op and right operator, the parentheses are necessary,
if min_op = left_op, the parentheses are necessary, otherwise
redundant)
2.4.5 if there is no left_op and no right operator(which also means
min_op = nil) and the stack is not empty, set the min_op of top
item as the min_op of the popped-up item
examples
The code below implements a straightforward solution. It is limited to +, -, *, and /, but it can be extended to handle other operators if needed.
#include <iostream>
#include <set>
#include <stack>
int loc;
std::string parser(std::string input, int _loc) {
std::set<char> support = {'+', '-', '*', '/'};
std::string expi;
std::set<char> op;
loc = _loc;
while (true) {
if (input[loc] == '(') {
expi += parser(input, loc + 1);
} else if (input[loc] == ')') {
if ((input[loc + 1] != '*') && (input[loc + 1] != '/')) {
return expi;
} else {
if ((op.find('+') == op.end()) && (op.find('-') == op.end())) {
return expi;
} else {
return '(' + expi + ')';
}
}
} else {
char temp = input[loc];
expi = expi + temp;
if (support.find(temp) != support.end()) {
op.insert(temp);
}
}
loc++;
if (loc >= input.size()) {
break;
}
}
return expi;
}
int main() {
std::string input("(((a)+((b*c)))+(d*(f*g)))");
std::cout << parser(input, 0);
return 0;
}
I coded it previously in https://calculation-test.211368e.repl.co/trim.html. This doesn't have some errors in other answers.
(6 / (-2454) ** (((234)))) + (-5435) --> 6 / (-2454) ** 234 + (-5435)
const format = expression => {
var change = [], result = expression.replace(/ /g, "").replace(/\*\*/g, "^"), _count;
function replace(index, string){result = result.slice(0, index) + string + result.slice(index + 1)}
function add(index, string){result = result.slice(0, index) + string + result.slice(index)}
for (var count = 0; count < result.length; count++){
if (result[count] == "-"){
if ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890)".includes(result[count - 1])){
change.push(count);
}else if (result[count - 1] != "("){
add(count, "(");
count++;
_count = count + 1;
while ("1234567890.".includes(result[_count])) _count++;
if (_count < result.length - 1){
add(_count, ")");
}else{
add(_count + 2, ")");
}
}
}
}
change = change.sort(function(a, b){return a - b});
const len = change.length;
for (var count = 0; count < len; count++){replace(change[0] + count * 2, " - "); change.shift()}
return result.replace(/\*/g, " * ").replace(/\^/g, " ** ").replace(/\//g, " / ").replace(/\+/g, " + ");
}
const trim = expression => {
var result = format(expression).replace(/ /g, "").replace(/\*\*/g, "^"), deleting = [];
const brackets = bracket_pairs(result);
function bracket_pairs(){
function findcbracket(str, pos){
const rExp = /\(|\)/g;
rExp.lastIndex = pos + 1;
var depth = 1;
while ((pos = rExp.exec(str))) if (!(depth += str[pos.index] == "(" ? 1 : -1 )) {return pos.index}
}
function occurences(searchStr, str){
var startIndex = 0, index, indices = [];
while ((index = str.indexOf(searchStr, startIndex)) > -1){
indices.push(index);
startIndex = index + 1;
}
return indices;
}
const obrackets = occurences("(", result);
var cbrackets = [];
for (var count = 0; count < obrackets.length; count++) cbrackets.push(findcbracket(result, obrackets[count]));
return obrackets.map((e, i) => [e, cbrackets[i]]);
}
function remove(deleting){
function _remove(index){result = result.slice(0, index) + result.slice(index + 1)}
const len = deleting.length;
var deleting = deleting.sort(function(a, b){return a - b});
for (var count = 0; count < len; count++){
_remove(deleting[0] - count);
deleting.shift()
}
}
function precedence(operator, position){
if (!"^/*-+".includes(operator)) return "^/*-+";
if (position == "l" || position == "w") return {"^": "^", "/": "^", "*": "^/*", "-": "^/*", "+": "^/*-+"}[operator];
if (position == "r") return {"^": "^", "/": "^/*", "*": "^/*", "-": "^/*-+", "+": "^/*-+"}[operator];
}
function strip_bracket(string){
var result = "", level = 0;
for (var count = 0; count < string.length; count++){
if (string.charAt(count) == "(") level++;
if (level == 0) result += string.charAt(count);
if (string.charAt(count) == ")") level--;
}
return result.replace(/\s{2,}/g, " ");
}
for (var count = 0; count < brackets.length; count++){
const pair = brackets[count];
if (result[pair[0] - 1] == "(" && result[pair[1] + 1] == ")"){
deleting.push(...pair);
}else{
const left = precedence(result[pair[0] - 1], "l"), right = precedence(result[pair[1] + 1], "r");
var contents = strip_bracket(result.slice(pair[0] + 1, pair[1])), within = "+";
for (var _count = 0; _count < contents.length; _count++) if (precedence(contents[_count], "w").length < precedence(within, "w").length) within = contents[_count];
if (/^[0-9]+$/g.test(contents) || contents == ""){
deleting.push(...pair);
continue;
}
if (left.includes(within) && right.includes(within)){
if (!isNaN(result.slice(pair[0] + 1, pair[1]))){
if (Number(result.slice(pair[0] + 1, pair[1])) >= 0 && !"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".includes(result[pair[0] - 1])) deleting.push(...pair);
}else if (!"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".includes(result[pair[0] - 1])) deleting.push(...pair);
}
}
}
remove(deleting);
result = format(result);
return result;
}
<input id="input">
<button onclick="document.getElementById('result').innerHTML = trim(document.getElementById('input').value)">Remove and format</button>
<div id="result"></div>
I think that you are looking for kind of algorithm as seen in the following photo.
This algorithm is "almost" ready, since a lot of bugs arise once the more complex it becomes, the more complicated it gets. The way I work on this thing, is 'build-and-write-code-on-the-fly', which means that for up to 4 parentheses, things are easy. But after the expression goes more complex, there are things that I cannot predict while writing down thoughts on paper. And there comes the compiler to tell me what to correct. It would not be a lie if I state that it is not me to have written the algorithm, but the (C#) compiler instead! So far, it took me 1400 lines. It is not that the commands were difficult to write. It was their arrangement that was a real puzzle. This program you are looking for, is characterized by a really high grade of complexity. Well, if you need any primary ideas, please let me know and I will reply. Thanx!
Algorithm

Resources