# Teaching recursion early? Make sure to use a good tool.

I replied this tweet yesterday and thought I'd expound a bit.

We introduced recursion very early in our intro course at Stuy and I think it worked well. In that course we started by using Racket (nee Scheme) as the first programming unit. Originally we started the kids out first using NetLogo or StarLogo and followed with Scheme but after a few years we switched the order.

I wouldn't always recommend Scheme for a first course and in fact frequently don't but given how the Stuy course was introduced and developed it made sense and worked.

Was it worth doing things this way? I think so. Prior to that intro course becoming a requirement I got to see students coming in from different pathways to APCS. Some came in raw with zero formal experience, some self taught, some through that intro course and some having taken another more traditional intro programming course or experience. The kids who started on Scheme had no more difficulty mastering loops and iteration but had an easier time getting to the more advanced recursive techniques. This wasn't a surprise - it wasn't their first rodeo. This also jived with reports I read at the time that felt that when students did recursion first, iteration was just as easy but when they did iteration first, recursion was harder.

You can of course make a strong case that recursion isn't necessary for a kid that isn't going to study more CS. I'll merely argue that what we did at Stuy worked with that population and I wouldn't change it. At the same time, I've helped a number of teachers design classes and programs where we agreed that recursion first was not the way to go.

In any event, it wasn't that I specifically wanted to do recursion early but rather, there were a number of things I wanted to do with the class for which Scheme made sense and recursion was just one of them.

Some reasons to like (or for some, to dislike) Scheme early:

• It's functional – everything is a function. While this is technically not true, we can fudge it a bit at this level. You put things in parens so instead of add(a,b) you write (add a b) or really (+ a b). You can also do (+ a b c). Things that would be statements are also functions: (if Booelean TruePart FalsePart) is the if statement. For example `(if (>= a b) a b)` returns the larger of a and b.
• Because it's functional it avoids the issue kids have with `=` being for assignment rather than comparison.
• It has great support for list processing.
• Recursion is much more natural.
• It's a super simple language with simple rules and a simple, small syntax

Of course, Scheme isn't perfect and some people dislike the above reasons. It's also easy to come up with a number of other good reasons not to use a language like Scheme.

On the recursion front, it makes things much easier. There are no loops so recursion develops as a natural form for repetition:

```(define f (lambda (x)
(* x  (f (- x 1)))))
```

This defines a function that takes one parameter and returns `x*(x-1)*(x-2)...`. It repeats, but never ends. This leads to adding a base case:

```(define f (lambda (x)
(if (< x 2)
1
(* x (f (- x 1))))))
```

Which is your basic factorial function.

Since this use of recursion for repetition develops naturally as we introduce language concepts it's easier for kids to get their heads around it as opposed to when they've seen loops already and have an "easier" alternative. You can make the case that you could introduce recursion this way in a language with loops like Python but once loops are available and particularly when loops are idiomatic, students will find them and getting them to think recursively will be more difficult.

Scheme and most other functional programming languages also have strong support for lists and list recursion. This means you don't have to limit yourself to mathy problems. Think about a todo list:

1. Go to the market
2. Buy a gallon of milk
3. If they have eggs, get a dozen (heh heh)
4. Go home

Processing a todo list is really a recursive problem:

1. If the list is empty you're done
2. Take the first item off the list
3. Do it
4. Recurse

Once you start working with lists, you can play with all sorts of recursive examples.

At the end of the Scheme unit the big project is creating a sentence generator. The kids don't know it but they're learning about grammars and in fact are writing a recursive descent parser - they just think they're writing a program that creates silly sentences. It's a really nice project that uses recursion in a way that's different and I'd argue more fun and interesting than the usual approaches.

I chose Scheme for a variety of reasons. I also chose NetLogo for specific reasons. Unlike Scheme (or most other popular learning languages), NetLogo is really all about agent based parallel processing. There are concepts that we can explore easily and in depth with NetLogo that would be tremendously difficult in any other language and at the same time, there are things that are easy to explore in other languages that Netlogo doesn't lend itself to.

