How you can improving your Programming Logic

Programmer is like an artist I think. Though programming is mainly associated with the field of Computer Science, but writing good and optimized code is mainly an art. So, Like all art forms programming also requires tremendous patience and rigorous practice. Some tips given below to improving your programming logic:

Tip 1: Learn the language ‘C’

You might be an expert .NET, Java or PHP developer, but I would recommend that you MUST learn ‘C. We all know why ‘C’ is the most powerful programming language, but I am not recommending learning ‘C’ to you because of its power in programming.

‘C’ offers you a structured style of programming. You have one file with the main() method and the execution begins from there and the execution flow proceeds as you have directed it to.

The main advantage in ‘C’ is that it allows you to play around with memory directly. This I believe is very important if you need to understand how data is passed from one memory block to another. The reason is that you start to visualize in your minds eye how data moves in your program.

The next step is to develop programs that will help you improve your logic.

Tip 2: Develop programs that test your mind skills Ever heard of the Fibonacci series?

Ever built a program that will allow the user to type his/her name and allow to bounce off that name on the screen from one corner to another like a ball?

Ever thought of creating a library for a Menu Bar system?

All these are examples of programs that you can develop to improve your mind and programming skills.

I remember the time I was at college and I would spends nights after nights to build my own library for screen interface for menu bars, windows, text fields, etc. In a UNIX box I would use the ncurses library and build it. I would then try and replicate the same in Windows using the conio.h file and some assembly code.

Try to develop as many programs as possible in ‘C’, this will help you improve your programming logic.

Following are some programs that I can help you with:

  1. Write a program (WAP) to find the max, min, average and total of numbers entered by the user
  2. WAP to accept a string from the user and find the number of vowels and the vowels that got repeated the most.
  3. WAP to accept an array of numbers and sort the same using Bubble Sort Algorithm.
  4. WAP to accept a string from the user and print all its permutations and combinations.
  5. WAP to accept to accept a number from the user and test if it is a Fibonacci number or not.

I can go on and on with such questions.

Tip 3: Locate code and try to understand why it was written that way

Use the internet or college library to locate code written by another developer. Try to understand why it was written that way and understand it completely. Once you have understood why it was written they way it is written, check to see if you could improve that logic.

The main objective of this exercise is to get your brain thinking.

Tip 4: Solve logic puzzles Check your local newspaper. One section of your newspaper will be filled with series of logic puzzles and riddles. Try solving them. Don’t get disheartened if you can’t solve them or take a long time to solve them. Remember that you are in the learning and improving stage. Things will be slow, but you will make progress.Your brain will be trained to think differently with every puzzle that you try to solve. This is because now you know a new method of solving. You could apply the same thinking pattern to your programs as well.

As a standard prescription, I would prescribe solving Suduku puzzles. Will help you improve your logic, concentration and skills of grouping and organizing.

Tip 5: Help other people build logic

Once you start feeling confident about yourself and your logic capabilities, you should immediately start helping people. Subscribe to a forum and start helping people there. The benefit of helping people on forums is that you get to learn new problems that people face. This immensely adds to your knowledge. Just imagine the power you would have once you start to learn problems faced by other people and how you or someone else resolved it.

I have seen friends following this advice but shying at the last moment. Why? Because they don’t want to be ridiculed in the forum. Don’t be scared of other people ridiculing you. Look at it as a learning experience. People who ridicule you would be the one’s with more experience… and learning from people who are experienced is no harm at all.

Some common programming mistakes to avoid

Every developer learn from mistake including me – heh heh. So from my long working experience some common programming mistakes given below which developer must avoid:

1. Not maintaining list of changes
Not every developer is blessed with a code repository, though it is best to have it. In development environments where code repositories don’t exist it’s important to maintain a list of changes done on the project. Changes to files, configurations, databases, images, environment settings, etc are all important pieces of informaiton that will be required at the time of deploying to staging or production environments and its a must to record these changes in a text file. Without such a text file you can imagine the outcome of deploying to production environments and missing some changes.

