10 steps to solve programming problems

Original author: Valinda Chan
  • Transfer


Translation of Valinda Chen's article .

This is a collection of tips for novice developers who are looking at a blank screen and do not know where to start. You can often hear from young developers working on solving some tasks in programming that they are not sure what to grab onto. You understand the task itself, the logic, the basics of syntax, and so on. If you see someone’s code, or someone helps you, then you can do everything yourself. But it happens that you are not confident in your abilities, or at first it is difficult for you to realize your thoughts in the code, despite the fact that you know the syntax and logic. Under the cut - a few tips to solve this problem that will help you in your daily work .

1. Read the conditions of the problem at least three times (or at least as many times as you like)


You cannot solve the problem if you do not understand it . There is a difference between a task and a task that you think you are solving. You can read the first few lines, and as for the rest, make assumptions, since everything looks similar to what you have encountered before. Even if you make a popular game like the Hangman, make sure to read all its rules, even if you played it before.

Sometimes you can try to explain the problem to a friend and see if he understands your explanation. You do not want to go half the way and find that you misunderstood the requirements. So it’s better to spend more time at the beginning to clear things up. The better you understand the problem, the easier it will be to solve it.

Let's say we create a simple functionselectEvenNumbers, which takes an array of numbers and returns an array evenNumbers with only even numbers. If there are no even numbers in the original array, then the array is evenNumbers returned empty.

function selectEvenNumbers() {
  // здесь ваш код
}

What questions can you ask yourself:

  • How can a computer say the number is even? Divide by 2 and check that the result is integer.
  • What am I passing to this function? Array
  • What does this array contain? One or more numbers.
  • What data types do array elements have? Numbers.
  • What is the purpose of this feature? What do I return at the end of its execution? The goal is to get all the even numbers and return them in an array. If there are no even numbers, then the array is returned empty.

2. Go through the task manually with at least three data sets


Take a sheet of paper and go through the task manually. Select at least three data sets to verify. Select maximum permissible and extreme cases.

Maximum permissible cases : a problem or situation arising outside the normal functioning parameters. For example, when at the same time several variables or environmental conditions have extreme values, even if each of the parameters is in its own specific range.

Extreme cases : problems or situations that arise only with extreme (minimum or maximum) values ​​of the functioning parameters.

Here, for example, are several data sets for use:

[1]
[1, 2]
[1, 2, 3, 4, 5, 6]
[-200.25]
[-800.1, 2000, 3.1, -1000.25, 42, 600 ]

When you first start, you often neglect some steps . Since our brain is already familiar with even numbers, you can just look at a set of numbers and immediately pass 2, 4, 6, and so on, without thinking about how our brain selects specific numbers. If you notice this for yourself, it is best to take a large data set to prevent the brain from solving the problem by simply looking at the numbers. This will help stick to the real algorithm.

Let's go through the array [1]

  1. We look at a single element of the array [1].
  2. Determine if it is even. Is not.
  3. We notice that there are no other elements in the array.
  4. We determine that there are no even numbers.
  5. We return an empty array.

Now let's go through the array [1, 2]

  1. We look at the first element of the array [1, 2]
  2. That 1.
  3. Determine if it is even. Is not.
  4. We look at the next element.
  5. That 2.
  6. Determine if it is even. Is an.
  7. Create an array evenNumbers and add to it 2.
  8. We notice that there are no other elements in the array.
  9. We return an array evenNumbers - [2].

You can go through the task several more times. Note that the number of steps in the algorithm for [1]differs from the algorithm for [1, 2]. Therefore, it is recommended to go through several data sets. For example, with a single element; a mixture of integers and non-integers; multi-digit numbers; sets with negative numbers.

3. Simplify and optimize your algorithm.


