Step 28: Separate the Means from the Ends

I was originally going to write about the new computer science curriculum that I had a heavy hand in designing. But the curriculum is currently going through the college-level approval process, so I don’t want to say anything that won’t be in the final curriculum. I also realized that I didn’t have anything concrete to say without showing what the curriculum itself. So instead, I’m going to talk about what I think a computer science curriculum should cover in general. I talked about what I didn’t like about the Liberal Arts Computer Science (LACS) Consortium’s curriculum several weeks ago; this post is the opposite of that, about what I would like to see in computer science.

The first thing to admit is that there are a lot of different view points of what computer science should be at the college level. For example, some people say that we should be focusing on programming and not computer science; others say that the science in computer science is paramount, and so the discipline should be taught using as much rigorous mathematical theory as possible. (Some schools offer separate degrees for computer science and software development.) There’s also the overlap with computer engineering which, at least in the discussions around Oxy, is often considered unsuitable for a liberal arts setting. What I think is interesting is that, even outside of “computer engineering”, there are still topics in “computer science” that deal with the engineering artefact that is the modern computer, and I think there can be another long discussion about whether that has a place in computer science.

Let’s start with the basics. Learning to write code is certainly part of computer science; it’s hard to argue that you know computer science without knowing how to program (although I know some people who try really hard to do exactly that…). The question I find myself asking is: is writing code an end in computer science education, or is it merely a (necessary) means along the path to learn something else? Writing code is central enough to computer science that the question might be hard to answer, but similar questions can be asked of other skills, such as the ability to use version control. At least to me, version control leans toward the side of being only a means to other things – there’s nothing critical in the use of version control that would broaden a student’s view of computer science, although of course it’s almost a necessary skill for any technical software development position.

If programming is an end in computer science education, then there’s not much more to say. If it’s only a means, however, it’s worth considering what the end(s) may be. One blog post that I keep referring back to lists several topics, both abstract and concrete, that are often considered goals in a computer science curriculum. Discarding the obvious skills such as debugging and testing – although there may also be important lessons learned there, especially for testing – what’s left for me is data representation, computational thinking, and problem solving.

I should take an aside and explain why I did not include data structures and algorithms in the list. It’s true that they are central to any computer science curriculum – but then, so is programming. As with the mathematics and theory that was in the LACS curriculum, I think these are all necessary for computer science, but I don’t think they are not the reason why people study computer science. They are all means, tools for achieving something, although at a sufficiently advanced level the tools themselves become the object of study.

This is definitely biased, but my answer to the central question of this post – what is the end goal of computer science education – is the ability to, with the aid of a computer, specify problems and their solutions and evaluate the latter. Computer science is about using the computer as a tool for thought. Under this goal, programming is merely the method of specification, and data structures and algorithms standardized tools to express common relationships. The three topics from the other blog post all play roles. Data representation is us picking the relevant features; computational thinking is our internal process that guides the programming; and problem solving is what generates the solutions that we are specifying.

There are, of course, many uses of computers that do not appear to be problems to solve, especially in more creative domains such as media arts – animation, video games, website design, and so on. But I think you would be hard pressed to argue that these products are not also driven by a thought with some goal – to tell a certain story, to provide a certain experience, or to present certain information. These drives to create, together with the more traditional uses of a computer to model and to analyze, are what draws students to computer science.

And I think this is why I object to emphasizing the mathematical or engineering aspects of computer science – these are only interesting after people understand why the computer as a tool is worth being understood/improved upon. And to do that, we need to first show them what computers are capable of – or rather, what they are capable of with the help of a computer.

Step 28: Separate the Means from the Ends

Step 27: Write Computational Assignments for Non-Computer-Scientists

I apologize for the late post. If you are not aware, things are a little hectic at Oxy, which threw everyone’s schedule off. Michigan is facing similar problems, as are more than a couple other universities, but I can’t see the school being as disrupted as things are now at Oxy.

Anyway, a long time ago I talked about how my AI class had a lot fewer programmers than I thought, and how I had to rethink the course and the assignments. Now that the semester is almost over, and all the assignments have been released (my students are working on the last one now), I want to talk about what I ended up doing, in case it’s useful to other people out there.

Just as a reminder, the course I’m teaching is an upper-level cognitive science course on AI, with the prerequisite of either a cognitive science course or a computer science course. The four topics I covered ended up being reinforcement learning, cognitive architectures, Bayesian networks, and natural language processing. Within this division were five assignments, two in reinforcement learning and one in the rest.

