Are best practices always the best?

I've been trying to be an active participant on the CS Educators StackExchange. You should try to as well!!!

I answered a question about using the command line which led to a back and forth. I gave an example of something I might do in class to illustrate the power of using the command line and linked to some of my past posts. There was some back and forth in the comments - some of the participants weren't happy with my code as they felt it was filled with poor coding practices.

I'm not going to comment on the discussion other than to say that I make no apologies for how I use the Linux tools and the command line as my methods have served me well over the years. I also make no apologies on how I teach my students as I seem to have by and large done right by them over the years as well.

The crux was that I was showing what I might type in a class without any of the class commentary. It wasn't meant to be a script in a file let alone reusable code or a full blown program.

I don't want to spend time here talking about "best practices" for shell scripting. There are plenty of resources a search engine away.

The question is that how universal are best practices and is it more important that we teach specific best practices or rather that we have a discussion with our students about best practices.

Some general best practices are probably pretty universal – "write clear code" but I've seen best practices that when followed religiously just don't always make sense:

  • never break out of a loop
  • one return statement per function
  • always or never do anything in particular
  • all code should be commented
  • always use an ORM

to list a few.

So, best practices aren't always best. More like guidelines to think about when you're programming and then you and your team can make smart decisions.

So, when I wrote those lines over on StackExchange, was I really showing my students how to code badly? The code:

ls *gif | while read i 
do
  f=`basename $i .gif`
  convert $i -resize 200x200 smaller-$f.gif
done

doesn't exist in a vacuum. We start with an ls to see the directory, we use the echo throughout to test things before we run it live and then we run it live in such a way that it can't be destructive. I've been using the command line this way for decades and while I've screwed plenty of things up, it's never been due to a bad command line shell practice.

The important part is the discussion with the class:

  • would this be appropriate in a script file?
  • what are the dangers
  • why and when is it ok?

etc.

It's not our job to dictate to our students which best practices to follow but rather to prepare them to make smart decisions.

This year, I'm back to using C++ in class after maybe two decades. I'm not up on current C++ best practices. I was wondering what was best:

#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
  cout << "something" << endl;
  return 0;
}
#include <iostream>

int main(int argc, char *argv[])
{
  std::cout << "something" << stdendl;
  return 0;
}
#include <iostream>

using std::cout;
using std::end;

int main(int argc, char *argv[])
{
  cout << "something" << endl;
  return 0;
}

or even if we should use "\n" vs endl.

I did my research, presented the results to my students and we talked about what they should consider when making their decision.

Students don't need us to blindly spout best practices. They can read them online or in a book. They do need us to guide them towards critically thinking about them.

Learning Languages

I stumbled across a video by Tim Baldridge this morning. I don't know Tim - it looks like he's a developer and he's made a number of instructional videos on Clojure.

This video is titled "Learning a Language Takes time."

In the video (embedded below) Tim talks about the design of a guitar and a violin. How a guitar is "better" designed - frets make it easy to hit correct notes, tuning pegs stay in place and you can easily play a single note or a chord.

Contrast that to a violin. Tuning pegs have no mechanism and are held in place by friction, notes must be precisely hit, and producing even a single note at a time so that it sounds good is a challenge.

On the other hand, you can do some really amazing things on a violin if you master it.

