Tuesday, April 28, 2015

Error: Invalid business key defined

In SAS DI Studio, when you try to add the column as Business Key which is already selected as a Detect Changes, you will get the error:

Error: Invalid business key defined

In order to resolve that, you need to remove whatever business keys you want to define from "Detect Changes" tab, it error is gone.

Tuesday, March 10, 2015

Java Expert RE-Learning Javascript Part 2 - Operators

What do you thing, what does javascript do with the following ?

"5" + 1
- result? "51"
5 + "1"
- result? "51"
"5" - 1
- result? 4
"5" == 5
- result? true
null == undefined 
- result? true

How did you do? I was bad at it, especially to realize that "5" + 1 and 5 + "1" would make the same result. Javascript tries always to do conversion whenever the types of operands dont match.

Javascript is pretty easy-going language. It allows you to do many things, giving you a bit of additional freedom. BUT you have to be VERY careful, as you can imagine that in some cases, above mentioned freedom might cost you a lot of bugs :)

So, summary of rules in Javascript about operators:

  • If you give Javascript different types to operate with, it will start doing type conversion. The way it would do it is based on set of (often confusing) rules. It would check first the operator, and then try to convert operands to the type appropriate to the operator. However, Javascript sees addition operator (+) as string concatenaton first.
  • null and undefined in operation with numbers will convert to 0 and NaN respectively (examples: 8+null = 8 , 8+undefined = NaN)
  • In order to assure yourself that the two values are properly compared, you should rather use === instead of ==. === (triple equals), checks precisely if the values are equals, without doing any automatic conversions.

So, what is the difference between double equals and tripple equals? With "==", Javascript tries to do automatic conversion before comparing the values, and with "===", Javascript does the precise comparison, without trying to "be smart".

Now the most favorite new thing for me: Logical Operators!

The rule sof && and || operators are the following:

  1. Javascript will try to convert the left-hand value to Boolean type in order to decide what to do,
  2. depending on operator (&& or ||) and the result of that conversion, it will return either original left-hand or right-hand value.
  3. "" is converted to false, and "jklkjsda" is converted to true. 0 is false, and 3124 is true.
some examples:
"Carl" && "Bob"
"Carl" || "Bob"
"" && "Bob"
"" || "Bob"

Java Expert RE-Learning Javascript Part 1 - Intro

You know the time when you come across so many different programming languages, it happens that you come cross programming language you never really learn from scratch, but just "learn by doing".

It has been like that all the way until I had "awakening" call, a job interview, where I got javascript questions which I did not know at all.

The biggest issue was its similarity to Java/C programming languages, where many things I rather "assumed" it is the same, without ever really checking it out.

After sobering up, I decided to RE-learn Javascript, and started reading book "Eloquent Javascript" . after reading now already a quarter of a book, I am positively surprised how nice it was written. I strongly suggest to anyone, either a core beginner in programming (no pre-knowledge whatsoever is required to read it), or even a veteran programmer. This book has also very challenging exercises in the end which solutions (can be found on above link) are really showcase-ing you the power of javascript in its core.

Wednesday, February 11, 2015

Today I listened a really nice clean-code google talk about bad practice of using IFs, and how much polymorphism helps out there. It is amazing to see how nicer code becomes, and how easy it is for a programmers to go into routine of making if/switch statements for no reason. All methods mentioned there are not new at all, but having it here shown reminds you on what and how should you think when programming.

Tuesday, December 23, 2014

CodeAnywhere, (thumbsup)!

I started some mini javascript project of my own, so needed to create a relatively simplistic development environment.
However, this environment has some constrains:
- it should not require install (portable to many different devices),
- it should connect to my Dropbox account.

For that purpose, I came across CodeAnywhere website, where you can for free set up your account and connect your dropbox account and immediately start working. However, the internal browser that they have is running through their proxy, which causes a number of issues for my javascript development, so I am not using it.

Friday, December 19, 2014

What makes SAS Enterprise Guide not a mature application ...

Ok, before I start expressing my opinion about SAS Enterprise Guide and SAS Base Programming, I would like to make a quick introduction of my technical experience and expertise.

Throughout 7-8 years of my professional life, I have been using in great extent software tools like MATLAB, and have been programming enterprise applications in Java/Spring. In last 6 months I am introducing myself to SAS World.

Version I am working on is SAS Enterprise Guide 9.4. For a system that still uses programming model (SAS Base) of 80s, a graphical interface which visually shows how the process is being executed is a great refreshment. There are many options on dealing with data and doing analysis on it, making it very comfortable tool to easily build a large data manipulation process.

