Want to learn to code? Don't copy and paste, type out other people's code
shockoe.com
shockoe.com
Then I would open up the book again and compare it to what I had typed, examine the differences between them, and see if/how they explained the errors I was getting.
Suggestion: code fragment on your interactive whiteboard. Ask students what each line does, how the loop works &c.
Then blank the screen and get them to replicate....
Super-simple silly example: You have to write a program to work with four colors: Red, Green, Blue, Black. Naive representation will use strings: "red", "green", "blue", "black". A little smarter would be an enum type where red=0, green=1, blue=2, black=4. And, depending on context, it might even make sense to use individual bits to identify each color: red=01h, green=02h, blue=04h, black=08h. And, if the goal is to extend to other colors, it might make sense to represent them as RGB vectors.
You get the idea. I find that a lot of newbie programmers are too focused on the mechanics of writing code. They forget (or don't know) that investing some time in optimizing the representation of the data or problem they are trying to solve could make a world of difference.
Let's say you have to write a routine that does something based on a color as the input. You have a few choices in terms of how to represent the colors:
- The name of the color in a string
- A typdef enum for your colors (integers)
- A color-per-bit scheme (U8, U16, U32)
- Channel-per-bit scheme (U8)
- 4 or 6 bit packed RGB values (U16 or U32)
- 8 bit packed RGB values (U32)
- 8 bit unpacked RGB values (struct of three U8)
- 16 or 32 bit unpacked RGB values (struct of three U16 or U32)
- Unpacked RGB floats (struct of three floats)
- and more...
I won't go into the implications of each of the above. Some of it is highly dependent on both the system and the objectives of the work being done.Say, for example, that you choose to use the names of colors stored in strings as your color representation. Now you have to compare strings in order to identify the colors:
if(strcmp(input_color, "red") == 0)
{
// Do something with red
}
else if (strcmp(input_color, "green") == 0)
{
// Do something with green
}
else if (strcmp(input_color, "blue") == 0)
{
// Do something with blue
}
... etc
Regardless of language the strings need to be compared character by character. Even if a language or OO framework allows you to say something like if(string1 == string2) you have to keep in mind that what is going on behind the scenes is pretty much exactly what strcmp() has to do. Which means that the above is, at the very least, slow.And, of course, it isn't very portable. What happens if the input has to be in German or Japanese?
The typdef enum representation gives you the ability to use a far more efficient construct to identify your colors:
switch(color)
{
case COLOR_RED:
// Do something with red
break;
case COLOR_GREEN:
// Do something with green
break;
case COLOR_BLUE:
// Do something with blue
break;
... etc
This is much, much faster. It is, at the core, an if/else-if structure that is only comparing integers, which is a single machine language instruction. Fast and clean and language-portable by means of the proper text-to-integer function somewhere to deal with different languages.If you are on an embedded system that can do bit testing in machine language it might make sense to encode one color per bit or one color channel per bit. for example, in some embedded C dialects you might be able to do something like this:
if(color.0) // Select and test bit 0
{
// This is red
}
else if(color.1) // Select and test bit 1
{
// This is green
}
... etc
At this level the advantages of doing this are tightly linked to the platform and the goals of the application.If, for example, one needs to be able to expand the available range of color inputs beyond what can be described with simple words a discrete RGB representation might be the best choice. This is also the case if you wanted to future-proof the program and be ready for when more colors arrive.
Here you have several choices, two of which are to represent each channel with an 8 bit value or choose floats instead.
The 8 bit values can be packed nicely into a U32, making it very efficient. You could also create a struct to facilitate access to the components and let the compiler optimize for you.
The float example is interesting because the conversion from float to whatever (if necessary) can be of any bit width. So, for example, if the color needs to ultimately be mapped to an 8-bit-per-channel display device you can translate from float to 8 bits on output. All of your intermediate math and color manipulation would be done in full-resolution floats which means that you are not going to accumulate errors. This, for example, is important if you are applying FIR filters to calculate missing color sample data from certain video data formats.
Packing has its issues as well. If you are dealing with little-endian vs. big-endian systems there might be overhead associated with unpacking and possibly rearranging a packed RGB value. If you are dealing with processing colors at a massive scale this can have performance and even power consumption implications.
I may have been lucky in that my very first CS professor was hell-bent to teach the importance of thinking deeply about data representation BEFORE thinking about code. He'd repeat this mantra 'till you were sick from hearing it. Years later I'd learn to appreciate this bit of wisdom in more ways than one.
Thanks for sharing!
The probably more important consideration is that with an enum, your compiler can catch misspellings. Depending on your runtime environment, this can be a huge killer advantage. In particular, if your runtime environment can't do much beyond blink an LED to report errors, compile-time checking is really really important.
In general teaching enum's is very important and something I've not really seen schools do (although their "learn to program" programs are typically 101 to newbie, I've never seen a program that really builds on the basics).
As an example, there are a number of sites showing the performance hit you take if you use some of the NS types in Objective-C. If I remember correctly, in some cases you are talking about NS types running 400 times slower than alternative code.
In my mind, the question of data representation could also include this very choice: Do I use an NSArray or do I do it "by hand", allocate memory and use a "simple" array?
Has really been effective for me as I feel like I now have a pretty good (beginner) grasp on JS and Python
[0]: http://vertstudios.com/blog/how-to-read-programming-tutorial...
For some reason, probably because I was a tiny kid learning a new thing, this tedious task was so much fun. And that's how I learned my first programming language. Never opened a single tut or instructional book.
They never worked worked first time as I'd invariably mistyped various characters, but the subsequent bug finding taught me about how the code worked.
The bonus was you got a playable game at the end of it.
It's very hard to learn how the code you're using works when all you've done is copy and paste it.
My very first programming class was Java and I had no experience prior.
I felt so alive writing every character and every line. I was too excited to read the paragraphs of description in the textbook because the code told most of the story anyway. I could look at it, read it and mostly understand it, then retype each character at a time and watch it work. Once it worked, I varied small things. Anything I could improve. Sometimes the goal was to make it as condensed as possible, sometimes it was to try to make it simpler to read, or to adapt a method for ints to also work on floats, or to add parameters making the code even more flexible. Kid in a candy store mentality fits perfect.
I did this for almost every example in the book, even ones we didn't cover in class, a few hundred in total.
I started by typing out other people's code from various books or tutorials, but found that it produced a feeling of "success" that made me lazy in taking the step to producing my own code from scratch. I had that feeling of progress, without actually making real progress.
In my experience the best way to learn to code is to pick a small-ish project that you personally want to use and just get started. You'll screw up a bunch of times, but it's the only true way to learn coding.
http://rubyrogues.com/070-rr-what-is-a-good-starter-project/
Integrating the manual activity of typing with the mental activity of thinking about what you're typing in and the visual activity of reading someone else's code just stimulates a lot of different neurons and helps you learn.
> This website uses CloudFlare in order to help keep it online when the server is down by serving cached copies of pages when they are unavailable. Unfortunately, a cached copy of the page you requested is not available, but you may be able to reach other cached pages on the site.
I'm probably being significantly thick-headed, but what exactly is Cloudflare even doing if it's not properly caching pages before traffic hits? And why would they want to advertise that fact on the error page?
http://tommy.authpad.com/don-t-copy-and-paste-other-people-s...
If you want to read it elsewhere
CloudFlare doesn't cache HTML by default, though you can enable that with Page Rules. http://blog.cloudflare.com/introducing-pagerules-advanced-ca...
And the origin needs to be responding long enough for us to keep a copy in cache, once the Page Rule is enabled.
It also means I've now heard of Cloud Flare.
It was a pain, but certainly learned things (like how poor / slow a typist you might be).
This slow process allowed you time to see and think about what was going on.
I picked up a few ideas, but you didn't really get the sense of what the program was doing in most cases.
These programs would get run only a handful of times, since I had no way (or it never occured to me) to save them for later use.
It's this memorization trick teachers usually told us to do, basically rewrite the notes you've taken or things you need to remember. It's somehow boring to apply and while doing it you don't necessarily realize you are learning but it does work great.
Then it's extended with programming where what you typed is used interpreted by your computer and turns results from what was typed.
When I was in school, I found that the most important part of the notetaking process was manually writing the notes during lectures. Reading them afterwards rarely helped me remember or learn more. Reading notes written by someone else was next to useless.
I think the best method to learn coding highly depends on the learning style of the person.
Understanding the data structures, not so much, but when you're trying to learn a new language the greatest initial friction is the syntax.
I have to admit, it greatly aided my ability to recall things and get "fluent" with the language.
open up your favorite library on Github, go back to the very first commit and start reading, commit by commit. If you don't understand something, just copy the difficult section, line by line, on a repl, inspecting variables and/or function results.
So in my case, it's more work to type out code than to copy and paste, but it saves work in the long run.
Related, this approach also reveals syntactic errors in printed books. This re-enforces the principle, since it shows that even published authors make mistakes. It also means that, even following the text verbatim, I have to account for code errors and the standard bugs (as others note here).
Somewhat related to other comments here regarding closing the book and trying to recreate the code or underlying logic, I often think of REPL iterations in relation to industrial-scale engineering (rocket launches, bridge-building, etc.). If the cost of the test-iterate cycle is not seconds or minutes, but months and millions of dollars, we'd think very carefully about the logic and edge-cases. Granted, I like that fast iteration is possible, but in cases where that's not an option, you'd just have to use other approaches. Mostly, that would mean truly, deeply understanding what you're asking the machine to do.
Despite being a fan of Gonzo Journalism, I've never heard the anecdote about transcribing entire Hemingway novels. Re-typing code examples verbatim seems sort of obvious, but re-typing narrative fiction, not so much. So it's sort fascinating to hear that anyone in fact did that (and for exactly the same reason).
This is the only article I know of someone using this method in narrative: http://www.publicationcoach.com/how-to-use-deliberate-practi... .
It's unfortunate the article is scientifically suspicious.
It lead to a lot of frustrating moments though. I remember sitting there and fuming trying to figure out where a variable came from. (This was when C++ was starting to get popular and variables started popping up everywhere. I was trying to figure out where in the world a counter was being declared in a for loop. Turns out it was being declared in the for loop.)
A bonus of this process is that I made a TON of mistakes and was exposed to dozens of programming styles. Because of this I can just skim code and error messages and have a general idea of what to look for.
So I regrouped and started writing my own code. Lots of code. Very bad C++ code. Excruciatingly bad code. Over and over again. I desperately wanted to understand, and I studied the books time and time and time again, taking those concepts into my very bad code, and after time, my code became less very bad and just... bad. After about two years of this, I was barely marginally competent, but I did pretty much understand how to write code. Then I went off to college and learned computer science.
Can't disagree with that. :-)
A side effect of this was that before kicking off the slow compiler I would do a careful read of my code to be sure I hadn't done anything stupid. Often finding other bugs along the way before I finally kicked off a compile. Whereas programming on the fast compiler was more iterative and it made me a rather lazy since I could just compile/edit my way to a clean build without thinking too hard about the code.
Writing code slowly let me write better code.
Back in the day when you had to submit your code to the computers overnight and wait until the next day to find out if you got your output or just a one-line compiler error, you were much more careful to avoid errors, big or small.
Having a longer iterative cycle can be good training.
I was in college at this point, so it made spotting syntax errors easy for multiple choice questions or debugging on tests.
I also approached coding problems on paper before typing a line of code. This helped to grow how I approached problem solving, rather than whether the page would run properly or not.
If I were to start fresh I'd still take the same approach. I'm a huge believer in repetition for remembering, and writing out code rather than copy/pasting or have it be autocompleted, eventually pays off.
"During this time he worked briefly for Time, as a copy boy for $51 a week. While working, he used a typewriter to copy F. Scott Fitzgerald's The Great Gatsby and Ernest Hemingway's A Farewell to Arms in order to learn about the writing styles of the authors."
I agree with this a lot. Just the act of typing it out is better (even if just marginally) than straight up copying and pasting especially early on in your career. There are some pretty complex tutorials for Java EE that rely on copy/paste and even with the context it's hard to absorb a lot of it.
It's down for me.
But thanks for the kind words!
I'll have to catch up with you guys sometime IRL. Really glad to find motivated devs in RVA.
I assume it's some sort of "kinesis" style loop in the brain that is at work when you do this. "Hands-on," learning is a very useful tool.
"The right approach is to get your hands dirty, get inside the core of the code and understand it, thus implement it well. We should also try to remember the code as much as we can at the first place so if we face a similar problem later, we can solve it in no time. Also I would suggest not to copy paste it and try to type it on your own (if the code consists of a few lines), this approach will definitely help you to remember it for later use. The coding ninjas, the coding beasts, the rock start programmers, whatever you call them, all the great programmers definitely have one thing in common and that is they are like living library of the programming language and framework they use. They spend maximum time in getting things done (not finding the solutions to the problems they have already worked on before)."
To be fair the case I am imagining myself in is the times I have looked up something relatively simple like opening a socket or something pretty mundane, so this may not apply to all situations.
This is how I taught myself mathematical problem solving (and math as a side effect). I would read the problem statement, instead of looking at the solution, try to solve it for upto 15 minutes or sometimes even for several days depending on how much value I am planning to get from the solution.
The Brachistochrone problem(http://en.wikipedia.org/wiki/Brachistochrone_curve) is an example of a problem that I tried to solve for several days. Newton solved it in 3 hours, and when you learn math like that you don't take things for granted. You can admire the amount of insight that went into the steps. You can also internalize the knowledge obtained thus exponentially more effectively than you would by listening(and falling asleep).
I've heard this story many times over the years and was always found it amusing but was skeptical that it did HST any good. I mean, what use is it to blindly just copy something letter by letter?
I did Nanowrimo on a whim this year and it was a lot of fun (I doubt I'm actually any good at it, though). In doing it I found myself going to Gatsby and a Hemingway book (The Sun Also Rises) for examples of clear, direct prose. I thought back to this Thompson anecdote and thought to myself that if I ever wanted to really pursue writing, a straight copy of one of those books would help my prose ten fold.
So I agree with this article. Type out the code you're borrowing from, don't copy and paste. Also, tchlock23 is right in that you also need to start some small projects from scratch and suffer through them with minimal help.
The book, "Day," by Kenneth Goldsmith was created by typing out, word for word, an issue of the New York Times. It's considered a book of poetry.
Typing out a novel word-for-word doesn't seem all that insane to me. And it likely isn't a useless exercise either: artists learning to draw and paint have often tried to reproduce the works of the masters in painstaking detail in order to try and internalize the techniques and effects used. I suspect the mechanical motions of typing out a piece of writing you admire will illicit much the same response in your brain as it likely shares the same mechanism of reinforcement.
char *names[] = {"Bob", "Dole", "Bananas"};
don't just write out the text as you see it (which is what I did too often). Think through and say "ok, I am creating a variable called names. There are brackets, so it must be an array, and there is an asterisk after char, so it must be an array of pointers to char. Then I construct it with string literals..."I caught myself writing whole source files from a book without understanding a single line. I agree with danielweber when he says to try and reproduce the code before typing it out verbatim.
That being said, word of advice: Make sure the code works before you start copying it, nothing is more frustrating then grabbing something OS - typing it by hand, then finding out it doesn't work (Granted, if you learned enough from typing it - hopefully you understand it well enough to fix it but you could have also picked up bad habits if it was broken to begin with.)
After 20 years, I've recently switched from csh to bash (so I can use rvm), and I've been applying this neuro-hack to less-used command. When you copy-and-paste, there's a kind of finger-learning that you miss out on.
Learning to play a guitar, for example, is difficult and yet crazily creative for this reason. It is (almost) completely behind finger-learning and thus in many original forms each with a signature of the individual who created the piece.
It is one of the key things that helps you get a "feel" for writing code, imo.
I also do this with math these days. Whenever I'm learning a concept I'm writing out all the definitions and theorems, which gives me time to reflect on them and helps memorization. In general, writing is an excellent way of learning.
http://webcache.googleusercontent.com/search?q=cache:www.sho...
At the end, the time spent to rectify the errors resulting from copy + paste is much more than I thought I would save.
- When I started out, including a floppy disk with a book or magazine was a rarity, so BBC Basic, Spectrum and PCW-9512 had to been typed in by hand, with frustrating hours trying to figure out why they didn't work (usually typos)
letterlasso.com signup with your email and we'll send you a testflight email in a couple weeks. Anyone who happens to see this and is willing to help us, it would really mean a lot!
http://tommy.authpad.com/don-t-copy-and-paste-other-people-s...
We're restarting our server because we weren't quite prepared for #1 on HN server load
I learn coding through doing it myself, not from simply seeing someone else's work.
When I come across something I don't fully understand, I'll take a few minutes to investigate that bit of code to learn even more.
Now get off my lawn.
I still do this when learning a new language, and I've been programming for almost 20 years now...
say, in c, you could type the main, and when there is a function call, go there and type it, understand, come back.. that way you get the flow of it and you'll understand the whole code in one go.
Yes, it helps to type.
Do not copy and paste code when you're trying to learn
Always type it out
http://karma-engineering.com/lab/wiki/HowTo
Eventually you must try to re-invent and re-write some of the classic procedures without trying to recall a memorized text.)
There are some immortal procedures: http://karma-engineering.com/lab/wiki/Tutorial5 to re-invent.)