About the talk
RailsConf 2019 - Coding with an Organized Mind by Jason Swett
Many developers fail to reach their productivity not due to lack of technical ability but for lack of mental organization and discipline. It's extremely helpful to always hold in one's mind the answer to the question: "What exactly am I trying to achieve at this particular moment?" It may sound like a no-brainer. However, many developers often can't answer this question. Here's how you can make sure that you always can.
I've worked with a lot of different programmers in my career so far. Some programmers I've worked with have been super productive. Other programmers although they're just as smart. They're not nearly as productive. It made me ask why is that why are some programmers super productive and and others aren't nearly so. And the answer you that I've been able to come up with that question is topic of my talk today. First I'm going to talk about the consequences
of coding with a disorganized mind contrasted with the benefits of coding with an organized mind. And then I'm going to discuss kind of three phases of organizing your work. The first is defining your work breaking a project into small discrete tasks. The next is setting up your work mainly using to do list and stuff like that. And then lastly after you've defined your working set it up. How do you actually carry out your work? First little bit about me. My name is Jason sweat. I'm
a consultant and I've been working with rails for about eight years now. I host a podcast called the Ruby testing podcast and another one that's coming out soon called rails with Jason. I wrote a book called real testing for beginners and all my stuff is at code with Jason. Com, which is mostly focused around rails testing. Okay, so organized vs. Disorganized. When you're disorganized basically, everything sucks, you know things are chaotic. You aren't achieving things in a reasonable. Of time things are stressful
and you'll probably experience something called psychic entropy, which I learned about from the book flow by mihaly csikszentmihalyi a basically. It's like you've ever try to like read a book and watch a TV show at the same time. You're not really watching the show and not reading the book. It's a sad State of Mind where you're like just jumbled and I find a lot of lot of programmers are in that state of mind a lot of time where there's kind of jumbled and not focused on any one particular thing. The opposite of that of course is that you have order you'd successful you sit
down to build a feature and you don't have to go all down all these different dead in pasta to finish it. You just sit down and do it and you're in a flow state which again is from that book flow, which is a state of enjoyment. You kind of forget about the passage of time. You're in the zone and you get your work done. My clicker is stopped working. So has the right arrow on my computer? Okay problem was apparently with yourself. Okay. So how do we take a project and break it down into discrete task to talk about two things breaking project into user
stories and then breaking those stories down into tasks most of the user Stories part. There's a really common problem with designs that you get as a programmer, which is that the bead designs don't make sense when you get a anybody experienced this there like hey build this it's like why can't feel this if it doesn't make sense. So at the risk of stating the obvious and I think I'll use that phrase a lot in this talk is a lot of this is the stuff that a lot of people might
consider common sense, but the designs have to make sense before you can start the work or even start estivation. But how do you make sure that the designs make sense? There's a methodology that I've been using for several years now, and it's pretty much guaranteed to work. It is known as usability testing has anybody here done usability testing in the past. So the great thing about usability testing is it forces your designs to make sense? Cuz when you go through the process of usability testing it leaves design defects no place to hide. The way that it works
is that at least the way that I've done it is all dry out designs on a piece of paper just pen and paper prototypes. And I'll sit down with somebody who's representative of the end-user who's going to be using the program. And I won't ask the person. What do you think of these designs? Cuz if you ask somebody what they think of the designs will say, oh, it's good. But really, you know, then you try to use it and everything falls apart. So what you do is you lay out a series of tasks jobs that you need to do using this design and you stay
who's the design try to use this design to do what you need to do and I'll give the person the pain they can fill out forms with a pen click on stuff with the pan and I'll act as the browser they'll pass me the sheet when they submitted it and I'll pass the subsequent page. It works cuz it's a pretty realistic simulation of actually using the software. But of course you haven't yet gone through all the time and expensive actually building it. And what I found and this is really really interesting. I found that every single time time of done
usability testing on the first round. I've discovered that my design is way off. That's that's with my designs and I consider myself a pretty good UI designer. Although not graphic designer, but pretty good UI designer and my designs are always way off on the first try. That's probably true of everybody even a lot of professional designers. Don't we discover in those first rounds that the design is way off go back. We work it bring it back do another round of usability testing do that a few times and usually it takes two or three rounds and then you finally have
something that makes sense and you can implement it that has a couple really nice benefits one. Is that a you know, that it makes sense but be everybody who's been involved in that process so far they know exactly what's being built. So nobody's going to be surprised. Have you ever gone out to build something and came back and said, hey I'm done. Isn't this great and the person is like this isn't what I thought we were building. So this completely eliminate that possibility and one of the best part is it removes fuel for bikeshedding. So we've all experienced this
where people are looking at the designs and saying I think the field should be like this. No, I think the field should be this way instead and there's no way to tell whether one person's right or the other person's right usability testing takes out most those conversations because no longer are you just sitting there arguing about what's better? You've tested it so you know, what better? Is a couple example usability testing scenarios? Let's say that I'm building an appointment scheduling system Winston the apples Apple calls to schedule an appointment for 2 p.m. On Monday
at the appointment to the calendar. So that's what the subject would have to try to use the software to do if it gets stuck. You don't give him any hints or anything like that. If a person gets stuck that's a sign there's a design defect the design isn't easy enough to understand and the design needs to be reworked. So then once you've gone through that process maybe you've done that with several screens in the project that you're building each one of those scenarios can be translated into a user story. And
I seen a lot of people in the room are familiar with with agile methodologies and terminology, but just in case anybody's now when I say user story, I just mean one, you know what you might call it a ticket. Whatever would be your your issue in your issue tracker. attributes of a good story and this is another another case of being at the risk of stating the obvious, but I've seen a lot of stories that that violate all these principles. A story should have a clear and descriptive title. So like ability to schedule appointment is
a good title. Something like appointments is a bad title, but he's just like a one-word user story title. That's that's not good. It should be clear. It should be obvious what it means for the story to be complete. So there's somebody looking at this story for the first time without any context. They should be able to read the description of the story and have a pretty good idea of like if I'm the Q a person Q Angus to see if it's done or not done. I can just read was here and tell whether it's done or not. There's kind of two parts to that
one is the particular story and the other is for any story that you work on. What does it mean for it to be done? So is it done when it's code complete is it done when it's Q8 and deployed to production and verified in production or somewhere in between that should be decided for all the stories that you ever do and then also individual free story. Stories also shouldn't each day each shouldn't be more than a few days of work. The reason I think that is because if you've ever experienced the alternative a story that supposed to last like a week
and then it drags on for like 3 weeks. That's a pretty big deal and it happens more than you might think and then by the time you're finally done with it, it's like super long time later, but if a store is only supposed to take a day it takes 3 days. That's not such a big of a deal. Okay, so that's defining the work saying what are we going to do? Now let's talk about setting up the work now that we know what we're going to do. Let's line it up for execution. So again at the risk of stating the obvious I'm going to talk about to do list. What's the
purpose of a to-do list? For me, the purpose of a to-do list is to always know was Zero ambiguity. What am I trying to accomplish right now? That's what I that's actually what inspired me to give this whole talk is working with programmers pairing with with colleagues and realizing that if I asked him the question right now, what are you trying to accomplish? I don't think they'd be able to answer that question. So we should always have an answer the question what exactly am I trying to accomplish right now?
So my to do list items come from the user stories in my projects. So hopefully, you know, I'm working somewhere where we work in Sprints of of one or two weeks in at the beginning of those prints. We each tackle a note a number of user stories. We each pick a handful of user stories to commit to for that Sprint and then each day, I'll look at my user stories that I've committed to for that Sprint and that'll be the start of my to do list. That's the main place where my to-do items come from, but there's a little more than more to it than that for
me. So when I'm generating my to do list for a particular day, I'll start at the very highest level in this might sound silly, but I'll really start at the highest level. What do I want to accomplish in my whole life? And what do I want to accomplish this year this month Etc? Cuz it's really really easy to just do your day-to-day work and then you find yourself, you know, 35 years old or whatever and it's like wait a second. I wanted to do all this stuff with my life, but I didn't and now I'm like old.
So I think that's a good thing to keep in mind every day and I actually have a list of things on the wall things. I want to accomplish in in 2019 and I really do make my to do list match those things. I also go from from coarse-grained fine. Grain. I'll talk more about that in a little bit. So here's here's how we go from coarse grain to find grain. So a user story is usually too broad to really be tractable and then to actually start working on it. Like if we have a user story of
adding an ability to to schedule an appointment text Lee even though it's pretty crisp. It's it's not small enough to work on. So think about it this way my big picture goal is to get this appointment system working. That's kind of a project level goal. Then I'll go down one level from that and I want to add the ability to schedule an appointment. One level down from that. I want to add the ability to add a patient to to an appointment cuz it's it's a little bit too hard to think about it like okay adding the ability to schedule an appointment. What does
that mean? I have to start somewhere. So say OK, I want to add a patient to the appointment. But even that is too broad cuz it's like okay. I want to add a patient to an appointment. But how does that work? But you are wise how does a patient get added to the appointment now, I have to think about like do I start with the view code for the controller code for the model? Where do I start salgo even finer grain and say I just want to get a patient field to show up on the appointment screen. I'm not worried about getting anything persisted to the database or anything like that. I just
literally want the field on the page. It doesn't even have to have the right idea or anything like that. I just need to be able to see it with my eyes. And then once I have that in place, I'll create several other to-do list of a similar granularity. So I start my day with a draft to do list. It looks kind of like this. I always have two sections to each day's to-do list a personal section and work section. So in a particular day, I might work on my railsconf talk in an oil change for my
van or spatulas on Amazon. And then for work, I'll start my day with just a couple goals. So I want to add the ability to save an appointment and cancel an existing appointment. I know that I'll work on more stuff in that day. But this is enough to get me started and that's really the job of this draft to do list is just to get me started on my day. What I don't want to do is sit down and be like, okay, what do I want to work on and then like randomly grab some stuff and then like 2 hours later. I like and kind of halfway done with multiple things. That's
that's bad. So if I can just sit down and immediately start being productive. That's that's really good. And by the way different people work differently, but I think this is true of probably more than half of of people which is starting in the morning really makes for a whole. It makes the whole pulled a much more productive if you get an early start in the morning and just hit the ground running with with getting some actual work done. There's this term they called The Rudder of the day. So so many people have
found this phenomenon to be true that they call that first hour of the day the rudder of the day. If you start off productively than the rest of the day will be productive you start off the day and it stayed of psychic entropy checking Twitter and Facebook and all that stuff and email and it makes your mind jumbled. It lasts for like the whole rest of the day. I don't know why that is but it's definitely the case for I think probably most people Okay, then I'll maintain my to do list throughout the day. The main thing that I want to emphasize here is that I'll take each of my
to-do items and I'll expand it cuz again like when we were talking about the course green versus fine grain to lose ability to save an appointment is too coarse grained. So I'll keep a list of things that I want to do in this particular case of like list out all the tests that I want to write for this feature. So what I'll be doing that all day, I'll start with coarse Grain list items and then expand them into fine-grained ones. Okay. So now that we've defined our work and we set
up our work in the form of to do list. How do we carry out our work in a way that's fast and efficient? And a touchdown Four Points Focus work sessions Atomic commits. small short live branches and small frequent deployments So Focus work sessions. I'm a big fan of closing email and closing slack while I'm working and I don't close email and flag for like the whole entire day or maybe close email and flag for an hour. And then like let's say I start at 8 a.m. At 9 a.m. I'll give myself permission to like have a treat and open up my email and slack and check on my
messages and stuff. It's kind of more fun that way because like when you get it all at once rather than being peppered with messages all throughout your work day and being distracted. So I don't like disappear for a whole day or anything like that allow pop up about once an hour and give myself like 2 or 3 minutes of checking email and slack and doing that. It helps emphasize like just how it's not important. Most of these messages are that you get through these channels. And then Twitter and Facebook, like I work with people who have Twitter
notifications popping up in their upper right hand corner. That's just insane. Those have no value and they just distract you and it's it's Madness. So don't do that and probably don't have that stuff on your phone either. Like I don't have those apps on my phone at all. And now that it's been like it's been well over a year since I've had Twitter or Facebook on my phone and I look back and it's like why did I ever have that stuff on my phone? It has no enjoyment to a person's life at all. My life is not any worse,
but it's better since I deleted those things off my phone. That's kind of a separate topic though. But I guess the point is at Twitter and Facebook are are poisonous and stay away from them as much as possible. So in addition to those things clearly State your current goal and you related tasks using those nested levels of granularity that I described earlier. Atomic commits So something that really frustrates me and is is counterproductive is when you
have commits that are several different pieces of work some of which are in a partial state of completeness. it makes everything hard and maybe the easiest way to explain why it makes everything hard is to explain how it's better when you don't do that to each should just be one single piece of work and I like that because Everybody makes mistakes, I make mistakes. And when I when I make my commits small and they're just one single thing. It's so much easier to roll back
something like if you've ever had the experience where you commit something and it's like this. Big chunk of work and then this little part of it that's mixed in it ends up like introducing a bug or something like that. You want to roll back the bug but now you have to roll back this whole piece of work because it contains a bug and an unrelated piece of work. So that sucks to have to do that. It's better just to have each commit be an individual piece of work. If you have a commitment introduces a bug and you need to roll it back then you can only roll back that one commits, and
it's much tidier to to fix it. I just give you a feel for the size of my commits. I tend to commit every 5 to 15 minutes part of what that allows me to do is clear my mind once I've commit something I'm free to no longer. Think about that thing cuz it's on the books. It's done. I can just forget about it. Go to place this is helpful is when I'm doing get bisect to try to find the place that a bug got introduced small atomic commits make by dissecting a lot easier. And if you're not a big get bisector
as a side note, I highly recommend get bisect. Okay, small short-lived branches Has anybody ever worked on a feature where the branch lasted like weeks or maybe even months? Whoa, I didn't expect that many people. That's horrific. Okay. I have to so it's risky when you have a branch that lives for a long time. It's diverging every day that you work on it. It's diverging from the master branch that makes it so when you integrate it to it's more risky. It increases the chances that when you try to integrate the two you're going to have some conflicts.
So that's bad in the more branches you have and the longer they live the more confusion and overhead it cost like I can think of projects. I've worked on in the past where at any given time we have like dozens of branches going at the same time and it's like you forget about what was this Branch for again? Is this work still important? Do we need this it it's much more difficult to manage much more time-consuming to manage than when you just have Master Branch off Master merch back in Branch off Master merch back in and those branches only live for like
a day or less than a day or a couple days at the very most. A common objection to having branches that only last like a day or two is that like what we're working on this feature. We can't release this feature and a state of partial completeness speech has to be done before we can release it so we can have a branch that only last a couple days. So the way people tend to address that is using feature Flags. The idea behind that is that you're separating the idea of deployment from the idea of release. So what the feature flag?
I might have let's say I have a user profile page and I'm adding a bunch of newfields to it. And I don't want to release it until I had all these all this new functionality. I'll put that behind a feature flag. So it's invisible when the feature flag is turned off. That way we can we can still deploy that code in a state of partial completeness still have branches that that only live for a short. Of time and still have user stories that that are very small and and I tend to have each branch corresponding to just one single user story.
And then when it's when it's finally done, even though you've been to playing at the whole time, you can turn your feature flag on and that feature will appear. It also makes it easier to roll back features if you roll out of feature and it and it has like an under for seeing negative consequence. For some reason you just turn that future back off. And get flow is horrible because of those reasons I listed earlier get flow involves, like all these different branches. So there's so much more overhead to managing all that. My preferred way
of working is like I kind of mentioned earlier you just have Master Branch off Master for each story and then merge right back into master. Small frequent deployments are advantageous for the same reason that small frequent commits are advantageous and that has to do with the detergent. Maybe experiences the scenario where you do a big deployment and the deployment causes problems and there's a lot of fire fighting and damage control that has to happen after the deployment. And so leadership says Okay,
that was a terrible experience. Let's deploy not as frequently anymore. And so then you deploy less frequently. And so your deployments are even bigger. And so even more things go wrong each time. You deploy that's bad, of course. So the way to take care of it though, the way did not have those issues is deployed as frequently as you can because then each of your deployments will be as small as possible. There's less stuff to go wrong each time. Baptizing of concept of parody. It's helpful to keep your development environment and your production environment in his
clothes of a state as possible at all times. Cuz we've all dealt with those bugs that only appear in production which are really hard to troubleshoot. So if you always keep production and development as close as possible, it reduces the likelihood that those scenarios arise both in terms of infrastructure and the co this living in the environment. So these are takeaways that I'd like you to take away from the stalk. Verses in the beginning when you're defining your work
iron out the flaws in designs by using usability testing cuz again that will that will force your designs to make sense to leave the defects no place to hide. And make sure that every story is crisply to find again. I should have a clear easily understandable title. By reading the body of the user story should be able to tell exactly what it means for that story to be complete. Write down everything you're going to do and always be able to answer the question what exactly am I
trying to accomplish right now? And work in small units using Atomic commits and frequent Integrations and frequent deployments. Okay, so if you want to learn more about this stuff and and the other rails topics that I write about it and go to the code with Jason. Com, or you can email me at Jason at code with Jason. Calm, and if you have questions afterward, I'm not going to do Q&A up here by bee. I'm going to hang around out hang around in this room after
Buy this talk
Access to all the recordings of the event
Buy this video
With ConferenceCast.tv, you get access to our library of the world's best conference talks.