AutoHotkey Community

It is currently May 27th, 2012, 10:48 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 62 posts ]  Go to page 1, 2, 3, 4, 5  Next
Author Message
PostPosted: March 16th, 2008, 10:49 pm 
Offline
User avatar

Joined: October 7th, 2006, 8:45 am
Posts: 3330
Location: Simi Valley, CA
btw: I'm invoking
The Forums Index Page wrote:
...Post helpful tips and tricks.
to post this here. {also this is my 500th post.}

What is it?!
The ternary operator is like an If/Else conditional, but packaged to fit inside an expression.

What does it look like?!
The ternary operator looks like a boolean expression followed by a question mark followed by something, then a colon and another something

What is it used for?!
The ternary operator collapses one or more "If/Else" blocks so that they fit inside a normal command or into an expression.

Why bother with it if I can do the same thing with "If/Else"?!
The ternary operator has a coolness factor rating of 14 units = sunglasses. Using it makes your code shorterr, cooler, and more complicated-looking.

Is there an easy way to write them?... I tried once and it I got confused.
Certainly! This is a guide to both writing and understand them...

Firstly: you should start by writing out your code the long Iffy way:
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
If answer < georgf
   MsgBox, Your name is stupid.
Else If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.


So... you can use the ternary operator to reduce all of those Ifs and Elses and Msgboxes down to a single Msgbox. To begin, comment out the lines that you want to convert and start a new line with the same command that is common to those If/Else blocks. Then put the string % (() ? () : ()) where the argument of interest is (that's pretty simple for a basic Msgbox, but you can use the ternary in whatever argument you want)
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
/*
If answer < georgf
   MsgBox, Your name is stupid.
Else If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
*/
MsgBox % (() ? () : ())


OK, now we can start building our ternary expression. Next, find the first boolean expression and paste it into the first set of () parentheses. REMEMBER to use 'expression format' when dealing with literal strings and variables
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
/*
If answer < georgf
   MsgBox, Your name is stupid.
Else If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
*/
MsgBox % ((answer < "georgf") ? () : ())


Next, put the contents of the first Block inside the second set of () parentheses.
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
/*
If answer < georgf
   MsgBox, Your name is stupid.
Else If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
*/
MsgBox % ((answer < "georgf") ? (MsgBox, Your name is stupid.) : ())


Have you spotted something that's missing and something that should be? Yes, because we are inside an expression, literal strings must be enclosed in "" quote marks and we don't need a second "Msgbox". So fix that and then copy the "Else" block into the third set of () parentheses.
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
/*
If answer < georgf
   MsgBox, Your name is stupid.
Else If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
*/
MsgBox % ((answer < "georgf") ? ("Your name is stupid.") : (
If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
))


OMG!! what have we done!! That expression is totally 'F'-ed UP!. Our "Else" block has more than just a single command... it has more "IF/Else"s in it! Have you guessed what we're going to do?... That's right, another ternary operator. Go ahead and paste another happy little (() ? () : ()) onto the line where we're working.
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
/*
If answer < georgf
   MsgBox, Your name is stupid.
Else If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
*/
MsgBox % ((answer < "georgf") ? ("Your name is stupid.") : ( (() ? () : ())
If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
))


Have you figured out what do do? Wash, rinse, repeat...
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
/*
If answer < georgf
   MsgBox, Your name is stupid.
Else If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
*/
MsgBox % ((answer < "georgf") ? ("Your name is stupid.") : ( ((answer < "normap") ? ("Your name ROCKsORZ!") : (
If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
))
))


...And again...
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
/*
If answer < georgf
   MsgBox, Your name is stupid.
Else If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
*/
MsgBox % ((answer < "georgf") ? ("Your name is stupid.") : ( ((answer < "normap") ? ("Your name ROCKsORZ!") : ( (() ? () : ())
If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
))
))


OK, here we are at the last one. We no longer have to nest more ternary operators, so we can go ahead and put the strings into their approprate parentheses
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
/*
If answer < georgf
   MsgBox, Your name is stupid.
Else If answer < normap
   Msgbox, Your name ROCKsORZ!
Else If answer < tog
   Msgbox, Your name is totally wimpy.
Else
   MsgBox, Your name is nothing special.
*/
MsgBox % ((answer < "georgf") ? ("Your name is stupid.") : ( ((answer < "normap") ? ("Your name ROCKsORZ!") : ( ((answer < "tog") ? ("Your name is totally wimpy.") : ("Your name is nothing special."))))))


Don't forget to bring those trailing "))" close-parentheses back to the proper line. Now, this expression will work fine, however there is one little thing we can do to make it even shorter. We can bring out the part of each string that is the same ("Your name ") and put it outside of our ternary operator.
Code:
InputBox, answer , Is anybody out there?, What is your name?, , , , , , , , Your Name
MsgBox % "Your name " ((answer < "georgf") ? ("is stupid.") : ( ((answer < "normap") ? ("ROCKsORZ!") : ( ((answer < "tog") ? ("is totally wimpy.") : ("is nothing special."))))))


And there you have it! A beautiful decorative hand-carved wooden duck decoy that you made yourself. Hopefully, those who didn't know about this shortcut will have gained a better understanding of how the ternary operator is used in command arguments and how it can be used in expressions.

Feedback welcome! --- [VxE]

_________________
Ternary (a ? b : c) guide     TSV Table Manipulation Library
Post code inside [code][/code] tags!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2008, 3:42 am 
Hey! Wait a second! My name is not stupid >:(


Report this post
Top
  
Reply with quote  
PostPosted: March 17th, 2008, 4:02 am 
Offline

Joined: December 29th, 2007, 9:40 pm
Posts: 142
[VxE] wrote:
Why bother with it if I can do the same thing with "If/Else"?!
The ternary operator has a coolness factor rating of 14 units = sunglasses. Using it makes your code shorterr, cooler, and more complicated-looking.

:lol: ROFL! That's good. Thanks for the giggles. Thanks, also, for the nice primer! Take care.

-t


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2008, 4:23 am 
Offline

Joined: April 17th, 2007, 1:37 pm
Posts: 761
Location: Florida
I'm very interested if this increases code execution speed over several if/else lines. Thanks for the primer - Very well put together!

_________________
[Join IRC!]
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2008, 5:39 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
Rhys, in [VxE]'s example, the ternary version is actually slower. Both are under 10µs, though, so it isn't really an issue. Readability is, though... this is one of those cases where ternary makes it less readable.

Generally ternary is more efficient in simple expressions, and less efficient in more complex ones.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2008, 10:20 am 
Offline

Joined: February 18th, 2008, 8:26 pm
Posts: 442
In higher level languages like C# and PHP I usually use associative arrays for lookup tables and switch/case as an alternative to stacking If statements. Ternary operators shouldn't be nested more than three times deep, and if it has to be this much for numerical values only. Ifs are faster because machine code processes them in the same form, giving the compiler more room to optimize.

Nice article by the way. As a hobbyist programmer there are many gaps in my knowledge so I always find it interesting to read stuff like this.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2008, 10:54 am 
Cool [HowTo]. Thx. :D
I'd like to see something similar for 'continuation sections'. *wishgrin*

Especially when we'll set up real loooooooooong lines, like those shown above, it would make sense to use the continuation option to get a better layout/visability, right?

I saw it sometimes used with DllCall()s ... 8)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2008, 10:12 pm 
Offline
User avatar

Joined: October 7th, 2006, 8:45 am
Posts: 3330
Location: Simi Valley, CA
Thx for the feedback everyone :D I thought of something that would improve this guide but that I probably would mess up if I did it myself:

Examples of commonly seen ternary usages !

I would like to keep a growing list of instances where the ternary operator is preferred for readability. For example:
Code:
Hotkey:: SetTimer, Label, % ((Bool := !Bool) ? (Number) : ("Off"))


Maybe some more examples like this with brief explanations would help new users learn from more examples, and would improve the search-hit-keyword spread for this thread.

_________________
Ternary (a ? b : c) guide     TSV Table Manipulation Library
Post code inside [code][/code] tags!


Report this post
Top
 Profile  
Reply with quote  
PostPosted: May 5th, 2008, 5:22 am 
Offline

Joined: January 7th, 2007, 1:43 pm
Posts: 107
[VxE] wrote:
btw: I'm invoking
The Forums Index Page wrote:
...Post helpful tips and tricks.
to post this here. {also this is my 500th post.}

Well Done! :o :lol: :D :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 7th, 2008, 2:22 am 
Code:
Hotkey:: SetTimer, Label, % ((Bool := !Bool) ? (Number) : ("Off"))


I tried decrypting this

isn't this the same since Number as a var isnt filled ?

Code:
Hotkey:: SetTimer, Label, % ((Bool := !Bool) ? () : ("Off"))


Why use the word Bool, I can use for example just a n or any var right ?
Code:
Hotkey:: SetTimer, Label, % ((n := !n) ? () : ("Off"))



Decrypting the whole expression would be ?
Code:
;Hotkey:: SetTimer, Label, % ((Bool := !Bool) ? (Number) : ("Off"))

Hotkey::
{
If Bool := !Bool
SetTimer, Label, %Number&
else
SetTimer, Label, off
}
Return




Is this all correct ?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: October 7th, 2008, 2:42 am 
Offline

Joined: July 15th, 2007, 1:43 am
Posts: 1320
Code:
Hotkey::
SetTimer, Label, % !Bool ? Number : "Off"

_________________
Religion is false. >_>


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 7th, 2008, 9:30 am 
Offline
User avatar

Joined: October 7th, 2006, 8:45 am
Posts: 3330
Location: Simi Valley, CA
I wrote:
Code:
Hotkey:: SetTimer, Label, % ((Bool := !Bool) ? (Number) : ("Off"))

This isn't meant to be literal code. The words are meant to stand in place of their specified type or class, or variable containing same (the exceptions being "off" which is meant to be literal, and 'SetTimer', which is a command)

Hence, the expanded illustration (and fully working example) would be
Code:
; Hotkey:: SetTimer, Label, % ((Bool := !Bool) ? (Number) : ("Off"))

; using left-ctrl + a will do exactly the same thing as right-ctrl + a, despite using different code
>^a::SetTimer, Ctrl_A_Label, % (Ctrl_A_Toggle := !Ctrl_A_Toggle) ? 1000 : "off"

<^a:: ; this is a Hotkey
If (Ctrl_A_Toggle := !Ctrl_A_Toggle) ; use () to indicate an expression in which a variable is assigned the value of its boolean negation
   SetTimer, Ctrl_A_Label, 1000 ; '1000' is Number in this case, but it could just as easily be a %variable%
Else
   SetTimer, Ctrl_A_Label, Off
Return ; because a multi-line hotkey-subroutine needs this

Ctrl_A_Label: ; this is a label
Tooltip Update position once a second
return

_________________
Ternary (a ? b : c) guide     TSV Table Manipulation Library
Post code inside [code][/code] tags!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 5th, 2009, 2:45 pm 
Offline

Joined: August 21st, 2006, 7:07 pm
Posts: 2925
Location: The Shell
Great info that I had to bump. This thread is god mode!

Thanks

_________________
Imageparadigm.shift:=(•_•)┌П┐RTFM||^.*∞


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 5th, 2009, 8:59 pm 
Offline

Joined: August 13th, 2006, 6:45 am
Posts: 355
Location: Germany
If you write it in another form, I think it is very good readable. How many lines would the following example use with if/else?
Code:
   sub := (command1 = "#a") ? "add"
        : (command1 = "#b") ? "build"
        : (command1 = "#c") ? "change"
        : (command1 = "#d") ? "down"
        : (command1 = "#e") ? "unten"
        : (command1 = "#f") ? "find"
        : (command1 = "#i") ? "info"
        : (command1 = "#j") ? "join"
        : (command1 = "#k") ? "kill"
        : (command1 = "#l") ? "locate"
        : (command1 = "#m") ? "move"
        : (command1 = "#o") ? "output"
        : (command1 = "#p") ? "tabulator"
        : (command1 = "#q") ? "tasten"
        : (command1 = "#r") ? "restore"
        : (command1 = "#s") ? "substitute"
        : (command1 = "#t") ? "text"
        : (command1 = "#u") ? "up"
        : (command1 = "#w") ? "woerterbuch"
        : (command1 = "#x") ? "exit"
        : (command1 = "#z") ? "zeile"
        : (command1 = "#1") ? "oben"
        : (command1 = "#ß") ? "datein"
        : (command1 = "#<") ? "fragen"
        : (command1 = "#v") ? "listv"
        : (command1 = "#?") ? "debuggen"
        : "falsch"
   gosub %sub%


Hubert


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 28th, 2009, 4:09 am 
Offline
User avatar

Joined: March 19th, 2008, 12:43 am
Posts: 5482
Location: the tunnel(?=light)
Since I think this guide is highly underrated in its usefulness to many AHK'ers out there, I thought I'd post an example of using ternary from a script collaboration I'm working on. We're working on making a GUI with tabs but on only one of the tabs we want to be able to toggle the window size to create a pseudo-"rolled up" window effect.

In terms of "normal" AHK coding I'd need to write something like this to check which tab is active first then check the window's size to determine which state to toggle to:

Code:
if CurrentTab=1
{
  if GuiHeight=572
     WinMove, %WinTitle%, , , , , 278
  else
     WinMove, %WinTitle%, , , , , 572
}
else
  return


But ternary condenses the whole thing down to one line:

Code:
WinMove, %WinTitle%, , , , , % CurrentTab=1 ? (GuiHeight=572 ? 278 : 572) : ""

_________________
Image
Try Quick Search for Autohotkey or see the tutorial for newbies.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 62 posts ]  Go to page 1, 2, 3, 4, 5  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], BrandonHotkey, chaosad, Google Feedfetcher, specter333, Yahoo [Bot] and 41 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group