Just because they were the first assignments, I struggled with the two reinforcement learning assignments. The first assignment was designed to get students thinking about the simplest reinforcement learning algorithms (tabular Q-learning) and how the parameters (learning rate, exploration rate) affect the results, with a dash of more conceptual questions thrown in. I did end up using an IPython notebook, which I thought worked well; it was, however, also the only time I used IPython, since the remainder of the topics did not require as much computational support.

In contrast, the second assignment was supposed to be one focused on the applications of reinforcement learning. The main component of the assignment was for the students to frame a problem of their choice as a reinforcement learning problem, specifying the states, actions, and rewards, and justifying their choices. Since there were some computer science students in the class, I also offered the option of implementing an agent with eligibility traces, with the goal for the students to learn something about how to run experiments and explaining their results.

I’ll be honest: this assignment was a disaster, especially the application option. The first issue is that the question was too broad, and without an actual computation model to constrain it, student’s representations were all over the place. The bigger issue, however, which applied to both options, was that my students and I had different understandings of how to justify their choices. Since we covered topics like partial observability and exploration/exploitation in class, I thought they would use those concepts in the answers. Instead, their justification was often phrased in terms of the domain – why a feature is important, but not whether there are better ways of representing the feature or how it would affect the agent’s learning.

I realized my mistake once the students turned in their work. My original idea was simply to take a lecture and have students workshop each other’s papers, after they have gotten some feedback on the type of questions they should be answering. The problem was that I didn’t really want them to go back and revise their paper, but I did want to see them learning. So I did something clever: I told the students that the assignments were not what I wanted, then asked them what I should do. Which is how a student suggested that they could just talk to me for fifteen minutes instead, and I can ask them questions about their assignment. This was a particularly apt assessment because in lieu of final exams, I’m planning on a one-on-one conversation with each student, where they talk about two of their projects (we would each pick one). By including a conversation in the assignment, I’m not only completing the assignment, but also giving them practice while they have a partner.

(By the way, I’m still not sure how I should conduct the final conversation…)

The third assignment was on cognitive architectures, and I focused on the different type of thinking involved in programming such agents. So I created a simple JavaScript app where students can use dropdowns to create condition-action rules for the water jug puzzle, which they could then run. Despite the assignment being the weakest – I under-estimated the time they would have before fall break – this assignment set the tone for the remaining two. If there’s a lesson I learned from this assignment, it’s that web apps are a flexible and powerful interface, especially when supported by server side computation. It helped that I’m fluent in Python web frameworks and competent enough in JavaScript – the entire cognitive architecture app took me an afternoon.

I got more ambitious for Bayesian networks. Since math was not the students’ strong suit, I instead focused the assignment on applying causal networks. Students had to pick some phenomenon they want to model, then create a network with at least nine factors, and do any research necessary to structure the nodes and provide the conditional probabilities. While there are existing Bayesian network packages, most of them either required installation, or were entirely unintuitive to use.

So I wrote my own instead, using a simple specification language as the input, transforming it server-side into a graph with conditional probabilities (or posteriors), then sending it back and using a JavaScript port of Graphviz to be drawn in the browser. The hardest part was understanding how to calculate the posterior – I’ve never coded up a Bayesian network before – but once I got that the whole system went up pretty quickly.

From the evaluations, I can tell the students enjoyed the assignment, and personally I enjoyed grading it too. Part of it was because I learned to be more explicit about the questions I want answered, but part of it is also because students chose interesting topics to model. One of my original reasons for getting into computer science was because it could simulate reality, so I had a lot of fun testing whether (for example) a car’s country of manufacture had any effect on its gas mileage (the answer: not really). In addition to creating and justifying their network students still had to do some manual probability calculations, but nothing too complex. I also offered the option of writing a Bayes net solver, but no student took up the challenge.

Which brings me to the final assignment on natural language processing, which is still ongoing. This assignment ended being a mix of the third assignment (which had some light programming) and the fourth assignment (which used a program as a tool to answer other questions). The assignment asks students to extract prerequisite information from the course catalog (which I had scraped before hand), by sequencing a bunch of fairly basic text transforms such as replacing text, breaking text apart, and selecting certain pieces (essentially, poor-man’s MapReduce). In terms of implementation, the hardest part was deciding on the interface between the front-end and the back end. Since one of the complaints about the cognitive architecture assignment was that you couldn’t save your work, I made sure that the HTML-created transforms actually translated into a script, that students can copy out, save, then reload when they resume. On the server side, of course, I also had to parse it then run the transforms; for this I’m thankful that functions in Python are first class.

