Is High Quality Software Worth the Cost? By Martin Fowler

I don’t like using term “fan”, however I do read Martin Fowler’s posts and tend to agree with him a lot. His recent post brought feeling of familiarity and a bit of pain. I would like to share it with anyone who is doing software development.

PDF version

I hope you will find it useful.

N26 coding exercise

A while back, I worked on N26 coding exercise and found the problem quite entertaining. Figured to share it:

N26 coding exercise

Correct, with minor test comments (should not use Thread.sleep(…)) and not entirely efficient but clean and 100% test driven solution can be found here and backup: here.

I think this exercise worth while, do it just for fun and giggles :)

How to solve it – cheatsheet

From a grateful reader:

About 8 months ago I finished reading “How to solve it” by George Polya. I was so fascinated with the book that I decided to read it again right away. This time around I took notes… in fact I managed to re-type almost the entire book, since I found almost everything the author wrote indispensable. Going over my notes, I realized that in order to fully grasp and appreciate ideas you must read the book in its entirety. However no effort should be put to waste and so I decided to pick a few things out and lay it out in this cheatsheet and the rest of my notes can be downloaded in rich text format document.

P.S: My apologies for any mis-types.

The cheatsheet:

The questions and suggestions of our list cannot work magic. They cannot give us the solution of all possible puzzles without any effort on our part. If the reader wishes to find the solution, he must keep on trying and thinking about it. What the questions and suggestions of the list can do is to “keep the ball rolling.” When, discouraged by lack of success, we are inclined to drop the problem, they may suggest to us a new trail, a new aspect, a new variation of the problem, a new stimulus; they may keep us thinking.

Questions and suggestions:

1. Understand the problem

  • First. You have to understand the problem.
  • What is the unknown? What are the data? What is the condition?
  • Is it possible to satisfy the condition? Is the condition sufficient to determine the unknown? Or is it insufficient? Or redundant? Or contradictory?
  • Draw a figure. Introduce suitable notation.
  • Separate the various parts of the condition. Can you write them down?

2. Devising a plan

  • Second. Find the connection between the data and the unknown. You may be obliged to consider auxiliary problems if an immediate connection cannot be found. You should obtain eventually a plan of the solution.
  • Have you seen it before? Or have you seen the same problem in a slightly different form?
  • Do you know a related problem? Do you know a theorem that could be useful?
  • Look at the unknown! Try to think of a familiar problem having the same or a similar unknown.
  • Here is a problem related to yours and solved before. Could you use it? Could you use its result? Could you use its method? Should you introduce some auxiliary element in order to make its use possible?
  • Could you restate the problem? Could you restate it still differently? Go back to definitions.
  • If you cannot solve the proposed problem, try to solve first some related problem. Could you imagine a more accessible related problem? A more general problem? A more special problem? An analogous problem? Could you solve a part of the problem? Keep only a part of the condition, drop the other part; how far is the unknown then determined, how can it vary? Could you derive something useful from the data? Could you think of other data appropriate to determine the unknown? Could you change the unknown or data, or both if necessary, so that the new unknown and the new data are nearer to each other?
  • Did you use all the data? Did you use the whole condition? Have you taken into account all essential notions involved in the problem?

3. Carrying out the plan

  • Third. Carry out your plan.
  • Carrying out your plan of the solution, check each step. Can you see clearly that the step is correct? Can you prove that it is correct?

4. Looking back

  • Fourth. Examine the solution obtained.
  • Can you check the result? Can you check the argument?
  • Can you derive the solution differently? Can you see it at a glance?
  • Can you use the result, or the method, for some other problem?

Main divisions, main question:

Trying to find the solution, we may repeatedly change out point of view. We have to shift out position again and again. Our concept of the problem is likely to be rather incomplete when we start the work; our outlook is different when we have made some progress; it is again different when we have almost obtained the solution.

Four phases: 

1. We have to understand the problem – see clearly what’s required

