On this page:
Software Development

Software Development

Software Development

I expect students to visit this page once per 24 hours starting with the first day of the semester.

image Wednesday, December 4th, 2019 8:59:31am

Even if you don’t couldn’t care about football (AE: "soccer") or sports at all, you will find this article on "language as a weapon" interesting, because it is your future.

Tuesday, December 10th, 2019 6:06:44pm

The End

Friday, December 6th, 2019 11:07:11pm

Here is the final grade computation in case you wish to figure out your final score yourself. Alternatively you may wish to study it as a rendered HTML document.

Wednesday, December 4th, 2019 8:58:53am

Basic Instructions

An hour before your final code walk, git-pull your repos.

During the final code walk you will
  • run ./xserver SOME_PORT < admin-test/NNN-in.json and we will connect to your server with clients using the same input

  • run ./xclients SOME_IP SOME_PORT < admin-test/NNN-in.json, which will connect them to our server at the specified IP address.

If we find bugs in your code, we may try to fix them.

Instructions for Code Walk: Plan A

Plan A may fail, in which case we will proxy through an off-campus machine for the final code walks.

Please read the following instructions carefully and test them before your appointment time.

Mac or Linux

In one terminal window, run:

    ssh -R 45678:localhost:45678 swdev@swdev.mballantyne.net

When prompted, enter password swdev12345


You may be able to follow the Mac and Linux instructions using the Windows Subsystem for Linux. Otherwise, you can use PuTTy.

If your Windows does not yet have PuTTy installed, download PuTTY via this direct download link.

Launch the downloaded executable. Enter swdev.mballantyne.net as the hostname. In the left-hand menu, open Connection -> SSH -> Tunnels. Check "Remote ports do the same". Then enter source port 45678, destination localhost:45678, select the "remote" radiobox, and click add.

Finally, launch the connection by clicking "Open" at the bottom right. Enter the username swdev and the password swdev12346 when prompted.


Please test the reverse tunnel as soon as possible, and visit Michael on Wednesday at his desk if you can’t get it working. Choose a random port between 40000 and 50000 in place of 45678 so you don’t collide with others. Once you’ve established the tunnel, you can test it by launching your server on your local machine, and launching the client with host swdev.mballantyne.net and the port you chose.

Instructions for Code Walk: Plan B

The above setup may fail for various reasons. If so, we will use Plan B.

Systems has opened ports numbered 10000 and above on the 31 Linux boxes ( vdi-linux-030.ccs.neu.edu to vdi-linux-060.ccs.neu.edu) so that you can connect to my desktop and vice versa. These boxes always come up on IP thru

Make sure to ssh into one of these Linux boxes, update your git repo there, and get its IP number.

Tuesday, November 26th, 2019 1:57:14pm

The final code walks will take place in West Village H, room 164 xor 164. The sign-up sheets will be posted on the door. Both partners must be present for a final code walk, so be there on time. Also bring at least one laptop that connects to HDMI or VGA.

Thursday, 05 Dec. 2019



Partner 1


Partner 2





























Friday, 06 Dec. 2019



Partner 1


Partner 2















































Monday, 09 Dec. 2019



Partner 1


Partner 2












































Tuesday, 10 Dec. 2019



Partner 1


Partner 2



























Friday, November 22nd, 2019 9:54:22pm

Integration testing is hard. It exposes mistakes that show up in time-based scenarios, complex scenarios, unusual scenarios, and so on. What they have in common is that several layers of functionality are involved.

How do you go about locating bugs that show up at this stage?

  • Pick failing problem cases that are “edge cases,” that is, cases with results that affect a major attribute.

    In our project, you want to deal with cases where the expected outcome does not list cheaters while the actual one does (and vice versa). Such a case has a more distinct edge than one where two rankings are swapped.

  • Simplify this case as much as possible. The visualize the problem.

    We have game observers and you can step through a single game and inspect the steps much more easily than you can step through complete tournaments.

  • Determine the edge transitions.

    Such transitions concern the player that is supposed to cheat (or not), and you need to find where it drops out or how it may continue to stay in the game when it clearly made an illegal move.

  • Turn such problems into failing tests as faithfully as possible.

    I made the big mistake of dropping the "white" avatar and keeping only the "black" one when I should have kept both. If I had, I would have almost immediately seen that the result state is marked as a collision state when it shouldn’t have. The rule checker treats collisions differently from specified cheats and thus interferes with them. I might have been able to fix the mistake in class if I had.

  • Derive unit tests from this first test case for all the functions that are called, especially those in lower layers.

    In my case, the actual mistake was three layers down, in board, and once the tests had been formulated for two layers down, it became obvious what was wrong.

Note that fixing such bugs may take careful touches at more than one layer in the end.

Wednesday, November 20th, 2019 10:28:03pm

A couple of students mentioned mid-terms and mid-semester projects to me during office hours. Since we do have some flexibility this week, I have pushed back the deadline for 10 — Remoting to Monday, 25 November, midnight.

I have also added some clarification and filled a gap that come up during office hours. The latter demands a very small new task. Hint The code for this task (reading a test input from STDIN and producing a STDOUT actual test result) mostly exist in xadmin. So it is at most a handful of lines of code.

