Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
I_R_SOCKET_KING
Posts: 10
Joined: 21 Apr 2019, 23:11

Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by I_R_SOCKET_KING » 22 Nov 2022, 19:04

Hi,

So I've been building a tool to help identify a series of numbers, ex. 21,192, then be able to sort the numbers found based off of the X coordinate from left to right, but I am having issues trying to output the desired end result being "21192". In this case I am receiving "COORDX2 COORDX1 COORDX1 COORDX9 ... etc"

I cannot seem to wrap my head around what I am doing incorrectly and I know 100% that there is probably a better way to do things, but I don't have a huge programming background to know what formula I should be using. I know my issues are after the initial sorting of numbers from left to right. I just cannot seem to arrange the numbers in the desired result I would like to be, in this case "21192". Below the code I'll list other things that I've tried but I couldn't seem to get the desired result correctly.

I know there are probably 50 ways to do this, but in my head and whatever I could learn from other posts this is the best and what made sense to me. You're more than welcome to break it up in a way that makes it work properly but if you don't mind explaining ♥ELI5♥ some of the stuff you'll be doing so I can walk away with some knowledge on this would be very appreciative. Thank you

Code: Select all

COLUMN1()
{
NumWord := ["num0", "img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8", "img9"]
GrandTotal := "", FoundX := "" ;; Reset and Stores Variables
Left = 1845
loop, 10
{
SEARCHAGAIN:
	ImageSearch, FoundX,, %Left% , 505, 1950, 529, % "*170 *transwhite " . a_scriptdir . "\LA\num1\" . NumWord[A_Index] . ".png"
	if !ErrorLevel  ;; Image found
		{
		GrandTotal .=  FoundX . A_Index - 1 . A_Tab
		Left := FoundX + 5
		goto SEARCHAGAIN
		}
}

Sort, GrandTotal, N DA_TAB  ;; Sorts by FoundX L-->R
GrandTotal.RemoveAt(A_Index, -1)  ;; Removes FoundX
GrandTotal.RemoveAt(A_Index, +1)  ;; Removes A_Tab
msgbox % GrandTotal . " is the total"
}
Here are some other things I tried toying around with but I wasn't able to get any of these to work correctly either.

Code: Select all

GrandTotal.RemoveAt(1)  ;; Removes FoundX
GrandTotal.RemoveAt(3)  ;; Removes A_Tab
msgbox % GrandTotal.RemoveAt(1) . " is the total"
msgbox % GrandTotal[2]

User avatar
mikeyww
Posts: 26951
Joined: 09 Sep 2014, 18:38

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by mikeyww » 22 Nov 2022, 20:06

Hi,

You can trouble-shoot this quickly.

1. Shorten the script so that you can test parts of it, one part at a time. Try hard-coding what you want to sort. After it works, expand little by little, testing along the way.

2. Display the values of your variables. You can then quickly see where the script is going wrong. You currently have no idea what the values are, until the end of the script. You don't even know the ErrorLevel from the searches.

I_R_SOCKET_KING
Posts: 10
Joined: 21 Apr 2019, 23:11

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by I_R_SOCKET_KING » 22 Nov 2022, 20:25

mikeyww wrote:
22 Nov 2022, 20:06
1. Shorten the script so that you can test parts of it, one part at a time. Try hard-coding what you want to sort. After it works, expand little by little, testing along the way.

2. Display the values of your variables. You can then quickly see where the script is going wrong. You currently have no idea what the values are, until the end of the script. You don't even know the ErrorLevel from the searches.
Hi Mikeyww,

I'm not well versed in programming terms or know if I am using the correct functions to begin with.

I have been hard coding to troubleshoot a lot bit by bit to ensure that I can get to the next step, but I'm kinda lost and need some direction here. I've done a lot of reading on things but I just can't seem to wrap my head around how to be able to display just the %A_index% part of the array and every %A_index% following that after that.

If you can help point me at some stuff to read up on to help solve my issues that would be a fantastic start.

I_R_SOCKET_KING
Posts: 10
Joined: 21 Apr 2019, 23:11

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by I_R_SOCKET_KING » 22 Nov 2022, 21:26

