Jump to content

Help needed to understand If/Then/Else syntax


Recommended Posts

I program in a lot of languages, and I love the development environment of AutoIt.

Muscle memory from other languages slows me down when coding in AutoIt.
Here's an example taken from the Helpfile for "If..Then"

Alternate ways of coding a simple If ... Then;  one avoiding an EndIf.

If $CmdLine[0] = 0 Then Exit
If $CmdLine[0] = 0 Then     ;; acceptable alternative
    Exit
 EndIf

I'm trying to determine the rules for coding these constructs.  Here is another example If..Then..Else Helpfile:

Local $sString = ""
If $sString > 0 Then
    MsgBox($MB_SYSTEMMODAL, "", "Value is positive.")
ElseIf $sString < 0 Then
    MsgBox($MB_SYSTEMMODAL, "", "Value is negative.")
Else
    If StringIsXDigit($sString) Then
        MsgBox($MB_SYSTEMMODAL, "", "Value might be hexadecimal!")
    Else
        MsgBox($MB_SYSTEMMODAL, "", "Value is a string.")
    EndIf
 EndIf

I think I have it now; combining the two styles, I find this format to be more readable (12 lines reduced to 8)

Local $sString = ""
If     $sString > 0 Then    MsgBox($MB_SYSTEMMODAL, "", "Value is positive.")
ElseIf $sString < 0 Then    MsgBox($MB_SYSTEMMODAL, "", "Value is negative.")
Else
    If StringIsXDigit($sString) Then MsgBox($MB_SYSTEMMODAL, "", "Value might be hexadecimal!")
                                Else MsgBox($MB_SYSTEMMODAL, "", "Value is a string.")
    EndIf
EndIf

AutoIt doesn't think so.  It's a format error and I'm struggling to figure out why.

The reason I find this format more readable is that all of the diagnostic messages
are aligned vertically ... and so are the tests that produce them.

I write code that is readable by me, and I find  vertically aligned code is:

  • more compact;  so I can see more code on a  single screen
  • vertically aligned ... so I can use human "pattern recognition" to understand it
    instead of wading through complex formats.

Do I have any hope of being able to write code this way?
so far, I have not established  what the rules are.
The two examples are inconsistent.

Oh ... and I love the fact that I can use a trailing underscore (_)
to align long lines of  code within a fixed width so that I can print it.

 

Link to comment
Share on other sites

Nope. you can't write the If,Then statements that way.

The difference between the two is with yours, the First IF statement block is closed out when you call the msgbox, and so the ElseIf block cannot be run. When the first If condition is false it will look for the next IF statement but will only find the ElseIf. Same thing again with the StringIsXDigit line, that's the reason for the error. I don't think there is a way to use a single line syntax in AutoIt like you can with some other languages.

If there are a lot of IF statements, It's sometimes better to use Switch or Select case to run the statements, or create a function

Local $sString = ""

CheckString($sString)

Func CheckString($s_String)
If $s_String > 0 Then Return MsgBox($MB_SYSTEMMODAL, "", "Value is positive.")
If $s_String < 0 Then Return MsgBox($MB_SYSTEMMODAL, "", "Value is negative.")
If StringIsXDigit($s_String) Then Return MsgBox($MB_SYSTEMMODAL, "", "Value might be hexadecimal!")
MsgBox($MB_SYSTEMMODAL, "", "Value is a string.")
EndFunc

 

Edited by benners
Link to comment
Share on other sites

I suggest to use Select

Local $sString = ""
Select
    Case Number($sString) > 0
        MsgBox(0, "", "Value is positive.")
    Case Number($sString < 0)
        MsgBox(0, "", "Value is negative.")
    Case StringIsXDigit($sString)
        MsgBox(0, "", "Value might be hexadecimal!")
    Case Else
        MsgBox(0, "", "Value is a string.")
EndSelect

BTW: Which result do you expect when $sString = 0?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Idk how to explain it but heres what ive got :lol:

#include <MsgBoxConstants.au3>
Local $sString = "0"
If $sString > 0 Then MsgBox($MB_OK, "This is greater than ", $sString)
If $sString = 0 Then MsgBox($MB_OK, "This is equal to ", $sString)

and

#include <MsgBoxConstants.au3>
Local $sString = ""
If $sString > 3 Then
    MsgBox($MB_OK, "if ", "Value is: " & $sString)
