Matvii Hodovaniuk Notes

While you are coding

Program by Coincidence #

We should avoid programming by coincidence—relying on luck and accidental successes— in favor of programming deliberately.
Don't Program by Coincidence

How to Program Deliberately #

Algorithm Speed #

Pragmatic Programmers estimate the resources that algorithms use—time, processor, memory, and so on.

Use: Big O Notation #

	bool IsFirstElementNull(IList<string> elements)
{
return elements[0] == null;
}

Int BinarySearch(list, target)
{
lo = 1, hi = size(list)
while (lo <= hi){
mid = lo + (hi-lo)/2
if (list[mid] == target) return mid
else if (list[mid] < target) lo = mid+1
else hi = mid-1
}
}

bool ContainsValue(IList<string> elements, string value)
{
foreach (var element in elements)
{
if (element == value) return true;
}

return false;
}

bool ContainsDuplicates(IList<string> elements)
{
for (var outer = 0; outer < elements.Count; outer++)
{
for (var inner = 0; inner < elements.Count; inner++)
{
// Don't compare with self
if (outer == inner) continue;

if (elements[outer] == elements[inner]) return true;
}
}

return false;
}

int Fibonacci(int number)
{
if (number <= 1) return number;

return Fibonacci(number - 2) + Fibonacci(number - 1);
}

Common Sense Estimation #

Estimate the Order of Your Algorithms

Test Your Estimates

Best Isn't Always Best #

Be pragmatic about choosing appropriate algorithms—the fastest one is not always the best for the job.

Be wary of premature optimization. Make sure an algorithm really is a bottleneck before investing time improving it.

Refactoring #

Code needs to evolve; it's not a static thing.

When Should You Refactor? #

Refactor Early, Refactor Often

How Do You Refactor? #

Code That's Easy to Test #

Build testability into the software from the very beginning, and test each piece thoroughly before trying to wire them together.

Unit Testing #

Testing done on each module, in isolation, to verify its behavior.
A software unit test is code that exercises a module.

Testing Against Contract #

This will tell us two things:

  1. Whether the code meet the contract
  2. Whether the contract means what we think it means.

Design to Test

There's no better way to fix errors than by avoiding them in the first place.
Build the tests before you implement the code.

Writing Unit Tests #

By making the test code readily accessible, you are providing developers who may use your code with two invaluable resources:

  1. Examples of how to use all the functionality of your module
  2. A means to build regression tests to validate any future changes to the code

You must run them, and run them often.

Using Test Harnesses #

Test harnesses should include the following capabilities:

Build a Test Window #

A Culture of Testing #

Test Your Software, or Your Users Will

Evil Wizards #

If you do use a wizard, and you don't understand all the code that it produces, you won't be in control of your own application.

Don't Use Wizard Code You Don't Understand

← Home