2. Second, we have to see how the various items are connected, how the unknown is linked to the data, in order to obtain idea of the solution, to make a plan

3. We carry out our plan.

4. We look back at the complete solution, we review and discuss it.

Understanding the problem:

It is foolish to answer a question that you do not understand.

  • What is the unknown?
  • What are the data?
  • What is the condition?

If there is a figure connected with a problem he should draw a figure and point out on the unknown and the data. Introduce suitable notation if needed.

  • Is it possible to satisfy the condition?

Devising a plan:

We have a plan when we know, or know at least in outline, which calculations, computation, or constructions we have to perform in order to obtain the unknown. The way from understanding the problem to conceiving a plan may be long and tortuous. In fact, the main achievement in the solution of a problem is to conceive the idea of a plan.

It is hard to have a good idea if we have little knowledge of the subject and impossible to have it if we have no knowledge. Good ideas are based on past experience and formerly acquired knowledge. Mere remembering is not enough for a good idea, but we cannot have any good idea without recollecting some pertinent facts; materials alone are not enough for constructing a house but we cannot construct a house without collecting the necessary materials. The materials necessary for solving a mathematical problem are certain relevant items of our formerly acquired mathematical knowledge, as formerly solved problems or formerly proved theorems. Thus, it is often appropriate to start the work with the question:

  • Do you know a related problem?
  • Look at the unknown! And try to think of a familiar problem having the same or a similar unknown.
  • Here is a problem related to yours and solved before. Could you use it?
  • Could you restate problem?
  • If you cannot solve the proposed problem try to solve first some related problem.
  • Did you use all the data? Did you use the whole condition?

Carrying out the plan:

To devise a plan, to conceive the idea of the solution is not easy. It takes so much to succeed; formerly acquired knowledge, good mental habits, concentration upon the purpose, and one more thing: good luck. To carry out the plan is much easier; what we need is mainly patients.

  • Can you see clearly that the step is correct?
  • But can you also prove that the step is correct?

Looking back. Even fairly good students, when they have obtained the solution of the problem and written down neatly the argument, shut their books and look for something else. Doing so, they miss an important and instructive phase of work. By looking back at the completed solution, by reconsidering and re-examining the result and the path that led to it, they could consolidate their knowledge and develop their ability to solve the problems.

  • Can you check the result?
  • Can you check the argument?

In order to convince ourselves of presence or the quality of an object, we like to see and to touch it. And as we prefer perception through two different senses, so we prefer conviction by two different proofs:

  • Can you derive result differently?
  • Can you see it a a glance?
  • Can you use the result or the method, for some other problem?

PART II. HOW TO SOLVE IT A DIALOG:

Getting acquainted:

Where should I start? Start from the statement of the problem.

What can I do? Visualize the problem as a whole as clearly and as vividly as you can. Do not concern yourself with details for the moment.

What can I gain by doing so? You should understand the problem, familiarize yourself with it, impress its purpose on your mind. The attention bestowed on the problem may also stimulate your memory and prepare for the recollection of relevant points.

Working for better understanding:

Where should I start? Start again from the statement of the problem. Start when this statement is so clear to you and so well impressed on your mind that you may lose sight of it for a while without fear of losing it altogether.

What can I do? Isolate the principal parts of your problem. The hypothesis and the conclusion are the principal parts of the “problem to prove”; the unknown, the data, and the conditions are principal parts of “problem to find”. Go through the principal parts of your problem, consider them one by one, consider them in turn, consider them in various combinations, relating each detail to other details and each to the whole of the problem.

What can I gain by doing so? You should prepare and clarify details which are likely to play a role afterwards.

Hunting for the helpful idea:

Where should I start? Start from the consideration of the principle parts of your problem. Start when these principle parts are distinctly arranged and clearly conceived, thanks to your previous work, and then your memory seems responsive.

