Sunday, March 22, 2020

Rails Project: What's for Dinner?

If I'm honest, Rails was the most difficult unit for me so far. I really, really liked Sinatra. I liked that at the end of my Sinatra project, I had a functional application and I could literally explain every line of code. I knew what it did, and I felt comfortable experimenting by changing it. As soon as we switched over to Rails, I felt like I no longer understood anything! Sure, it's possible in Rails to generate an entire app with basic CRUD functionality in seconds ... but what the heck is actually happening??? I found that to be a theme with Rails. Even now that I have finished my project, half of the files are still a big mystery to me. What exactly does database.yml do? What are all these initializer files? I've been told that this is the thing about Rails, that there's always more to learn and understand, to be patient ... but still, this is outside of my comfort zone. I like to understand all of the nuts and bolts.

Which is not to say that I'm not proud of the project I built! I called my application What's for Dinner? and it's designed to solve a most basic need of parents everywhere: finding kid-friendly weeknight dinners. Users can submit recipes, view recipes, filter recipes by category, search for recipes, and save recipes to a "recipe box" (as long as they have an account). They can also sign in through Google! (Let me tell you, after the headache this feature gave me, I will never take for granted being able to do this on any site I visit, ever again!)

Rather than walking through the entire design, I'll focus on a key understanding I gained through the process of building my project:

Nested Forms

These have been my biggest obstacle in Rails -- specifically, understanding all of the different form macros (form_for, form_tag) and using them to generate forms for nested attributes. After much trial and error, I think I finally understand the beauty of form_for!

In my domain, a Recipe has many RecipeSteps (something like recipe_id: 15, step_number: 1, content: "Boil water") and RecipeIngredients (a table joining ingredients to recipes, something like recipe_id: 15, ingredient_id: 12, quantity: "1 cup"). When a user wants to create a new recipe, I first ask them how many steps and ingredients their recipe has (an annoyance I hope will no longer be necessary once we learn JavaScript). I then use my RecipesController#new action to build a new Recipe and build the correct number of RecipeIngredients and RecipeSteps associated with that Recipe object:

Then, in my /views/recipes/new file, I can use fields_for to capture data for those nested attributes (RecipeIngredients and RecipeSteps). Note that recipe_form is the form builder object defined at the start of my form_for; i.e., <%= form_for @recipe do |recipe_form| %>

So what happens when the submit button is clicked, triggering the RecipesController#create action? Well, a new Recipe record is generated and then there is an attempt to save it to the database. But, this simple-sounding step - "a new Recipe record is generated" - is actually quite involved! In particular, the Recipe class has custom setter methods responsible for creating the associated RecipeIngredient and RecipeStep records while creating the Recipe object they belong to:

And that's that. Now that I've talked through it from start to finish, I wonder why it ever seemed to mysterious!

Thanks so much for following me on this coding journey. Please feel free to check out the repo for my Rails project here; I'm also hoping to "go live" with this project one day soon (once I've made some upgrades, of course!). Comments and suggestions are all welcome!

Thursday, February 13, 2020

Sinatra Project: Practice-It

I hesitate to say that I have "completed" my second project as part of Flatiron's Online Software Engineering Bootcamp. There are still some unresolved issues relating to connecting to a local host, and I have done absolutely no styling. (Starting to learn some CSS is on my agenda for break week!) However, I can proudly say that I have created an application that works and solves a real-world need of some sort. But, before we get to that...

Reflections on My Learning:

Databases were a big "a-ha" for me because all of a sudden I could imagine how companies store data related to all of the objects they create in the course of a day -- it's probably not in class array variables, but rather in tables that live in a database somewhere. Databases also solved the mystery of how information gets persisted, and further solidified my understanding of classes and objects. (In fact, I wish I had this analogy when I was teaching AP CS. There are some students who are confused about classes and objects all year, despite the 5,000 analogies you come up with. I actually think that the relationship between objects and databases -- that a table represents a class, and a row in that table an object from that class -- is one of the most student-friendly explanations I've heard!)

