Programming: bug in compareson with empty strings

For notifying us of what you believe are bugs or errors in EViews.
Please ensure your copy of EViews is up-to-date before posting.

Moderators: EViews Gareth, EViews Moderator

mamo
Posts: 82
Joined: Wed Nov 07, 2012 9:11 am

Programming: bug in compareson with empty strings

Postby mamo » Wed Mar 15, 2017 7:24 am

Dear Eviews team,

I use Eviews 9.5, June 2016 built.

Comparing a non-empty string variable with an empty string variable in a program using the inequality sign "<>" gives the wrong result of equality (see example program listed below)

Best, mamo

Code: Select all

wfcreate u 1
%string1=""
%string2="Hello"
if %string1=%string2 then
   string result_equal = "Strings are equal"
else
   string result_equal  = "Strings are unequal"
endif

if %string1<>%string2 then
   string result_unequal = "Strings are unequal"
else
   string result_unequal = "Strings are equal"
endif
' result_equal has the correct result of strings being unequal
show result_equal
' result_unequal has the incorrect result of strings being equal
show result_unequal

EViews Gareth
Fe ddaethom, fe welon, fe amcangyfrifon
Posts: 11378
Joined: Tue Sep 16, 2008 5:38 pm

Re: Programming: bug in compareson with empty strings

Postby EViews Gareth » Wed Mar 15, 2017 8:10 am

Not really a bug per se. Just the way comparisons are defined.

When doing comparisons of numbers, if one of the numbers is an NA the comparison will return NA (which is not a true). So:

Code: Select all

if 1=NA then
 ' this will not happen
else
  'this will happen
endif

or:

Code: Select all

if NA=NA then
  'this will not happen
else
  'this will happen
endif


What happens with strings? Well exactly the same behaviour, but in string world an NA is a missing value. So if one of the strings is empty, the comparison returns an NA which is not a true.
Follow us on Twitter @IHSEViews

EViews Matt
EViews Developer
Posts: 158
Joined: Thu Apr 25, 2013 7:48 pm

Re: Programming: bug in compareson with empty strings

Postby EViews Matt » Wed Mar 15, 2017 10:11 am

As Gareth points out, it helps to think of "" as an NA rather than as an empty string. However, EViews does have functions supporting classical empty string behavior if that's what you need. Take a look at this section of the EViews manual.

mamo
Posts: 82
Joined: Wed Nov 07, 2012 9:11 am

Re: Programming: bug in compareson with empty strings

Postby mamo » Thu Mar 16, 2017 1:46 am

Many thanks!
@eqna works as expected
Best, mamo

mamo
Posts: 82
Joined: Wed Nov 07, 2012 9:11 am

Re: Programming: bug in compareson with empty strings

Postby mamo » Fri Mar 17, 2017 3:48 am

Sorry for coming back on this; it may appear a bit nitty-gritty, but it may be helpful to point to users that the safe approach to comparing a string with an empty string consists of making use of the functions @isempty(), or @equna().

Strictly spoken, your reply applies to comparisons with alpha series containing the value of an empty string, but not to quite to direct comparisons with an empty string or with a program variable referring to an empty string. With regard to the latter two, I still think there is a bug, or at least an inconsistency which may point to an issue of how strings and string variables are dealt with internally in EVIEWS.

The example code 1 below goes through various ways of checking inequality with an empty string, generating the message strings message1-message8 and the corresponding indicator series m1-m8. All indicators series should come out as being equal to 1.

All messages and indicator series come out correctly and as expected, with the exceptions of a) message3 and the corresponding indicator series m3, and b) message 2, but here, the respective indicator series m2 is computed correctly as unity.