Im currently working my way backwards again to see what is going on.
Now I've got some other weird stuff happening because %A_index% is acting as a negative I am assuming and not as an interger.. I believe those are the correct terms. So I'm now getting ErrorCode=2 when the 0 is searched.

We'll Ill keep working at it trying to guess what terminology to search here is where I'm at now:

Code: Select all

COLUMN1()
{
NumWord := ["img0", "img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8", "img9"]
GrandTotal := "" ; , FoundX := "" ;; Reset and Stores Variables
Left = 1845
loop, 10
{
	ImageSearch, FoundX,, %Left% , 505, 1950, 529, *170 *transwhite %a_scriptdir%\LA\num1\img%A_Index%.png
	if (ErrorLevel = 2)
		msgbox "error with the img search"
	if (ErrorLevel = 0)  ;; Image found
		{
		msgbox "you found the number" . A_index
		}
}
msgbox "this is the end"


User avatar
mikeyww
Posts: 26951
Joined: 09 Sep 2014, 18:38

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by mikeyww » 22 Nov 2022, 21:43

OK. Start with a two-line script. On the first line, do the ImageSearch. Instead of using variables there, hard-code your coordinates and image path. On the second line, display the ErrorLevel from the search. That is a way to get started, to see if the search works. If it doesn't work, then there is some work to be done to fix the search.

Next, you can write a brief plain-language description, step by step, of what should happen with the coordinate that is found. Are you building a list? What does this list represent? What is an example of the list that you want to build (i.e., the input)? Do you then want to sort the list numerically? From your example, what should the output look like?

Things to consider as you are working:
1. How could you eliminate the Goto, and use a Loop or While instead?
2. RemoveAt is used only for arrays, but it certainly looks like GrandTotal is a string rather than an array. An example of an array is seen in your script elsewhere (NumWord).
3. Is GrandTotal supposed to be a sum? If so, are you adding numbers? If so, where?

The bottom line is that you have a script with many steps, but it seems that you might not undertand any of the steps. This is why I suggested starting with a two-line script, and writing a simple description of what you want to achieve. Your initial post actually does not describe what the script should do. It really just names the final output, and then spends two paragraphs explaining that the script does not work! :)

ErrorLevel of 2 is easy to fix. It usually means that the image path does not exist, or you had a wrongly formatted option.

You can remove the loop while you test. If one iteration fails to achieve what you want, then there is no point iterating further.

My initial suggestion of hard-coding your ImageSearch line will enable you to debug that line quickly. You can also issue a FileExist to see if the image path exists.

As you do your testing, none of this needs to be wrapped as a function. You can remove the function to simplify your testing.

You can read the documentation about arrays and loops. Inside a loop, A_Index is never zero.
The built-in variable A_Index contains the number of the current loop iteration. It contains 1 the first time the loop's body is executed. For the second time, it contains 2; and so on. If an inner loop is enclosed by an outer loop, the inner loop takes precedence. A_Index works inside all types of loops, including file-loops and registry-loops; but A_Index contains 0 outside of a loop.

User avatar
Chunjee
Posts: 1422
Joined: 18 Apr 2014, 19:05
Contact:

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by Chunjee » 23 Nov 2022, 02:36

I_R_SOCKET_KING wrote:
22 Nov 2022, 19:04
So I've been building a tool to help identify a series of numbers, ex. 21,192, then be able to sort the numbers found based off of the X coordinate from left to right, but I am having issues trying to output the desired end result being "21192". In this case I am receiving "COORDX2 COORDX1 COORDX1 COORDX9 ... etc"

I cannot seem to wrap my head around what I am doing incorrectly and I know 100% that there is probably a better way to do things, but I don't have a huge programming background to know what formula I should be using.

I would start by organizing your coordinates into key-value objects (so the x and y can stay together and clearly labeled)

Code: Select all

coordX := 211
coordY := 92
oneXYpair := {"x":coordX, "y":coordY}

You can then put all of them into an array. An array of objects:

Code: Select all

myData := [{"x":211, "y":92}
, {"x":300, "y":11}
, {"x":107, "y":74}
, {"x":150, "y":99}]


https://biga-ahk.github.io/biga.ahk/#/?id=sortby or similar can then sort this by smallest to largest x, or other value.

