Jump to content

Recommended Posts

Posted (edited)

Easy to do, but it seems to me that this should be a built-in function  -- unless I'm missing something, somewhere....

Updated: UDF _PathSplit returns extension with "." prepended. Why? Extension is a string, "." just happens to be to be the separator, and it forces StringTrimLeft($extension, 1) for no good reason (IMO).

 

#include <File.au3>

Global $sDr, $sPa, $sFn, $sEx
$sFileFullPath = "d:\path\blah blah blah.foo foo.bar bar.extension"
Exit MsgBox( 0, "", _PathSplit($sFileFullPath , $sDr, $sPa, $sFn, $sEx)[4] )

Original function (less expensive??):

Func _FileGetExt($sFn)
; Parse EXTension from [d:\path\]filename.EXTension
    Local $sExt = "", $aA
    If StringInStr($sFn, ".") Then
        If Not StringInStr(FileGetAttrib($sFn), "D") Then
            $aA = StringSplit($sFn, ".")
            $sExt = $aA[$aA[0]]
        EndIf
    EndIf
    Return $sExt
EndFunc  ;==>_FileGetExt

 

Edited by CarlD
Update (thanks to TheDCoder :-))
  • 1 month later...
Posted (edited)

Func _ConsoleEraseLine() is for compiled CUI scripts. It allows successive one-line console outputs to be printed to a single line on the screen (by overwriting the previous line). Output lines must NOT end in @LF.

Compile the code, then command EraseLineDemo.exe.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=EraseLineDemo.exe
#AutoIt3Wrapper_UseUpx=y
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Run_Au3Stripper=y
#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
;
; CLD rev.10/31/2021

Global $vLine1 = "The quick brown fox jumped over the lazy dog."
Global $vLine2 = 9999999
Global $vLine3 = 0000001
Global $vLine4 = "0000001"
Global $vLine5 = 3.1416
Global $vLine6 = -9999999
Global $vLine7 = -0000001
Global $vLine8 = "-0000001"
Global $vLine9 = -03.1416
Global $vLine10 = "-03.1416"
Global $vLine11 = True

ConsoleWrite($vLine1)
Sleep(2000)
_ConsoleEraseLine($vLine1)
ConsoleWrite($vLine2)
Sleep(2000)
_ConsoleEraseLine($vLine2)
ConsoleWrite($vLine3)
Sleep(2000)
_ConsoleEraseLine($vLine3)
ConsoleWrite($vLine4)
Sleep(2000)
_ConsoleEraseLine($vLine4)
ConsoleWrite($vLine5)
Sleep(2000)
_ConsoleEraseLine($vLine5)
ConsoleWrite($vLine6)
Sleep(2000)
_ConsoleEraseLine($vLine6)
ConsoleWrite($vLine7)
Sleep(2000)
_ConsoleEraseLine($vLine7)
ConsoleWrite($vLine8)
Sleep(2000)
_ConsoleEraseLine($vLine8)
ConsoleWrite($vLine9)
Sleep(2000)
_ConsoleEraseLine($vLine9)
ConsoleWrite($vLine10)
Sleep(2000)
_ConsoleEraseLine($vLine10)
ConsoleWrite($vLine11)
Sleep(2000)
_ConsoleEraseLine($vLine11)

Exit ConsoleWrite("Done!" & @LF)

Func _ConsoleEraseLine($vIn)
; Erase one line (only) from console output (DOS only, not SciTE)
; $vIn = Line_to_Erase
; Does NOT work if line ends with @LF !!
    If StringRight($vIn, 1) = @LF Then Return
    Local $sOut = ""
    For $i = 1 To StringLen($vIn)
        $sOut &= Chr(8) & " " & Chr(8)
    Next
    ConsoleWrite($sOut)
EndFunc  ;==>_ConsoleEraseLine

 

 

Edited by CarlD
Update
Posted (edited)
18 hours ago, JockoDundee said:

@CarlD, yes but what happens if the string to write and erase is also a valid integer, say 999999999 or 000001 ?