2. Not indenting your code

Indenting your code is very important, its ultimately you who will maintain it later. Indenting code not only helps you to structure your code better but also helps you to read and debug your code better. You should try and get a code beautifier that will help you indent all your code as per the rules defined, thus saving you time on bigger projects.

3. Improper or No comments
Can you imagine a program without comments. Just imagine how difficult it would be to read someone else’s code without comments. The reason why we as developers miss out on comments is because when we write code, we are so engrossed in developing logic that we forget this essential step. I recommend that let you develop with the flow of logic that you have and plug in comments after you finish coding. Write comments for any and all complicated logic and SQL queries. Comments will help you a long way in reviewing your code.

4. Not modularizing code
Not breaking the functionality into multiple modules/functions is a big crime. Break your code into as little form as possible to complete one logical set of functionality. Your function should do what it is intended to do, nothing more – nothing less. As a rule of thumb your code per function should not exceed one page of your screen. Exceptions to this rule do exist, but keeping this rule in mind from the very beginning of development will ensure that your code as modularized to a great extent.

5. Not reviewing your code
Once you get that big ‘AAha’ feeling looking at your code after you have completed it, it’s best to review your code immediately and try finding issues if any. You should not only review your logic but also your SQL queries. Look for instances where you have executed SELECT/UPDATE/DELETE without a WHERE clause (not a joke… this happens). For logic that is complicated you should dry run that piece of code to test if it works well.

6. Assuming Business Logic
What do we all do when we have no one from the business side to help us with Business Logic… we assume. Being proactive is good, but it could cost the client his business if you assume business logic. In situation like these its best to escalate your issues and concerns along with your assumptions to the business side and seek clarifications.

7. Not refactoring code
A silly question to ask, but here it is. How many times have our clients asked to take our sweet time to deliver a code? Well, never for me. So what do we do as developers? Develop code at the speed of thought, which results in the code being completely messed up and duplication of functions being created. I recommend that once you are done with your project and before the phase of QA begins, spend some time to refactor your code and optimize it as much as possible. This will ensure that your code is stable, reliable and reusable.

8. Not unit testing your code
Completing your code and getting ready for integration is the good part, but not unit testing your code bounces back on you when you start getting a series of integration errors. Its always better to unit test your code before you move ahead with SIT (System Integration Testing). Test functions and code separately to check if it works as desired with a range of parameters and try to automate it. Automating your unit tests will help you to execute tests whenever you make changes to your code.

9. Hard coding messages and configurations
Its bad to hard code messages and configuration parameters. This effects the flexibility to change the behaviour of the application at runtime. With scripting languages like PHP it is easy to make such runtime changes. But for applications developed in Java or .NET that are compiled and deployed, it is a daunting task that can take as much as 30 – 40 minutes for deployment.

10. Not optimizing queries
I have been guilty of this too. We as developers think that writing the best code and using the most optimum function provided by the API is the only thing to do. But, we don’t realize that the time taken to execute the script is entirely dependant on how sooner your database can serve results. Therefore, I recommend that you check all your queries with the query optimizer tool that comes along with most of the database engines.

11. Not comparing files
You should always compare the modified files with the original source base. This gives you an addition opportunity to review the code and changes done and if it confirms to business logic. Configuration and function files should always be compared to see and validate the changes that have been made.

12. Not having a backup of files before upload
Without a source control software it becomes important to that you backup important files before you upload changes. Such files should include but not limited to – configuration, database and important function files.

Design Pattern – Part 1

In software engineering, a design pattern is a general reusable solution to a commonly occurring problem in software design. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations. Object-oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved.

Patterns originated as an architectural concept by Christopher Alexander (1977/79). In 1987, Kent Beck and Ward Cunningham began experimenting with the idea of applying patterns to programming and presented their results at the OOPSLA conference that year. Design patterns gained popularity in computer science after the book Design Patterns: Elements of Reusable Object-Oriented Software was published in 1994.

