The main content of the course hasn't changed. Complexity, Big O notation, sorting and searching are introduced in the first two or three weeks. Students work through the usual implementations of arrays, linked lists, stacks and queues (both array and linked-list based), trees, heaps, tries, etc. All these data structures are explained first as chunks of data with external functions for the operations; then a second time as objects with methods for operations, once object orientation is introduced in week 5 or 6. Iterators are introduced as an abstract interface to list-, array- and tree- walking. Where relevant, we explain every operation twice, showing the iterative and recursive approaches. The course ends with two weeks of lower level work, where the students hand-compile pseudo-Python to working MIPS assembly.
The move to Python gained us, among other things, the freedom not to have to explain Java's generics and access modifiers. Many of our students have never programmed with a text editor before our unit, and dropping them into the big boilerplate world of Java micro-management was not good for them or for the course. We used to spend too much time on syntax and other details ("native types are like this, reference types are like htat") that we should have been spending on data structures and algorithms.
With Python, we even have time to explain idiomatic Python iterators and generators, and to discuss Python scoping rules (which come up again when we work on local variables in their hand-compilation tasks). So we still teach a bit of language-specifics, but we don't feel we are shackled to have to teach them. Also, teaching them idiomatic Python is a good deed after spending the first three or four weeks in a not very idiomatic subset of Python where we maintain explicit indices, update them by incrementing or decrementing them manually, use while loops the condition checking on the index value, etc. as required by the course content.
I don't have data on the results, because I was only the adjunct adapting the tutorial materials. The only difference I noticed was that students had less support from their IDE, and that some common errors (attempting to access attributes on None is the top one) that used to be picked up statically are now runtime errors, as expected. There didn't seem to be any big problems from Python's lack of lexical typing. Type errors are still caught, again by the runtime instead of the IDE and, if anything, this is a better exercise for students, since fixing them requires better understanding of what the program is doing.
If anyone is interested, I can ask the lecturer about the outcomes, but just from the fact that neither she nor anybody else teaching the unit has raised any issues the second and third times the unit was taught I can tell it's all going smoothly.
This means that we have ten weeks to take people who may have never programmed by typing text into an editor and teach them enough CS and programming that they can implement their own hashmap in Python and reason about its big O performance in one week, start programming in MIPS assembly the next week, and implement function calls in assembly and reason about stack frames the following week.
Anything we can do to make their learning curve less steep is good. You say that your Data Structures course was graduate level, and that you were already familiar with C from a lower course. These are two big differences between you and our first year intake.
Now, like Spolsky, I too have a bit of the Yorkshireman in me, and I wish our students would be forced to work with simple text editors and the command line, instead of having the IDE to do some of their lifting for them. I wish they were taught more maths too. And spelling, now that we are at it. And C, why not.
But when you say that in your course you "just had to focus on our algorithm and nothing else", it echoes exactly our intention when we picked Python for this unit. We wanted the language that would allow our students to focus on the fundamentals, and spend the least time and effort on the incidentals. We were already running the unit in Java, which was an inherited decision. I think Python was the best of our available choices.
But the next course would be a hardcore introduction to C, embracing the language peculiarities instead of shunning them and trying to stick to concepts. I think at least once in an undergrad's career, preferably sooner than later, they should go through the process of learning the nuts and bolts of C.
I've probably been doing my own thing for too long to know for sure whether C is still the best choice, all I know is that NOT having the sort of class I describe, early in my college career, made things far more difficult later on.
When you're teaching systems programming, all the things that have to be done by hand in C are precisely the things the students are supposed to be learning. But for almost everything else, they're pointless details that obscure what you're actually trying to teach.
Teaching multiple languages also has the advantage of showing people how they're mostly not that different.
1. Historically, before it was taught in Java, this unit was taught in C, and it would have been a natural transition from building data structures via explicit pointer manipulation to explaining stack frames as a specialised data structure for handling scoped variables in function calls.
2. Despite the move to a higher level language (and, from assembly and machine code, even C is a higher level language), it's good for the students to get some exposure to the machine model, and what is going on deeper in the stack of turtles.
3. The lecturer who runs the course also has a bit of the Yorkshirewoman in her. So students learn a tiny bit of MIPS like they should eat their spinach and shower with cold water, uphill both ways, in the snow, or something.
"Now, I freely admit that programming with pointers is not needed in 90% of the code written today, and in fact, it's downright dangerous in production code. OK. That's fine. And functional programming is just not used much in practice. Agreed.
But it's still important for some of the most exciting programming jobs."
Pretty much saying that everything he just spoke to us is purely for the "exciting programming jobs". And let's face it, most of us do not have that unless we go out of our way to pigeon hole business problems into being fun and exciting.
The truth is, universities shouldn't care what industry does, because "real-world" computing is more about fashion than it is about any sort of science. And if you do it right people can learn any language they need (case in point, I learnt FORTRAN at college, now I do Python for a living and OCaml as a hobbyist).
That's not what I'm seeing at all. What I'm seeing is discussion of specific traits about Python that make it especially suited for a beginner language. And I'm seeing these arguments made over and over and over again, convincingly, in a way that was NEVER done for Java.
However, if you want your Computer Science majors to be able to create the next runtime like the JVMs, .NETs etc. or be able to do some device programming they need to learn C/C++.
A decade after going through a top-tier CS undergraduate program what saddens me is that a lot of university students today, think that Computer Science is cobbling github sourced code with their choice of scripting language. Yes, the startup market is hot and sometimes that's all you need but CS is much more than that. CS is about understanding the underlying models and concepts rather than a language. If you are totally missing how memory management is done, how data structures are laid out in memory, how typing works you are missing a big chunk of code-base out there in the world today.
I think the new wave of CS students, who are expected to solve larger problems, need to understand how billions of devices/apps are running in today's technology so they can create something better in the future.
"think that Computer Science is cobbling github sourced code with their choice of scripting language."
This is the beauty of programming, and I'm sorry you can't appreciate that. Not everyone is willing to stab themselves in the eyeball trying to re-implement the .NET/JVM wheel or other low-level library.
It's the same reason the majority of us don't write assembler anymore. We've moved on and abstracted away from that arcane knowledge. Does that mean that arcane knowledge is irrelevant? For most of us, yes. For others, no.
"Yes, the startup market is hot and sometimes that's all you need but CS is much more than that. CS is about understanding the underlying models and concepts rather than a language."
Meanwhile, in the real world, CS is not really necessary for most business problems. No matter how much you wish to romanticize it as a discipline.
It doesn't have to be the first language introduced. It should be second. My other comment in this thread: https://news.ycombinator.com/item?id=8004582
CS is about understanding the underlying models and concepts rather than a language.
Programming Language implementations are exploratory tools critical to understanding those underlying models and concepts. Indeed, in my experience the "CS is about understanding the concepts" logic is more often than not used as an excuse NOT to teach C.
The second was assembly.
I've gotten by in my career (to put it mildly).
What "top tier" undergraduate program is graduating students that can't lay out data structures in memory, don't know types, and so on?
Those schools actually DO try to teach students about these concepts. How do I know? I personally have spoken to the deans of CS departments. Now imagine these same students, who no longer even hear of concepts such as garbage collection, pointers, etc. because it just works in their chosen language.
I believe the era of a single language for your career is long gone. Most people in their 20s and even 30s today will go through at least 4-5 different languages throughout their career.
Personally, I learned and enjoyed C++ 15 years ago but I do not find it practical for anything I do today. However, the same "impractical" knowledge allows me to get familiarized with a new language in a few weeks and start producing working software.
I don't quite care what language students learn as long as the concepts are understood. However, if the language they first start with hides most of these fundamental concepts, they no longer have any incentive to even learn how anything works.
This is not terribly different than what I suggest. I'm saying in the modern world, Python fills the role of Basic and C fills the role of assembly.
The abstract idea is:
First Language: Clean and simple, to introduce the very idea of coding algorithms for a computer.
Step two: Low-level language requiring a lot of attention to detail. Should be useful for exploring low-level details about computer architecture as well as writing real programs.
Notably: Java doesn't fit very well into either category. There's a lot of overhead for pure beginners, and too many layers between the programmer and the hardware
that seems utterly pointless to me.
Remember that if this is a 4-year curriculum, they may eventually be expected to write code for a hashmap in C or some other low-level language as part of a data structures or algorithms class. And often, a class like that will spend time on analysis and algorithm design tradeoffs. The best way to understand why accessing a hashmap can be done in O(1) time is to actually code one for yourself.
This may simply be a preview.
> This may simply be a preview.
No, this is it as far as the core units go.
This is the first course on data structures and algorithms.
There is a second year course that deals with further data structures and algorithms: we teach amortized performance, proofs by induction, some randomized data structures (skip lists and maybe another), different tree-based structures (I remember red-black trees and patricia trees), some graph search algorithms and a bit more than I forget now. And currently we are doing it in Python for the first unit, and in any language that the student and their tutor can agree on for the second unit.
Remember: these are just class exercises, not real implementations. Of course nobody is going to write actual functioning data structures in Python and expect them to be usable for general purpose programming. That would be daft!
Or even http://toolz.readthedocs.org/en/latest/
Daft, indeed! :-)
We moved from Java to python this year and I miss a few things. Due to the absence of explicit typing the students don't bother to understand types anymore and it leads them to a lot of mistakes and misunderstandings: confusion between simple types, lists, dictionaries, instances of a user created class, etc. Besides I think the verbose and rigid syntax of Java forced them to understand what their wrote and for a first language that was a good thing.
Overall I found that since it is easier to write code in python they rush to writing anything without understanding the algorithmic problem first. Thus they are less able to decompose a problem in sub-problems and write atomic functions to solve each of them.
Note that I think teaching python as a first language is a viable option but in our case the course needs to be intensively rewritten and the labs adapted. For instance my lattest point about algorithms is not a problem with the language: it could be resolved by having a part of the lab being pure algorithmics and then an implementation part.
I graduated from Monash Clayton a few years ago when the Java train was in full effect and the focus on Java was a big source of frustration for me. I distinctly remember an algorithms & data structures assignment about Markov chains which had to be done in Java. I spent a good 40 minutes writing what was effectively boilerplate to load the provided files into a meaningful representation and then just snapped and did the entire assignment in Python in maybe 15 minutes. Its crazy how much Java gets in your way for small projects.
Even though it was made clear that Python submissions won't be accepted, my tutor was very understanding and gave me full marks after I stepped him through the code. If that tutor was you, I owe you.
My first year CS data structures class was in scheme, as used to be popular. I enjoyed the class a lot, leanred a lot, and also found it very challenging. I think scheme was perfect for it. But I had no particular desire to continue with scheme afterwords, which is fine. (Not because I have anything against scheme, but on to other things).
It's important to remember we're talking about an introduction, here. Creating the spark of interest in students is the most important point in this class. There's always time after this to move them toward more expressive languages.
Maybe you felt you had to jump in and defend high level languages, and maybe slash the other guy's tires on the way out, but this reads as trollish. Plenty of people working in C find it plenty expressive. Is it "more" or "less" expressive to choose to express different things? I don't think so. This comes off as uninformed C bashing, sadly very common and accepted around here.
The rest of your comment, that it is good for learning or as a first language, makes more sense to me.
Python can be circuit bent into any semantic you desire, so I think it is a great introductory language.
I haven't taught an introductory Python course in years, but with Ipython Notebook I think it would be a blast.
Secondly, it makes for an easy transition from Python to Matlab, and Matlab is used a fair bit throughout UQ's Mechanical and Mechatronics departments. They both share very similar syntax (the major issue for most mech engineers, who deal with little more than loops, is that Python is 0-indexed whereas Matlab is 1-indexed).
The above makes Python a great introductory langauge for non-programmer beginners like mech engineers. It is ridiculously simple and human-readable, and when you're outside an IT/EE department then you don't end up spending excess time explaining the quirks of a language to those who will never care for it. On the other hand, it still gives more than enough rope for those that do end up wanting to run with it and they can end up doing some pretty fancy stuff with it.
Does Monash align there in that it's used in the non-IT related technical degrees?
Curious. Why is object orientation introduced in a data structures and algorithms course?
I find that incredible. Long before I got to university I was been programming by myself with whatever editor I could find, edt, vi etc
I hedge that many of our students have never programmed "with a text editor" before because:
1. Many of them have used spreadsheets in higschool to build quite complex formulas, and spreadsheet formulas are turing complete, so they have programmed in some form of another.
2. I didn't want to discuss this here in order not to muddle the debate, but our introduction to programming course is now ran on Scribble, a dialect of the Scratch family. So many of our students in this data structures and algorithms unit have previously done just 12 weeks of programming instruction, and understand many of the concepts, but our unit is the first time that they have to deal with (for instance) syntax errors in textfiles.
Many people here in HN were teaching themselves programming by age 6, but to repeat myself: you are not our first year intake. We teach the students we get. These are not bad students: they are often hardworking and smart, and do well and learn a lot in our unit.
They may be ignorant of programming, but that's also ok, because that's what we're there for. And, to go back to the OP's topic, using Python as a teaching language lowers the barriers for access to the concepts that we really want to teach: complexity and big O, searching and sorting, etc.
I love python - used it for years, but I am dumbfounded that people enter a CS degree without having ever first tried to write a program. That's like taking english lit without having read a book before.
Groovy (the JVM version) is marketed towards programmers who already know Java, and its main use cases (e.g. manipulating/testing Java objects, gluing together Java apps, and scripting in Grails) make the syntax terser but the programmer still needs to know what's happening underneath at the Java language level or they'll quickly hit a snag they can't solve.
The only use case where they don't need to already know Java is Gradle, where the script for a whole project is typically 20 to 100 lines long, usually copied and pasted from another project, and only using a tiny subset of the Groovy grammar, i.e. the DSL which is the least Java-like, so programmers won't be introduced to Java by using Gradle.
I even tried writing a Groovy(JVM) tutorial a while back for those new to both Java and Groovy  but found I had to introduce most Java and Groovy concepts at the same time. Groovy only gives some syntactic tersity via collection syntax, closures (though now obsolete with Java 8), and getter/setter syntax, nothing more.
The world has 6B+ people and HN is a very very small portion of the world, just like USA and the UK.
This by analogy with "lexical scoping", where you know where a certain name will be bound just by looking at the program's text, while with dynamic scoping, the stack is what determines where a variable is bound, and you can only know about it at runtime.
I guess I should have said "static typing". I probably made the mistake because lexical scoping is also called static scoping, and I was writing in a hurry.
That said, I believe that pylint could statically catch some of the type errors that are being referred to.
How sad, not that you only do array and linked-list implementation of data types but that you think this is an exhaustive list. Inductive data types?
If you don't drop context that's a perfectly reasonable thing to say.