Wednesday, December 06, 2006

Jython Quick References

Table 1. Summary of Jython data types

TypeComment Example
NullAn undefined value (like null in the Java language).None
IntegerA normal (int in the Java language) or long (BigInteger in the Java language) integer number.
-1  0  100
-1L 1000000000000000000000000000000000000000000001L

Float A fractional or exponential (like double in the Java language) number.
1.0
-1e6 0.000001e-10 1E11

Complex A pair of floats supporting complex arithmetic.
1j  -10J
2-3j 1e6j

String An immutable sequence of characters. There is no character type (use one character strings instead).
"a string"
'a string'
"""a long (possibly multi-line) string"""
'''another (possibly multi-line) long string'''
r'''^xxx(.*?)\.yyy(.*?)\.zzz(.*?)\.$'''
'x' "y" '\n' "\\"

Range An immutable sequence of integers.
range(10)
range(10,0,-1)
xrange(1,100000,10)

Tuple An immutable sequence of any type (like java.util.Collections.unmodifiableCollection(someList)).
()  (1,)  (1,2,3)
(1, "mixed", 2, "tuple")
((1,2),(3,4))

List A mutable sequence of any type (like java.util.ArrayList).
[]  [1]  [1,2,3]
[1, 'mixed', 2, 'list']
[[1,2],[3,4]]

