Figure out a problem that interests you, and then break it down into discrete steps.
The only way to learn this is by doing it. Dealing with problems already broken down for you by someone else might work for learning the basics of syntax, but yeah, it doesn’t really help you with the conceptual matters.
Say I need to clean my gutters. I can break that down into a number of steps: Move the ladder next to my house, climb the ladder, pull the shit out of the gutter, put the shit somewhere for temporary storage, climb down the ladder, move the ladder a few feet down, climb back up it, pull more shit out, etc.–these last few get repeated several times, of course, so it might be represented as a loop: do (these things) until (ending condition) is reached.
There are a couple more steps, of course: dispose of the shit, and return the ladder to its storage location.
Then, I break each of those steps further down. Moving the ladder next to my house involves getting the ladder out of my shed, carrying the ladder, setting the ladder down, opening it up, and finally moving it into its final position.
And we can break it down further: getting the ladder out of my shed involves getting up from where I am now, walking to my shed, opening the door, walking to where the ladder is, wrapping my hands around the ladder, lifting the ladder up a few inches, walking back outside the door, closing the door, etc.
“Pulling shit out of the gutter” also requires a number of steps: I reach my hand in, wrap my hand around a bunch of shit, lift the shit up, move my shit-filled hand away from the gutter, drop the shit–and since this is repeated a few times for each trip up the ladder, then it too can be represented as a loop, nested within the broader go up the ladder–pull shit out–go down the ladder–move the ladder loop described above.
You keep dividing these steps into further and further substeps and control structures until you reach the level at which your chosen language and environment abstracts away everything more fundamental.
You do this enough, and you’ll notice a few things. First, there are certain patterns that are approximated in a number of different problems–some are common to a class of closely-related problems, others are mostly universal. Second, you’ll notice that certain collections of substeps are logically equivalent to other, differently-expressed collections of substeps, and sometimes one form or another of expressing it can be better either in terms of how much time it takes you to write it, resource usage, the time it takes to execute, etc. Third, a lot of times processes that you thought were very different actually look very similar on a more fundamental level, meaning that you can use the same code to accomplish different tasks by adjusting some starting parameters.