So, in the end, this post really isn't about when to teach recursion. It's more about how languages lend themselves to solving different problems and teaching different concepts in different ways. If all you have is a hammer, everything looks like a nail. Fortunately, we can do better.

# Is Cs for All Worth Doing

Last time I mentioned the pushback on CS for All. While many people are all in for CS for All, resistance is coming from many areas. There's resistance from teachers of other subject areas, people who think it's merely job training for the tech industry (which it can be if done poorly), people who feel it will be implemented at the expense of other important subjects already on the chopping block like music and art, and others.

When I started the intro course at Stuy I tried to design something that would be of value to all Stuy students and also inspire some to continue on to more advanced CS classes. The class has been a requirement for well over a decade at this point. I know that not everyone loved the course but as they say, the proof is in the pudding. It clearly got more people into the pool as gender numbers for our more advanced CS courses got and remained much better since the intro class became a requirement. I can't tell you how many people now in tech have told me that they never considered CS and only got into it from our intro course.

So, we had CS for All at Stuy before there was a CS for All and if exposing more kids to CS was the only benefit it would have been worth it but there's more. In addition to getting more people and more underrepresented people into tech, I've had scores of kids in a huge range of fields come back to exclaim the value of having been forced to take our intro course. These kids became authors, lawyers, entrepreneurs, (non CS) teachers, journalists, venture capitalists, Wall Street people, (non CS) professors and researchers, and more.

The benefit of being in the latter stages of a career is that you can look back at years of results and see the good and the bad.

There's no doubt in my mind that the battle to get a good CS course to every Stuy student was one worth fighting and winning.

# Should CS for All be implemented at the college level?

There's been a lively discussion on pushback to CS for All at the K12 level over on Facebook. Mark Guzdial started a sub thread asking if CS for All should first be implemented at the undergrad level rather than K12.

It's an interesting question and as good as anything to get me out of my month long non-blogging rut.

Mark was right when he said that if Colleges implement CS for All, K12 will likely do so to follow - just look at AP. Colleges have been saying that students should take more AP classes (while giving less credit) and we all know where that's led.

On the other hand, can colleges really do CS for All, what does it mean and what would it look like.

Much like there is no single K12 - it's 50 states and who knows how many independent school districts, there won't be a single CS for All at the college level but let's think about how things could play out.

Many colleges have distribution requirements. Students must take one course from bucket A, two from bucket B etc. Many schools that I've looked at already count CS courses in one of their distribution buckets. This doesn't mean every student will take CS but in theory means they can. Colleges could in theory create a required CS bucket or even a required CS course but I don't think it's as easy as that. It might be at a private institution but while I don't know all the ins and outs of Hunter's governance rules I do know that adding a universal student requirement is a HUGE undertaking.

So my take is that while it might be easy for a private college to add a CS requirement I'm guessing other public institutions are more similar to Hunter and it's not going to be an easy task.

Regardless, let's say we have a required class on the books. Will we have the capacity to teach it? It seems that schools are struggling to deal with their existing CS majors and running sufficient electives and courses for them. Just a month or so ago there was an article about a college ending its CS minor due to lack of resources. It doesn't sound like a radically different problem then that faced in K12. Maybe it's harder given that at least in NY, there is room for a required CS course if you can find the teacher.

Even so, assuming we have the capacity to enroll every undergrad in a CS course what would that be? I think most people would be in agreement that it shouldn't be CS 101. Maybe existing pre-major courses but even there I don't know if that's always the best path. There could be a great pre-major course to give students the basics and lead some into the major but what about a CS course for students in majors that need some deeper but focussed programming skills. The appropriate course for them isn't the same as a general/pre-major course. Using Statistics as an example, at Hunter, many majors require a statistics course which is off loaded to the Stats department. Each major has slightly different requirements. Over years, the end result is a course that it seems that nobody is happy with - a least common denominator course. CS for All at the college level could give us a least common denominator course that doesn't serve anyone.

Now, if you have the resources, none of these are issues. A well heeled private institution can run tons of sections of specialized classes no problem but this means just like on the K12 level we'll get the CS for All tale of two cities that I see coming in NY where the rich schools have good programs and the poor get a substandard experience.