That’s all the assignments – three of them involve computation (two of which involve pseudo-programming), four of them involve answering addition questions about the AI technique they are using, none of them requiring any real programming. While I think I would tweak many of these assignments if I had to teach the course again, I think overall the approach of creating web-based GUIs for non-computer-scientists work well, and (hopefully!) may introduce students to computational thinking. This exploration is particularly appropriate, as faculty in other departments want to include more computational tools in their courses. Although the web app approach will not work for many faculty – most only have intermediate mastery of a single language, often neither Python nor JavaScript – I think there is value in showing that it’s possible for students without programming experience to consider computational questions, simply by providing a familiar interface.

I would love to see this approach used in more classes, and would also love to learn how others have enabled non-programming students to do computational work.

Step 27: Write Computational Assignments for Non-Computer-Scientists

Step 26: Attract Students to Computer Science

I’m pressed for time this week, so let me just tell a story.

When I first came to Oxy, one of the first things I need to do was understand what students thought of computer science. To that end, I sought out one of the student clubs on campus. Open Source is a relatively new club, formed only three years ago by a group of students interested in computer science and programming. Since I am not teaching any computer science classes this semester, the club served as the main channel for me to meet other interested students. A couple of the students on the board of the club was also in my cognitive-science-heavy AI class, and through them I learned more about the computer science culture at Oxy.

Or rather, the lack thereof. It turns out that most students are unaware that Oxy even has a computer science minor, and are overall baffled by what it means to study computer science (or math, for that matter…). Most of the students who are in the computer science minor program are math and physics majors, with cognitive science majors a distant third. This composition is significant, since it meant that students may not be as interested in the aspects of computer science with a broader appeal, and similar would not ask for those topics to be included in the curriculum.

Partly recognizing this, Open Source starting hosting discussions in their meetings. I went to these, partially because I want to know what those meetings were like, but also to broaden my exposure to students (or rather, students’ exposure to me). The first meeting was about security and privacy, which to me should be interesting to students in sociology and politics. To my surprise, despite having a mailing list with over 150 subscribers, the total number of members who came was about five. The next meeting, about artificial intelligence, had a similar turnout.

Lest you want to blame the students for not doing a good job of advertising, I was invited by an RA to talk to some freshmen about computer science. The turnout: one additional student who I didn’t already know, despite there having been posters, and despite me telling my cognitive science class that I will be giving the talk. The single most successful meeting that Open Source held this semester was one where students to got to meet members of the Computer Science Advisory Committee, for which 18 students showed up, out of which I had yet to meet five. It was a good group, relatively diverse, although the math/physics/engineering bias was still present.

So I was pretty worried when this week came around. This is registration week at Oxy, and I’m teaching a new computer science course next semester. The course is designed to become the entry point for a revamped computer science curriculum, and is aimed at absolute beginners. In particular, wanting to address the lack of diversity in computer science right off the bat, I restricted the course to students who have not already taken a computer science course at Oxy, not even the language-focused half-semester courses – the same courses that currently serve as the entry point to the computer science minor, and that 69 students are currently enrolled in. Which is to say that I’m rejecting, a priori, the students most likely to be interested in computer science. It’s not a particularly small class for a liberal arts college – there are 32 seats – and I was really worried about what message it would send to the administration if the class was only half full.

Registration opened yesterday (Monday) at 8:00am.

By noon, there were 11 students registered for the course.

By midnight, there were 21 students registered, and the freshmen registration time hadn’t even come up yet.

By noon today, the course was full.

As of right now (about 30 minutes before midnight), there are three students on the wait list, and I have heard from seven more who expressed disappointment at the lack of seats. It’s a curious mix of students too: not just math and physics majors, but students in DWA (our equivalent of international affairs) and economics, several students in art, and a smattering in politics, biology, and psychology (in addition to a number of undeclared students). The roster seems to be diverse by all other metrics – it’s roughly split evenly between all four classes (ie. freshmen, sophomore, etc.) and between genders (going by name). If I had ethnicity information I would have looked at that too, but all in all it looks like the course is off to a good start.

I don’t know if there is a moral to this story. One easy way to explain this is that Oxy is primed for computer science, and that students were simply waiting for a course that tackled the right issues. Another, complimentary explanation is that the existing computer science course wasn’t sold properly – I explicitly say that the course will involve manipulating images, sounds, web apps, and other kinds of media. More cynically, a third explanation is that the course satisfies the lab science core requirement, which the existing courses don’t, and that made all the difference. More likely, it was all three, plus some others like the faculty I know nudging their students in the direction of this course.

