0

I'm really sorry if this question has been asked before, but I can't seem to find the solution to this error anywhere for my case.

I have a text file with screen coordinates (x and y, separated by a new line), and I want to read the file, and store every line of the file onto an two separate arrays - one for X, and one for Y.

I then want to use pyautogui.moveTo() to move to the two x and y coordinates, then click (I haven't done any of that yet).

The variable actionNumber simply acts like i in a for loop, to count which line we're on in the text file.

How can I create the two arrays (dataX[] and dataY[]) in python that can be read through mainLoop(), and then store a line of data from the file in dataX[actionNumber] and then the next line of the file into dataY[actionNumber]?

Here is my code, it is pretty simple:

actionNumber = 0

dataX = []
dataY = []

f = open("track_cursor_position_log.txt", "r")
#print(f.read())


def mainLoop():
    #I need to store the first line of the file into dataX, then the second into dataY, then the 3rd into dataX, and so on...

    actionNumber = actionNumber + 1

    mainLoop()

mainLoop()

Here are the errors I get:

Traceback (most recent call last):
  File "C:/Users/devel/Downloads/python-imagesearch-master/python-imagesearch-master/ClickAgentTest.py", line 17, in <module>
    mainLoop()
  File "C:/Users/devel/Downloads/python-imagesearch-master/python-imagesearch-master/ClickAgentTest.py", line 13, in mainLoop
    actionNumber = actionNumber + 1
UnboundLocalError: local variable 'actionNumber' referenced before assignment

Here is a small snippet of the data in the file track_cursor_position_log.txt, just so you can get what I'm talking about:

1858
1129
1292
1165
927
1287
1501
461
1567
709
2298
1049
1473
1244
2511
1722

I once more apologise if this is a noob question, but I am more of a c++/JS coder, and I haven't used python in a while...

Thank you very much to everyone who can help out!

eyllanesc
  • 221,139
  • 17
  • 121
  • 189
SavvyDev06
  • 23
  • 6
  • actionNumber is not in the scope of `mainLoop`. You need to make it a global, define it in the function, or pass it in as an argument. – Denver Jan 30 '20 at 18:57
  • Got it, I'll try that out (thanks a lot btw), is there any chance you could also tell me how to read the file line by line, so I can store each line into dataX[actionNumber], then the next line into dataY[actionNumber]? – SavvyDev06 Jan 30 '20 at 19:03

2 Answers2

1

Well, there's a few things I would do differently than your approach. But, to fix your error, you need to reference the global variable actionNumber rather than the local instance in your mainLoop namespace. Do this by adding this to your code:

def mainLoop():
    global actionNumber
    actionNumber = actionNumber + 1

Full example of code:

coords = []
f = open("track_cursor_position_log.txt", "r")
lines = f.readlines()
for item in lines:
   x,y = item.split(', ')
   coords.append([x,y])

for item in coords:
   pyautogui.moveto(item[0], item[1])
eyllanesc
  • 221,139
  • 17
  • 121
  • 189
  • Thanks so much for the help! Is there any chance you could also tell me how to read the file line by line, so I can store each line into ```dataX[actionNumber]```, then the next line into ```dataY[actionNumber]```? – SavvyDev06 Jan 30 '20 at 19:06
  • Sure! f.readlines() will create a list of lines in the file (each line is stored as a string). You could then split each string at the `,` and store the x and y values respectively. I personally would just create a single list called coords to store the values and set it up as so: `coords=[[x,y],[x2,y2], [x3,y3]...]` – JattCode113 Jan 30 '20 at 19:42
0

Since you are defining a function, it is treating any reference to actionNumber as a local variable, a variable that exists only within the function with no connection to the global variable actionNumber.

You can add global actionNumber as the first line to your function, which will make any reference to actionNumber in the function, a reference to the global actionNumber, not a local one. However, I suggest you define actionNumber as 0 in the function unless you need to use actionNumber in multiple difference functions/outside the function.

So, you're fixed code would be either:

actionNumber = 0

dataX = []
dataY = []

f = open("track_cursor_position_log.txt", "r")
#print(f.read())


def mainLoop():
    #I need to store the first line of the file into dataX, then the second into dataY, then the 3rd into dataX, and so on...
    global actionNumber

    actionNumber = actionNumber + 1

    mainLoop()

mainLoop()

or

dataX = []
dataY = []

f = open("track_cursor_position_log.txt", "r")
#print(f.read())


def mainLoop():
    #I need to store the first line of the file into dataX, then the second into dataY, then the 3rd into dataX, and so on...
    actionNumber = 0

    actionNumber = actionNumber + 1

    mainLoop()

mainLoop()

Also, as an aside, actionNumber += 1 would be the same as actionNumber = actionNumber + 1

Mike Smith
  • 494
  • 6
  • 18
  • 1
    Nice, thank you so much for the very helpful and detailed answer! Is there any chance you could also tell me how to read the file line by line, so I can store each line into ```dataX[actionNumber]```, then the next line into ```dataY[actionNumber]```? – SavvyDev06 Jan 30 '20 at 19:05
  • `f.readlines()` will separate the file you have stored to `f` into an array where each element of the array is a line of the file. You could probably then using some code to alternately store each line into dataX and dataY. – Mike Smith Jan 30 '20 at 19:08
  • Got it! Thank you so much for the great help! – SavvyDev06 Jan 30 '20 at 19:09
  • Just to confirm - with arrays in Python, do I need to fill them with values as soon as I create them? or would ```dataX = []``` simply work? – SavvyDev06 Jan 30 '20 at 19:12
  • That would definitely work. I often use that in my code, and later use a for loop to append to them. This is a very useful feature which you should definitely use. – Mike Smith Jan 30 '20 at 19:17