Friday 7 July 2017

String to Validate in case letter (Uppercase/ Lowercase) [Regular Expression is AX ]

I would like to share a logic puzzle that baffled me today. This may likely work in many programming languages, but obviously I am going to show you X++ code.

Problem:
Given the following string, write a job that displays a list of all the characters that are uppercase: AbDtw%@32E

Job-1:

static void findCapitalLetters(Args _args)
{
    str testStr = "R12345678";
    int i = 1;
    str character;

    character = subStr(testStr, i, 1);

    //If the character is EQUAL to it's uppercase counterpart, it must be uppercase:
    if (char2num(testStr, i) == char2num(strUpr(testStr), i))
    {
        info(strFmt("'%1' at position %2 is an uppercase letter.", character, i));
    }
}

I assumed that you would write a loop that compared each character with it’s uppercase character and if the character is equal to it’s uppercase counterpart, the character must be uppercase. Let’s try that:

Job-2:

static void findCapitalLetters(Args _args)
{
    str testStr = "AbDtw%@32E";
    int i ;
    int stringLenght = strLen(testStr);
    str character;

    for (i = 1; i <= stringLenght; i += 1)

    {
        character = subStr(testStr, i, 1);
        //If the character is EQUAL to it's uppercase counterpart, it must be uppercase:
        if (char2num(testStr, i) == char2num(strUpr(testStr), i))
        {
            info(strFmt("'%1' at position %2 is an uppercase letter.", character, i));
        }
   }
}

Output:


OOPS! The characters %, @, 3 and 2 are evaluated as uppercase; this is not what I had in mind. So I assumed (wrongly again) that the answer would be to first check if the character is a letter (if it is a number or symbol, I can just ignore it). I was thinking along the lines of adding str2IntOk()

The simple solution:
It turns out, if you reverse the question and ask, “Is this character not equal to its lower case letter?”, you get the correct answer:

Job-3:

static void findCapitalLetters(Args _args)
{
    str testStr = "AbDtw%@32E";
    int i;
    int stringLenght = strLen(testStr);
    str character;

    for (i=1; i<=stringLenght; i+=1)
    {
        character = subStr(testStr, i, 1);
        //If the character is EQUAL to it's uppercase counterpart, it must be uppercase:
        if (char2num(testStr, i) != char2num(strlwr(testStr), i))
        {
            info(strFmt("'%1' at position %2 is an uppercase letter.", character, i));
        }
    }
}

Explanation:
At first the two jobs looked the same to me. I thought the issue was with the way strLwr() and strUpr() work. It wasn’t until I examined the return values that I realized the problem is with the logical operators and not the string funtions.
Consider this table:


If the character is a letter, it has a different value for upper and lower case. If the value is a symbol or number, it doesn’t have an upper or lower case, and the same value returned as upper and lower case.
In the case of numbers and symbols, the question “Is this character not equal to its lower case letter?” has a different answer than “Is this character equal to its upper case letter?”.

Of course, in both cases the real question you should ask yourself is: “What is the problem I am trying to solve?”.

Happy DAXing....

No comments:

Post a Comment