What's Visual FoxPro's string lt(<)/gt(>)/lte(<=)/gte(>=) comparison rule? - visual-foxpro

?"ABC">"A" returns .F.
?"ABC">"B" returns .F.
?"ABC">"a" returns .T.
This seems not an ASCII comparison (as in other common programming languages).
I'v searched MSDN, however Relational Operators only explained comparison across numeric type or boolean. String and Value Comparison didn't mention lt/gt/lte/gte operators.
Why string comparison work like this? What's VFP's internal rules for string lt/gt comparison?

Actually VFP's string comparison is not much different than in other languages (some languages -ie: C#- doesn't even let you use >=, >, <= and < with strings). However, in VFP there is one setting that affects string comparison and it is 'SET EXACT'. Other than that, VFP strings are case sensitive, thus "ABC" > "a" is false (alpha sort is based on their ASCII character codes).
With default SET EXACT OFF, strings are compared up to the length of right operand. ie:
"ABC" = "A"
is compared like:
"A" = "A"
thus they are equal, so "ABC" > "A" is false (and also "ABC" < "A" is false, "ABC" = "A" is true).
To recap, with default SET EXACT setting, which is OFF:
"ABC" = "A" (but "A" = "ABC" is false - compare up to right operand's length).
AND, the alphabetic ordering use ASCII code.
SET EXACT OFF && Default if not set explicitly
? "ABC" = "A" && .T.
? "ABC" > "A" && .F.
? "ABC" < "B" && .T.
SET EXACT ON
? "ABC" = "A" && .F.
? "ABC" > "A" && .T.
? "ABC" < "B" && .T.
A special note: If you are doing this equality check in SQL commands, then there the ANSI rules are applied and SET EXACT has no effect there. By default SET ANSI is OFF and "ABC" = "A" (and due to SQL rules, changing the operands' left and right sides wouldn't matter, thus "A" = "ABC" is also true). ie:
Select * from myTable where firstName = "A"
would return records having firstName "Anthony", "Alice" ... and so on.
There is a special == (exactly equal) operator in VFP that works independantly from SET EXACT or SET ANSI setting. Beware its behavior is different with regular commands and SQL commands. With regular commands it really means 'exactly equal' including the trailing spaces in both of the compared strings. ie:
? 'ABC' == 'ABC ' && false, regardless of SET EXACT
With SQL however (regardless of SET ANSI setting):
select * from myTable where myField == 'A'
select * from myTable where myField == 'A '
select * from myTable where myField == 'A '
all mean the same and searches for records whose myField content is A (whatever the field size is - trailing spaces on both sides of the comparison are ignored).
Note: I think you can request document topics to be added in stack overflow. VFP documentation has just started and no additions done yet, AFAIK.

Related

Difference in a one line block code between === and match?

I have the following code example to check whether some elements in an array match or not the given regular expression:
["SELECT column1, column2 FROM table1, table2 WHERE column2='value';",
"SELECT * FROM Customers WHERE Last_Name='Smith';",
"SELECT * FROM Friends"].none? { |sql| /WHERE/i.match?(sql) }
# false
As you can see, I'm using match? just to see if both the receiver and the method parameter match. I'm not interested on the pros of using match as it's stated on the docs:
Returns a true or false indicates whether the regexp is matched or not without updating $~ and other related variables. If the second parameter is present, it specifies the position in the string to begin the search.
So, I could easily use === for that:
["SELECT column1, column2 FROM table1, table2 WHERE column2='value';",
"SELECT * FROM Customers WHERE Last_Name='Smith';",
"SELECT * FROM Friends"].none? { |sql| /WHERE/ === sql }
# false
Which returns the very same. Maybe isn't so common to use case equality for this kind of things, but that allows me to pass the regular expression as the none? parameter, and avoid opening the block, as I'm using Ruby 2.5+:
array.none?(/WHERE/) # false
And works pretty much the same (also the same for every enumerable predicate method):
array.any? { |sql| /WHERE/i.match?(sql) } # true
array.any? { |sql| /WHERE/ === sql } # true
array.any?(/WHERE/) # true
So, my question is; would it be the same for me, considering these cases to use === to check every string instance in the arrays match with the given regular expression? If so, I could replace them all to just pass the regular expression as the method (none?, any?) parameter.
The reason for Regexp#=== existing is primarily for use in case statements, like:
case (str)
when /WHERE/i
# ...
end
As internally that calls the === to check for matches. This is why you can do a lot of really wild things like:
case (str)
when String
when 0..20
when 'example'
when /text/
end
Among other things, all by virtue of the === comparison.
It's worth noting it's not intended to be used as you have. match? communicates quite clearly your intent, but === may be confusing as it looks a lot like == which indicates "comparison", but this is not any ordinary comparison.
The good news is Ruby allows using a regular expression directly with any? as well as an alternative like:
[
"SELECT column1, column2 FROM table1, table2 WHERE column2='value';",
"SELECT * FROM Customers WHERE Last_Name='Smith';",
"SELECT * FROM Friends"
].grep(/WHERE/i).any?
Where the grep method can take either a string or a regular expression.
The grep method is great for filtering, but if you just want to know if any of them match it's not as efficient as any?, so I'd use that instead.

Lua: Inverse of string.char()?

I'm wondering if there is a function that does the exact opposite of string.char(). It would be convenient to get a number value from letters in order to sort things alphabetically.
string.byte()
Is probably what you're looking for.
To get the first UTF-8 Byte of a string, you can use either string.byte or str:byte() where str is your string in question.
However, if you're sorting a table, or doing a sort in general, Lua actually has you covered! You can compare two strings as if they were numbers! "A" < "B" returns true and "B" < "A" returns false. This also works for multiple letters in a string. "Ba" > "Aa" and "Ab" > "Aa" and so on. So you can do table.sort(t) or if you're sorting by a sub value, table.sort(t,function(a,b) return a.text < b.text end). Hope this helps!

Classic ASP InStr() Evaluates True on Empty Comparison String

I ran into an issue with the Classic ASP VbScript InStr() function. As shown below, the second call to InStr() returns 1 when searching for an empty string in a non empty string. I'm curious why this is happening.
' InStr Test
Dim someText : someText = "So say we all"
Dim emptyString : emptyString = ""
'' I expect this to be true
If inStr(1,someText,"so",1) > 0 Then
Response.write ( "I found ""so""<br />" )
End If
'' I expect this to be false
If inStr(1, someText, emptyString, 1) > 0 Then
Response.Write( "I found an empty string<br />" )
End If
EDIT:
Some additional clarification: The reason for the question came up when debugging legacy code and running into a situation like this:
Function Go(value)
If InStr(1, "Option1|Option2|Option3", value, 1) > 0 Then
' Do some stuff
End If
End Function
In some cases function Go() can get called with an empty string. The original developer's intent was not to check whether value was empty, but rather, whether or not value was equal to one of the piped delimited values (Option1,Option2, etc.).
Thinking about this further it makes sense that every string is created from an empty string, and I can understand why a programming language would assume a string with all characters removed still contains the empty string.
What doesn't make sense to me is why programming languages are implementing this. Consider these 2 statements:
InStr("so say we all", "s") '' evaluates to 1
InStr("so say we all", "") '' evaluates to 1
The InStr() function will return the position of the first occurrence of one string within another. In both of the above cases, the result is 1. However, position 1 always contains the character "s", not an empty string. Furthermore, using another string function like Len() or LenB() on an empty string alone will result in 0, indicating a character length of 0.
It seems that there is some inconsistency here. The empty string contained in all strings is not actually a character, but the InStr() function is treating it as one when other string functions are not. I find this to be un-intuitive and un-necessary.
The Empty String is the Identity Element for Strings:
The identity element I (also denoted E, e, or 1) of a group or related
mathematical structure S is the unique element such that Ia=aI=a for
every element a in S. The symbol "E" derives from the German word for
unity, "Einheit." An identity element is also called a unit element.
If you add 0 to a number n the result is n; if you add/concatenate "" to a string s the result is s:
>> WScript.Echo CStr(1 = 1 + 0)
>> WScript.Echo CStr("a" = "a" & "")
>>
True
True
So every String and SubString contains at least one "":
>> s = "abc"
>> For p = 1 To Len(s)
>> WScript.Echo InStr(p, s, "")
>> Next
>>
1
2
3
and Instr() reports that faithfully. The docs even state:
InStr([start, ]string1, string2[, compare])
...
The InStr function returns the following values:
...
string2 is zero-length start
WRT your
However, position 1 always contains the character "s", not an empty
string.
==>
Position 1 always contains the character "s", and therefore an empty
string too.
I'm puzzled why you think this behavior is incorrect. To the extent that asking Does 'abc' contain ''? even makes sense, the answer has to be "yes": All strings contain the empty string as a trivial case. So the answer to your "why is this happening" question is because it's the only sane thing to do.
It is s correct imho. At least it is what I expect that empty string is part of any other string. But maybe this is a philosophical question. ASP does it so, so live with it. Practically speaking, if you need a different behavior write your own Method, InStrNotEmpty or something, which returns false on empty search string.

IsNull in sybase where clause

I am using vb6 front end and sybase as backend. Can I use IsNull in where clause OR I must use = NULL
SQLStr = "select distinct thrd_pty.id_thrd_pty, thrd_pty.name_thrd_pty, thrd_pty.nbr_tax_idtn " _
& "from thrd_pty, cntct_rltn, cntct " _
& "where cntct.id_cntct = '" & cntct(ColNum, CurThrdPty) & "' and cntct_rltn.id_super = cntct.id_cntct and cntct_rltn.name_super = 'cntct' and thrd_pty.id_thrd_pty = cntct_rltn.id_thrd_pty and cntct_rltn.dt_eff_end IsNull "
The usual syntax in Sybase is either AND cntct_rltn.dt_eff_end IS NULL (which is perfectly fine for your example) or ISNULL(cntct_rltn.dt_eff_end, 0) for the more complicated stuff where you want to replace null with a defined default value. But you can do any of the follownig in ASE 15:
Adaptive Server treats null values in different ways, depending on the operators that you use and the type of values you are comparing. In general, the result of comparing null values is UNKNOWN, since it is impossible to determine whether NULL is equal (or not equal) to a given value or to another NULL. The following cases return TRUE when expression is any column, variable or literal, or combination of these, which evaluates as NULL:
expression is null
expression = null
expression = #x where #x is a variable or parameter containing NULL. This exception facilitates writing stored procedures with null default parameters.
expression != n where n is a literal not containing NULL and expression evaluates to NULL. (source)
(uppercase is mine as a personal style preference)
As a side note, you can also use COALESCE() function to deal with NULL values, but in your use case it won't add anything useful.
Reference:
Testing column for NULL values at Sybase infocenter
ISNULL as a function
COALESCE
Use is null:
cntct_rltn.dt_eff_end is null
More info, here
EDIT:
cQ = "update var1 = null ".(can be) .cQ = "update var1 is null" ?????
– niru dyogi
If you are updating, you have to use the assignment operator =. You can use is null only when evaluating conditions (such as the one in the example you provided).

Checking if a string has balanced parentheses

I am currently working on a Ruby Problem quiz but I'm not sure if my solution is right. After running the check, it shows that the compilation was successful but i'm just worried it is not the right answer.
The problem:
A string S consisting only of characters '(' and ')' is called properly nested if:
S is empty,
S has the form "(U)" where
U is a properly nested string,
S has
the form "VW" where V and W are
properly nested strings.
For example, "(()(())())" is properly nested and "())" isn't.
Write a function
def nesting(s)
that given a string S returns 1 if S
is properly nested and 0 otherwise.
Assume that the length of S does not
exceed 1,000,000. Assume that S
consists only of characters '(' and
')'.
For example, given S = "(()(())())"
the function should return 1 and given
S = "())" the function should return
0, as explained above.
Solution:
def nesting ( s )
# write your code here
if s == '(()(())())' && s.length <= 1000000
return 1
elsif s == ' ' && s.length <= 1000000
return 1
elsif
s == '())'
return 0
end
end
Here are descriptions of two algorithms that should accomplish the goal. I'll leave it as an exercise to the reader to turn them into code (unless you explicitly ask for a code solution):
Start with a variable set to 0 and loop through each character in the string: when you see a '(', add one to the variable; when you see a ')', subtract one from the variable. If the variable ever goes negative, you have seen too many ')' and can return 0 immediately. If you finish looping through the characters and the variable is not exactly 0, then you had too many '(' and should return 0.
Remove every occurrence of '()' in the string (replace with ''). Keep doing this until you find that nothing has been replaced (check the return value of gsub!). If the string is empty, the parentheses were matched. If the string is not empty, it was mismatched.
You're not supposed to just enumerate the given examples. You're supposed to solve the problem generally. You're also not supposed to check that the length is below 1000000, you're allowed to assume that.
The most straight forward solution to this problem is to iterate through the string and keep track of how many parentheses are open right now. If you ever see a closing parenthesis when no parentheses are currently open, the string is not well-balanced. If any parentheses are still open when you reach the end, the string is not well-balanced. Otherwise it is.
Alternatively you could also turn the specification directly into a regex pattern using the recursive regex feature of ruby 1.9 if you were so inclined.
My algorithm would use stacks for this purpose. Stacks are meant for solving such problems
Algorithm
Define a hash which holds the list of balanced brackets for
instance {"(" => ")", "{" => "}", and so on...}
Declare a stack (in our case, array) i.e. brackets = []
Loop through the string using each_char and compare each character with keys of the hash and push it to the brackets
Within the same loop compare it with the values of the hash and pop the character from brackets
In the end, if the brackets stack is empty, the brackets are balanced.
def brackets_balanced?(string)
return false if string.length < 2
brackets_hash = {"(" => ")", "{" => "}", "[" => "]"}
brackets = []
string.each_char do |x|
brackets.push(x) if brackets_hash.keys.include?(x)
brackets.pop if brackets_hash.values.include?(x)
end
return brackets.empty?
end
You can solve this problem theoretically. By using a grammar like this:
S ← LSR | LR
L ← (
R ← )
The grammar should be easily solvable by recursive algorithm.
That would be the most elegant solution. Otherwise as already mentioned here count the open parentheses.
Here's a neat way to do it using inject:
class String
def valid_parentheses?
valid = true
self.gsub(/[^\(\)]/, '').split('').inject(0) do |counter, parenthesis|
counter += (parenthesis == '(' ? 1 : -1)
valid = false if counter < 0
counter
end.zero? && valid
end
end
> "(a+b)".valid_parentheses? # => true
> "(a+b)(".valid_parentheses? # => false
> "(a+b))".valid_parentheses? # => false
> "(a+b))(".valid_parentheses? # => false
You're right to be worried; I think you've got the very wrong end of the stick, and you're solving the problem too literally (the info that the string doesn't exceed 1,000,000 characters is just to stop people worrying about how slow their code would run if the length was 100times that, and the examples are just that - examples - not the definitive list of strings you can expect to receive)
I'm not going to do your homework for you (by writing the code), but will give you a pointer to a solution that occurs to me:
The string is correctly nested if every left bracket has a right-bracket to the right of it, or a correctly nested set of brackets between them. So how about a recursive function, or a loop, that removes the string matches "()". When you run out of matches, what are you left with? Nothing? That was a properly nested string then. Something else (like ')' or ')(', etc) would mean it was not correctly nested in the first place.
Define method:
def check_nesting str
pattern = /\(\)/
while str =~ pattern do
str = str.gsub pattern, ''
end
str.length == 0
end
And test it:
>ruby nest.rb (()(())())
true
>ruby nest.rb (()
false
>ruby nest.rb ((((()))))
true
>ruby nest.rb (()
false
>ruby nest.rb (()(((())))())
true
>ruby nest.rb (()(((())))()
false
Your solution only returns the correct answer for the strings "(()(())())" and "())". You surely need a solution that works for any string!
As a start, how about counting the number of occurrences of ( and ), and seeing if they are equal?

Resources