Thursday, November 21st, 2019 1:42:43pm

The test fest for 9 — Cleaning Up produced extremely strange results. Only two pairs agreed on two instructor tests over the entire test run and no pair agreed with the instructor’s code base. Michael and I extensively reviewed my administrator, strategies, and rule checker. They are in sync with the specs.

Since making progress on this integration test is important for the success of the overall project, Michael has run additional small tests through your executables and sill push them out together with the results. You have until

Saturday midnight (as in 23 November 2019)

to turn in an improved executable for 9 — Cleaning Up and to get a second chance at the test-fest points. To do so, you need to email Michael and specify which additional test cases the revised executable passes. Michael will then re-run the test fest for those who have gone thru this second effort.

Friday, November 15th, 2019 4:29:30pm

It turns out that there was a miscommunication between me and the TAs for last week’s rubric. If the given README file specified the path of a file, there was no need for your WELCOME to repeat this path. Aditi and Dustin will fix the grades some time this weekend.

Thursday, November 14th, 2019 10:04:54pm

Two days ago Disney launched its streaming service. Here is how this stress test went.

Friday, November 8th, 2019 8:42:26am

Next week you will need to meet with the TA who is going to grade your homework 8 during his/her office hours (see Office Hours, Etc.). We will push a timely notification into your git repo.

On Tuesday I will post a listing of 10-minute time slots to see your TA. Then:
  1. Show up before the appointment time.

  2. Open the game observer module in your IDE.

  3. Start one of the games from the testing task in 7 — The Administrator.

  4. Demo the running game observer.

  5. Be prepared to respond to the TA’s questions and react to suggestions.

This is the only way to obtain points for your game observer.

Saturday, November 2nd, 2019 8:58:03pm

The make-up code review will take place on Monday at 10:30am in West Village H, room 366. See Lectures.

Thursday, October 31st, 2019 9:32:32am

Tomorrow you will receive email notifying of who your new partner is and where your new git repo is located. Please, immediately get in touch with your partner and set up a joint work schedule.


A number of students complained to me and/or the TAs about the past rubric. Here are some basic notes on why we checked certain points and what went wrong:

In general, I don’t mind if you ask the TAs or me such questions. I do mind if you’re overly aggressive with my TAs and I am especially unhappy if it turns out that you have not done your “homework” and read up on the basics.

Friday, November 1st, 2019 2:21:29pm

During the code walk today, the question of while true came up and we did not analyze the question (mostly because I thought it was too subtle without comparison between actual pieces of code). So let me address this issue because it matters for your understanding. So here is the generative recursion for the administrator Both variants are pseudo-code, though the left version is just a slight simplification of my actual code. In reality my code also tracks cheaters in case we need this information later.

in Racket

in Python

; Player* -> (values Player* Player*)
; GEN REC may not terminate due to ...
(define (LOOP lop0)
  (define lop (re-sort remain* lop0))
    [(too-few-for-one-game lop) lop]
    [(enough-for-one-game lop)
     (define ranked (referee lop))
     (if (empty? ranked) '[] (first ranked))]
     (define games   (prepare-games lop))
     (define results (map referee games))
     (define remain* (top-2/cheats results))
     (LOOP remain*)]))



