Jump to content
InunoTaishou

Why does a string used in an expression return 0?

Recommended Posts

InunoTaishou

I know on other languages when you try to use a string like this

Global $sString = "Some String"

If ($sString) Then
    ; ...
EndIf

The compiler will fail because string cannot be used in an expression where it needs a bool (something along those lines). But I see instances in other languages where using $sString in an expression will work and implicitly use the length of the string (or because there is some value in that variable).

I'm wondering why AutoIt doesn't do the same. If the $sString is used like in my example (or some other expression where it wants a bool type) implicitly use the length of the string instead of the converting to 0?

Share this post


Link to post
Share on other sites
Subz

Isn't that what the _IsString(), _IsDeclared(), StringLen() functions are for?  From my logic:

If "Some String" Then ... doesn't really mean anything or maybe my logic is just screwed up :) 

Share this post


Link to post
Share on other sites
InunoTaishou

But AutoIt implicitly converts any string used in an expression where it wants a true/false to 0 if that string is not a string representation of a number or true/false ("True" or "False"). If it's going to do that why not implicitly convert it to 1 if the string is not "" (empty/null string)?

IsString just checks if the variable is a string (I.e., 32 is not a string but "32" is)

_IsDeclared just checks if the string representation of the variable is declared in the script

and StringLen is what would be used currently

This is how we currently do it

Global $sString = "Some String"

While (StringLen($sString))
    ConsoleWrite($sString & @LF)
    $sString = StringTrimLeft($sString, 1)
WEnd

And this is how we could be doing it

Global $sString = "Some String"

While ($sString)
    ConsoleWrite($sString & @LF)
    $sString = StringTrimLeft($sString, 1)
WEnd

Seems like such an insignificant thing but it's surprisingly useful. I went from C++, VB, AutoIt to Python (where the latter does work) and it's so freaking nice being able to use the string as a boolean in an if statement

Edited by InunoTaishou

Share this post


Link to post
Share on other sites
Guy_

I used to do that all over the place and am still correcting it when I see it :D

It seems a bit silly to have to write ...

If $sTring <> "" Then

If isEmpty($sTring) Then ... (in some languages)

But I guess there may be good reasons for it...
It's why it's good to first start studying the basics before you start tinkering. I'm still telling myself that every day... ;)

Share this post


Link to post
Share on other sites
czardas

It was an illogical decision IMO. I believe you should be able to use strings in boolean expressions. Actually it seems to be working. Which version of AutoIt are you using?

Edited by czardas

Share this post


Link to post
Share on other sites
InunoTaishou

I just ran

Global $sString = "Some String"

While ($sString)
    ConsoleWrite($sString & @LF)
    $sString = StringTrimLeft($sString, 1)
WEnd

And it actually worked.... I don't know who did it, I don't know when it happened, but I swear this used to not work.... Strings used to always evaluate to 0 when used in a boolean expression.

Does this work for anyone else?

Share this post


Link to post
Share on other sites
czardas

We are mistaking it for something else. This works for me.

If 'some string' Then MsgBox(0, '', 'hey')


Conversion of string to number is the oddball.

MsgBox(0, '', Number('3v')) ; converts to 3

I find that so illogical.

Edited by czardas

Share this post


Link to post
Share on other sites
InunoTaishou

I remember very specifically that it didn't used to work, and was very frustrated by this. Looking back at a few old scripts I had to use things like Stringlen and Not $sString == ""

Share this post


Link to post
Share on other sites
czardas

Maybe it was like that previously. I don't remember.

Edited by czardas

Share this post


Link to post
Share on other sites
iamtheky

strings still evaluate to 0 in some cases, no?

msgbox("some string" , "some string" , "some string")

 


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

Share this post


Link to post
Share on other sites
czardas
3 hours ago, iamtheky said:

strings still evaluate to 0 in some cases, no?

Could be two different things. A boolean comparison verses a default error override. I don't know.

Edited by czardas

Share this post


Link to post
Share on other sites
iamtheky