What can I do? Consider your problem from various sides and seek contacts with your formerly acquired knowledge. Consider your problem from various sides. Emphasize different parts, examine different details, examine the same details repeatedly but in different ways, combine the details repeatedly but in different ways, combine the details differently, approach them from different sides. Try to see some new meaning in each detail, some new interpretation of the whole. Seek contacts with your formerly acquired knowledge. Try to think of what helped you in similar situations in the past. Try to recognize something familiar in what you are examine, try to perceive something useful in what you recognize.

What could I perceive? A helpful idea, perhaps a decisive idea that shows you at a glance the way to the very end.

How can an idea be helpful? It shows you the whole of the way or a part of the way; it suggests to you more or less distinctly how you can proceed. Ideas are more or less complete. You are lucky if you have any idea at all.

What can I do with an incomplete idea? You should consider it. If it looks advantageous you should consider it longer. If it looks reliable you should ascertain how far it leads you, and reconsider the situation. The situation has changed, thanks to your helpful idea. Consider the new situation from various sides and seek contacts with your formerly acquired knowledge.

What can I gain by doing so again? You may be lucky and have another idea. Perhaps your next idea will lead you to the solution right away. Perhaps you need a few more helpful ideas after the next. Perhaps you will be led astray by some of your ideas. Nevertheless you should be grateful for all new ideas, also for the lesser ones, also for hazy ones, also for the supplementary ideas adding some precision to a hazy one, or attempting the correction of a less fortunate one. Even if you do not have any appreciable new ideas for a while you should be grateful if your conception of the problem becomes more complete or more coherent, more homogeneous or better balanced.

Carrying out the plan:

Where should I start? Start from the lucky idea that led you to the solution. Start when you feel sure of you grasp of the main connection and you fell confident that you can supply the minor details that may be wanting.

What can I do? Make your grasp quite secure. Carry through in detail all the algebraic or geometric operations which you have recognized previously as feasible. Convince yourself of the correctness of each step by formal reasoning, or by intuitive insight, or both ways if you can. If your problem is very complex you may distinguish “great” steps and “small” steps, each great step being composed of several small ones. Check first the great steps, and get down to the smaller ones afterwards.

What can I gain by doing so? A presentation of the solution each step of which is correct beyond doubt.

Looking back:

Where should I start? From the solution, complete and correct in each detail.

What can I do? Consider the solution from various sides and seek contacts with your formerly acquired knowledge.

Consider the details of the solution and try to make them as simple as you can; survey more extensive parts of the solution and try to make them shorter; try to see the whole solution a a glance. Try to modify to their advantage smaller or larger parts of the solution, try to improve the whole solution, to make it intuitive, to fit it into your formerly acquired knowledge as naturally as possible. Scrutinize the method that led you to the solution, try to see its point, and try to make use of it for other problems. Scrutinize the result and try to make use of it for other problems.

What can I gain by doing so? You may find a new and better solution, you may discover new and interesting facts. In any case, if you get into the habit of surveying and scrutinizing your solutions in this way, you will acquire some knowledge well ordered and ready to use, and you will develop your ability of solving problems.

Random notes:

Inventor’s paradox. The more ambitious plan may have more chances of success. This sounds paradoxical. Yet, when passing from one problem to another, we may often observe that the new, more ambitious problem is easier to handle than the original problem. More questions may be easier to answer than just one question. The more comprehensive theorem may be easier to prove, the more general problem may be easier to solve.

Look at the unknown. This is old advice; the corresponding Latin saying is: “respice finem.” This is, look at the end. Remember your aim. Do not forget your goal. Think of what you are desiring to obtain. Do not lose sight of what is required. Keep in mind what you are working for. Look at the unknown. Look at the conclusion. The last two versions of “respice finem” are specifically adapted to mathematical problems, to “problems to find” and to “problems to prove” respectively.

Focusing our attention on our aim and concentrating out will on our purpose, we think of ways and means to attain it. What are the means to this end? How can you attain your aim? How can you obtain a result of this kind? What causes could produce such a result? Where have you seen such a result produced? What do people usually do to obtain such a result? And try to think of a familiar problem having the same or a similar unknown. And try to think of a familiar theorem having the same or similar conclusion. Again, the last two versions are specifically adapter to “problems to find” and to “problems to prove” respectively.