Look for suitable patterns, maybe something can be generalized. Think about whether you can reduce the number of steps.

  1. Create a function selectEvenNumbers.
  2. Create a new empty array evenNumbers for storing even numbers.
  3. We go through each element of the array [1, 2].
  4. We find the first element.
  5. Divide it by 2 and determine if it is even. If yes, then add to evenNumbers.
  6. We find the following element.
  7. Repeat step number 4.
  8. Repeat steps 5 and 4 until the elements in the array run out.
  9. We return an evenNumbers array regardless of whether there is anything in it.

This approach resembles mathematical induction :

  1. To prove the truth n = 1, n = 2...
  2. We assume that will be true for n = k.
  3. We prove the truth for n = k + 1.



4. Write the pseudo code


After working through the basic steps, write a pseudo-code that can be translated into real code. This will help determine the structure of the code, and indeed facilitate its writing. Write the pseudocode line by line . This can be done on paper or as comments in the editor. If you are just starting out and think that a blank screen looks creepy or distracting, it is best to write on paper.

In general, there are no rules for writing pseudocode, but you can include syntax from your language, if it is more convenient. But focus not on the syntax, but on the logic and steps of the algorithm .

In relation to our case, there are many different options. For example, you can use filter, but for the sake of simplicity, we use a simple loopfor (however, with subsequent refactoring we will still encounter filter).

Here is an example of a pseudo code mainly consisting of words:

function selectEvenNumbers
создаём массив evenNumbers и делаем его эквивалентным пустому массиву
для каждого элемента в этом массиве
  смотрим, является ли элемент чётным
   если чётный (при делении на 2 результат получается нецелым)
     добавляем его к массиву evenNumbers
return evenNumbers

And here is a pseudo-code in which there are much fewer words:

function selectEvenNumbers
evenNumbers = []
for i = 0 to i = length of evenNumbers
  if (element % 2 === 0) 
    добавляем его к массиву evenNumbers
return evenNumbers

The main thing is to write code line by line and understand the logic of each line.

Return to the task to make sure that you are on the right track.

5. Convert the pseudo code to normal code and debug it


When your pseudo-code is ready, convert each line into real code in your language. Here we will use JavaScript.

If you wrote on paper, then transfer everything to the editor in the form of comments, and then replace each line.

Now call the function and give it some of the previously used datasets. So you can check whether the code returns the desired result. You can also write tests to verify that the output matches the expected result.

selectEvenNumbers([1])
selectEvenNumbers([1, 2])
selectEvenNumbers([1, 2, 3, 4, 5, 6])
selectEvenNumbers([-200.25])
selectEvenNumbers([-800.1, 2000, 3.1, -1000.25, 42, 600])

After each variable or line you can use console.log(). This will help verify that the values ​​and code behave as expected before moving on . This way you can catch any problems without going too far. Here is an example of what values ​​can be checked at the beginning of work.

function selectEvenNumbers(arrayofNumbers) {
let evenNumbers = []
 console.log(evenNumbers) // Удаляем после проверки выходных данных
 console.log(arrayofNumbers) // Удаляем после проверки выходных данных
}

Below is the code obtained after processing each line of the pseudocode. Symbols //indicate lines from pseudo-code. Bold indicates the actual JavaScript code.

// function selectEvenNumbers
function selectEvenNumbers(arrayofNumbers) {
// evenNumbers = []
  let evenNumbers = []
// for i = 0 to i = length of evenNumbers
  for (var i = 0; i < arrayofNumbers.length; i++) {
// if (element % 2 === 0) 
    if (arrayofNumbers[i] % 2 === 0) {
// добавляем его к массиву evenNumbers
      evenNumbers.push(arrayofNumbers[i])
    }
  }
// return evenNumbers
  return evenNumbers
}

We remove the pseudocode so as not to get confused.

function selectEvenNumbers(arrayofNumbers) {
  let evenNumbers = []
for (var i = 0; i < arrayofNumbers.length; i++) {
    if (arrayofNumbers[i] % 2 === 0) {
      evenNumbers.push(arrayofNumbers[i])
    }
  }
return evenNumbers
}

