I was one of many students hired by the university during the summer to prepare resources for the upcoming online fall semester. Since I had programming experience my role was to prepare code examples and digital notes for upcoming classes.
The main project I was tasked with was building a form of 'virtual textbook' for CIS*2430, the
'Object-Oriented Programming' course that every Bachelor of Computing student takes to complete their degree.
In past years supplementary content was given through a physical textbook and interactive content from a
third-party
provider, Zybooks.
With the shift to online learning in the upcoming semester, the idea was to create an
interactive textbook
consisting of a series of Jupyter Notebook pages, each with interactive code samples that can be edited in real
time. Students
could then follow along with the professor as they go through the notes or access them at their own pace.
Every workday we would have standup meetings via Zoom for co-op students, students with summer research projects and faculty involved in the project. About once every month we would have a "Show-And-Tell" meeting, where students presented the current status of the projects they were working on.
I found the daily standups to be an excellent way of getting an overview on how other's projects are progressing, and in getting help for blockers your project might face. This was especially important when the majority of communication was through asynchronous chat and email - synchronous communication is ideal for getting issues immediately addressed.
The programming language used was mostly Java, as that was the object-oriented language chosen for the class. Examples for the different topics in the course were designed to be fully built and run using Gradle - a build system for Java projects, similar to what make is for C projects.
I had used Maven before at previous co-op positions, so I had an idea of what a build tool could do and how it they are generally structured. Gradle revolves around a build.gradle file that pulls in plugins, adds dependencies and repositories, and defines tasks for building and running the application.
In addition to the Java example projects, a main focus of my work was writing Jupyter Notebooks for
each of
the topics covered in CIS*2430. Jupyter Notebooks are like a combination of markdown and code - a collection of
cells
that can be either markdown prose or code that can be run directly within the document. This combination creates a
sort of "code narrative" where the markdown explains a concept that is then demonstrated by the code cells.
Originally developed for scientific computing and analysis applications in Python, Jupyter now supports many different languages including Java.
It was decided early on that the Java examples and projects I would work on would all use Gradle as a build system to compile and run the applications. I had used Maven at my previous co-op position, but in a more operational role as the Maven project had already been built. Gradle is a widely-used build system for Java (being the standard build system for Android projects for instance), so it is a very useful tool to learn for future roles in Java development.
Gradle can support many different project structures - from a single-entrypoint class to multiple classes with main() methods running separate programs. Gradle can efficiently run multi-project structures as well - have a build.gradle for each project and a root settings.gradle file that connects all of the build files together. All of the tasks in each project build file can then be run from the settings.gradle location. I built every Java project to be built and run using Gradle, including projects with external dependencies like JUnit and Lanterna.
Gradle can be installed manually (via package manager tools like apt) but a cool feature of Gradle is wrapper
files,
named gradlew or gradlew.bat respectively for the different shell systems. If a project has a
Gradle
wrapper file, you run Gradle commands using that wrapper file (ex. ./gradlew build
)and it will
automatically
download and run a local verison of Gradle for you, no manual installation required! This makes getting up and
running
with Gradle projects as a new user very easy.
I consider this goal achieved as I have a solid understanding of both setting up a Gradle build for different project scenarios and running Gradle builds from the command-line. Next steps would be to learn how to use Gradle for more advanced processes like running CI builds or advanced testing scenarios. Gradle scripts can also be written in Kotlin which would be an interesting avenue to explore and could lead to more Kotlin development.
I made this goal when I learned I would do most of my work in Java - object-oriented languages benefit from modular design patterns that promote flexible, reusable code.
The projects I worked on - preparing practice problems and Jupyter Notebooks for course topics - does not naturally lead to implementing Design Patterns, so I worked to include them into my role. I designed Jupyter Notebooks that would introduce a Design Pattern, explain why it was useful, and provide examples in Java that were relevant to the course project students would work on.
The patterns I focused on were the Factory Method, Singleton, Decorator and Strategy patterns. Each have their own approach to making code structure flexible and easy to work with.
The Factory Method pattern allows you to decide at runtime what subclass type you want to instantiate
The Singleton pattern creates a class with one (and only one) instance active at a time, globally accessed by other classes.
The Decorator pattern allows you to layer additional effects and attributes onto a base class implementation. Think of it like decorating a tree - you start with a base tree, then you layer on whatever additional ornaments and effects you want the individual tree to have.
The Strategy pattern provides a collection of methods that can be freely interchanged with different implementations. While quite similar to the Decorator pattern, the difference is that with the Strategy pattern you completely swap out method implementations, while with Decorator you are adding details on top of a base implementation.
I believe I accomplished what a set out to achieve with this goal - I learned the mechanics behind multiple common design patterns and applied them in code examples. I think learning design patterns from the perspective of having to explain them to other students was useful in understanding both the mechanics and why you would want to use design patterns. Some next steps for this goal would be to apply design patterns in a project setting, rather than as isolated code examples.
This was a continuation of a goal a set last work term; I found that when attempting to introduce or explain technical topics I was often unclear or took a long time to get an idea across. As I was doing solo work on multiple projects this work term, I thought it would be good practice to present my progress on these projects as much as possible to build experience and confidence.
I had plenty of opportunities to present my work to others. Every workday the team would have virtual standup meetings, where we would be broken off into random groups to discuss our progress. Since each standup would have a different group of people than the last one, I made an effort to introduce and explain the projects I was working on - both so my group would have context and so I could get valuable practice.
Once every month the team would have a "Show and Tell" meeting where we would present what we were working on over the summer. These meetings were an excellent opportunity to practice technical and presentation speaking, and I used them as a judge for if I was improving or not. At the first meeting I presented the Jupyter Notebooks I had been created for CIS*2430, and at the second meeting I presented a proof-of-concept of making a Roguelike game using the Lanterna terminal library.
I found that creating a rough bullet-point 'script' to follow when demoing my work was really helpful in keeping me on track and providing a logical flow to my presentation. I created a bullet-point script for my Lanterna presentation and I found it was much clearer than my first presentation, where I went without a script.
This work term was a much different experience than my previous one. Whereas my previous work term was working closely with an Agile team on business software, this work term was mainly independent, self-driven work on educational content. Design details were largely left for me to determine, which really forced me to have a concrete method of planning work and designing my project structure. I had walked into an existing design structure in my previous placement, so coming up with my own was a challenge, but also highlighted how important planning really was to the development process.
The fact that the entire work term was done remotely was also a major change. Initiative and self-motivation are really important to getting work done remotely, even more so than working in-person where there are more reinforcement mechanisms in place (eg. Peers/supervisors becoming aware of your distraction).
Overall this work term provided a lot of insight into how course content is created, and a lot of experience in independent, self-driven work - both of which are valuable going forward!
I want to thank Prof. Judi McCuaig for taking me on in this position, and all of the other co-op students I worked with this summer for making it a great experience!