If statement not evaluating correctly

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
GoneFishing
Posts: 126
Joined: 20 May 2022, 16:17

If statement not evaluating correctly

Post by GoneFishing » 20 May 2022, 23:06

Hi,

I'm trying to display a message if the value of the last two digits of a string is a certain value. The value is correct but the if statement does not evaluate it correctly. It keeps thinking it's false for some reason. I can't figure out why it is not working. Code is fairly simple. I'm reaading a file, getting a string and then finding the number after that string. Then extracting the last 2 digits and executing a second if statement based on the value of those two digits. It works fine till the second if statement. Can anyone tell me how to correct so it works properly ? Code is as follows (I've commented out a few sections till I get this piece working)

Code: Select all

;#IfWinActive, Game Name
;\::reload
;$]::
;pixelGetColor, pixel1, 282, 56, RGB
;sleep 530
;if pixel1 = 0xFCD79D
{
Loop, read, C:\AHk\Scripts\TestLogFile.txt
{
    if (InStr(A_LoopReadLine, "seed"))
    last_line := A_LoopReadLine
    Substr(last_line, -1)
      if (Substr(last_line, -1) = 10 )
      {
       MsgBox It Glows !
       return
      }
      else
      {
       MsgBox It does not Glow :-(
       return
      }
}
   ;MsgBox % Substr(last_line, -1)
   ;return
}
return
The test file is also attached. There does not appear to be any hidden characters or line feeds. Greatly appreciate any help to resolve. Thanks !
Attachments
TestLogFile.txt
(365 Bytes) Downloaded 18 times

User avatar
boiler
Posts: 16929
Joined: 21 Dec 2014, 02:44

Re: If statement not evaluating correctly

Post by boiler » 20 May 2022, 23:21

It actually works as expected (it says "It Glows !") with the file you provided. It only kind of works with that file (despite you saying it doesn't) because the line with "seed" in it is in the first line. Your code is not structured correctly to find that line and act on it if it appears after the first one because your first if statement only makes the line that assigns last_line conditional. The code below it executes on any line whether it contained "seed" or not, so when the first line doesn't contain "seed", it will still check it to see if it contains "10" then it exits the loop when it hits the return and never checks any lines after that.

To fix it, you need to define a code block for the first if statement. This is how it should be structured:

Code: Select all

Loop, Read, C:\AHk\Scripts\TestLogFile.txt
{
	if (InStr(A_LoopReadLine, "seed"))
	{ ; this marks the beginning of the code block you were missing
		last_line := A_LoopReadLine
		; Substr(last_line, -1) ; this line doesn't do anything so remove it
		if (Substr(last_line, -1) = 10 )
		{
			MsgBox It Glows !
			return
		}
		else
		{
			MsgBox It does not Glow :-(
			return
		}
	} ; this marks the end of the code block you were missing
}
return

GoneFishing
Posts: 126
Joined: 20 May 2022, 16:17

Re: If statement not evaluating correctly

Post by GoneFishing » 21 May 2022, 08:13

Thank you for cleaning this up for me. I don't code by trade so it's a bit of a learning curve. I ran the code against a larger file and it did not work again. I got the negative answer (does not glow !) when I should have gotten a positive result. All I did was change it so it looked for "00", which is in the file. Why is it not matching with the "00" ? I've attached the new test file

Code: Select all

Loop, Read, C:\AHk\Scripts\TestLogFile2.txt
{
	if (InStr(A_LoopReadLine, "seed"))
	{ 
		last_line := A_LoopReadLine
		if (Substr(last_line, -1) = 00 )
		{
			MsgBox It Glows !
			return
		}
		else
		{
			MsgBox It does not Glow :-(
			return
		}
	}
}
return
Attachments
TestLogFile2.txt
(428.18 KiB) Downloaded 13 times

User avatar
boiler
Posts: 16929
Joined: 21 Dec 2014, 02:44

Re: If statement not evaluating correctly

Post by boiler » 21 May 2022, 10:02

The reason is that you have a return in each branch of your if/else statement, so it's only acting on the first time it finds a "seed" line. If you intend for it to act on each "seed" line it finds, then you can't return after acting because that ends the script. Apparently, you want it to act on each "seed" line, which would be like this:

Code: Select all

Loop, Read, C:\AHk\Scripts\TestLogFile2.txt
{
	if (InStr(A_LoopReadLine, "seed"))
	{ 
		last_line := A_LoopReadLine
		if (Substr(last_line, -1) = "00")
			MsgBox It Glows !
		else
			MsgBox It does not Glow :-(
	}
}
return
When running the above with your new file, it says the first four "seed" line instances do not glow and the fifth one does.

Notice that I also put the 00 in quotation marks so it compares it as a string. Otherwise, you are doing a numeric comparison, so if the last two characters were something like 0. or .0 it would also be considered a match for 00, which I don't think is your intention.

User avatar
boiler
Posts: 16929
Joined: 21 Dec 2014, 02:44

Re: If statement not evaluating correctly

Post by boiler » 21 May 2022, 10:20

By the way, here is a more compact version of the script that doesn't need any code blocks defined because everything below each Loop, if, or else is a single statement (the if/else and its associated lines are grouped as a single statement of the first if statement. One reason it is able to be collapsed as much as this is you don't need a separate variable to contain the value of A_LoopReadLine. Just use that variable directly. But if you don't need to refer to that variable directly, then go ahead and leave that variable assignment line in the code.

Code: Select all

Loop, Read, C:\AHk\Scripts\TestLogFile2.txt
	if InStr(A_LoopReadLine, "seed")
		if Substr(A_LoopReadLine, -1) = "00"
			MsgBox It Glows !
		else
			MsgBox It does not Glow :-(
return
And even more compact using the ternary operator as a shorthand if/else within the MsgBox statement:

Code: Select all

Loop, Read, C:\AHk\Scripts\TestLogFile2.txt
	if InStr(A_LoopReadLine, "seed")
		MsgBox, % (Substr(A_LoopReadLine, -1) = "00") ? "It Glows !" : "It does not Glow :-("
return

GoneFishing
Posts: 126
Joined: 20 May 2022, 16:17

Re: If statement not evaluating correctly

Post by GoneFishing » 21 May 2022, 21:37

This is great ! Thank you so much. I'm almost there with the full script (I think). I need some help in completing it. I'll attach it at the end but a full outline of what I'm trying to achieve might be useful.
I first check that a specific window is active. I have then defined a reload and a key to run the script. I then check for a specific icon on the screen. If it is present I them go in to a second loop (which is most of the script you have helped build so far). The script then reads a log file and checks for two conditional parameters (the word seed and the last 2 digits of the number that comes directly after "seed"). If the conditional parameters are meet an alert sound plays and the script is paused. All these parts are working as expected.

If the conditional parameters aren't meet initially, then an else clause is triggered. The else clause needs to do several things
- Create a new instance via several mouse and keyboard strokes (hence the click and ctrl+click sections). This works as expected (I've used the same code elsewhere), however
- It also needs to re-read the log file each time a new instance is created to see if there is now a conditional match. If there is a match, the alert sound sound play and the script pause again, until it's restarted

This is where I'm currently stuck. I'm not sure if I just repeat the loop, read code again or I need to do something else. I also need to make sure I don't re-read an existing entry that matches the conditionals when I restart the script or create an infinite loop in this section either. Any help to finish this would be greatly appreciated. Here's the code so far

Code: Select all

#IfWinActive, WindowsName                  ;specific window must be open
\::reload                                  ;reload key
$[::                                       ;press [ key to kick script off
loop
{
pixelGetColor, pixel1, 282, 56, RGB        ;on screen co-ordinates for icon
sleep 530
if pixel1 = 0xFCD79D                       ;if icon present then go to next loop
{
Loop, Read, C:\C:\AHk\Scripts\TestLogFile2.txt ; Read log file. Only need last line with "seed" and the last two digits of the number on same line ending in "00"
	if InStr(A_LoopReadLine, "seed")
		{
		if Substr(A_LoopReadLine, -1) = "00"
			run, c:\AHk\Scripts\English.mp3    ; play specific sound
			pause                              ; pause script for other actions
		}
		else                                   ; if seed number doesn't end in "00" loop the activites below until a match in the log file is found. Then play sound and pause script as above
		 click, 1816, 1032                    ;mouse co-ordinatesco-ordinates
         sleep 500
         send ^{click, 654, 647}              ;ctrl+click for new instance 
         sleep 500
         click, 781, 698                      ;select from menu co-ordinates
         sleep 400
         ; read file and check for conditionals. Another loop ?
         ; if a match
         ; run, c:\AHk\Scripts\English.mp3    ; play specific sound
	     ; pause  		                      ; pause script for other actions
}
else 
sleep 120
}
return

User avatar
boiler
Posts: 16929
Joined: 21 Dec 2014, 02:44

Re: If statement not evaluating correctly

Post by boiler » 22 May 2022, 06:48

It's not a simple answer at this point because you are now describing something much more complicated than your initial question and for which your script isn't set up to handle. You were asking about evaluating the contents of a static file, and now you're saying you want to only act on new entries to the log file and not on the previous results, at least after the initial reading of the file. That totally changes how your script would have to be structured. Using Loop, Read is not the way to go. Here is a basic structure I use for monitoring log files:

Code: Select all

FilePath := A_ScriptDir "\chatlog.txt" ; or whatever your path is
File := FileOpen(FilePath, "r")
OldLogFileSize := 0
File.Seek(0, 2) ; move the file pointer to the end of the file to start reading newly added lines

Loop
{
	LogFileSize := File.Length
	if (LogFileSize > OldLogFileSize)
	{
		Loop
		{
			if File.AtEOF
				Break
			TextLine := File.Readline()
			IfInString, TextLine, PM from
			{
				RegExMatch(TextLine, "\[\K\d+(?=\])", ID)
				MsgBox, % "The ID is " ID ; replace this with your action
			}
		}
		OldLogFileSize := LogFileSize
	}
	Sleep, 1000 ; wait one second before checking again (change to whatever)
}
return

Esc::
	File.Close()
	ExitApp
return

Incorporating that into your script where you're saying you might want to restart the script at times (while presumably keeping your current place in the log file) is beyond the scope of this thread. You may want to try to re-build your script incorporating the above structure or some other structure that would only capture new entries in the log file, and then post in a new thread about any difficulties you might run into.

GoneFishing
Posts: 126
Joined: 20 May 2022, 16:17

Re: If statement not evaluating correctly

Post by GoneFishing » 22 May 2022, 12:33

Understood. Appreciate the extra information. I'll push forward and see if I can get it working as intended at some point.

Post Reply

Return to “Ask for Help (v1)”