Regarding message3 and m3, they depict the outcome of the variant comparing (%test<>alpha_emptystring, and they give results in line with what you have said in your reply: message3 gives the wrong result of " "1" = alpha_emptystring " and the series m3 becomes a missing value.

message2 and m2 depict the outcome of the comparison (%test<>%emptystring). Here, message2 gives the incorrect outcome " "1" = emptystring " whereas series m2=(%test<>%emptystring) computes correctly to unity.
In contrast, message1, depicting the outcome of comparison (%test<>"" ), is correctly computed as " "1" <> "" " (and the corresponding indicator series m1=1 comes out correctly as well). The right outcome in message1 using an empty string directly contrasts with the wrong one in message2 using a program variable referring to an empty string.

Finally, it is funny that the same approaches of checking equality with an empty string as in example code 2 gives overall consistent results. All indicator series compute to 0, with the exception of m3=(%test=alpha_emptystring) which yields a missing value; the respective message string message3 comes out correctly as " "1" <> alpha_emptystring ".

Best, mamo

Example code 1 - approaches to checking INEQUALITY with an empty string

Code: Select all

' Approaches to checking INEQUALITY with an empty string
wfcreate u 1

%test="1"
%emptystring=""
alpha alpha_emptystring=""

series m1=(%test<>"" )
if %test<>"" then
 string message1=@addquotes(%test)+" <> """""
else
  string message1 string message1=@addquotes(%test)+" = """""
endif

series m2=(%test<>%emptystring)
if %test<>%emptystring then
 string message2=@addquotes(%test)+" <> emptystring"
else
  string message2=@addquotes(%test)+" = emptystring"
endif

series m3=(%test<>alpha_emptystring)
if %test<>alpha_emptystring then
 string message3=@addquotes(%test)+" <> alpha_emptystring"
else
  string message3=@addquotes(%test)+" = alpha_emptystring"
endif


series m4=not @eqna(%test, "")
if not @eqna(%test, "") then
 string message4=@addquotes(%test)+" is not equal to """""
else
  string message4=@addquotes(%test)+" is equal to """""
endif

series m5=not @eqna(%test,%emptystring)
if not @eqna(%test,%emptystring) then
 string message5=@addquotes(%test)+" is not equal to emptystring"
else
  string message5=@addquotes(%test)+" is equal to emtpystring"
endif

series m6=not @eqna(%test,alpha_emptystring)
if not @eqna(%test,%emptystring) then
 string message6=@addquotes(%test)+" is not equal to alpha_emptystring"
else
  string message6=@addquotes(%test)+" is equal to alpha_emtpystring"
endif


series m7=not @isempty(%test)
if not @isempty(%test) then
 string message7=@addquotes(%test)+" is not empty"
else
  string message7=@addquotes(%test)+" is empty"
endif

series m8=not @isempty(%test)
if not @eqna(%test,%emptystring) then
 string message8=@addquotes(%test)+" is not emptystring"
else
  string message8=@addquotes(%test)+" is emptystring"
endif

for !i=1 to 8
   show message{!i}
next


Example code 2 - approaches to checking EQUALITY with an empty string

Code: Select all

' Approaches to checking EQUALITY with an empty string
wfcreate u 1

%test="1"
%emptystring=""
alpha alpha_emptystring=""

series m1=(%test="" )
if %test="" then
 string message1=@addquotes(%test)+" = """""
else
  string message1=@addquotes(%test)+" <> """""
endif

series m2=(%test=%emptystring)
if %test=%emptystring then
 string message2=@addquotes(%test)+" = emptystring"
else
  string message2=@addquotes(%test)+" <> emptystring"
endif

series m3=(%test=alpha_emptystring)
if %test=alpha_emptystring then
 string message3=@addquotes(%test)+" = alpha_emptystring"
else
  string message3=@addquotes(%test)+" <> alpha_emptystring"
endif


series m4=@eqna(%test, "")
if @eqna(%test, "") then
 string message4=@addquotes(%test)+" is equal to """""
else
  string message4=@addquotes(%test)+" is not equal to """""
endif

series m5=@eqna(%test,%emptystring)
if @eqna(%test,%emptystring) then
 string message5=@addquotes(%test)+" is equal to emptystring"
else
  string message5=@addquotes(%test)+" is not equal to emtpystring"
endif

series m6=@eqna(%test,alpha_emptystring)
if @eqna(%test,%emptystring) then
 string message6=@addquotes(%test)+" is equal to alpha_emptystring"
else
  string message6=@addquotes(%test)+" is not equal to alpha_emtpystring"
endif


series m7=@isempty(%test)
if @isempty(%test) then
 string message7=@addquotes(%test)+" is empty"
else
  string message7=@addquotes(%test)+" is not empty"
endif

series m8=@isempty(%test)
if @eqna(%test,%emptystring) then
 string message8=@addquotes(%test)+" is emptystring"
else
  string message8=@addquotes(%test)+" is not emptystring"
endif

for !i=1 to 8
   show message{!i}
next

EViews Matt
EViews Developer
Posts: 158
Joined: Thu Apr 25, 2013 7:48 pm

Re: Programming: bug in compareson with empty strings

Postby EViews Matt » Fri Mar 17, 2017 5:19 pm

Hello,

You have identified some important nuances regarding the empty string and the <> and = operators. In the general context of your initial post, using string objects or variables in simple expressions, those operators treat empty strings as NAs as per the documentation. However, there are two important exceptions in which empty strings are treated as empty strings:
  • Using the empty string literal "". This exception is documented.
  • Using empty strings, in any form, in a series generating expression. This exception is not documented (to my knowledge).
Your follow-up programs make us of these exceptions a great deal. Examining your inequality tests, let me highlight why some of the code lines behave the way they do.

Code: Select all

%test="1"
series m1=(%test<>"" )
if %test<>"" then

The series generating expression above falls under both exceptions, thus empty strings are treated as empty strings. The expression is therefore conceptually equivalent to "1" <> "", which is true, and thus evaluates to 1. The conditional expression falls under the first exception, is also interpreted as "1" <> "", and evaluates to 1 (true).

Code: Select all

%emptystring=""
series m2=(%test<>%emptystring)
if %test<>%emptystring then

The series generating expression falls under the second exception, is conceptually equivalent to "" <> "", and evaluates to 1. However, the conditional expression falls under neither exception, thus empty strings are treated as NAs. The expression is therefore conceptually equivalent to "1" <> NA, which evaluates to NA and is considered false by the if statement. This explains the discrepancy between m2 and message2 that you observed. Due to the second exception, all your series generating expressions treat empty strings as empty strings, so there is no effective difference between using = versus @eqna, or <> versus @neqna. Only your conditional expressions hold the potential of illuminating the difference between the operators and the analogous functions. Here's a snippet of code summarizing when the operators might produce surprising results:

Code: Select all

%empty = ""
%one = "1"
series s = %empty = %empty   ' series context, "" = "" -> 1
scalar t = %empty = %empty   ' scalar context, NA = NA -> NA
s.fill %one = %empty         ' series context, "1" = "" -> 0
s(1) = %one = %empty         ' scalar context, "1" = NA -> NA

Thus far I've avoided mentioning your examples involving an alpha series. Alpha series basically have their own rules, which I'll demonstrate with commented code:

Code: Select all

create u 10

%empty = ""
%one = "1"
alpha a1 = ""
alpha a2 = "1"

series series_context
series_context.fill a1 = "", a1 = %empty, a1 = %one, a1 = a1, a1 = a2, a1 <> "", a1 <> %empty, a1 <> %one, a1 <> a1, a1 <> a2

series scalar_context              ' scalar_context versus series_context
scalar_context(1) = a1 = ""        ' 0 vs 1
scalar_context(2) = a1 = %empty    ' 0 vs 1
scalar_context(3) = a1 = %one      ' 0 vs NA
scalar_context(4) = a1 = a1        ' 0 vs NA
scalar_context(5) = a1 = a2        ' 0 vs NA
scalar_context(6) = a1 <> ""       ' both 0
scalar_context(7) = a1 <> %empty   ' both 0
scalar_context(8) = a1 <> %one     ' 0 vs NA
scalar_context(9) = a1 <> a1       ' 0 vs NA
scalar_context(10) = a1 <> a2      ' 0 vs NA

All comparisons in scalar contexts fail (evaluate to 0), all series context comparisons with the empty string as literal or string variable evaluate correctly, and the remaining cases evaluate to NA. :shock: I think the moral of the story is: be careful how you use alpha series in comparison expressions when the empty string is involved.


Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 3 guests