Sometimes new developers are so addicted to syntax that it is difficult for them to move on. Remember that over time, it will be easier for you to observe the syntax, and there is nothing to be ashamed of then referring to reference materials when writing code to correctly observe the syntax .



6. Simplify and optimize your code.


You may have noticed that simplification and optimization are recurring themes.

"Simplicity is a prerequisite of reliability."
Edsger Dijkstra, a Dutch scientist and one of the pioneers in a number of areas of computer science.

In our example, one of the optimization ways would be to filter elements in an array by returning a new array using filter. In this case, we do not need to define a variable evenNumbers, because it filter will return a new array with copies of the elements that match the filter. In this case, the original array will not change. Also we do not need to use a loop for. filter will go through each element, and if it returns true, then the element will fall into the array, and if it is false, it will be skipped.

function selectEvenNumbers(arrayofNumbers) {
  let evenNumbers = arrayofNumbers.filter(n => n % 2 === 0)
  return evenNumbers
}

It may take several iterations to simplify and optimize the code as you find new ways.

Ask yourself these questions:

  • What are the goals of simplification and optimization? The goals depend on the style adopted by your team or your personal preferences. Are you trying to maximize code compaction? Or do you want to make it more readable? In this case, you can add separate lines with the definition of a variable or calculation of something, and not try to do everything on one line.
  • How else can I make the code more readable?
  • Is it possible to reduce the number of steps?
  • Are there variables or functions that are not needed or not used?
  • Are any steps repeated? See if you can define in another function.
  • Are there more effective ways to handle extreme cases?

“Programs should be written so that people read them, and only secondarily, so that the machines execute them.”
Gerald Sassman and Harold Abelson, authors of “Structure and Interpretation of Computer Programs”

7. debug


This step must be completed throughout the process. End-to-end debugging will help you catch any syntax errors or logic flaws earlier. Take advantage of your IDE (Integrated Development Environment) and debugger. If a bug is detected, it is recommended to scan the code line by line, trying to find unexpected things. A few tips:

  • Read what is written in console error messages. Sometimes they indicate line numbers for verification. This will give you a starting point for your searches, although problems can sometimes be hidden in other lines.
  • Comment out blocks of code or lines, as well as output, to quickly spot code behavior. If necessary, the code can always be uncommented.
  • Use other data samples if unexpected scenarios arise.
  • Save different versions of the file if you use other approaches. Do not lose what you have gained if you want to roll back to your previous decision!

“The most effective debugging tool is thoughtful thinking combined with reasonably placed on-screen display commands.”
Brian Kernigan, professor of computer science at Princeton University

8. Write useful comments


After a month, you may not remember what each line of code means. And the one who will work with your code does not know this at all. Therefore, it is important to write useful comments in order to avoid problems and subsequently save time when you have to return to this code again.

Avoid comments like this:

// Это массив. Итерируем его.
// Это переменная.

Try to write short, high-level comments to help you understand what’s going on here if it’s not obvious. This is useful when solving complex problems, you can quickly understand what a particular function does and why. By using clear comments and variable and function names, you (and other people) can understand:

  • What is this code for?
  • What is he doing?

9. Get feedback through code revisions.


Get feedback from colleagues, executives, and other developers. Read Stack Overflow. Watch how others solve similar problems and learn from them. Often there are several ways to solve a problem. Find out what they are, and it will be faster and easier for you to come to them yourself.

"No matter how slowly you write clean code, you will always spend more time when writing dirty code."
Uncle Bob Martin, Software Engineer and Co-author of the Agile Manifesto

10. Practice, practice, practice


Even experienced developers are constantly practicing and learning. If you get a helpful response, implement it. Again, solve the problem, or similar tasks. Force yourself. With each solved task you become better as a developer . Rejoice at every success and do not forget how much you have already passed. Remember that programming, like any activity, will be made easier and easier over time.

“Be proud of how much you have passed. Believe that you will go even more. But don’t forget to enjoy the journey. ”
Michael Josephson, Founder, Joseph and Edna Josephson Institute of Ethics

Also popular now: