2010s in Review

The timing of the holidays this year and my various work responsibilities makes the ending of the decade align with a week where I’ve been able to set aside time to step away from work and catch my breath. It’s inspired me to, in addition to just resting and catching up on reading and maybe even getting some fresh air, spend the next week reflecting a bit on the past decade. Not from any deep philosophical stance. But I’ve been reading through the various “decade in review” posts and articles that are cropping up and a few ideas caught my fancy – thinking about places I’ve been, books I’ve read, and things I’ve accomplished.

So, expect that here over the next few days. I’m hoping that it might also kick start me into returning to regular weblogging in the 2020s. Or at least set me up for another good round of posts in late 2029…

Education at the Bauhaus

I started exploring the Bauhaus: Building the New Artist online exhibit (companion to a current live exhibit at the Getty Center) out of curiosity to learn more about the design principles that the interactive modules present. From the blurb I read promoting it I didn’t realize there would also be significant content about the educational vision of the Bauhaus. There were elements of how the exhibit discusses the blending of fine arts and applied arts that resonated with conversations I’ve had with colleagues about the goals of education – including outside the domain of the arts.

In fact, I’m frequently struck by how often the educational considerations of artists and of computer scientists can be highly similar once you dig below the most surface level of the content. Two quotes from the Bauhaus exhibit echo this to me. Describing the painter Lyonel Feininger’s illustration of a cathedral as a representation of the school’s philosophy:

A preindustrial building form, the cathedral promised the possibility of realizing the Gesamtkunstwerk, or the total work of art, in which designers, artists, and artisans worked together toward a single, spiritual goal.

And in an excerpt from the school’s 1919 program:

This world of mere drawing and painting of pattern-designers and applied artists must at long last become a world that builds. If the young person who senses within himself a passion for creative practice begins his career, as in the past, by learning a trade, then the unproductive ‘artist’ will no longer be condemned to imperfect artistry because his skill will be preserved in craftsmanship, where he may achieve excellence.

While I know I am abstracting away some of the deeper underlying sentiment of this philosophy, there is a thread here of balancing learning with doing and with engaging in doing that grapples with the entire breadth of a messy problem embedded in the real world rather than an academically constructed puzzle. From a computer science perspective, there is a similar balance between theory and practice within education, and an ongoing tension in ensuring individual students engage with both sides of the spectrum.

The whole online exhibit, including the interactive exercises, is worth checking out. The content about the specific design principles being taught is interesting and also continue to echo the above themes in describing how they were taught, particularly in the section on Body and Spirit. I think it would be a fun read for any educator, regardless of discipline.

How we think about coding and computing literacy

I’ve been meaning to write about Annette Vee’s Coding Literacy: How Computer Programming is Changing Writing for a while now. The book looks at the current interest in “coding literacy” from the perspective of literacy studies. I picked up the book because I was interested in this outside perspective, and two quotes in the introduction immediately told me I was going to enjoy this book:

Programming as defined by computer science of software engineering is bound to echo the values of those contexts. But the concept of coding literacy suggests programming is a literacy practice with many applications beyond a profession defined by a limited set of values. The webmaster, game maker, tinkerer, scientist, and citizen activist can benefit from coding as a means to achieve their goals.

and, more pointedly,

My approach suggests that because programming is so infrastructural to everything we say and do now, leaving it to computer science is like leaving writing to English or other language departments.

There is a lot more to Vee’s book than these introductory thoughts on who codes and how they learn to code. She has great content about the history of literacy, connections between how reading and writing literacy movements relate to coding literacy movements, and how literacy, education, and power are connected. But a thread through all of it that connects to the ideas above is that what is expected in order to be “literate” shifts over time and the types of writing/coding that is considered literate evolves. This suggests that if we do achieve coding literacy, we will also see computer scientists having less ownership over defining coding literacy. Which – as Vee indicates – would be a good thing.

At the same time, I’ve been doing a lot of reading in the computing education research literature over the past month and some themes there brought me back to thinking about Vee’s book. It’s generally accepted that teaching programming is hard and we’re still learning how to do it well. This suggests that computer scientists could give our colleagues in other disciplines a leg up by sharing some of what we have figured out so far. For example – there’s a lot of evidence that collaborative learning really helps and there are some established pair programming practices for the CS classroom that could be adopted regardless of who is doing the coding.

At the same time, CS educators might consider if the goals of coding literacy allow for a broader definition of “success at programming” than we’ve been willing to consider. Can thinking about coding literacy help us refocus on the most essential first outcomes. I just read a paper from SIGCSE ’19 by Pollock, Mouza, Guidry and Pusecker titled “Infusing Computational Thinking across Disciplines: Reflections and Lessons Learned” (ACM Digital Library: https://dl.acm.org/citation.cfm?id=3287469) and while they are writing from the perspective of mentoring faculty in other disciplines to integrate computational thinking in their courses (which they have some really interesting ideas around) I thought their draft of a Computational Thinking Rubric that could be used across disciplines was also a useful reflective tool for me as a computer scientist considering what I hope to achieve in a first course that both encourages students to consider further study in my discipline but also serves students well who may not take any more courses in my program. I think there are connections to what Guzdial has been blogging about recently related to task-specific programming as well, and the “powerful ideas of computer science” identified in an essay he linked to by Marina Umaschi Bers, What Kids Can Learn Through Coding, such as using logic to order a sequence of complex behaviors.

So I’m seeing a lot of connections in various writing I’m encountering about coding literacy (under this or a variety of other labels). Turning back to Vee then, I think this quote from her conclusion is a helpful way to think about how to continue to move forward on these projects:

Studying textual literacy in international contexts, Brian Street advises understanding first what the context for literacy is, and what people want to use it for, and then afterward establishing a curriculum to support and respect those uses. Following this advice from literacy researchers, then, would mean that computational literacy campaigns can aim for certain outcomes, but they must also solicit and respond to the aspirations, ideas, and established practices of their audiences.

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.