@JockoDundee, Yes, I don't think it makes a difference. Once I removed the erroneous IsInt() test, if If you feed an integer like 000001 to ConsoleWrite, it evaluates it (to "1") before writing it to the screen. If you want the output to actually be "000001" it has to be quoted as a string. _ConsoleEraseLine now behaves the same way, so it will (or should) erase whatever ConsoleWrite outputs. Try the updated code in the original snippet -- as modified to respond to your comment -- and see if it works for you.

Edited by CarlD
Eating crow
Posted
28 minutes ago, CarlD said:

Try the updated code in the original snippet and see if it works for you.

I think it would work now.

However, my objection was due to the IsInt() statement in your original code:

9DF65139-771D-4486-9451-D591DCEF2D37.thumb.png.e47401366ae5a604cc293cf68adcd429.png

a line which no longer exists in the refactored code.

What was that line supposed to do?

Code hard, but don’t hard code...

Posted
4 hours ago, JockoDundee said:

I think it would work now.

However, my objection was due to the IsInt() statement in your original code:

9DF65139-771D-4486-9451-D591DCEF2D37.thumb.png.e47401366ae5a604cc293cf68adcd429.png

a line which no longer exists in the refactored code.

What was that line supposed to do?

It was supposed to allow inputting either the string itself or an integer representing the length of the string to overwrite -- but as you pointed out, what if the "string" was itself an integer? So I was wrong to say in my last message that "it doesn't make a difference". I'd conveniently forgotten that I modified my code to respond to your comment, and then pretended that there was nothing to your comment in the first place. 😏 Thank you for setting me straight. 😁

  • 5 months later...
Posted

_StringCapitalize() - version 1.0

I like _StringProper, but it has some unwanted effects, like capitalizing the letter s after an apostrophe (ex: cat's = Cat'S) or letters after other symbols. Also, _StringProper changes all letters after the first to lowercase. With this code, it only capitalizes the first letter and leaves the rest alone. If you use the exceptions option ($text4 example), it makes email addresses all lowercase and deals with names that begin with mc (like McDonald). Lastly, you have the ability to override the default symbols that the script will capitalize afterwards (space, period, comma, brace, bracket, etc.).

When you run the example, you will see the difference between _StringProper and _StringCapitalize (standard and with exceptions). It's not perfect (yet), but it's closer to what I want than _StringProper.

Usage:

_StringCapitalize ( string,  [, exceptions= 0  [, symbols="[.| |,|/(|/[|-]"  ] ] )

Parameters:

string

string passed to function

exceptions       

[optional] Default = 0
0 = do not use exceptions
1 = use exceptions

symbols [optional] define symbols for function to use

 

#include <String.au3>
#include <Array.au3>

$text1 = "mcdonald's AshtonK Ke$ha #trending @realcelebrity (etc) TEST@MSN.NET"
$text2 = _StringProper($text1)
$text3 = _StringCapitalize($text1)
$text4 = _StringCapitalize($text1, 1) ; 1 = use email and "mc" exceptions
$text5 = _StringCapitalize($text1, 1, "[.| |,|/[|-|#|@|*]") ; user defined symbols - script will capitalize next letter after these symbols.

MsgBox(0, "", "Original Text:" & @CRLF & $text1 & @CRLF & @CRLF & "_StringProper:" & @CRLF & $text2 & @CRLF & @CRLF & "_StringCapitalize:" & @CRLF & $text3 & @CRLF & @CRLF & "_StringCapitalize with exceptions:" & @CRLF & $text4 & @CRLF & @CRLF & "_StringCapitalize with exceptions and user specified symbols:" & @CRLF & $text5)


Func _StringCapitalize($__sText, $__iExceptions = 0, $__sSymbols = "[.| |,|/(|/[|-]")   ; version 1.0
    $__aText = StringSplit($__sText, "")
    For $i = 1 To $__aText[0]
        If $i = 1 OR StringRegExp($__aText[$i-1], $__sSymbols) = 1 Then
            $__aText[$i] = StringUpper($__aText[$i])
        EndIf
    Next
    $__textOut = _ArrayToString($__aText, "", 1)
    If $__iExceptions = 1 Then
        ; Lowercase all email addresses
        $__aExpression = StringRegExp($__textOut, "[\w]+@[\w]+\.+[\w]+", 3)
        For $i = 1 To UBound($__aExpression)
            $__textOut = StringReplace($__textOut, $__aExpression[$i - 1], StringLower($__aExpression[$i - 1]))
        Next
        $__aExpression = "" ; reset variable
        ; Format words beginning with mc. Ex: mcdonald = McDonald
        $__aExpression = StringRegExp($__textOut, "([Mm][Cc][A-Za-z])", 3)
        For $i = 1 To UBound($__aExpression)
            $__textOut = StringReplace($__textOut, $__aExpression[$i - 1], "Mc" & StringUpper(StringRight($__aExpression[$i - 1], 1)))
        Next
    EndIf
    Return $__textOut
