To-do list from SIGCSE 2019

The timing of SIGCSE (the technical symposium for ACM’s special interest group on computer science education) as midway through the Spring semester is a nice lead-in for course revisions that might happen over the summer for the next year, but the trick is to actually remember those intended revisions. There’s also so much one can take away from SIGCSE that I’ve committed to, each time I attend, identifying three manageable things I can do to follow up from the conference in the coming year.

Top of the list is a revision to my OO programming course inspired by Prather et al’s paper “First Things First: Providing Metacognitive Scaffolding for Interpreting Problem Prompts” (ACM Digital Library: https://dl.acm.org/citation.cfm?id=3287374). They demonstrated how working test cases before beginning to program can help with successful program completion (and, tangentially, that re-reading the problem prompt does not have a similar positive effect). I already instruct students to work through a few given test-cases by hand for most of the assignments I give, and I also give daily “preparation quizzes” due before class through our CMS. This fall, I’m going to try having the quiz for the next class session after an assignment is distributed require students to work through a test case for the assignment by hand. I particularly like how this takes things I’m already doing and makes them work together to hopefully get real benefit for my students without much additional work on my part beyond what I’m already doing.

My prior Screenshot entry was about the importance of students being open to learning from their failures or missteps, so the “Rethinking Debugging as Productive Failure for CS Education” panel (ACM Digital Library: https://dl.acm.org/citation.cfm?id=3287333) resonated with so much of what I’ve been thinking about and discussing with colleagues in my department. There were a lot of good suggestions, but one that I want to try out next year (and part of this will be figuring out the right place for this) is asking students to journal about their goals around debugging and their personal process of debugging. I’m leaning towards introducing this in my CS0-style game design course to get students reflecting on how they respond to programming errors early.

Finally, I had some great conversations with many of the people who’ve been involved in the SIGCSE Committee on Computing Education in Liberal Arts Colleges. Our final report should be appearing soon, but I’m looking forward to continuing to work with this group over the coming year and hopefully help organize a session/workshop for SIGCSE 2020 that will start addressing some of the needs of the liberal arts computing education community that the report identifies.

Making a note to myself to check in on how I’ve done with these projects before heading off to Portland next March!

Just silliness

I always enjoy the updates to Math with Bad Drawings that reflect on the process of teaching math. The recent entry The Serious Truth About Silly Mistakes rang particularly true for me, especially when I think about teaching programming.

Orlin writes about how students do sometimes make careless mistakes – what I might think of as “typos” or “silliness” as he calls it – but that students (or, in his case, their parents) can struggle to distinguish an actual careless slip and an instance of “silliness” that reveals a lack of underlying understanding. He suggests the following for why mathematics may be particularly prone to this phenomenon:

“To some, mathematics feels like the successful performance of prescribed steps. In that case, the whole subject is mechanical and straightforward. All mistakes, in this light, are “silly” misfires.”

This description can easily apply to programming as well. The early tasks you do in a programming class can help create this mindset – you’re just getting started so a certain amount of the focus is on learning the structure and syntax of the language. If you’re focusing on reasoning out the right arguments to a method or what to set as your loop condition, it’s easy to omit a parenthesis or a comma or some other bit of syntax.

On the other hand, small bits of syntax can also have deeper meaning. You forgot that you have to call your method through an object? You didn’t declare your variable and just started using it? You have the order of your assignment statement backwards? Understandable mistakes – especially if you’ve programmed before in a language that operates differently – but also potentially reflective of, as Orlin says, your mental models still needing some development.

Orlin labels this as appeals to “silliness”; I experience this as the use of the word “just”. Many times when I work with students to help resolve a problem they are having with a program, once I’ve helped them understand the issue, they’ll declare “so I just forgot to _____”. And sometimes, it is “just” a thing they forgot to do – the carelessly omitted bit of syntax or typo they didn’t spot because they were focusing on whether their design choices and understanding of the concepts and problem had led them astray.

But I’ve started to push back on the word “just” when it seems to be softening the importance of the underlying concept that has been missed. It is a totally understandable instinct, but as Orlin says:

“Easier to admit occasional clumsiness than real confusion. But it’s the deep mistakes that signal the greatest opportunities to learn.”

If “just” gets in the way of realizing that an error reflects an insufficient understanding and the subsequent work to deepen that understanding, that “just” is a barrier to learning. I suspect it aligns with a mindset that the goal of a programming exercise is to produce a working program that meets the specification. But a more productive mindset for learning is that the goal of a programming exercise is to successfully work through the process of producing that program (I, as the instructor, already have a perfectly nice working version of the program and do not need several more), including all of the missteps that might occur along the way.

If I have done my job well as an instructor, I’ll have provided exercises that are likely to expose weaknesses in students’ mental models. But then we have to spend time in resolving the underlying misunderstanding. “Just” can be useful in defusing the tension and even self-doubt inherent in getting stuck on an exercise and create the space to be open to improving. But some care needs to be taken to make sure that it doesn’t just become the end of the process.

Missing the phone part of my phone

This week I got to spend a bit over three days without a phone due to unrecoverable failure of my old phone and a delay in getting a replacement. When I discovered I wouldn’t have a phone for that stretch a time, my immediate reaction was semi-panic – what would I do without my phone!

I was sort of surprised that, in reality, it was way less of a hassle than I expected. I attribute this to a few things:

  • I have so many devices that there were only a small number of apps on my phone whose functionality wasn’t replicated at least one other place.
  • I wasn’t teaching and had a fairly unstructured schedule this week. I wouldn’t have been using my phone to keep track of meetings or to read email and put new appointments in my calendar on the fly, even if I had had it.
  • Similarly, I was mostly around my house or my office where my other devices could be easily accessed.

I still figured I’d end up reaching for my phone out of habit but I was pleasantly surprised that there were only a few times that happened, mostly in my dentist’s waiting room. I quickly switched to jotting down shopping lists on paper. I did miss my phone as a media player – both in my car and around my house – but I pulled out an old iPod and listened to the radio while driving and it was fine.

In fact, what I ended up most missing my phone for was not any of the smartphone functionality, but as a PHONE. I had access to other phones, but why I tried calling a family member from an unfamiliar number to arrange a time to visit, it took many tries to get them to pick up. This was a consistent problem – nobody answers unknown numbers anymore! I also found myself more cautious while driving because I was aware that if I got in an accident or the car broke down, I couldn’t call for help. And I had to wonder – would people be as quick to stop and see if you need help if they figure everyone of course just has a phone with them to call for help themselves?

I’ve got a phone again now and I am, of course, using it just as much as before. No revelation that I am going to go device free from my technology mini-break. But it was interesting to see that what I missed most about my device wasn’t what I would have expected.

Reflections on Debugging Tips

I’ve had a copy of The Pragmatic Programmer (Hunt and Thomas) on my shelf for years but I’m finally reading through it in anticipation of teaching three programming-heavy courses this Fall. I just got to the section on Debugging and there are many tips in here that are helpful for reflecting on the mindset that novice programmers have as they start writing code and encountering bugs.

A few of the tips are classics: “Don’t panic” and “Don’t say it’s impossible” – I think of student queries about whether the compiler might be broken as off-shoots of the later of these two. And I’ve observed “Don’t panic” to be increasingly important advice as our OS’s and devices have trained us to simply click “OK” to make error messages go away as quickly as possible or have become smart enough to hide from us when errors are happening. But there are two deeper tips that I want to make sure to take into my classes.

First, “Resist the urge to fix just the symptoms you see”. Make sure you’re digging in to the root of the problem, not just making a fast, minimal change to correct the behavior for the one case you’re looking at. With introductory students, I often see this manifesting itself as what I call “flailing at their code” – switching around some ANDs and ORs and hoping it makes the problem go away rather than sitting down and understanding why the incorrect behavior is popping up. This is an easy habit to get into when the problems you are solving are simple. And changing a few things around to see what happens can be a good way to learn more about how your program (and programming language) function. But eventually you need to exercise the skill of being able to understand what your code will do before you compile and run it. I do a lot of live coding with students in my classes and I think it’s a great practice, particularly when students are taking the lead and you get to model not just solutions but the debugging that it takes to get to solutions. But I’ve started to also interrupt the live coding process and ask students to write out the line(s) of code to solve a small problem on a piece of paper. It seems to help slow some students down from a habit of just typing some code and seeing what happens rather than planning their problem solving and to highlight different types of issues than I see in the code they’re writing live in class. As an instructor bonus, I find it a lot quicker to walk around the room and glance over everyone’s shoulders to see what solution they’ve written down than to try to identify which portion of what is showing on everyone’s monitors is the bit I need to review.

The second deeper debugging tip relates to what we mean by “bugs” and isn’t a tip that Hunt and Thomas write about explicitly in their book. But, they do suggest turning up your compiler warnings as high as possible, because “It doesn’t make sense to waste time trying to find a problem that the compiler could find for you”. And, implicit in this is the fact that a compiler error isn’t a bug. For beginning students, it is easy for the goal to become “write code that compiles”. It’s certainly a base-line start and it’s often hard enough to do that. But debugging properly is about what you do after your code compiles and runs and it is very common for students to skimp on this part. There’s lots that can be done as an instructor to help students over this hurdle like providing or having students write unit tests, incorporating code review, modeling the debugging process during class, or giving every student a rubber duck. I give a first assignment in one of my classes that asks students to take a program that I’ve introduced errors in (both compiler errors and ones that will produce bugs) and correct them so the program has the correct output. It’s an assignment I’ll always include in the course because there are always students who stop when the compiler errors are gone and don’t identify the bugs in the program behavior. Because I let students resubmit the assignments, I can make sure that everyone’s gone back and practiced actual debugging before we get into harder content.

 

The Other Reasons Small Classes Matter

A couple of weeks ago Inside Higher Ed briefly higlighted a BioScience paper, Do Small Classes in Higher Education Reduce Performance Gaps in STEM? The answer seems to be “perhaps for women”. It’s an interesting result but despite my interest in the topic what it really got me thinking about was how this is one more in a long string of “are small classes better” articles that talk about the question only from the perspective of whether students acquire particular knowledge or skills better.

Obviously, this is important. But small class sizes permit a classroom experience where the outcomes for a student are more than just the learning outcomes.

When I think about the interactions with students that a small class enables, beyond the pedagogies I can use, there are many other benefits to the student, both short-term and long term. All of them tie back to actually getting to know them all as individuals.

I can learn their interests and find ways to wrap in course content that reflect those interests or point out interesting connections in passing. I can be aware of those interests as I encounter opportunities on campus and in the community and connect students with those opportunities – even if they aren’t related to my course content at all. I can become another adviser about educational experiences they might want to have – other courses in my department or courses colleagues in other departments teach. I can connect them up with alumni who share their interests. This is the “building connections and relationships” that I think really comes into its own at colleges that are built around the small classroom experience.

It less resembles the admissions sales pitch one hears about the benefits of small classes, but from my experience it’s equally valuable that I can get to know my students well enough that I can spot when something is going wrong. Not just academically, but personally. Or, on the flip side, I have a chance of having built enough of a trusting relationship with my students that when something goes wrong – not necessarily in my class – they feel they can tell me. We know that life’s challenges can easily derail students and students don’t always know that there are options open to them to help keep them on track or at least put things on pause in a recoverable manner. In a small-class setting, it’s easier for me to be an individual and to establish a consistent pattern of interaction with my students as individuals.

I’m always happy to see research that confirms that the specific learning of the course goes better in small class settings. But for me the biggest value, and I would suggest also part of the reason the learning goes better, is that we’re doing the work of the class in a room full of individuals who are able to connect with each other.

Readability of rainbow schemes

The core argument in this discussion of color schemes in maps of Hurricane Harvey rainfall makes sense to me – darkness and light have intuitive intensity meanings to us and it is a problem when a visualization violates those meanings and expects a key to do the work of remapping our understanding. But the suggestion to rework the map with an entirely different visualization technique based on a gradient of color (perhaps with a slight hue shift as well) rather than a rainbow scheme seems to miss what I, at least, find to be functional about the rainbow scheme. I’m accustomed enough to how the rainbow scheme maps to amounts of rainfall in the online weather maps I use that I now have a learned sense of what “dark green rainfall” is like as compared to “light orange rainfall”, etc. It goes back to what one thinks the purpose of the map is. In the linked article, the Washington Post version does a nicer job of showing historical rainfall data about the region. But if the main purpose of National Weather Service maps is to help people understand the weather conditions they are about to experience, with a historical map of accumulated rainfall in a case like this being an outlier use case, I feel like the rainbow scheme makes that easier for me as a user of the visualization than a version using only a light-to-dark shift in a single color.

Defining a Liberal Arts Major

Over the past few months I’ve been spending more time than usual in discussions about the value and mission of liberal arts education, coming at it from a few different directions. This seems to align with an increased number of articles in various sources (mainstream and higher-ed focused) about the value of the liberal arts. There are a lot of pieces to the challenging problem of explaining liberal arts education. One piece I keep coming back to, though, is my frustration with the phrase “liberal arts majors”, generally intended to mean arts and humanities majors.

If it were up to me, we would insist on being clear that at a liberal arts institution that truly embraces its mission, all of its majors are liberal arts majors. I understand that underlying much of these conversations is a need to defend the value of the humanities and arts, but from my own disciplinary perspective I fear that this lets science and technology programs off the hook for their own obligations towards a liberal arts philosophy.

If done properly, a liberal arts STEM major is not just a STEM major as would be experienced at any institution with some extra gen ed distribution requirements tacked on. The program itself should reflect the interconnectedness of disciplines from across the institution and ensures students can approach problems broadly as well as deeply. Further, taking on a liberal arts perspective ought to change how each course itself is taught; it is a mindset that the instructor should adopt towards the range of interests and priorities their students might have. This might be reflected in pedagogy, in course problems and examples, or even in the scope and specifics of course content.

While certainly not an absolute, it is frequent that liberal arts institutions or liberal arts programs within larger institutions are relatively small entities. This means that the faculty can work together to build a shared vision of a liberal arts education and integrate it within their own disciplinary perspective. STEM faculty have an obligation to provide a robust liberal arts education the same as their colleagues in other disciplines. Falling into informal language suggesting that some disciplines are what constitute the “liberal arts” and other disciplines simply coexist with them works against the unified mission that ought to exemplify a liberal arts education.

Finding a use for Twitter

As part of the obligatory year-end reflections, I have noticed that despite consistent good intentions, I haven’t been posting here regularly this fall. As always, I hope to remedy that as I don’t imagine ever entirely abandoning Screenshot.

However, in my absence from this space, I have been somewhat more active in another corner of the internet. After some false starts and a general sense of apathy about the service, I have found a use for Twitter that seems to be working for me, mostly as a replacement for Delicious which I found became cumbersome at some point a few years ago (at least for the ways I was using it).

So, tweeting under @ProfAMH, I’ve been linking to stories I want to keep track of but don’t have full weblog posts about. Most of the time, this means they’re stories I want to be able to pull up again for use in a class I’m going to teach, which means most of my tweets are labeled with hashtags like #cis105 (for my games course), #cis335 (for my security course), and so on. At my most optimistic I hope this might be interesting for students (or even alumni) and more appealing than following my very-sporadically-updated weblog. I’ve also started collecting some links under an #InterdisciplinaryCS tag as I’ve found myself involved in more projects related to interdisciplinary computing, CS in the liberal arts, and related topics over the past year.

I’m not sure if I’ll ever get on board with the social interaction aspect of Twitter, but for now this is helping me keep track of content and if others find it interesting or helpful that’s just bonus. My goal for the coming year is to make consistent use of it while phasing back into the habit of posting here as well.

And so into the new year we go, with the best of intentions for positive habits of social media usage!

Next, they rise up and kill us all….

My most recent weblog post was on teaching ethics to self-driving cars, flippantly titled At least they’re not using GTA as a data source. Except….

Self-Driving Cars Can Learn a Lot by Playing Grand Theft Auto

Let’s console ourselves that “there’s little chance of a computer learning bad behavior by playing violent computer games” and instead admire the clever efficiency of allowing them to get practice navigating the complexities of realistic roads. And, in this case, it does seem that they are just extracting photo-realistic screenshots rather than having to produce authentic training data, which is a cool trick.

But the fact that the type of data you feed into a machine learning algorithm affects the type of results you get does keep rearing its head.

At least they’re not using GTA as a data source

MIT’s Media Lab wants you to help crowd-source solutions to the Trolley Problem as a decision-making data set for self-driving cars. This is exciting news, because asking the internet to solve tricky moral dilemmas using binary decision making will surely reflect our societal values accurately.

Putting aside snarky skepticism, I had the following thoughts as I went through a judging session:

  • Having to pick one of these options without any “it depends” or “I don’t want to choose” selection got uncomfortable fast.
  • After a few scenarios I started to question the definiteness of the outcomes. How is there equal certainty that plowing straight ahead through four people will kill all of them, but swerving and colliding with a barrier will absolutely kill all passengers. Are self-driving cars not allowed to have airbags?
  • I wonder if they are storing data about how long people spend on each question and if they read the scenarios. Overall I wonder how they actually intend to use this data.
  • Best scenario I encountered on multiple trials was a self-driving car transporting two cats and a dog when its brakes fail with three pedestrians in the road in front of it. The two cats made the dog sit in the back seat.

Finally, a note on the “Results” page you get to – if you land there and find yourself bothered by some of the values it attributes to you, keep in mind the data sample is way too small relative to the number of things that change between scenarios. I just did a run through to see what my results looked like if, without considering any other details, I applied the principles that (1) if the choice exists to hit a barrier and harm those in the car rather than those outside the car, always take that choice, (2) if the choice must include hitting others, maintain your course (presumably hitting the brakes) and drive predictably rather than swerving erratically. Based on an application of ONLY those rules and the scenarios I happened to be served up, I was able to also create a 100% preference for saving children and criminals and always hitting physically fit people.