Python Forum

Full Version: found “Node_3” and X1=10 Y1=100, how to copyX1Y1+findNext “Node_3” pasteX2Y2
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi there this is how it looks like BEFORE and AFTER, for the problem am trying to solve using Python. I have been trying for weeks. And am failing so miserable to tell python to do the following:

STEP1: If you find on this document: "LinkedTo=" (Example value: Node_3)
STEP2: Then Stop
STEP3: Go to the previous NodePosX= and copy the value (Example value: 10)
STEP4: Go to the previous NotePosY= and copy the value (Example value: 100)
STEP5: Then find the next "Node_3" on the document
STEP6: And replace inside the NodePosX=30 and NodePosY=300 for the copied values 10 and 100
STEP7: Then look for the next "LinkedTo=" (Example value: Node_5) and repeat the STEP2 to STEP5

This is how it looks like BEFORE runing the Python script:


Output:
Begin ----Name="Node_1" ----NodePosX=10 ----NodePosY=100 ----LinkedTo=Node_3 ----LinkedTo=Node_5 End Object Begin ----Name="Node_2" ----NodePosX=20 ----NodePosY=200 End Object Begin ----Name="Node_3" ----NodePosX=30 ----NodePosY=300 End Object Begin ----Name="Node_4" ----NodePosX=40 ----NodePosY=400 End Object Begin ----Name="Node_5" ----NodePosX=50 ----NodePosY=500 End Object
This is how it should look like AFTER runing the Python script:

Output:
Begin ----Name="Node_1" ----NodePosX=10 ----NodePosY=100 ----LinkedTo=Node_3 ----LinkedTo=Node_5 End Object Begin ----Name="Node_2" ----NodePosX=20 ----NodePosY=200 End Object Begin ----Name="Node_3" ----NodePosX=10 ----NodePosY=100 End Object Begin ----Name="Node_4" ----NodePosX=40 ----NodePosY=400 End Object Begin ----Name="Node_5" ----NodePosX=10 ----NodePosY=100 End Object
Do you think am asking to much from python to do?
Any better sugestions for the title to this problem?
Best regards!
I posted it as a Job also on freelancer for those interested on earning a buck
https://www.freelancer.com/projects/pyth...indReplace
The following code I just wrote could help you with the problem. It works as expected on the data above,
but it is not clear how to handle cyclic relations between nodes, e.g. A->B->C->A.

import re

# NOTE:  Dirty version

input_string = """
Begin 
----Name="Node_1"
----NodePosX=10
----NodePosY=100
----LinkedTo=Node_3
----LinkedTo=Node_5
End Object
Begin 
----Name="Node_2"
----NodePosX=20
----NodePosY=200
End Object
Begin 
----Name="Node_3"
----NodePosX=30
----NodePosY=300
End Object
Begin 
----Name="Node_4"
----NodePosX=40
----NodePosY=400
End Object
Begin 
----Name="Node_5"
----NodePosX=50
----NodePosY=500
End Object


"""



begin = r'Begin' 
end =  r'End Object'

property_words = ('Name', 'NodePosX', 'NodePosY', 'LinkedTo')


node_pat = re.compile(begin + r'(.*?)' + end, flags=re.DOTALL)


nodes = list()

def create_node(a):
    node = dict()
    for line in a.split('\n'):
        for word in property_words:
            if word in line:
                value = line.split('=')[-1]
                if word not in node:
                    node.update({word: value})
                else:
                    if isinstance(node[word], list):
                        node[word].append(value)
                    else:
                        old = node[word]
                        node[word] = [old, value]
                
    return node


def parse_nodes(input_string):
    result = list()
    for strnode in node_pat.findall(input_string.strip()):
        result.append(create_node(strnode))
    return result

def repr_node(node):
    """ NOTE: node is just a dict"""
    result = begin + '\n'
    result += '\n'.join(['-' * 4 + '{}={}'.format(k, v) for k, v in node.items()]) + '\n'
    result += end + '\n'
    return result

def find_node_by_name(nodes, name):
    for n in nodes:
        if name in n['Name']:
            return n

def change_nodes(nodes):
    linked_nodes = ['LinkedTo' in node for node in nodes]
    
    for node in nodes:
        if 'LinkedTo' in node:
            if isinstance(node['LinkedTo'], list):
                for link in node['LinkedTo']:
                    tochange = find_node_by_name(nodes, link)
                    tochange['NodePosX'], tochange['NodePosY'] = node['NodePosX'], node['NodePosY']
            else:
                tochange = find_node_by_name(nodes, node['LinkedTo'])
                tochange['NodePosX'], tochange['NodePosY'] = node['NodePosX'], node['NodePosY']
    
            
nodes = parse_nodes(input_string)
# Print parsed nodes 
for node in nodes:
    print(repr_node(node))


# changing nodes
change_nodes(nodes)

    
for node in nodes:
    print(repr_node(node))
Waw thanks!

This is the code of this Developer and works like charm!!
Profile Freelancer

'''
By: Alex Reichenbach
'''
import re
begin_regex  	= re.compile("Begin")
name_regex 		= "(?<=Name=\"Node_).*(?=\")"
posX_regex 		= "(?<=NodePosX=).*"
posY_regex 		= "(?<=NodePosY=).*"
linkedTo_regex  = "(?<=LinkedTo=).*"
end_regex  		= re.compile("End Object")

## Reading the contents of the file
text = open("1-Example-Original.txt", "r").read()
class Node:
	def __init__(self):
		self.name = ""
		self.nodePosX = 0
		self.nodePosY = 0
		self.linked_to = []

	def __str__(self):
		linked = ""
		for l in self.linked_to:
			linked += "\nLinkedTo="+l
		return """Begin
Name="%s"
NodePosX=%s
NodePosY=%s%s
End Object
"""%(self.name, self.nodePosX, self.nodePosY, linked)

## Read the text into the node objects
nodes = []
current_node = None
for line in text.split('\n'): ## Iterate through each line
	if begin_regex.match(line): 	       ## Begin
		current_node = Node()
		nodes.append(current_node)
	elif re.findall(name_regex, line):     ## Name
		name = re.findall(name_regex, line)[0]
		current_node.name = name
	elif re.findall(posX_regex, line):     ## PosX
		posX = re.findall(posX_regex, line)[0]
		current_node.nodePosX = posX
	elif re.findall(posY_regex, line): 	   ## PosY
		posY = re.findall(posY_regex, line)[0]
		current_node.nodePosY = posY
	elif re.findall(linkedTo_regex, line): ## LinkedTo
		name = re.findall(linkedTo_regex, line)[0]
		current_node.linked_to.append(name)

## Copy the linked_to attributes
for i in range(len(nodes)):
	for j in range(i, len(nodes)):
		node1 = nodes[i]
		node2 = nodes[j]
		if node2.name in node1.linked_to:
			node2.nodePosX = node1.nodePosX
			node2.nodePosY = node1.nodePosY

## Print it all out
s = ""
for node in nodes:
	s += str(node)
print(s)

## Write to File?
open("_edited.txt", "w").write(s)