maybe?

#include<array.au3>

local $aArray["zero elements please"]
_ArrayDisplay($aArray , ubound($aArray))

 


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

Share this post


Link to post
Share on other sites
czardas

Of course you should never rely on undocumented behaviour.

#include<array.au3>

local $aArray["3 elements please"]
_ArrayDisplay($aArray , ubound($aArray))

In this case it certainly appears to be a conversion.

In addition: boolean comparisons between different data types may sometimes lead to (apparently) contradictory results.

Edit: This is also a conversion, and not the result of some default override value.

MsgBox('1 or 2', '', 'meh')

 

Edited by czardas

Share this post


Link to post
Share on other sites
jchd

There is no more "contradictory results" than "some cases" or "random conversion behavior".

Well written computer programs are pretty bad at creating non-repeatable surprising behavior, contrary to humans. Instead, they hopefully exhibit very deterministic behavior which we all rely upon, else our lives would turn turmoil.

A string evaluates to its content when used in a string expression (or parameter of a function expecting a string). No surprise here.

It evaluates to a boolean in a boolean context: Flase if the string is empty, True if non-empty.

It evaluates to its numeric conversion (using Number()) when in a numeric context. Here an empty string evaluates to 0.

All of this always behaved the same for decade(s) AFAICT.

  • Like 1

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
iamtheky

I have shown two cases where a non-empty (or empty) string evaluates to 0, I could understand that being a product of the msgbox function, but the behavior exists with declaring arrays as well.  And that behavior has existed as long as I have been trolling threads regarding magic numbers.

Edited by iamtheky

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

Share this post


Link to post
Share on other sites
jchd

An dimension index is expected to be numeric, so Number is applied to the string, yielding zero. No surprise here either.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
iamtheky

so this would be an expected solution if I needed arrays from a list?  because formatting seems like an extra rather than necessary step if the behavior is expected, but I never see it in action.

#include<array.au3>

$sList1 = "20 bottles"
$sList2 = "45 plates"
$sList3 = "200 cups"

local $aArray1[$sList1]
local $aArray2[$sList2]
local $aArray3[$sList3]

_ArrayDisplay($aArray1)
_ArrayDisplay($aArray2)
_ArrayDisplay($aArray3)

 

Edited by iamtheky

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

Share this post


Link to post
Share on other sites
jchd

I don't believe the interpretor would get mad at you if you use that, albeit that useage might surprise future maintainers.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
InunoTaishou

