Calculating distance of context node from nearest preceding text node - xquery

I wish to record how many elements intervene between a context node and the nearest preceding text node. What I do now is the following:
xquery version "3.0";
let $text :=
<text>
<p n="1">text-node<pb/><lb/><seg>text-node<context-node>context-node</context-node>text-node</seg></p>
<p n="2">text-node<pb/><lb/><seg><context-node>context-node</context-node>text-node</seg></p>
<p n="3">text-node<pb/><seg><lb/><context-node>context-node</context-node>text-node</seg></p>
<p n="4">text-node<pb/><seg>text-node<lb/><context-node>context-node</context-node>text-node</seg></p>
<p n="5">text-node<pb/>text-node<seg><lb/><context-node>context-node</context-node>text-node</seg></p>
<p n="6"><seg>text-node<pb/><lb/><context-node>context-node</context-node>text-node</seg></p>
<p n="7">text-node<seg><pb/><lb/><context-node>context-node</context-node>text-node</seg></p>
<p n="8">text-node<seg><pb/><cb/><lb/><context-node>context-node</context-node>text-node</seg></p>
</text>
let $predicate := 'context-node'
return
for $element at $i in $text/element()
let $context-node := $element//element()[. eq $predicate]
return
<context-text-distance n="{$i}">{
if ($context-node/preceding-sibling::node()[1] instance of text() or $context-node/parent::element()/child::node()[1] is $context-node)
then 1
else
if ($context-node/preceding-sibling::node()[2] instance of text() or $context-node/parent::element()/child::node()[2] is $context-node)
then 2
else
if ($context-node/preceding-sibling::node()[3] instance of text() or $context-node/parent::element()/child::node()[3] is $context-node)
then 3
else ()
}</context-text-distance>
This returns the right answers and of course I could go on like this - a number higher than 5 is extremely unlikely - but I am curious to know whether it is possible to calculate this distance without testing each individual possibility?
I take point of departure in the context node, an element node. I want to see how many preceding element nodes have to be traversed in order to reach a text node sibling of the context node or if the context node is the first child node of its parent. If one of these requirements is satisfied, the distance is 1. Thus in the example 1, the preceding-sibling of the context node is a text node, and the distance is therefore 1. In the example 2, a seg element is parent of the context node, and since the context node is its first child, the distance is again 1. In the example 3, the encompassing seg element comes before the empty lb element, so the count is 2. In the example 4, a text node comes before the empty lb element, so the count is again 2. Example 5 is actually a replay of example 3 and could be deleted. In example 6, two empty elements "intervene" between the context node and the nearest preceding text node, so the distance is 3. In example 7, the parent seg node has the same effect on the distance count as the text node of example 6. Example 8 returns empty, since the distance is 4 which is not covered.
I use this in order to determine in which order to extract and insert standoff markup in text. Empty elements have the same offset, but have to be inserted in a determinate order. All offsets are calculated in relation to text nodes. A context node which is the first child of its parent has the offset of 0, as if there was a text node.

I think the return statement has to be something like the following in order to get the same result:
if ($context-node/preceding-sibling::text())
then
<context-text-distance type="1" n="{$context-node/ancestor::p/#n}">{
for $node at $i in $context-node/preceding-sibling::text()[1]/following-sibling::node()
return
if ($node is $context-node) then $i else ()
}</context-text-distance>
else
<context-text-distance type="2" n="{$context-node/ancestor::p/#n}">{
count($context-node/preceding-sibling::node()) + 1
}</context-text-distance>

Related

Guaranteeing that node is above all other nodes in group

