I know that none of the people that I have in my circle of people really know what I do for a living. Most seem to think that I fix hardware.
To be clear, I am mostly going to talk about programming from a utility or business standpoint. But even games follow the same principles (although it might not be as obvious).
Programming is a natural thing that people do all of the time - but usually, it is 'throw-away' coding. They figure out how do perform a task, perform the task, and forget about the whole thing until (unless) they need to do it again.
Computer programming requires something more regimented. We (you) are figuring out how to explain to a computer exactly how to perform a task. Because computers are very good at doing exactly the same thing over and over again (but not good at filling in the blanks if you skip a step) it is important to include every necessary step.
Good computer programming would require making those steps simple. Computers can follow complicated steps, but when you are trying to read your work in the future (or someone else is trying to read it) simple will be easier for you. And a good practice would be to make sure that not only are your steps as simple as possible, but that you make them self describing. Name variables so that the tell you what they hold. Put in comments. Include logging that makes your program tell you what it is doing as it is doing.
Great programming adds in speed and elegance.
There is no one way to add speed and elegance. I think that mostly, they will come from practice at trying to be a good programmer.
I think that every program is made out of a small number of 'major' parts.
The data is the information that your program has to work with. Whether it is temperature and wind measurements for a weather modelling program - or the amount of money in your bank account along with your deposits and expenditures...data is the whole reason for writing a program. It is what you want to keep track of and the building blocks that you need to solve a problem.
Presentation is how you show your data (and results) to your user. Input is how you get the source data from them. Ugly screens or complicated interfaces will make it more difficult for someone to use your program. It may be the best at what it does, but if it is painful to use...no one will ever know that.
And processing is all of the work mixing the data together and applying various rules against it. If you have the best data and the most pleasant, understandable presentation...It will not matter if you program does not do something useful (and correct) with it.
From the order that I listed them, you would probably infer that I think the data is the most important part of the puzzle. And, you would be right. If your data is wrong or you are keeping track of the wrong information - your system is never going to be useful. So, the first step in any programming exercise should be to figure out what your data is.
But, whatever you come up with will probably be wrong. With practice, you will get closer to being initially right (so keep practicing) but you will need to keep an open mind as to what needs to be kept track of. And also, what your user will need back from you. As you move through the process both sides of that equation will (hopefully) become clearer and clearer. As changes make themselves obvious - adjust.
The next part of programming is figuring out how you will get that starting information from the user, how you will show them what they told you, and how you will give the results back to them after they have been processed. You will also need to figure out how the processing actions are going to be started. Will the user press a button on screen, set a timer, etc...? A well designed user interface is one of the things that can make or break a program.
And finally, what processing needs to be done? There needs to be a payoff for your user otherwise, they will not go through the bother of starting your program (never mind taking the time to enter all of their data into it!). This is where the meat of programming is. Someone has a problem that they want solved. It is a problem that requires keeping track of a lot of information or performing difficult manipulation of information (or both). Sometimes your user would be capable of doing that work themselves and sometimes they will not be. You will need to make it 'cheaper' (in time, stress, accuracy) for them to use your program than to do the work themselves.
This is a little more than strictly 'programming'. Working through all of these would encompass system analysis, system design, interface design, data processing, as well as the programming part. If you have a team to work with and each person takes a piece - that might make it easier for each to become expert at the part they do. But I would say that being able to see the big picture and all of the parts is what truly makes creating programs fulfilling.