def run_all_games(lop0):

 '''GEN REC ...

    lop0: [Listof Player]


 lop = re_sort(lop0)

 while True:

   if oo_few_for_a_game(lop):

     return ...

   if enough_for_one_game(lop):

     .. referee(lop)

     return ...

   # run many games

   games   = prepare_games(lop)

   results = run_all_games(games)

   lop     = get_top_2(results)

As you can see the two variants—when written out with appropriate helper functions—look nearly the same. Many generative recursions (from Fundamentals I or II) show up as "while"+"worklist" algorithms, and the while+true+return idiom is a direct translation into languages where function calls aren’t implemented properly (so you that you are forced to re-work your proper design with the use of while or for).

Monday, October 21st, 2019 6:23:51pm

In response to a request, I clarified Ending a Game in Tsuro.

Monday, October 14th, 2019 5:33:19pm

For some reasons, the Saturday revision of 5 — Observing Players was not synced properly with the CCIS web server. Please re-visit and note the clarifications.

Friday, October 11th, 2019 5:29:23pm

Here are some essential announcements for the week starting Monday, Oct. 14:

Monday, October 7th, 2019 12:19:26pm

I have added some clarifications to 4 — The Rules (summarizing Piazza posts) and to Tsuro, A Local Protocol.

Tuesday, October 1st, 2019 9:06:05pm

General now comes with images so that you recognize the teaching assistants when you go to their office hours.

Saturday, September 28th, 2019 6:53:18pm

I hadn’t finished editing the tile-generating code on Friday for lecture, so I thought I’d post my Racket version of the code here. Please take a look to see where I add comments and where I rely on the name of the function, method, or module to convey an interpretation. Additionally, you may wish to study the algorithm itself, especially in case you struggled. Irrespective of the representation of tiles and edges plus the syntax of the solution, the essence should be similar.

Since we are given a test, let’s state it up front:
#lang racket
(module+ test (require rackunit))
(define TILES# 35)
(module+ test
  (check-equal? (length all-tile-types) TILES# "check number of tiles"))

Next we need a representation for edges ...
(module edge-representation racket
    ; type Edge
  ; type Edge = [List Port Port]
  (define edge list)
  (define edge-from first)
  (define edge-to second))
(require (submod "." edge-representation))

... and tiles, which we construct from a list of four edges:
(module tile-representation racket
    ; type Tile
    ; [List Edge Edge Edge Edge] -> Tile
    ; {Tile Tile -> Boolean}
  (require SwDev/Lib/or)
  (require (submod ".." edge-representation))
  (require Tsuro/Code/Common/port)
  (struct tile [lo4edges] #:transparent)
  (define (create-tile edges)
    (tile (sort edges <-port #:key edge-from)))
  (define (rotate-=? c1 c2-0)
    (or~ (equal? c1 c2-0)
         #:let c2-1 (rotate-tile c2-0)
         (equal? c1 c2-1)
         #:let c2-2 (rotate-tile c2-1)
         (equal? c1 c2-2)
         #:let c2-3 (rotate-tile c2-2)
         (equal? c1 c2-3)))
  ; {Tile [#:degree Degrees] -> Tile}
  (define (rotate-tile c0 #:degree (d 90))
      [(zero? d) c0]
       (define rotated-edges
         (for/list ((e (tile-lo4edges c0)))
           (define 90from (90degrees (edge-from e)))
           (define 90to   (90degrees (edge-to e)))
           (if (<-port 90from 90to) (edge 90from 90to) (edge 90to 90from))))
       (rotate-tile (create-tile rotated-edges) #:degree (- d 90))])))
(require (submod "." tile-representation))
My actual tile representation adds a mechanism for applying the tile to a port, as if it were a function, to retrieve the connected one. The data representation and its interpretation take half a laptop screen.

Now we can write down the algorithm for generating the 35 distinct tiles, modulo rotations by 90, 180, and 270 degrees:
(require Tsuro/Code/Common/port)
; generate all 35 unique tlle configurations
; {[Listof Port] -> [Listof [Listof Edge]]}
; for the given 2 * N ports, create list of all possible N edges
; GENERATIVE by removing 2 ports, we get closer to the empty case
[define (all-edges-for 2*n-ports)
    [(empty? 2*n-ports) '(())]
     (define from (first 2*n-ports))
     (define others (rest 2*n-ports))
     (for/fold ([result '()]) ((to others)) ; < loop collects gen.-rec. results
       (define the-edge (edge from to))
       (define n-ports  (remove to others))
       (define other-edges (all-edges-for n-ports)) ; < generative recursion
       (define with-edge (map (λ (1other) (cons the-edge 1other)) other-edges))
       (append with-edge result))])]
; [Listof Tiles]  
(define all-tile-types ; loop eliminates rotated tiles
  (for/fold ((set '())) ((lc (all-edges-for PORTS)))
    (define next (create-tile lc))
    (if (memf (curry rotate-=? next) set) set (cons next set))))

Monday, September 16th, 2019 9:40:23am

On Tuesday we will do some in-class software development. Please coordinate with your partner so that every pair has at least one laptop in class. Thanks.

Saturday, September 14th, 2019 12:20:32pm

I have modified C — Exploring Your TAHBPL Some More to fix a mistake, clarify a bullet, and explain some terminology that may have gotten lost in the lecture. While this terminology isn’t all that important, clear terminology is always helpful when all parties accept and understand it.

Friday, September 13th, 2019 6:00:42pm

Industrial people are slowly recognizing the downside of ticket-driven software development. Considering reading the Jon Evans’s blog post to get a sense of what these people are getting at.

Friday, September 13th, 2019 12:33:36pm

netcat (abbreviated nc) is the best way to manually send JSON information from your shell to your server:

    [login-faculty] $ cat test-input.json | nc login-faculty.ccs.neu.edu 45678

This command connects the cat command with the nc command via a pipe, a combination that is also available on your macOS. Specifically it sends the content of the test-input.json file to nc, which in turn transmits it to the computer with the IP address login-faculty.ccs.neu.edu at port 45678 (if all of you use 8000 on the same computer, bad things will happen).

Here is a demo screen shot from my computer:

In this example, I am using nc to send JSON from login-faculty to a computer called antarctica, also on the ccs.neu.edu network.

In the right shell window I start ./C up, waiting to connect with a single client. Then in the left window I first display the content of the test file to the shell, before I use the command combination from above to send it to the “server” in the right window. As soon as the server has done its work for the client, it shuts down—of course after sending back the correct answer to the client, which displays the answer in the shell.

Thursday, September 5, 2019 10:44:25am

Please prepare a letter-size sheet of paper by folding it lengthwise, writing down the name of your favorite programming language on one side and placing it in front of you on your desk. ~~ You will get the chance to build a large code base in this language so that the instructor’s taste in PL won’t inhibit your amazing programming skills.


Even Congress Doesn’t Understand Why Software Engineers Take So Long

Even Congress Can't Wait for Software