I just graduated a year early from high school and I’m doing a CS major in the Fall. I took AP computer science at my high school and loved it. I’d love to learn more, but I feel like the links you post above help me learn bits and pieces (trees), but I don’t really know where that’s leading (forest). In essence, I want to learn about coding before I learn more coding, so that I can direct my studies in the directions I want to take them.
I think you should elaborate on this. This seems to be the first project I would want to apply my coding skills to.
“Productivity software. Writing your own is much nicer than using stuff made by other people. The reason there are so many to-do list applications is because everyone’s needs are different. If you use the terminal as your interface, it doesn’t take much effort to write this stuff; you’ll spend most of your time figuring out what you want it to do. (Terminal + cron on Linux with JSON log files is a very flexible productivity app platform in my experience.)”
I don’t know of any good resources for learning what the forest is like. As far as I can tell, everyone who knows what the forest is like learned by learning about more and more trees.
Assuming your AP computer science class used Java, a good next step is to learn Python (probably using some resource like Dive into Python written for people who already know how to program) and learn the command line (using the Hard Way book on the topic or http://code.google.com/edu/tools101/linux/basics.html or something).
Then you can take a shot at following the instructions in the rest of this comment.
Note that it assumes you’re on Linux. I don’t know the best way to duplicate my results on Windows.
If you’re on Ubuntu, a good next step is to type “man gnome-terminal” from the command line and figure out how to use flags to cause gnome terminal to run an arbitrary program when it starts. Then you can substitute the command you construct for the Firefox command in the original cron example.
With lots of Google searches and persistence and trial and error, it should be possible to set things up so that you get a window popping up every hour with a random item from your to do list. You can complicate things from there as you desire. For example, figure out how to input some number of minutes that the window should wait before popping up again. There’s tons of stuff you could try out.
Persistence example: if you get gnome terminal to start running a command, the terminal will close as soon as the command terminates. So you’ll need to ask the user for input in the last line of your script. (In user experience terms, this will translate into you pressing enter to close the terminal window that pops up.) This is one of those things that could take an hour or so to figure out.
In general, you want to start by getting extremely simple examples to work and gradually modify them, making sure they still work after each modification.
You should probably ignore the JSON bit for now and craft your own log file formats; it will be more educational.
Feel free to respond to this comment with more questions. I’m counting on you to figure out a lot of stuff for yourself here. You’re going to have to do this anyway if you’re going to be a coder; you’ll need a decently high tolerance for frustration. But I can help you out some in the early stages.
I don’t really know where that’s leading (forest). In essence, I want to learn about coding before I learn more coding, so that I can direct my studies in the directions I want to take them.
I think the “forest” is knowing different programming metaphors, and knowing when to use which one. A proper choice of metaphor will allow you to solve the problem more efficiently—which means that the program is not only quickly written, but also easier to understand (though sometimes only for people familiar with given metaphor).
By metaphors I mean things commonly called “programming paradigms” and “design patterns”; the former are more abstract, the latter are more specific templates for solving given set of problems. It is good to know these individual metaphors, and to be aware that they exist and you can choose the one you need (instead of seeing every problem as a nail, because you have completed a good hammer-using lesson and you are a certified hammer expert). Different programming languages put emphasis on different metaphors, which is why a good programmer usually knows more than one programming language.
A programming paradigm is an answer to question: What exactly is a program?
a sequence of commands for the computer
a collection of mathematical functions
a collection of facts and predicates (to be reasoned about by a standard algorithm)
a collection of small parts (objects) cooperating with each other
a collection of reactions “in situation X, do Y”
Depending on your problem, a different paradigm is useful. A functional paradigm is useful when you want to calculate functions. A command (imperative) paradigm is useful for tasks you could best describe as series of steps. An object paradigm is great for a user interface, together with “if this is clicked, do this” reactions. Sometimes you should use different paradigms for different parts of your program; for example a program for solving mathematical equations, with a user interface. Sometimes different paradigms support each other; for example you can write a list of steps to do, and then describe additional aspects such as: “and by the way, every time you read from a file or write to a file, make a note in the application log”.
On the bottom level (machine code) it is all a sequence of commands for the computer. Thus the imperative paradigm is most frequently used, because it is difficult to avoid in some tasks, while in other tasks you can still use it instead of other paradigms (even if it sometimes results in a horrible code). Object paradigm is great to split complex code into small manageable parts (although most people split complex code to complex parts, thus creating imperative/object hybrids), and it is also a popular marketing buzzword. Function paradigm is the right thing to do when you have functions without side-effects (the same inputs always produce the same outputs), because calculation of such functions can be cached, paralelized, etc. (Again, most people create imperative/function hybrids by writing functions that have almost no side-effects.)
There is a pattern here: most programmers are stuck in the imperative paradigm, and don’t really understand the constraints and benefits of the other ones. Many languages support multiple paradigms to allow you use them as you need, but this also allows the abuse. It is good to have an experience with a language that only allows one paradigm and nothing else, to understand the essence of the paradigm, so you can later use it efficiently in other languages.
In theory, a perfect programmer needs these skills:
high-level understanding of programming paradigms and design patterns;
mathematical insight to understand complexity of algorithms;
ability to communicate clearly, write clean code, tests and documentation;
detailed knowledge of necessary programming languages and technologies.
In real life, in most job interviews only the last skill is required, because it is most easy to evaluate by people who themselves don’t understand programming. (“Do you have Java experience?” Check. “How many years?” Write a number. “Did you also work with databases?” Check. “Do you know SQL?” Check. “Do you also know Oracle databases?” Check.)
Long comment here.
Short comment:
I just graduated a year early from high school and I’m doing a CS major in the Fall. I took AP computer science at my high school and loved it. I’d love to learn more, but I feel like the links you post above help me learn bits and pieces (trees), but I don’t really know where that’s leading (forest). In essence, I want to learn about coding before I learn more coding, so that I can direct my studies in the directions I want to take them.
I think you should elaborate on this. This seems to be the first project I would want to apply my coding skills to. “Productivity software. Writing your own is much nicer than using stuff made by other people. The reason there are so many to-do list applications is because everyone’s needs are different. If you use the terminal as your interface, it doesn’t take much effort to write this stuff; you’ll spend most of your time figuring out what you want it to do. (Terminal + cron on Linux with JSON log files is a very flexible productivity app platform in my experience.)”
I don’t know of any good resources for learning what the forest is like. As far as I can tell, everyone who knows what the forest is like learned by learning about more and more trees.
Assuming your AP computer science class used Java, a good next step is to learn Python (probably using some resource like Dive into Python written for people who already know how to program) and learn the command line (using the Hard Way book on the topic or http://code.google.com/edu/tools101/linux/basics.html or something).
Then you can take a shot at following the instructions in the rest of this comment.
Using cron:
http://lesswrong.com/lw/2dg/applying_behavioral_psychology_on_myself/267c
Note that it assumes you’re on Linux. I don’t know the best way to duplicate my results on Windows.
If you’re on Ubuntu, a good next step is to type “man gnome-terminal” from the command line and figure out how to use flags to cause gnome terminal to run an arbitrary program when it starts. Then you can substitute the command you construct for the Firefox command in the original cron example.
With lots of Google searches and persistence and trial and error, it should be possible to set things up so that you get a window popping up every hour with a random item from your to do list. You can complicate things from there as you desire. For example, figure out how to input some number of minutes that the window should wait before popping up again. There’s tons of stuff you could try out.
Persistence example: if you get gnome terminal to start running a command, the terminal will close as soon as the command terminates. So you’ll need to ask the user for input in the last line of your script. (In user experience terms, this will translate into you pressing enter to close the terminal window that pops up.) This is one of those things that could take an hour or so to figure out.
In general, you want to start by getting extremely simple examples to work and gradually modify them, making sure they still work after each modification.
You should probably ignore the JSON bit for now and craft your own log file formats; it will be more educational.
Feel free to respond to this comment with more questions. I’m counting on you to figure out a lot of stuff for yourself here. You’re going to have to do this anyway if you’re going to be a coder; you’ll need a decently high tolerance for frustration. But I can help you out some in the early stages.
I think the “forest” is knowing different programming metaphors, and knowing when to use which one. A proper choice of metaphor will allow you to solve the problem more efficiently—which means that the program is not only quickly written, but also easier to understand (though sometimes only for people familiar with given metaphor).
By metaphors I mean things commonly called “programming paradigms” and “design patterns”; the former are more abstract, the latter are more specific templates for solving given set of problems. It is good to know these individual metaphors, and to be aware that they exist and you can choose the one you need (instead of seeing every problem as a nail, because you have completed a good hammer-using lesson and you are a certified hammer expert). Different programming languages put emphasis on different metaphors, which is why a good programmer usually knows more than one programming language.
A programming paradigm is an answer to question: What exactly is a program?
a sequence of commands for the computer
a collection of mathematical functions
a collection of facts and predicates (to be reasoned about by a standard algorithm)
a collection of small parts (objects) cooperating with each other
a collection of reactions “in situation X, do Y”
Depending on your problem, a different paradigm is useful. A functional paradigm is useful when you want to calculate functions. A command (imperative) paradigm is useful for tasks you could best describe as series of steps. An object paradigm is great for a user interface, together with “if this is clicked, do this” reactions. Sometimes you should use different paradigms for different parts of your program; for example a program for solving mathematical equations, with a user interface. Sometimes different paradigms support each other; for example you can write a list of steps to do, and then describe additional aspects such as: “and by the way, every time you read from a file or write to a file, make a note in the application log”.
On the bottom level (machine code) it is all a sequence of commands for the computer. Thus the imperative paradigm is most frequently used, because it is difficult to avoid in some tasks, while in other tasks you can still use it instead of other paradigms (even if it sometimes results in a horrible code). Object paradigm is great to split complex code into small manageable parts (although most people split complex code to complex parts, thus creating imperative/object hybrids), and it is also a popular marketing buzzword. Function paradigm is the right thing to do when you have functions without side-effects (the same inputs always produce the same outputs), because calculation of such functions can be cached, paralelized, etc. (Again, most people create imperative/function hybrids by writing functions that have almost no side-effects.)
There is a pattern here: most programmers are stuck in the imperative paradigm, and don’t really understand the constraints and benefits of the other ones. Many languages support multiple paradigms to allow you use them as you need, but this also allows the abuse. It is good to have an experience with a language that only allows one paradigm and nothing else, to understand the essence of the paradigm, so you can later use it efficiently in other languages.
In theory, a perfect programmer needs these skills:
high-level understanding of programming paradigms and design patterns;
mathematical insight to understand complexity of algorithms;
ability to communicate clearly, write clean code, tests and documentation;
detailed knowledge of necessary programming languages and technologies.
In real life, in most job interviews only the last skill is required, because it is most easy to evaluate by people who themselves don’t understand programming. (“Do you have Java experience?” Check. “How many years?” Write a number. “Did you also work with databases?” Check. “Do you know SQL?” Check. “Do you also know Oracle databases?” Check.)