This was also been an exciting month because I've started to learn something that's totally new to me, which is how the internet works. I now feel comfortable with the idea that the internet functions because of conversations between a client (i.e., browser) and a server (the code that runs a specific website you're trying to load). Essentially, a client makes an HTTP request, the server runs some code (maybe code that future-me will write!) and sends a response, and then the client (browser) renders that response string into something visually appealing.

As we started to see how basic Sinatra apps are set up with models, views, and controllers, one of the big mysteries of my life became a little less foggy. When I taught CS, my kids would write programs in Java or Python that lived on their computer and could run through an IDE. They'd often ask me how you create websites that other people can interact with and allow your code to live somewhere other than your computer, and that's honestly something I was never able to answer (which is part of the reason I decided to go to boot camp!). I love the fact that I'm starting to gain a basic understanding of that process, and it's really the MVC framework that has been helpful for visualization:

  • Models are responsible for interacting with the data. In our Sinatra apps, these were written as Ruby classes, each of which was connected to a table in the database. The model classes were where we indicated associations between our objects (i.e., belongs_to and has_many), which are basically ActiveRecord macros that give us even more methods that we can call on objects from those classes.
  • Controllers are the middle-men. They contain routes that match HTTP requests (i.e., GET '/posts/new', which might result in a form for a new blog post displaying). Based on the request, the controller runs (Ruby) code that might redirect to a different route or render a view (something the user will see in their browser, like a form) using some information retrieved from the database.
  • Views are the front-end of your app (i.e., what the user will actually see on their screen). They are written in HTML and although they may display information from the database, they did not retrieve that information themselves! Instead, the "middle-man" controller got the necessary information and then passed it over to the view.
And in this way, we created a Sinatra app that is basically a lovely dance wherein the browser makes a request, the server processes the request and implements some logic in order to determine which view to render, and then digs into the database to find what it needs -- and then finally renders a view, which is all that the user will ever see. And this happens again and again. As I now visit websites in my everyday life, I'm amazed at how complicated -- yet how simple! -- it all seems. Complicated because I'm sure there are thousands of lines under the hood giving everything its functionality. Simple because, at the end of the day, it's all just HTTP requests and responses. Which finally brings us to the app that I created for my Sinatra project!

Reflections on Sinatra Project:

I was trying to come up with a "real-world" problem I could solve with my app, something that required managing a lot of content and giving users a nice interface for interacting with that content, when it hit me! As an AP teacher, I always had the following problem when it came time to reviewing for the AP exam: there are a ton of practice questions available for every combination of topics in the course, but it's really hard to keep track of which students have completed which questions. There is lots of other functionality related to this, like being able to easily access all questions related to a certain topic, or view all students who have completed a given question when you're looking for a good "peer tutor" for another student. So, I decided to create Practice-It, a Sinatra app for making an AP teacher's life easier during those critical review weeks.

I had a great time with this project, as it cemented for me a lot of the content we had been learning. It was also fun to think about an app from the perspective of a teacher user, since that's literally what I was until I started bootcamp!

It's hard to say for sure since I'm still knee-deep in the process, but I think I may have begun to clear a few hurdles on my way to becoming a software developer.
  • Workflow: I started to hit my stride in terms of an effective workflow. I set up a notes file in my project, which I used to record and categorize features I wanted to implement. I'd pick a feature, write a controller route that rendered a dummy view file, and then finally work on getting the correct HTML in the view file. After each component appeared to work even a little, I'd make a commit and push my code to GitHub. I'd then test the route out in the browser and use lots of binding.pry's to inspect what was going on from the console. After however many iterations that took, I'd make another commit, update my notes file, and then choose a new feature to work on.
  • Reading documentation: I spent a lot of time on Rails Guides learning about various ActiveRecord methods, as well as getting un-stuck on Stack Overflow. Stack Overflow used to intimidate the heck out of me -- I'd literally feel my anxiety level increase anytime I clicked on a post. I feel like our relationship is finally improving and, although I still certainly have trouble parsing through some of the responses, I generally feel like I can get what I need from it. 
  • Thinking about object relationships: Before this project, I had a basic understanding of object relationships (we focused on "is-a" and "has-a" in AP CS) as well as some of the ActiveRecord associations, like belongs_to and has_many. My project really clarified things like why I would ever need a join table (in my app, a student has many questions and a question has many students -- so I needed a join table to keep track of all (student, question) pairs) as well as the importance of thinking about all aspects of your program. For example, in the spirit of collaboration among teachers, all teachers in my app have access to all of the questions. However, every question has an "owner" who created it, and only that owner can update or delete a question. It was only after lots of fiddling around with various use cases that I came upon the question: what should happen to the questions a teacher "owns" when that teacher deletes their account? As a simple solution, I reassigned ownership of that question to another teacher in the database -- but it did get me thinking about some of the subtle questions that must come up when you've got lots of models with plethora of associations among them.
My next thought is to dive into CSS a bit so that I can make the user experience more visually appealing; I'd also love for teachers to be able to import student and question data via CSV files rather than having to manually enter it all into forms. 

I'll leave it at that for now, and invite you to check out the Practice-It GitHub repo. I'd love your feedback and ideas, and I really thank you for joining me on this journey!

Wednesday, January 29, 2020

Back in my Students' Shoes

Now that I am actually a "student" again, I could probably write dozens of posts with this title ... but this is the first time I've felt that head-spinning brain explosion that I suspect many of my math or CS students may have felt upon being introduced to a new topic that was heavy with both concepts and terminology.

Flashback to a typical AP Computer Science class for my students: I introduce some pretty rich content, demo some code, and have them write some code together. They do some legit troubleshooting, often using what they just learned, and then - Eureka! - by the end of the class period, they have something working and they feel good about it. The next day, they walk into class and I ask them to write an explanation of what they did yesterday, or connect the terminology to the content, and I get ... *blank stares*. Which always made me wonder, "Did they even learn anything at all the previous day???"

Of course, it was easy for me to stand on my metaphorical pedestal, having taught the content multiple times, and claim to students that they didn't truly understand something until they could explain it. I still think that is technically true ... but I also now see that there's a bit of a gray area where your brain may have started to make some significant connections, and is primed for deep learning, but is just not quite there yet. Which is all a long-winded way of saying that after a mind-blowing week of jumping into SQL, ORM, and ActiveRecord labs, I felt AMAZING about how MUCH I was learning ... and then I stopped to think about what these technologies actually are, and how they relate to each other, and I (like my students) had nothing.

So, here's my attempt to take a step back and articulate my understanding of these tools and their relationships to each other. Think of it as a little check for understanding that "teacher-me" assigned to "coder-me" before moving on.

SQL (Structured Query Language): The language of managing databases. It was fun spending a couple of days training my brain to thing along the lines of queries and "how do I access that piece of information I'm trying to find, that doesn't seem like it should be so complicated???" When we started learning about relational databases (i.e., tables with foreign key columns that relate them to other tables), the connection to object-oriented programming became clear: tables have relationships just like classes have relationships! Which brings us to...

Objected Relational Mapping (ORM): My understanding of ORM is that it allows you to access and modify a relational database using an object-oriented programming language (like Ruby). The big idea is that classes are mapped to tables, while individual rows in those tables are instances of the class they represent. This was a big "a-ha moment" for me: so far, everything we had been learning seemed to use toy examples and I still felt like something big was missing. For example, when instances of a class (like a Facebook user object) are created, are they really stored in an array called @@all??? Does an insurance company's software store its thousands of policies in a list??? I'm guessing not, and now I'm thinking these objects actually get stored in databases somewhere.

We were writing ORM's in Ruby, and the cool thing about these was that they used both Ruby and SQL so the connection between the object-side of things and the table-side of things was really transparent. To set this all up, we created a database in our environment file (that responsibility shouldn't fall to a specific class). We also created this special Ruby object that represented the connection between our Ruby program and the database we had just created.