With all of this said, I'm finally getting to the big red flag with college CS for All and it's an issue that everyone conveniently ignores. I'm talking about teacher quality. One of my big takeaways from SIGCSE is that college faculty are well behind K12 teachers in terms of pedagogy and I don't see this changing anytime soon. This is to be expected given that professor's career advancement is really based on research. Having a good teacher is always important but it's even more important for non-major students since a student in the professor's major will at least be passionate about the subject area. To me, this is not a recipe for success.

One can certainly make the claim that we aren't any better off right now at the K12 level because we don't have teachers who know either the subject nor how to teach it and at least at the college level they know the subject matter. This is very true and it's why pre-service CS teacher preparation is so critical to getting this right even though it will take time. That's something that both Mark and I have been vocal about but more on that subject next time.

# Is there room for CS for All

A fear revolving around CS For All concerns where will the money come from and how will we fit in the new classes.

One suggested solution is to integrate CS into other subjects. I thought I'd write today about why I don't think the fear is valid and while integrating CS into other classes can have value, it probably isn't a long term solution for CS education.

Let's start with the integration solution. The idea is to bring CS into an existing class. Bootstrap, a program I've written about before and one of the programs I like does this, primarily in Algebra. The idea is that this supports the student's learning Algebra while exposing them to CS. It's a nice program but a math teacher using Bootstrap shouldn't be confused with a computer science teacher. They're bringing some CS to their student and engaging the students in a different way mathematically and that's all great but in general you can't take two classes worth of material and concepts and fit them into one class and the number of teachers who are truly knowledgable in any two academic subject areas both in content and pedagogical content knowledge is few. I'm guessing that one of the reasons that Bootstrap works in Algebra is the alignment of the toolset and Algebra and how you can teach it. The other is that Algebra is frequently given more time for fewer topics. In some struggling schools, students might have two years of algebra or a double period so there's time to add in some CS.

I'm all for cross curricular work. You can look at applications of science in math classes, do mathy work in a CS class, run stats and data analysis in math and CS classes on materials from History classes and all of this is great. You can even create great combined curricula where you do indeed teach multiple subjects in an integrated way but to think that you can take what is typically taught in two different classes and you can combine both so that they're taught in one class with one teacher sounds fishy to me.

So, at the end of the day, if you go the integration approach you're either going to have to dedicate a similar set of resources both in time and personel to having independent courses. The alternative is that CS will be the second class subject.

So, let's look at actually bringing in CS For All as a separate course.

Here are the New York State Graduation Requirements 1:

Subject   Number of semesters
English   8
Soc Studies   8
Science   6
Math   6
LOTE   2
Arts   2
Phys Ed   4
Health   1
Electives   7
Total   44

It can be difficult to fit Phys Ed in since it has to be offered every semester so let's double the Phys Ed requirement to 8 semesters. What is actually normally done is to have 7.5 periods of science a week and 2.5 periods of Gym.

This means that the basic student program uses 48 class slots and includes 7 elective slots.

In terms of exit exams, students have to pass the following Regents:

• English
• Any single math (Algebra, Geometery, Alg 2 / Trig)
• Any single Social Studies (US History or Global History
• Any single Science (Living Env (bio), Chem, Phys, Earth Science)
• Any additional Regents exam

The requirement of passing a single Math regents is what leads to the extra time allocated to Algebra that I mentioned when discussing integrating CS into Algebra above.

To get an Advanced Regents diploma you have to pass additional exams - both history, all three math, three science and maybe more.

Using a Typical 7 period plus lunch day, we have room for 56 single semeter classes in a high school career. This means that assuming students aren't failing too many classes, even with the extra Phys Ed allocation I mentioned above we can easily fit computer science into our day. In fact, we can technically fit in four full years assuming a student doesn't have to repeat any class.

So in New York state we certainly have the time but what about the budget? That's not an issue either. The state also requires that students recieve 5.5 hours of instruction a day exclusive of lunch. At 47 minute periods, that translates to students being assigned 7 instructional classes a day which means we can't just give the kids the required 44. We have to fill all 56 available class slots over those four years.

Of course it's not really that simple. Students fail classes and have to repeat them and some classes might be assigned more time than others but it looks to me like we should be able to fit computer science in without any big budgetary or scheduling changes. The challenge will be finding the teacher and working the internal politics and policies since as computer science comes in it will mean removing some electives even if those electives are additional years of science, math, or English.

Programs like TEALS and Bootstrap are important transitional programs and even when we do have qualified CS teachers they will play an important role - TEALS in providing industry support and resources and Bootstrap by integrating curricular areas and over time as preservice programs start to appear the rest will work itself out.

## Footnotes:

1
The state lists by credits which are a year, I doubled the numbers to map to semesters

# Unfunded Mandates and CS For All

This morning, Mark Guzdial wrote about unfunded mandates and CS for All. Unfunded mandates frequently wreak havoc on schools in a number of ways but in the long run, I don't think it should have a severe effect on CS for All. Rather, it could have a big impact on the number of CS courses we offer beyond that.

Mark relay's a story from the Cambridge Rindge and Latin School where at the time many students wanted more CS classes but the school wasn't planning on hiring a new CS teacher. The money quote is:

Over 50 percent of students signing up for Level 2 [computer science] courses next year identify as African Americans,

No, I'm not talking about the diversity issue raised by the quote, I'm talking about Level 2 [computer science]. This implies that the students already had Level 1 computer science. Level 1 would cover CS For All so now we're talking about CS electives vs other electives. This is something I had to deal with for most of my career even after we got a CS requirement at Stuy. It was always a battle to hire enough CS teachers to meet demand. The hard part was politics - there were always older more entrenched subject areas who would rather force kids into their electives rather than allow them to take my CS electives. This is a whole other kettle of fish than CS for All. It's an issue for some schools now and will become a BIG issue in five to fifteen years when a single CS required course is more the norm. The issue raised here is a new CS elective vs entrenched teachers and classes which shuld lead to a discussion of the relative value of CS electives vs other electives. That said, the reality is that it usually comes down to school and local power and politics. Also to be considered is the potential ebb and flow of interest - there might be demand for 5 more CS classes and 5 less something else this year but there might not be next year and then we're in real trouble staffing wise.

Schools, public high schools in particular are zero sum endeavors. You have a fixed number of periods a day, specific class requirements, and certain mandates as to a the minimum and maximum number of classes a student can take. In New York City, I believe students are required to have a "full" schedule which basically means they can't come in for English, Math, and History and then go home.

With CS for All, you're basically allocating reallocating some amount of time to computer science. It might be hard to find a qualified teacher. particularly in a small school where the population won't support a full time CS teacher and it might ruffle the feathers of the teachers that will be losing the time but it shouldn't make much of a dent or really any dent on the budget.

Mark also raises the possibility of embedding CS into other subject classes. Bootstrap is a program that I'm rather fond of that does just this in Algebra classes (although more recently they're working to branch out into other subject areas). Even though I'm a big Bootstrap fan I don't think that's the answer to CS for All or CS in the high schools in general. I think that one of the reasons why Bootstrap works so well is the alignment between the CS tool they use and the way Algebra is or can be taught. Another reason is the fact that while Algebra is the lowest level of the traditional high school classes, it's frequently the one for which the most time is allocated. Students in low performing schools might take Algebra over two years or have a double period. This won't be the case for other subject areas. What this means is that there's more likely extra time to embed another subject, cs, into the Algebra class. Long term, embedding CS into another subject area requires:

• a teacher that really knows both subjects
• enough time so you can add all the cool CS content while still preparing the students for both the next level of whatever subject you're embedded in as well as for whatever standardized assessments come at the end of the year.

As I said, I'm a Bootstrap fan but I don't think that's the answer for CS in K12.

