For my last apprenticeship pattern blog post, I felt that the pattern Sweep the Floor was appropriate given where I currently am at in my career, given that I hope to be starting in the very near future. This pattern refers to the scenario in which you’re a new apprentice on a project or a new member of a team and you’re not sure what your place is in the team, so you want to contribute and earn the team’s trust. The solution to this is to volunteer for simple, necessary tasks that no one else wants to do and to make sure to do a great job with them. Of course, you want to make sure that you don’t end up only doing menial tasks that no one else wants to do and that you’re given more challenging assignments after proving yourself “worthy”.
As I said earlier, this pattern is probably one of the most applicable to me at the moment, because once I start I can see myself in almost the exact same scenario as described in the pattern. I always figured that most junior level roles start with you being assigned simple tasks like one-liner bug fixes to help you get acquainted with the code base, but I hadn’t considered that it would be a good idea to take on tasks like literally sweeping the floor in order to build confidence as a member of the team. Of course, I don’t entirely agree with consistently taking on tasks that aren’t relevant to what you want to work towards, but there’s merit in doing menial labor when you happen upon it. As long as you make sure to let it be known that you want to be challenged and not just be comfortable standing still working as the team’s gopher.
Overall, I would say that it’s very likely that I’ll end up using this pattern in the very near future, so hopefully I remember to avoid the negative consequences of applying it. In fact, I wouldn’t be surprised if this pattern would be useful for me anytime I happen to enter a new team, not just my first one.
For the last sprint of the semester, I spent most of my time working on my part for our groups final presentation. There was one minor bug fix that I made involving an incorrect mapping for one of the product endpoints found from a user reported issue, but otherwise the rest of my time was spent on the presentation. This bug in particular could have easily been avoided if the project contained tests for each of the endpoints maybe by using a mock database. If, for example, we had a test that tested what would be an expected successful response, then the test would have failed for the given endpoint because it gave a 404 not found response instead.
For the presentation, since my task was separate from the main project for the food pantry, my section felt like it was a short, stand-alone presentation contained in a longer one. Looking back on what I did for the project, I definitely feel like it wasn’t too complicated and if I needed to do something similar now it wouldn’t take me nearly as long.
That being said, I think there are several major things that I should take away from this project. First of all, although the resources that I followed through were helpful in its creation, I wish that I had started from the ground up to understand how everything actually worked. It’s very easy to get something to do what you want from making minor changes to resources you’ve already found, but being able to actually understand how everything is working together and also being able to explain it well are much harder and take time. Another big takeaway is to make sure to have good tests and to make sure everything is still working properly by running through those tests after making any changes. The fact that the bug with the typo in one of the get mappings exists is proof that I hadn’t properly tested the code to make sure that everything was still working as intended when I pushed my code and created a pull request. I was very fortunate to have run into this issue at the end of the project because if I hadn’t then I might have gone on to make the same mistake in the future.
If anyone happens to work on the project in the future, the first thing they should definitely do is implement the automated semantic versioning that I neglected to do myself. It’ll save them a lot of headache if they make any changes because they won’t have to remember to update the version in multiple locations. Without a doubt, when I saw that issue, it was clear that it was poorly designed. There’s no reason for the current version of the project to be hard coded in multiple locations. Actually, when I pushed the changes for the endpoint bug fix, I ended up forgetting to update the version number and the pull request had already been merged, so definitely fix that first.
Link to project GitHub repository:
The apprenticeship pattern Nurture Your Passion refers to the problem in which you feel the environment in which you work in is stifling your passion for the craft. Depending on which aspect of work you feel is doing this there may be different solutions for everyone. For example, if you’re in a situation of constant project death marches that are sapping your time and energy, then you need to set clear boundaries and protect your passion. Whether that means to decline working “culturally pressured” overtime to avoid burning out or not would likely depend on how much you feel these death marches are affecting you.
As someone who hasn’t had much if any experience in the industry, this pattern definitely worries me a little. I’ve heard similar horror stories about project death marches from game developers working in the games industry. People who were filled with passion for their craft entering an industry that commonly abuses that passion with forced overtime until they burn out. Then, once you finish the project you’re working on, you’re laid off in an effort to cut costs by reducing headcount because you’re no longer needed, not because you’ve done anything wrong.
Obviously this isn’t the case with every company and the software development industry likely has many differences when compared to the games industry, but they do bear many similarities as well. This problem can be avoided by finding the right company that offers what you’re looking for, whether that be working overtime on something you believe in and enjoy, or somewhere that offers you good work-life balance. I’m always a little bit worried getting stuck in a situation with poor work-life balance because I’m not sure I would be confident enough to put my foot down, so I’ll have to remember in the future that I should focus on what’s best for me because I’m sure most companies wouldn’t think twice to cut costs whenever they can.
Overall, I agree with what the pattern’s saying and hopefully I’ll remember to nurture my passion even if it means getting passed over for promotions or having to find somewhere else to work.
The apprenticeship pattern Find Mentors refers to the problem in which you feel like you require help and guidance because you’re not sure where the path is taking you and you feel unprepared for what’s to come. The solution to this is to reach out to other craftsmen who are ahead of you and to try your best to learn from them.
This pattern in particular was interesting to me because I feel as though I’m at or nearing a point in which I would benefit greatly from mentorship. Of course, no matter how far along the path you are, there’s always something to gain from mentorship. People who just graduated or recently graduated, I feel, are more likely to have that feeling of being unsure of what they should be doing. These are the people who need help and guidance the most in order to push them along the path. Even though it would be ideal for apprentices to find mentors, it’s definitely not as simple as it sounds. I’m certain that some people who are in need of mentorship don’t feel as though they know anyone who they feel comfortable asking to be a mentor to them. One of the most interesting parts of the section is that, even if you feel intimidated about reaching out to someone to ask for an apprenticeship, the risk of being rejected or considered strange by a potential mentor is relatively low, while the potential payoff is huge. So, if you find someone that you’re really interested in learning from, you should definitely reach out to them as there’s so much to gain.
I don’t feel like the pattern really changed the way that I think about Software Engineering, but I think my biggest takeaway from this is the make sure to not be too intimidated to reach out for mentorship. Had I not read this pattern I’m certain that I would have felt that way for a long time, so hopefully in the future I power through. I think it would be a good idea to seek out opportunities to find potential mentors in the future.
For this week’s sprint, I’ve spent most of the time looking into a way to automatically increment the version number (based on semantic versioning) every time we make changes. Currently there is a reference to the version number in 4 different places: The Procfile used by Heroku, the build.gradle file, the Java configuration file for Swagger, and the README Markdown file. To do this, I’ve been looking at different Gradle plugins that could do this automatically. There seem to be many different options available, but there doesn’t seem to be one that completely fits what I’m trying to do. I think that the fact that some of these files simply have the version number hard coded in is causing this issue. It would be simpler if the version number was located in one place (maybe a version.properties file) where all of the other files simply reference that file to do what they need to do with the version number.
While it’s not exactly an high priority task, given that there doesn’t seem to be many more changes needed to be made to the project at the time, it’s important to automate the version incrementation now in case the project needs to be updated in the future. It’s definitely not a good idea to keep it the way it is, as having the change the version number in multiple locations could potentially break something if one of them is forgotten. For example, we already ran into an issue where Heroku couldn’t find the jar file created because the version number hadn’t been updated in the gradle.build file but it had been in the Procfile. This caused the jar file that was created to have the wrong name, so Heroku couldn’t find it.
Also, another thing that I want to start looking into is to add unit tests using JUnit, as it’s something that I’ve neglected to do but definitely want to get done before the semester ends. That would include some basic unit tests for each class to make sure their methods are working properly but also some Spring Boot specific tests. For example, I should be able to create tests for each endpoint to confirm that they’re working properly, perhaps using some of the techniques learned from previous coursework such as mocks. Spring Boot appears to have a wide variety of auto-configured annotations that could potentially be useful for creating these tests. For example, the annotation “@RestClientTest” disables full automatic configuration and instead only applies the configuration that is relevant to REST client tests. This ensures that Jackson and GSON support is auto-configured.
In conclusion, I’m hoping to finish up with the automatic versioning as well as added necessary tests to the project by the end of the last sprint and before the presentation. I definitely don’t want to leave the project without adding any tests as that’s bad practice. In any future projects I’ll need to make sure not to neglect creating useful tests but I also want to avoid creating useless tests that were made just to have tests in the project.
The apprenticeship pattern of “Expand Your Bandwidth” refers to the situation in which you’ve picked up a basic set of skills, however your understanding of software development is still narrow and only focused on the low-level details of what you’ve been working on. In this situation, you’ve only been taking in a relatively small amount of information gradually, but sometimes you need to take in a large amount of information and efficiently absorb it. So in this case, “Expand Your Bandwidth” means to be able to do just that.
I can see how this pattern is really important and would be immensely helpful to master, but being able to take in more information than you’re used to and at the same time efficiently absorb it, understand it, retain it, and apply it is a tall task. No doubt that mastering this early on in your career will be a massive boon.
This pattern includes some useful examples of where you could seek out new knowledge and experiences. For example, signing up for Google Reader or any other blog aggregator and subscribing to software development blogs that interest you is definitely a good idea to learn about a variety of topics from multiple perspectives. If nothing else, this is something that I certainly plan on taking away from this post. Rather than wasting my time on websites like Reddit, I think it’s in my best interest to spend that time reading something more productive. I also think subscribing to a moderately high-traffic online mailing list and trying to answer people’s questions is a good idea as well (maybe something like stackoverflow).
Overall, I’d say that this pattern made me understand a little better about how an apprentice will have to take in much more information than they’re used to taking and also be able to process and retain it, while at the same time not getting overwhelmed by it. Of course there are times in which you should stop focusing on expanding your bandwidth and come back to the craft, so it should only be used as a means to an end.
For this sprint, I worked on several different tasks to improve the project. Firstly, we needed to get the project hosted onto Heroku, so I added some of the dependencies that Joshua Farrar had created in order to allow it to be deployed directly from GitHub. There were also some minor bugs that needed to be fixed such as typos, missing new line characters, etc. Next I worked on adding build instructions to the readme by working through installing the project on a clean windows install on a virtual machine in order to figure out every dependency needed to be installed. Then I added a landing page to the project which contained a list of all of the available endpoints, however this was a very bare bones solution as it was just a list of the endpoints with no further information. We decided to integrate Swagger 2 and Swagger UI to automatically create more description documentation containing endpoint descriptions as well as a UI to test the endpoints. There was also a minor issue where the example model of the object returned by the endpoint was showing up as empty. This was due to the way the endpoints were returning objects (showing the model of the “Object” class rather than the actual classes being returned).
From what I understand, Swagger gathers the endpoint data in the same way that I did, however, it’s far more detailed and robust. I think if I were to do something differently in this situation I think definitely I would do more research into the possible alternatives to solving each task in order to figure out what the best solution would be before starting to work on it. Had I initially looked into Swagger prior to starting to work on the landing page, I would have saved a lot of time. This is something that I should take into account for the future as it will be important to avoid wasted time whenever possible.
When making the build instructions, I think using a virtual machine to start from a clean slate was definitely the best course of action, as it’s important to see what it’s like for someone who potentially started from that state to get the project up and running. By doing this, even people who already have some of the dependencies installed will be able to follow through the build instructions by skipping steps that they’ve already installed. Although, I hadn’t considered the difference in the installation process between Windows devices and Mac/Linux devices. This project in particular doesn’t require many dependencies to get started, so it’s not difficult to create combined installation instructions, but I think for larger projects it would be smart to separate them. One of the differences I ran into was including the installation of Git Bash while Mac/Linux devices would be able to just use command line.
For the next sprint I’m hoping to automatically update the version number whenever necessary, as it’s definitely bad practice to have to update it in 4 different locations every time. Also, it would probably be a good idea to add an endpoint that gives you a products maximum shelf life and best storage method, given what the data would probably be used for.
For the third sprint, I was assigned to create a REST API for the USDA’s Food Safety Inspection Service’s FoodKeeper Data (located here:
https://catalog.data.gov/dataset/fsis-foodkeeper-data). Prior to starting this assignment, I felt I had a poor understanding of what a REST API was, let alone how to go about making one. Fortunately, the resources that Professor Wurst sent me were a very helpful step in understanding what one looks like. I also read several other resources and followed many other tutorials while making it. By the end I had over complicated things by storing the data into a MongoDB database and ended up switching to data stored in memory, but despite this I think it was still very useful to work with MongoDB as well integrating it with the REST API. I had also considered trying to use a relational database such as PostgreSQL, as the data seemed to lend itself well to it given that each data type already contained keys relating to the other data, however it was a bit harder to set up when compared to a document database.
This sprint began before spring break, and during that time I felt that the project was at a much earlier point than was initially assumed, so I spent a good chunk of my break working on it. As I said I started with a poor understanding of REST APIs so I felt that there was some catching up that needed to be done. By the end of the break I had something that was mostly working but was a bit complicated to set up since it required installing MongoDB locally at the time. I imagine we may have run into similar issues when trying to host it in Heroku, but fortunately it’s since been simplified. I don’t think that it would necessarily be a bad thing to store the data in a separate database, however, given the relatively small set of data as well as the fact that changes aren’t made very often, it didn’t really make much sense to go that route. Changing the code that I had already written to no longer use MongoDB was pretty trivial, as not many changes needed to be made. At this point, the REST API Order System example (located here: https://gitlab.com/worcester/cs/kwurst/rest-api-order-system) that was sent to me was particularly useful, as the was it was set up was almost one to one, with a few changes here and there.
Currently the project is almost at a point where it’s ready to be used, as far as I’m aware at least. I feel that it was much simpler than I had originally thought it would be, but since I hadn’t had any experience with doing something like this before it took longer than it should have. I think one of the most important things that I’ve learned from this is how to start working on a task in which I’m unfamiliar with. It was definitely useful to learn how to make a simple REST API, but I’d say being able to work on something you’re uncomfortable with is a skill that will help me greatly in the future.
The Apprenticeship Pattern “Breakable Toys” refers to a scenario where the environment you’re working in doesn’t allow for you to fail, stifling your learning because failure is often the best way to learn anything. According to the author, the solution to this is to create your own “breakable toys” from which you’re able to learn through catastrophic failure that won’t have an effect on anyone but you.
The thing I find most interesting about this pattern is some of the examples it suggests to do in order to create opportunities to learn. For example, creating your own wiki and adding more interesting features without being bound by existing implementations. I can see how working on something like this from start to finish would greatly improve your ability as a software developer.
It would be great if you could be satisfied with the amount of learning that you’re able to do within your current work environment, but given the fact that businesses need to make money to survive, taking risks and learning through failure is typically not something that can consistently happen if a company wants to continue existing. That’s not to say that mistakes should never happen, but it makes sense that a company would want to avoid them as much as possible in order to retain the trust of their clients. If someone were to make a costly mistake for a company, it should be used as a opportunity to learn from it, rather than just firing that employee and moving on.
I recall there being a disruption in Amazon’s S3 service causing around 3 hours of downtime being attributed to human error. One of the employees on the S3 team was debugging an issue when he accidentally removed a larger set of servers than he had originally intended, all due to a small typo in his input. Regarding this incident, Amazon stated: “We will do everything we can to learn from this event and use it to improve our availability even further”, acknowledging that they would seek to prevent it from happening in the future. I would imagine that the employee who made the mistake may have learned a lot about the potential effects of something that seemed so insignificant.
Our second sprint was much more productive than the first, thanks to our meeting with the representative from the food pantry. During the meeting we were able to gather a lot of information about what they needed from us. Currently, new users fill out a Google form which determines what level of aid they qualify for. This is something that we would want saved and automatically determined when that user comes to the food pantry. One of the main issues they’re currently having is that employees have to manually track the weight of their current stock. So every donation they receive they have to measure its weight and then manually enter the weight of the donation as well as what types of items were received. This is the main task we’re working on finishing this sprint. For this we should be focusing on making small quality of life improvements (such as automatically adjusting the total weight) and work from there. I’m interested in seeing if it would be possible to connecting to a scale to do this automatically after weighing a donation, but that’s something that should come later.
From the meeting we were able to figure out some of the food pantry’s pressing needs that we could address. I feel like we were able to devise clear goals to work towards.
After the meeting was over I believe we may have ran out of time before assuring that everyone knew what tasks were assigned to them for the sprint. During the sprint I think this was cleared up as Nick had already begun re-purposing one of his previous projects for the food pantry and let us know what he needed help with. Although, since we missed a couple of meetings we ended up making less progress than we could have.
During our retrospective, Nick showed us and the representative from the food pantry the progress he made on the new worker intake form. It’s definitely a step in the right direction. Once it’s cleaned up a bit I think it’ll be better than what they’re currently using. One thing we need to do is to make sure that we create something that actually makes it easier for employees at the food pantry to do their job. For this project in particular, we need to solve the main bottlenecks that they described: manual data entry and calculations. These are things that can easily be solved by automating the process. It’s important that we create something that is an actual improvement from just sticking with the Google form.
Near the end of the sprint I was given a different task to work on. This was what we were initially working during the first sprint prior to the meeting with the employee from the food pantry. For this I need to create a REST API interface using the USDA’s FoodKeeper Data so Joshua Farrar can deploy it to Heroku. While we were working on this during the first sprint, we were all researching what we needed to do individually which I feel may have wasted a lot of time. The resources for REST APIs that Professor Wurst sent me have been useful, and hopefully I’ll be able to finish this during the next sprint.