Then, we were able to call the execute method on this special Ruby object and pass in raw SQL! This allowed us to, say, define a class method for SomeClass where we queried the table representing SomeClass to find a class instance with a specific attribute.

Just like with anything, after awhile, you get the feeling that you are doing a lot of work by hand that would be duplicated if you were creating an ORM for a different set of classes and a different database. Creating a table, saving instances to that table, and then finding an instance by an attribute all seem pretty standard. Which brings us to...

Active Record: Active Record is "just a gem" (this was emphasized multiple times) that gives you access to a bunch of standard ORM methods (create, save, find_by) you'd otherwise have to build from scratch. One cool thing about Active Record is that once you create a table called, say, users, that has columns for user_name and user_location, then your User class will automatically get instance variables corresponding to those columns! Pretty nifty, huh? (Although, I am grateful to have built some ORM's by hand first so that I could really see this relationship in a concrete way.)

Another feature of Active Record that blew my mind was the idea of creating class associations. Class associations are a concept I'm familiar with. When I taught AP Computer Science, my students did a bank account project and understood that "The Bank 'has many' BankAccounts" and that "a CheckingAccount 'is a' BankAccount", etc. Active Record lets you abstract these relationships using keywords like belongs_to and has_many that create those associations for you. Despite this being really cool, it's also not magical: what I've called "keywords" are really just "macros" that build methods for us - the same methods we'd be building if we were creating ORM's without Active Record!