ElseIf $sString = 2 Then
    MsgBox($MB_OK, "ElseIf", "Value is: " & $sString)
Else
    MsgBox($MB_OK, "Else", "Value is: " & $sString)
EndIf

 

Edited by 232showtime
or just feeling lazy to explain :P

ill get to that... i still need to learn and understand a lot of codes graduated.gif

Correct answer, learn to walk before you take on that marathon.

Link to comment
Share on other sites

26 minutes ago, Subz said:

Another way:

Local $sString = ""
If StringIsDigit($sString) Then
    MsgBox(4096, "", $sString > 0 ? "Value is positive." : "Value is negative.")
Else
    MsgBox(4096, "", StringIsXDigit($sString) ? "Value might be hexadecimal!" : "Value is a string.")
EndIf

 

Oh boy, the ternary operator is my new favorite thing that's catching on. SO easy to use.

UHJvZmVzc2lvbmFsIENvbXB1dGVyZXI=

Link to comment
Share on other sites

When comparing a number against a string, the string is normally converted to a number if possible. If there are no numbers at the beginning of the string, the string evaluates to zero.

Hexadecimal numbers in a string though seem to be causing this to process the string to be greater than zero, even when set to a negative number, in the If comparison.

If you set the $sString to "0" or if it's set to 0 (no quotes) then the Value might be hexadecimal msgbox shows up.

The only time the Value is a string msgbox shows is if it's a string, even an empty string.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Also the issue that there are literal strings that there are many English words comprised of hex characters, as well as hex values that are all numbers, so you probably need an exact length or range to watch for.

heres my effort tho

;~ $string = "AB00BB"
;~ $string = "12344"
;~ $string = "5T121NG"

msgbox(0, '' , _TestStr($string))

Func _TestStr($string)

    $x = StringIsXDigit ( $string ) ? "string might be hex" : "string is string"

        If $x = "string is string" Then return $x

    $x = ($x = "string might be hex" AND stringleft($string , 1) = "-" AND StringIsDigit(stringtrimleft($string , 1))) OR  ($x = "string might be hex" AND StringIsDigit($string)) ? "string is number" : "string is hex"

return $x

EndFunc

 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

I deliberately chose  AutoIt Help Example code to demonstrate the problem.
The question is about Style, not algorithm or solution completeness.
What the code is doing;  why they are doing it; whether they are complete is not relevant to my question.

I agree that Select might be better for this task, as well as ternary operation.

Nothing I've seen so far explains why the action of a Then keyword must be on a separate line.
It wasn't required in the first example.

These rules are not consistent with a vast number of programming languages I'm familiar with.

I cannot take what I learn from Example 1 and apply it generally to more complex code.
I'm trying to understand why my failing rewrite cannot be permitted.

I understand the circumstances where an EndIf is necessary.

In most cases I am trying to reduce the size of the code vertically.

Ternaries are sometimes difficult to read quickly, looking for "?" and  ":", so I might rewrite Subz's example as:

Local $sString = "99"
If StringIsDigit($sString) Then MsgBox(4096, "", $sString > 0 _
                                               ? "Value is positive." _
                                               : "Value is negative.")

A slight rewrite to narrow the code width fails unless I add an EndIf:

Local $sString = "-99"
If StringIsDigit($sString) Then 
    MsgBox(4096, "", $sString > 0 _
                   ? "Value is positive." _
                   : "Value is negative.")

But a simple trailing "_" makes the rewrite acceptable.

Local $sString = "-99"
If StringIsDigit($sString) Then _
    MsgBox(4096, "", $sString > 0 _
                   ? "Value is positive." _
                   : "Value is negative.")

I don't know why I find this so disturbing, but these things slow me down.
I'll happily trade the syntatic underscore sugar for an EndIf.
But why do I need  "Then _"  sugar?

One of the reasons I did not like C++ in a corporate setting was programmers were
constantly trying to "trick the compiler" into doing something they wanted to do.
Perhaps  50% of the developer chatter was devoted to "clever" tricks;
tricks that would work on one compiler but break the code base on another platform.
 

Link to comment
Share on other sites

10 hours ago, water said:

I suggest to use Select

Local $sString = ""
Select
    Case Number($sString) > 0
        MsgBox(0, "", "Value is positive.")
    Case Number($sString < 0)
        MsgBox(0, "", "Value is negative.")
    Case StringIsXDigit($sString)
        MsgBox(0, "", "Value might be hexadecimal!")
    Case Else
        MsgBox(0, "", "Value is a string.")
