An industry-led, fully remote programming course for Indian B.E/B.Tech degree
For the last 4 months, I've been a coach and content-creator for a course we call SaaS & Web Technologies 201. It is the first of its kind that I know of in Indian engineering education - a fully remote course, shaped and run by software industry participants, and treated as first-class citizens of the academic curriculum in a B.E/B.Tech course.
This was made possible by three participants: Freshworks, SASTRA University, and Pupilfirst. Freshworks funded me as a coach and provided the course outline and initial content. In fact the two companies had already run the first iteration of the course last year at SASTRA, and had figured out the shape and formula for successfully running a remote programming course.
SASTRA allowed students from 4th and 6th semester of any engineering stream to choose this paper as one of their electives. The grades would count towards their final GPA, just like any other academic paper.
This course was a dream come true for me. In the past I had the good fortune to help build RubyMonk, teaching Ruby to beginning programmers. I've also been teaching Reason/OCaml through public workshops and in-house trainings with my co-founder Sherin. All of that fit into the part of me that wanted to share the joy of programming with others. But this opportunity allowed me to work within an academic environment, helping shape the very course that I wished were done differently during my spell with higher education a decade ago.
Through the course I was able to try out some long-held ideas on teaching web development, and thankfully, student performance have exceeded my expectations. It is in the hopes that it might pave the way for more remote, industry-led courses in Indian higher education that I'm sharing a retrospective of the course below.
Course outline
Here's what we taught: building a SaaS web application from the ground up using Ruby, Rails, and PostgreSQL. No Javascript, just plain old server-side web development.
We had about 100 hours to work with: students would get 40 hours of classroom time through the 4 to 6 month semester, and were expected to put in equivalent hours outside the class.
We then designed the course by working backwards: at the end of this 100 hours, what concrete skill do we want the student to have? With consultation from engineers at Freshworks and Pupilfirst, we decided that a) they should learn modern engineering practices like version control, code reviews, and should care about code quality. And b) they should be able to build a Todo management application by themselves using Ruby on Rails.
Before writing off Todo Management as cliche and trivial, note that the students know only the basics of programming - they can write your average FizzBuzz program, but we can't expect much more than that in practical programming experience.
One way to go about this would've been to start with rails generate scaffold
- and everything would be sorted in a few hours. But we wanted the students to be able to reason about every single line of application code in their codebase. Which meant we had to take the magic out of the very magical Rails framework and instead build up concepts from first-principles.
This meant starting with the Ruby language, moving on to object-oriented programming, databases, ActiveRecord, HTML & CSS, request-response, view templating, cookies & sessions, user authentication, security, data validations, and the whole gamut of MVC. Considering all that, the 100 hours we had felt inadequate.
By the end of the course we had created about 44 video screencasts, spanning 7 hours of instruction. The content was split into 9 chapters covering all the above topics, and after finishing each chapter, the student had to submit a code assignment through a GitHub repository.
By the time they're done with the course, they would walk away with a repo of 30+ commits and a live Todo Manager app hosted on Heroku, similar to this. They become well-versed in how the web works, and with the myriad concepts that together make for a web application.
To cap it all, they also had to build their own final project. For this semester, it was a cafeteria management system - a food delivery app and a POS rolled into one. The total marks for the course was divided between this final project and all the assignments forming the remaining half.
An assignment is a conversation
The remote nature of the course had its pros and cons. Assignments were one of those things that worked well, especially because the process was fully digital.
An assignment, in a regular Indian academic environment, is a testing tool. You submit something, you get graded on that, and that's it. You might have to re-do if the submission was terribly bad, but otherwise it often ends up being a pointless chore that you have to get somehow through.
This dynamic was inverted in SaaS 201. In Pupilfirst, the open-source LMS we use for the course, an assignment is a conversation starter and a wonderful learning opportunity.
We designed the problem statements for each assignment so that students don't get it completely right on the first try. We did this by leaving out a few key reminders. For example - do not put complex queries directly in ERB views. Now this would've been covered in the course already, but without explicitly mentioning it in the assignment instruction, most students forget to follow it. So they submit code with complex database queries invoked right from the view.
This gives us an opportunity to review it and remind the student why it is a bad practice. They engage more with the idea and it sticks to them much better than if we had never allowed them to make the mistake in the first place. In all of our programming journeys, we can recount things we learnt only the hard way. No amount of book knowledge would help us until we experience it ourselves. Making mistakes, and then recognizing and fixing them is when things click. Assignments with multiple rounds of feedback, all done online, enabled us to practice this.
But the down-side to it was that as students improved their submission based on feedback, their assignment grade also improved. Without that, we couldn't incentivize students to work on the feedback and re-submit the code. But this led to grade inflation and its accuracy as a testing mechanism went down. As a personal call, whenever learning goals conflicted with testing goals, I optimized for learning. But accurate assessment of student progress is a key part of learning and it is something I hope to address in the next iteration of the course.
Code review works
We approached assignment grading and feedback like a professional code review - kind, courteous, and addressing the code not the person. In the initial days of the course the students were thanking us profusely for the feedback - I like to think that they appreciated someone actively going through their work and helping to improve it. But this process was no different from a regular pull request and associated code review. It satisfied one of our goals for the course: to expose students to professional software engineering practices.
The challenge of teaching Rails
Rails, circa 2009, was one of the easiest web development frameworks to teach and to learn. But years of feature accumulation, essential though they are, has made it unfriendly to beginners.
So to ease the learning curve, we tried to teach concepts decoupled from Rails as much as possible. For example, we taught ActiveRecord before Rails by getting the students to write stand-alone scripts that requires the library, connects to the database, and executes queries. So when they saw Rails, they could see ActiveRecord as just a piece of the puzzle rather than as a magical entity that just exists in the Rails world.
We also tried to avoid magic, even in little things. Our motto was always "explicit is better than implicit". For example a controller action like index
automatically renders index.html.erb
even if the method body is empty. This is a Rails convention. But conventions, for the uninitiated, are just arbitrary rules without any rhyme or reason. So the students always wrote render :index
explicitly and I never taught them otherwise.
The upside is that when they learn about the convention, they understand the shortcut for what it is.
Another important decision was to make them build user authentication from the ground up instead of using the Devise gem. This allowed us to have conversations about the state-less nature of HTTP and how cookies work, and finally use that information to maintain user session.
The upside of learning Rails
One of our goals with this course was to help build vocational competency in students. They should be able to build their own web applications and later find jobs because of what they learn here.
This has borne fruit - in the final project, they were able to build complex features by themselves and showed good understanding of the web application model. More importantly, it seemed to me that they found the work fun, and we could see a sense of achievement as they realized their increased range.
Effort
When I started off as a coach, I was expecting a comparatively light work-load and hoped to balance it with my work at Protoship. But it took more time than I had planned - I had to design the course, record videos, grade assignments, and speak to students over monthly AMA calls. Thankfully, this was not a one-person effort. I was assisted by two TAs - Vamsi and Mamatha. They are senior students who'd taken this course previously and had done well. We split the assignment grading workload equally between us and co-ordinated with weekly review calls.
From the University side, all the 60 students were helped by Prof. Karthikeyan from SASTRA who admirably filled in the gaps left by the remote nature of our course. We were supported inside the University by the Technology & Business Incubation department, who were very forward-looking in improving student outcomes.
We were also shepherded through the whole process by Dr. Reena from Pupilfirst, who was responsible for us achieving our course objectives. There were also folks like Suma from Pupilfirst, and Vignesh from Freshworks who worked behind the scenes with the University to make it all possible. Additionally, Arvind, an engineering leader from Freshwork provided the course objectives, helped me design the course, and gave constructive reviews as it progressed.
All this was done with the Pupilfirst platform, an open-source learning management system. The team improved the software based on our feedback, and features like Review Checklist - which allowed us to create review templates for common mistakes made by students - helped make the teaching more effective.
In short, running a remote course well requires over a dozen people working in tandem. The work-load can become lighter over multiple iterations as the content is stabilized and a routine is set. But I for one was surprised to realize the amount of planning and sheer effort that went into the process.
What next?
There is no doubt that without theoretical rigor and fundamental research, we cannot as a nation, hope to make break-through progress in the sciences. Western academic curriculums, with the support of an advanced knowledge economy, are already optimized for that.
But Indian engineering education shouldn't blindly follow their lead without considering our unique situation. We have about 800,000 graduates coming out of our colleges every year, but a large chunk of them lack sufficient vocational competency. This is a problem that should be solved first, without which we cannot cross over to fundamental research and innovation.
Thankfully, computing, unlike the hard sciences, is something where one can build an intuition for the craft without necessarily being versed in its underlying theory. But we continue to lean towards the theoretical side of computing to the detriment of practical engineering experience. We are teaching our students the intricacies of automata theory without ensuring they have basic programming skills.
To fix this, India has to adapt and devise our own educational path forward. I think key to that would be to welcome more industry participation in our academic programs. This will help students find better jobs and help their livelihoods, while providing our industry with competent junior engineers.
As a continuation of our efforts, we're planning to create two more courses - a programming 101 where we teach practical programming to complete beginners, and a 301 where we teach advanced engineering skills, sufficient to take students beyond the traditional engineering bootcamps run for fresh hires by Indian software companies. But irrespective of how that goes, I hope we see more efforts in this direction, where the government, academia, and the industry work together to improve the vocational competency of our engineering graduates.
- Next post: Materials for learning ReasonML