Phew. Writing this all out was extremely helpful, and makes me remember that I can use my experience as an educator to benefit me as a learner. I'm starting to feel like those connections are becoming a bit more solidified and that that my brain is primed to fill in that next big hole -- How do you actually use all of this stuff to create an application that doesn't just live on your terminal and that other people can actually use???

Thursday, January 16, 2020

My First Coding Project: A Ruby CLI Application

I was a little nervous getting started with Flatiron's Coding Bootcamp. I knew that I enjoyed coding, but I had also been teaching the same introductory content for years and didn't know how I would feel once I left that little bubble. After completing my first project, I can say that it is an incredible high to have designed and written a program that uses a host of tools and concepts -- object models, interacting classes, a command line interface, data from an API -- and that someone else could legitimately use! It's a far cry from being "useful" in the real-world sense, and still leaves me with this gnawing question of "will I actually be able to create things that people are willing to pay me for?" but I do feel that this project was a big step in the positive direction. Here are some reflections on the process.

Using an API: Imposter syndrome is always an issue for me, and it is often triggered by hearing terms over and over that seem to mean something specific to everyone else but are confusing to me! Once of those terms has always been "API" -- I would hear those letters thrown around so casually and think that I must be the only one who doesn't actually understand what an API is. This project was a great way to tackle that head-on. My awesome instructors demystified the idea of an API as simply a way of communicating with a database, and modeled the process of playing with various API requests and the data they returned. I used this list of public API's to guide my research and wound up choosing Open Trivia Database's Trivia API.

Starting with the End Product: In teaching we call this "backwards planning", and I found it to be great advice in terms of getting past that blank-screen syndrome. Instead of starting by mapping out all of my classes and methods, I started high-level: by creating my command line interface. What did I want the user to see when they pressed 'run'? When they pressed 'play', what menu should appear? As I thought about this from the perspective of the user's experience, the necessity for certain methods just became super clear. (I love the idea of calling the methods you wish you had, and then going back and implementing them!) Once I had something working, I was able to go back and refactor my methods ... but it was much easier to think calmly and deeply about my program's structure when I already had some working code.

Creating Object Models: In previous labs, we had been told what attributes and methods our objects should have. This time, it was up to us to design our classes. It made sense to create TriviaQuestion objects out of the trivia question data I was retrieving. Most of my attributes corresponded with information I was pulling directly from the API request: every trivia question had a category, a difficulty, a question, etc. I had to get a bit more creative in terms of storing a TriviaQuestion's answer choices. The API returned a question's correct answer as a string, and its incorrect answers as an array of strings. For example, the following question:

has a correct_answer of "1984", and incorrect_answers of ["Catcher and the Rye", "The Old Man and the Sea", "To Kill a Mockingbird"] ... which is all well and good, but doesn't really help when the user types in 'A' or 'C' as their answer choice! So, I decided to create an answer_hash attribute in order store the (randomized) letters themselves as data, and associate them with their corresponding strings. This particular question would have an answer_hash attribute of:

The previous data structure labs were interesting but had left me wondering why and how I would organically create such a structure (like a nested hash) on my own. Hence the epiphany when I came to this part of my project!

Testing for Bugs: After some playing around, I decided that five was the right number of questions for these mini trivia quizzes. I was having a lot of fun testing my program and answering trivia questions from various categories, and it wasn't until I had done this about 15 times that I happened to hit a category that didn't have five questions for the difficulty I had specified (I believe I was looking for hard questions about gadgets?). I referred back to the API documentation and noticed that "the API appends a 'Response Code' to each API call to help tell developers what the API is doing." How convenient! As a solution, I decided that I would generate as many questions as possible using the desired category and difficulty, and then fill in the remainder with questions from random categories of the same difficulty.

In future iterations of the program, I'd like to enable the user to select multiple categories from which to pull questions. For now, I think this is an effective work-around that prevents a somewhat subtle bug from causing some unexpected behavior!

Being OK with "Smile and Nod": As I continue to embrace the beginner's mindset on my coding journey, I can't help but think about phrases I used to repeat to my high school AP Computer Science students (most of whom were coding for the first time). One such instance was on the first day of class, when they'd write their first Hello World program in Java. To get this one statement to display to the console, students would have to declare a class and a main method using public static void main(String[] args). This was literally gibberish to my kids and I tried to encourage them by telling them this was a "smile and nod" moment: although they had no idea what things like public and static meant, it didn't matter -- they could still write cool code, and if they kept on learning then one day they would understand things like public and static.

As a highly linear thinker, it can be difficult to take this particular advice myself. I like to start at the beginning and understand everything fully, in order. As we know, this just isn't always possible. One particular "smile and nod" moment for me in this project was noticing that the API calls seemed be returning strings with some encoded symbols. I did a little digging and decided that the easiest solution was to ask the API to return the data using what seemed like an even deeper level of encoding (base-64), but one that appeared straightforward to ask Ruby to decode using the Base64 module. I understand very little about encoding and literally nothing about base-64, but I'm proud that I forged ahead and patched up the problem rather than allowing it to consume me.

Saturday, December 21, 2019

Why Software Engineering?

Wow, it sure has been awhile since I've posted here! I thought about starting a new blog to document my software engineering journey, but then figured that the real start of my journey was my experience as a computer science teacher ... so really, it makes perfect sense to document that here!

This blog is definitely missing an account of the past several years of my professional life, so I'll start there. Until 2016, I was lucky enough to teach at one of the most amazing schools in the country -- a public charter school in Newark, NJ that has a true sense of mission and is doing fantastic things for its students and their families. Everyone at the school truly believes that education is freedom and that mantra imbues the work ethic that is evident from classroom to classroom -- from the teachers who put in countless hours reflecting on their lessons and putting those reflections into practice to ensure better outcomes for their students, to the students who bring incredible perseverance and focus, to the administrators who truly support classroom learning and create an environment that incents everyone to be their best.

Although I started out teaching math (and pure math will always hold a special place in my heart!) I quickly realized that teaching computer science was my jam. I learned to code by teaching AP Computer Science A and got such a thrill out of both my students' progress and my own -- I honestly remember struggling with the idea of a constructor in Java for months! As concepts started clicking for me, it was great to use my new insights (as well as an amazing AP CSA teacher community) to hone my lessons and design activities centered around conceptual understanding, especially since most of my students were totally new to coding. I found tons of personal fulfillment in my role, and was rewarded in a variety of ways - not the least of which was a Milken Educator Award in December of 2015 (if you're not familiar, the folks at Milken go above and beyond to showcase teachers and schools; check out their work here).

As my own family began to grow (I now have two little guys of my own), I decided to leave my full-time role and pursue various opportunities in education while spending more time with my sons. After awhile, though, I just felt like I wasn't quite finding my niche in education the way I had hoped. I also noticed that I was happiest at work when I was coding -- either coming up with new projects for my students, or learning something new myself. I just loved the intellectual challenge, and I would often get lost in code for hours at a time. At some point I had to just listen to that nagging voice in the back of my mind telling me that I owed it to myself to pursue coding as a career.

As a CS teacher I have a grasp of many programming fundamentals, but still lack an understanding of how those fundamentals get used in real applications (as opposed to, say, simple games that live in an IDE). After just two weeks of Flatiron School's coding bootcamp, I'm starting to get a taste for what those applications might look like. Last week, we wrote Ruby code to scrape a web page's HTML and use the scraped data to create and manipulate objects. Seeing code that I wrote interact with actual websites was kind of mind-blowing, and I know that this was merely the tip of the iceberg.

I'll admit that I'm nervous about leaving a field that I'm so comfortable in, to pursue a field that is a big unknown to me. I have lots of motivators -- primarily my own intellectual curiosity, but also my sons. My 4 year-old asks me constantly, "How did coding go today?" and I love that he gets to see mommy taking on this challenge. I will always be passionate about education and part of me hopes I will eventually find a way to marry education and coding -- whether that's back in the classroom, or by designing software to help tackle one of the many problems in public education. Perhaps I can work with an organization that's already doing great things, or maybe one day I can found my own. For now, I'm interested in learning as much as I can and broadening my perspective on how I can make even a tiny contribution to the technology industry.

Tuesday, February 18, 2014

Setting the Record Straight: My Experience at an Urban Charter School

