czardas Posted January 27, 2015 Share Posted January 27, 2015 (edited) In the following scenario I wish to run a sequence of tests until a satisfactory condition is met. Then the remaining tests are skipped. ; Local $bCondition = False Do ; test 1 If $bCondition Then ExitLoop ; test 2 If $bCondition Then ExitLoop ; Debug or get out of the script. Until True ; Loop will not repeat. ; continue... ; I could do the same thing in other ways but this is nice and clear: keeping everything in one place has certain merits. The problem I have is trying to convince myself that using a loop which never repeats (Do...Until True) actually qualifies as good programming. I keep asking myself why use a loop at all when it isn't really needed? Do you think I should do this differently, or should I leave it the way it is? Edited January 27, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Gianni Posted January 27, 2015 Share Posted January 27, 2015 (edited) The condition "true" will be met in just one pass I suppose. (and no need to repeat the test to check again if some condition has changed) so if the true condittion will not be met, you will be catch in an endless loop or you need an one further check at the end maybe you could use a (For ... next) loop instead of (Do...Until True) to avoid the last check.... ? For $i = 1 To 1 ; only one pass anyway ; test 1 If $bCondition Then ExitLoop ; test 2 If $bCondition Then ExitLoop Next ; continue... edit: corrected 0 to 1 with 1 to 1 Edited January 27, 2015 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
water Posted January 27, 2015 Share Posted January 27, 2015 If the loop is never repeated it is useless (IMHO). Why not simply remove it and add some comment lines to reach your goal: "nice and clear: keeping everything in one place" ; -------------- ; Test code starts here ; -------------- Local $bCondition = False ; test 1 If Not $bCondition Then Test1() ; test 2 If Not $bCondition Then Test2() ; -------------- ; End of Tests ; -------------- ; continue. 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 More sharing options...
czardas Posted January 27, 2015 Author Share Posted January 27, 2015 Chimp - Your loop For ($i = 0 To 1) will run twice. I modelled the approach on the expression While 1: being equivalent to While True. It appears to work in the same way. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted January 27, 2015 Author Share Posted January 27, 2015 (edited) If the loop is never repeated it is useless (IMHO). Why not simply remove it and add some comment lines to reach your goal: "nice and clear: keeping everything in one place" ; -------------- ; Test code starts here ; -------------- Local $bCondition = False ; test 1 If Not $bCondition Then Test1() ; test 2 If Not $bCondition Then Test2() ; -------------- ; End of Tests ; -------------- ; continue. Having to keep testing conditions will impact performance. The idea is to skip all subsequent tests and conditions. Edited January 27, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Gianni Posted January 27, 2015 Share Posted January 27, 2015 (edited) Chimp - Your loop For ($i = 0 To 1) will run twice. I modelled the approach on the expression While 1: being equivalent to While True. It appears to work in the same way. .... I was editing my post while you was typing..... anyway, (for next) should avoid possible endless loops.... Edited January 27, 2015 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
water Posted January 27, 2015 Share Posted January 27, 2015 How many tests do you run? In your OP you are testing the condition as well. Maybe not as often as in my code but such a test doesn't increase runtime dramatically. 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 More sharing options...
czardas Posted January 27, 2015 Author Share Posted January 27, 2015 Hmm, conditions are sometimes inside other loops. Here's a snapshot. ; Do ; First attempt to divide by factors of 10 While StringRight($aSciNotation[$iLo][0], 1) = "0" $aSciNotation[$iLo][0] = Execute(StringTrimRight($aSciNotation[$iLo][0], 1)) $aSciNotation[$iHi][1] -= 1 If $aSciNotation[$iHi][1] = 0 Then ExitLoop 2 ; no need to go any further WEnd ; More loops and conditions. Until True operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
water Posted January 27, 2015 Share Posted January 27, 2015 Then I would stick with your current approach. Seems to be the best way to do what you want. czardas 1 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 More sharing options...
czardas Posted January 27, 2015 Author Share Posted January 27, 2015 (edited) Thanks water. I suppose the more standard approach would be to remove this part of the code to a different function and return according to whatever condition. I could still do that, but I think it might make it harder to follow the flow of arguments. Keeping everything in one place also avoids having to pass a number of parameters to a different function. I asked because I was wondering what opinions people might have. Edited January 27, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
water Posted January 27, 2015 Share Posted January 27, 2015 When I start a new project my code should be as clean as possible (means: adhere to good coding practices. A good starting point is the "Good Coding Practices" thread on the forum). Over time the code gets more complex as new functionality gets implemented. The script should be so well documented that you still understand what you have intented with your code even when you have a look at it again a few years later. czardas 1 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 More sharing options...
TheSaint Posted January 27, 2015 Share Posted January 27, 2015 Is it not feasible to just use Else and Return? Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
JohnOne Posted January 27, 2015 Share Posted January 27, 2015 (edited) You might consider recursion. _Test () Func _Test() ConsoleWrite("Test condition" & @LF) ;if test is not zero If Random(0, 10, 1) Then Sleep(10) _Test() EndIf _Continue() EndFunc Func _Continue() ConsoleWrite("Condition met" & @LF) Exit EndFunc EDIT: I don't know if this is pertinent or just stupid, but you could also unwind the recursion, but that ironically requires a loop _Test () Func _Test() ConsoleWrite("Test condition" & @LF) Local Static $Unwind = 0 ;if test is not zero If Random(0, 10, 1) Then $Unwind += 1 Sleep(10) _Test() EndIf While $Unwind ConsoleWrite("Unwind" & @LF) $Unwind -= 1 Return WEnd _Continue() EndFunc Func _Continue() ConsoleWrite("Condition met" & @LF) Exit EndFunc Edited January 27, 2015 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
czardas Posted January 27, 2015 Author Share Posted January 27, 2015 (edited) Is it not feasible to just use Else and Return? Using Return would exit the function, and not the contained region. You might consider recursion. Nope! I don't see how that is useful here. It's unfinished code, but here's a bit more of it. I am using ExitLoop() to skip forward however many steps (notice the aborted attempt). ; Do ; Some preprocessing goes here If StringLen($aSciNotation[$iHi][0]) + $aSciNotation[$iHi][1] <= 15 Then ExitLoop ; no need to go any further ; First attempt to divide by factors of 10 While StringRight($aSciNotation[$iLo][0], 1) = "0" $aSciNotation[$iLo][0] = Execute(StringTrimRight($aSciNotation[$iLo][0], 1)) $aSciNotation[$iHi][1] -= 1 If $aSciNotation[$iHi][1] = 0 Then ExitLoop 2 ; no need to go any further WEnd ; Attempt division by factors of 5, followed by factors of 2. Local $iExpansion, $aFactor[2] = [5, 2] For $i = 0 To 1 While Mod($aSciNotation[$iLo][0], $aFactor[$i]) = 0 ; Integer division is possible. $iExpansion = Int($aSciNotation[$iHi][0] * $aFactor[1 - $i]) If $iExpansion >= 1.0e+15 Then ExitLoop ; Abort the current attempt. $aSciNotation[$iHi][0] = $iExpansion $aSciNotation[$iLo][0] = Int($aSciNotation[$iLo][0] / $aFactor[$i]) $aSciNotation[$iHi][1] -= 1 If $aSciNotation[$iHi][1] = 0 Then ExitLoop 3 ; no need to go any further WEnd Next ; More attempts to achieve the desired result. Until True ; Code continues inside the function. Edited January 27, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
guinness Posted January 27, 2015 Share Posted January 27, 2015 I guess this is a little bit more readable than nested if statements, which most would do I guess (including me). I have seen your approach in the Crypt UDF by the way. Is it better? Actually I don't know if anything is wrong with it. I am stumped. UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
willichan Posted January 27, 2015 Share Posted January 27, 2015 The benefits of a GOTO statement without using a GOTO statement. I find it very clever. czardas 1 My UDFs: Barcode Libraries, Automate creation of any type of project folder, File Locking with Cooperative Semaphores, Inline binary files, Continue script after reboot, WinWaitMulti, Name Aggregator, Enigma, CornedBeef Hash Link to comment Share on other sites More sharing options...
Solution Bowmore Posted January 27, 2015 Solution Share Posted January 27, 2015 (edited) I write lots of data validation routines that run several hundred validation checks on each row of data and I use the same sort of structure as sown in your first post. The alternative would be a ridiculous set of nested IFs or ElseIfs. The loop that never loops in combination with If False Then ExitLoop statements is my opinion an elegant way to implement this for the following reasons: It is clear to read and understand. It is easy to add additional tests The order of the tests is easy to change It can be optimised by putting the tests most likely to fail at the top. Edited January 27, 2015 by Bowmore czardas 1 "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook Link to comment Share on other sites More sharing options...
czardas Posted January 27, 2015 Author Share Posted January 27, 2015 (edited) Bowmore - Indeed there are some benefits to using a construct like this. My code posted above will require some optimization later. Tests need to be run for fine tuning etc... Working this way is easy. Chimp - There's hardly any difference using a For loop. In fact the way I am doing this does not require the comparison of an incremented loop iteration count. Thanks for all your responces. I would like to mark this solved, but there are a number of best answers here. I'll just pick one. Edited January 28, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
JohnOne Posted January 28, 2015 Share Posted January 28, 2015 (edited) I finally read the topic correctly,.I suppose I can see why this approach might suit some folk. Personally I think Functions are as modular as I need. Depending how much code was in the tests, I might find it more difficult to follow. Edited January 28, 2015 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
czardas Posted January 28, 2015 Author Share Posted January 28, 2015 (edited) If the code did not sit so well, I would normally call another function. There are several other variables involved in the following part of the loop including an extended return value for the current function. Since the data is manipulated in various ways in an attempt to achive a single objective - the code belongs together in one place. Passing lots of ByRef parameters is the alternative. Edited January 28, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now