Code: Select all

A := new biga() ; requires https://github.com/biga-ahk/biga.ahk


sortedDatabyX := A.sortBy(myData, "x")
; => [{"x": 107, "y": 74}, {"x": 150, "y": 99}, {"x": 211, "y": 92}, {"x": 300, "y": 11}]

You can do it :superhappy:

I_R_SOCKET_KING
Posts: 10
Joined: 21 Apr 2019, 23:11

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by I_R_SOCKET_KING » 24 Nov 2022, 13:49

Ok, I've run into a bit of a snag on things, but when I try to do a static search for the individual images everything works perfectly, but when I try to pull from the Array I am able to get all the images perfectly, but once completed the numbers it spits out an Error Code 2 which I am not understanding. I've gone back to doing static checks twice now on each image and it works, but the second I put the array option in will always spit out the Error Code 2 at the end.

Code: Select all

NumWord := ["img0", "img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8", "img9"]
GrandTotal := "" ; , FoundX := "" ;; Reset and Stores Variables
Left = 1845
while (NumWord <= img9)
{
	ImageSearch, FoundX,, %Left% , 505, 1950, 529, % "*170 *transblack " . a_scriptdir . "\LA\num1\" . NumWord[A_Index] . ".png"
	; ImageSearch, FoundX,, %Left% , 505, 1950, 529, % "*170 *transblack " . a_scriptdir . "\LA\num1\img9.png" <--- commented out but this is what I used for the static value check
	if (ErrorLevel = 2)
			msgbox "error with the img search"
	if (ErrorLevel = 0)  ;; Image found
		{
		msgbox % "I found " . A_Index - 1 . " this"
		}
}

User avatar
mikeyww
Posts: 26951
Joined: 09 Sep 2014, 18:38

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by mikeyww » 24 Nov 2022, 14:07

It is possible to learn how to debug your scripts. One example is below.

Code: Select all

NumWord := ["img0", "img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8", "img9"]
while (NumWord <= img9) ; This does what, exactly?
{
 a := "*170 *transblack " . a_scriptdir . "\LA\num1\" . NumWord[A_Index] . ".png"
 b := "*170 *transblack " . a_scriptdir . "\LA\num1\img9.png"
 MsgBox, %a%`n%b%
}
You do not need a while statement because you can use For.

Code: Select all

NumWord := ["img0", "img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8", "img9"]
For each, fn in NumWord
{
 a := "*170 *transblack " . a_scriptdir . "\LA\num1\" . fn . ".png"
 b := "*170 *transblack " . a_scriptdir . "\LA\num1\img9.png"
 MsgBox, %a%`n%b%
}
If you add FileExist, it will help you understand whether the file exists. You can display the value returned by the FileExist function. This will most likely enable you to solve the puzzle within five minutes.

User avatar
Chunjee
Posts: 1422
Joined: 18 Apr 2014, 19:05
Contact:

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by Chunjee » 24 Nov 2022, 15:45

while (NumWord <= img9) seems like the main issue. But I fixed a few.

If you wanna loop an array; you should use https://www.autohotkey.com/docs/commands/For.htm

Code: Select all

NumWord := ["img0", "img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8", "img9"]
GrandTotal := ""
Left := 1845
for key, value in NumWord {
	ImageSearch, FoundX,, %Left% , 505, 1950, 529, % "*170 *transblack " a_scriptdir "\LA\num1\" value ".png"
	if (FoundX)	{
		msgbox % "Found " A_Index - 1 " this"
	} else if (ErrorLevel == 2) {
		msgbox "error with the img search"
	}
}

I_R_SOCKET_KING
Posts: 10
Joined: 21 Apr 2019, 23:11

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by I_R_SOCKET_KING » 25 Nov 2022, 04:07

Ok so I've sorted out a lot of the code and got it to work and output exactly how I wanted it to, but I have some questions and would like some input on things I could/should change.

I used a GOTO because I ran into an issue where it wasn't able to find any of the same numbers after it finds the first one. I don't know a way around this, but maybe one of you might be able to help point me in the right direction on that.