Separate the various parts of the condition. Our first duty is to understand the problem. Having understood the problem as a while, we go into detail. We consider its principal parts, the unknown, the data, the condition, each by itself. When we have these parts well in mind but no particularly helpful idea has yet occurred to us, we go into further detail. We consider the various data, each datum by itself. Having understood the condition as a while, we separate its various parts, and we consider each part by itself.

Choosing notation. An important step in solving a problem is to choose the notation. It should be done carefully. The time we spend now on choosing the notation may be well repaid by the time we save later by avoiding hesitation and confusion. Moreover, choosing the notation carefully, we have to think sharply of the elements of the problem which must be denoted. Thus, choosing a suitable notation may contribute essentially to understanding the problem.

A good notation should be unambiguous, pregnant, easy to remember; it should avoid harmful second meanings, and take advantage of useful second meanings; the order and connection of signs should suggest the order and connection of things.

Pedantry and mastery are attitudes toward rules.

To apply a rules to the letter, rigidly, unquestioningly, in cases where it fits and in cases where it does not fit, is pedantry. Some pedants are poor fools; they never did understand the rule which they apply so conscientiously and so indiscriminately. Some pedants are quite successful; they understood their rule, at least in the beginning (before they became pedants), and chose a good one that fits in many cases and fails only occasionally.

To apply a rule with natural ease, with judgement, noticing the cases where it fits, without ever letting the words of the rule obscure the purpose of the action or the opportunities of the situation, is mastery.

The questions and suggestions of our list may be helpful both to problem-solvers and to teachers. But, first, they must be understood, their proper use must be learned, and learned by trial and error, by failure and success, by experience in applying them. Second, their use should never become pedantic. You should ask no question, make no suggestion, indiscriminately, following some rigid habit. Be prepared for various questions and suggestions and use your judgement. You are doing a hard and exciting problem; the step you are going to try next should be prompted by an attentive and openminded consideration of the problem before you. You with to help a student; what you say to your student should proceed from a sympathetic understanding of his difficulties.

And if you are inclined to be a pedant and must rely upon some rule learn this one: Always use you own brains first.

Worth-while problem: We cannot hope to solve any worth-while problem without intense concentration. But we are easily tired by intense concentration of our attention upon the same point. In order to sleep the attention alive, the object on which it is directed must unceasingly change.

If our work progresses, there is something to do, there are new points to examine, our attention is occupied, our interest is alive. But if we fail to make progress, out attention falters, our interest fades, we get tired of the problem, out thoughts began to wander, and there is danger of losing the problem altogether. To escape from this danger we have to set ourselves a new question about the problem.

The new question unfolds untried possibilities of contact without previous knowledge, it revives out hope of making useful contacts. The new question reconquers our interest by varying the problem, by showing some new aspect of it.

Bright idea: What is progress toward the solution? Advancing mobilization and organization of our knowledge, evolution of our conception of the problem, increasing prevision of the steps which will constitute the final argument. We may advance steadily, by small imperceptible steps, but now and then we advance abruptly, by leaps and bounds. A sudden advance toward the solution is called a BRIGHT IDEA, a good idea, a happy thought, a brain-wave (in German there is a more technical term, Einfall). What is bright idea? An abrupt and mementoes change of our outlook, a sudden reorganization of our mode of conceiving the problem, a just emerging confident prevision of the steps we have to take in order to attain the solution.

Rules of discovery. The first rule of discovery is to have brains and good luck. The second rules of discovery is to sit tight and wait till you get a bright idea.

It may be good to be reminded somewhat rudely that certain aspirations are hopeless. Infallible rules of discovery leading to the solution of all possible mathematical problems would be more desirable than the philosophers’ stone, vainly sought by the alchemists. Such rules would work magic, but there is no such thing as magic. To find unfailing rules applicable to all sorts of problems is an old philosophical dream; but this dream will never be more than a dream.