Back to the original topic there are certainly issues with implementing CS for All but I don't think school funding is the biggest hurdle. For me there are other big challenges. One is having a supply of qualified teachers. In the long run as states outline CS requirements and pre-service programs crop up this will work itself out. Until then, yes, we will have an issue and yes it will take some funding for stop gap and transitional teacher preperation. A second issue is working the internal politics. Adding CS does mean removing something else or more likely a piece of something else. The third one is what I'm noticing in NY where CS for all seems to at times forget about the CS. If we have knowledgeable teachers we can work around that one but I still think that might be my biggest concern.

# Pull Requests and Other People's Code

One of the things I've heard for years from former students - both those looking for jobs and those looking to hire is that colleges don't really do a good job preparing students for careers in tech. Sure they teach the algorithms and the theory but ther are a lot of missing pieces, particularly on the practical end. I'm certainly not advocating turning CS programs into coding schools but there are many low cost opportunities to bring practical real world best practices in to the CS classroom. I most recently wrote about unit testing and had earlier about using GitHub as an educational tool. I've been happy with the way I introduce students to Git and how we use GitHub in my classes but I've never found a smooth way to introduce Pull Requests. A pull request is basically a mechanism by which one can suggest a change to a project even if you don't own it. The project owner can then decide to merge it in or not.

Being comfortable with the pull request work flow is an important part of contributing to open source projects. The basic process is that you make a copy of the project you want to work on by forking it, make your changes, then issue a pull request back to the project. For a beginner, there are a lot of moving parts. Instead, I teach my students branching and merging within a project. It's much easier and arguably more useful for day to day projects. I'd like my kid to learn the pull request mechanics but I haden't thought of a good way to do it.

I've also wanted to give kids more real world experiences in class and one experience they rarely get is working in other people's code bases. In school you largely write your own projects be they group or solo or work off a hopefully tried and true code base provided by the instructor. In the real world you're frequently working off of someone elses code and it's rarely in a polished state.

I finally found a way to kill both birds with one stone. A couple of weeks ago my class' lab was rather lengthy. It involved reading in a source file and reformating it in a sensible way. I knew most of the students wouldn't finish it in the allotted time and even if they did, this was an easy assignment to extend. On lab day I had students create a new repo for this lab (normally they just add a folder in a their "labs" repo) and get as much done as they could. The rule was simple - push what you've got up to GitHub at the end of class and then you can't push anything else. I also made it clear that I didn't expect a completed lab..

We continued the lab in the next class session. This time. I randomly assigned repos to students so that they would fork someone elses lab. They then had to complete the lab on the other students code base and then issue a pull request back to the original

This was the first time I've tried this so it was a little klunky. I'll do a much better job specifying the assignment and instructions next time around but even so I think the class went well. By the end of the class the students had sucesfully forked a project, issued a pull request, and merged one in to their own project. The only think I wasn't happy with was that many of the merges happened automatically. I have to figure out how to set things up so that there are merge conflicts since I want my students to experience that.

Overall, I was very happy with the way things worked out. The students were able to experience important real workd software engineering techniques without removing any of the academic CS in the class.

# Do the students finish the tests or does the test finish the students

I tweeted this the other day:

What led to the tweet was a discussion I was having with some students about not having enough time on tests which led to a discussion of having to drop everything to spend every waking hour on a project.

### Let's talk about tests.

I'm not saying that tests are the best forms of assessment - most of the time I'd much rather have students work on projects. There are, however, times when tests make sense or are otherwise appropriate.

In any event, writing a test is hard. Rather, writing good test is hard. It's certianly easy enough to put a bunch of multiple choice or short answer questions on paper and it's easy enough to give a hard equation to solve or some code to write but creating a good test is a task and half. You first have to figure out what you're trying to assess - memory, thought process, synthesizing concepts? Then you want to construct questions that give you insights into your students knowledge and thought process.

Some things that I consider when putting together a test:

• Does it ramp up in difficulty - that is, are there some "gimme questions" and some challenges.
• Are questions all or nothing - if a kid doesn't see things my way are they dead in the water.
• Will the test repeatedly penalize or reward the same concept over and over again on the test.
• Do I cover all the concepts I want to assess.
• Do you make kids waste time with boilerplate code.
• Do the questions take so long to read and digest that there's little time to form and write down answers.
• Do the answers convey anything about the students thought process or just correctness.
• Is it easy or impossible to grade and grade fairly.

