I need to teach a teenage beginner programmer (private tutoring style). The problem is that despite their poor knowledge and skills, they are sure of their abilities, to the point where I find it hard to teach them "better ways".
What's the best way to tackle this?
Just to be clear what I'm talking about:
Let them fail. Nothing proves your own mortality more than seeing bugs you never thought possible in your own code.
Ok here comes a rather philosophical, but nevertheless correct, idea:
A strange phenonemon is that regardless the skills people have or don't have, the skills they think they have are more or less constant.
This is because the skills you have are the only skills you can use to judge the skills you have....
This lead to the phenonemon that your pupil, and many others, suffer from: "unskilled and unaware of it"
See this very interesting text: Unskilled and unaware of it: How difficulties in recognizing one's own incompetence lead to inflated self-assessments. [1]
Now, ask yourself, why you think you are skilled and your pupil is not? You know you shouldn't copy paste from the internet. But if you really know why, why is that? If you can phrase it for yourself, why not for her?
What I mean is, if you know something is bad, you should know it that well that you can explain it to others. If you want to tutor, make a habit of questioning your own certitudes. Explain them to yourself as if you had to persuade yourself.
And importantly, try to find examples. Examples are the alpha and the omega of teaching. That's how people tend to get something: by seeing an example of it.
If a design is bad, show her where it goes wrong with an example. If you cant find an example, produce one yourself. If you can't produce an example, ask yourself why that is.
I think if you can find counter-examples for every false certitude a beginner has, you will not find it that difficult to persuade them.
[1] http://psycnet.apa.org/?fa=main.doiLanding&doi=10.1037/0022-3514.77.6.1121Simply ask.
Let them do something. When you see they do it wrong, ask why they do it. Let them explain their reasoning. Nobody likes it to be pampered but everyone likes to boast -- to the point where they will talk themselves into a corner.
When they start to struggle with their answer, ask a "how about ..." question: "How about you encapsulate this into a class, so you can forget about the details?"
This makes them lead themselves, using your experience.
[EDIT] In my experience, there are no fools. When someone does something extremely foolish, that happens for two reasons: They didn't think about it at all ... or they thought about it and came to the conclusion that this course of action was the perfect one. Since you can't tell what it was by looking, you have to ask. This is the key to answer your question: How can I help?
Unplug the internet connection.
I've done private tutoring for some years, and I think that the same approach can work with maths and programming. (After all we know that they're more than closely related).
Point him/her at StackOverflow, and see how many questions they can answer.
The breadth of issues on here might give them some idea how big the programming problem space is.
Teenagers almost always think they know everything. In some ways they're like two- or three-year-olds - their experiences haven't taught them (yet) that there's more to [insert your thing here].
Working with teenagers in my church youth group and as a Boy Scout leader (and Computers Merit Badge counselor) has taught me a few things:
I was once that know it all, fresh out of college developer. It took about 2 weeks and 10 code reviews to show me that I was nothing.
When I started my current job out of college, I had to do a throw away program to learn the companies standards for 2 weeks. My code followed the companies SOP for development, meaning the code was code review. The two code reviewers I had tore it apart for 2 weeks. By the end of it, I realized that I and my code are no better then anyone else. That is the exact time that I started to grow as a developer and actually learn.
It's not enough to tell them they're wrong, you have to show them. There are limits to the coding style you describe. You're going to have to make your student reach those limits before they can go beyond them. Challenge them with interesting problems that they won't be able to solve the easy way. Work through them with the student the right way. I'd recommend Project Euler [1], but it's not for everyone, and I have a feeling you're going to need to find problems that are particularly interesting to this specific student.
[1] http://projecteuler.net/Give them a rather complex assignment. When they complete it, analyze the code failures (such as lack of extensibility, etc), and make them, for example, extend it. Make them do modifications that require changes in the copy-pasted code. As they run into difficulties, explain how these could be avoided, by better design, and understanding what they copy-paste.
Additionally, you might what to give them problems from http://projecteuler.net/, which require thinking and not just brute-force+copy-paste programing, though i may have diverted myself a bit.
Require her to grow a project: to start it and then, in your next assignments, add to it.
That should:
I suggest too that you concentrate on verifying the correctness of program's output (because the extent to which the output meets requirements is an objective measure of goodness, whereas 'design' is subjective).
Something else is to teach by example ("that works; I would have done it this way though, because ...").
Confidence is a common and necessary attribute of programmers. We tackle problems that seem hard in their totality, and often are in their constituent parts. This confidence can be evident in strong ego, and even arrogance.
I remember being confident at pretty much every stage of my development career. The first time I wrote some code in assembly, I thought I could rule the world. That feeling is less strong now, because it is less important to me. I have been humbled so many times by other developers, and by the rapid, constant evolution of our field, that I assume anything I know to be a "truth" now, will be considered terrible practise in very short time (I exaggerate to make my case, but believe this to be true in spirit).
For me, the best way I have learned the "better way" is by using those tools and practices. Make the student work with, and modify good code, so they appreciate the elegance and ease that prior programmer has afforded them. Make them use design patterns and frameworks (e.g., MVC) that are generally agreed on to be a good thing at this point in history.
Ask them to do things THEIR way as well, and then discuss the differences. Why is A preferable to B? More maintainable? Less lines of code? Less layers of abstraction for a new developer to get oriented with? More loosely coupled? Better documented? Faster? More common standard? Feels better?
Give them a task that is very hard. Look through 'The Art of Computer Programming' as there are plenty of good ones there. Maybe issue an NP-Complete problem. Then when it runs in O(stupid) you can point out how bad there design way and show them why they were wrong. Or maybe ask them to write something in under-x-lines of code.
I tend to think I am right until I find out that I am wrong. The lessons best learned are the ones you find out yourself
What was it Obi-Wan said... "Was I any different when I was that age"?
Give them problems from TopCoder, and then compare and contrast the elegance and efficiency of their solution to the examples of contest winners.
One option might be to get them trying to contribute to an open source project. Pick a bug and try to fix it together. It might be a helpful way of showing them other peoples code and getting a wider response to their code when they try to submit it to the project.
Your problem is not new.
Here is some research on the subject, makes an interesting read. Unskilled and Unaware of It: How Difficulties in Recognizing One's Own Incompetence Lead to Inflated Self-Assessments [1]
[1] http://www.apa.org/journals/features/psp7761121.pdfHis fake omniscience is due to insecurity, not confidence. You must destroy him before he can be rebuilt.
Actually sounds like fun... =)
Introduce them to StackOverflow
I find that seeing the depth and breadth of knowledge available, especially dealing with somewhat foreign languages and concepts, is extremely humbling, even on my most egocentric days.
Tell him/her "Until you can out-wit Jon Skeet, you've got more to learn."
I personally feel the best way to teach is not to tell a kid how to think but to ask them what they think and then ask them to defend their ideas with facts. So if the kid says XYZ is the best method don't disagree say, "OK great answer and now why is it the best?"
Never use "but" with a kid, or anyone really, because it sounds like you are saying, "I heard you BUT you are wrong." Kids just shut off if they think you aren't listening to them. I try to go by the adage that you should never take away from what they say but instead you try to nudge them in the proper direction by showing them how to deduce and answer for themselves.
Though you should be careful that in the teaching you don't forget to keep you mind open and learn too; very often we learn from those we teach.
Oh, and make sure you are non-confrontational. You aren't there to force them to do things your way, you're there to teach them how to think for themselves and you're just providing the tools.
Maybe you can get them to shift their ego. Instead of being writing the best code around (as we are all :), maybe they can find some fun at saying WHY other's code SUCKS ? What if they where the buyers, would they pay for that ? Since they would be riches (after coding some killing app, of course), they would not have time to code all what they want - so they would have to hire - what kind of code would they want ? Is unmaintenable code ok ?
And what if they were Bill Gates with 100 000 developpers beneath them ? Would they accept that a wiz kid create a killing feature that nobody would understand ?
That's the beginning of code review. And the begining of great software development carriers, I think.
All the best :)
This is coming from a teenager,
choose one platform, and stick to that platform (iphone, mac, windows, etc.) don't switch UNTIL he knows enough about that platform that he can pump out programs.
GO TO A USERS GROUP MEETING WITH
HIM!!!! (eg cocoaheads) it'll get him
excited about that platform.
When you teach him DO NOT USE THE
INTERNET!!!! Use books.
When things get hard, help him figure it out, don't leave him in the dust
IMPORTANT! Create a new user account on the computer he uses, this is your "development account" on the desktop (if you're using windows) remove all the icons EXCEPT: my computer, the IDE, a folder that will contain all the projects, and an image editor (photoshop, gimp, etc.). On a mac just leave these in the dock: Finder, xcode, IB, and an image editor. On this account BLOCK ALL INTERNET ACCESS
Do "contests" with him. Come up with an application idea, it can be something simple, like a calculator. Just make sure you can easily do it. When you do it with him make sure he's using the "developer" account that I mentioned above, and you use a different computer. Chances are it'll be too hard for him and he'll steam off in a pissy mood, THAT'S OK!!! Once he cools down show him your finished app and go through the source code with him, line by line. He'll pick up little "tricks" that you used, if he starts to ignore you make something up, don't keep on going, stop, say something to him, and continue. After seeing this he SHOULD realize that he doesn't know everything and be more prepared to learn.
DON'T FORCE HIM TO SAY HE DOESN'T KNOW EVERYTHING, HE'LL REALIZE IT SOON OR LATER (and won't admit it)
Give hints you want him to learn a specific language, go to your local bookstore and pick a book out about that language/platform and first YOU USE the book (optional, you can fake it if you want, or just give it to him), then when you're all done put the book somewhere where he'll see it, if you want to put a note on the book saying "here you go!" but you don't have to. Eventually he'll look at it, it probably won't be right away, but he'll look at it.
IT TAKES TIME, BE PATIENT.
Oh yea, a biggy:
Ask them lots of questions. Get them to explain their designs, their modelling and their implementation.
Then start picking apart the explanations. It may not sound pleasant, but it might be one of the few ways to get them really thinking about their designs and approaches.
Hopefully they'll realise that there is a lot more to programming than "just making it work".
Lastly, give whatever they build the "manual tester" treatment and start breaking their applications by doing things in a way that "real users would never do" (i.e. things they haven't considered).
Give them a good book to read. I had this problem with a co-worker and it was very hard to convince him with the basic concepts behind things like encapsulation and so. I threw at him a good book (that matches his level being experienced in the field not in programming) and it was miraculous how he changed his mind about many aspects of his work. Try books that serve as moral advisers for languages or general practice like "Code Craft" or "55 Effective C++" or "The Productive Programmer" and so on ..
I'd try moving away from the tools/libraries and tackling on more theoretical topis, such as OO design, algorithms, etc.
The only thing that may help her is time and experience.
My initial answer is to always let them fail -- agreeing with the current solution. Even after I was made aware of my failures and my ridiculous software designs, I took it as a personal failure and not one of lack of experience or knowledge. Furthermore, it doesn't really help if you need to teach someone.
What helped me to gain perspective is work in the Enterprise consulting field. Looking at the APIs and designs of professional (and expensive) projects taught me a lot about where I was, and how far I had to go. I saw how much more complex these things are, and how people are made to work with them. It shocked me out of my bravado and made me listen and study.
Don't let them fail by giving them something difficult. That leads to frustration which is not a fertile ground for a teacher/student relationship.
Give them a simple problem, but strive for elegance and clarity in the code. If you have multiple students, try making it into a little contest: Whoever can come up with the solution in fewest lines of code / fewest operations / fewest bugs.
Don't talk tech at first, judge code purely on its aesthetic merits.
And, yes, disable the internet. Or, better yet, switch off the computers. Let them do the coding on paper/whitebooard/blackboard/origami/spaghetti.
A teacher really cannot "teach". What happens is that the pupil learns, or learns not. Teacher's job is to create suitable conditions so that it's easier to learn effectively.
Give him more challenging tasks so that bad designs simply won't work. It's possible to solve easy problems with bad designs, but with challenging enough problems it becomes more difficult. Maybe he then will learn to appreciate better designs.
Nothing sucks more, especially from a teenager's point of view, than having to listen "don't to that way, do this way, even though your way works for now, just believe me.." kind of preaching. Things have to be experienced to be understood.
I think we all started out as the invulnerable teenage programmer who knows everything that there is to know about programming and especially doesn't know when they're attacking the impossible. It takes a while to work out that the problem usually isn't the tools but sitting in front of the keyboard.
Realising that good practise is something that's useful to be adhered to comes wiht experience and that's usually best gained with trial, error and failures...
I'm not in the "destruct their beleave" thing, i think you could make an sample project with some mistyrious bugs or exeption that you've put in, and has an exercice or practice they have to debug it.
You learn alot by debuging code and they wont find the solution on the internet :) beside that case happens all the time at work, some tools is jamed and the programmer isn't here so you end up debuging someone elses code...
Let them find out the hard way when they choose to not follow direction and attempt to do it their own way.
The greatest thing is to just keep at it. Eventually they will learn that what you are showing them is the best way and eventually they will start listening.
Good question by the way!
Competition: have them try and solve a problem with some criterion like "fewest lines of code", or "fastest runtime". Then show them how well a more experienced programmer can do it. If you can't find any local programmers, try websites like http://www.topcoder.com/
Elaboration: before entering university or a workplace, many smart teenagers have rarely had the opportunity to meet someone smarter than themselves, and even more rarely someone who knows more about computers. Depending on their social or family background, they may only know a couple of dozen people, and the chances are they have got used to being the best or only programmer out of that set of people. Realising that there are other, better programmers out there can be hugely beneficial by giving them something to aspire to.
This makes me immediately think of the empty cup story of Zen Buddhism:
Nan-in, a Japanese master, received a university professor who came to inquire about Zen.
Nan-in served tea. He poured his visitor's cup full, and then kept on pouring.
The professor watched the overflow until he no longer could restrain himself. "It is overfull. No more will go in!"
"Like this cup," Nan-in said, "you are full of your own opinions and speculations. How can I show you Zen unless you first empty your cup?"
-Zen Flesh, Zen Bones
Ask your student to bring an empty cup and serve him tea...
Regarding bad designs, have the student perform a code review. Write a solution in the student's style and another with a good design. Hopefully that without an investment in the code, the student's ego won't interfere with criticism. Of course, if the student doesn't understand enough to see why one approach is better than another...
While this isn't a panacea, it might be a useful pedagogical tool.
Don't worry about it, this guy will probably be a manager in a few years time.
When he starts looking for source to copypaste from the Internet, tell him that he is already proficient with this programming technique; there is little point in further exercising what he is greatly capable of. The skills which need attention and exercising are those which are lacked, so today, we're going to write programs with the Internet disabled. He may argue, that this is pointless, as the copy-n-paste methodology is the superior; well, it doesn't matter if it is, because he has to know the "inferior" solutions as well.
Likewise, if the way he partitions business logic into modules and subprograms is mediocre but he argues it is superb, you may tell him, that he has perfected the skill of writing all of the application in one main function with seven levels of nested if
s. Thus, no point in pursuing education of that skill. Time to learn another solution for the sake of variety, let's say, how about learning about restructuring the classes and methods in a way which allows all methods to have at most one indentation level and no use of else
branches (through, for example, proper use of inheritance).
Just make the learning fun and all the rest will follow ! Amazingly Scala might be the easiest language if you try Kojo [1] Examples, puzzles, help and FUN - all included in a simple installer.
[1] http://www.kogics.net/sf%3akojoHelp them discover by themselves the weaknesses of their code.
It depends on their weaknesses, but for instance, if they were not sanitizing user input, you can ask them to work out how they would crack their own code. And if they are so full of it, make a bet with them, win it and make them pay for it.
If the code is long winded, ask them how they would do the same in 5 lines of code. And when they say it can't be done, do it.
If they have a design set in stone, add one requirement that will force them to redo the whole darn thing.
...
The whole point is that they have to find out for themselves that they do have a problem. Until they know they have a problem, you have little chance to get them actually learn.
I would have her implement a binary search algorithm. It is fundamental, looks easy, and it is surprisingly tricky to get right. Even "Programming Pearls" had a bug in the implementation.
I think that I would start with Donald E. Knuth series and get them to work through them.
I'm assuming you've tried the "talking it through with them" route and not getting much feed back. So...
Take just one of their files that they are very happy with and ask them to wheel to one side then start hacking it up how you'd do it. Its easy to write bad code and hard to write good code. Talk as you do stuff, don't ask for an opinion this time, you are showing the way rather than getting them to think about it. They are clearly dead sure their way is best so no point asking this time around. Make it neat, make it clear, commented, well defended (try catches that are actually needed and do stuff if appropriate), declare all your variables that sort of stuff. Basically show them how its really done!
With luck you'll end up quietly humbling them into realising that maybe they are not such a hotshot and they have a long way to go. If not leave them to Google and go find another student :)
While I would argue they shouldn't act that way, perhaps they are a "hacker" and not a programmer like you. Maybe it's a personality clash.
There is a programmer that I work with that can simply glance at code, intuit what it does, and modify it almost instantly; he can hack kernel modules all day and they actually work when he is done. Whereas I would need to spend time investigating the structure of the code, he can pick it up instantly. He does have a bit more experience than I do, is terribly cocky and somewhat arrogant and a total hotshot, but he has programming skills and knows what he's doing. Doesn't mean he doesn't get into trouble or everything he does is right, but you're pupil might be better than you, as humbling/aggravating that may be.
Without meeting the pupil, I can't say for sure. If I'm wrong, I recommend pondering all of the rest of the answers and ignoring mine. :)
Horse; water; think...
A true programming god knows that all software has it's design and performance limitations at any implementation level.
A true programming god sees flaws in their own designs and understands how the customer wants it, not just how they think it would be better.
Personally, such egos are not worth dealing with. The truly skilled developers are always open, always asking, always open to being wrong (and learning), and always curious about different ways to do things.
notepad and notepad alone...that and the command line
Patience. Sounds like your student lacks patience... so teach him or her patience by example.
I will give them a task where you know they will mess up. Maybe before you give them the task tell them what they MUST use to get the task working 100%. The when you see that they cant do the task tell them "SEE, i told you guys what you must use and still you dont LISTEN to me!!!!" Then show them how its done and tell them to pay attention from NOW ON!!
As soon as projects exceed a certain size everybody feels that some discipline is needed to really keep being productive, which correlates at least a bit with having fun programming ;-)
So I would try to let them write stuff that can be modified and extended. This forces them to face their own crap again and again. This can then lead to introduction of refactoring, code quality, unit testing and so on.
In university I participated in a XP-style programming course. We were handed over a running traffic simulation. Then the product owner appeared and wanted us to fix certain issues and change some of the behavior. In order to simulate reality as good as possible he changed his opinions every week.
Maybe a running prototype might be a good starting point in your case, too.
Give her a closed book exam, no books, no phone, no Internet access. Something simple, code written in notepad, compiled at the command line. Let her fail, see her make excuses when she has nothing to blame except herself.
Also, find something external to IT that she's interested in Sports, Musicians, fictional characters, and teach using their example
e.g. Do you think David Beckham would be proud if he played a game the way you did that assignment? or Spiderman has natural ability but even he has to study . . .
Bad examples, but you see where I'm going
Don't let them copy-paste code. I've seen far too many developers depend on copy-pasting of other people's code even though they don't understand how or why it works. It becomes a very bad habit.
I would also be a little hardcore with them too. Notepad and the command-line. That's what I used while learning Java, and I turned out all right. Ok, bad example...