Being productive between terms

We're now at the end of my first semester at Hunter. The Spring term classes don't start until the end of January. I've got an assortment of projects to work on but some of the students should have a nice block of relatively free time.

I wanted to share some recommendations on things to explore with a few student groups and thought it would be easier to write those recommendations down here once and then just share a link.

So, here we go.

Much of the first few CS classes at Hunter and elsewhere focus on the fundamentals of programming, data structures, and algorithms. It's all good stuff but students want to supplement that classroom knowledge with some practical skills.

I recommend playing with a language like Python that can be used in all sorts of domains. If you haven't played with it, check it out.

I like Automate the Boring Stuff with Python as a nice, free, online text.

I'd also recommend learning a web platform like Flask. Flask is a web framework in Python. The web site has a nice getting started guide and tutorial but here are a couple of other great learning Flask resources:

Once armed with the above, you'll be well positioned to work on a variety of your own projects, enter hackathons, and more.

I'm also a big believer in using good tools. I love the emacs text editor. Why not spend some time going through the web series on Using Emacs.

Finally, if you're not using Git, you should be. Here are a couple of playlists to get you started:

And if you haven't done so already, head over to Github Education and sign up for a student developer pack.

So, there are a few recommendations on things to work on before the next term begins.

Enjoy

It gets easier (or advent of code 2016 day 19)

Today's Advent of Code problem was a variant on the Josephus problem.

I recalled that there was a formula to figure out the sole survivor but I decide to run a simulation rather than looking it up. I also decided to write it up in C++, well, really C with cout instead of printf.

Part 1 was the traditional problem. Part 2 was a variant where at each iteration, you remove the elf opposite the elf being processed (see the problem description for details).

For both solutions I coded up a circular doubly linked list:

struct node *make_ring(int size){
  int i;
  struct node *n;
  struct node *current,*first;

  first = (struct node *)malloc(sizeof(struct node));
  first->id=1;
  current=first;

  for  (i=0;i<size-1;i++){
    n=(struct node *)malloc(sizeof(struct node));
    n->id=i+1;
    n->prev=current;
    current->next=n;
    current=n;

  }
  current->next=first;
  first->prev=current;
  return first;

}

You can see my complete solutions here.

I was thinking about how I wrote the code – I just rolled it off the top of my head. The same was true for the earlier AoC problems where I had to implement a breadth first search or something similar.

I'm not making a statement about my amazing coding abilities - linked lists and graph searches are pretty basic, but rather than having done the CS thing for so long, these fundamentals have become somewhat routine. I haven't really written C code in years but other than a couple of typos (and a stupid mistake in calculating steps) things worked right off the bat.

I remember a time when I was in college or even a young professional when I would use an array and an index as a stack or queue - not because it made more sense but rather, because I wasn't fully comfortable with memory manipulation and linked lists. The same could be said for my first few years working with anything more than the simplest recursion.

All of this is to say that it does get easier.

Things that seem trivial to us now seemed insurmountable when we were beginners. Last year, I wrote about an overnight homework assignment I gave to my class that would have been a final project a year earlier (the post is here but the homework links are no longer active) and a few weeks ago I recall a fellow CS teacher talking about how much longer it takes his students to write a chunk of code than it takes the teacher.

New things are challenging and take time but with practice and persistence techniques that were once daunting can become tools ready at our disposal to use on a whim.

A couple of things I learned from Danny Jaye

I got an email from my good friend and mentor this weekend. Danny Jaye, after 45 years, is finally retiring for real.

Danny, the Maestro, or Doc, as we sometimes called him spent most of his career at Stuyvesant. First as a math teacher, then math chair. Danny also spent time as the director of the Bergen Academies and his last few years as the Chief Academic Officer at Solomon Schecter in Bergen.

Danny's always been a master teacher - back in the day, he managed to teach Calculus to my brother - no small feat and as a department and school leader, he has a great eye for collecting and developing talent. Over the years, Danny's influenced a number people who've gone on to be education leaders of one form or another.

For me, Danny was and continues to be a great mentor. I can't tell you how much I learned - much of it on our 5:00am bike rides from Stuy up to the GW bridge and back.

Far too much to share here but let me drop a couple of thoughts:

It doesn't cost anything to be nice.

and the related:

It's easy to be nice on a good day.

The former talking about treating everyone with respect regardless of station and the latter a reminder not to forget it on a bad day. Also a valuable reminder when sizing up new school leaders.

We'd spend hours discussing class, departmental, and school strategies. How to develop a program with safety nets, how to separate real value from the hypes and how to always remember that it's the student first and the big picture, not just our little corner of the world.

It feels weird for me to know that my go to guy on Ed stuff is no longer working and is now moving towards a life of leisure.

It doesn't change anything other than a reminder to me that I'm now one of the more senior people in my circles and that now Danny can mock me for having to go in to the office every day.

So, here's to you Danny – one of the best education people out there.

Rookie Season Redux

Today was the last day of classes at Hunter thus ending my first semester of teaching at Hunter College.

I very much enjoyed the semester and my class and look forward to working with the same group when the spring term starts in a few weeks.

At the same time, even though I'm a quarter century veteran teacher, in many ways this was like my rookie season all over again.

My class was an honors intro class so the material wasn't new to me but there were a number of adjustments going from high school to college.

I taught a few college classes as an adjunct back in the nineties but I was a young teacher at the time and that was a lifetime ago.

The biggest difference is that we only met two days a week. Monday and Thursday and we met for 1:45 rather than 45 minutes. The longer class is nice but the twice a week means that you don't get that every day reinforcement you have in high school.

It also means that there were times when we would go a week between classes due to a single day off.

The biggest challenge, one that I'm continuing to work on, is figuring out how much we can do in a class, what and how much to assign between classes and what's the best way to motivate the student's to space out the work while doing something every day.

That wasn't much of a challenge at Stuy. Having been there so long, I had a good feel for my students as well as the pace and rhythm of Stuy. Hunter has it's own rhythm and pace and I'm still figuring it out.

We also had to pivot early on as the student laptops didn't arrive until a third of the semester was over.

On the other hand, much of my work these days has to do with developing the overall honors program as well as Hunter's forthcoming teacher education programs in CS so I'm only teaching a single class right now and it's small.

If there are any rookie teachers reading this, congratulations on getting through your first semester. I know you guys go a little bit longer, but you're in the home stretch.

Teaching right, particularly in public schools with large classes will always be an all in activity - certainly harder and more draining than anything I ever did in industry but it does get easier as you learn your school and students and develop your craft.

Advent of Code 2016 - Check your data

I'm spending the weekend up in Michigan. Visiting my brother and is family. We're here to see the UMGASS production of Gilbert and Sullivan's The Sorcerer. Batya also came up from Cornell to join us so the two families are all togehter for the first time in about 10 years.

This hasn't left much time for Advent of Code but I did manage to finish yesterday's challenge this morning.

What took me so long? Much like last year, it was because I'm an idiot.

The problem seemed pretty straighforward. I coded a solution and it worked for all the test cases. I tried it on my data set but the grader said the answer was wrong. I went through the problem a number of times as well sa my code. I figured I either mis-interpreted the question or had some bug. I found neither to be true.

After some frustration, I went over to the Advent of Code subreddit grabbed a couple of posted solutions (trying not to look at them) and ran both on my data - those solutions got the same answer on my data set as I did.

This morning, I asked Batya to look over my code and the problem (it's always good to have a daughter that's smarted than you are) but she saw no problems.

Finally, I emailed my buddy JonAlf since I know he completed the problem. He sent back his answer along with his data set and I got the same answer as he did on his data.

What could be the problem.

His data set was about 12k characters long, mine was 4k. Something had to be wrong here. I went back to the Advent of Code site and grabbed the data set again. This time, I went to the page and did a "save-as" to save it - last time, I cut and pasted.

The cut and paste version was 4k, the save-as was 12k. This time it worked and was accepted and I also finished part 2 in short order.

The moral of the story – make sure you check the integrity of your data set - you'll never get the right answer if you're working with the wrong data.

In case anyone's interested, you can find my AoC code here.

A Teacher looks at Advent of Code 2016 #2

Today we're looking at Advent of Code 2016 number 2.

To change things up, I thought I'd do a video where I live code a solution.

The solution I present is pretty straightforward - use a 2D array (or technically, an array of strings) to represent the keypad, parse the input, and follow the input instructions to build the code.

One of the things I really like about Advent of Code is that every problem has two parts and depending on how you solved part 1, you may or may not have extra work to do for part 2.

A couple of years ago, I wrote about one of the coding techniques I try to convey to my students. The idea of changing the data to take away edge and special cases.

Part two of this problem is a perfect time to use that technique.

Here's the video, I hope you enjoy it:

A Teacher looks at Advent of Code 2016 #1

I recently posted about Advent of Code - a series of programming problems relseased one a day. While they vary in terms of level of difficulty, a number of them make nice problems for introductory to mid level programming classes.

I thought I'd share some of my thoughts on a few of them starting with the first problem from this years competition.

Take a minute to read it over.

At first glance, it might seem to a young programmer that this problem requires a two dimensional array - all about (x,y) coordinates but then there's a problem - there are no limits on coordinates and we can't make an unlimited size array.

After thinking a bit, hopefully the programmer realizes that all they need to do is keep track of the how the (x,y) location changes over time. In the solution below, we start at (0,0) and count the steps as we update two variables x and y.

When we finish processing the moves, we have our current location in (x,y) and we have the number of steps taken to get there.

The solution below hsa a couple of niceties that a beginning programmer might not know or use (and I'm not arguing that what's written is superior in any way, it's just what I ended up writing).

I make use of tuple destructuring:

x,y = (0,0)

which assigns x to the first item in the tuple and y the second. I used that a number of times

I also use a list I call dirs to hold dx and dy values for the four direcitons:

dirs=[(0,1),(1,0),(0,-1),(-1,0)]

This made it easier to to update the location based on the 4 directions. I could also have just used if statements.

Here's all the code:

x,y = (0,0) # assume our starting location is 0,0

# we start with d=0 -> facing north
# as we turn left or right, we can just increment or decrement d
# and dirs[d] will give us the appropriate dx and dy to update
# our locatoin for the next step
dirs=[(0,1),(1,0),(0,-1),(-1,0)]   
d=0

# This is only needed for part 2  - We track visited locations
# by adding them to the dictionary. If we try to add a location
# that's already been visited we know that we've found our final 
# location
# locs={}  # uncomment this line for part 2


totalsteps=0
for i in l:

    # the first char in i is the direction to turn in (L or R)
    # the rest represents the number of steps.
    dir=i[0]
    steps=int(i[1:])

    if dir=="L":
	d = (d+1)%4
    else:
	d = (d-1)%4
    (dx,dy) = dirs[d]
    for i in range(steps):
	(x,y) = (x + dx, y + dy)
	totalsteps=totalsteps+1

	# Uncomment this block for part 2
	# each time we have a new location, see if it's already in
	# locs, if it isn't, add it.
	# if it is, we're visiting somewhere twice so we're done.
	#if ((x,y) not in locs):
	#    locs[(x,y)]=1
	#else:
	#    print((x,y))
	#    print(abs(x)+abs(y)) # the answer
	#    sys.exit(0)
	#    break


print(x,y)
print(abs(x)+abs(y)) # the answer

Overall, a nice little problem for beginning and intermediate students.

Using Emacs - 24 - Org Capture 2

Not much in today's actual post. The video is a continuation of the last one on org-capture.

The video goes over how I set things up to pop up a new frame to do a capture even if emacs isn't on screen (as long as it's running) by hitting F1. I would have preferred to bind to C-c c - the same as within emacs but I havn't figured out how to do that in Ubuntu or Mint Linux yet.

Here's the elisp code for the configuration file to do the heavy lifting. I can't for th elife of me remember who's blog I found it on. If anyone knows, please leave a comment - I'd like to give credit where credit's due:

(defadvice org-capture-finalize 
    (after delete-capture-frame activate)  
  "Advise capture-finalize to close the frame"  
  (if (equal "capture" (frame-parameter nil 'name))  
    (delete-frame)))

(defadvice org-capture-destroy 
    (after delete-capture-frame activate)  
  "Advise capture-destroy to close the frame"  
  (if (equal "capture" (frame-parameter nil 'name))  
    (delete-frame)))  

(use-package noflet
  :ensure t )
(defun make-capture-frame ()
  "Create a new frame and run org-capture."
  (interactive)
  (make-frame '((name . "capture")))
  (select-frame-by-name "capture")
  (delete-other-windows)
  (noflet ((switch-to-buffer-other-window (buf) (switch-to-buffer buf)))
    (org-capture)))

The command I bind to the keyboard shortcut in my window manager:

emacsclient -ne "(make-capture-frame)"

There will be a third capture video in a few weeks where I'll talk about scheduling and agendas. Right now, I'm playing with org-gcal to sync with my Google calendar and want to figure out a config I'm happy with before making that video.

Advent of Code 2016

Once again, it's time for Advent of Code - a series of small programming problems released once a day.

I wrote a bit about it last year and you can still find last years problems here.

It's only day three but so far, all of the problems look really nice for students in APCS-A or any similar intro course. I'm thinking of looking at a couple of the problems this week with my class at Hunter.

I didn't think about this much last year but one thing I really like about the competition is that each problem comes in two parts. You're first presented with the problem and the input and once you put in the correct answer, you're presented with part two.

This can be annoying at times, particularly when it requires a large code rewrite but it also means that well designed, not too specific solutions are rewarded.

It's not quite the same as changing the specs on a project mid way but it does encourage thinking about more than just solving a super specific problem.

Check out Advent of Code and see if it's something you or your classes might enjoy.

Selling out or getting a seat at the table

The other day, a friend posited a question on Facebook (paraphrased):

If called upon, would you take a job in an administration who's policies you strongly disagreed with?

Would you go work for an administration that you reviled in order to get a seat at the table? To try to affect change from the inside or would you consider yourself a sellout or worse, publicly promote positions you disagree with.

Tough question.

The original question implied national level positions. I've never and will never breath such rarefied air but I have had such experiences closer to ground level, both with DOE projects and also in conversations with some charter chains.

My take?

Anyone that knows me knows that I've had various dealings with the NYC DOE and also knows that those dealings never resulted in outcomes I was happy with. Over my time at Stuy, I had many philosophical differences with Tweed (a common nickname for the NYC DOE as they're housed in the old Tweed courthouse) and these were times where I tried to play nice to have a seat at the table.

Once I was at a meeting that also included a number of tech industry heavy hitters. After the meeting, one came over to me. He knew me by having worked with my former students. I knew him by reputation. He asked "do they really want our thoughts on this or are we just here so that they can do what they wanted in the first place and then parade us out to say that they consulted experts in the tech industry?" I honestly didn't know at the time but I had my doubts as to the DOE's sincerity in being open to either my views or this CTO's As it turned out, they just did want to parade us. Later in the process, I was told in a back room that it would be wise of me not to publicly voice my thoughts about the direction of one particular project.

So there you have it. I was given a seat at the table but only as long as my views mirrored the views of those in power. Not really much of a seat.

I've also sat down with some charter chains - chains that I've been more than happy to denounce publicly. Why did I take the meetings? Mostly to find out if I was mistaken in my position and if so, maybe I could help them. Every time I've had such a meeting, however, I've left the table with my feelings unchanged and knowing that I would never willingly help them as I felt their practices were harmful to kids.

In one case, I took the seat but failed to affect change. In the other I refused the seat. I'll always take a meeting and I'll always work with someone who wants to help kids and who has an open mind but I've found that the more powerful the player, at least in education, the more likely they are to just want confirmation of their own bias.

You might get a seat at the table but you also might end up lending your reputation to a cause you don't believe in.




Enter your email address:

Delivered by FeedBurner

Google Analytics Alternative