I am currently trying to make a group of arcs, with text above them. This seems to be working, but for only half the cases. The other half is ending up below the arc node and is invisible.
I have tried using node.tofront() , toback() etc but it is still not changing anything.
class pieslice extends Group{
pieslice(double centerx,double centery,double segpart,double totalseg){
Text value= new Text(String.format("%.2f",worth));
segment = totalseg;
Arc innerArc=new Arc();
Arc outerArc=new Arc();
outerArc.setType(ArcType.ROUND);
innerArc.setType(ArcType.ROUND);
value.setFill(Color.WHITE);
innerArc.setStrokeWidth(1);
innerArc.setRadiusX(150.0f);
innerArc.setRadiusY(150.0f);
outerArc.setRadiusX(innerArc.getRadiusX()+10);
outerArc.setRadiusY(innerArc.getRadiusY()+10);
outerArc.setFill(Color.WHITE);
innerArc.setStartAngle((360/segment)*segpart);
outerArc.setStartAngle((360/segment)*segpart);
innerArc.setCenterX(centerx);
innerArc.setCenterY(centery);
outerArc.setCenterX(centerx);
outerArc.setCenterX(centery);
innerArc.setLength(360/segment);
outerArc.setLength(360/segment);
innerArc.setStrokeWidth(1);
innerArc.setStroke(Color.BLACK);
innerArc.setFill(Color.color(Math.random(),Math.random(),Math.random()));
value.setX(150);
value.setFill(Color.BLACK);
value.getTransforms().add(new Rotate((360/segment)*segpart+((360/segment)/2),0,0));
System.out.println((360/segment)*segpart+((360/segment)/2));
this.getChildren().add(outerArc);
this.getChildren().get(0).setViewOrder(2);
this.getChildren().add(innerArc);
this.getChildren().add(value);}
I would expect that since I am adding the two arcs (Inner and outer for aesthetic effect only) and then the text, that the text would be rendered above the shapes, but that is not the case. Any ideas?

Ternary Search Tree Implementation in R

I'm trying to implement a ternary search tree in R.
Here's the logic I'm trying to implement:
A vector will be "tiered" by designating each level of the tree as the next 3^somepower of cells after the existing tier. So tier 1 will be the first cell, tier 2 will be cells 2-4, tier 3 will be cells 5-13, tier 4 will be cells 14-40, tier 5 will be cells 41-122, and so on.
I want my code to do the following:
1) Take a vector, and an object obj to insert in the tree. In practice obj will be a number.
2) If the slot I'm trying to go into is full, jump down to the next tier, according to the rules:
2a) If obj is < than the occupied cell, go down to the left cell in the next level, of the three-cell-block "directly below" it.
2b) If obj is == the occupied cell, go down to the center cell of the three-cell-block "directly below" it.
2c) If 'obj' is > the occupied cell, go down to the rightmost cell of the three-cell-block "directly below it".
I drew a diagram of what I want the output to be if I put in the numbers 34,42,15,24,16, 34,52,32,42,19,21,16,54,60,55. I included the code that does something, but I don't understand exactly what it's doing. I just know that it isn't doing what I want to do.
Thanks for your help.
Desired output:
My code:
put<-function(obj, Tree,pow=0,offset=1,arity=3)
{
level<-arity^pow
if (is.na(Tree[level])){
Tree[level+offset-1]<-obj
return(Tree)
} else {
if (obj<Tree[level]) {
put(obj,Tree,pow+1,offset=0)
} else {
if (obj == Tree[level]){
put(obj,Tree,pow+1,offset=1)
} else {
if (obj > Tree[level]){
put(obj,Tree,pow+1,offset=2)
}}}}
}
BeforeTree<-c(34,42,15,24,16,
34,52,32,42,19,21,16,54,60,55)
Tree<-NA
for (idx in 1:(length(BeforeTree)))
{Tree<-put(BeforeTree[idx],Tree)}
(Tree)

Longest cycle of key-value pairs in a dictionary

I've got a question regarding Python 3 which I can't wrap my head around.
Let's say I got the following dictionary.
{'Noah': 'Liam', 'Ethan': 'Peter', 'Liam': 'Olivia', 'Emma': 'Ethan', 'Peter': 'Emma', 'Olivia': 'Noah'}
I need to find the longest cycle of key-value pairs in this dictionary.
In pseudo-code this would be
for key in dictionary:
find value in dictionary, make this key
continue process untill start key has been detected
In this example the longest cycle would be:
Noah --> Liam --> Olivia --> Noah (length of 3)
I have no clue how to go about this, even though I know exactly what I want to do. Would appreciate some help.
The keyword to your problem is recursion... Or google "linked lists". Draw what you want to do on a sheet of paper and think of each step individually.. with that small amount of data it is possible.
It's for sure not the prettiest solution but it works. And you get the point.
import copy
people = {'Noah': 'Liam', 'Ethan': 'Peter', 'Liam': 'Olivia', 'Emma': 'Ethan', 'Peter': 'Emma', 'Olivia': 'Noah'}
def walk_the_links(person, subtree, counter):
print(person)
if person in subtree:
counter += 1
next_person = subtree[person]
subtree.pop(person)
counter = walk_the_links(next_person, subtree, counter)
return counter
for person in people:
subtree = copy.deepcopy(people)
counter = 0
length_tree = walk_the_links(person, subtree, counter)
print(length_tree)

Graph: node dependency

