Ask HN: How to Teach Coding?
I finally did it and I get my first Trainee.
I already teached coding to internships for a few weeks. But this time I have three years to share my knowledge and grow with him.
I already checked methods and stuff online like pair programming, visualization of data flows ect.
But what I would love to know is, what has worked for you guys on both sides. Sharing knowledge and get trained.
I want to be the best mentor I can be and I want to proof that this is a thing I can do good and continue doing it the next years of my career.
So, what helped you to train others or receiving knowledge?
125 comments
[ 2.6 ms ] story [ 183 ms ] threadJust being there to answer questions or help when they have issues can be a tremendous assist since it means they're rarely left frustrated by being unable to move forward on their own.
I am glad that i will start with only one Person here and i can focus on how he learns :)
Help them grow by venturing into unknown terrain when the time is right, show them the path when they are lost. Give feedback when work is done to help them stay on the path.
Basic structure is: -nightly readings and videos on a new concept -a homework on the readings -a quiz on the material
Next day: -a half day lecture on the new material from the previous night. -a half day of paired project work on the material.
I think the reason why it’s a pretty effective format is because it forces you to struggle on your own the night (homework and quiz force you to do something and not just read along) before some new concept is taught, meaning you’re not going into a lecture completely cold. Then in the lecture you can solidify your understanding of the material, ask questions, follow along demos, and then really have things sink in with the longer, more difficult project work that same day.
But that sounds reasonable and i just made a note about this for my plannings.
Thanks for your insights.
If you don't keep practicing, you'll never see the value in what you're learning and you'll quickly get fed up. Additionally you'll start encountering road blocks during your practice and you'll start becoming eager to learn if there's a better way to do things.
Small goals make learning more enjoyable. If you set out to make a MMO online 3D game from the start, you'll never do it. But if you make yourself a to-do list app, word/numbers/guessing games, a note-taking app, you'll enjoy these small wins and more importantly will be eager to improve them.
1. reading algorithm flows 2. following changes in variables for C code 3. drawing their own algorithms 4. implementing those in C.
repeat for a whole semester.
in the end, those who are really interested will pick up tooling and go ahead by themselves.
1/ there's such an astronomical disparity between students 2/ where it's more of a requirement to be an autodidact.
All the good devs i know just pick up books and start reading. If you look professional devs out there, if they all taught themselves how to code, then one must wonder whether you can even produce a good coder by teaching them directly.
Instead, pointing them in the right direction on their learning path at the right time is probably going to be hugely beneficial.
I know for myself i wish i'd spent more time learning than building things. It's been useful too building, however my ratio was off by quite a bit.
BUT not all people like or are comfortable with that. For example, if you've started learning programming in a rough environment, I imagine it could feel difficult or even scary. So making them feel more secure through pair programming or something of the sorts could help them ease that out.
Plus there's the benefit of efficiency - sure, they might need to learn Java or C or Python by themselves (which you could state to them), but learning to navigate through the internals of a large codebase can be quite challenging and not necessarily useful right away. Sure, you might need to face the more hairy bits of the repo at some point, but figuring everything out right off is probably not ideal - or, not always.
And another issue is process - different companies (even different teams within the same company) have different processes - e.g. pick up ticket, read description and possibly discuss with lead/QA about what the acceptance criteria is, write code, open PR, get reviews, get QA review, check code coverage and static analysis.... you get the idea
Don't make assumptions. Observe and test them frequently. How you should teach them will be driven by this, and nothing else.
Btw, I ran a tutoring company for 8 years with over 6k tutors.
I will follow your suggestion.
Well, over 6k tutors sounds like you found ways to guide people successfully through the process.
My Question about this is, was peer-programming a standard tool, or just plain code-reviews?
This is the main benefit of 1-1 teaching. In a class room setting you can, and perhaps should use "recommended techniques", but 1-1, just do what works for your mentee. Anything you read about benefits of peer-programming or code-reviews is just an idea, which you should be able to verify very quickly with your own student. This trumps everything you might read.
You might find one method works better all the time, or you might find one works better in some situations.
If I may elaborate: What I believe you are teaching your student, first and foremost, is the ability to observe themselves.
In fact, you may never need to "teach" them anything, if they begin to understand the difference between good and bad, better and worse, themselves, they are well on the route to becoming an autodidact. You do this through testing - not just formal tests, but simple questions too. Your aim is to develop the questioning ability in the student themselves.
I like to think of these analogies: A painter's ability to see is the foundation for their ability to paint. A chef's ability to taste is the foundation for their ability to cook. Both the eye and the palate can be trained.
In my experience, what helped me the most when starting to learn how to code was having a motivating problem that I wanted to solve. Why do I care what a for-loop is if I can't see how it is even helpful? Many tutorials have examples when teaching, but I believe that the problem should come first, and act as the glue between the basic ideas that will be introduced. Then, the mentor's most important role is to guide the student through best practices, such as style and performance.
Yeah, real world problems are what my favorite way to teach particular ways of building things. No one wants to build the 7th calculator.
Thanks for your Feedback!
Someone said that finding good teachers is difficult, and that's true from my experience; but it 's a Sunday walk in the park compared to finding good students.
Well after reading your message, i just hope to stick in the "good teacher" category soon.
My feelings say i found a good student who wants to learn, so i have a rock solid base here.
1) Information provider - search for suitable materials. For example, if the student finds the materials not engaging, it would be your role to find different material that suits the needs of the student better
2) Problem provider - this is extremely important. It is difficult, for example, to care about loops when all the textbooks show only that--loops in isolation. Your role is to construct or find problems that the student can solve with their new knowledge. Generally, the challenges/issues should be one level above the student's knowledge, so that it pushes them forward.
3) Guidance role - it is your job to analyze the students' motivation behind learning how to code, and provide suitable path. E.g. if one wants to become a web designer, it might not be the most suitable to start with assembler. You should also course correct, e.g. when you see a web designer to be struggling with data structures, it is absolutely appropriate to make a detour into some CS territory with data structure classes.
But, of course, most of the learning does the student him or herself. You can't teach anyone anything ever. You can just be there for the student, to help them and guide them.
My 2c as a self-taught developer.
Provide help when they need it (critically, also teach them to recognize when they need help, most novices are pretty bad at this), but don't over support (if the student isn't reaching, they probably aren't learning).
Pair programming can also be a great tool in general for learning (with you playing the role of metacognition [1] for the trainee, which again is notoriously difficult for all novices - even experts in other fields have a hard time being metacognitive in new ones). The key there is again: don't prevent all of your trainee's mistakes as they happen, but try to guide them toward noticing them and repairing them before they get too stuck. The other part of teaching that's a learned skill is determining how much struggle / wheel-spinning is productive for your particular student.
All of this is with the caveat that YMMV - people learn best in different ways, but productive struggle and real tasks are really good starting points for most (and way better than lecturing).
https://easyprog.online
If you have a trainee in a work context, where they're expected to soon be productive in the particular tools your company uses... get them started with those tools, point them to good instructional material, give them appropriate work assignments, and give them lots of mentoring (talk with them at beginning/milestones/end of each assignment, walk them through things they need to know that aren't in the materials, find the right balance of being available for questions but also getting them comfortable finding answers, etc.), and also get them started familiarizing with your organization's stuff and examples of good practices (e.g., reading select internal docs/code, monitoring Git commits, etc.). You'll also notice things they're doing or not doing, that you didn't think to mention before, so you can give tips as you see them. And it's important to be encouraging, not discouraging, even if you're encouraging them to work harder/smarter at something.
At my last long-term consulting arrangement, I helped hire and onboard a developer who was a new college grad (who'd had military work experience, but in a different STEM area). Because the team was growing, we needed some lightweight process tweaks, and I decided to involve him as a peer in determining those tweaks. (Secondarily, I didn't know what his military experience had been like, and this new role required him to be comfortable speaking up.) On a couple of occasions, it would've been easier for me, had I declared myself benevolent dictator on the decisions, but I think the peer treatment from the start worked out well for the process, and set a good cultural tone.
He only can learn from this.
Thank you for your feedback
I will give that book a shot!
Git is something on my earlier Todo list, I just introduced the existence of git at first and think we will investigate there more soon.
[0] https://media.ccc.de/v/35c3-9800-how_to_teach_programming_to... [1] https://htdp.org
So, I'd go for what others have already mentioned. Learn about the person, how they are, how they learn better, what are their interests.
Find something they like and enjoy, so they are motivated in learning.
Be ready and available to answer questions and adapt to their rhythm and needs.
Prepare materials and different options so they can chose their path as they go.
Facilitate them changing their mind, going back and forth, making their own mistakes.
In my case, for example, I learn by doing, and pair programing with somebody helps me a lot, but other people might prefer having a theoretical background first and will want to read a book before diving into coding.
EDIT: adding paragraphs for clarity
Can't really tell objectively how is my process going because my end goal is to be able to sit down imagine a thing a code it, not even close.
I get some concepts a lot better because I am constantly going back to the basics and start over, but still I struggle on low-level real world examples or mid-level problems from websites like codewars and etc.
Here is my advice to you. Make real world examples. What I mean by that, don't make a tutorial how to do a calculator or a weather app or something like that.
Instead, after each new concept or lesson that you make introducing something new about coding, create real life scenario examples with a minimum of 10 examples that your students needs to code. For example make them write 10 different functions that do something in different situations, and niches - business related function, pet related function, vegetables related function, cars related function, water related function and so on.
Why? It is very hard for a new person to grasp the concept of coding, most of the courses and tutorials do that - this is a function, they give you an example with function a + b that returns the sum and that's it. So when you are a complete beginner then you struggle to figure out a function that can applied in complete different situation like a function to sort a music playlist.
By proving different scenarios from the real world for your students and break it into small chunks after each new concept and lesson, it will be easier for them to understand better how you can use this skill in the real world. By making them repeat it with different examples will help them memorize it faster, and recall the solutions when they see something similar that they need to do.
Why this works in my opinion? I live in a small country and in high school I had to learn English. The teacher made us write every single new word that we were introduced to in our notebooks, like minimum of 30 times. Not only that helped to memorize the words and their right way of syntax but then you get to start using them in a more complicated sentences.
My English is far from perfect but I haven't taken any addition classes and it helped me a lot so far.
After all you are also teaching a language, with which you communicate with the computer, I think you can take a look at different disciplines and apply some really good practices to make you a better code teacher.
This of course is from my personal perspective like a super beginner that try to do that in his free time online.
Best of luck to you.
Up to this moment i learned that going with real world examples is the way to go. Since i work in a software department of a real world company and mainly code Inhouse solutions, i am sure that i can provide a lot of them.
Beeing available for Questions and Feedback and provide Learning Material and doing sessions about technology and patterns, before they are needed to solve a problem is the next thing i noted down in my plannings.
I am very thankful for all the Feedback and can't wait to get more!
The concepts of programming can be learned from the noosphere easily, the resources are there to learn but good practices are not. A teacher should pass these as well, in addition to "what is a variable" etc. stuff. And like any course, if the student doesn't actually work on the stuff on his free time it is worthless - another analogy can be a guitar course here. No matter who your teacher is, if you don't play it at home willingly... you won't be able to learn how to play guitar.
My 2 cents...
He already has some knowledge because he visited an IT focused school here in Germany and his father is a coder too.
So I don't need to explain loops, or if statements and can go a bit further in logic and processes
2. Give them a playground to fail - Offload any non-business critical tasks and let them make mistakes. No one I know ever learnt programming without making any mistakes. Immediately tell them about best practices and how to avoid such mistakes in future.
3. Show them the impact of their work - There's nothing more motivating than seeing the impact of one's work.
4. Build curiosity - Answer as many questions as you can answer. Admit when you don't know any answers and start looking it up on the web right in front of them. People pick habits by looking at their superiors.
If it's absolute beginning to programming, this video is a great way to show how difficult it is to teach a machine to do something and how clear instructions can help get things done: https://www.youtube.com/watch?v=cDA3_5982h8
[0] https://www.nytimes.com/2019/04/24/health/artificial-speech-...
Many (most?) people don't have know how to take a big problem and turn it into something they can make progress on.
You give them the lego bricks and say 'make me a windmill' and they don't have the first clue where to start. They may not even understand that programming is lego.
So, you either have to teach that first. Or, if you want to teach it later, start with a sequence of problems that have one obvious step each.
Some good approaches to attacking a problem too big to be obvious:
1. Break it into smaller and smaller pieces, then implement those pieces.
2. Bite off a small piece that you think you can do, then grow that.
3. Write down everything about it then think very hard about what are the essential characteristics of a solution.
I think even more importantly is to encourage failure, or at least reporting it. How many times have you been ecstatic that you managed to get a program to crash differently? A lot of people are terrified of failure, but people probably learn better from their mistakes. And showing them that it's ok (even encouraged) to report what their stuck on to you means that they can potentially get a quicker solution, learn from you.
Here’s an exercise (not sure where I discovered it) that I use at the community college level: https://www.youtube.com/watch?v=meSK1rn2VbA It has the same elements of analyzing a problem, breaking it into steps, and making sure they’re in the right order; but it’s set up for students to succeed.
This exercise is very effective when you put the students in groups of two or three to work on it.
The point being "I can't even tell someone how to make a sandwich without establishing the platform we're building on". If you start a python app writing in assembly or Fortran then (in general, you pedants!) it's not going to work.
If you do the same exercise with cooperative people then you don't normally emphasise the point because they do a lot that's not clearly defined, and that hides the point about defining the parameters and metrics you're working with.
I've found that learners will succeed when they are able to answer affirmatively these two questions: "can I do this?" (self-efficacy), and "do I want to?" (motivation).
The robot scenario with a handful of commands is preferable compared to the "make me a sandwich" task in both respects, because failing badly at even getting bread out of the bag (say) can destroy both self-efficacy and motivation.
Coding should probably be taught with a background of requirements that are precisely given in terms of the abstractions that are being used in the code. So that is to say, the problem itself doesn't have to be something abstract (like a number-theoretic computation); it can be connected to something in the real world. But the representational mapping from that domain to the computer should be established by the teacher, so there is no irrelevant fumbling about the requirements.
In the case of the sandwich, we should provide a procedure which somehow takes the slices of bread out of the bag. Similarly, we provide all other necessary procedures, and only those procedures are to be used. Then we eliminate questions about the detailed requirements about what those procedures themselves do, like can the bag be ripped, or does the removal have to be tidy.
A good domain for teaching coding might be game playing (cards, etc). People understand that the objects used in games are abstract, and that certain details do not matter to the game, like the exact shape of a rook in chess or its precise placement within a square. It could just be the letter "R" in an 8x8 grid of characters (with "r" being the opposite color).
Symbolic games are basically a form of mathematics that is instantiated in the real world whose abstractions people readily understand. Moreover, they have a point (to have fun), so the "why are we doing this" question is settled.
Also there's his follow up video where he solves the puzzle (https://www.youtube.com/watch?v=z5VKyKvgyRs). Another helpful video is him teaching how to go through a program by hand, using pen and paper (https://www.youtube.com/watch?v=9Ahejeuasf0)
Reminds me of a blog post I wrote a few years ago on how breaking down problems is the most important skill you can ever learn as a developer.
I had a similar example where I talked about tying your shoes. What seems so trivial can easily end up being hundreds of steps without even delving into really low level details like controlling individual muscles of a specific part of your body.
I personally teach people to code with Python. Because it's easy to get into but can grow with someone where ever they want to go. It has a strong culture of clean code and DRY, and it is fully formed with a great community.
1. Start with Learn Python the Hard Way and do it until you are frustrated.
2. When frustrated with LPTHW, move to setting up a Django website. Do the Hello World of Django.
3. I work with the person to figure out something in their life that they'd like to make a web app of and help them do a simple website with basic Django models and bootstrap (so it looks good and like the familiar face of a finished product).
4. Work with them on simple deployment patterns and looping back into LPTHW to continue rudiments.
What I'm trying to teach here is that when you're staring at a wall of infinite unknown; set yourself up for success. Taking bites out of the elephant and learning to tolerate frustration / lack of knowledge by balancing with feeding yourself success. Always try to back learning of complicated things with a process of exploring something personally relevant to you and keep a sense of play.
I try to emphasize that the feeling of unknown that they are experiencing IS the state of being a programmer, the problems just change. The scale of what you can leverage grows. But at the end of the day, the unknown is what you're exploring and if you take to the process you'll learn to be excited about that. It will still always be scary, annoying, and sometimes really fun.
Ask the student what they want to build or achieve.
Like if they want to make a game, or an app, then sit with them to code the simplest form of that, step by step, starting with the player data model (score/HP/ammo), then the HUD, and so on.
You may even write the first version all by yourself while they watch, accompanied by your live commentary.
Let them know that development is generally about sending messages/commands to things (APIs) that send messages to other things (CPU/GPU) on your behalf, so they can understand early on that coding is as much about SDKs and frameworks as it's about languages and platforms, and the ways of talking to/between them changes across APIs, so one of the most important skills is learning how to learn; to figure out how to dig through all the different ways of achieving the same result.
Tell them they can generally make things easier by putting in more intermediary messengers between themselves and the screen: Dev » Unity/Unreal/SpriteKit » C#/Swift » DirectX/OpenGL/Metal » iOS/macOS/Windows » App Store/Steam » Player
and they generally get more control by removing the middlemen, but if they change a layer in the chain they might need to relearn how to talk to all of them.
Best of luck!