First, though, let me eliminate a myth: some people think that math skills are important, but I've seen great mathematicians who are mediocre programmers, and lots of great programmers who are certainly not mathematicians (and probably never expected to be). Programming is more of a designer's task--to be a good programmer, having an eye for style and good design is extremely helpful. I don't mean the type of style that governs where you put pieces of syntax (for instance, in C, there are several places where you can put curly braces to surround blocks of code, and while there are heated debates about whether Code: if (...) { } is better than if (...) { } these are small points of little consequence as long as you are consistent, a trait that will eventually come naturally. What I really mean by style is that you have to have a good sense for descriminating between "good" and "bad" approaches to attacking problems. Why, you ask? When you first sit down to write a program, you probably don't know exactly what it should do (or how to do it). If you're disciplined about it, you'll take some time to plan things out on paper and figure out more or less what you'd like your program to do. That's great, but it won't substitute for having actually used the program and noticed that, yes, it would be fantastic to add this one little feature here. The secret is that adding little features can be very hard! This seems surprising to someone who's never programmed before: all you need to do is have it print this one piece of data, or take this one type of input, or, etc etc. The problem is that inside the program, the architecture might not be designed to support that kind of information. For instance, let's say that you wanted to move a button from one place to another on a simple graphical user interface. If the program has been well-designed, this shouldn't be too much of a problem, but if it hasn't, well, consider this possibility: the position of the button is governed by its location in pixels. All button locations are hard-coded into the program to allow it to decide which button a particular moues click was over. Now, if you move one button, you may have to go back and change where every single button is located both in the routine to draw the buttons and in the routine to accept the input. This can be quite a hassle! Clearly, you want some way of having a notion of button positions that isn't quite so hard to change. But if you started out your program and didn't consider that it would be nice to be able to move the buttons around, bam, you have to go back and change possibly 20 or more lines of code (say, two for each button) just to move one of ten buttons. And if you make a mistake with one button, you're likely to see unexpected results that whose cause is hard to discover. This kind of program design is brittle: it can work at first, but when you need to change something, it's not flexible. Each button depends on every other button and relies on the programmer to make the changes. A much better approach would be one in which the position of buttons when they're drawn and when they're clicked on are linked--changing one wouldn't mean you have to change the other. The more willing you are to put in the up-front thinking before designing your program, the easier you will find the actual writing of code. This is not to say that when you're first learning you shouldn't just write some simple programs without worrying too much about these issues. But you should be prepared to pay attention to these things and what problems your first programs did have. The second trait that you need is patience. At some point in your programming career, you will certainly make small mistakes that cost you hours of debugging only to realize that you were misspelling a variable name so the compiler thought it was another variable. These things happen even to good programmers--and the better you get as you practice, the more you find that your bugs are interesting--but still hard to find. If you're not willing to patiently work through possible hypotheses and test each one in turn, you're probably going to find programming to be frustrating as much as it is exhilarating. If you're looking to eventually have a programming job full-time, you'll want to acquire excess patience because you'll almost certainly be expected to spend a great deal of time working on documenting your code for other programmers and possibly even hunting bugs in someone else's code. The benefit of all of this is that you gain an eye for small details that can have ripple effects and you become much better at the process of asking yourself what could go wrong and how can you test it. Finally, you have a lot of tools at your disposal to help mitigate the problems; you can use the compiler to find syntax errors and debuggers to find runtime errors. Life is not bleak: not all of your time will be spent finding bugs! Third, you need to be able to think in a precise, rigorous way--you have to be willing and able to specify all of the details in a process and understand exactly what goes into it. This can lead to some amazing realizations--for instance, you will understand almost anything better once you've written a program to actually do it. One story goes that a group of programmers discovered a flaw in a state law when trying to program the logic of the law--it turned out two paragraphs made contradictory statements! Nobody noticed until they tried to make it easy enough that a computer could understand it. But it does mean that you need to have the ability to in some way come to understand the entirety of a process at the level of detail required for a computer to be able to mechanically reproduce it. At the same time, you must be capable of framing problems the right way and be or become a good problem solver. While your program may need to accomplish a certain task, don't get caught up in the first way you tried to solve the problem. For instance, if you need to store 20 phone numbers, it might make more sense to use an array than 20 separate variables. Even though you could eventually write the program that way, it would be much better to write it with the array. It would be a shorter program and an easier program to maintain. If you are persistent, willing to pay attention to issues of design and focus on both problem solving and precise solutions to problems, you will go far as a programmer. If not, then you may find a programming career to be frustrating and tedious.