What about length? To me a well crafted test should be completed by the average student with a few minutes to spare - enough time to check a couple of answers. This is not to say that they'll ace the exam, just finish it. Far too many teachers make tests an assessment of speed and accuracy at speed rather than understanding. That might actually be important in certain contexts - preparing for the APCS-A multiple choice section as an example but in general, it's not a good way of assessing what a student really knows.

It's also important that the the average student can achieve a score that you expect from an average student. That's probably in the 80s on a 0-100 scale or a B. Yes, I know, C is supposed to be average but with grade inflation being what it is…

You should NOT give an assessment where the average score is something like 17 out of 100 with the top student earning a 37. Sure, you can curve it but it also places a lot of stress on the students. You might do this from time to time - you might misjudge the difficulty of a test or your class but it shouldn't be a regular occurence. Teachers sometimes forget about the psychological affect that a unfair test can have on a student even if the teacher "fixes" it after the fact.

### Don't be afraid to experiment or have some fun.

It's also ok to try different things. One year, having just completed a unit on Cellualar Automata I decided to give a quiz. I figured it would take the kids 10 to 15 minutes so I gave them 30. The quiz was something like the following:

You have 30 minutes to compose something on a sheet of paper that when I review it convinces me that you know something about the Cellular Automata Unit we just completed.

Some kids loved the quiz, some hated it. The ones that hated it had been trained for years as expert standardized test takers and this level of freedom really freaked the out.

### Tests to drive instruction and future practice

As a final point to ponder, tests shouldn't only be about grades. A well crafted test should drive instruction. Kids will get answers wrong - will your questions be crafted so that you can gain insights into why the got them wrong.

In an early class you might notice things like:

• kids printing rather than returning answers
• kids not understanding scope
• kids having difficulty with idioms like `i=i+1`
• kids needing more scaffolding to approach a problem

This can drive instruction moving forward.

Over time you'll also learn how to fine tune your tests and other assessments.

### Next time, we'll talk about projects

Unless of course I get distracted by another blog topic or shiny object.

# Using Emacs 48 Silversearcher

A couple of days ago I wrote about on my lab grading workflow. In the post I mentioned that I used Emacs to easily navigate between student folders and files so I can actually look at their work in addition to their programs output and test results.

The key is a combination of `dired` and ag, Emacs's interface to the Silver Searcher which is something like a recursive code grep on steroids. I also briefly try to show wgrep in the video which allows you to edit Emacs grep buffers, effectively allowing you to make changes across a set of files all at once. It ended up not working with silversearcher - if anyone out there knows why, please chime in.

Enjoy:

# No Magic Bullets - Discovery Learning

The most recent NYC CSTA chapter meeting was "How do I assess CS?" I wanted to go but it's been such a crazy month I was just too wiped out. Fortunately, the meetup was recorded. I was able to watch the first half this morning while working out on my stationary trainer which leads me to today's rare Saturday morning blog post. The meetup consisted of two panels. The first was made up of K12 teachers who taught CS. I can't talk about the second panel yet since I'm only halfway through but there were a couple of points made by my friend Katie Jergens who teaches at Dalton that I thought were worth talking about.

The first was when Katie noted that through working with the panel, one of her takeaways was that:

Giving students an explicit strategy for solving a problem - "this is how I would do it….," - giving them an explicit strategy first and then giving them a problem for which that strategy would apply is much more effective than having them discover it on their own.

This was refreshing to hear after being beaten over the head on discovery learning and constructivism for the past five or so years as being the magic bullet for teachers. I shared more thoughts on this a few weeks ago when I wrote about a SIGCSE paper presented by Bootstrap World that I very much liked.

Katie went on to talk about how the group found that while "discovery learning" can be effective it can also be frustrating and lose kids along the way. It also takes a lot of time and preparation, something that's short on supply in most public schools.