Classification:

Design Patterns originally grouped design patterns into the categories Creational Patterns, Structural Patterns, and Behavioral Patterns, and described them using the concepts of delegation, aggregation, and consultation.

Creational patterns

These patterns have to do with class instantiation. They can be further divided into class-creation patterns and object-creational patterns. While class-creation patterns use inheritance effectively in the instantiation process, object-creation patterns use delegation to get the job done.

  • Abstract Factory groups object factories that have a common theme.
  • Builder constructs complex objects by separating construction and representation.
  • Factory Method creates objects without specifying the exact class to create.
  • Prototype creates objects by cloning an existing object.
  • Singleton restricts object creation for a class to only one instance.

Structural patterns

These concern class and object composition. They use inheritance to compose interfaces and define ways to compose objects to obtain new functionality.

  • Adapter allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class.
  • Bridge decouples an abstraction from its implementation so that the two can vary independently.
  • Composite composes one-or-more similar objects so that they can be manipulated as one object.
  • Decorator dynamically adds/overrides behaviour in an existing method of an object.
  • Facade provides a simplified interface to a large body of code.
  • Flyweight reduces the cost of creating and manipulating a large number of similar objects.
  • Proxy provides a placeholder for another object to control access, reduce cost, and reduce complexity.

Behavioral patterns

These design patterns are about classes objects communication. They are specifically concerned with communication between objects.

  • Chain of responsibility delegates commands to a chain of processing objects.
  • Command creates objects which encapsulate actions and parameters.
  • Interpreter implements a specialized language.
  • Iterator accesses the elements of an object sequentially without exposing its underlying representation.
  • Mediator allows loose coupling between classes by being the only class that has detailed knowledge of their methods.
  • Memento provides the ability to restore an object to its previous state (undo).
  • Observer is a publish/subscribe pattern which allows a number of observer objects to see an event.
  • State allows an object to alter its behavior when its internal state changes.
  • Strategy allows one of a family of algorithms to be selected on-the-fly at runtime.
  • Template method defines the skeleton of an algorithm as an abstract class, allowing its subclasses to provide concrete behavior.
  • Visitor separates an algorithm from an object structure by moving the hierarchy of methods into one object.

Concurrency patterns

Active Object: The Active Object design pattern decouples method execution from method invocation that reside in their own thread of control. The goal is to introduce concurrency, by using asynchronous method invocation and a scheduler for handling requests.

Balking: The Balking pattern is a software design pattern that only executes an action on an object when the object is in a particular state.

Double checked locking : Double-checked locking is a software design pattern also known as “double-checked locking optimization”. The pattern is designed to reduce the overhead of acquiring a lock by first testing the locking criterion (the ‘lock hint’) in an unsafe manner; only if that succeeds does the actual lock proceed.

The pattern, when implemented in some language/hardware combinations, can be unsafe. It can therefore sometimes be considered to be an anti-pattern.

Guarded In concurrent programming, guarded suspension is a software design pattern for managing operations that require both a lock to be acquired and a precondition to be satisfied before the operation can be executed.

Monitor object A monitor is an approach to synchronize two or more computer tasks that use a shared resource, usually a hardware device or a set of variables.

Read write lock A read/write lock pattern or simply RWL is a software design pattern that allows concurrent read access to an object but requires exclusive access for write operations.

Scheduler The scheduler pattern is a software design pattern. It is a concurrency pattern used to explicitly control when threads may execute single-threaded code.

Thread pool In the thread pool pattern in programming, a number of threads are created to perform a number of tasks, which are usually organized in a queue. Typically, there are many more tasks than threads.

Thread-specific storage Thread-local storage (TLS) is a computer programming method that uses static or global memory local to a thread.

Reactor The reactor design pattern is a concurrent programming pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers.