I completed reading 'The Pragmatic Programmer', probably one of the most recommended pieces of literature on software engineering. I'll try to put down some of the quotes and my interpretation of them in the following paragraphs. I'll be coming back to this from time to time. Hope they help you in your next software project.

The Cat Ate My Source Code

The greatest of all weaknesses is the fear of appearing weak.

Take responsibility for the code that you write and the decisions that you make, and when things go south, present options to recover from the mess instead of pointing fingers.

Software Entropy

When disorder increases in software, programmers call it "software rot."

Active efforts have to be made to keep the disorder low and go against the nature's law (of ever-increasing entropy) to keep away from software rot.

Don't Live with Broken Windows

Once there is a broken window in a building, there will be more broken windows. This is the broken windows theory. Similarly, once a piece of sloppy code enters a codebase, it will attract more sloppiness. Don't be the one to introduce a broken window into your codebase and fix existing ones as soon as feasible.

Stone Soup and Boiled Frogs

The frog just doesn't notice the change. Don't be like the frog. Keep an eye on the big picture. Constantly review what's happening around you, not just what you personally are doing.

If you throw a frog into boiling water, it will jump out at your face. But if you put the frog in cold water and boil it, it won't notice and get cooked to death. Good software projects die just like that, slowly, without anyone noticing.

Good-Enough Software

But artists will tell you that all the hard work is ruined if you don't know when to stop. If you add layer upon layer, detail over detail, the painting becomes lost in the paint. Don't spoil a perfectly good program by overembellishment and over-refinement.

Know when to stop refining a piece of software. Make tradeoffs if they improve the overall quality of your software.

Your Knowledge Portfolio

  • Serious investors invest regularly—as a habit.
  • Diversification is the key to long-term success.
  • Smart investors balance their portfolios between conservative and high-risk, high-reward investments.
  • Investors try to buy low and sell high for maximum return.
  • Portfolios should be reviewed and rebalanced periodically.

Think about your knowledge portfolio as investors think about their investment portfolio.

Communicate!

It's not just what you've got, but also how you package it. Having the best ideas, the finest code, or the most pragmatic thinking is ultimately sterile unless you can communicate with other people. A good idea is an orphan without effective communication.

Learn to communicate with different kinds of people, technical and non-technical alike.

The Evils of Duplication

DRY (Don't Repeat Yourself) principle: EVERY PIECE OF KNOWLEDGE MUST HAVE A SINGLE, UNAMBIGUOUS, AUTHORITATIVE REPRESENTATION WITHIN A SYSTEM.

Documents are no exception. Don't duplicate business logic in code AND documentation. There should be one true source of knowledge (model) and the others should simply be views of that source.

Orthogonality

In computing, the term has come to signify a kind of independence or decoupling. Two or more things are orthogonal if changes in one do not affect any of the others.

The code you write has to be as decoupled from the rest of the project as possible. It makes bugs easier to find. There should never be overlapping functionality or duplicate code (also a violation of the DRY principle).

The Basic Tools

Every craftsman starts his or her journey with a basic set of good-quality tools.

Selecting a good set of tools can greatly improve your productivity and skills.

Source Code Control

Always Use Source Code Control

Even on single person projects that's never going to see the light of the sun.

Debugging

Embrace the fact that debugging is just problem solving, and attack it as such.
The best way to start fixing a bug is to make it reproducible. After all, if you can't reproduce it, how will you know if it is ever fixed?
"select" Isn't Broken

If you encounter a bug, always be suspicious of your own code. No, the compiler isn't broken and nor is the CPU. It is your code, fix it.

Pragmatic Paranoia

You Can't Write Perfect Software
But Pragmatic Programmers take this a step further. They don't trust themselves, either.
When everybody actually is out to get you, paranoia is just good thinking.

We overestimate our capabilities often. Most people think they're the best drivers out there. Pragmatic programmers understand that everyone, including themselves, make mistakes, and hence keep an eye out for bugs before they creep in.

Dead Programs Tell No Lies

When your code discovers that something that was supposed to be impossible just happened, your program is no longer viable. Anything it does from this point forward becomes suspect, so terminate it as soon as possible. A dead program normally does a lot less damage than a crippled one.

Assertive Programming

If It Can't Happen, Use Assertions to Ensure That It Won't
Turning off assertions when you deliver a program to production is like crossing a high wire without a net because you once made it across in practice. There's dramatic value, but it's hard to get life insurance.

Always use assertions to make sure things are working well, even in situations when you're sure or things are 'obviously simple'. Detect early and abort.

When to Use Exceptions

"Will this code still run if I remove all the exception handlers?" If the answer is "no," then maybe exceptions are being used in nonexceptional circumstances.

Don't use exception for normal code flow control. Exceptions need to be reserved for 'exceptional' situations.

Decoupling and the Law of Demeter

Organize your code into cells (modules) and limit the interaction between them. If one module then gets compromised and has to be replaced, the other modules should be able to carry on.

Metaprogramming

Configure, Don't Integrate
Our goal is to think declaratively (specifying what is to be done, not how) and create highly dynamic and adaptable programs.
Program for the general case, and put the specifics somewhere else—outside the compiled code base.
Put Abstractions in Code, Details in Metadata
Because business policy and rules are more likely to change than any other aspect of the project, it makes sense to maintain them in a very flexible format.

It's Just a View

The view is an interpretation of the model (perhaps a subset)—it doesn't need to be graphical.
The controller is more of a coordination mechanism, and doesn't have to be related to any sort of input device.

Understand what a view really is. Everything revolves around the models, and views are just different ways in which you can represent those models.

While You Are Coding

However, good, safe drivers are constantly reviewing the situation, checking for potential problems, and putting themselves into good positions in case the unexpected happens. The same is true of coding—it may be largely routine, but keeping your wits about you could well prevent a disaster.

Programming by Coincidence

Fred doesn't know why the code is failing because he didn't know why it worked in the first place.
If you don't have fundamentals or infrastructure correct, brilliant bells and whistles will be irrelevant.

Program consciously. Write code thinking of it as an autonomous task once you have the business requirements and architecture clear is a mistake. There has to be equal involvement during programming.

Refactoring

Rather than construction, software is more like gardening—it is more organic than concrete. You plant many things in a garden according to an initial plan and conditions. Some thrive, others are destined to end up as compost. You may move plantings relative to each other to take advantage of the interplay of light and shadow, wind and rain. Overgrown plants get split or pruned, and colors that clash may get moved to more aesthetically pleasing locations. You pull weeds, and you fertilize plantings that are in need of some extra help. You constantly monitor the health of the garden, and make adjustments (to the soil, the plants, the layout) as needed.
If it hurts now, but is going to hurt even more later, you might as well get it over with.

Code That's Easy to Test

All software you write will be tested—if not by you and your team, then by the eventual users—so you might as well plan on testing

The Requirements Pit

Don't Gather Requirements—Dig for Them
Work with a User to Think Like a User
The key to managing growth of requirements is to point out each new feature's impact on the schedule to the project sponsors.

Ubiquitous Automation

Civilization advances by extending the number of important operations we can perform without thinking.

Automate as much as you can.

Ruthless Testing

Most developers hate testing. They tend to test gently, subconsciously knowing where the code will break and avoiding the weak spots. Pragmatic Programmers are different. We are driven to find our bugs now, so we don't have to endure the shame of others finding our bugs later.
Test State Coverage, Not Code Coverage

It's All Writing

One of the most important pieces of information that should appear in the source file is the author's name—not necessarily who edited the file last, but the owner.

Pride and Prejudice

We want to see pride of ownership. "I wrote this, and I stand behind my work." Your signature should come to be recognized as an indicator of quality. People should see your name on a piece of code and expect it to be solid, well written, tested, and documented. A really professional job. Written by a real professional. A Pragmatic Programmer.

Take pride in your work. Don't just assume it will be a small cog in the big wheel and use that as an excuse to write sloppy code.

In Closing

That's all. There's a lot more in the book, the stories and the experiences. I highly recommend you give it a try if your day job involves writing computer code. Thanks for reading.