Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 06/14/2024 in all areas

  1. This is how windows standard works! The WorkDir is the active directory at the time you start the program. You can easily change that in the script if so desired, just look at the helpfile FileChangeDir() to set the required Workdir in the script. When you like to change it to the ScriptDirectory, just use: FileChangeDir(@ScriptDir)
    1 point
  2. @ioa747 thanks for the speed test between Map and Scripting.Dictionary What about we try the tests on larger arrays ? Below is your reworked speed test. Now we can define the number of rows in each array with this line : Local $iRows = 50 ; after this 1st test, try other values for $iRow, like 5000, then 10000, 20000... The 2 arrays generated for each test will be exactly the same (because of the SRandom instruction, for example 4 for the 1st array, 5 for the 2nd array) Could you please run this reworked script, first with the indicated value (50, it will ConsoleWrite the results, just for checking) . Then re-run it with $iRows = 5000, 10000... (no more ConsoleWrite of values in these cases, just the timer difference) Does the Map part is still quicker than the Scripting.Dictionary part, when the arrays grow bigger ? Thanks ; AutoIt 3.3.16.1 (Map) ; Comparing speed between Map and Scripting.Dictionary #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <Array.au3> Local $iRows = 50 ; after this 1st test, try other values for $iRow, like 5000, then 10000, 20000... ConsoleWrite("$iRows = " & $iRows & @crlf & @crlf) ; I do 3 laps to compare For $i = 1 To 3 ConsoleWrite("- Round " & $i & " -----------------" & @CRLF) FuncSpeedTest('_Dictionary($iRows)') FuncSpeedTest('_Map($iRows)') Next ;-------------------------------------------------------------------------------------------------------------------------------- Func _Map($iRows) Local $a[$iRows], $b[$iRows] GenerateArrayInt($a, $iRows, 4) ; seed value for random number generation (to generate exactly the same array for each test) GenerateArrayInt($b, $iRows, 5) ; ditto Local $mda[] Local $mdb[] Local $mdc[] For $i In $a $mda[$i] = $i ; unique keys ; $mda[$i] = Null ; no need to associate a value to each unique key (to match the script dictionary test) Next ; _ArrayDisplay(_Map2D($mda), "$mda : Map Keys & Values") ; comment out this line during tests ! For $i In $b $mdb[$i] = $i ; unique keys Next Local $ada = MapKeys($mda) For $vKey In $ada If MapExists($mdb, $vKey) Then $mdc[$vKey] = $vKey MapRemove($mda, $vKey) MapRemove($mdb, $vKey) EndIf Next Local $asd1 = MapKeys($mda) Local $asd2 = MapKeys($mdb) Local $asd3 = MapKeys($mdc) If $iRows <= 50 Then _Print($asd1, "$asd1") If $iRows <= 50 Then _Print($asd2, "$asd2") If $iRows <= 50 Then _Print($asd3, "$asd3") EndFunc ;==>_Map ;-------------------------------------------------------------------------------------------------------------------------------- Func _Dictionary($iRows) Local $a[$iRows], $b[$iRows] GenerateArrayInt($a, $iRows, 4) ; seed value for random number generation (to generate exactly the same array for each test) GenerateArrayInt($b, $iRows, 5) ; ditto Local $sda = ObjCreate("Scripting.Dictionary") Local $sdb = ObjCreate("Scripting.Dictionary") Local $sdc = ObjCreate("Scripting.Dictionary") For $i In $a $sda.Item($i) ; unique keys Next For $i In $b $sdb.Item($i) ; unique keys Next For $i In $sda If $sdb.Exists($i) Then $sdc.Item($i) $sda.Remove($i) $sdb.Remove($i) EndIf Next Local $asd1 = $sda.Keys() Local $asd2 = $sdb.Keys() Local $asd3 = $sdc.Keys() If $iRows <= 50 Then _Print($asd1, "$asd1") If $iRows <= 50 Then _Print($asd2, "$asd2") If $iRows <= 50 Then _Print($asd3, "$asd3") EndFunc ;==>_Dictionary ;-------------------------------------------------------------------------------------------------------------------------------- Func _Print(ByRef $aArray, $sTitle) Local $sTxt = "" For $i = 0 To UBound($aArray) - 1 $sTxt &= $aArray[$i] & ", " Next $sTxt = StringTrimRight($sTxt, 2) ConsoleWrite($sTitle & ": " & $sTxt & @CRLF) EndFunc ;==>_Print ;-------------------------------------------------------------------------------------------------------------------------------- Func FuncSpeedTest($sExecute) Local $hTimer = TimerInit() Execute($sExecute) ConsoleWrite($sExecute & " processed in: " & TimerDiff($hTimer) & " ms " & @LF & @LF) EndFunc ;==>FuncSpeedTest ;-------------------------------------------------------------------------------------------------------------------------------- Func GenerateArrayInt(ByRef $aArray, $iRows, $iSeed) SRandom($iSeed) For $i = 0 To $iRows - 1 $aArray[$i] = Random(0, $iRows, 1) ; 1 to return integer values Next EndFunc ;==>GenerateArrayInt ;-------------------------------------------------------------------------------------------------------------------------------- Func _Map2D(Const ByRef $mMap) Local $aMapKeys = MapKeys($mMap) Local $aMap2D[Ubound($aMapKeys)][2] Local $iRow = - 1 For $vKey In $aMapKeys $iRow += 1 ; 0+ $aMap2D[$iRow][0] = $vKey $aMap2D[$iRow][1] = $mMap[$vKey] Next Return $aMap2D EndFunc ;==>_Map2D ;--------------------------------------------------------------------------------------------------------------------------------
    1 point
  3. Hello everybody I'm a total newbie to Maps in AutoIt. Instead, I used a few times the similar Scripting.Dictionary object (which is damn fast) . Maybe the advantage of Maps could be that, if one day MS removes the Scripting.Dictionary object (I doubt it but who knows...) then we'll be happy that Maps exist in recent versions of AutoIt. Anyway, I just started to learn Maps and needed to display at same time the Keys & their corresponding Values. So I scripted this simple reusable function which seems to do the job and is called by one line : _ArrayDisplay(_Map2D($mMap), "Map Keys & Values") Here is the functional example corresponding to the pic : ; AutoIt 3.3.16.1 (Map) #include <Array.au3> local $mMap[] $mMap["Beethoven"] = "Bee" $mMap["Berlioz"] = "Ber" $mMap["Chopin"] = Null ; create a key "Chopin" without assigning it a value _ArrayDisplay(_Map2D($mMap), "Map Keys & Values") Func _Map2D(Const ByRef $mMap) Local $aMapKeys = MapKeys($mMap) Local $aMap2D[Ubound($aMapKeys)][2] Local $iRow = - 1 For $vKey In $aMapKeys ; or a simple For... loop as commented out below $iRow += 1 ; 0+ $aMap2D[$iRow][0] = $vKey $aMap2D[$iRow][1] = $mMap[$vKey] Next ;~ For $i = 0 To Ubound($aMapKeys) - 1 ;~ $aMap2D[$i][0] = $aMapKeys[$i] ;~ $aMap2D[$i][1] = $mMap[$aMapKeys[$i]] ;~ Next Return $aMap2D EndFunc I just tested it on 10.000 pairs of key/values created by using the code below and the return from the function was immediate : For $i = 0 To 9999 $mMap[$i] = $i + 10 Next If you guys got some improvements for the function, please share them here, thanks.
    1 point
  4. pixelsearch following and exploring your latest posts prompts me to share the results ; https://www.autoitscript.com/forum/topic/164728-compare-2-arrays-with-3-arrays-as-a-result/?do=findComment&comment=1534659 #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <Array.au3> ; I do 3 laps to compare For $i = 1 To 3 ConsoleWrite("- Round " & $i & " -----------------" & @CRLF) FuncSpeedTest('_Dictionary()') FuncSpeedTest('_Map()') Next ;-------------------------------------------------------------------------------------------------------------------------------- Func _Map() Local $a[11] = [1, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12] ; some duplicate values (1 found twice) Local $b[12] = [1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 13, 14] ; some duplicate values (2 found twice) Local $mda[] Local $mdb[] Local $mdc[] For $i In $a $mda[$i] = $i ; unique keys Next For $i In $b $mdb[$i] = $i ; unique keys Next Local $ada = MapKeys($mda) For $vKey In $ada If MapExists($mdb, $vKey) Then $mdc[$vKey] = $vKey MapRemove($mda, $vKey) MapRemove($mdb, $vKey) EndIf Next Local $asd1 = MapKeys($mda) Local $asd2 = MapKeys($mdb) Local $asd3 = MapKeys($mdc) _Print($asd1, "$asd1") _Print($asd2, "$asd2") _Print($asd3, "$asd3") EndFunc ;==>_Map ;-------------------------------------------------------------------------------------------------------------------------------- Func _Dictionary() Local $a[11] = [1, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12] ; some duplicate values (1 found twice) Local $b[12] = [1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 13, 14] ; some duplicate values (2 found twice) Local $sda = ObjCreate("Scripting.Dictionary") Local $sdb = ObjCreate("Scripting.Dictionary") Local $sdc = ObjCreate("Scripting.Dictionary") For $i In $a $sda.Item($i) ; unique keys Next For $i In $b $sdb.Item($i) ; unique keys Next For $i In $sda If $sdb.Exists($i) Then $sdc.Item($i) $sda.Remove($i) $sdb.Remove($i) EndIf Next Local $asd1 = $sda.Keys() Local $asd2 = $sdb.Keys() Local $asd3 = $sdc.Keys() _Print($asd1, "$asd1") _Print($asd2, "$asd2") _Print($asd3, "$asd3") EndFunc ;==>_Dictionary ;-------------------------------------------------------------------------------------------------------------------------------- Func _Print(ByRef $aArray, $sTitle) Local $sTxt = "" For $i = 0 To UBound($aArray) - 1 $sTxt &= $aArray[$i] & ", " Next $sTxt = StringTrimRight($sTxt, 2) ConsoleWrite($sTitle & ": " & $sTxt & @CRLF) EndFunc ;==>_Print ;-------------------------------------------------------------------------------------------------------------------------------- Func FuncSpeedTest($sExecute) Local $hTimer = TimerInit() Execute($sExecute) ConsoleWrite($sExecute & " processed in: " & TimerDiff($hTimer) & " ms " & @LF & @LF) EndFunc ;==>FuncSpeedTest ;-------------------------------------------------------------------------------------------------------------------------------- if I did it right and I'm not missing anything, the difference was quite significant (considering that the sample is quite small)
    1 point
  5. First, this is awesome! I don't use AutoIt much anymore, but I appreciate being able to use VS Code as a multipurpose tool now. I have a few suggestions and questions... Can the output be colorized like in SciTE? Previously all of my debug messages were green if they started with +, red with !, and yellow with... I never used yellow. Can the file links in the output jump to specific lines/characters in the file? With SciTE, you could use this: "full/path/to/file.au3" (Line, Char) What do you think about folding multiple lines of single-line-comments? I like adding documentation and this is usually through multi-line comments, mimicking what UDF functions use It looks like #include <Filename.au3> doesn't search like #include "Filename.au3" does. Per the help docs, both can be used, but the search order is reversed And this is probably out of scope of this extension, but... is there any way to collapse all collapsible sections in VS Code? In VS I use Output/Collapse to Definitions all the time, but there doesn't seem to be an equivalent in VS Code
    1 point
  6. Norm73, glad you found a solution for your need I never saw this old thread before today, so I studied just now mikell's good solution (based on Scripting Dictionary) It seems to me that mikell's script can be improved, by the use of 3 loops instead of 4, with the same result, like this : #include <Array.au3> Local $a[11] = [1, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12] ; some duplicate values (1 found twice) Local $b[12] = [1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 13, 14] ; some duplicate values (2 found twice) Local $sda = ObjCreate("Scripting.Dictionary") Local $sdb = ObjCreate("Scripting.Dictionary") Local $sdc = ObjCreate("Scripting.Dictionary") For $i In $a $sda.Item($i) ; unique keys Next For $i In $b $sdb.Item($i) ; unique keys Next For $i In $sda If $sdb.Exists($i) Then $sdc.Item($i) $sda.Remove($i) $sdb.Remove($i) EndIf Next $asd1 = $sda.Keys() $asd2 = $sdb.Keys() $asd3 = $sdc.Keys() _ArrayDisplay($asd1, "$asd1") ; 7, 9, 11 _ArrayDisplay($asd2, "$asd2") ; 2, 4, 13, 14 _ArrayDisplay($asd3, "$asd3") ; 1, 3, 5, 6, 8, 10, 12 Another thing we could think about is : should the 3rd loop be... For $i In $sda ; or For $i In $sdb ...I think it depends on the number of elements in each dictionary. In our case they're nearly the same so it doesn't matter which one you'll choose, but imagine one dictionary got only 3 elements and the second dictionary got 10000 elements, then it seems quicker to execute the For...In loop 3 times (by using the shorter dictionary), instead of looping 10000 times by choosing the longer dictionary. Anyway, results will be same, no matter the dictionary you choose in the 3rd For...In loop If you guys think something is wrong in this reworked script, please be kind to indicate it, thanks.
    1 point
  7. Briefly to understand: The map $mMap is to be read from a file in its nested structure and then written again with the corresponding changes? If yes: The term for this is serialize/deserialize. Basically, you are completely free to do this. You can write something of your own for the special structure. However, it is easier to use the corresponding ones. You have already mentioned one of these: >>JSON<< That would be very suitable for this. Basically, you only need one call to fill $mMap from a file and only one call to write the file again. That should also answer your question: You don't need to worry about the structure of the JSON file. It is automatically structured according to the structure of your nested AutoIt map. JSON is a text format. If you prefer a binary format that produces smaller files, you can also take a look at >>CBOR<<. The operation is basically exactly the same as in the case of JSON: One call to serialize the map into a file and one to read it back from the file. Let me give you a basic example of how this would work in your case with CBOR: #include "CBOR.au3" ; initial data if not exists already If not FileExists("myData.bin") Then Local $mMap[] Local $mPerson[] $mPerson["no"] = 42; $mPerson["first"] = "Jerry" $mPerson["name"] = "Mouse" $mMap[42] = $mPerson $mPerson["no"] = 43; $mPerson["first"] = "Tom" $mPerson["name"] = "Cat" $mMap[43] = $mPerson ; save $mMap in file FileDelete("myData.bin") FileWrite("myData.bin", _cbor_encode($mMap)) EndIf ; --------- read data from file --------------- Local $mMap = _cbor_decode(FileRead("myData.bin")) ; -------- add data (example for changing data) ------------------- Local $mPerson[] $mPerson["no"] = 44; $mPerson["first"] = "Bucks" $mPerson["name"] = "Bunny" $mMap[44] = $mPerson ; ------- save the new $mMap into file ---------- FileDelete("myData.bin") FileWrite("myData.bin", _cbor_encode($mMap)) ; ------- The next time the program is called, $mMap contains the updated data ---------- ; print the data to see if ok For $no In MapKeys($mMap) ConsoleWrite($no & @CRlF) $mP = $mMap[$no] For $key in MapKeys($mP) ConsoleWrite(@TAB & $key & ": " & $mP[$key] & @CRLF) Next Next And for JSON, the process is basically almost the same: #include "JSON.au3" ; initial data if not exists already If not FileExists("myData.json") Then Local $mMap[] Local $mPerson[] $mPerson["no"] = "42"; $mPerson["first"] = "Jerry" $mPerson["name"] = "Mouse" $mMap["42"] = $mPerson $mPerson["no"] = 43; $mPerson["first"] = "Tom" $mPerson["name"] = "Cat" $mMap["43"] = $mPerson ; save $mMap in file FileWrite("myData.json", _JSON_GenerateCompact($mMap)) EndIf ; --------- read data from file --------------- Local $sFile = FileRead("myData.json") Local $mMap = _JSON_Parse($sFile) ; -------- add data (example for changing data) ------------------- Local $mPerson[] $mPerson["no"] = 44; $mPerson["first"] = "Bucks" $mPerson["name"] = "Bunny" $mMap["44"] = $mPerson ; ------- save the new $mMap into file ---------- FileDelete("myData.json") FileWrite("myData.json", _JSON_GenerateCompact($mMap)) ; ------- The next time the program is called, $mMap contains the updated data ---------- ; print the data to see if ok For $no In MapKeys($mMap) ConsoleWrite($no & @CRlF) $mP = $mMap[$no] For $key in MapKeys($mP) ConsoleWrite(@TAB & $key & ": " & $mP[$key] & @CRLF) Next Next
    1 point
  8. Hello MazeM, Thank you for your contribution! I've discovered a couple of issues with ComUDF at the moment: 1) The following code fails to properly recognize 2 and 3-digit COM ports on both 1x Win7 64-bit PC and 5x Win10 64-bit laptops. Anything past the first digit is simply ignored (odd because the code seems fine to me...). ;extract $comPort from $defs $comPort = StringLeft($def, 4) ;"com1".."com9" (com plus 1st digit) If IsNumber(StringMid($def, 5)) Then ;"com10".."com99" (2nd digit) $comPort &= StringMid($def, 5) If IsNumber(StringMid($def, 6)) Then ;"com100".."com256" (3rd digit) $comPort &= StringMid($def, 6) EndIf EndIf 2) Windows uses UNC paths for anything above COM9 (https://support.microsoft.com/en-us/help/115831/howto-specify-serial-ports-larger-than-com9), so any 2 and 3-digit strings generated by the code above would be invalid. It is recommended to append "\\.\" to every COM port number. Fortunately, the following code was tested on the above systems and will remedy the issues above completely by a) utilizing StringIsDigit/StringTrimLeft instead of IsNumber/StringMid and appending a prefix of "\\.\" to any COM port between 1 and 256. ;extract $comPort from $defs $comPort = "\\.\" & StringLeft($def, 4) ;"com1".."com9" (com plus 1st digit) If StringIsDigit(StringLeft(StringTrimLeft($def, 4), 1)) Then ;"com10".."com99" (2nd digit) $comPort &= StringLeft(StringTrimLeft($def, 4), 1) If StringIsDigit(StringLeft(StringTrimLeft($def, 5), 1)) Then ;"com100".."com256" (3rd digit) $comPort &= StringLeft(StringTrimLeft($def, 5), 1) EndIf EndIf itagashu
    1 point
×
×
  • Create New...