 First of all, I just wanted to start off by thanking the organizers. They've really put in a lot of effort to make me feel really special as a speaker and also as an attendee watching these other talks. So I just want to give them a huge thanks. Can I get an extra round of applause for the organizer? And also, thank you for, thanks everyone for being here. So I'm Blythe. You can find me at Blythe on Twitter and GitHub. I work for a company called Big Nerd Ranch. It's based in Atlanta and some people know it, all right? It's based in Atlanta and I work remotely full-time in Oakland. We do a couple things at Big Nerd Ranch. We develop apps, we write books, and we also teach courses. And of course, we're hiring good people always. As you heard, I used to be a scientist. I have a PhD in physical chemistry. And a lot of people ask me, what is physical chemistry? What does that mean? Well, if you think about it, it's right on the border between what you know as physics and what you know as chemistry. And that means I've spent a long time in grad school. It also means I've done a lot of experiments. And a lot of people ask me, how did you do it? How did you make it through six years of grad school, make it to the end? And I did it by using the scientific method. And I'm still using it every day. I'm a developer, but I'm still using the scientific method every day. How many of you have gotten an error, Googled it, pulled the first answer straight from Stack Overflow and put it in your code and run it? I think we've all tried it. We've all tried it. And did it solve your problem? Maybe it did. Maybe if you were lucky. But probably not. Most of the time, probably not. And it was pretty inefficient. And the more important question is, did you learn anything from that? The most important part of troubleshooting is learning. If you solve a problem without learning from it, it's only a temporary fix. It's either going to come back later or you're going to make the same mistake in the future. Learning is how you level up as a developer by learning from your experiences. And that brings me back to the scientific method. How can using the scientific method help you level up as a developer? Well, what even is it? Well, if you Google it and go straight to Wikipedia, you'll see this definition. It's a set of techniques for acquiring knowledge. And I love this definition because it can apply to anything, any career, including being a developer. The scientific method, it's methodical. It's an established procedure. And scientists have been using it since the 17th century. It's also systematic. It's a step-by-step process. And it's for gaining knowledge and incorporating that into your process. And a time for reflection is built right into the scientific method. The other day, a coworker of mine popped up in the company chat room and said, has anyone seen Ruby string interpolation fail? And I thought, that's a pretty interesting question. Why are you asking that? And so we dug a little deeper. And they were using factory girls sequencing method to create a series of users with unique email addresses. So email one, email two, email three. And it wasn't working. It was failing. It was trying to create users with the same email address. And it was failing. And they couldn't figure out why. And their solution, they ended up just like rolling their own sequencing method, and while that may have solved their problem temporarily, that wasn't really the most elegant solution. And it turned out, the real problem was just that they were missing the hash symbol that's required for interpolation. So simple mistake, but we've all made simple mistakes like that. We all make them all the time. But maybe using the scientific method would have helped in this case. The first step of the scientific method is defining the problem. As a scientist, this means saying, what is the information that you're trying to gain? What knowledge are you trying to gain or learn? What's important to keep in mind when you're defining the problem is forget what you think you know and question everything. Just think about, open up your mind, question everything and just define the problem. It's also important to get rid of your emotions at this point. You want to, maybe you're on a tight deadline and maybe you think you know what the answer is and I'm just going to go do this. I already know what's wrong, blah, blah, blah. Get rid of all that and just define the problem. And you can do that by answering a few questions. What is the behavior that you're expecting to happen? What's actually happening? And how are those two things different? And how will you know when you've solved your problem? What is your criteria for success? This is particularly important when other people come and ask you to help them troubleshoot. Don't listen to their assumptions, get rid of that out of the way and just start from scratch and answer these simple questions. What do you want to happen? What's actually happening? How will you know when you fix the problem? Once you've defined your problem, you can start by doing some background research. And in reality, you guys are already doing this. Everyone's doing it. In grad school, we would just be constantly reading. Before we would ever start an experiment, we would just be reading for days and days and days. Reading recent articles or sometimes really old articles that we had to go to the library and dig up. We were just constantly reading. And the reason is because you want to have enough background information so that you know that you're starting with the right experiment. As a scientist, it's really expensive. It costs a lot of time and money to do an experiment. So you want to make sure that you're starting with the right experiment. And you do that by making sure you have enough background information. As a developer, you can do that by knowing your environment. So you need to know the language that you're working in. And you can always become a little more familiar with it. Go dig in that dark area that you're unfamiliar with. How does this work? What's going on here? When you're working on a specific application, you can look what are the dependencies that you're using. Get to know those. And even which versions of those dependencies are you using? For the case of the factory girl sequencing, probably just taking a look at the documentation might have helped. Oh, I'm missing the hash symbol. That's it. You also want to be reading the literature. You want to stay up to date with blog posts. Always be reading what's coming out, what's new. There's always a lot of content out there, so you want to be reading it. For your specific dependencies, you can look at the readme's or the change logs for the most recent versions, what's changed, what's different. You can also look at the specific source code of the versions that you're using, either on GitHub or just using bundle open and the gem name. You can pull it right up, right on your computer, and dig around in there and look at what's going on. And also, a helpful thing is to look at the test suites of those dependencies that you're looking at. Sometimes that helps you tell the expected behavior of the gem, what's supposed to be happening. Another helpful source of background information is just discussion with your friends and colleagues. Maybe they've already encountered your problem and they know the perfect solution, the best first experiment for you to start with. That's really helpful. Particularly when you're struggling on a problem, maybe you've been working on it for a long time and you're not getting anywhere, it's time to get up and go ask somebody for help. Have you seen anything like this? And that's exactly what my colleague did. They popped in the company chat room. Hey, I need some help on this. We have a rule at Big Nerd Ranch. If you're working on something for more than an hour and you're not making progress, it's time to stop and go ask somebody for help. It's better to get help from other people. And of course, sometimes the good old rubber duck is a good helpful solution. Maybe the rubber duck doesn't talk back, but just by explaining your problem and how you got there is a good way to get ideas. You also want to make sure that you can replicate the problem that you're having. Make it fail. I mean, can you even reproduce it? Is it an error that you can reproduce? And what are the steps that it takes to do that? Once you have that information, you can go ahead and write an automated test to help you solve that problem. After you've gathered a lot of background information, you can then establish a hypothesis. And a hypothesis needs to be educated and based in evidence. So this goes back to all the research that you've been doing. And it also needs to be something that you can test. So this goes back to defining your problem and your criteria for success. So once you have a hypothesis, then you can start to design and experiment. And the most important part of experiment design is that it tests your hypothesis, of course. Don't do an experiment that doesn't test your hypothesis. A couple of tips for designing an experiment. One good thing to start with is just dividing and conquering your code base. Well, first of all, hopefully you've written an automated test. So you can just run that test over and over again to focus on the condition that you're working on. So that isolates a lot of other behavior that you don't need to test immediately right now. Of course, you can always comment out big chunks of code. If you're like, I know this stuff is working, let me kind of comment it out and just run the parts of the code that I need to look at right now. Break points are excellent, helpful way to do it. Say your code has to go through 10 steps and only the last one isn't working. Go ahead and enter a break point or a binding.pri right in there. You can stop and just look at the code that's broken, that's not working. You can also, say you suspect that there's a problem with a dependency or a gem. What you can do is maybe create a new app and only use that one dependency or API. Are you still having the problem? Okay, well maybe you just got rid of all of the other code that you had written and you know it's just with that. You can replicate it in a fresh app. That's another way to isolate the code. Another important thing is to limit the variables that you're testing. When you look at beginners troubleshoot, sometimes they try to change many variables at once. Maybe it's a problem with the controller over here and the view or maybe it's in the model, I don't know. And sometimes they get down a road that's really hard to come back from and they can't even answer the question, what has changed? So you really don't want to do that. You want to limit your experiment to one variable at a time. Let's test one variable and finish our experiment before we start another one so that we know and we need to make sure we do the analysis part of the experiment. Don't be afraid to try something weird. Sometimes you're thinking, ah, this is never going to work but I'll try it anyway and you try it and you find your solution. Don't be afraid to do that. Try something strange. You can also try maybe try something that you know is going to break your program. Go throw some gibberish in there, type it in there and you know it's gonna break it. You know it's gonna make it fail. What happens when you run your program and it doesn't fail? Maybe that code was never even getting run. Maybe you're not including that file or something. So try something strange. A friend of mine told me a story the other day about how they had created a table and any time they were trying to do a join with that table it was throwing some obscure error and they couldn't figure it out. What's wrong with this one table? What's wrong with it? And so they ended up, they just, they got rid of the table and they created a new one and they named it bananas. Just something weird, like do it weird. And that actually fixed their problem. So bananas worked. And they was just like, what is going on? Why? Why does that work? And it turned out they had named their original table attributes. So of course that's a protected name so it didn't work. So trying something weird, naming the table bananas, that worked for them. How many of you have ever done something like this? Where you dig, you super deep dive. Yeah, you're like, oh it's way down here. There's some weird problem. And it ends up being just right on the surface. Something simple. When you're designing your experiment you want to focus on, think about the hierarchy of blame. Think about, okay, what is the most likely candidate for this problem? Once you've eliminated the most likely candidates, then you can go on to the harder problems. For example, more recently changed code is probably more likely to be at fault than code that's been in production for a long time. And something that you wrote is probably more likely to be the problem than say something in Ruby. But through your experiments, go ahead and eliminate the most likely candidates and then work your way down. Don't start by trying to figure out what's wrong with Ruby. After you've designed your experiment, go ahead and carry it out. And you're going to start gathering your data that you're gonna use for your analysis. So you need to think about, okay, what's the current status of your program now? What's happening now? Were there any changes? Are there any new messages? Are there any new results from your experiment? What else changed recently? Were there any other things that you had changed? What did the log files say? So you can gather all that information. And this one may seem obvious, but it needs to be said even for senior developers. Read the error message. Just read it. Read it out loud. Even that alone will help it. Just read it. Take a look at the stack trace. Look at the line number. What's going on? That's very useful information for a reason. So gather that information as part of your experiment. Once you have all your data, you can start doing your analysis. And you really don't wanna skip this part. This is the most important part because this is where the learning happens. This is where you level up as a developer. And it's built right into the scientific method, so. So now that you've done your experiment, did it solve your problem? That test that you wrote, is it passing now? And what about all the rest of your test suite? Make sure it's also passing. Make sure that you've solved your problem without breaking something else. And make sure that you've met all of your criteria for success. And you also wanna think about what did you learn from that experiment? What information can you get from that? Don't just move on to the next thing and say, okay, it's fixed now, let's go. And take a moment, take the time to reflect on your experiment. What went well, what didn't go well. Think about that. And most importantly, you need to understand why you solved your problem. Have you ever said, well, I don't know why it works, but it works. I have news for you. You didn't fix it. You didn't solve your problem. It's the understanding that cements the knowledge in your brain. And that's what makes you a better developer. And for those of you who are in leadership positions, maybe you're teaching a newer developer, it's important that you make sure that they understand the why. So make them explain it to you. Why did this change solve your problem? Your results from your experiment will also help you determine what's going to happen in your next experiments. Maybe you solved your problem already and you don't have to do another experiment, but it will influence your experiments in the future. Maybe now you know a better first experiment to start with. I know, I know the fix, I'll start with this next time. Or if you didn't solve your problem, maybe you have a new error message. Okay, you can work with that. Now what's the new experiment? Or, oh, maybe it's a problem with this gem. I should go do more background research on that. Another important part of the analysis is embracing your successes. This is really important. A lot of people, they sort of skip over this part and just go back to work. But it's really important. If you did solve your problem, let that sink in, because that's gonna drive you for future troubleshooting problems. You need to remember all those problems that you've solved before and know that you can do it and that you can keep going. And even if you didn't solve your problem this time and you're still working on it, maybe you got a new error message. That's progress and that's something to be celebrated. Another important part of being a scientist is keeping a good lab notebook. And the reason you do this is because it tells the story of your experiences, either to you in the future when you're going back to look at it or to somebody else, maybe another developer in the future. So this is a picture of one of my lab notebooks from grad school. I probably filled about 10 of these and there are like 300 pages each. So I did a lot of documenting in grad school. The reason I included this is just to say, it's okay to have a paper lab notebook and write down the things that you're doing. That's okay. Digital works also. And the reason you keep a lab notebook is because you're just not going to remember. You're not going to remember. As a grad student, we probably did about 20 to 30 experiments a day, each just changing one variable at a time. And there's just no way we would have remembered all of the things that we had tried. And think about how many experiments you do as a developer each day when you're troubleshooting. And maybe you think, okay, well, I'm already just recording all this stuff in the logs. It's all saved over there. I can always go back and look. But that's not a sufficient lab notebook. Too much information can be just as bad as too little information. So it's up to you to glean the meaning from these experiments that you're doing and record that. One of the best first steps for keeping a good lab notebook is writing a good commit message. It's all fresh in your brain. And so maybe you've solved the problem so you're gonna commit that change and push it. So write some explanation in that commit message and let people know what's going on. And people will see this in the future. Either you'll come back and look at it or maybe another developer who's working in the code base will come back and look. Additionally, if you added a test for the scenario that you're working on, that's also a good documentation for what's going on. Okay, this was a problem. We've added a test for it now. Also, right after you solve a problem, you wanna update the documentation. Is it missing anything? Did you have that error because the documentation wasn't good enough? So go ahead and go update the readme or maybe you were missing some environment variables. Go ahead and set up an example environment variable file so people know, hey, you need this thing to save them that time. So that's all part of good documentation. So keep that, set that up for other people. You can also contribute to open source. So say you find a problem in somebody else's software or gem, go ahead and let them know. So open up an issue on GitHub if it doesn't already exist. Let them know the steps that it takes to recreate this problem. If you were able to write a test for it, go ahead and submit a pull request with that test. Sometimes that's helpful, even if you don't know how to solve the problem, that's helpful for maintainers to say, oh, this is a test that's failing. And of course, if you do know how to solve the problem, go ahead and submit a pull request for that. You just got some open source contributions and that's awesome. You can also write about your experiences. Have you ever written something up and then later down the road, you're like Googling for that same problem and you come back and you find your own blog posts? Yes, yes, and you're like, man, thank you so much, old me. That was really helpful, thank you for writing that down. So think about all those other people out there that are getting the same reaction when they find your blog posts and they're like, man, that was a really helpful blog post. Thank you for writing that down. So if you're not doing this already, you should be doing this. Anyone can start a blog. If you don't already have one, go start it. You can also write failed experiments. Don't be afraid to do that. In grad school, we always joked about starting a journal of failed experiments and that way we would publish a million papers that way, like, well, these are the million things that we tried. They didn't work, but that's okay. If you, sometimes that's also helpful and maybe somebody comes along and reads this and can help you and say, hey, you might try doing it this way. That might solve your problem. The most important part about keeping a lab notebook is sharing the knowledge. In academia, it's all about gaining knowledge and then sharing that knowledge, either through publications or through teaching. And I think developers can really learn a lot from that. So as you're doing these experiments, go ahead and share that information. Maybe tweet about it or blog about it, like I said. Or you can even come and present a talk at a conference like this. Hey, here's this weird thing that I figured out. Let me tell you about it. So that's really the most important part, is sharing that knowledge with other people and teaching it to other people. And so I'm really looking forward to seeing all of your lab notebooks online soon. Thanks very much.