So now I have to deal with wait lists and student complaints, but that’s a good problem to have.

Step 26: Attract Students to Computer Science

Step 25: Dissent against the LACS Model Curriculum

In the process of designing the computer science curriculum for Oxy, I came across the Liberal Arts Computer Science Consortium (LACS). Made up of a number of computer scientists at multiple liberal arts colleges across the country, the group published a paper in 2007 with “a model curriculum for a liberal arts degree in computer science”. The paper first identifies what they consider the discipline of computer science, before suggesting the following twelve-course computer science major curriculum:

  • Introduction to Computer Science
  • Data Structures
  • Foundations of Computer Science
  • Computer Organization
  • Software Development
  • Algorithms
  • Programming Languages
  • Theoretical Foundations of Computer Science
  • Math Elective
  • Elective
  • Elective
  • Elective

The paper helpfully goes on to provide a list of topics for each course, as well as the suggested number of hours spent on each subgroup of topics. All in all, the paper is a fantastic resource for faculty thinking about curricular issues in computer science.

My first reaction is that the two course core sequence that I see in many computer science curricula is reflected here, validating my investigations.

My second reaction is that I strongly disagree with this curriculum.

My biggest complaint in this curriculum is that nowhere in it is any connections to other fields even mentioned. The paper does provide a “partial list of possibilities” for the electives, of which only five of the sixteen have anything remotely interdisciplinary – Artificial Intelligence, Bioinformatics, Computational Science, Natural Language Processing, and Simulations and Modeling. It was ironic to me that the paper emphasizes that the curriculum was designed with the liberal arts in mind, and explicitly mentions how the “social and ethical issues” of computer science must be worked into all courses in the curriculum. By “social issue”, the authors suggested privacy on the internet; by “ethics issue”, the authors suggested the responsibility of the programmer to produce correct code.

It was around this time that I realized perhaps I’m not a true “computer scientist”.

To me, the interesting and worthwhile parts of computer science is the computational thinking, which Wikipedia defines:

The characteristics that define computational thinking are decomposition, data representation, generalization/abstraction, and algorithms. By decomposing a problem, identifying the variables involved using data representation, and creating an algorithms the result is a generic solution. The generic solution is a generalization or abstraction that can be used to solve a multitude of variations of the initial problem.

Getting students to think computationally, and be able to apply that skill to novel problems, necessarily requires them to have experience with the many disciplines that use and are informed by computation. Just for a informal talk to students today, I made the following list (quoted verbatim):

  • Physical sciences need simulations, analyses, and visualizations
  • Social sciences need it too
  • Humanities increasingly use digital techniques
  • (Interactive) digital arts
  • Philosophical questions

Precisely one of these extremely broad categories of disciplines show up in the curriculum: the physical sciences, and then only as a minority of possible electives. If we stretch the definition of “simulations and modeling”, maybe we can include the social sciences, but that still fails to fully account for the breadth agent-based simulations and their value to sociology, economics, or even environmental science. The digital humanities has an ongoing debate about whether computational techniques can truly determine the authorship of an unknown play (or other such related questions). Computational arts – both passive animation and interactive gaming experiences – are blossoming and is one of the more vibrant industries.

And the philosophical questions! Are people Turing machines? How do simulations provide scientific insight? How is technology changing society? To what extant should we delegate life-or-death decisions to computers? These are the topics that a liberal arts education should prompt students to think about, and I do not see any trace of this in the proposed curriculum. What I see instead are courses on theory that even computer science students are bored by, and courses on the engineering artifact that is the modern computer. I am not saying that these courses should not be taught, or even that they should not be required as a category of necessary knowledge for computer scientists, but I am not sure I can justify them, in and of themselves, being required for all students.

Here’s the response I expect to get: “But the curriculum you’re suggest is more about the uses of computing than about the computing itself; doesn’t that mean it’s not a computer science curriculum?”

Maybe, and maybe because of that I am a bad computer scientist.You see, while I think parsers are cool and operating systems are clever, I really care more about computing as a way to formalize and make concrete how we reason about processes and representations. Computer science does this in the same way that (for example) critical theory allows us to understand structural causes and pressures (eg. discrimination) from a perspective not offered elsewhere. Sure, sometimes this methodology is turned on the computer itself, and there is much to be understood there, but to do so by foregoing its use on the majority of the external world is the wrong direction for a major at a liberal arts college.

Perhaps I might simply say that my ideal computer science curriculum is one designed for a renaissance man’s view of education, and leave it at that.

Step 25: Dissent against the LACS Model Curriculum