EndSelect

 

I agree, Select is a better style for complex test examples.  But this topic is about Style so I reformatted:

Local $sString = "-100"
Select
    Case Number($sString) > 0     MsgBox(0, "", "Value is positive.")
    Case Number($sString < 0)     MsgBox(0, "", "Value is negative.")
    Case StringIsXDigit($sString) MsgBox(0, "", "Value might be hexadecimal!")
    Case Else                     MsgBox(0, "", "Value is a string.")
EndSelect

The code structure reveals a difference in the test between positive/negative choices.
Not trying to be picky about your example, but the reason I reformat is to visually
discover these differences ... which might be the difference between the entire Switch
working and failing subtly for certain situations.  For me, it's about "speed reading" the code.

A simple correction isn't necessary here, it just improves consistency for human inspector "pattern recognition".

Local $sString = "-100"
Select
    Case Number($sString > 0)     MsgBox(0, "", "Value is positive.")
    Case Number($sString < 0)     MsgBox(0, "", "Value is negative.")
    Case StringIsXDigit($sString) MsgBox(0, "", "Value might be hexadecimal!")
    Case Else                     MsgBox(0, "", "Value is a string.")
EndSelect

No intent to be picky;  just trying to convey the coding style I'm adopting for a huge new project I'm developing.
This style has one additional benefit.  Code query.   Since the MsgBox and Case are on the same line,
using a tools like "Find/Grep" can quickly discover where a message is coming from in a large code base.

# cygwin
find . -print0 -name '*.au3' | xargs -0 grep 'MsgBox'

The Message I'm looking for and the test that produced it are quickly discovered.

AutoIt is the best for developing complex Windows projects;  concentrate on the problem, not the tool.
Simplify, Simplify, Semper Fi.

Edited by vmguy
grep
Link to comment
Share on other sites

As to the syntax, it works that way because the author chose it to work that way.

A single line If statement doesn't require an EndIf, while a multi-line one does only because the script is interpreted one line at a time. If the interpreter sees something after the Then on the same line, it figures that it's a single line If and won't look for an EndIf later. If there's nothing after the Then, other than a CRLF or a comment, then it will start reading the next line as part of the If statement. If you put something after the Then on the same line, on a multi-line If statement, it will probably cause problems, not to mention running into an unopened EndIf section (to the interpreter) later on.

To the interpreter these are 2 separate "lines" of code.

If StringIsDigit($sString) Then 
    MsgBox(4096, "", $sString > 0 _
                   ? "Value is positive." _
                   : "Value is negative.")

With the continuation character in your second attempt, it's seen as one line. Simple and very straightforward. It's the opposite of the semicolon in C variants, they signify that the code line ends at that point, where the underscore here tells it that it should be treated as all one line. I'd rail against the totally unnecessary semicolon in C variants, before I'd go after the underscore in AutoIt which actually serves a purpose.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

On 5/24/2017 at 7:25 PM, BrewManNH said:

> As to the syntax, it works that way because the author chose it to work that way.

I worked with a talented software engineer who had two signs in his office;

On the left:  "Why would you ever want to do something like that?"
On the right:  "Once you get used to it, you're going to like it."

A software engineer works between those two signs.

  Left   Sign: Response to a user requesting a feechur you hadn't considered.
  Right Sign: Response to a user complaining about a code breaking change you introduced.

 > I'd rail against the totally unnecessary semicolon in C variants, before I'd go after the underscore in AutoIt which actually serves a purpose.

I am not railing against AutoIt; 
I'm trying to understand the principles so I don't have to keep reading the documentation.
As an exercise, I reformatted all of the scripts in Examples and Include in order to become
immersed in AutoIt features and style, before I start coding a very ambitious project.

I didn't make it clear in my post.  I understand what the "_" is for, and
appreciate that degree of freedom to choose my own style.

If you dislike unnecessary C semicolon's,  Python fixes a lot of that,
and also the requirement to have code blocks contain some kind of enclosing syntax.

One of the major objectives of Python was to make code more readable;
one of the design choices that makes that possible is rigid indentation rules.
AutoIt isn't Python, nor should it be.

I use autoit because it is very productive;  the Help file alone is pure genius.
Thank you, Team AutoIt.

I got what I came here for.  --Cheers

 

Edited by vmguy
no reason
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...