EndFunc

 

  • 3 months later...
Posted (edited)

_ArraySafeDelim() - Returns a usable delimiter that is not in the array. Could probably be expanded to use Unicode but I CBA to filter symbols from letters for the entire unicode range. You could technically use letters as a delim but eh, maybe as a flag.
 

Func _ArraySafeDelim($aArray)
    
    $sChars = _ArrayToString($aArray, "")
    
    Select
        
        Case Not StringInStr($sChars, "|")
            Return "|"
        Case Else
            For $iLoop = 33 To 191 Step 1
                Switch $iLoop
                    Case 48 to 57 ; Skip Numbers
                        ContinueLoop
                    Case 65 to 90 ; Skip Upper Case
                        ContinueLoop
                    Case 97 to 122 ; Skip Lower Case
                        ContinueLoop
                    Case Else
                        If Not StringInStr($sChars, Chr($iLoop)) Then Return Chr($iLoop)
                EndSwitch
            Next
            
    EndSelect

    ; If No Char Found, Error
    Return SetError(1, 0, False)

EndFunc
Edited by rcmaehl

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

My Projects

WhyNotWin11
Cisco FinesseGithubIRC UDFWindowEx UDF

 

  • 3 weeks later...
Posted

Here are 2 ways to move a ridiculous amount of GUI controls at once. This could easily be extended to resize at the same time.

;stop window from redrawing, set control positions, allow and redraw the window
Func _CtrlsSetPos($hGUI, ByRef $aCtrls, $offsetX = 0, $offsetY = 0)
    Local $aCurrentPos
    _SendMessage($hGUI, $WM_SETREDRAW, False)

    For $i = 0 To UBound($aCtrls) - 1
        $aCurrentPos = ControlGetPos(GUICtrlGetHandle($aCtrls[$i]), "", 0)
        GUICtrlSetPos($aCtrls[$i], $aCurrentPos[0] + $offsetX, $aCurrentPos[1] + $offsetY)
    Next

    _SendMessage($hGUI, $WM_SETREDRAW, True)
    _WinAPI_RedrawWindow($hGUI)
EndFunc   ;==>_CtrlsSetPos

 

;move many GUI controls at the same time using Windows' DeferWindowPos structure
Func _DeferWindowPos(ByRef $aCtrls, $offsetX = 0, $offsetY = 0)
    Local $aCurrentPos
    Local $hDeferWindowPos = _WinAPI_BeginDeferWindowPos(UBound($aCtrls))
    For $i = 0 To UBound($aCtrls) - 1
        $aCurrentPos = ControlGetPos(GUICtrlGetHandle($aCtrls[$i]), "", 0)
        _WinAPI_DeferWindowPos($hDeferWindowPos, GUICtrlGetHandle($aCtrls[$i]), Null, $aCurrentPos[0] + $offsetX, $aCurrentPos[1] + $offsetY, 0, 0, $SWP_NOZORDER + $SWP_NOSIZE)
    Next
    _WinAPI_EndDeferWindowPos($hDeferWindowPos)
EndFunc   ;==>_DeferWindowPos

 

  • 4 weeks later...
Posted (edited)

Hello, I have written a small UDF containing some Python string functions for AutoIt, because I know it can be useful to many.

 

; misc string functions
; by Mateo C
; #FUNCTION# ====================================================================================================================
; Name ..........: _String_startsWhit
; Description ...: Checks if the string starts with a specific criteria, similar to the function in Python.
; Syntax ........: _String_startsWhit($sString, $sStart)
; Parameters ....: $sString             - The string to be examined.
;                  $sStart              - A value (string) to check.
; Return values .: True if the string starts with that value; otherwise, return false. If $sString is not a string, return @error.
; Author ........: Mateo Cedillo
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _String_startsWhit($sString, $sStart)
    If Not IsString($sString) Then Return SetError(1, 0, "")
    Return $sStart = StringLeft($sString, 1)
