I’ve asked my students to reflect on their experience in my Introduction to Python Programming for Librarians class (now in its last week). I’m going to reflect on mine too, but I’ll do so publicly. 🙂
First off, the course sold out and had to turn people away. So I guess people really do want to learn this. Hooray! I felt like I could’ve done more to publicize it, but maybe that wouldn’t have a ton of ROI, considering.
And now for my torrent of categorized thoughts. (And then I want to hear yours, too!)
Boston Python Workshop and true beginners
The course is based on the intro to Python workshop at ALA, which in turn is based on the Boston Python Workshop, a one-day+evening sprint through Python fundamentals geared toward beginners. At ALA we covered the material in 7 hours, minus a break for lunch, plus time in advance for students to install Python and a text editor independently, so I used that to gauge how much to cover in the course.
And the thing is? That’s totally inaccurate.
In the one-shot version, students are often confused, but that’s not surprising because of the pace, and they generally accept that it’ll be intense and persevere through those feelings. Also, they have tons of help due to a great student-teacher ratio.
When you spread it out over a month, though…I think people expect to get to a place where they’re not confused. They have lots of time to think through the hard parts — which is great — but I think it means they also spend a lot of time confused (on which more later) and it’s harder to persevere, because they have different expectations about how things should feel.
I also think this has exposed how poorly these coverage goals work for true beginners. BPW has some wonderful beginner-friendly aspects to it (e.g. it’s good about identifying and defining jargon). But it takes a lot of time and practice to build mental models of these concepts, and the one-shot format (in which no one really expects to build those models) obscures how hard it is. You can frog-march people through a lot of exercises in a few hours, but that doesn’t mean you’ve got more than a cargo cult.
I expected to see a difference in how students with and without prior programming experience handled the course, but it’s a wider difference than I’d guessed, and not shaped like I expected.
I’ve started to think it’s not possible, outside of a truly intensive situation to cover enough material in four weeks to enable true beginners to program short scripts unsupported. So I’m turning over in my mind, what could one cover in that amount of time that would be useful? Going to have to mull that over for a while.
Feelings of confusion
Over the weekend, I came across this good essay on learning to code. It was tweeted with a pull quote about how you don’t have to fit the coder stereotype to be good at coding (I wholeheartedly agree), but the quote that stood out to me was this:
I’ve found that a big difference between new coders and experienced coders is faith: faith that things are going wrong for a logical and discoverable reason, faith that problems are fixable, faith that there is a way to accomplish the goal. The path from “not working” to “working” might not be obvious, but with patience you can usually find it.
Anyone who’s done much coding takes for granted that things will be really confusing (where am I, and why is this floor covered in yak hair and broken razors?). We get that, as you learn more code, you don’t actually spend less time confused — you just spend it confused about more abstract things, and with a bigger toolkit of better yak-razors.
But confusion is uncomfortable. And especially when you’re a beginner, the line between “this is confusing because it’s hard” and “this is confusing because I’m hopeless at it” is not clear (and yes, I did tell people explicitly about impostor syndrome). And I think some students have an expectation that things will become not confusing, that you do the exercises and at the end you are un-confused.
And it…doesn’t work that way. Maybe it never really did for any subject, but it’s a especially acute in programming. You get these total flashes of insight where it works and you feel like a genius and you’re standing atop a flaming wreckage of tracebacks totally triumphant, booyah…but you truly had to spend time climbing those tracebacks first.
I need to be way, way more explicit about this. How it’ll be confusing and that’s okay. How everyone who codes spends a lot of time confused, including experts, and confusion doesn’t mean you can’t do this stuff, or even that you don’t have a good grasp of it. How if you persevere you will get better tools, and you will find that the things that confuse you become more complex, at least. How some days, the best you can do is make code that reliably works and you don’t know why, but it works, and that’ll do.
Seriously, I still have no idea how some of the things I encountered in my first semester computer science class in college work. I literally emailed my professor about one of them just the other day. But I can also do lots of awesome stuff I couldn’t do when I was 17. It’s okay.
Be explicit about your nontraditional course formats!
A few students have indicated that they expected a more traditional course format – lectures and stuff.
I do not have those. I have lots of interactive reading (prompting them to do various things in the Python shell and asking questions about inputs, outputs, and expectations). I have sample scripts to read and modify. I have discussion forums, with questions that ask students to consider important functional elements of programs — trying to lead them to think like programmers, to identify the salient parts and reason about them.
And I have these on purpose. Regardless of people’s overall learning preference, everyone I know who’s learned how to code has done so in a hands-on way. I want them to get their hands dirty — to encounter actual errors, to be walked through how to recover from them in practice before encountering them in the wild. To test the differences between general ideas and pseudocode (which is what you’ll build in your head during a lecture) and actual running code, every step followed with blind literalism by a persnickety computer.
And the forums. And the fact that I sacrificed some coverage goals to ensure that everyone had a Python shell and a text editor, rather than looking for some online interactive shell. And the fact that I spelled out how you ask a good question, and what the canonical reference documents are. And the fact that the bibliography links to lots of online and face-to-face communities that do libtech and Python, and I’ve explicitly asked students to look into these.
Because — lone-wolf-in-the-basement stereotype be damned — code learning is social. We have this pipeline whereby you don’t get to the advanced parts if you couldn’t hack the lone-wolf gauntlet when you were ten, but in practice everyone I know who’s an advanced programmer has gotten there in part by working with other people. You collaborate on a codebase and you see someone else’s approaches to a problem, and they aren’t yours, and sometimes they’re better, and you learn. You shoulder-surf a colleague and see a tool you didn’t even know existed that makes some part of your workflow ten times faster. You get frustrated and ask a question and someone says, “did you try X?” And you hadn’t even known X existed and damned if it isn’t a revelation. You work together, and your strengths are this part of the codebase and theirs are that part, and suddenly you have something so complex it couldn’t fit in a single person’s head, and far better than either of you could have made alone.
Code-learning is social, and I want my students to be doing that early, so that when the class ends, when they’re on their own to take the material beyond the class, they are not, in point of fact, alone.
So. Reasons. I have them. But I need to be more explicit about them, because otherwise for some students it will feel like a violation of expectations.
Also I expect the class would benefit from some video of me thinking out loud about some of these problems, modeling a way to go about it.
Craft knowledge and non-beginners
So I had expected that beginners would get more out of this course, because the programming material is new to them, and non-beginners would be frustrated by some of the review and mostly be getting “oh, that way that PHP does a thing, Python spells it this way, cool”. Yeah. Totally wrong.
One of the things I have discovered, to my surprise, is how much I value craft knowledge. Like I said above, this stuff is social. The craft knowledge is all transmitted socially. And I’m being really explicit and intentional about surfacing it. I ask people to reflect on what a good comment looks like and why we do that. I talk about reusability and maintainability and modularity. I talk about it more than I expected to.
And I’m finding the non-beginners get a ton out of it. They have enough background that they don’t need to spend much time on if
and for
, and so they’re picking up on all these hooks about quality and style, and internalizing them.
That part is awesome.
Proofread!
Yeah, so I made some humiliating errors in my code samples. Which my students were clever enough to find and fix, but really, the educational benefit of that discussion was less than the educational detriment to others of stuff not working. Note to self: just because it’s a simple program doesn’t mean you get to skimp on testing. You are error-prone about details and always have been.
(Related note: every single class, you need to make a clean virtualenv and develop new scripts in it, so that you will discover what your students need to install. If you are developing outside of a virtualenv the program will not complain when it relies on a module you installed in 2011 and forgot about. And then your students will be confronted with yaks, and maybe not armed with razors.)
Encourage more discussion earlier
My students have been doing a more and more awesome job as the course goes on of helping one another. And this is great, not just because they’re helpful, but because they detail their thought processes, and they come up with solutions that are different from the ones I would have come up with (there are lots of right answers!). I’d like them to do more of that earlier, though, both because it’s great, and because as a practical matter I can’t provide sufficiently prompt and thorough feedback when I get a couple dozen emails per day from my class. (Not all of which require feedback, but some do.)
Will have to do some thinking to the architecture of forums. A lot of them are set so that you don’t see others’ posts until you post, because I want people to think about the answer independently, and because I’ve been a student posting the 10th nearly-identical answer on a forum where I can read everyone else’s content and it feels pretty pointless. At the same time, though, this format discourages discussion. I think I can get there with a more carefully crafted mix of open troubleshooting-and-discussion forums and more locked-down think-about-the-answer forums. (And then also be clearer about the visibility settings, and encourage people to at least skim their classmates’ answers, particularly if they were unsure of their own.)
Affective goals…?
I thought going into this that the hardest part of making the leap to an online forum would be preserving the outstanding affective quality of BPW. It’s so strong in creating a welcoming, inclusive culture, in naming impostor syndrome so it loses some of its hold over people, in having tons of help available. I feel like I should have a lot more thoughts about this at this point, and yet I don’t, and I’m not sure what’s up with that.
And…?
This is the part where I invite comment from my students, and from other code-teachers and online-teachers (and especially online-code-teachers). What do you think does and doesn’t work here? What should I keep? What should I change?