It's like we've had a breakthrough! Lol (Sorry I'm late, was busy yesterday)

I quite like the

#include<array.au3>

$sList1 = "20 bottles"
$sList2 = "45 plates"
$sList3 = "200 cups"

local $aArray1[$sList1]
local $aArray2[$sList2]
local $aArray3[$sList3]

_ArrayDisplay($aArray1)
_ArrayDisplay($aArray2)
_ArrayDisplay($aArray3)

Then you could give self documenting arrays self documenting values

#include<array.au3>

Global $aBeers["10 draught beers"]
$aBeers["0 Coors"] = "Coors"
$aBeers["1 Fosters"] = "Fosters"
$aBeers["2 Staropramen"] = "Staropramen"
$aBeers["3 Personi"] = "Personi"
$aBeers["4 Fuller’s London Pride"] = "Fuller’s London Pride"
$aBeers["5 Cruzcampo"] = "Cruzcampo"
$aBeers["6 Heineken"] = "Heineken"
$aBeers["7 San Miguel"] = "San Miguel"
$aBeers["8 Stella Artois"] = "Stella Artois"
$aBeers["9 Mockingfish"] = "Mockingfish"

_ArrayDisplay($aBeers)

(I don't drink, beer was just something that came to mind)

  • Like 1

Share this post


Link to post
Share on other sites
czardas

I said '(apparently) contradictory' results. Anyway, I don't like the numeric conversion of strings (current implementation) because it doesn't differentiate between valid and invalid numbers. The loose conversion is a bit too loose IMO.

Edited by czardas

Share this post


Link to post
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

  • Similar Content

    • Miliardsto
      By Miliardsto
      I got that func
      Func makeHelpImgGUI($title,$width,$height,$img) $img = GUICtrlCreatePic("",20,40,$width,$height) _ResourceSetImageToCtrl($img, "HERE") EndFunc and I call this func like that
      makeHelpImgGUI("Image",1190, 800,$SETTINGS_JPG)  
      so what is the problem in the parameter where is - "HERE" I need value of img but passed as string
      so $img = $SETTINGS_JPG and how make it "SETTINGS_JPG"
       
      I tried something like that but not work
      Func makeHelpImgGUI($title,$width,$height,$img) $name_str = String($img) $name_str = StringTrimLeft ($name_str, 1 ) $img = GUICtrlCreatePic("",20,40,$width,$height) _ResourceSetImageToCtrl($img, $name_str) EndFunc  
    • ShakeelAhmad
      By ShakeelAhmad
      I've to upload different number of photos online in different assignments. There is a problem that all photos cannot be selected at once to upload. I have to choose and upload photos one by one. For this purpose I have made a script to automate whatever I have to do manually for choosing and uploading photos one by one.
      Please see my script below and check the last "MouseClick" command. This command clicks the button to choose and upload next photo. The problem I'm facing is; the last "MouseClick" works 1 step extra when all photos have been selected and uploaded. I mean if 7 photos are to be uploaded, this command opens the box from where next photo is selected and uploaded then it again opens the box and next photo is choosen and so on.... when last photo is selected and uploaded, this button once again opens the box. When all photos are uploaded, it should not click the button to select next photo. Please suggest how can I resolve this issue.
      #include <AutoItConstants.au3> Sleep(200) HotKeySet("{ESC}","Quit") ;Press ESC key to quit Send("{ALT DOWN}") Send("{TAB}") Send("{ALT UP}") Sleep(200) Local $photos = InputBox("Question", "How many photos to upload?", "#", "", _ - 1, -1, 0, 0) ; How many photos to upload Local $selector = 0 While $photos <> $selector MouseClick("Left", 281, 238, 1) ; mouse click on very first photo in the box. if $selector = 0 Then Send("{ENTER}") ; for selecting very first photo from "open" window. Sleep(800) Else sleep(200) Send("{RIGHT " & $selector & "}") ; for selecting 2nd to onward photos from "open" window. sleep(1000) Send("{ENTER}") sleep(1000) EndIf MouseClick("Left", 495, 198, 1) ; for clicking a button to choose next photo to upload $selector = $selector + 1 WEnd Beep(1500, 300) ; beep when all photos uploaded Exit Regards,
       
      Shakeel
    • Dzenan03
      By Dzenan03
      I want to make a while loop, that creates variables based on a array. For thist I created the array $iDsO with the number and the name of folders in an other folder. Every folder has a different name an I want to create variables(arrays) for each folder that show me all the files in that folder. For example: I have the Folder \Folder1. In it there are the Folders \1, \2, \3. In 1, 2 and 3 there are some files(.png). The array for Folder1 is $iDsO and now I want to crate the arrays $iDsO1, $iDsO2 and $iDsO3 with the files in them can I make something like this:
      While $iDs > 0 ;$iDs is the number of files in Folder1>> $iDsO[0] $iDs#here should come the Foldername for example '1'# = _FileListtoArray(@ProgramFilesDir&"\Folder1\"&$iDsO[$iDs]) $iDs = $iDs - 1 Wend So that in the End I have three variabels ($iDs1, $iDs2 and $iDs3)
       
      Is this posible or if not what could I do instead ( I don´t know the number of folders in Folder1 in the begining).
    • liagason
      By liagason
      Hello everyone,
      How can I display in ascending  sequence some numbers stored in a string variable?
      $str = "18,03,48,23" MsgBox(0,"test",$str) I would like it to display "03,18,23,48"
×