I recently attended an education forum in Newark, NJ where two mayoral candidates spoke to several educational issues. Beneath the exterior of good old-fashioned debate, though, some well-worn myths about high-performing urban charters reared their ugly heads. We’ve all had that experience: the family dinner where you’re asked - no, told - for the umpteenth time that “students have to take a test to get into your school, don’t they?”, or the casual conversation where an acquaintance finds out that you teach in Newark and immediately responds in a sympathetic tone with some vacuous comment like, “It must be so difficult when the kids have so many other issues to deal with.” Education is a funny thing, because everyone feels like they’re a little bit of an expert. (Heck, we’ve all been to school!)

I’m all for discussion - but let’s get some facts straight.

First, a little about me: I am a math and computer science teacher at North Star Academy College Preparatory High School in Newark, NJ. I began my teaching career at High Tech High in San Diego, California - a project-based charter school that I loved and that continues to shape many of my classroom activities and goals for students. I am a product of a large, suburban public high school. I have my Bachelors’ and Masters’ Degrees in Mathematics, and took an “alternate route” to my teaching certification. I have been teaching in public charter schools for 5 years - and I am about 5 years overdue in writing a response to the incessant questions on the very existence of charter schools (based in varying degrees of fact), as well as unfounded attacks on methodologies employed by some of the highest-performing urban charter schools, like North Star. I do not speak for my school, for the “education reform” movement, or for anyone other than myself and my students who have turned themselves into into amazing, college-bound young adults with a little help from us. And so, the high-performing urban charter movement as I see it:

The Data Myth

Based on some of the scathing critiques of exit tickets I’ve read (see this rant by a former KIPP teacher), I have to come right out and say it: If you are that critical of the very idea of an exit ticket, then clearly you and I have different ideas for what an exit ticket is.

An exit ticket is just a way for you as a teacher to figure out what your kids learned in a given class period or series of class periods, and what they didn’t learn. It’s a low-stakes, immediate form of assessment that is used to inform your teaching tomorrow and next week, because goodness knows that not everything we teach gets “learned” the first time around. It’s an acknowledgement that, yes, while I might be teaching the same curriculum as I taught last year, I’m teaching it to a different group of students who are going to have different needs. How do I know their strengths and weaknesses unless I gather that data? Not on some standardized test at the end of the year. Not even on a unit test, or a weekly quiz. But sooner. That day. Why wait until a high-stakes assessment to figure out what your kids know?

For this reason, I am sure you can understand my confusion around the attacks on exit tickets. Call it an exit ticket or call it something else, but if you’re not assessing what your kids have learned before moving on, then what kind of teacher are you?

The Robot Myth

My students are not little minority robots, relegated to a classroom where silence, obedience, and multiple choice tests reign supreme. Instead, they are budding intellectuals, realizing the potential and the brilliance that all students of any race or socioeconomic circumstance have within them. On any given day, they are discovering the subtleties of object-oriented programming in Java through inquiry-based labs, debating a mathematical question in a hands-down discussion, or playing a ridiculously fun game to practice their Unit Circle facts because, yes, black or white, sometimes you just need to jump through some hoops to be able to get to the next level in life. In my English, History, and Science colleagues’ classrooms, you will be confronted with a similar level of intellectual engagement that would be astonishing even at a suburban school. Without reservation, I would send my own children to North Star.

Do we have systems that some perceive as “over-the-top” - a relentless uniform policy, daily homework detention, mandatory after-school tutorials? Yes, we do. And I assert, unapologetically, that those systems are the very means by which our students are able to achieve to the levels that they do (see above), and that similar systems would benefit any student, of any race or socioeconomic background. And yet, I understand the realities. If I were a teacher at a suburban school, I might not freak out to the extent that I do now if a student didn’t turn in their homework one day. Of course, systemic poverty is an ugly thing and forces us to be a little more relentless on our mission. Anyone who doesn’t acknowledge that teaching underserved students requires a different set of tricks, has clearly never taught an underserved student. Even Diane Ravitch would agree with that, right?

Bottom line: My students are not robots. I am not an ivory-tower outsider who is inherently disrespecting them and underestimating the unfortunate circumstances they were born into. On the contrary, I am committed to doing whatever it takes to unsurface the scholars - the budding philosophers, engineers, computer scientists - that lie beneath the sometimes-ugly picture that is life for a child in Newark, NJ.

“There’s nothing that charter schools are doing that public schools couldn’t be doing if they wanted to.”