I also don't know a good way to output the data other than by the following steps:
- Sort by FoundX first
- String Split and remove ., and img so all I'm left with are numbers. I couldn't find a way to delete X number of characters from the desired character (in this case I could use . or ,) so I did a split string instead since it also cleaned up the data.
- then adding every other element (basically Value). I couldn't find a good way to doing this step.

And some questions I have in regards to some of the other stuff that was said by you guys:
- I noticed that Chun used "if (FoundX)" after the ImageSearch. Is this a better way for image searches or is "ErrorCode = 0" fine? I dont know if FoundX there has some importance.
- how do you add something into an empty array/string? I'm a bit confused on this and I dont know how to tell if something will be an array or string other than to make the string, then use split string to make it into an array.. I think at least. Example below.

Code: Select all

FoundX := ""
FoundX .= var1 . VAL1 . "," . var2 . VAL2 . ","
What are the best times to be using the following:
- For - best used in Arrays? or only used in arrays? Im guessing so pls confirm this and below.
- While - ???
- Loop .... Until - ???

Code: Select all

NumWord := ["img0", "img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8", "img9"]
xPos := "", FoundX := "", xSplit := "", xFinal := "" ;; Reset and Stores Variables
for key, value in NumWord
{
Left = 1845
SEARCHAGAIN:
	ImageSearch, FoundX,, %Left% , 505, 1950, 529, % "*170 *transblack " . a_scriptdir . "\LA\num1\" . NumWord[A_Index] . ".png"
	if (ErrorLevel = 2)
		msgbox "error with the img search"
	if (FoundX)  ;; Image found
		{
		xPos .=  ".," . FoundX . "." . Value
		Left := FoundX + 5
		Goto SEARCHAGAIN
		}
}
Sort, xPos, N D,  ;; Sorts by FoundX L-->R
xSplit := StrSplit(xPos, ., " ,img") ;; object testing - creates object
xFinal := xSplit[3] . xSplit[5] . xSplit[7] . xSplit[9] . xSplit[11] . xSplit[13] . xSplit[15]
msgbox % xFinal . " is the total"

User avatar
mikeyww
Posts: 26951
Joined: 09 Sep 2014, 18:38

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by mikeyww » 25 Nov 2022, 07:52

Many of your questions are answered in the AHK documentation, so I recommend having a look there. Instead of Goto, you can use Loop... Until, or simply Break from the loop. Those approaches are better.

Using ErrorLevel is better than If FoundX, because FoundX may be zero when the image is found. FoundX is the x-coordinate in your example.

Arrays are always defined by you as you code the script. For will loop through an array's elements. While checks the condition before an iteration. Until checks the condition after an iteration.

User avatar
Chunjee
Posts: 1422
Joined: 18 Apr 2014, 19:05
Contact:

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by Chunjee » 25 Nov 2022, 17:27

I'm a bit confused. What is the desired output? For example given the following theoretical input:

image.png
image.png (26.75 KiB) Viewed 694 times

Are you trying to get 42.png, Hey.png, 33.png or something else?

I_R_SOCKET_KING
Posts: 10
Joined: 21 Apr 2019, 23:11

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by I_R_SOCKET_KING » 26 Nov 2022, 06:05

mikeyww wrote:
25 Nov 2022, 07:52
Many of your questions are answered in the AHK documentation .... Until checks the condition after an iteration.
Ah ok.. so you'd do something like FOR then inside of that put a loop so that A_index retains the same value. example below. Is this what you mean?

Code: Select all

for key, value in NumWord
{
	loop
	{
	ImageSearch .... .png
		if (ErrorCode = 0)
			{
			DataIn .=  DataFromImgSearch . A_index
			}
	}
	Until ErrorCode = 1
}
When you said Arrays are always defined by me... I thought I was making an array from the first post but you said it was a string which got me confused on array creation vs a string creation. Can you give me a short example of this because I've gone through other peoples code and the documentation and I'm still confused on the approach I should be taking moving forward. Example below is what I thought would make something into an array

Code: Select all

GrandTotal .=  FoundX . A_Index - 1 . A_Tab
Ah ok.. those examples of For, While, and Until make total sense now. Adding it to my notes of AHK tips to remember.

