14 ms·
How to help a programming student get unstuck
- jleyank 5y agoHell, it’s Saturday and I feel talkative. If somebody is stuck, several steps come to mind: Do they understand the problem(s) they’re being asked to solve? Toy or otherwise, this strikes me as a necessary condition. Can they express their solution in discrete steps? Software is brilliantly stupid, and must be told in detail what to do. This step should be independent of language, and is more of a logic exercise. Can they express their “discrete steps” in the language(s) that are required. This is an engineering problem that can be solved with references, practice, etc. Perhaps we can think of the steps stage as writing in ones native language and the implementation stage as writing in a nonnative tongue. Debugging. This is a generally applicable skill for any multi step problem. In the case of software there is language and hardware issues in addition to logic and understanding the problem space that usually make things worse. But I have found that if these two aspects can be separated things go much better than blurring the two. If needed, tuning can be seen as both a (re)design or additional debugging step which is outside the initial discussion. But aside from design, one should separate making something work vs. work fast unless they have a very good grasp of their problem and solution. Much of what we do is separable, as things like abstractions are so useful. If a student is struggling, the mentor can help them determine which step they are hung up on and the kind of nudging that would be most helpful. People who can create sound, stepwise solutions are useful - they can apply this to pretty much any environment. Knowing the nooks and crannies of a language without good logic/design merely creates hard to maintain code.
- throwaway2331 5y agoA lot of this is mirrored in "Code Complete" -- especially the part about expressing a solution. Most of it was self-evident information you would naturally pick up, as you made your way through your "programming journey," but the parts about planning were the ones I took copious notes on (and integrated into my own craft). If you don't know -- exactly -- what problem you're solving, then you're either gonna sit there dumbfounded, unsure of where to go from there, or you'll frenetically start brute-forcing the problem, trying -- sloppily -- everything you can think of. It never really occurred to me before I read that book that writing the actual software shouldn't be just about 95% of the process. ~40% should be planning: understanding the problem, understanding the tools you have available, and building out a rough outline of how everything's going to work (preferably in pseudocode comments you can then convert into actual code). Or that you could write code without painstakingly testing every few lines to make sure you "did it right" a la code cowboy. Wasted a lot of time, and spent too many nights up on caffeine trying to force my way through a problem (albeit it usually worked, with the cost of having to rewrite everything ;).
- jleyank 5y agoYup. That was on of the books I read, along with the pragmatic programmer and other most technical, Unix-y things. People always said I was a step by step kind of guy and that seemed to map well to programming/hacking. Although it helped seeing external reinforcement to solve things ina logical manner without skipping steps.
- andai 5y ago> you could write code without painstakingly testing every few lines to make sure you "did it right" This technique would eliminate many of the bugs I create (mostly careless mistakes), if I could be bothered to do it, so I'm surprised to see it presented in a negative light.
- pxc 5y agoIt's tedious, and tedium is unpleasant. What's surprising about that?
- andai 5y agoYes, which is why I often don't do it, and only discover my mistakes far later in the process.
- throwaway2331 5y agoHow careless is careless? If they're basic typos/syntax, having something like Rust's "cargo watch" running in a terminal to rebuild files that have changed can be useful. Usually, when I'm done writing a big abstraction, I'll do a quick proof-read, and then go maximize that terminal to see what the compiler found. A heavy-weight IDE would also serve that purpose. But, I personally cannot stand all the distractions they introduce (drop-downs, red lines, auto-complete shadows, etc.), so I stick with emacs, and just run my unit tests after I'm done writing a big logical block. If they're matters of logic/constructs/and such: I've found reasoning about in my head the piece I'm writing, first -- and understanding exactly what it's going to do and how it's going to do it, before I even start programming -- to be useful in preventing bad code. The main problem I've had with "code a few lines, test, code a few more lines, test" is that it always pigeon-holed me into thinking tactically, rather than strategically. "OK, I gotta write a class that handles X, Y, Z. How's that gonna happen? I don't know. The compiler is a fickle mistress, so I have to focus on getting it to work at all first, before I even think about the grand scheme of things." When, I could've just written the whole piece in one go, and then dealt with my lexical errors. As long as the logical expressions all make sense, and I understand what my code should be doing, I can make small adjustments here and there. Dealing with the interpreter/compiler is a distraction, that's best left to a dedicated chunk of time to go over all my errors -- so I can learn from them, and not just give them a quick patch, and move on to the next challenge, without really reflecting on why I had errors.
- hdctambien 5y agoThis is pretty much how I taught my High School Computer Science classes. The biggest step for me was to never touch the student keyboards. And then I basically only answered their questions with more questions. Sometimes I would hear students grumble "He never answers my questions...", But in the long run, they would start asking themselves the same questions they knew I would ask (what did you expect it to do?, what did it do?, Why did it do that?)... Then they would usually solve their problem without me! Or, when they called me over they would start with "I tried a, b, and c" and got results x, y, and z" which is a way better start to a learning experience for everyone than the old "it doesn't work, fix it, please"
- andi999 5y agoI still think there are also questions which are best answered straight, like 'how many bytes does a float have? Do arrays start with 0 or 1 in this language? Is printf of %s with null argument, undefined behaviour, implementation defined or actually standard conforming'.
- Siira 5y agoFinding the answer in the docs is itself a skill, so even these simple questions might best be not answered directly.
- popcube 5y agoso, just touch the keyboard and display how do you resolve this problem?
- MathYouF 5y agoThose kind of questions are a great opportunity to show a student where to find documentation and how to read it, because that is a daily journey that will never end.
- rablackburn 5y agoYou've been down-voted, but you're absolutely correct in some situations. Sure, answering those questions with "this is a great opportunity to learn how to read the documentation" is the "right" response. But I think we've all experienced the frustration of trying to write something in a language we don't use every day, and 'wasting' our time looking up simple things ("okay, what's the exact syntax of a for-loop in this language again?") that just adds friction when we're trying to solve a problem. There's a reason programmers complain so much about being interrupted. Part of being a good teacher is being able to make those points of friction disappear and enable your students to "get it" and experience the joy of solving a problem. Don't let perfect be the enemy of good. How many kids would play football/soccer if you were only allowed to play a match with regulation numbers of players on each side, and stopping play every time someone didn't have 'perfect' form?
- exdsq 5y agoHTDP has a nice 7-step process to designing programs and suggests teachers ask the student to point to which step they’re stuck on, to help formalize it a little bit in their minds. I quite like it.
- marginalia_nu 5y agoIs there a general process for solving problems? These last 25 or so years I've been programming I've mostly just been thinking about the problem until I have a solution. Sometimes I go for a walk but that seems pretty hit-and-miss. My process seems to boil down to not realizing I was supposed to get frustrated and give up.
- Jtsummers 5y agoHow to Solve It by Pólya is about math, but can be used more broadly. https://en.wikipedia.org/wiki/How_to_Solve_It https://en.wikipedia.org/wiki/How_to_Solve_It
- marginalia_nu 5y agoIf it's just a matter of following this algorithm, why do we still have unsolved problems?
- deleted 5y ago[deleted]
- Jtsummers 5y agoI don't understand your question, I didn't say it was just a matter of following this algorithm or process described in the book. You also have to possess the base knowledge that feeds into it, which is described in the book in a mathematical context. Even then, it's a set of heuristics and guidelines. Neither the book nor my comment claim it to be truly universal.
- unsung 5y agoI would strongly second the GP's recommendation. The book mentioned is aimed at math teachers up to an undergraduate level, but generalizes quite naturally. The idea is that one may induce a path to solution in a student by stripping a problem down to it's knowns, unknowns, and constraints so that it may be comprehensible, then connecting these elements back together by asking pointed questions that could have conceivably occurred to the student. He gives plenty of practical examples of how one may dial the complexity of these questions up and down, how to relate by analogy, and plenty of other techniques for approaching problem solving generally all in a flimsy paperback that can be finished in two evenings in a weekend. The most impressive part, to me, is that nearly every example is both illustrative enough to be a word-for-word guidebook for math tutors, and accessible enough for even a middle school student studying Euclid to understand in it's entirety.
- cyb_ 5y agoNote to author: I couldn't find a RSS/Atom feed for your blog. Would be nice to have one so those of us who avoid Twitter can still follow you.
- Ozzie_osman 5y ago> The same principle applies when learning how to code. Once you understand how it works, it’s extreamly challenging to imagine not understanding it. There's a formal word for this, the Curse of Knowledge. https://en.m.wikipedia.org/wiki/Curse_of_knowledge https://en.m.wikipedia.org/wiki/Curse_of_knowledge
- MeinBlutIstBlau 5y agoMy teacher in both my Architectures and AI courses had this bad. Still to this day have no idea how any ML works in python or what the purpose of keras is or how it does any processing. Or why certain 1's and 0's churned out of a breadboard. All I can tell you is that I learned nothing and just paid to get them done.
- pedrosorio 5y ago> just paid to get them done Paid whom to get what done?
- SilasX 5y agoWeird, I seem to mostly not have that problem, and vividly remember the confusions and mysteries. I’m constantly jumping in to improve others’ explanations that assume too much. I’ve started calling myself “the translator”. Maybe I should take some teaching role?
- yawnr 5y agoI’m kind of the same way and have always really enjoyed tutoring.
- rablackburn 5y agoAll the best teachers I've worked with have this skill. I use the "translator" analogy as well. Though I've found it's not so much "remembering" the confusion and mysteries from your own past, but paying very close attention to the student(s) so you notice as soon as there's some divergence in their mental model from what you're trying to relate. Stop, slow down, address the assumptions you didn't even realise you were making, and it's amazing how much complexity and knowledge you can seemingly transfer into someone else's brain. Of course they'll forget 2/3 of it over night, but it's easier next time, and once they've "gotten" it (and the corresponding endorphins) once they've got way more motivation to keep going.
- lordnacho 5y ago> Once you understand how it works, it’s extreamly challenging to imagine not understanding it. This can be problematic when teaching because it creates a gap between teacher and student. Even the most empathetic teachers can’t quite imagine themselves in a student’s shoes. This reminded me of my old engineering tutorials. Where I went to uni you have these 2/3-on-1 sessions with a tutor to go through a weekly sheet of questions across subjects. After a short time, we came to the conclusion that the more decorated the tutor, the less good they were at teaching. I had people spanning from just-started PhD students to professors who were members of various academies. The more letters they had after their names, the harder it got to pick up anything from them. The professors had a couple of things going against them. First, they were no longer warm hands. Too long since they themselves had to analyze transistor circuits. They might know something about how the state of the art is done on an industry grade computer, but no way they could go back to hand drawings of toy systems. They also probably wouldn't know quite how to operate that state-of-the-art system themselves, but trust a postdoc to do it. Second, they were busy. Really really busy, mostly with the business of running a lab. A lot of not-analyzing undergrad level transistor circuits. A lot of grant proposals. So when you got one of these highly decorated people slumming it with the undergrads, they just wouldn't know what it is you didn't understand. The best were people who'd just done the course not long before you, and understood what to say to trigger you to think the right way. They'd been down the same dead ends, the same oddly worded questions. This is why I'm no longer so interested in my kids having a lot of professor time. You often hear people complaining their expensive degrees are taught by TAs, but in the end the professor guy would not do much better for the kid.
- jiggawatts 5y agoSomething that shocked me was that when I was trying to teach a scripting language to some non-programmer sysadmin types, they kept getting stuck on what I thought of as minutiae. Things like the difference between single-quoted and double-quoted strings. Special character escapes. Etc... One person was confused as to why I kept using different kinds of brackets -- round, square, and squiggly. To me, these basic idioms are so ingrained, that I simply didn't even think to explain them. Of course the squiggly brackets create a nested scope! What's a scope? Uh... that isolates variable names so they don't clash. Why can I refer to the same variables across those squiggly brackets but not those ones? Well... umm...
- dimal 5y ago> If you find this useful, let me know, and I’ll write another one about helping students who are pair programming. Just want to say, I found this very useful! This is a problem I’ve been trying to solve recently, with only some limited success. (I also want to second the other comment about providing an RSS feed.)
- coverband 5y agoThese suggestions are pretty useful, and most would apply in other teaching domains as well. Thanks for sharing.
- MeinBlutIstBlau 5y agoI think what a lot of instructors fail at is they don't give students a working example of how something works. Sure you're not really going to learn, but what's the point of me having a half-assed assignment that isn't useful for me referencing a couple years down the road? The simple best way to program is exposure, and a lot of it. Not these boring petty tasks we do. They're logic puzzles and not much else. Showing someone how everything works from start to finish in creating a website with a specified framework helps tremendously. Or how to work with low level C programming making practical applications. For myself personally I developed a method of TODO's with some of what my lead taught me mixed in. My lead doesn't like redundant code, but said "working code is better than no code." So what I did is made one type of TODO that means "this code sucks or should very much be revised." Another one I have is "talk to my lead." With those, I don't address it with my lead unless we already have a meeting and it'll be quick, or I compound enough of them to devote an actual meeting regarding them. Overall it has helped me stay organized, and it keeps me from annoying my lead. So what I'd add is, a system for people to make their own notetaking is vital when learning. If you don't have that or arent willing to take the initiative to do that, personally I think coding is not for you.
- rablackburn 5y agoI love that taxonomy of TODOs, I'm stealing that ;) > I think what a lot of instructors fail at is they don't give students a working example of how something works. Sure you're not really going to learn, but what's the point of me having a half-assed assignment that isn't useful for me referencing a couple years down the road? Like everything else in life it's a balancing act (or a chicken and egg problem). In a university/college context in particular it's not about being practical, it's about learning the (hopefully up-to-date) theory. There are concepts, classes of problems, and mental tools in computer science that are extremely valuable, but if you don't teach them explicitly you have everyone reinventing the wheel, and worse, doing it without a common vocabulary. But as a student you can learn/memorise some concept (let's say recursion as an example), but you never really 'get it' until you've struggled with a real-world problem and realised that recursion solves it elegantly. Sometimes the way we teach reminds me of hypnopaedia/sleep-teaching in Brave New World: ``` A small boy, asleep on his right side, the right arm stuck out, the right hand hanging limply over the edge of the bed. Through a round grating in the side of a box a voice speaks softly. 'The Nile is the longest river in Africa and the second in the length of all rivers of the globe. Although falling short of the length...' At breakfast the next morning, 'Tommy,' someone says, 'do you know which is the longest river in Africa?' A shaking of the head. 'But don't you remember something that begins: 'The Nile is the...' 'The-Nile-is-the-longest-river-in-Africa-and-the-second-in-length-of-all-the-rivers-of-the-globe...' The words come rushing out. 'Although-falling-short-of...' 'Well now, which is the longest river in Africa?' The eyes are blank. 'I don't know.' ``` The takeaway (in the book at least) is that rote-learning like that has no value because its not conscious knowledge (but it's great for _moral_ lessons, like 'Ending is better than mending'). But I've lost count of the times where I've come up against a problem that niggles at the mind and realised I learned to solve it years ago at university, and it all falls into place. If nothing else, you know what to google for. So I've come around full circle on how theory-heavy universities are (if we don't teach theory at university, where would we teach it?), but agree that there's a huge benefit to student experience by pairing it with exposure to full systems. The older I get the more I find myself regretting (/resenting) how we've off-loaded so much job training to universities. You know how students can get exposed to real-world systems and learn real-world lessons? By having them recruited by real-world companies who invest in their development. Seems like a CS degree would be most useful after you've been working with real-world code for ~5 years. Perhaps we need to split out most of the content of the current undergrad degrees into a CS equivalent of an MBA? Let the undergrads focus on practicality (ie, making the MIT missing semester the core experience), then come back in a few years to learn all the "correct terms" for the problems you've been coming across and learn the best-practice/optimal approaches.
- rpmisms 5y agoEvery engineering manager who works with juniors should read this.
- cturtle 5y agoI do a lot of one-on-one programming teaching, and this really hit home with how I approach teaching. I especially liked the following: > You’re not a machine. Every teacher and every student is different. The art of teaching is finding a technique that works for the situation at hand. Just knowing something (like programming) isn't enough to be a good teacher. It really is an art that takes time and caring to develop. Thanks to the author for putting my thoughts into words so well!
- ChuckMcM 5y agoThis is all solid advice. I also note that new managers of programmers should read it as well. Managers feel the weight of the responsibility for the project and when one of their engineers is stuck it puts the schedule at risk. For new managers especially, their instinct is to just tell the engineer how to fix the problem. That solves the near term schedule risk but does nothing to prevent recurrence. When I'm managing software engineers I try to make it really really clear that getting stuck is a "known" thing and getting unstuck is a "learned" thing. So to come to me early when they are stuck so we can practice ways to get unstuck. If they wait too long to ask for help, it is a much bigger problem. (and when I am programming for someone I can be just as bad at not asking for help soon enough) for one of my employees who was an ex-marine and really really didn't like asking for help, I got him to think about it as asking someone in their unit to provide covering fire, that is "help" and essential to achieve the objective. They understood that reference really well and we got along great after that. My point being that everyone is a teacher to somebody, so when an article that frames the teaching as instructor to student, don't make the mistake of thinking it doesn't apply to you. There are things to learn in there.
- kodah 5y agoThis may be good advice for programmers that learned in an academic setting, but as someone that taught themselves this would drive me nuts. I still struggle with abstract problem solving in problems that I haven't solved before. A lot of algorithm based interviews I'll totally flunk the first time around. Depending on the interviewers behavior I've either bailed out from there or tried to learn something. More helpful is backing up and framing the problem to be less abstract. When learning to code, we're learning new ways to represent things that we likely already intuitively know. In that way, you're teaching expression. The two are taught very differently, imo.
- deleted 5y ago[deleted]
- taldridge 5y agoAs someone who is also largely self taught in cs terms, it's actually very amazing to me how even very abstract ideas which seem to be very far away from a "solution" to a "problem" often fall into place very nicely. For example consider a unification algorithm (e.g. https://reasoning.page/29021/unification-sort-of-in-rust https://reasoning.page/29021/unification-sort-of-in-rust which is an explanation of it that I wrote). The individual parts of it do not seem that spectacular, and also seem quite abstract. It is so simple (in my mind) that it could not possibly be correct. However, there is an emergent property when the interactions between the different parts of the program are taken together.
- zanethomas 5y agoAll good advice. But... After teaching fullstack at a well-known university for a year and tutoring many students I feel that about 90% of them will never be competent entry-level programmers. There will be much disappointment ahead for the thousands (and thousands) of people being steered towards coding instead of to some more appropriate job (of which, I recognize, many have left the country).
- finnh 5y ago> about 90% of them will never be competent entry-level programmers. What's crazy is that I feel the majority of people I interview/phone screen would not be a competent entry-level programmer, and they've all had at least 10 years in industry.
- zanethomas 5y agothat's even crazier, how could they be in the industry that long?
- Jtsummers 5y agoIME, they get into companies that don't fire people (or government jobs) but rather move people to other projects, or they bounce before they're discovered to be incompetent. Companies often won't make stronger statements than "X worked for us on these dates" (the company, individual recommendations may be different). Barring legal trouble you may have caused, if the issue of departure is primarily performance, they don't want you suing them for making unprovable negative statements about you.
- zanethomas 5y agoThat's a pity inasmuch as it punishes those who have done well on a job. I would really appreciate it if when checking references a past employer would feel comfortable saying good things about my work.
- 5y ago
- Plexpert 5y agoIt was a good information. I hope we will get daily one post like this. You are good writer. Thanks for share it.
- zekenie 5y agoI’ll try :) check out today’s