Distilling logic to come up with an algorithm before coding aka Logic —> Pseudocode —> Code approach
Programming is all about logic. In fact, we might even say that programming is a reflection of the logic implemented in a certain programming language.
So before we start writing code it's a great idea to think about logic and figure it out first.
Especially if you feel like "I'm not sure where to start", "I understand it but don't know what code to use", "I don't know how to solve it", etc..
I’d say if we start with the logic we do not even care about any exact programming concepts, rather just trying to come up with an algorithm to solve this as a purely logical task.
First we need to clearly understand what we are being asked to do. Let's take this coding exercise as an example:
// Write a function called getWords which takes a string as an argument.
// The string will contain some uppercase and lowercase letters mixed with some numbers.
// Create a function which will return this string without numbers all in lowercase and
// with spaces between words.
//====================== EXAMPLE ========================
// original sentence = An2323t2323one32llo123455Likes567323Play323ing567243G2323a3mes345
// function call
getWords("An2323t2323one32llo123455Likes567323Play323ing567243G2323a3mes345")
// expected output
"antonello likes playing games"
In this case — we take a mix of letters and digits and we need to discard all the digits and only have letters; before every letter in uppercase we need to have a space since they signify beginning of a new word.
So once we understand what is the final goal we focus on the logic. We can ask ourselves a question — how do I do it in real life, without thinking of programming. Of course initial response our brain will give is “I just see letters among those numbers”. But we need to force ourselves to distill all the tiny steps we do unconsciously behind that.
For example, below we can show the process of thinking about logic and writing it down. Shown in several versions to illustrate the progress but of course we do not need to do it in real life, we just working on one algorithm iterating and updating it along the process of our thinking. At this point we do not care how we are going to do it, we care about what we want to do:
LOGIC VERSION 1
We get a string of letters mixed with digits
-
We start from the beginning of the string and look at each character
- If this character is a letter we want to keep it |––> at this point of writing we realize that we want some place to keep discovered letters so we can go back to before point 2 and inject one more step there
LOGIC VERSION 2
- We get a string of letters mixed with digits
Create a place to keep discovered letter
-
We start from the beginning of the string and look at each character
- If this character is a letter we want to keep it in our “discovered letters place”
- If it’s a digit we do nothing
After we finished going through the string and discovered all the letters we have a string of text with words but no spaces |––> we can now think about this step and iterate again over step 3.1 above to think about how to add spaces
LOGIC VERSION 3
- We get a string of letters mixed with digits
- Create a place to keep discovered letter
- We start from the beginning of the string and look at each character
- If this character is a letter
- And it is in lowercase we want to keep it in our “discovered letters place”
- And it is in uppercase we want to add a space before it and keep it in our “discovered letters place”
- If it’s a digit we do nothing
- If this character is a letter
- After we finished going through the string and discovered all the letters we have a string of text with words divided by spaces
- Make them all lowercase
- Task is completed and we have final results in our "discovered letters place"
Now our logic seems to be solid and we can move to the next step of writing language-agnostic pseudo code which can be implemented in any programming language. If we discover some flaws in our logic we can modify it, it’s not set in stone. But most likely it will be minor changes.
We can copy our final version algorithm, comment it out, and use it as a blueprint of for the pseudocode. Now we can use the programming concept like function. loop, condition, but we do not care about particular syntax, since it is language-agnostic.
PSEUDOCODE VERSION 1
// 1. We get a string of letters mixed with digits
declare a function which takes one argument a string, lets call this string "str"
// 2. Create a place to keep discovered letter
declare a variable to keep results and let's call it "results"
// 3. We start from the beginning of the string and look at each character
start loop on the "str" to have a character for every iteration
// 1. If this character is a letter
condition A to check if current character is a letter (not a number)
// 1. And it is in lowercase we want to keep it in our “discovered letters place”
condition B to check if current letter is lowercase
if it is we concatenate it with "results"
// 2. And it is in uppercase we want to add a space before it and keep it in our “discovered letters place”
if it is uppercase we join it with a space before and concatenate them with "results"
close condition B
close condition A
// 2. If it’s a digit we do nothing
Do nothing means we can just ignore it completely
// 4. After we finished going through the string and discovered all the letters we have a string of text with words divided by spaces
close loop
// 5. Make them all lowercase
Modify string to make it all lowercase
// 6. Task is completed and we have final results in our "discovered letters place"
Now we can output the "results"
close function
Now we have the pseudo code and we can try to implement it in a programming language. Now the psudo code will be commented out since we are relying on it while writing code.
Let's go with JavaScript:
CODE VERSION 1
// declare a function which takes one argument a string, lets call this string "str"
const getWords=(str)=>{
// declare a variable to keep results and let's call it "results"
// start loop on the "str" to have a character for every iteration
// condition A to check if current character is a letter (not a number)
// condition B to check if current letter is lowercase
// if it is we concatenate it with "results"
// if it is uppercase we join it with a space before and concatenate them with "results"
// close condition B
// close condition A
// Do nothing means we can just ignore it completely
// close loop
// Modify string to make it all lowercase
// Now we can output the "results"
// close function
}
CODE VERSION 2
// declare a function which takes one argument a string, lets call this string "str"
const getWords=(str)=>{
// declare a variable to keep results and let's call it "results"
let results = "" // <-- since the final output is a string we can assign initial value of an empty string
// start loop on the "str" to have a character for every iteration
// condition A to check if current character is a letter (not a number)
// condition B to check if current letter is lowercase
// if it is we concatenate it with "results"
// if it is uppercase we join it with a space before and concatenate them with "results"
// close condition B
// close condition A
// Do nothing means we can just ignore it completely
// close loop
// Modify string to make it all lowercase
// Now we can output the "results"
// close function
}
CODE VERSION 3
// declare a function which takes one argument a string, lets call this string "str"
const getWords=(str)=>{
// declare a variable to keep results and let's call it "results"
let results = "" // <-- since the final output is a string we can assign initial value of an empty string
// start loop on the "str" to have a character for every iteration
//NOW: if we are not sure which loop to use we can check reference for which loop works with a string in JS
for(character of str){
// condition A to check if current character is a letter (not a number)
// condition B to check if current letter is lowercase
// if it is we concatenate it with "results"
// if it is uppercase we join it with a space before and concatenate them with "results"
// close condition B
// close condition A
// Do nothing means we can just ignore it completely
// close loop
}
// Modify string to make it all lowercase
// Now we can output the "results"
// close function
}
CODE VERSION 4
// declare a function which takes one argument a string, lets call this string "str"
const getWords=(str)=>{
// declare a variable to keep results and let's call it "results"
let results = "" // <-- since the final output is a string we can assign initial value of an empty string
// start loop on the "str" to have a character for every iteration
//NOW: if we are not sure which loop to use we can check reference for which loop works with a string in JS
for(character of str){
// condition A to check if current character is a letter (not a number)
if(isNaN(character)){
// condition B to check if current letter is lowercase
// if it is we concatenate it with "results"
// if it is uppercase we join it with a space before and concatenate them with "results"
// close condition B
// close condition A
}
// Do nothing means we can just ignore it completely
// close loop
}
// Modify string to make it all lowercase
// Now we can output the "results"
// close function
}
CODE VERSION 5
// declare a function which takes one argument a string, lets call this string "str"
const getWords=(str)=>{
// declare a variable to keep results and let's call it "results"
let results = "" // <-- since the final output is a string we can assign initial value of an empty string
// start loop on the "str" to have a character for every iteration
//NOW: if we are not sure which loop to use we can check reference for which loop works with a string in JS
for(character of str){
// condition A to check if current character is a letter (not a number)
if(isNaN(character)){
// condition B to check if current letter is lowercase
if(character === character.toLowerCase()){
// if it is we concatenate it with "results"
}else{
// if it is uppercase we join it with a space before and concatenate them with "results"
}
// close condition B
// close condition A
}
// Do nothing means we can just ignore it completely
// close loop
}
// Modify string to make it all lowercase
// Now we can output the "results"
// close function
}
CODE VERSION 6
// declare a function which takes one argument a string, lets call this string "str"
const getWords=(str)=>{
// declare a variable to keep results and let's call it "results"
let results = "" // <-- since the final output is a string we can assign initial value of an empty string
// start loop on the "str" to have a character for every iteration
//NOW: if we are not sure which loop to use we can check reference for which loop works with a string in JS
for(character of str){
// condition A to check if current character is a letter (not a number)
if(isNaN(character)){
// condition B to check if current letter is lowercase
if(character === character.toLowerCase()){
// if it is we concatenate it with "results"
results+=character
}else{
// if it is uppercase we join it with a space before and concatenate them with "results"
results+=(' '+character)
}
// close condition B
// close condition A
}
// Do nothing means we can just ignore it completely
// close loop
}
// Modify string to make it all lowercase
// Now we can output the "results"
// close function
}
CODE VERSION 7
// declare a function which takes one argument a string, lets call this string "str"
const getWords=(str)=>{
// declare a variable to keep results and let's call it "results"
let results = "" // <-- since the final output is a string we can assign initial value of an empty string
// start loop on the "str" to have a character for every iteration
//NOW: if we are not sure which loop to use we can check reference for which loop works with a string in JS
for(character of str){
// condition A to check if current character is a letter (not a number)
if(isNaN(character)){
// condition B to check if current letter is lowercase
if(character === character.toLowerCase()){
// if it is we concatenate it with "results"
results+=character
}else{
// if it is uppercase we join it with a space before and concatenate them with "results"
results+=(' '+character)
}
// close condition B
// close condition A
}
// Do nothing means we can just ignore it completely
// close loop
}
// Modify string to make it all lowercase
results = results.toLowerCase()
// Now we can output the "results"
return results
// close function
}
Now let's try our function.
If we run it with some input data like so:
getWords("An2323t2323one32llo123455Likes567323Play323ing567243G2323a3mes345")
We will see the following output:
' antonello likes playing games'
Everything seems to work pretty much from the first attempt except we have an extra space in the beginning of the string. Why? Because the first word start with an uppercase letter and we are adding a space before every uppercase letter in out code. So all we have to do is to get rid of the first character in the "results" variable on our code before returning it.
We can do it in several ways, one of them can be .trim()
method which removes spaces in the beginning and in the end of the string.
CODE VERSION 8
// declare a function which takes one argument a string, lets call this string "str"
const getWords=(str)=>{
// declare a variable to keep results and let's call it "results"
let results = "" // <-- since the final output is a string we can assign initial value of an empty string
// start loop on the "str" to have a character for every iteration
//NOW: if we are not sure which loop to use we can check reference for which loop works with a string in JS
for(character of str){
// condition A to check if current character is a letter (not a number)
if(isNaN(character)){
// condition B to check if current letter is lowercase
if(character === character.toLowerCase()){
// if it is we concatenate it with "results"
results+=character
}else{
// if it is uppercase we join it with a space before and concatenate them with "results"
results+=(' '+character)
}
// close condition B
// close condition A
}
// Do nothing means we can just ignore it completely
// close loop
}
// Modify string to make it all lowercase
results = results.toLowerCase()
// Now we can output the trimmed "results"
return results.trim()
// close function
}
And we have the perfect output:
getWords("An2323t2323one32llo123455Likes567323Play323ing567243G2323a3mes345")
// the output is:
'antonello likes playing games'
Conclusion
By following this approach it is possible to not only improve your logical thinking which is the cornerstone in programming, but also being able to learn how to break bigger challenges into smaller chunks, come up with the plan before writing code and solve the logic before coding.
It would be anit-efficient to write code without understanding the logic to only realize at some point(s) that the approach chosen is not working or something important is missed out...
Logical thinking is regarded as one of the required skills for a developer. Sometimes people think that it's a skill that can't be acquired. But from what we've seen with our students if practiced properly everybody can improve their logical thinking and learn it. It's just a matter of practicing.
Top comments (0)