Saturday, November 7, 2009

On maintaining legacy code

I have been assigned the horrifying task of making some "minor" changes to a "php goo" site.
It is a true horror movie. After reaching this part of code in a file named 'functions.php' (wow informative), I performed the most important refactoring ever.

switch($type){
case 'card':
$filter = ' AND (prdct_productattribute.context = "Card Printer" OR prdct_productattribute.context = "PVC Cards" OR prdct_productattribute.context = "CardReader" OR prdct_productattribute.context = "Hospital Bracelet" )';
break;
case 'bracelet':
$filter = ' AND prdct_productattribute.context = "Hospital Bracelet"';
break;
case 'acc': // !! I hate your coding I hope you die
case 'ribbon':
$filter = ' AND prdct_productattribute.context = "Ribbons"';
break;

Although what you are seeing is only a minor, abbreviated view of the idiosyncrasy abundant in the code base, the author thought it was ok just to drop 2 cases above each other since the 'acc' (which is a parent of the 'ribbon' type) happens to only contain a single child, 'ribbon'.
The refactoring which is the most important is the comment I added. It made me start to refactor the whole thing. I am going to hate myself later on since the pay isn't worth it.
I am leaving the comment in the code base, period.

Tuesday, October 27, 2009

Anti If Campaign, I'm in!

I joined the anti-if campaign.
It's about raising awareness about using object oriented code style instead of letting type checking ifs creep through the code base.


I have joined Anti-IF Campaign

Saturday, September 19, 2009

Checked Exceptions vs. Automated Testing -- you judge

There was this interesting post I came across on Google testing blog which you can seehere.

Among the other interesting posts you can see in the area, my personal belief is that:
1. Many exceptions of the standard library should go unchecked
2. Use of checked exceptions have made the use of an IDE for java development a must (and rather replacing documentation).
3. Checked exceptions, very much like static typing, are just one of the possible tests. Why don't we just write complete tests (which we should be doing anyways) instead of boilerplate code?

Edit: I'm in love with the other blog's motto. Debugging sucks, testing rocks. One up google!

Wednesday, September 16, 2009

Web Application in 4 days -- Lessons learned

After doing this project under such pressure, a number of lessons were learned.

(.) Do use a web framework. One that let's you get working quickly
(.) ERDs are absolutely necessary. When drawing your ERD, you should consider your ORM capabilities. It will prove to be more essential than having your ERD in 3NF.
(.) Your ORM will help you a lot of places, but fail in a couple. Know how to work with your low level SQL API.
(.) Performance is a non-issue. Code, Code, Code...
(.) Project management is harder than coding. Don't spend valuable development time of your team, reading books.
(.) Django should be DRYer.
(.) DRY your code. Don't underestimate it
(.) If you are writing lots of "if"s, refactor, refactor.
(.) Tests are so important. Don't skip them.

Web Application in 4 days

Is it secure? No. Is it foolproof? No. All bugs fixed? No. Did it happen? Yes.

Team: Me. (Backend) 2 Friends (View).

Day 1
(T=0) Language changed from java/spring to python/django.
(+0 hr) Models created based on previously drawn ERD.
(+2 hr) Working "document view" system implemented. Models upgraded.
(+2 hr) "Static" directory created for HTML/CSS coders.
(+3 hr) edit, new , delete document abilities added
(+1 hr) Switched from manual post handling to framework form module.
(+1 hr) Initial HTML commit
Estimated effort of me: 6 hrs

Day 2
(+17 hr) Support for different data types added to project
(+5 hr) Data type support complete
Estimated effort of me: 4 hrs

Day 3
(+20 hr) Initial works on search functionality
(+4 hr) HTML/CSS upgrade
(+0 hr) Forms working
(+2 hr) More view stuff
(+1 hr) Simple reporting
(+1 hr) Bug fixes
(+8 hr) View
(+1 hr) More view (at this point an initial demo of the project is given)
(+2 hr) More view
(+4 hr) I ping the view developers with this commit!
(+1 hr) DB patch-up, I did some JS.
(+0 hr) More incoming work from view team
(+1 hr) commit with support for edit of document type
(+1 hr) Did I do this commit? (Log: eeeeee.)
(+2 hr) Same as above....
(+0 hr) Views upgraded
(+1 hr) User creation added
(+1 hr) UI for document designer added
(+1 hr) Rc1 announced :D
(+0 hr) Some little changes
(+0 hr) Some more little changes
Estimated effort of me: 10 hrs

Total estimated effort of me: 20 hrs (backend development)
Result: Satisfactory

Tuesday, June 30, 2009

Why Python (2)

The next features of Python that I chose to rant on are ones that come from functional languages. These are what provide a lot of power and short syntax to Python. The first and most important of them are first order functions. This allows us to treat functions as any other normal argument or return value, which is an important concept that allows us to write smaller code with "high order functions", or functions that take functions as arguments. The full support of closure adds to this feature.

def adder(n):
def f(x):
return x + n
return f
f = adder(4)
print f(3)


This is an example of a function returning a function and taking a closure. This behavior is also somewhat possible in Java if we use syntax like:

class Demo {
public void test() {
Adder t = new Adder(4);
System.out.println(t.f(3));
}
}

class Adder {
private int n;
public Adder(int n) {
this.n = n;
}
public int f(int x) {
return x + n;
}
}
but it seems somewhat awkward; this method will also introduce an interface or abstract class into our type system for each time we want to do this.
In particular there are some important high-order functions in functional languages such as map and filter. Map takes a list and a function and applies the function to all of the elements of that list. Filter takes a list and a function and returns a list containing elements that cause the function to return true. Python provides support for these functions and a special shortcut for it called list comprehension. See this example:

L = [x+2 for x in L if x > 0]


This small example would looks very weird in Java, since it would involve removing items from a list and otherwise appending 2 to them, a simple thing that comes to mind is:

for (int i = 0 ; i < L.size(); ) {
int value = L.get(i);
if (value > 0) {
L.set(i, value+2);
++i;
} else {
L.remove(i);
}
}
This is exactly one of the most important ways that Python looks better than such languages, and the difference is real, consider quicksort:

def quicksort(L):
if L == []:
return []
key = L[0]
return quicksort([x for x in L if x < key])
+ [x for x in L if x == key]
+ quicksort([x for x in L if x > key])

This it a copy paste quicksort implementation I found on the net for Java:

int partition(int arr[], int left, int right) {
int i = left, j = right;
int tmp;
int pivot = arr[(left + right) / 2];
while (i <= j) {
while (arr[i] < pivot)
i++;
while (arr[j] > pivot)
j--;
if (i <= j) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
};
return i;
}

void quickSort(int arr[], int left, int right) {
int index = partition(arr, left, right);
if (left < index - 1)
quickSort(arr, left, index - 1);
if (index < right)
quickSort(arr, index, right);
}
This difference in length of code and obviousness of what is going on will present itself in real situations.

This rant will continue.

Monday, June 29, 2009

Please use a web framework!

I have always been hyped over discussions about which framework is better and why. Today, I encountered a very weird debate regarding ditching web frameworks. Previously I have heard of making self-designed ones, but this one totally knocked my socks off. Then suddenly I realize there are lots of coders out there who still code this no-framework style.

Therefore I will list some reasons why we need a framework,
  1. Less code. As you may have noticed, writing boilerplate code, that handles incoming requests, deals with HTTP headers, HTML, basic parsing, low level SQL connections to databases is very boring. It also is very error prone. Above all, good news, it has already not only been accomplished, but also this code will improve and debug itself. Programmer (your) time is very expensive, I'm sure you have better things to do (such as writing code that provides you with entertainment or income).
  2. Such frameworks are coded by different people, and they may have had more expertise on the topic of their code. For example, ORM code is nothing to joke with. It requires specific knowledge of how SQL works on different systems as well as internal aspects of the programming language. It is more likely that the solution available in a framework has been debated over in mailing lists and seen many tweaks and hacks.
  3. Security. Open source frameworks with peer review are often more secure than locally hacked solutions
  4. Reinventing things. Some argue that use of frameworks will remove flexibility and performance. Well, bad news, so does using a high level language, so we might as well code all web apps in pure C, or assembler, how about taking advantage of GPU processing for web requests? And we should write our own OS, you know, the way the TCP stack is handled may be important. Or new interpreters and compilers. Often CPU microcode can be upgraded as a part of a web project to increase performance.
  5. Worldwide success. Success and rapid development (almost explosive in case of Rails) of many frameworks from Java land to PHP, Python and Ruby and any other language used for web coding shows something is happening and world reputable coders aren't playing cat's games.
The specific debate I have heard was against PHP's Symfony in favor of "pure" PHP. The first thing that I have to say here is that PHP may be easily viewed as designed to be the horror of the web coder:) SQL injections, and automatic type conversions have lead to many serious financial losses worldwide. Basically to me PHP without structure looks like a large pile of goo.

The debater points out that there is nothing new in such frameworks, all parts have been written previously. Then goes on to point out PEAR for DB Independence, but forgets to mention anything about ORM. A quick reference to the PEAR official site shows PEAR is not related to databases and is " PEAR is a framework and distribution system for reusable PHP components. "

He continues to point out that in Symfony checking authorization scripts and other validation scripts are in the heart of Symfony. This is obviously true. Anyhow as you may know, in such frameworks it is very easy to replace / ditch this code and use your own. This points out the ill understanding of such web frameworks and is probably the residue of older "closed up" frameworks at work in Javaland and .Netland.

The next point is switching to filing instead of using databases, which again is possible through frameworks, but has little reason for. He also suggests using mod_rewrite for url matching and so, but fails to indicate why it is superior to have to maintain .htaccess files as a part of your code base, which seems to me that is very unnecessary and bad.

The next attack is on Symfony's templating which is basically the same as PHP, anyhow for templating I am more favorite of limited languages such as that of Django's, anyhow the issue of power of syntax is not related to separation of code and view. He then backs smarty as a good substitute, and I agree, but don't know what sort of attack this is to frameworks.

Then he points out that there is nothing new in frameworks and has just made them easier. Yes exactly. Which is why we should use them, unless you have some sort of masochism fetish for maintaining low level code. In that case, I suggest APL.

What I am trying to point out is reuse codes, fellow programmers. Reuse, don't be afraid. Business web applications should not write code for accessing databases, manipulating strings, perform weird system calls, rewrite spellcheckers, calenders, or search engines, or database backends! They should be a simple expression of simple business logic.

It is however important to select a nice framework. The most important feature of a framework is not closing you down. You should select parts you need and ditch / replace other parts easily. Another thing I like is for frameworks to be lightweight and not impose lots of overhead. Also I hate nosy frameworks which impose a special coding style. You should also be able to have access to low level parts when you need. Such as raw sql, or, http request and response objects.

The main point I have is that being scared of change is bad; learning these frameworks are often very easy for the experienced coder. A coder that can only work with his own code is a red light for me. My POV here is that simply people who are fighting new concepts in coding, have never tried them, simply.

As a final roundup, I recommend Symfony, Rails, Django, as closely related friends, and also Spring is a nice thing in Javaland.