This struck a chord with me. I once saw an interview with Itzhak Perlman - my favorite violinist or all time (and coincidentally my childhood violin teacher' teacher). He was comparing a violinist with a pianist. He said that it was easy to play the correct notes in tune on a piano and since the mechanics were simpler a musician can, earlier in their career, start working on interpreting the music. A violinist, on the other hand (in his opinion) can take half a lifetime to master just from the mechanics point of view and only then can you really start working on the music.

Perlman was talking about an album he had released - "Concertos from my Childhood." The idea was that young violinists study a standard repertoire of "learning concertos" and of course, since they're beginners they never sound good. Perlman decided to record a number of these as an adult and this album was the result.

Here's a track of Perlman playing one of those concertos that I remember struggling through as a kid:

Of course, this is Perlman so I'm betting he sounded pretty good as a kid:

Back to Tim's video.

Tim talks about the idea that learning a language, much like an instrument takes time and also that some languages do less hand holding and are harder to learn than others. The two key points are:

  1. Some times things are harder to learn because at the end of the day they have more power and so it's worth it.
  2. Don't expect to learn something subntantial overnight.
  3. With focused practice over time, you can master new hard things.

Tim's a little less sympathetic than I'd be in my classroom but that's okay - Tim's talking about teaching developers a new language and so I think he's view is appropriate and correct there.

The truth is that learning does take time. You can create the illusion of results with concentrated coaching and flashy tools but real education takes work and time 1.

A couple of years ago I was speaking to a non-teacher friend who had just run a month long intensive "coding" summer program. They were very proud of the work and what the kids accomplished – "They learned so much… Their projects were awesome." The group had a reunion some time later. I asked how much they remembered - "pretty much nothing."

So, here's Tim's video. It's about 20 minutes but if you're pressed for time, just up the speed of playback:

Footnotes:

1

but work can indeed be fun

A Community Curated List of CS Education Resources

One of the things I mentioned in my post on the CS Educators StackExchange was the fragmentation of resources for CS Educators. My friend and fellow CS teacher Ben pointed out that this is appropriate as we're so young as a community. He's absolutely right but until we mature, discover-ability can be a problem. We all have our resources and I for one am frequently surprised when talking to a friend and discovering that they don't know about a site or a mailing list that I've known about for years. Likewise, I'm appreciative when others share resources with me.

There are some collections of information, for instance, Alfred Thompson has a list of CS Education bloggers but it's not so easy to discover and it certainly shouldn't fall on Alfred to maintain such a list making sure the links are all active and always being responsible for adding new ones.

Recently I've noticed a proliferation of awesome lists. These are community curated lists hosted up on GitHub for a variety of projects. I find myself using awesome-emacs and awesome-python more and more and there are tons of other such lists.

I thought we, as a community could benefit from such a list.

I started one off. It's over at https://github.com/zamansky/awesome-cs-education with instructions on contributing at https://github.com/zamansky/awesome-cs-education/blob/master/contributing.org.

I seeded it with a few items but I'd love everyone to get involved. I also started it with a few categories and a specific format but I'd love to see that evolve into something most useful for the community as well.

If you agree that this could be something useful, please contribute to it and help spread the word.

Using Emacs - 34 - ibuffer and emmet

A couple of quick, unrelated packages today.

first up, ibuffer. If you keep Emacs open all the time, you'll start to accumulate buffers. Last time, I talked about using projectile and how that can help when navigating between buffers. IBuffer is another one.

Out of the box, C-x C-b is bound to the Emacs list-buffers command. It brings up a buffer with all the buffers listed inside it. You can navigate that buffer and hit enter on a particular buffer to go to it. You can also mark buffers and then operate on all the marked buffers. Hitting h in the list-buffers buffer brings up more details.

IBuffer is like list-buffers on steroids. It looks much nicer and I think it has more functionality (again hitting h in the buffer brings up help).

IBuffer really shines though, once you start customizing it. I found this post by Martin Owen which shows how to customize the way ibuffer appears. You can group buffers however you want or even omit some from the listing.

Here's my configuration (mostly stolen from Owen):

(global-set-key (kbd "C-x C-b") 'ibuffer)
(setq ibuffer-saved-filter-groups
      (quote (("default"
	       ("dired" (mode . dired-mode))
	       ("org" (name . "^.*org$"))

	       ("web" (or (mode . web-mode) (mode . js2-mode)))
	       ("shell" (or (mode . eshell-mode) (mode . shell-mode)))
	       ("mu4e" (name . "\*mu4e\*"))
	       ("programming" (or
			       (mode . python-mode)
			       (mode . c++-mode)))
	       ("emacs" (or
			 (name . "^\\*scratch\\*$")
			 (name . "^\\*Messages\\*$")))
	       ))))
(add-hook 'ibuffer-mode-hook
	  (lambda ()
	    (ibuffer-auto-mode 1)
	    (ibuffer-switch-to-saved-filter-groups "default")))

;; don't show these
					;(add-to-list 'ibuffer-never-show-predicates "zowie")
;; Don't show filter groups if there are no buffers in that group
(setq ibuffer-show-empty-filter-groups nil)

;; Don't ask for confirmation to delete marked buffers
(setq ibuffer-expert t)

The video also shows emmet mode. A terrific mode for quickly creating HTML and CSS. I tried it a long time ago when it was called zencoding and found it lacking but after watching this video at Build Fun Things I started playing with it again. It's a real winner.

Here's the config I'm using:

(use-package emmet-mode
:ensure t
:config
(add-hook 'sgml-mode-hook 'emmet-mode) ;; Auto-start on any markup modes
(add-hook 'web-mode-hook 'emmet-mode) ;; Auto-start on any markup modes
(add-hook 'css-mode-hook  'emmet-mode) ;; enable Emmet's css abbreviation.
)

Check them both out:

CS Educators StackExchange

The CS Educators StackExchange is now in public beta. For those of you who are not in tech, StackExchange is a network of question answering sites. StackOverflow is probably the most famous - many peoples go to site for computer science and programming questions and answers.

During this period of public beta the site will be working on defining itself and also on developing a critical mass of users. I hope the site succeeds and I encourage everyone to check it out, ask questions, answer some and let's all see where this goes.

An interesting difference between StackExchanges and most other communities is that it's a question answering site not a discussion board or shared resource collection. This works well for programming questions where you can share a code snippet, algorithm, or derivation which can be shown to be correct. We'll see how it works for something more nebulous like education. The voting system should help but the CS education community is already awash with anointed thought leaders with little or no teaching or CS experience. It will also be interesting to see how things develop given that, by and large, K12 educators know a whole lot more about teaching than those in higher ed while the on the flip side, the professors are generally much more knowledgeable about the subject matter and then you have the education researcher which is another beast altogether.

Part of me thinks that discussion could be more valuable than answers and in fact, I'm finding the comments which are more discussion like to be more interesting, but that's just me.

A side thing I noticed was that the moderators have taken to asking contributors not to link to other sites but to either write self contained answers. I understand this desire to have everything under your roof but it strikes me as wanting to use their silo instead of someone else's silo. This happened to me on an answer because I had already written a series of blog posts on the subject. Admittedly, I just put up four links and could have (and will) provide more context but I also had no desire to rewrite my content just to share info that was already out there. Likewise there was a question that was posed on A* which led to this post. I wanted to share my thoughts with "my" community as well as on the stackexchange and didn't want to have to do the same thing twice.

One of the moderators claims is that a link might not be permanent. This is true. My blog might not be around in 5 years but then the CS Educators StackExchange might not as well. I hope both are around and thriving but time will tell.

This also got me thinking about the mish mash of CS Educator communities floating around. I'm familiar with and a member of:

  • A few Facebook groups (CS Education, CS Education Discussion, AP Comp Sci, APCSP)
  • The CS Education subreddit
  • A couple of mailing lists (the College Board AP Community, SIGCSE)
  • A few blogs are kind of communities in that there's a core group of readers but discussion is pretty sparse.

Are there others I'm not aware of?

This has led to a lot of duplication and some fragmentation and there is a concern about silos. The Facebook groups are very much a silo and to a certain extent so are the mailing lists. I guess the SIGCSE list is more community run than the College Board one, but still. Blogs are our own personal islands so while I wish more people would both blog and comment about CS Ed they're not necessarily open and permanent either. At least with some blogs and with the subreddit and stackexchange we can, if we want, download all of the data if we want and preserve it for posterity.

I don't know if there's a solution - maybe we should set up a discourse instance - something really open and accessible.

In any event, please do check out the CS Educators StackExchange and let's all help it become the best question answering resource it can be for our community.

Disclosing Bugs - requiring a project roadmap

Over on Facebook, a fellow CS educator 1 made a comment on something he wanted to try with his students this summer: having the students pre-disclose bugs when they submit their projects.

The post was asking for any links to "the literature." I can't speak to that but I I've done something similar to what the post was asking about so, as per usual, I thought I'd write about it here. It may not be "research" but I'm more interested in teacher practices than ivory towers anyway so here goes…

At a very basic level, I ask my students to provide a roadmap to any project they submit - usually in a readme file. I basically ask:

  • How to use the project
  • What's cool and I should make sure to check out
  • What doesn't work, where were the sticking points and what's the status.

I tell my students that when I test the project, I'm not "out to get them" and by their telling me how to navigate the project, it makes sure I see things in the best possible light. I also tell them that I will be more harsh on bugs that they don't tell me about - particularly bugs that only occur some of the time.

I also encourage (and sometimes require) that students maintain a changelog in their repo and also sometimes encourage them to have a todo list and list of bugs and for longer projects, I expect to see these and the readme updated over the course of the project (which should always be up to date on GitHub, Dropbox or wherever the project is living).

When the students provide a good write up it makes evaluating the project much easier.

When students buy in, they're hopefully thinking more deeply about their projects in terms of design and implementation and also from the point of view of someone else using their product. When they maintain the readme and other files over time, it also enables me to better support them.

So, does this work? Yes but with some caveats. It works better once the class and teacher know each other. If the students trust the teacher they're more likely to be open and honest when they write up the project. On the other hand, there will always be some students to "phone it in" and do the bare minimum in terms of writing up their projects.

The bottom line is that having the students do this is has a low cost and is beneficial to both the students and the teacher. When it works, it's great and when it doesn't, it's still pretty good.

Footnotes:

1

I'm not sharing names from the Facebook post because it was made in a semi-private forum and I haven't asked permission.

A* is born

Over on the CS Educator StachExchange, which is in private beta for a few more days, I saw a post asking about how to introduce the A* search algorithm.

I taught A* as part of the APCS class at Stuy so I thought I'd talk about what I did here.

Some time around mid year, we get to intermediate recursion. This is about the time, give or take, when we talk about the nlogn sorts.

We also build a recursive maze solver. It's a nice algorithm and a nice little program. It's around 15 lines of code to perform a recursive depth first search:

dfs.gif

The basic algorithm is:

/* solve the maze from an x,ylocation */
solve(x,y){
  if (we're at the exit)
    Yay! We found the exit
  if (we're at a wall or a visited space)
    return (to previous step)
  else {
     mark current space as visited
     solve(x+1,y)
     solve(x-1,y)
     solve(x,y+1)
     solve(x,y-1)
  }
}

It's a nice lesson because in addition to all the recursion stuff, we also get to talk about state space, state space search, backtracking, efficiency concerns and much more. After we finish the maze solver, we also talk about other problems that can be similarly examined using state-space search like the knights tour and N-queens problems.

A month or so later, when we're learning about stacks and queues as data structures, we revisit the maze solver. This time we solve the problem in a more general way. We talk about using a data structure to hold the set of nodes that we're aware of and that we want to visit next.

add start node to data structure
while data structure not empty{
  current = remove item from data structure
  if current is goal, return (we're done)

  for every node adjacent to current that isn't yet visited{
     mark that node as visited
     add node to data structure
  }
}

As we write the solution, we see that using a queue for this data structure yields a breadth first search:

bfs.gif

while using a stack yields depth first.

All of this leads to a discussion as to how deciding on which locations to look at next can greatly influence the steps to the exit. From here it's easy to see that you can use a heuristic to order the nodes in our data structure so that we explore "better" possibilities first. The data structure becomes a priority queue and we finally get to both "best first" and A* search:

astar.gif

It's a nice sequence of lessons, albeit lessons spread out over months. The end result is that the students see both the need and motivation for something like A* and they see that it's not hard to implement. One basic routine where you can plug in one of three data structures - stack, queue, or priority queue to get very different results.

Python - Editor or IDE

Earlier today I read Garth Flint's latest post on choosing a Python environment for his classes. While our classes and populations are different it looks like Garth and I share a lot of thoughts on the subject.

I started to write a comment to leave on Garth's blog but since it was getting a little long I thought I'd write it up as a post.

The question of development environment can be an important one and can make a big difference. When I designed the intro course at Stuy, the fact that Dr. Scheme existed made the use of Scheme in the class an option. Without it as a supportive and simple environment for the students I probably wouldn't have been able to use Scheme even though I really liked it as a teaching and learning tool.

Garth writes about issues relating to choosing a local development environment so that's what I'm going to stick to here. If you want an online environment check out Codesters - a terrific online Python environment with lots of educational support materials and features and repl.it - an online environment that supports many languages and is also developing great teacher and class support – I very much like both of these platforms.

The first question is editor or IDE?

As a user, I'm very pro editor. Learn a tool that you can customize to your tastes and that will work for all sorts of text editing chores from coding to document preparation to scheduling and more and you're in great shape. Personally, I'm an Emacs wonk but there are other choices as well.

As a teacher, though, Emacs or another programmers editor can be overwhelming for younger students and rank beginners.

This can make IDEs attractive.

Some IDEs are too big and cumbersome and can add even more cognitive load than an editor - think Eclipse for Java development. If you think writing

public static void main(String[] args)

is a lot of overhead, just wait until you have a novice try to start a Java project in Eclipse.

Other IDEs are more streamlined. One common choice is Idle. It's big advantage is that it's always available and is "part" of Python. On the other hand, it doesn't seem to add much to a bare editor and I've found that it can be somewhat confusing.

Garth seems to have settled on PyCharm from JetBrains. It's pretty streamlined and really easy to get up and running. JetBrains also provides a free community edition as well as a heavier professional one available for purchase. Garth notes that it's a Python only IDE but JetBrains has similar IDEs for a whole bunch of languages and I seem to recall you can add plugins across their IDEs to basically make them multi-language development environments.

I really like the JetBrains products and if I used an IDE I'm pretty sure I'd use their products. As a teacher though, I find their IDEs a little too powerful for my tastes. I want a learner IDE to provide the bare minimum of features - an interactive REPL, a code window, run and debug buttons, some completion and help - but to make those features really easy to use. JetBrains does a little too much.

What I ended up using in the past is Dr Python. For me it hit the sweet spot. As an added bonus we were already using Dr. Racket (nee Dr. Scheme) and Dr. Java so our students had a similar environment across languages and even NetLogo looked and behaved similarly.

Is there a right answer? Probably not. Just as with choosing a first language there are always trade offs. Besides, if you don't have the right solution, there will be another one next week. Just recently I saw this project. A new beginners IDE for python. It looks interesting and worth checking out.

The right IDE can make a big difference while keeping the overhead low and giving just the right amount of support. For me, the last time around it was Dr. Python. For Garth, it looks like PyCharm fits the bill. Looking at the overall plan, I usually start the kids off with a simple learners IDE and then transition them to a programmers editor like Emacs as they gain more comfort and experience.

As a postscript, let me share these links on how I use Emacs for Python development (each with a video) as well as my series on how I use Emacs in general:

Designing a course with constraints

One of the hats I wear at Hunter is to build a new CS Honors program and to bring my particular brand of insanity to Hunter College CS as a whole.

Yesterday was my last class for the semester so I thought I'd write a bit about the course.

For the Fall semester, I taught an intro programming course to the entire cohort. For some in the cohort, this was their first exposure to CS. Others had one or more classes under their belt. It was a Python based programming class and a big part of it was to start building the cohort into a community. I'm going to work on tweaking what I taught for next time around but the constraints of designing such a course are pretty common – an intro course where the students all want to be there the level of previous experience varies to some degree.

Second semester was more of a challenge. The "next" course was CSCI 135, CS 100 - like APCS but in C++. I could teach that but since some of my students had APCS credit, they didn't need 135. This would break up the group. There was also the issue of the students getting credit for the course without showing any proficiency in C++.

Fortunately, Hunter requires students in 135 to take CSCI 136. A 1 credit programming lab. It meets once a week in a computer lab and the students complete a weekly programming assignment. The lab meets for 2 hours. The instructor goes over anything that's needed for the lab that hasn't been covered yet and then the students work independently (with the instructors support) on the lab. Overall it works well. It makes sure the students are spending at least a couple of hours a week coding in a supported environment.

How did 136 help me? I taught a 3 credit course where 1 day was basically the lab component (what the students were to do in 136) and one day was enrichment - the stuff I was going to do with them. This enabled us keeping the cohort together and it also made sure that by taking the class, the honors cohort members with AP credit would indeed get up to speed in C++.

I was happy with the basic structure. I was able to cover some topics in project development, testing, debugging, and software engineering but the designing and teaching the class proved to be challenging for a number of reasons.

One was timing. The lab class meets 1 day a week for 1 hour. My class, 2 days a week for 1 hour 15. This meant that if we were to keep the lab to one day either the students would have less time or I'd have to impose on them to stay late or come early. I wasn't happy with that but given the inconsistency in the way the other sections handled lab timings, I think it worked out OK.

Some of the other difficulties included:

The language was C++:

Since the labs were to be done in C++, I had to use that as the language for the class. That meant no "fun" libraries or frameworks.

The labs were solo assignments:

Since the labs were solo projects and there was one per week it made it very difficult to structure group experiences. I wanted to cover things like group development, code review, working off of other peoples code bases but this proved difficult with an outside separate lab being handed down each week.

Someone else dictated the language sequence:

The labs were designed to support what the students were learning in 135 and were only distributed a day or two before the week was to start. This meant that I couldn't plan too far ahead and had to adjust frequently. This should be easier next year.

Labs didn't match the supplemental material:

The best example of this was when we were talking about testing. We ended up using Catch as a testing framework. The problem was that right afterwards the lab (and also 135 project) didn't lend themselves to using a testing framework like catch.

There were more challenges but overall I think the class went fairly well. I'll know more when I get feedback from the students and when we all look back next year with some perspective.

It's been an interesting experience designing a class that had to interleave with another, existing class. I've designed many classes over the years and I know that whatever you plan, it probably changes once you're actually in the classroom and working with the kids, or as Mike Tyson said: "Everyone has a plan until they get punched in the mouth." This has been a little more of a challenge but I think the first go through went well and that the course will get better and be better defined as we go through a couple more iterations.




Enter your email address:

Delivered by FeedBurner

Google Analytics Alternative