Most people out there can learn to program computers. For the most part this isn’t really rocket science. Sure, when you’re getting into some of the stranger parts of programming like language or operating system design — design in general I suppose — or similar things you can wind up with a different answer.
Today I’m talking about the standard run-of-the-mill programmer, not the lead architect of a project.
I think the difference between a programmer and a non-programmer is patience.
Much of programming is figuring out why something doesn’t work rather than getting it to work in the first place. A lot of time is also spent verifying that what’s been written works like it should — both automated and manual testing is tedious work.
Programming is all about being able to work through the tedium and get stuff done despite the frustration.
Like I said, designing and architecting systems is a different ball game. There’s plenty of classical training that goes into that, but even this isn’t that hard when it comes down to it. It’s learning what works and what doesn’t work over a lot of time. It’s like being a mechanic working on an engine; you just learn over time what feels right and got with it.
Most of this (again with some exceptions) isn’t a science — even if colleges call it “Computer Science.”