I have had similar questions over the years. And I have, personally, struggled a lot myself too because I thought I just couldn’t do it because I am not logical enough or analytical enough.
Over time, it has been very clear to me that our education systems, in general, don’t appropriately help all of us, individually, to learn something the right way and it can have negative consequences over time.
So, thinking programmatically, is indeed a skill, but just practicing more and more is not necessarily going to be enough either. I am currently comfortable with programming that I can work on projects which might fall under an “advanced” category, but they really aren’t that advanced. I find it difficult to build something over time, and I think that speaks to how someone should be practicing in general.
Make sure you understand what you are implementing. You say you write out comments and focus on this. That’s excellent, keep that up.
When learning through any kind of course, online or in a traditional setting, make sure you understand what you are solving before you write the code or follow the instructions. Take good notes if needed. After a while, go back to those notes and revise them. You don’t need an upcoming test or exam to revise your notes. It’s a continuous learning process; incorporate it into your life.
Build a strong foundation through understanding those fundamentals.
Planning Your Code
Start to focus actively on planning out what you are going to work on instead of jumping into it. This moves from just practicing and into deliberate practicing. How much can you draw somewhat humanoid figures before you realize you need to sit down and study human anatomy a little bit to improve your drawings? How many words of a language can you go through before you realize you need to sit down and think about how those words come together and form sentences? That’s why deliberate practice is more important than just practice.
While you will learn a lot more through the courses on this website over time, they will also hold your hand often. It becomes extremely important to think about what you are going to work on before jumping into the code. The end of goal of learning something new and challenging should always be - apply it to a different problem. And to do that, you need to be able to think more and more about the problem you are working on.
I notice the above as a personal shortcoming at times. I am eager to jump into the code instead of breaking the problem down. To structure it so that it makes sense on how it all connects together. If let’s say you are trying to implement some code for an algorithm to sort numbers -
[4, 7, 2, 6] -> [2, 4, 6, 7]
Don’t try to just write some code and figure things out as you move forward. Think about the problem first,
- what is required - just to sort numbers? any particular way to do that?
- think about what your input would be - positive numbers, negative numbers, floats, repeating numbers, how many numbers?
- think about what your output should be - ascending, descending?
- write down the pseudo-code etc.
It’s a really good exercise as per me and a lot of educators don’t really focus on helping a lot of students create this positive learning habit.
The more you do the above, the more it will become a habit to think of how different pieces connect or should connect to each other. And in relation to this, the more you practice, the more you will learn to think like that.
In a broader sense, being able to break things down can also help to isolate problems within the code. If you go through the posts here in this forum, you will see quite a lot of posts that state “I have this error, I don’t know what to do”. Being able to debug our code is a very important skill and helps to think programmatically as well.
Most errors, at least in Python, are easy to debug. Often, we will have to rely on a google search (which is another important skill to learn). And there are multiple ways to debug. Starting from just simply reading the error and figuring out what the issue might be, to printing certain values of different variables, tot using an actual debugger.
Over time we learn a lot from the above and expand on those skills, but it’s important to know how to debug. So, slowly, learn to do that as well. The plus point is that the more you practice the more errors you will encounter, so the more you can get comfortable with debugging as well.
Yup. Do this. Often. EVERY developer does this.
Feel stuck, can’t figure something out, don’t know what to do next. Google it. Spend time going through the results. But don’t forget to actively think about what you come across and understand it.
This will seem the opposite of the point about googling something. But, if you feel stuck, don’t jump into asking for help on the forums or anywhere else.
Think about the problem, break it down, try to figure it out yourself first. The more you exercises those “thought muscles” the better.
This is directly related to a concept called
Recall when it comes to learning. The more difficult it is to remember something, the stronger the connections between our neurons become when we do successfully recall it. Struggling to make those connections is helpful for us. It’s very easy to ask for help, especially on such forums. Leave that till you have made the necessary efforts yourself.
Another point which is unfortunately not taught well enough at most places. It’s almost problematic as per me.
Slowly, as you learn more and more, you will learn about adding tests to your code. There are multiple ways to do that. The initial way is to think about what inputs your code could have, and what the output should be. For example, I ask you to get an input number from someone and print out the square of the number. You write out the code, simple enough. But instead of providing a number, the user inputs a text/string. Your code wasn’t prepared for that. You can’t square a string. You get an error. So writing a test is essentially trying to think ahead of what problems your code could face and accounting for those. So you could think of this situation, and account for it by checking if the input is a number or not. If it’s not, you could ask the user to input a number instead.
This relates again to planning out your code and breaking it down. It’s again about actively thinking about the problem you are trying to solve.
Learning to explain what you are doing is also important. You don’t have to communicate with someone else. Take an inanimate object, and explain in simple words what your code does, line-by-line.
Learning to read someone else’s code over time is massively helpful. And it’s extremely daunting when you go through large codebases. But if you are able to read and understand someone else’s code, that’s a sign of progress.
You don’t have to do this as a weekly chore. When you implement something, just google it up later. You will find similar implementations after a bit of search (at least for some of the more basic problems), and you will find different ways to solve that same problem. You can learn quite a bit through reading someone else’s code.
Based on how education systems are structured for a lot of people, and how we are made to learn problem-solving skills, trying to focus on the above can create a very strong mental resistance. Often, there are instances where you try to solve a problem but it seems so overwhelming and so difficult, that our brain just tries to escape from it. We try to look for a distraction to get a quick reward and feeling comfortable.
Breaking that mental barrier is the single most important thing to do. The more you systematically approach and solve problems, the easier it will be. But being aware of it is a good first step.
Remember this. This is your learning journey. Not someone else’s. Not something to compare against someone else.
It’s also not about your level of intelligence or any inherent talent.
It’s about the consistent effort you put in over time at a pace that you are comfortable with.
You will see a LOT of people who do better than you in a short amount of time. Doesn’t matter. Focus on yourself. Take care of yourself.
Conclusion (of sorts)
The above might seem overwhelming, and there is quite a bit more to the above. You don’t have to focus on everything at once. Mostly, try to break down the problem and think about it in a more active sense before coding it out. As you move towards building something, being able to break down the problem is immensely important.
MOST online courses don’t teach this. Most traditional education doesn’t teach this. It’s a very big problem.
So, continue to practice. But be more deliberate about it.