EndFunc   ;==>_String_startsWhit
; #FUNCTION# ====================================================================================================================
; Name ..........: _String_EndsWhit
; Description ...: Checks if the string ends with a specific criteria, similar to the function in Python.
; Syntax ........: _String_EndsWhit($sString, $sEnd)
; Parameters ....: $sString             - The string to be examined.
;                  $sEnd                - A value (string) to check.
; Return values .: True if the string ends with that value; otherwise, return false. If $sString is not a string, return @error
; Author ........: Mateo Cedillo
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _String_EndsWhit($sString, $sEnd)
    If Not IsString($sString) Then Return SetError(1, 0, "")
    Return $sStart = StringRight($sString, 1)
EndFunc   ;==>_String_EndsWhit

 

miscstring.au3

Edited by Mateocedillo
  • 3 months later...
Posted

Get Array Column Number From Column Header Name
I've been using this to get the column number of a 2D Array, given the name of the column header. For return type COLUMN_LETTER, I've used a function _Excel_ColumnToLetter from the Excel UDF.

Func _ArrayGetHeaderColumnNumber(ByRef $array, $columnname, $returntype = "COLUMN_NUMBER_0BASED")

    Local $ReturnValue = -1

    Local $TargetColumn = -1
    For $h = 0 To UBound($array, $UBOUND_COLUMNS) - 1
        If $array[0][$h] = $columnname Then
            $TargetColumn = $h
            ExitLoop
        EndIf
    Next

    If $TargetColumn <> -1 Then
        Select
            Case $returntype = "COLUMN_NUMBER_0BASED"
                $ReturnValue = $TargetColumn
            Case $returntype = "COLUMN_NUMBER_1BASED"
                $ReturnValue = $TargetColumn + 1
            Case $returntype = "COLUMN_LETTER"
                $ReturnValue = _Excel_ColumnToLetter($TargetColumn + 1)
        EndSelect
    EndIf

    Return $ReturnValue

EndFunc   ;==>_ArrayGetHeaderColumnNumber
Posted

Intersection Of Two 1D arrays

Func _ArrayIntersect($array1, $array2)
    
    Local $ReturnValue = 0

    Local $Array1Unique = _ArrayUnique($array1, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
    Local $Array2Unique = _ArrayUnique($array2, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
    _ArraySort($Array1Unique)
    _ArraySort($Array2Unique)

    Local $SmallerArray
    Local $LargerArray
    If UBound($Array1Unique) <= UBound($Array2Unique) Then
        $SmallerArray = $Array1Unique
        $LargerArray = $Array2Unique
    Else
        $SmallerArray = $Array2Unique
        $LargerArray = $Array1Unique
    EndIf
    
    Local $ArrayString = ""
    Local $Check = 0
    Local $StartAt = 0
    For $i = 0 To UBound($SmallerArray) - 1
        $Check = _ArrayBinarySearch($LargerArray, $SmallerArray[$i], $StartAt)
        If $Check <> -1 Then
            $ArrayString &= $SmallerArray[$i] & "|"
            $StartAt = $Check
        EndIf
    Next

    If IsString($ArrayString) And StringLen($ArrayString) > 0 Then
        If StringRight($ArrayString, 1) = "|" Then
            $ArrayString = StringTrimRight($ArrayString, 1)
            ConsoleWrite(@CRLF & "------")
            ConsoleWrite(@CRLF & "ArrayString: " & $ArrayString)
            ConsoleWrite(@CRLF & "------")
            $ReturnValue = StringSplit($ArrayString, "|", $STR_NOCOUNT)
        EndIf
    EndIf

    Return $ReturnValue

EndFunc

 

Posted

Some String Functions For Code Readability

I started reading the book "Clean Code" by Robert C Martin a week ago, and the idea of "make code readable" really appealed to me (I'm not a programmer, so most of these concepts are somewhat new to me). Here are some simple examples of functions I've written to make my code more readable:

Functions For StringInStr

Func _StringContainsSubstring($string, $substring)

    Local $ReturnValue = 0

    If StringInStr($string, $substring) <> 0 Then $ReturnValue = 1

    Return $ReturnValue

EndFunc
Func _StringDoesntContainSubstring($string, $substring)

    Local $ReturnValue = 0

    If StringInStr($string, $substring) = 0 Then $ReturnValue = 1

    Return $ReturnValue

EndFunc

In terms of readability, I like how simple wrapper functions like these make my code look so much more like human-readable text. For example:

Local $String1 = "asdfgh"
Local $String2 = "asd"
If _StringContainsSubstring($String1, $String2) Then
; ----- etc -----
Else
; ----- etc -----
EndIf

Instead of:

If StringInStr($String1, $String2) <> 0 Then
;---- etc -----
Else
;---- etc -----
EndIf

 

Some more snippets:
Remove Trailing Characters From A String

Func _StringRemoveTrailingChar($string, $char)

    Local $ReturnValue = $string

    If IsString($string) And IsString($char) And StringLen($string) > StringLen($char) Then
        If StringRight($string, StringLen($char)) = $char Then
            $string = StringTrimRight($string, StringLen($char))
            $ReturnValue = $string
        EndIf
    EndIf

    Return $ReturnValue

EndFunc

Remove Leading Characters From A String

Func _StringRemoveLeadingChar($string, $char)

    Local $ReturnValue = $string

    If IsString($string) And IsString($char) And StringLen($string) > StringLen($char) Then
        If StringLeft($string, StringLen($char)) = $char Then
            $string = StringTrimLeft($string, StringLen($char))
            $ReturnValue = $string
        EndIf
    EndIf

    Return $ReturnValue

EndFunc

 

Posted

Hi @noellarkin,

regarding readability I like to agree with you. Custom wrapper function are often a good way to represent what is actually going on in a function.

2 hours ago, noellarkin said:
Func _StringContainsSubstring($string, $substring)
    Local $ReturnValue = 0

    If StringInStr($string, $substring) <> 0 Then $ReturnValue = 1

    Return $ReturnValue
EndFunc

Func _StringDoesntContainSubstring($string, $substring)
    Local $ReturnValue = 0

    If StringInStr($string, $substring) = 0 Then $ReturnValue = 1

    Return $ReturnValue
EndFunc

 

In your snippet for the StringInStr functions, I would say it's not necessary to have two separate functions. Why not just like that:

Func _StringContains($sString, $sSubstring)
    Return (StringInStr($sString, $sSubstring) <> 0) ? True : False
EndFunc

ConsoleWrite(    _StringContains('This is a simple test.', 'simple') & @CRLF)
ConsoleWrite(Not _StringContains('This is a simple test.', 'simple') & @CRLF)

Anyhow, thanks for sharing some code snippets 👍 .

Best regards
Sven

________________
Stay innovative!

 

Stay innovative!

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

  • 2 weeks later...
Posted
On 1/2/2023 at 7:41 PM, SOLVE-SMART said:

In your snippet for the StringInStr functions, I would say it's not necessary to have two separate functions. Why not just like that:

Func _StringContains($sString, $sSubstring)
    Return (StringInStr($sString, $sSubstring) <> 0) ? True : False
EndFunc

ConsoleWrite(    _StringContains('This is a simple test.', 'simple') & @CRLF)
ConsoleWrite(Not _StringContains('This is a simple test.', 'simple') & @CRLF)

👍 .

 

 

 

Thanks! Yeah your example is a LOT more concise, of course :) I really like the use of ___ ? ___ : ___ - -  I should use it more often in my scripts.
On the other hand, I kinda like how functions names that are "natural language" look esp when in the context of conditionals.

Example: If _StringDoesntContainSubstring($string, $substring) Then _________________ Else _________________

For me, if its more readable, I'd gladly deal with a few extra lines :)

Posted (edited)

Yes, why not @noellarkin 👍 . I also like well defined names for variables, functions (methods), classes etc. As long as you and your team (in business cases) are fine with a consistent way of writing "clean code", at best defined by coding guidelines, all is good 😀 .

Best regards
Sven

Edited by SOLVE-SMART

Stay innovative!

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

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
  • Recently Browsing   0 members

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