This made me think about the recent flurry of discussion around the debunking of learning styles which had previously been the magic bullet. When I started, the secret sauce was cooperative learning.

Of course any good teacher knows there's no magic bullet. You fill your tool belt and chest with as much as you can and use what's best based on your strengths as a teacher combined with what will work best with your students.

Another point that Katie made that I found refreshing had to do with something she does with her classes. A good portion of a student's grade is based on what she calls a "booster." Each student has to work one on one with her on some project. The student either scores a 0 or a 100 - the student keeps working with the direct support of the teacher until it's perfect.

The important thing that Katie said with respect to this is "I can do this because my largest class is sixteen students." No way could this ever scale to a public school where a teacher can meet with over 150 students a day and barely has time eat lunch let alone work one on one with a student in a suitably quiet place like an office. The refreshing thing to hear was the acknowledgment of the fact that what works in a rich private school won't work in a public school.

All to often education and yes, CS Ed is driven by people who really have no clue. They're anointed as thought leaders but they don't walk the walk. Some have some knowledge and experience but many don't. Until you've gotten a few years under your belt in a strap cashed public school that takes all comers, don't tell them how they should do it. Katie didn't - she acknowledged the problem - too bad so many others don't.

I'm looking forward to watching the rest of the video during a future workout and might have more to share then. For now, take a look for yourself.

# Unit Tests Grading Workflow

I've talked before about unit testing (here, and here). My premise is that in addition to being an important industry technique, it's a sound practice for students studying CS. I also contend that it can make grading easier on the teacher. Maybe not as easy as an auto-grader but those have their own problems.

Since I spent most of today grading I thought I'd share my current workflow and how unit tests have made me more efficient.

I have each student make a single GitHub repo for all individual homeworks, labs and small projects. They'll make additional repos for larger and group projects. They fill out a Google form to give me the repo link. I download the form and end up with a CSV file something like this:

```Doe, John, git@github.com:johndoe/mymoework.git
Doe, Jane, git@github.com:janedoe/labs.git
etc.
```

My goal is to clone each students repo into a directory and then throughout the term, they add assignments to their own repos using the names and specifications I give them. For example, after assigning three assignments, I could pull everything from their repos and I would have a directory structure something like this:

```hw
├── doe_jane
│   ├── hw_01
│   ├── hw_02
│   └── hw_03
│
└── doe_john
├── hw_01
└── hw_02
```

To get there, I have to change the csv file to a small shell script:

```git clone git@github.com:johndoe/mymoework.git doe_john
git clone git@github.com:janedoe/labs.git doe_jane
etc.
```

I usually do this in Emacs with a macro.

Now I'm ready to go.

Whenever there's a new assignment, I just have to update all the repos. I go into the root hw directory and loop through all the subdirectoryes:

```cs /path/to/hw_root
for i in `ls`
do
cd /path/to/hw_root/\$i
git pull
done
```

At this point I could go into each repo but we can do better. Since I have all of my students submit a Makefile with a default target to build an executable named `main` and also a target named `tests` which will build an executable to run the unit tests named `tests` I do this instead of a straight pull:

```cs /path/to/hw_root
for i in `ls`
do
cd /path/to/hw_root/\$i
git pull
cd hw_03 # or whatever assignment I'm grading
make tests
make
done
```

Now, if I want, I can go into each directory, run the tests by typing `./tests` and the hw or project with `./main`. I can also add a couple of lines to the for loop above like:

```echo "\$i Test Report\n----------------\n" >> /path/to/hw_root/test_report
./tests >> /path/to/hw_root/test_rport
echo "----------------------\n\n"
```

This gives me a single file with everyone's test results. Either by doing this or by running the tests in each folder manually I can quickly see what works and what doesn't.

While I'm doing this, I have Emacs up and with dired mode and more specifically ag-dired-regexp which lets me easily navigate to any student's files. Combined with the test results I can quickly evaluate the entire assignment.

Put all of this together and it makes grading somewhat bearable. I can work through well written, correct assignments extremely quickly and drill down into the other projects efficiently as well.