A reasonable sort of heuristic cannot aim at unfailing rules; but it may endeavor to study procedures (mental operations, moves, steps) which are typically useful in solving problems. Such procedures are practiced by every sane person sufficiently interested in his problem. They are hinted by certain stereotyped questions and suggestions which intelligent people put to themselves and intelligent teachers to their students. A collection of such questions and suggestions, stated with sufficient generality and neatly ordered, may be less desirable than the philosophers’ stone but can be provided. The list we study provides such a collection.

Rules of style. The first rule of style is to have something to say. The second rule of style is to control yourself when, by chance, you have two things to say; say first one, then the other, not both at the same time.

Rules of teaching. The first rules of teaching is to know what you are supposed to teach. The second rules of teaching is to know a little more than what you are supposed to teach.

First things come first. The author of this book does not think all rules of conduct for teachers are completely useless; otherwise, he would not have dared to write a while book about the conduct of teachers and students. Yet is should not be forgotten that teacher of mathematics should know some mathematics, and that a teacher wishing to impart the right attitude of mind toward problems to his students should have acquired that attitude himself.

First important discovery. The future mathematician learns, as does everybody else, by imitation and practice. He should look out for the right model to imitate. He should observe a stimulating teacher. He should compete with a capable friend. Then, what may be the most important, he should read not only current textbooks but good authors till he finds one whose ways he is naturally inclined to imitate. He should enjoy and seek what seems to him simple or instructive or beautiful. He should solve problems, choose the problems which are in his line, meditate upon their solution, and invent new problems. By these means, and by all other means, he should endeavor to make his first important discovery: he should discover his likes and his dislikes, his taste, his own line.

If you cannot solve the proposed problem do not let this failure afflict you too much but try to find consolation with some easier success, try to solve first some related problem; then you may find courage to attack your original problem again. Do not forget that human superiority consists in going around an obstacle that cannot be overcome directly, in devising some suitable auxiliary problem when the original one appears insoluble.

Polya’s quotes:

  • “If you can’t solve a problem, then there is an easier problem you can’t solve: find it”
  • “If the student is not able to do much, the teacher should leave him at lease some illusion of independent work. In order to do so, the teacher should help the student discreetly, unobtrusively.”
  • “Look at the unknown!”
  • “There are two aims which the teacher may have in view when addressing to his students a question or suggestion of the list: First, to help the student to solve the problem at hand. Second, to develop the student’s ability so that he may solve future problems by himself.”

Ugly Pit

A few months back I started a small project, the aim of which was to remove extra siding bricks out of the garage. I didn’t know what to do with all those extra bricks and figured that a small fire pit would be a good idea – two birds with one brick.

I also have almost no experience with landscaping, however after few YouTube videos and Pinterest pictures I realized two things:
– Fire pit must be functional
– I don’t want to spend any more resources on it

So I took measurements and figured a little platform around the fire would be a good idea – easier to cut the grass around it. Additionally, the fire pit must have two fire areas, one for cooking on hot charcoal and another for general fire.

Despite the functional reasoning, I decided to cut on quality by not digging too deep. Less than half a foot was enough to level the ground and lay out the bricks. The entire endeavour took a few days and the fire pit was done.

The resulting landscape view quickly attracted feedback from my wife and friends. After careful consideration I decided to name my little creation “ugly pit” and present it as a postmodern take on a rustic outdoor cooking contraption.

 

Awesome TDD & Agile posters

Last week, at last, my little work related side project came to successful end. Together with an awesome in-house graphics designer, we finalized series of inspirational posters. I would like to share it and hope those posters will bring smiles and joy to any software development environment. You can print it and hang it all over your work space.

 

Links to full size files:

3 Laws of TDD: PDF | TIF

Uncle Bob – Test Driven Development: PDF | TIF

Agile Manifesto: PDF | TIF