Python Forum
found “Node_3” and X1=10 Y1=100, how to copyX1Y1+findNext “Node_3” pasteX2Y2
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
found “Node_3” and X1=10 Y1=100, how to copyX1Y1+findNext “Node_3” pasteX2Y2
#1
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!
Reply
#2
Cross-post on SO
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
I posted it as a Job also on freelancer for those interested on earning a buck
https://www.freelancer.com/projects/pyth...indReplace
Reply
#4
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))
Reply
#5
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)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How can I found how many numbers are there in a Collatz Sequence that I found? cananb 2 2,548 Nov-23-2020, 05:15 PM
Last Post: cananb

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020