I have a graph like this:
for example I want to know the dependency of node 8 which are : 1,2,3,5 . can some body give me some code or may be pseudo code to solve this problem?
Thanks
Dependency structure is a partially ordered set. I had similar case which I covered with 2 methods (in python):
nodes_to_update( to_proc ) parameter is a set of nodes to start with (e.g. set([8])). Returns two set of nodes: set of all nodes on which given nodes depend and set of leaf nodes. Idea is to recursively visit all nodes on which depend visited nodes.
sequence_to_update( to_proc ) parameter is like above. Return (ordered) list of nodes so that nodes in list depend only on nodes before in list. It is done by adding leaf node to the ordered list, and updating set of nodes to processed (all and leaf nodes).
Dependent nodes are get with method down_nodes(o_id) and nodes that depends on are get with up_nodes(o_id).
def nodes_to_update(self, to_proc):
all_to_update, first_to_update = set(), set()
while to_proc:
n = to_proc.pop()
all_to_update.add(n)
ds = self.down_nodes(n) # nodes on which n depends
if not ds:
first_to_update.add(n)
else:
to_proc.update(ds)
return all_to_update, first_to_update
def sequence_to_update(self, to_proc):
all_to_update, first_to_update = self.nodes_to_update(to_proc)
update_in_order = []
while first_to_update:
n_id = first_to_update.pop()
all_to_update.discard(n_id)
update_in_order.append(n_id)
# nodes which depend on n_id (intersection of upper nodes and all nodes to update)
for up_id in (self.up_nodes(n_id) & all_to_update):
if all(d not in all_to_update for d in self.down_nodes(up_id)):
first_to_update.add(up_id)
return update_in_order

(PyQt) QTreeView - want to expand/collapse all children and grandchildren

