One of the places I think is ripe for innovation is journalism. That is why I have been working on some side projects with Doug and Christine of CTNewsJunkie. Last week we launched bills.ctnewsjunkie.com, a tool for sharing your opinion about activity in the Connecticut legislature. We are using software as lever to help inform the public about their world.
Over a year ago I worked with them to launch the CTNewsJunkie Voter Guide. The idea behind the voter guide was to better make available to the public information about the candidates running for office. The app has seen large year over year growth, especially as we focused on providing information on municipal candidates last cycle. People are clearly starving for information about their communities and they want something that is a little more authoritative than Facebook.
Check out my two apps and share any feedback you have in the comments below.
Up until a few months ago my primary outlet for writing has been on Facebook. Facebook provides a great user experience and importantly to me has an integration with the sharing features in macOS and iOS. This made it easy to copy a quote from an article I found and link it to my friends so they could get a glimpse into my own thinking. Unfortunately due to recent changes in the news feed and maybe the progression of life, it feels like Facebook is turning into a ghost town. I find myself spending more time on Twitter.
While I do not dislike Facebook and other social networks as much as some people, I have decided that in the long run it is better to own my content. Going forward I will talk more about my work and my experiences at Code for Boston along with interesting writing and videos that I find.
In March I developed some back issues while sitting in an old office chair. This lead me to finally give in and decide to order a new one. After reading this article I made the decision that buying an office chair is an investment and procuring a cheap one would leave me disappointed. Once I decided upon that I just had to pick the right chair. While the Steelcase Gesture was favorably reviewed, I never had a chance to try it. I did try some Aeron’s at the local start-up. They felt comfortable to me and given that I run hot, it seemed like the better fit. Since I was planning to own this for a long time I ordered the Aeron v2 with the following features:
- Adjustable armrests
- Leather armrests
- Forward tilt
- Posturefit XL
I am convinced that despite costing extra money, each of those four features made my new Aeron noticeably superior to the older stock models that I tried at the start-up. The leather armrests are incredibly comfortable compared to the stock ones and look great. I also never realized how much I would adjust my arm rests. They can swing in to support my arms while typing and then swing out when I want to more freely move my arms. The height adjustability is critical to sitting in a stance that is comfortable for me as well.
I also decided to spring for the forward tilt option. I am glad I did. I never realized how much time I spend leaning a bit forward focusing on my screen as I type. This feature lets the chair easily support me in a perching position. The experience makes it vastly superior to all the other office chairs I have used. If there is one feature you do not want to skip, this is it. I am currently writing this review with my Aeron in a forward tilt position with the recline locked so it supports my back.
Furthermore I find the PosturefitXL unit to be superior to the regular lumbar support I tried at the start-up. It felt more natural and supportive. I have not made any adjustments to it, but in its stock configuration it makes it feel like I can sit in my Aeron for hours without problems.
Sitting on Herman Miller’s proprietary pellicle material is more comfortable than other mesh materials. I feel well supported. Having sat in both the original Aeron and the Aeron 2, I think that the update to the pellicle material is a noticable improvement. However I do not believe an original Aeron owner will find they are misisng out on much. Both the original and Aeron 2 are much better than regular mesh.
Once you figure them out, the adjustments are logical and easy to change. I find myself modifying my chair for my mood multiple times a day. Sometimes I like the chair to recline, and other times I want something that will hold me in a position. If I’m typing and my arms are fatigued I can swing the arm rests in to support me, but if I want to send them out of the way that is easy to do as well.
I do not think the Aeron will be the right fit for every person, but I think that someone considering an Aeron today should try the newer version with all the new features before deciding whether they might want to get it versus something else. Along with a keyboard tray it has made using my computer at my desk a much more pelasant experience.
As a software developer, I spend almost every week at Code for Boston. There are a large number of attendees consisting of optimistic boot camp graduates thirsty to get some experience coding on real open source projects. Having worked with over fifty boot camp graduates over the past year and a half and seeing their challenges, I have developed an understanding of the challenges boot camp graduates face as they transition to coding in the real world. While you can join me at Code for Boston to learn these things, I am going to share some of my wisdom below.
In order to effectively code in a team, you should have mastery of git and work with some kind of project management tool. For most of our open source projects, we use GitHub at MAPC and Code for Boston. We use GitHub Issues to manage our project tasks. GitHub Issues are close to the code base, open to the world, and can be easily referenced and closed from commits.
There are lots of philosophies around how to structure git commits. Writing good commits will come to you with practice and experience. As a boot camp graduate, you have likely not yet had to dig into someone else’s code base and pray that certain information about a commit was there so that you can figure out what is going on. It is important to write a great commit message. If you are intentional about writing that great commit message and keeping your bug fix or feature down to a few great commits, it will be easier for others to understand the purpose of your code. Often the question you need to know the answer to is: “is it safe to change this code and if so, how?” Commit messages are a big part of how you find the answer to that question. You can also get a sense of commit message quality by looking at a class with git blame.
Inevitably you will at some point in your life commit a secret to a public GitHub repository. Do yourself a favor and setup and practice using BFG Repo-Cleaner today. When you actually need it, it will feel like a scary emergency and you will feel better having practiced this skill.
Pull Requests and Code Review
An important part of building your coding skill is to receive constructive criticism of your current work and style. You will likely do this by submitting a bug fix or feature as a pull request to an existing project. To improve your skills it is also helpful to review other people’s code. This is a chance to think and be intentional about what makes good code. While some new coders get anxious about making comments, the best thing to do is to treat code review as a discussion and not expect every thought of yours to be blindly implemented by the pull request author. Thoughtbot’s Guide has great advice on reviewing pull requests.
My process for reviewing a pull request is to first review the code on GitHub for any errors, opportunities for improvement, or obvious bugs. I make sure to understand what the pull request is attempting to do as a unit and also what each commit accomplishes towards this goal. If I do not understand I ask the requester questions to create this understanding. Once I fully understand the pull request I clone it to my local machine. There I run and check to see if the test suite passes. Then I actually run the app to try out the feature or go through the steps to reproduce to the fixed bug to prove it has been fixed. Once this has occurred I approve the pull request and let the requester merge it into the develop branch. Then the update is deployed to a staging instance to be tested one last time by a developer and any relevant outside parties before being promoted to production.
Fixing bugs on your own or other software can be challenging. With the right toolset, you can surmount these challenges and successfully get your software working. Your first step is to reproduce the bug. Hopefully, the user has submitted enough information so you can see and experience the bug for yourself. If not, you need to open the lines of communication with your user so that you can effectively reproduce it. If they are getting the bug and you are not, you need to figure out what is different between their setup and yours that might be causing the bug. If you cannot reproduce a bug, you do not understand it and most certainly will not be able to fix it.
Once you can reproduce the bug you need enough information to figure out what is going wrong in your code to cause it. There is a large menu of options of what can cause incorrect software behavior, your job is to eliminate options from that menu by trying the most likely things and working your way to the least likely things. If you are lucky you get a warning message somewhere that surfaces an obvious solution. Googling reveals a typo or need to coerce an object to another type. If you are unlucky you enter the frontier of the unknown. You uncover a bug in the web framework or programming language you use. An external API behaves differently than its documentation suggests. All sorts of crazy things can happen and go wrong in software, so when it comes to things you believe to be true: trust, but verify.
How to Build These Skills
Many of these skills involve coding in teams and working with users. While you are now one step ahead of your peers by reading about them above, you will only master them through practice and experience. The best way to get this practice and experience is to work on real projects with other developers. Try your hand at an issue for an open source project. Submit a pull request. As long as the project is maintained, you will likely get the feedback you need to improve your code.
Today I spent a lot of time trying to figure out how to organize a controller in Rails where we needed to filter based on some query params. I was initially inspired to follow a pattern from DHH which turned out to be a bit challening to follow due to some incomplete information in the original blog post. The first thing that the blog post had failed to explain was how to organize files in a situation with the co-controllers. The answer to this quesiton is that you setup a folder with the parent controller name and then name the .rb files after the sub-controller. So in the linked example the “Inboxes::PendingsController” class would go into app/controllers/inboxes/pendings_controller.rb. The second component is that in the routes.rb file you need to be aware that the nested route for the index action must come before the route for the parent resource’s show method. So for example in this commit I made /applicants/interests works, but if I put line 12-14 below line 15, then it would try and find an applicant with the ID intersts and fail to do so.
However I also learned that the sub-controller approach is not great for situations where the client is sending the controller params. After some research I determined the best practice was to simply concede that I should check for the presence of params in the applicants index method and filter on that. It is important to note that after a while your controller can get cluttered with if statements checking for params to filter. Several friends have suggested that the natural evolution of this pattern is to extract the query into a query object that takes params and returns a scope on applicants. This way the query object is testable and my controller does not get bloated.
Finally we also have been struggling with nested controllers in relation to some has_many relationships between our models. The struggle was largely related to the fact that the Rails routing documentation on nested resources does not explain the changes that need to be made to a controller when you start using nested routes with it. However as you can see later in that thread I was lucky enough to find an old Railscast with a useful pattern.