Greetings. I'm Professor Seth Frey and we're going to talk for a bit about debugging. We're looking here at a blank screen now already we're intimidated because there are ways that this is not a real programming course. I'm teaching you to be able to read code, to skim code, to run code, more than anything trying to motivate code, making it something exciting so that you'll take Course 2, Course 3 and keep going and building. Or at least feel like you have more of a literacy, more of an understanding what people are talking about when they're talking about it, and more like less like a stranger in the world of code. The one major thing this course is laid on is the amount of code you're writing from scratch. My course is not alone in that. There's a lot of courses that you come out feeling like you know what you're doing, and then you're provided with this blank screen and you're just paralyzed, you're just lost. I'm going to write up some code. There's going to be errors in it. The major point of this is I'm going to show you, we'll just walk through writing code from scratch. But separate from that, I'm going to show you when your code doesn't work, when you wrote some stuff and it's not doing what it's supposed to do and you're just stuck or paralyzed, what do you do then? We're going to walk through that. What I wanted to do was I want to take a list of scores of sporting events, and I want to filter out the ones that are soccer scores rather than basketball or what's another high scoring game? Maybe, yeah, I want to distinguish soccer and hockey scores from basketball scores. Here's going to be my data and then we're going to solely work through what's going on. Here's an example of a soccer score. Now, here's an example of, here's another. That's a reasonable outcome of a game. Here's a basketball score. We've got like 90-62. This is a bad one. That's pretty unbalanced. We've got really low scoring basketball, but high scoring by global standards. What else? I'm just keeping going and great. Good. There's a bunch of scores and what I want to know is which ones are soccer scores. I'm going to initialize this empty list. Then what we're going to do, I want to loop one by one through all the scores and find out which ones are soccer scores, which ones are not. How are we going to do that? Well, there's a couple of signatures of a soccer score. It should have a hyphen here. Let's put an example of a bad score that's definitely not any sports score, so like 4 4. There's no hyphens, so now we're going to count that as not a score. That's one test. We could look for ones that are essentially strings that are just three characters long. If they're five characters long there from a high scoring game. But if there are three characters long, one digit, a hyphen and another digit, then they're from a low scoring game. That's one another signature. Obviously they should start or end with a number. Here we'll give another example of a bad score, 2-2. I would consider that outside of what we're up to. Maybe it's on the right format. We're just coming up with rules. Three criteria if it's three long, if it maybe starts with a number and ends with a number, and if it has a hyphen in it, then it's a legitimate soccer score. Let's see, for scores in scores. First I'll do the test of the first thing is a number. We'll do indexing and then we'll see is the first element in the list of all the numbers, is how I'm going to do that. Let's see. Scores in, great. If it's in there, then I'll run my second test, which is, is there a hyphen in it? Let's see. Hyphen in score. If it passes that, I'm going to run another test. Let's see. What's my other test? I guess I wanted to see, Oh, yeah, it's three long. That's not right. That's completely wrong. Length of score equal to three. If all those tests pass, then I want to add it. I want scores. Let's see, scores_soccer equals scores-soccer.append. We're going to add the score that passed this test to the end of the list. Then we'll finally print out. Great, then we'll print it out. This is my code and what it's doing, line by line is taking a bunch of data. It's also initializing like the output list, the list we're filtering. We're going to put everything we filtered out to get in there. We're doing a for loop. Then for every item in the for-loop, does it begin with the number, does it have a hyphen in it? Is it three long? If so, add it to this list we defined up here and then print that list out. Good. Maybe you've noticed that there's mistakes in here. Let's say I didn't know that because this is, right now you know it. But maybe you didn't catch all my mistakes, or maybe you're going to make mistakes in your own. We should pretend we don't see mistakes in here and see what Python tells us, and see how we can follow the hints that the code gives us for isolating those errors. Let's see. We run this, we get in there. Already, there's ugly lots of red. It seems to be referring to the first line. I'm actually seeing a little caret here telling me where it found the error. Now, what's it saying? Is it saying that this here apostrophe is the error? No. It's saying that that's where it got when it realized something was wrong. You want to look around there. What I'm going to do is I'm going to be like, oh, well, every item in this list should have a, if they're separate items, they should have commas between them. If I add a comma, that will fix it. That's one solution. But we have to ask, is that what I intended? Is that what it was supposed to happen? Actually, I think I just like mistyped that shouldn't have been there at all. I think I meant to type 30-40, but I typed an extra three in there, so I'm deleting it. Now we're going to run again. What do we see? Invalid syntax. I have another syntax error here. What's it seeing? Well, it got here by reading everything before it. It starts on the left and then reads to the right. If it found an error here, then the error is probably further back. Lo and behold, I'm seeing that I put two apostrophes, so we fix that and put one apostrophe. Great. I think we're good. I feel good. Run it again. Now we made two different line, invalid syntax on this line here. What's going on in this line here? We're in the for-loop and then we're doing our first test. What's going on here? I was doing if statements. But it looks like it doesn't like my colon because it looks like I just forgot to type if. Let's type if. I think that fixes it, except wait a second. I didn't type ifs on any of my if statements. I'm realizing. What I'm doing is I'm reading there invalid syntax that says I did something basically wrong with the basic elements of code. Then I look where it pointed me. I just remember what I know about Python and try to compare that to my intentions and try to compare that to what's in front of me, what I'm seeing. I know my intentions was an if statement. I realize eventually that I don't see the word if. We'll run this again. I fixed quite a few mistakes already, so hopefully we're making progress. Into object is not subscriptable. This is an error message that if you don't know what you're doing, if you're just learning, if you're at the beginning of that learning curve, this can be a pretty paralyzing error message. People tend to know what to do this. Let's read the error message and see what we can figure out about what's going on here. Let's see, well, it's in this line. It's talking about subscripts, basically it seems like it's saying I'm trying to put subscripts, I'm trying to subscript index, same thing. That's some jargon. I'm trying to index something that can't be indexed. I'm trying to subscript something that can't be subscripted. What it's actually saying is that this is a number, but I didn't intend for that to be a number. This is Shelby's strings, I don't really know what's going on. I could solve it by looking back at the original definition of this and look for things that aren't strings. But that implies me knowing a lot, that's me looking behind the curtain and knowing what my mistakes were. What do you do if you don't know what your mistakes were? If you don't have the definition of the object in error handy, if you're a lot further from the data going in, this is one of the great strategies for debugging. I mean, obviously, anyone's going to tell you read the error messages, but sometimes the error messages are not informative enough, they're not useful enough, you have to go beyond just reading the error message, just seeing what line's being pointed to where the little arrow points. Here's your great tip. I could be wrong, but I'm guessing it has a problem with the variable score. Why I don't know what that problem with score is. I'm just going to see what score is before the error message happens here. I'm going to type "Print score" and I the indenting to be right. I'm just going to print score out immediately before the error message occurs. This way, I'll see what it was trying to do, what was about to happen. What I get here is the output zero, and then the error message occurs. That means that printed score, printed out score once, and then once that happened, then the error message occurred. Let's see what is score. Where is score defined? This scores the plural, this scores soccer, the score is the one I'm using up here. That's supposed to be score, but I've put another S on. I even defined the for-loop wrong. I don't actually know how score here ever got defined to be zero. That's wild. I don't know how that happened. It might be from previous time I wrote this? Yeah, maybe I didn't wipe things. But regardless, there are so many errors that some are popping, making me find others on my way to finding one. We still have this error, we're about to discover the error again. The error we would have gotten if I'd been doing this right, is that it would say scores not defined, scores not named, and that's because score was never named. Where I thought I was naming it, was here and I wasn't. We might encounter that error again. We'll see, and I'll will prepare you for that error. Now I feel like we got something, we basically got a bunch of printouts before we got an error. That's informative, and we can actually map what we get to what we see over here. This print is before any IF statements, so what should happen is that every element of scores is going to get printed out. That's what we see, the first thing that gets printed out is 2-0, and here 2-0, great. I'm guessing the next that should get printed out 3-3 and we see it 3-3. Next thing that should get printed out is 90-62, and there it is, then 30-40, then 0-0, then 4-3, but that's weird after 0-0, instead of getting 4-3 we get 1. That's weird. Why don't we get one? Well, looking here, it looks like I forgot to put my apostrophes, my quotes. What was going on is that instead of reading this as zero hyphen zero or four hyphen three, it was reading this as arithmetic, four minus three. I didn't put it in quotes, so it wasn't treating those numbers as strings, is treating those numbers as numbers. When I take one number, hyphen another number, I do subtraction, and 3 minus 4 is 1. I was getting the number 1 instead of the string 4, 3. The number 1 is an int object. We've learned, the whole point of indexing is you can index strings, you can index lists, and you can't index numbers. That's what it's saying here. It's using different words, it's calling, instead of numbers saying int object instead of index is saying subscript. We have to get past some jargon, which we can do by googling. That's actually super common, is just google your error messages, int object is not subscript-able. This doesn't, this actually tends to start working once you know what you're doing. It can be not the best strategy for the very beginner coder. But let's see how far we get. So what's going on? I'm on a website called Stack Overflow. Well, the way it is, there's the first block where someone asks a question. Then There's a bunch of other blocks below answers where a lot of people answer the question. What you tend to want to do is sometimes I just skip the question as skip straight to the answer, specifically the first answer that has a green check mark. It's talking about there's a lot of code. It looks like a really specific questions, so I'm going to just skip this one. But fortunately, there's a lot of people who've encountered this error in a lot of environments, so I'm going to try something else. Okay, Let's see. Simple piece of code. Get someone's name and age and let him or her know when they turn 21. Okay. This seems like elementary code, though, a little complicated there, that's ugly. I'm going to say this isn't, you know what I'm going to do? I'm going to also add the word beginner. You can do this. I want when a beginner encounters these types of errors. Let's see. Okay, this looks like a really short example. It's the same kind of structure is what we're going. We're using a for-loop. We have very few lines of code. Let's see. If I were to read this, what I would get eventually is that this person here has sub-scripting something. I'm going to guess that temp ends up being a number and look, temp should be a number because, this is all arithmetic. They define the number and then they tried to sub-scripting it and you can't do that. They're finding the same thing we found, which is here, that we defined a number. This wasn't in quotes before. It was just a number, and we tried to subscript it. Googling error messages. It's worth doing. What I recommend when you do it is don't spend too much time. Like look for the first couple of answers, give them quickly if you see what you're looking for good, if you don't, don't go down that rabbit hole, go to your code and play with your code. A lot of print statements. We just fix an error. We identified that there was a problem in this definition. I hadn't put quotes that was leading down the line to a very different kind of error message. The other error is we got on this line, we're pretty worried about this line. Particular error didn't pop up until a couple lines later until down here. It was kind of arcane. It was talking about something like down the line. We weren't dealing with the immediate consequences of this error because it's totally fine to define a list that has both strings and numbers, so there was no syntax error. It was more like a data quality error that this code was making an assumption. It was assuming everything you encounter would be a string and that assumption is being violated. Because we didn't check, we had no way of checking the assumption up here, so we find out it violated lines later. This is a lot of debugging. Some of your errors just pop out right away, and Python can find them right away and tell you exactly where they were, others you don't discover except down the line once a bunch of other staff has happened. This is where a lot of detective work comes in. Print, helped us so much right here. Print brought us back to the data. I printed score and I got the thing that was problematic immediately before it came problematic. That's how we were able to isolate the error, and that's a really great strategy in general.