Map A mutable collection of items (name/value pairs) (like java.util.Map). Names must be immutable and unique; values may be None.
{}
{1:'one',2:'two',3:'three'}
{"one";1, "two":2, "three":3}
{"x":1, "ints":(1,2,3),
"name":{"first":"Barry", last":"Feigenbaum"}}

Boolean A true/false value based on other types. false - 0 or empty:
None
0 0.0
() []


true - non-0, not empty:
1  -1  0.0001
[1] [1,2,3] {"greeting":"Hello!"}

Function Any function. Functions do not need to be members of classes.
lambda x: x > 0

def isPositive(x): return x > 0

def addem(x,y,z):
return x + y + z

Class Any class. Classes are namespaces for class attributes and functions (called methods).
class MyClass:
x = 1
y = 2

class subclass(superClass):
def method1(self): ...

def method2(self, arg1, arg2): ...

Module A source file (and namespace) that contains variable, function and/or class definitions. Any .py file that defines importable variables, functions and/or classes. If it does not define any of these then it is just called a script.


Back to top


Statement types

Jython provides the statement types summarized in Table 2.

Table 2. Summary of Jython statement types

Statement Comment Examples
Expression Any expression. The results are discarded. Often used for their side effects.
(1 * 2) ** 3 / 4

"string"[2:] == "ring"

someFunction(1, 2, 3)

Assignment Assigns an expression to a target.
x = 3
x = f(1,32,3) * 10 + x

list[1:3] = [7, 8, 9 , 10]

Augmented Assignment Updates a target with an expression.
x *= 100

s += "…"

Unpacking Assignment Assigns elements of a sequence to multiple targets; very convenient for access to tuple and list members. Note that the expression 1,2,3 is a short form of (1,2,3).
x,y,z = 1,2,3

Multiple Assignment Assigns the same expression to multiple targets.
z = y = z = 10

Pass No operation.
pass

If
If/Else
If/Elif/Else
Conditional processing.
if x < 0: x = -x

if x == 3:
print "It's three!"

if x == 1: ...
elif x == 2: ...
elif x == 3: ...
else: print "Bad value " + x

While Looping over a condition.
x = 10
while x > 0:
print x
x -= 1

For Iterates over a sequence. Use range to iterate over a numeric sequence.
for i in range(10): print i

for c in "A string":
print c

for i in (10, "Hello", 1e6):
print func(i)

Continue Advances to the next loop (while/for) iteration.
for i in range(10):
if not testOk(i):
continue
:

Break Exits a loop (while/for)
for i in range(10):
if testBad(i):
break
:

Delete Removes a variable or sequence element(s) or class attribute.
del x

del list[3:5]

del x.attr1

Global Declares a reference to a global value; used in functions.
x,y,z = 0,1,2
def f(a,b,c):
global x,y,z
:

Print Prints expression(s) to a stream.
print "Hello World!"
print "Hello","World!"
print "Hello" + ' ' + "World!"

msg = "Name: %(last)s, (first)s"
data = {'last':"Feigenbaum", 'first':"Barry"}
print >>out, msg % data

Assert Asserts a condition is true.
def process(v):
assert v > 0, "Illegal value %i" % v
:

Import Imports all or part of a module.
import sys
from sys import argv
from javax import swing
from java.util import Map

Execute Executes a string/file as a subprogram. There is also a related function, exec, that executes a constructed string and returns its result. This support allows you to dynamically create programs.
globals = {'x':1, 'y':2, 'z':3}
locals = {'list':(1,2,3)}
code = "print x, y, z, list"
exec code in globals, locals

Try/Except Executes code within an exception handler.
try:
x = int(string)
except ValueError, e:
x = 0

Try/Finally Executes code with a cleanup routine.
f = open("test.dat")
try:
lines = f.readlines()
finally:
f.close()

Raise Creates and throws an exception.
def factorial(x):
raise ValueError, "x must be > 0"
:

Define Defines a function; arguments may be optional and/or keywords; Functions are generic which allows for very flexible programming.
def f(x,y=2,z=10): return x+y+z

q = f(1,2) + f(3) + f(4,5,6)
s = f("a","b","c")

Return Returns from a function with an optional value.
return 10

Class Defines a class (a container for attributes and methods) .
class X: pass

class MyClass(SomeClass):
pass



Back to top

Tuesday, November 28, 2006

Reading and Editing Registry Keys

First, you need to import Microsoft.win32.

Sample code for edit the registry

Public Shared Sub UpdateiPhysicalFlagTo0()
Dim regConnectionKey As RegistryKey
regConnectionKey = Registry.LocalMachine.OpenSubKey("key here", True)
If (regConnectionKey Is Nothing) Then
regConnectionKey.Close()
Else
Try
regConnectionKey.SetValue("FirstTimeTrain", "0")
regConnectionKey.Close()
Catch er As Exception
Throw New Exception(er.Message)
End Try
End If
End Sub

Sample code for reading registry

Public Shared Function GetRegistryFirstTimeTraining() As Boolean
Dim bool As Boolean = False
Dim regConnectionKey As RegistryKey
regConnectionKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\SQLView\\DMSConnection")
If (regConnectionKey Is Nothing) Then
Throw New Exception("GetRegistryFirstTimeTraining() : The registry key is not found")
Else
Try
Dim vr As String
vr = regConnectionKey.GetValue("FirstTimeTrain")
regConnectionKey.Close()
If (vr.ToString() = "1") Then
bool = True
End If
Return bool
Catch er As Exception
Throw New Exception(er.Message)
End Try
End If
End Function

Thursday, November 23, 2006

IDIOTIC Me Missing Dlls

When an application I was developing failed to work in the deployment area, I struggled hard to find the bug, and the clause of the problem.

Like most novice programmers, I concentrated on the code, twinking here and there, trying to get it working. But tried as I might, I could not find the clause of the problem. Finally I could not bear it any longer, approached my supervisor for help to trace the problem.

My supervisor, Sindy, is a smart lady, who immediately look at the dll.. And discovered that one dll is missing from the deployment package. When she inserted the missing dll, the whole thing work well.

Lesson Learnt and Humble pie eaten: Always check the dll when you are deploying to a the deployment area to make sure no missing dll. This save you a lot of time in the long run. Missing dlls are very hard to trace and problematic.

Sunday, November 19, 2006

Oracle and Autonumber



Oracle does not have an autonumber like SQLServer has. Oracle's way to for autonumbers is using sequences and triggers. The sequence makes sure that unique numbers are generated while the trigger fills the these numbers into the column for which an autonumber is desired. This is demonstrated in the following.
I need a table with a autonumber column. In this case, it will be column id.
create table tbl_autonumber(
id number primary key,
txt varchar2(20)
);
Then, the sequence:
create sequence seq_autonumber;
And the trigger. It fires whenever a new record is inserted and assigns the sequence's next value (using nextval) to :new.id.
create trigger trg_autonumber
before insert on tbl_autonumber
for each row
begin
select seq_autonumber.nextval into :new.id from dual;
end;
/
Now, three records are inserted:
insert into tbl_autonumber (txt) values('bar');
insert into tbl_autonumber (txt) values('baz');
insert into tbl_autonumber (txt) values('qqq');
select * from tbl_autonumber;
The trigger did its job and filled id with unique values:
        ID TXT
1 bar
2 baz
3 qqq
Now, trying to circumvent the 'autonumber' and specify an aribtrary id:
insert into tbl_autonumber (id, txt) values(100, '###');
insert into tbl_autonumber (id, txt) values(200, '???');
insert into tbl_autonumber (id, txt) values(300, '!!!');
Doesn't work, is overwritten by trigger!
select * from tbl_autonumber;
        ID TXT
---------- -------------------------
1 bar
2 baz
3 qqq
4 ###
5 ???
6 !!!
Changing the trigger and ...
create or replace trigger trg_autonumber
before insert on tbl_autonumber
for each row
begin
if :new.id is null then
select seq_autonumber.nextval into :new.id from dual;
end if;
end;
/
.... trying again to overrule the trigger:
insert into tbl_autonumber (id, txt) values(111, 'This');
insert into tbl_autonumber (id, txt) values(222, 'should');
insert into tbl_autonumber (id, txt) values(333, 'work');
And indeed, it worked. However....
select * from tbl_autonumber;
        ID TXT
---------- --------------------------------------
1 bar
2 baz
3 qqq
4 ###
5 ???
6 !!!
111 This
222 should
333 work
.... it should be clear that it is a bad idea to supply primary keys if there is a sequence.

Thursday, October 19, 2006

How to custom define ApplicationExit Event

In the main() method, before calling the application.Start.Run() or Application.Run() methods,
include the following line of code

AddHandler Application.ApplicationExit, AddressOf OnApplicationExit

Include another method in the application as follows

VB:
Private Sub OnApplicationExit(ByVal sender As Object, ByVal e As EventArgs)
'your code here.
End Sub
C#:
private void OnApplicationExit(object sender, EventArgs e) {
// Your code here.
}

Tuesday, September 19, 2006

Could not load file or assembly 'CrystalDecisions.CrystalReports'

I managed to get hold of Visual Studio 2005, and like any new programmers, I was rubbing my hands in glee at getting the latest toolkit for development.

When I tried to open an existing file in Visual Studio 2005, it prompted me to upgrade to the .NET framework and create a new webconfig file. Then my nightmare with debugging begins, especially with Crystal Reports. In particular, this error got me stumped

Could not load file or assembly 'CrystalDecisions.CrystalReports.Engine visual studio 2005 .

The error occurs in the web.config file.

add assembly="CrystalDecisions.CrystalReports.Engine, Version=10.2.3000.0, Culture=neutral, PublicKeyToken="

I tried everything I knew, googling it, getting deployment packages from BusinessObjects etc. But none of them work as all I want is to compile my code without the darn error and make sure the migration to .NET 2.0 is successful.

So after sitting in the dark without a clue to what the error may be for an hour and fed up with reading tons of articles that don't work, I decided I have enough of googling and time to do something. As a first step, I open the bin folder, and check the Crystall report dll. Oops! There is the darn error! The version number for the old dll is 9.1.9800.9 and the assembly version is 10.2.3000.0! So I delete all the dll, and add the new CrystalReport dll.

To my surprise, Visual Studio version number is higher than what the assembly version is 10.2.5150.0. Thinking myself smart, I did what I think is right and changed the assembly in the web.config file to

add assembly="CrystalDecisions.CrystalReports.Engine, Version=10.2.5150.0, Culture=neutral, PublicKeyToken="

Then I found out that there is no such assembly in the .NET 2.0. Only the Version 10.2.3000.0 is there in the assembly. All attempts to add the new version into the assembly failed. Since I cannot edit the assembly, I tried changing it back the original version:

add assembly="CrystalDecisions.CrystalReports.Engine, Version=10.2.3000.0, Culture=neutral, PublicKeyToken="

And hey pesto, everything suddenly can compile!

Morale of story: Make sure your dlls in the bin directory in your new .NET 2.0 application is updated to the latest version and leave the assembly code in the web.config file alone. It saves you a lot of pain in migrating to .NET 2.0.

Sunday, September 03, 2006

How to send Email using C#

In order to send email in C# in ASP.NET 1.1., do the following:
using System.Web.Mail;

// create mail message object
MailMessage mail = new MailMessage();
mail.From = ""; // put the from address here
mail.To = ""; // put to address here
mail.Subject = ""; // put subject here
mail.Body = ""; // put body of email here
SmtpMail.SmtpServer = ""; // put smtp server you will use here
// and then send the mail
SmtpMail.Send(mail);


In ASP.NET 2.0, the MailMessage class and Smtp.Mail is obsoleted. Instead, you have to use the following code:

public static void CreateTestMessage4(string server)
{
MailAddress from = new MailAddress("ben@contoso.com");
MailAddress to = new MailAddress("Jane@contoso.com");
MailMessage message = new MailMessage(from, to);
message.Subject = "Using the SmtpClient class.";
message.Body = @"Using this feature, you can send an e-mail message from an application very easily.";
SmtpClient client = new SmtpClient(server);
Console.WriteLine("Sending an e-mail message to {0} by using SMTP host {1} port {2}.",
to.ToString(), client.Host, client.Port);
client.Send(message);
}




Monday, July 24, 2006

How to store the database connection in webconfig file in ASP.NET

ASP.NET provides a configuration system we can use to keep our applications flexible at runtime. In this article we will examine some tips and best practices for using the configuration system for the best results.

The element of a web.config file is a place to store connection strings, server names, file paths, and other miscellaneous settings needed by an application to perform work. The items inside appSettings are items that need to be configurable depending upon the environment, for instance, any database connection strings will change as you move your application from a testing and staging server into production.

As an example, let’s examine this appSetting entry in the web.config file to hold our connection string:

<appsettings>
<add key="ConnectionInfo" value="Data Source=Annapurna;Initial Catalog=ISClass;User Id=isclass;Password=isclass">
<appsettings>


To read the key we use the ConfigurationSettings class from the System.Configuration namespace, as shown below.

12 private void Page_Load(object sender, EventArgs e)

13 {

14 string connectionInfo = ConfigurationSettings.AppSettings["ConnectionInfo"];

15 using(SqlConnection connection = new SqlConnection(connectionInfo))

16 {

17 connection.Open();

18

19 // perform work with connection

20

21 }

22 }

Some applications will duplicate these lines of code in many places. If we think about how the above code will evolve over time, we might see a handful of weaknesses. First, we have a hard coded string in place to fetch connection information from the web.config. Hard coded strings can be easy to mistype and difficult to track down if the key ever changes. Secondly, the code will tie us forever to the appSettings section of the web.config file. Although web.config is designed for just such a setting, we might find in the future that we need to pull configuration settings from a database, or change a setting from being application-wide to being a per-user configuration item kept in the Session or in a cookie.

Encapsulation

Let’s abstract away the source of the connection string using a class with a static property.

1 using System.Configuration;

2

3 namespace aspnet.config

4 {

5 public class Configuration

6 {

7 public static string ConnectionInfo

8 {

9 get

10 {

11 return ConfigurationSettings.AppSettings["ConnectionInfo"];

12 }

13

14 }

15 }

16 }

Now our Page_Load method looks like the following.

11 private void Page_Load(object sender, EventArgs e)

12 {

13 using(SqlConnection connection = new SqlConnection(Configuration.ConnectionInfo))

14 {

15 connection.Open();

16

17 // perform work with connection

18

19 }

20 }

The changes we made to the above code were relatively small - but powerful. Now the Page_Load function doesn’t know where the connection string comes from. We could easily change the ConnectionInfo property to retrieve the string from a different source without modifying any other code in the application. We also no longer have to remember the key string and hard code the string at various points in the application. Instead, we can utilize Visual Studio Intellisense when accessing the Configuration class to find the setting we need. The key value only appears once – inside the ConnectionInfo property – so we could again change the key name in the web.config and have only one line of code to update.

Of course this approach only works if all of the code in the application goes to the Configuration class instead of directly to web.config to retrieve settings. For each appSetting entry added to web.config we would add a corresponding property to the Configuration class.

Another advantage to this approach becomes apparent if we have an application setting that is not a string, but a date, integer, or other primitive type. In this case we could have the corresponding Configuration property parse the string from the web.config file and return the appropriate type.

You’ll notice we provided a read-only property for ConnectionInfo. The web.config file is not designed for constant updates. When an ASP.NET application launches a watch is put on the web.config file. ASP.NET will detect if the web.config changes while the application is running. When ASP.NET detects a change it will spin up a new version of the application with the new settings in effect. Any in process information, such as data kept in Session, Application, and Cache will be lost (assuming session state is InProc and not using a state server or database).


Friday, July 14, 2006

How to Enter Symbols into Window Forms or ASP.NET web pages

Letters with Accents

This list is organized by Accent type. To determine the appropriate numeric code, match the accent with the vowel.

Accent A E I O U Y
Grave
(Cap)
À
0192
È
0200
Ì
0204
Ò
0210
Ù
0217

Grave (Lower) à
0224
è
0232
ì
0236
ò
0242
ù
0249

Acute
(Cap)
Á
0193
É
0201
Í
0205
Ó
0211
Ú
0218
Ý
0221
Acute (Lower) á
0225
é
0233
í
0237
ó
0243
ú
0250
ý
0253
Circumflex
(Cap)
Â
0194
Ê
0202
Î
0206
Ô
0212
Û
0219

Circumflex (Lower) â
0226
ê
0234
î
0238
ô
0244
û
0251

Tilde
(Cap)
Ã
0195
-- Ñ
0209
Õ
0213
--
Tilde (Lower) ã
0227
-- ñ
0241
õ
0245
--
Umlaut
(Cap)
Ä
0196
Ë
0203
Ï
0207
Ö
0214
Ü
0220
Ÿ
0159
Umlaut (Lower) ä
0228
ë
0235
ï
0239
ö
0246
ü
0252
ÿ
0255

Example: To input the acute a á (0225), hold down the ALT key, type 0225 on the numeric keypad, then release the ALT key.

If you are having problems inputting these codes, please review the instructions for using the codes at the bottom of this Web page.

Other Foreign Characters

These include special punctuation and unique consonant and vowel symbols.

SYMBOL NAME CODE NUMBER
¡
Upside-down exclamation mark 0161
¿ Upside-down question mark 0191
Ç, ç French C cedille (caps/lowecase) 0199
0231
Œ,œ O-E ligature (caps/lowecase) 0140
0156
ß German Sharp/Double S 0223
Ø,ø Nordic O slash (caps/lowecase) 0216
0248
Å,å Nordic A ring (caps/lowecase), Angstrom sign 0197
0229
Æ, æ A-E ligature (caps/lowecase) 0198
0230
Þ, þ Icelandic/Old English Thorn (caps/lowecase) 0222
0254
Ð, ð Icelandic/Old English Eth (caps/lowecase) 0208
0240
« » Spanish/French quotation marks 0187
0171

Currency Symbols

SYMBOL NAME CODE NUMBER
¢ Cent sign 0162
£ British Pound 0163
Euro currency 0128
¥ Japanese Yen 0165
ƒ Dutch Florin 0131
¤ Generic currency symbol 0164


Math Symbols

SYMBOL NAME CODE NUMBER
÷ Division sign 0247
° Degree symbol 0176
¬ Not symbol 0172
± Plus/minus 0177
µ Micro 0181

Other Punctuation

These incude copyright symbols and special section marks.

SYMBOL NAME CODE NUMBER
© Copyright symbol 0169
® Registered symbol 0174
Trademark 0153
List Dot 0149
§ Section Symbol 0167
en-dash 0150
em-dash 0151
Paragraph Symbol 0182

Using the Codes

Windows assigns a numeric code to different accented letters, other foreign characters and special mathematical symbols. For instance the code for lower case á is 0225, and the code for capital Á is 0193. The ALT key input is used to manually insert these letters and symbols by calling the numeric code assigned to them.

To use the codes:

  1. Place your cursor in the location where you wish to insert a special character.
  2. Activate the numeric key pad on the right of the keyboard by pressing Num Lock (upper right of keyboard). The Num Lock light on the keyboard will indicate that the numeric key pad is on.

    NOTE: You must use the numeric key pad; if you use the number keys on the top of the keyboard, the characters will not appear. If you are on a laptop or computer without a separate numeric keypad, other methods are recommended.
  3. While pressing down the ALT key, type the four-digit code on the numeric key pad at the right edge of the keyboard. The codes are "case sensitive." For instance, the code for lower-case á is ALT+0225, but capital Á is ALT+0193.

    NOTE: If you have the International keyboard activated, you will only be able to input codes with the ALT key on the left side of the keyboard.
  4. Release the ALT key. The character will appear when the ALT key is released.

    NOTE: You must include the initial zero in the code. For example to insert á (0225) you must type ALT+0225, NOT ALT+225.


Wednesday, July 12, 2006

How do I enter a null date into the database?

Make sure that the System.Data.Namespace is included.

include System.Data.SqlType;

In the command parameters to be parsed into database, use SqlDateTime.Null:






public void InsertDateOfBirth(string Date1){
SqlConnection cn = new SqlConnection();
string sqlstring = "Insert into Database1 values (@birthday)";
SqlCommand cmd = new SqlCommand(sqlstring, cn);
cmd.Parameters.Add("@birthday", SqlDbType.DateTime);
try
{
cmd.Parameters["@birthday"].Value = DateTime.Parse(Date1);
}
catch (Exception er)
{
cmd.Parmeters["@birthday"].Value = SqlDateTime.null;
}
try
{
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
catch (SqlException sqlerror)
{
Console.WriteLine(sqlerror.Message);
}
catch (Exception er1)
{
Console.WriteLine(er1.Message);
}
}

Tuesday, July 04, 2006

Common Project Management Pitfalls part 1



This is a multi-part article about common project management pitfalls.


Why is it that for most IT Projects, it is often difficult to meet the projected datelines, and deliver the system within time, budget and specification constraits? Indeed, as any project manager who is worth their weight in salt can testify, IT projects seldom, if ever meets the dateline, budge and specification. In fact, a study by the Standish Group Report (1995) shows that some 83.8% of projects are either challenged (the project is completed, but over-budgeted, over time-estimated or offers fewer features and functions than originally specified) or impaired (the project is canceled at some point during the development cycle). This has lead many project managers to dispair when things failed to go their way. What are the common causes of this problem?

Project objectives not fully specified / Poor Communications

Surprisingly, a study by Pete Marwick (1998) found that 51% of projects planning fails because the project objectives is not fully specified and poor communication between the client and the system analyst. There are many reasons why the project objectives are not fully specified or well-detailed. Below list some of the common pitfalls that lead to project failure under this catergory.
  • Lack of Project Methodology to plan the deliverables
    Project Methodology refers to the way in which the project is done. Most software development projects follow a project life cycle - the collection of project phases. A Software Development Life Cycle is a framework for describing the phases involved in developing and maintaining information systems. It provides a consistent and effective approach for undertaking projects. Without a clear Project Methodology or Software Development Life Cycle, it is difficult to impossible to plan for a job.

    A clear framework or Software Development Life Cycle model to follow makes it easy for programmers and IT consultants to understand the job scope, and what the deliverables are at each stage. For instance, at the Requirements Specification phases in the waterfall model, the deliverables are all the requirements of the system, sample user interfaces, and the flow of events (sequence diagrams, event diagrams or flowcharts). With a clearly defined project objectives signed by both parties, it makes it easier to agree on the project objectives. Without doubt, one of the first objective of any solid project management plan is to plan for and agree on the project requirements.

  • Analyst failed to understand client's requirements and understand client's needs.
    It is my opinion that the planning and agreeing on the project requirements phases is the most important part of the project life cycle. Finding out why the client wants a system, what type of system he is looking for, what type of software/hardware he needs is one of the most critical stages in the software development phases. By understanding the needs of your clients and putting it in writing, you can constantly review if the design of the UI meets their needs. Gathering information such as samples of previous work, documentations, interviews, surveys and other information prior to starting the work is essential to confirm what you will be doing, and scope of the project. Many project manager failed to see this as the most important part of the project, and allocated too little time to this phase. How are you going to plan and propose an effective system for your clients if you do not understand what is required?

    Do allow at least 1 week to ensure that you understand all the documentations and process involved in the system, and the job scope. Only and only then can you begin to plan how long the project will take.

    One good way of ensuring that you understand your client's business process is to draft a flowchart of the sequence of diagrams for each process. By doing so, you are confirming what you think is the way the process work against what the process actually work. Most clients happily point out your mistakes, so present your findings and ask them to clarify any doubtful points. Once there are no more obstacles, get your client to sign the documentation confirming that is the actual flow of events.

  • User Design is not what the clients wants...

    Once the scope of project is confirmed, the next most important item is to draft the user interface. Those who just jump straight into programming without a drafting the user interface is in for a lot of re-coding work - especially when your user interface is flatly rejected by the client later on. Your user interface speaks volume of what you think what the clients want and need against what he actually needs. By providing a good user interface, both of you are agreeing on the scope of the work, and how the data should be presented.
    The client should sign off the user interfaces to show that he accepted the UI design.

  • Failure to check with client the actual data stored

    The next most essential phase of the project is the design phases. Before you go on to conduct class diagrams, sequence diagrams etc, the first thing you need to do is to design the database first. The database should take in account all fields in the UI design. The primary key, a description of key flags (e.g. status: p = pending, c = completed, a = approved, r= rejected), and any foreign keys should be identified. Each table should have a short description of what information it stores. Finally relationship diagram should be drawn for easy referencing. By confirming with your client what type data are actually stored and can be retrieved, it helps to prevent problems later on, especially when they need some more data that is not stored (believe me, this is darn common).

  • Planning the Project Timeline.

    Once all documentations above has been signed off, only and only then can the project datelines, deliverables and budget be planned and controlled with any good chance of completing the project on time and on budget, with all features and functions as initially specified. A common mistake many new project manager makes is to break down the work structure accordingly to phases in the Software Development Lifecycle. While this provides a good overview of what is to be done, it is at best, fairly inaccurate. The project manager should instead further breakdown the work into sections, and allow some time for each sections. For instance, the work involved requires some 30 User Interfaces screen. Planning 1-2 days for each UI for a 3 tier development for each staff assigned helps to paint a more accurate picture of the time required for documentation and programming.

    The client should be informed of the project plan and sign off the agreement on datelines of the project. Also, it is a good communication practice to inform and update the client on project progress status on a weekly basis.

  • Documentation and Designing the Sequences Diagram, Class Diagram, Event Diagrams

    At this point, the next key step is to draft all the documentation. The sequence diagram, class diagram and event diagrams should be planned and documented prior to coding. By documenting how each class is related to one another, and planning for a 3 tier architecture, you are ensuring reusibility of class, and saving time on programming.
    Also, by doing this, you are insuring yourself against changes in business logic or database structure. When such change are required, they can be implemented with minimum effort by identifying which classes are affected by the changes.

    Many programmers hate this step and in some companies, this step is often left until all the programming has been done.

  • Frequent changes to the project specification

    Let's face it, the client is human too, and human has a tendency to change their mind. The worse clients are those who have no clue to what they want and frequently change their mind - because once the system is coded and development is under way, the system is often inflexible and the changes to the coding or database are often tedious and time-consuming. This is especially so when a small change in code or database can lead to all sorts of bugs can pop out elsewhere in the program, and tons of re-editing the documentations is required. By getting the work flow, user interface and database signed off, you are protecting yourself against any changes to project specifications.

    Should your client insist on the changes after all the specifications have been signed off - it is best to evaluate if the change can be implemented with minimum inconvenience. This is where all the documentations come in handy - review the documentation to see if the changes will affect several classes or isolated to one or two classes. If the changes can be implemented with minimum effort, it should be incorporated into the system - building a good relationship with a client is important. However, if the changes required is medium to heavy in effort, it is often required to politely but firmly inform the client that these changes are not in the requirements, as per the signed off UI, database and project plan, but you can implement them for an added fee - it is not good business to engage in a losing preposition. Also, there will be a delay in schedule to accommodate the changes required. Often the increase in budget and delay in delivering the system will make the client think twice if the changes to be implemented are essential or just a whim on his side. Even if the changes is to be incorporated into the system, there is some benefit for your organization in terms of increased timeline and profits.
In the next part of this series, I will cover the common pitfalls of bad planning and estimating.

Monday, July 03, 2006

Sun Java IDE

Sun Java developers new IDE (Integrated Developer Environment) is available for FREE at http://developers.sun.com/prodtech/javatools/jsenterprise/index.jsp :)

It automatically creates class diagrams, UML, sequence diagrams, with intellisense (Java Version) + UI design and best of all, it is free! It comes with a neat, easy to use UI for developing JSP, EJB code quickly and effectively.





Saturday, July 01, 2006

Connection Strings

These connection strings are for .NET programming environment which can be connected to a wide variety of database. Below are some of most common connection strings

MSSQL Server
  • SQLServer
    "Data Source=MSSQLServerName;Initial Catalog=Northwind;User Id=id;Password=password;"
  • OleDbServer
    "Provider=sqloledb;Data Source=MSSQLServerName;Initial Catalog=Northwind;User Id=id;Password=password;"
MS Access
  • Standard
    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;User Id=admin;Password=;"

  • With Password
    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;Jet OLEDB:Database Password=MyDbPassword;
Oracle
  • ODBC
    "Driver={Microsoft ODBC for Oracle}; Server=OracleServer.world; Uid=Username;Pwd=password;"
  • OLE DB
    "Data Source=MyOracleDB;User Id=username;Password=passwd;Integrated Security=no;"
MySQL
  • OLE DB
    "Provider=MySQLProv;Data Source=mydb;User Id=UserName;Password=asdasd;"