I am paraphrasing a quote from Shavar Jeffries, a brilliant son of Newark who is currently the underdog in the race for mayor of that city. I am beyond sick of hearing complaints that the most successful charters are benefiting from an uneven playing field, from more autonomy that the public schools are allowed. The conclusion that some draw that we should all be subject to the same inefficiency (economic and otherwise), bureaucracy, and paralysis by teachers’ union that has sucked the education out of urban public schools is the true disservice.

Indeed, that conclusion is exactly 180-degrees incorrect. There are immediate, instruction-based changes that any school could be making in its classrooms tomorrow if it wanted to replicate some of the best practices of some of the best charter (or public, or magnet) schools - that’s something we do constantly at North Star, and it almost always results in more student learning. If it doesn’t, we stop doing it. It really is that simple.

Thinking longer term, a strangled public system that has proven a failure for our most vulnerable population should not be stuck in the status quo just because it’s not “fair” for some schools to be better than others. The system needs a slow, careful, and deliberate overhaul.

A “corporate agenda”?

Slow, careful, and deliberate is the name of the game. The best charters have been subject to so much criticism because they don’t immediately serve the highest-need students in the same quantities that public schools do. Factually, this is correct. Rather than a criticism, though, I see this as a necessary part of the reform process. You don’t perfect a long-term successful model by immediately subjecting it to the highest possible amount of stress. Instead, you start with a small test group - 50 kindergartners, say, or 25 fifth-graders - and you slowly expand. Because of the level of control possible especially at those early stages, you are able to experiment with systems and determine which ones work and which ones need to be changed. Six or eight years later, you find yourself serving 2,000 students, many of which are coming to you with significant challenges. Now, though, you are in a position to actually serve them using a model whose components have been refined and might just actually work.

This is how real, sustainable progress happens in any sector - technology, business, or education. And if that’s a little too “corporate” for your tastes, you’ll get no apologies from me.

Wednesday, May 15, 2013

Have an hour to fill with your students?

Something amazing is happening at my school right now: the kids are all abuzz over - WAIT FOR IT - the prospect of a computer science class next year! I mean, yes, there is also talk of prom and all other aspects of teendom, but for the past few weeks there has also been a tangible excitement over coding.

It started when my school decided to hold an "Academic Festival" - one day when we were encouraged to deviate from our curriculum, throw guided practice to the wind, and teach something that we are passionate about. I decided on a one-hour introduction to programming, which was really a thinly disguised pitch for the computer science course we'll be offering for the first time next year. I had my students warm up with a Do Now asking them to identify some of the many ways they rely on coding in their everyday lives, without even realizing it. I used this PowerPoint as a basis for our discussion, which led into this (now semi-viral) video put out by, and finally some live coding in Python (the Word Smoosher was a big hit). The anxiety I felt prior to this lesson can only be compared to the anxiety I felt nearly every day when I taught in a project-based environment: What if the kids don't find programming interesting? What if the lesson is a flop? What if we speed through the PowerPoint in two minutes flat and they have NO questions and they fall asleep during the live coding???

Of course, that did not happen - not because of anything special I did, but because my students had never before been exposed to the world of coding. In fact, I had to pinch myself at one point, when I announced to one group that there would be a coding class next year and they actually - no exaggeration - cheered wildly. "Okay," I thought. "They're really into it now. But they've never actually tried coding. What if they find it boring/frustrating/uninteresting?" 

I thought I'd have to wait until next fall to get that question answered, but just a couple of days ago North Star was lucky enough to be paid a visit by Jeremy Keeshin, cofounder of Thirty-two (out of 74) juniors from across the academic spectrum signed up for an after-school workshop that Jeremy ran to introduce students to some of the basics of coding as well as the terrific online platform for learning coding that he has developed. The program is such that students are able to watch short tutorial videos and work on challenges at their own pace, and Jeremy and I mainly circulated to help students troubleshoot -- what a great model for true differentiated instruction in computer science! In less than an hour, kids were already getting at some pretty big concepts softened only by the cuteness of Karel the Dog and the entertaining challenge names (Mario Karel!): "How can I teach the dog to turn right using ONLY turnLeft() commands?" "What if I want to make Karel move over and over - is there an easy way to do that?" 

When it comes down to it, what I'm feeling right now is probably what every teacher feels at some point - the magical epiphany that "A few weeks ago, my students didn't know [what programming was], and now they're [running home to work on coding challenges] and [saying that they want to study computer science in college]." 

They say that what we do every day changes lives, but some days that just feels especially true.