I want to be able to expand or collapse all children of a particular branch in a QTreeView. I am using PyQt4.
I know that QTreeView's have an expand all children feature that is bound to *, but I need two things: It needs to be bound to a different key combination (shift-space) and I also need to be able to collapse all children as well.
Here is what I have tried so far:
I have a subclass of a QTreeView wherein I am checking for the shift-space key combo. I know that QModelIndex will let me pick a specific child with the "child" function, but that requires knowing the number of children. I am able to get a count of the children by looking at the internalPointer, but that only gives me info for the first level of the hierarchy. If I try to use recursion, I can get a bunch of child counts, but then I am lost as to how to get these converted back into a valid QModelIndex.
Here is some code:
def keyPressEvent(self, event):
"""
Capture key press events to handle:
- enable/disable
"""
#shift - space means toggle expanded/collapsed for all children
if (event.key() == QtCore.Qt.Key_Space and
event.modifiers() & QtCore.Qt.ShiftModifier):
expanded = self.isExpanded(self.selectedIndexes()[0])
for cellIndex in self.selectedIndexes():
if cellIndex.column() == 0: #only need to call it once per row
#I can get the actual object represented here
item = cellIndex.internalPointer()
#and I can get the number of children from that
numChildren = item.get_child_count()
#but now what? How do I convert this number into valid
#QModelIndex objects? I know I could use:
# cellIndex.child(row, 0)
#to get the immediate children's QModelIndex's, but how
#would I deal with grandchildren, great grandchildren, etc...
self.setExpanded(cellIndex, not(expanded))
return
Here is the beginning of the recursion method I was investigating, but I get stuck when actually trying to set the expanded state because once inside the recursion, I lose "contact" with any valid QModelIndex...
def toggle_expanded(self, item, expand):
"""
Toggles the children of item (recursively)
"""
for row in range(0,item.get_child_count()):
newItem = item.get_child_at_row(row)
self.toggle_expanded(newItem, expand)
#well... I'm stuck here because I'd like to toggle the expanded
#setting of the "current" item, but I don't know how to convert
#my pointer to the object represented in the tree view back into
#a valid QModelIndex
#self.setExpanded(?????, expand) #<- What I'd like to run
print "Setting", item.get_name(), "to", str(expand) #<- simple debug statement that indicates that the concept is valid
Thanks to all for taking the time to look at this!
Ok... siblings did not actually get me to where I wanted to go. I managed to get the code working as follows (and it seems like a decent implementation). Kudos still to Prof.Ebral who got me going on the right track with the idea of siblings (turns out I needed to use QModelIndex.child(row, column) and iterate recursively from there).
Note that there is the following assumption in the code: It assumes that your underlying data store objects have the ability to report how many children they have (get_child_count() in my code). If that is not the case, you will somehow have to get a child count differently... perhaps by just arbitrarily trying to get child indexes - using QModelIndex.child(row, col) - with an ever increasing row count till you get back an invalid index? - this is what Prof.Ebral suggested and I might still try that (It is just that I already have an easy way to get the child count by requesting it from my data store).
Also note that I actually expand/collpase each node at a different point in the recursion based on whether I am expanding or collapsing. This is because, through trial and error, I discovered that animated tree views would stutter and pop if I just did it at one place in the code. Now, by reversing the order in which I do it based on whether I am at the top level (i.e. the root of the branch I am affecting - not the root of the entire treeview) I get a nice smooth animation. This is documented below.
The following code is in a QTreeView subclass.
#---------------------------------------------------------------------------
def keyPressEvent(self, event):
if (event.key() == QtCore.Qt.Key_Space and self.currentIndex().column() == 0):
shift = event.modifiers() & QtCore.Qt.ShiftModifier
if shift:
self.expand_all(self.currentIndex())
else:
expand = not(self.isExpanded(self.currentIndex()))
self.setExpanded(self.currentIndex(), expand)
#---------------------------------------------------------------------------
def expand_all(self, index):
"""
Expands/collapses all the children and grandchildren etc. of index.
"""
expand = not(self.isExpanded(index))
if not expand: #if collapsing, do that first (wonky animation otherwise)
self.setExpanded(index, expand)
childCount = index.internalPointer().get_child_count()
self.recursive_expand(index, childCount, expand)
if expand: #if expanding, do that last (wonky animation otherwise)
self.setExpanded(index, expand)
#---------------------------------------------------------------------------
def recursive_expand(self, index, childCount, expand):
"""
Recursively expands/collpases all the children of index.
"""
for childNo in range(0, childCount):
childIndex = index.child(childNo, 0)
if expand: #if expanding, do that first (wonky animation otherwise)
self.setExpanded(childIndex, expand)
subChildCount = childIndex.internalPointer().get_child_count()
if subChildCount > 0:
self.recursive_expand(childIndex, subChildCount, expand)
if not expand: #if collapsing, do it last (wonky animation otherwise)
self.setExpanded(childIndex, expand)
model.rowCount(index) is the method you want.
model = index.model() # or some other way of getting it
for i in xrange(model.rowCount(index)):
child = model.index(i,0, index)
# do something with child
model.index(row,col, parent) is essentially the same as calling index.child(row,col); just with fewer indirections.
I would recommend using a QTreeWidget which inherits QTreeView. You can then grab the children as a QTreeWidgetItem.
Since you do not want to use the QTreeWidget but want to stick to your current model .. you can iterate through the 'possible' children using, .isValid(). You should not use the internalPointer() though. Instead use the cellItem you have, as it is the original ModalIndex .. then attempt to find it's siblings. Something like
x = 0; y =0
while cellIndex.sibling(x, y).isValid():
child = cellIndex.sibling(x, y)
x += 1
I make a evnetFilter Class for that.
My particular use case is shift click the drop indicator then expand all or collapse all the child nodes like software maya outliner.
class MTreeExpandHook(QtCore.QObject):
"""
MTreeExpandHook( QTreeView )
"""
def __init__(self, tree):
super(MTreeExpandHook, self).__init__()
tree.viewport().installEventFilter(self)
self.tree = tree
def eventFilter(self, receiver, event):
if (
event.type() == QtCore.QEvent.Type.MouseButtonPress
and event.modifiers() & QtCore.Qt.ShiftModifier
):
pos = self.tree.mapFromGlobal(QtGui.QCursor.pos())
index = self.tree.indexAt(pos)
if not self.tree.isExpanded(index):
self.tree.expandRecursively(index)
return True
return super(MTreeExpandHook, self).eventFilter(self.tree, event)
Usage Example below
import sys
from PySide2 import QtCore,QtGui,QtWidgets
class MTreeExpandHook(QtCore.QObject):
"""
MTreeExpandHook( QTreeView )
"""
def __init__(self, tree):
super(MTreeExpandHook, self).__init__()
self.setParent(tree)
# NOTE viewport for click event listen
tree.viewport().installEventFilter(self)
self.tree = tree
def eventFilter(self, receiver, event):
if (
# NOTE mouse left click
event.type() == QtCore.QEvent.Type.MouseButtonPress
# NOTE keyboard shift press
and event.modifiers() & QtCore.Qt.ShiftModifier
):
# NOTE get mouse local position
pos = self.tree.mapFromGlobal(QtGui.QCursor.pos())
index = self.tree.indexAt(pos)
if not self.tree.isExpanded(index):
# NOTE expand all child
self.tree.expandRecursively(index)
return True
return super(MTreeExpandHook, self).eventFilter(self.tree, event)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
model = QtGui.QStandardItemModel()
# NOTE create nested data
for i in range(3):
parent = QtGui.QStandardItem('Family {}'.format(i))
for j in range(3):
child = QtGui.QStandardItem('Child {}'.format(i*3+j))
for k in range(3):
sub_child = QtGui.QStandardItem("Sub Child")
child.appendRow([sub_child])
for x in range(2):
sub_child_2 = QtGui.QStandardItem("Sub Child 2")
sub_child.appendRow([sub_child_2])
parent.appendRow([child])
model.appendRow(parent)
treeView = QtWidgets.QTreeView()
treeView.setHeaderHidden(True)
MTreeExpandHook(treeView)
treeView.setModel(model)
treeView.show()
sys.exit(app.exec_())
example gif

Resources