Basic Application use issues:

  • "Object reference not set to an instance of an object".
    • It relatively often happens (every 4 days of 8h daily use of SAS Enterprise Guide) that the file you think you saved ends up to be corrupted. You open the saved file, and during the load above quoted message comes up, which makes you not being able to see the project tree, rendering this project file completely useless. You might have some chance, if the project is not too big, to refresh the project tree, and that it actually brings you back the project tree, but bigger the project gets (more process flows you create), less chance you have of any recovery. This errors would be completely fine, if a error message would be shown if something during saving process gets wrong, but there is no such message, leaving you only to wonder if you really have saved your project properly or not.
  • the first created Query Builder node on a newly created process flow suddenly jumps into some other process flow.
    • This annoying issue is happening usually when you want to address a table you used in some other process flow. Even though you have the new process flow currently open, and that you when to Tasks->Data-> Query Builder, if you chose a table referenced in some other process flow, it will (automatically) jump into that process flow. If you have referenced multiple tables referenced also in different process flows, the destination of the "jump" is at random. The worst part of it all, it does not get selected and automatically shown once it jumps, so if you dont know about the "jumping" behavior, you will think something went wrong, and will start building a new one again. It happened to me couple of times, even if I knew this issue, to be distracted and build the same node again. Couple of hours later, you just realize you have some junk created in the process flow you haven't even worked on...
  • Deleting nodes sometimes ends up in deleting the whole process flow. 
    • It does happen very seldom, but often you want to delete one step in between of the flow you created, it deletes not just all nodes that are directly dependent on its result, but also every node on the process flow.
  • Waiting for Godot
    • when you run a number of tasks, queued one after another, it does happen that the Queue Controller does not receive the "finish" signal from previous task, and simply does not start the next task. However, the finished task is being even cleared from a Task Status list, so the first in queue task waits literary for no task...
  • Edit-> Undo feature is only for text... no graphical nodes...
    • it does happen when you work long or get distracted, to accidentally delete a wrong graphical node. YES, YOU CAN'T BRING IT BACK. IT IS GONE. unless you have similar tick like me and save project every couple of minutes, so the process of "closing without saving and opening again" successfully replaces undo option.

General issues (or simply, why it is not there?)

  • A proper versioning system? Apache Subversion has been created in year 2000. 14 years exists a well functioning versioning system. Why SAS Enterprise Guide does not have that feature? By versioning system means working in parallel on a same project, with a possibility without any conflicts to work on different process flows. 
    • I read about SCM in SAS post, but this approach enforces you to use ONLY SAS Base code in your SAS Enterprise Project, because all the graphical implementation (main feature of SAS EG) is saved in .egp file. Now this is the funny part... the whole project is written in one XML file and in bunch of folders which contain log files, and all that zipped and renamed as egp file... option to do a versioning of that XML file would already be a big step further! Why it isn't done then?
  • SAS Base Code <-> SAS Enterprise Code? 
    • One is able to extract the code of SAS Enterprise Code, but there is no chance that the same exported code gets imported into a fully structured SAS project
  • Testing in SAS? 
    • Is there any testing method supported by SAS? Unit testing?
  • Design Patterns? 
    • I have read a paper (this one) which describes multiple design patterns using a sas macro language. As a initial C developer, my experience with macros is that having a dumb text-placing/no-thinking is extremely dangerous style of coding.
    • One can say
  • Is a "TRICK the SAS Base Language" a main solution to every upcoming problem?
    • Throughout development, often I had to google for some info how to do what in SAS, and it often turn to be the "trick" the final solution, which is actually some awful side-effect of existing SAS feature that then makes you do the job you need. For Example, creating a folder through SAS (let's say you want your reports to be placed in a folder tree defined by the business specification. Through a solution on this site it means, you have to make a meaningless librefs with specific option to create such a folder structure?). Now it makes me wonder... does it mean becoming a senior SAS developer means how many hacks you know???

Monday, December 15, 2014

Small C code to convert german text to old ASCII-DE encoding

I had a task to convert a UTF-8 or ISO-8859-2 encoding german text (names, addresses,...) into a 7bit ISO-646-DE (ASCII-DE) encoding. Since this encoding almost is non-existent, it was a bit difficult to find on Google search any example of such a conversion. I decided to be that sucker to write it :) I know this is not really the best code ever, but does its job. To see it in action, you can check it here (in case you see in a code pane [object Object], just refresh the page, and it will show the code) :)

compile it with: 
gcc -o convert convert.c
run it with:
convert input.txt output.txt && hexdump -ve '1/1 "%.2X"' output.txt


int main ( int argc, char *argv[] )

 static unsigned char utfconv[NUM_OF_CONV_TABLE] = 
     {0x84, 0x96, 0x9C, 0xA4, 0xB6, 0xBC, 0x9F}; 
 static unsigned char conv[NUM_OF_CONV_TABLE] = 
     {0xC4, 0xD6, 0xDC, 0xE4, 0xF6, 0xFC, 0xDF}; 
     //Ä, Ö, Ü, ä, ö , ü, ß
 static unsigned char values[NUM_OF_CONV_TABLE] = 
     { 0x5B, 0x5C, 0x5D, 0x7B, 0x7C, 0x7D, 0x7E }; 

    if ( argc != 3 ) /* argc should be 2 for correct execution */
        /* We print argv[0] assuming it is the program name */
        printf( "Text Encoding Convertor: From UTF-8/ISO-8859-2, to ISO-646-DE (ASCII-DE)");
        printf( "usage: , ");
        // We assume argv[1] is a filename to open
        FILE *fileIn = fopen( argv[1], "r" );
        FILE *fileOut = fopen( argv[2], "w");

        /* fopen returns 0, the NULL pointer, on failure */
        if ( fileIn == 0 || fileOut == 0)
            printf( "Could not open file\n" );
            unsigned char x;
/*            unsigned char size;
            if (strcmp(covertToUpper(argv[3]),"UTF-8") != 0) {
            } else {
            /* read one character at a time from file, stopping at EOF, which
               indicates the end of the file.  Note that the idiom of "assign
               to a variable, check the value" used below works because
               the assignment statement evaluates to the value assigned. */
            unsigned char isUTF=0;
            unsigned char wasC3=0;
            while  ( fread(&x,1,1,fileIn)==1 )
                int i=0;
                int o=x;
             while (i Reached EOF
      If nrd <  0 --> Some kind of error */