Friday, May 14, 2010

How much agile should we be?

First, I should make it clear that I'm talking about building a middle size website, such as, say for a news agency.

Until now, I thought that it's so great to be agile.
Yay, let's sign the contract with the customer, for a slightly overrate price, screw documents, we'll play by ear, the customer is always there (phone call, frequent meetings), so no worry.
But....
I've learned that particularly bad things will happen to you if you do this, especially when you tell the customer about agile, and change and so on.
What happens, is basically, that the customer will ask you to build a different site each iteration, most likely because they have no idea what they want, and what a usable website looks like. They will progressively destroy the nice, clean design your CSS team has made (they will hate the whitespace, and keep adding more and more ads). After that they will also delete any sort of logic and flow there may have been.

I have found the following changes, most devastating to such a plan:
. Changes to page layouts: Adding boxes being the most frequent, changing around places, etc.. will have your CSS team confused, and you will be monkeypatching your html templates in no time.
. Changes to database schema: Call me old school, or whatever, but changing your database schema, will take time. More time than it's worth, especially if you need to change; I mean not add or delete something, but change things, and already have lots of data to migrate.
. Changes to "types" and "categories" that the website handles: Often special functionality is required for each "type", each shows in a box, some are searchable, etc... Each comes with it's own newly made (in 3.2 minutes by the customer) business rules that most likely don't make sense or fit in with the other rules (each made up in 3.2 minutes).
. Overhaul of the UI style: Doesn't fit well with having a separate CSS team.

So, guess what?
For the next project, I will do some requirements, and have the customer sign them. Wants these to change? Too bad, next contract. I don't have that sort of time, for that sort of business style.

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.