Chunjee wrote:
25 Nov 2022, 17:27
I'm a bit confused. ... Are you trying to get 42.png, Hey.png, 33.png or something else?
So using your image as an example I am looking for the numbers only. Umm but let's just say that the number is actually 4233, (four thousand, two hundred, and thirty three).
The script would run trying try to match the number from images in a folder of numbers from 1 to 9. It would run from left to right and grab data along the way and would spit it out like this first.

2000 img2, 6000 img3, 7000 img3, 1000 img4, <== each 1000 is the coordinate for X. the img+single digit being the number found

I did a basic sort using the "," as a delimiter so the data was presented like this ==> 1000 img4, 2000 img2, 6000 img3, 7000 img3,

So here is where I THINK.. there might be a better way of doing the additional sorting.. but I made it work using the things I understood how to use from the documentation/examples from others using it in their scripts.

then I used String Split to break it up into an array at every {space} AND in the process I deleted the "," and "img" and all {spaces}
Data would look like this now ==> 10004200026000370003

then I added every other line manually and spit out the data through a message box which would say something like "Hi! I've found the number 4233 from the picture shown"


So in a nut shell I just need the numbers seen on the image to be given to me as "4233"


I'd really love to hear what you would anyone else would do. I'm learning so much and I'm hoping to improve because it's amazing the things you guys can come up with to simplify and/or make things easier for yourself.

User avatar
mikeyww
Posts: 26951
Joined: 09 Sep 2014, 18:38

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by mikeyww » 26 Nov 2022, 06:50

You have one possible idea for the For & Loop.

AHK does not use ErrorCode as a built-in variable, but some commands do set ErrorLevel.

You are mistaken about arrays. You can read about appending to strings, concatenation, and arrays. Appending or concatenating strings does not make the string an array or convert it into an array.

Here is an example of how to append a value to an array that has been defined.

https://www.autohotkey.com/docs/objects/Object.htm#Push

User avatar
Chunjee
Posts: 1422
Joined: 18 Apr 2014, 19:05
Contact:

Re: Finding numbers, Sort Numbers, but Problems with outputing the Numbers

Post by Chunjee » 26 Nov 2022, 11:47

I_R_SOCKET_KING wrote:
26 Nov 2022, 06:05
I did a basic sort using the "," as a delimiter

then I used String Split to break it up into an array at every {space} AND in the process I deleted the "," and "img" and all {spaces}

then I added every other line manually
I think most of that string juggling can be skipped if you use objects. I find {"num":"img2.png", "x":2000} easier to work with than "2000###1" or whatever the string looks like.




Obviously this script can be thought of as two separate parts. 1. Finding all the number via image. I would use viewtopic.php?f=6&t=100838 (ImageSearchAll) to vastly simplify all the 'ok same image but a littlemore left' code. Thankfully that function returns the x and y of where each was found.
Lets say it looks something like:

Code: Select all

NumWord := ["img0", "img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8", "img9"]
OutputArray := []
; find all
for key, value in NumWord {
	thisImage := ImageSearchAll(a_scriptdir "\LA\num1\" value, 1845, 505, 1950, 529, 170)
	for key2, value2 in thisImage {
		; remeber what image this was associated with
		value2.num := value
		; put them all in the output array, so we have all search numbers in one place
		OutputArray.push(value2)
	}
}




The second part is what I'm interested in, 2. sorting the output.
Given the theoretical OutputArray; lets output "4233"

Code: Select all

A := new biga() ; requires https://github.com/biga-ahk/biga.ahk

; I ommited the y's because they aren't too important here
OutputArray := [{"num":"img2", "x":2000}
			, {"num":"img3", "x":6000}
			, {"num":"img3", "x":7000}
			, {"num":"img4", "x":1000}]

; sort by x
sortedOutput := A.sortBy(OutputArray, "x")
; get a new array with ust the nums
numbersArr := A.map(sortedOutput, "num")
; => ["img4", "img2", "img3", "img3"]

; turn it into a string
string := A.join(numbersArr, "")
; remove all the "img" text
string := strReplace(string, "img", "")
; msgbox the output:
msgbox, % "Out: " string
; => "Out: 4233"
image.png
image.png (4.14 KiB) Viewed 620 times

Post Reply

Return to “Ask for Help (v1)”