[MUSIC PLAYING] SPEAKER 1: This is CS50 and this is the start of week two. So, let's dive right into something that is buggy, so to speak. So, over here is CS50 IDE and I've pulled up in advance this screen-- damn it. Spoiler alert. All right. I've pulled up this screen here, which has a very simple program. If we scroll down, most of this is just comments, but here in lines 13 through 17 we have a program. It's syntactically valid, which means if I compile it, it will compile and run, but it's buggy. This program claims in the comments up top that it should print 10 stars, but it does not. And based on your experience, or soon to be experience with C, can you logically discern why this is, in fact, buggy? Yeah? AUDIENCE: It goes from zero to 10. That's 11 iterations. SPEAKER 1: Yeah. So, it's going from zero up through and equal to 10, which of course is 11 iterations. So, it's going to print, indeed, 11 stars. So, the computer science convention in most programming languages is, indeed, just to start counting at zero, but count up to but not through the value that you actually care about. Now, this is one thing that takes a little getting used to and even Scratch, designed as it is for non programmers or non computer scientists and for children largely, is designed to have you start counting generally at one. And that's fine. You can absolutely start counting at one if that's more comfortable. And count up to and through 10, but you'll realize particularly this week and beyond that just so many things in programming assume that 0 is the first digit with which you count, that you're going to find it easier just to get into this habit of starting from zero and counting up to the value you care about right now from the get go. So, that has fixed that. We changed the less than or equals to just less than. Let's take a look at a second example here. So, this program too claims in its comments up top that it should print ten stars, but it doesn't. What's the bug here? So, what-- and sorry, let's be clear. 10 stars. One per line, but it doesn't. So, in fact, let me go ahead and compile this one because it's a little less clear based on that description. Let me go into our source directory. Make buggy one dot slash, buggy one. OK, I see 11 stars, which is still problematic, but they're also all in one line. What's the issue here? Yeah. AUDIENCE: [INAUDIBLE]. SPEAKER 1: Yeah. So this is a subtlety that you may recall me making brief mention of. Even though everything looks pretty, and it's nicely indented, and it kind of looks Scratch-like in that line 16 and 17 are, indeed, indented under that for loop. That's immaterial. The computer doesn't know or see white space. White space is just for us humans, stylistically. The computer does know when you have curly braces, which would, indeed, fix this problem. So, if we actually went in and explicitly put in these curly braces that would fix this problem by making clear to the compiler that I actually want to execute two lines of code again, and again, and again. But what's the fundamental explanation? Right? We don't strictly need curly braces all the time, even though it's probably best practice to get into that habit anyway even though it adds two characters to your code. why? AUDIENCE: [INAUDIBLE]? SPEAKER 1: Yeah so that's another solution altogether. Right? Especially if at first glance you don't really appreciate what's going on. Well, surely we could just do two things at once and just avoid the problem altogether. And that's fine, but now, for today's purposes, what is the explanation for the bug? Why were all those stars on one line? Yeah? AUDIENCE: It seems that if you have one line of code, you can do it without those. SPEAKER 1: Exactly. This is just a human convention. People realize that it's a little annoying or tedious to have to put curly braces all of the time if all you want to do is execute one line of code. So, humans decided some time ago that that's fine. If you want to put all of your loop on just that one line like this, that's fine with the single semicolon at the end. But you can only do one such line without the curly braces. So, when CS50 style guide as will point you to, you'll see that generally it is good habit to get into this until you're quite comfortable straying from these kinds of conventions and doing your own thing. So long as you're self consistent. And we'll talk more about style a little bit later today. So, let me open up one other program. Of course, we should fix that 10 as well. Let me go ahead and write a real quick program that I'll call, let's say, loop dot C. So, loop dot C. And in loop dot C I'm going to have, include standard I/O dot H int main void. And now let's just do, indeed, a loop. So, 4 int I gets zero. I is less than, say, 50. I plus, plus. And then in here let's go ahead and do print F. And then I want to print I and a new line, semicolon. And this should print all the numbers from zero up to 50? A few head nods. A few nos. What's the bug already? What's the easy mistake I made? Yeah. AUDIENCE: [INAUDIBLE]. SPEAKER 1: Yeah. So even though it looks like this is what I intend, recall that I is also just an ASCII character. So, if I say, print "I." It's literally going to print I. So, if I want to plug-in a placeholder value I actually need to do this and then plug-in the value of I dynamically. Otherwise I'm just going to get 50 I's on the screen. So, let me go ahead and make this loop, run it, and, indeed, we have all the way up through 49. And if I scroll back in time I see the number zero at the beginning. Well, what if I kind of screw up? What if I do this? Just because I'm not thinking. What's this program. Once re compiled and run, going to do logically? AUDIENCE: Nothing. SPEAKER 1: Nothing. Why is that? AUDIENCE: I is designed for zero. So, the condition is false. SPEAKER 1: Yeah, exactly. All the code is correct, syntactically. This will compile, this code will run, but it's not going to do anything useful because I initialize I to zero. We then check, is I greater than 50? Obviously, no, it's not. So the loop never executes at all. What if we do something a little more reckless? So, what if we do like int I gets zero. And now let me use the while loop, which was another condition. And while I say, while I is greater than or equal to zero, and then in here I go ahead and save the file, make loop. And I'm about to run it. What am I going to see this time with a while loop? Yeah. AUDIENCE: An infinite loop? SPEAKER 1: An infinite loop? Yes, and why? AUDIENCE: Because it's always zero. SPEAKER 1: Yeah. So, I is initialized as zero. Of course I is always greater than or equal to 0 as a result. So, I'm just going to see this infinitely. And now, this has come up once or twice to the course's heads. What happens when you have an infinite loop? AUDIENCE: Control C. SPEAKER 1: Yeah. So Control C will eventually respond. Unfortunately, we've printed out millions and millions of zeroes already and so the computer has kind of got ahead of me. So, it's going to ignore me for a little bit. But if you just hit Control C a few times on your Mac or PC keyboard, eventually it should, indeed, terminate. And if not, we'll show you some techniques before long where you can actually forcibly kill programs, much like in Windows and Mac OS, if need be. But let's try something else. Let's actually increment I. Is this still going to be infinite? Let me run this. And now you can kind of see what's happening. This, too, is an infinite loop. But this is a bit of a trick question. Is this going to print numbers forever? AUDIENCE: No. SPEAKER 1: No. Why? I heard some nos over here. Someone-- Yeah. AUDIENCE: You don't have enough bits to really keep going. SPEAKER 1: All right. So I don't have enough bits to keep going. So, what's going to happen? It's just going to stop? AUDIENCE: At some point it will shut the-- SPEAKER 1: It will shut the loop down, but why? What's going to happen at the very end of its boundaries? Yeah? AUDIENCE: It will cycle back to negative numbers. SPEAKER 1: To negative numbers, or if we were just treating positive, zero at least. So yes, absolutely. Recall that we saw last time that if you increment your bits one too many times, and you there fore overflow the capacity of your int or whatever the data type is, you're going to wrap around, probably, two negative numbers. Or if you've specify that your range should only be positive, which you can do, but we've not seen that yet, you might end up at least back at zero. Although, actually yes. In this case, negative numbers, in which case the loop is going to terminate because I is not, in fact, greater than or equal to zero if it's negative. So, unfortunately, how long would we have to wait? Right now we're up to what, 2 million-ish? We are like 2 billion, we're going to have to wait until we can actually see this symptom. But we can see it a little faster, maybe-- let's see if we can interrupt. Come on. Even the menus are appearing slowly. All right. So, we'll come back to that before long. It's a good time-- damn it, puppies. It's a good time for some announcements. So, if you might like to engage in YHack, which is an event being sponsored by our friends at Yale. And, indeed, some of the course's TFs at Yale are involved with this. YHack is an international hack-a-thon hosted by and held at Yale, bringing together 1,500 like minded hackers and creatives all over the world. If this is of interest, take a look here. If this is too briefly on the screen, take a look at today's slides for the URL for yhack.org. So, also a few quick announcements. So, officially sections will start next week both here and New Haven. Keep in mind you'll be getting an email later this weekend most likely. It takes a long time for CS50 to section, given all the people in the class and everyone moving around. And all the Teaching Fellows' schedules are also still solidifying, but stay tuned for an email and if need be, you can re-section there after. Study.cs50.net. So, even if you are a constant attendee at sections, realize that almost all of the resources we use in sections are publicly available at CS50 Study at this URL here. So, if you'd ever like to re review material from section, or read ahead, or you can't make it some week, realize that sample slides, and problems, and definitions, and more are all there as well. Office hours resume today, and tomorrow, and Wednesday, and Thursday check the course's website for the schedule. And also, now launching today is CS50 Discuss. So, if and when you have questions for each other or for the course's staff, and are generally working on some problem set, realize that you don't necessarily have to turn to the human next you. If there's no one there, you can reach out to us and classmates online via CS50 Discuss. So, this is a discussion board for the course, and realize that this is perhaps the best place to start when you have questions when outside of office hours in particular. Lunches will start up this week too. At Fire and Ice [INAUDIBLE] in New Haven. Take a look at the course's website in order to RSVP. First come, first serve for that. If you don't get in this week we'll do these most every Friday during the term. OK, and now a word about grading. Particularly as we enter problem set one, which is out this week, and problem set two and thereafter. How do we go about evaluating P sets and evaluating the quality thereof? So, it's four axes that we use in CS50, and they're these four here. Scope, which captures on a numeric basis just how much of the P set did you tackle. It's roughly corresponds with effort, and it's our way of capturing did you try half the P set, all of the P set. This is an easy one to get perfect scores on if you do, indeed, try every aspect of the P set. So, keep that in mind. Correctness is exactly that. Does your code work as the specification and as the staffs' sample solution suggest that your code should, in fact, work. Check 50, if you haven't met it yet, is in P set one specification and will generally give you yes/no answers as to whether your code is correct. At least so far as we're going to evaluate it based on the tests that we run within that program. Design is much more subjective. This is how well written is your code. And this is something that you'll get better at over time, and it's something that we'll provide more qualitative feedback on. And by design I might mean before long you might be tempted in some P set to do something loopingly, but to have maybe three, or four, or five nested fore loops or nested while loops. That generally should start to make you cringe and would generally be considered bad design. And you'll start to see in class and out of class good ways of doing things, bad ways of doing things that might all be correct, but not necessarily well designed. Like writing an essay. You might be able to put words on a page that are grammatically correct, but the essay or the thesis they're in is just completely incoherent or unpersuasive. And so that might be the analog in the written world of bad or good design. And style, too, is fairly subjective. But at least we expect consistency. This is how pretty is your code. Are things nicely indented? Are your variables well named/ Are all of your parentheses and curly braces aligned as they should be? We do have a CS50 style guide as the problem set will point you at. Those more comfortable are welcome to stray from that so long as you are self consistent. And this, too, is a lesson we'll reinforce in section. So, if all of this was a little fast, realize the P set and sections will go into more depth before long. But generally we have very few buckets for CS50. Scores are generally on a scale of one to three, or one to five. We're literally-- and I can't say this enough in the first week. Three is good. So, even though, yes, three out of five normally, mathematically, might be a 60 percent or like a D minus. Three is, in fact, good. And, in fact, we expect most students in the class to start off the term around twos, and threes, and fours. Probably not so many fives. Not too many ones. But generally to start in that sweet spot in the curve so that as time progresses, there's actually room for, and opportunities for upper progression. So, please do not equate three with 60%. It's much more abstract than that. The formula with which we calculate grades is weighted as follows. Correctness is worth the most. Design is worth a little less. Style is worth a little less. And this generally captures the amount of time that goes into getting each of these axes just right. Style is super easy, should be super quick, but it's an easy habit to get lazy about. Correctness might take you most of the time. Chasing down some bug might take that extra hour or more, and so, the scoring ultimately captures that. And so, now a more serious word. Since CS50 has the distinction, for better or for worse, of being perhaps better acquainted with the issues of academic honesty than most any other course. And indeed, it is to my knowledge that we send more students, unfortunately, for disciplinary purposes every year as a result. So, in the interest of full disclosure, let's talk briefly about what goes on in CS50, and what you can do, and what you can be mindful of. So, here since 2007, when I inherited the course, is the number of Ad Board cases. Ad Board is Harvard's disciplinary body, or now the Honor Counsel, to which cases are referred when students do something that the course's syllabus considers unreasonable. There's no real pattern here, I would say. It fluctuates over the years but generally this is the number of cases that are referred. The number of students that are involved? It too varies. Typically, last year for instance, 29 students at Harvard were Ad Boarded, so to speak. 29 of them current students, two of them prior students, who were collaborating in some untoward way. And then in terms of the percentage, it's usually about 3% of the class that, unfortunately, makes these kinds of decisions. So, last year it was 3.5% of CS50's student body that was Ad Boarded, so to speak. So, what does all of this mean? And what do we actually do? So, for full disclosure, we absolutely, as computer scientists, have software tools at our disposal and it's very easy for us, in fairness, that other's classmates who are not crossing these lines to cross compare every submission this year against every submission for the past eight years. Software does this. And ultimately it's human eyes that decide whether or not to refer some matter for further adjudication, but software certainly helps. And this, frankly, is why that I think we have such large numbers in CS50. It's not because CS50 students or CS students more generally are any less honest than any other students, it's just we have the tools and the techniques with which to take this first pass. But we do keep an eye on all of these things as well, again, in the interests of recognizing the work that's being put in by a super majority of the class. And the course's policy on academic honesty, even though it's a bunch of paragraphs long with a bunch of bullets that are hopefully quite readable, it really does boil down to be reasonable. And the best rule of thumb that we offer up within the syllabus is this, the essence of all work that you submit to this course must be your own. And indeed, in almost all of those cases referred for disciplinary action it was because of some student late one night typically turned his or her code over outright to a classmate, who then adopted it in its entirety or significantly thereof. But really, this is OK. And indeed, at office hours, the slips of paper you've been handed if you came by office hours last week encourages as much. You're absolutely welcomed and encouraged to discuss problem sets with classmates. To help each other when stumbling. But generally the rule of thumb should be this, "when you are asking for help, you may show your code to others, but you may not view theirs." So, in other words, if I'm struggling with some P set and I'm sitting there in the dining hall, or in the library, or in the classroom trying to find some fault, I can certainly show my code on my screen to the person sitting next to me, certainly the staff, but also a classmate. But if the solution that my classmate offers is, oh, here just take a look at what I did, that crosses the line. And I would dare say that's generally a reasonable thing for most people to very easily spot the line of. And so, see the syllabus for more detail. And now one of the more controversial aspects of CS50 syllabus that I thought I would speak to in conclusion here is the so-called regret clause. So, here's all the fine print. But in general we have seen over the past 8 plus years that, indeed, almost all of CS50's cases of academic dishonesty have been the result of just poor decision making late at night. The result of stress, the result of lack of eating, lack of sleep, too many P sets, too many deadlines, too many commitments. Stress building up in a 2:00 AM, 3:00 AM, 4:00 AM, with a deadline looming. Most students in these cases have just made bad decisions that they might very well regret the next morning if not minutes later, but until last year there was no release valve that these students could actually open up to actually address the problem head on without fear of being booted from college altogether. And, indeed, we introduced this regret clause last year, which says that if within 72 hours, three days, of crossing some line prescribed in the syllabus you come forward to one of the course's heads and we'll have a chat about it. There are still be some outcome, contrary to what's been reported to the contrary. There is still some outcome that is actionable by the course, generally zeroing a P set or taking some other action, but we will, indeed, handle it ourselves and not refer it higher were the outcome might be much more severe. And, indeed, to share what happened last year, in the eight years, and now nine years, of teaching this course and after tinkering with various knobs, turning various dials over the past several years on academic honesty, and seeing per the data no apparent impact, even of speeches like this, this was hands down the best thing we've introduced pedagogically in eight years along these lines in CS50. 19 students came forward under this clause last year. We took no action for seven of those students, determining that they were unnecessarily worried. They had not, in fact, crossed a line, but it was a good chat to have nonetheless. We zeroed 11 of the scores that were submitted. And in one case we asked a student to do a problem set. But more compelling, honestly, with these 19 chats, which was way more than I expected to have, each of them 10 minutes to maybe an hour long, also brought to light a number of issues regarding familial issues, friend issues, mental health issues that we then engaged, with the student's blessing, resident dean, or friends, or any other number of support resources. So that this was by far one of the best uses of our time and one of the best interventions. With that said, it had no input on the rate of detection of academic dishonesty more generally. And I dare say, this subset of students last year was a demographic that we previously never identified before and had never connected with before. And so, these were wonderful success stories even though they were brought to light in less than optimal circumstances. So, keep this in mind as you make, perhaps, some poor decision yourself late at night, that there is recourse so long as the student in that situation own up and come forward so that we can have that kind of chat and deal with it in a way that's educational, and then we can put it behind us the next day. So without further ado, take the edge off of this conversation, the reason the puppies are up is just to break the ice for a moment. And unfortunately, they're all sleep, but what was supposed to happen here was everyone was supposed to awe and kind of relax after that very heavy conversation. But apparently I put the puppies to sleep. But if you go to CS50's website slash puppies, you can watch them all day long. Particularly maybe 2:00, or 3:00, or 4:00 AM at night to see a little stress relief there. So that is slash puppies. All right. Wasn't that fun? OK. So, back to some computer science, if I may. So, recall that last time we started looking not just at main, which was the default function, the when green flag clicked equivalent, but we also started briefly writing some of our own functions. And thus far none of these functions have been particularly big or meaty. You'll get into those larger functions probably, P set 2, P set 3, definitely P set 4 and onward. Right now most of your programs, if not all of them, certainly for P set 1 can be done entirely in main. If your program's only five lines, 10 lines, even 20 lines long, perfectly reasonable to write it all in main and not to over complicate your code, but what we're doing today and onward is trying to also introduce some good design techniques so that as your code gets more complicated and as the problems you want to solve get harder and more interesting you have, sort of, the tools in your toolbox with which to design good solutions to those. So, let's take a quick look back at this program from my last week, which was functions zero dot C. And notice that, quite simply, it looks like this with two functions, main and print name. And thinking back or perhaps reverse engineering today, what was the motivation for introducing a function in line 28 called, print name? Or what was this an example of in terms of a principle or takeaway, if you would. Some murmurs. What? Yeah so Functional Decomposition is kind of the fancy way of saying, decompose your program into its constituent parts and then use those parts to assemble a whole. So, that too is just kind of a mouthful already, but this is perhaps even a better example of something just called abstraction. Right? Abstraction is going to be one of the recurring themes in CS50 and also computer science more generally since it's a technique with which you can solve problems more effectively because you can write solutions more intuitively and in a way that scales and is understandable by other people. What do I mean by that? So, arguably it is much more readable to look at a program like this, super short though it is. When you see on line 22 that there's a function called, print name. That name alone says what it does. That function apparently takes input between its parentheses, and apparently does something, presumably prints the name. And so, even though we absolutely could have done what we did a week ago, which was just take this actual line of code, get rid of this, and get rid of this all together, we sort of abstracted away the notion of printing a name. I don't care if you're using print def. I don't care if you have a percent S and a backslash N. These are incredibly arcane details. What I do care about as a programmer is printing a name. And so, what better way to do that than by calling a function, print name? And so, that was one of the motivations for doing something like this. Making the code more readable, more reusable, and also self descriptive. Now, let's take a look at another example, which was functions one, which we had over here. So, this one is perhaps even more compelling because, in this case, I don't want to just get an int. I want to get a positive int. And it turns out to get a positive int you have to do a bunch of legwork. Right? It's not a simple one line call like print name was, which is admittedly less compelling. To get a positive int, logically-- let me scroll back down to hide this. What do you have to do? Like all the tools we have at the moment are things like print def from Standard Library and also from CS50 library we have Get Int, and Get Float, Get Long Long, Get String, but the only one, Germane, right now is Get Int. So, if the only tool you have in your tool box is Get Int, how do we go about implementing it to get positive int? AUDIENCE: Create a log and check on whether the input that they gave was positive or not. SPEAKER 1: Perfect. Exactly. Another tool we have in our toolbox from a week or two ago is just the looping construct. And so, yeah, if we use a while loop, or a do while loop, or a fore loop we could probably get away with any of those in some form. We can implement the notion of get positive int by just using Get Int, and then just keep calling it again and keep pestering the user until he or she actually gives us what we want. And so now, this abstraction of the process of getting a positive int into a function called Get Positive Int is a little more compelling because look at this. These are like 10 plus lines of code that are involved in getting a positive int, and I don't really care how you do it. All I care is that you can do it, and so I've hidden all these details behind a function called Get Positive int that, indeed, has this do while loop. And see last week for the syntax there, but it just declares N, and it prints out the instruction to the user. It calls Get Int and then it checks this condition again, and again, and again until the user cooperates. So now, a few sanity checks. For those perhaps familiar with some programming, why is N declared, why do I create N outside of the do while loop? Why is it on line 29 and not on like 33, for instance. AUDIENCE: Because when you declare it outside, it kind of more, the larger scope-- SPEAKER 1: Good. AUDIENCE: --and if you declare it inside the loop, [INAUDIBLE] because it doesn't know about it. SPEAKER 1: Exactly. If I can simplify-- it's an issue of scope. And scope refers to the context in which a variable exists or is usable. And the nice rule of thumb here is that generally when you declare or create a variable you can only use it inside of the closest embracing curly braces. So what does that mean? If I, instead, undo this and go with something that feels a little simpler. Right? Line 32 just looks cleaner to me now. I'm doing both things at once and then assigning the right hand to the left hand. The problem now based on that definition of scope is that N can be used in lines 31 and 32 inside of this loop, but where by that definition can it not be used? In line what? Yeah. AUDIENCE: 35. SPEAKER 1: 35. Definitely not 35. And also where else? AUDIENCE: 34. SPEAKER 1: Even 34 is problematic because it's outside of the curly braces. And so in fact, let's see what happens. Right? This might seem a little intuitive or might not, but let's see what the compiler has to say when we go into today's source directory. Make function one. Oh, my god. Well, I finally finished that, by the way. All right. And what's the issue here? Very arcane to look at. But here's what I typed-- make function one. Here's what make induced, which is actually using the compiler clang with some of those flags that we'll see again before long. And again, always look at the first error, because it might just have a cascading meaningless effect on other lines. So what this means is that the problem is in function 1.c. It is on line 32. And it's at column, or character, 13. So when your text editor that can help you identify where the issue is. So if I scroll up, what is line 32? That's indeed this one that's already highlighted right here-- unused variable n. But it's not unused. I'm using it. But the compiler's confused, because it only exists inside of this scope. And so I can't use it here. I can't use it here. And the compiler, therefore, doesn't even care that I'm trying. It seems to be unused within its actual scope. So we can broaden the scope by doing exactly what we started with-- int n. And even though it doesn't look as elegant, perhaps, and we're taking an extra line here, now it's in scope everywhere. So let's try again. So make function one. Nice. And now if I if I run function one, let's give it negative 10, negative 1, 0, 1, and it indeed works. So there's another solution here. You know what? What if I really am wrestling with this? I don't know where the n's supposed to go. You know what? I'm just going to put it all the way at the top of my file here. What would this do, do you think? Yeah? AUDIENCE: [INAUDIBLE]. SPEAKER 1: Yeah. So I've made it global, so to speak. If you have a variable that's outside all of your functions that is allowed, and the code should compile, and n will now be accessible not only in get positive int, but also in main-- which is a little worrisome because there's already an n in main, so more on that in just a moment-- but this would be considered bad design. All right. If you have to resort to something like, oh, I'll just put it up here because the code seems to compile is generally not the best practice. Rather you want to choose the narrowest possible scope for your variables, which would mean going with our initial design, which is right here. Now as an aside, if you did have an identically-named variable here, the way c would handle this-- though this won't happen too often-- is that this is still perfectly fine in here. But this definition of n in line 22 will shadow the global one. So this one will work within main, and the global one will actually apply when you're in get positive int But more on that another time, but just for those curious. So in short, we fix this here. Now let's tease apart two other pieces before we look at one last line of code in this program. Get positive int. On the left-hand side of its word is the word int. What does that signify do you think? Thus far we've mostly seen void. Yeah? AUDIENCE: It's the type of variable that you're asking about. SPEAKER 1: Yeah It's the type of, let me not say variable, but the type of value that I'm asking back for. And indeed, that's intuitive here, hopefully. Right? If you want to get a positive int, what is it you want the function-- like our volunteers from last week to hand you back a piece of paper with an int on it? And so we've specified that the so-called return type of this function is get positive int. If we didn't want it to return anything, you say void. If you want it to return a string, you say string. If you want it to return a float, you say float. But the only one that applies here logically, because I'm using get int, even though I'm restricting it to positive values, is to return an int. So conversely, what does it mean that there's a void in parentheses? What do the parentheses generally define? Yeah? AUDIENCE: It means the function's not actually getting it. SPEAKER 1: It means the function's not actually getting what? AUDIENCE: An input. SPEAKER 1: An input, whatsoever. So indeed, if parenthesis here you specify void, that just means I don't want any input. I'll deal with the problem myself. And indeed, you don't have to tell get positive int anything. You just say, get positive int, and that function will go off and do its thing. But there's been a little trick I've been playing here this whole time to make sure this code compiles. Notice that int-- get positive int void-- is on line 27. But for some seemingly weird reason it's also up here on line 16. And just for good measure I'll repeat this so it's perfectly identical. And I've said prototype with a little one-line comment. What happens if I delete that, And now rerun make function 1, enter. Whoops. Wait a minute. Where's my tab? Huh? Standby. Make function 1. There we go. OK. Hadn't saved it properly. So, I think there's a little bug here where I'm not seeing the tab name at the moment. So what is going on here? Implicit declaration of function get positive int is invalid in C99. So confusing again. So what is this indicative of? Well, it turns out that C is pretty stupid. Well, it's the programming language, or rather the compiler is. It only knows what you have taught it, and it's only going to know something if you taught it before. In other words, in main at the moment, I'm trying to call a function called get positive int. But the compiler is not going to notice that get positive int exists until line 26. And so what the compiler does is just errors as soon as it gets to line 17, saying implicit declaration of get positive int, which is just a fancy way of saying, I don't know what get positive int is yet. Other languages like Java and Python and Ruby might look ahead. C does not. And so the way we fix this is one of two ways. Either one, if the problem is that get positive int hasn't been seen before, well, let me just move it to the top. That would fix this problem. But generally, it's considered better technique to put your main function at the very top so that a human reading your code knows what the program does, because main is not buried all the way at the bottom or in the middle. It's at the very top. So that doesn't feel ideal. And you can actually get into situations where if one function calls another, which calls another, you can get into an issue where neither can go above the other, logically. It's just not possible. And so the way to work around this is to just take the function's signature, so to speak-- the first line where it's declared-- and just copy, paste it at the top, but not with curly braces-- just with a semicolon. It's like a little hint of what is to come. And in fact, all of this time when we have seen things like standard io.h and cs50.h, similarly, in those dot h files are there other prototypes. And we'll see that before long. So in short, when you have a program in a file with multiple functions besides main, you almost always want to declare them just by way of their first line, followed by a semicolon, at the very top of the file. That was a lot all at once. Any questions? Any questions? All right. So let's move on then to something like cough. Oh. How fitting. All right. Cough. So here is a c implementation of a program we did the other day in Scratch that very simply just says cough, cough, cough. All right. And someone said a few days ago that there's a way of cleaning this code up already. All right? As soon as you're copying and pasting probably bad design. At least once we get to four or five or 20 coughs, it feels bad practice. We just keep copy, pasting. What's the obvious solution to cleaning this program up? AUDIENCE: Loop. SPEAKER 1: Yeah. So use a loop. And we can use a for-loop, a while loop, any number of approaches. And indeed, that's what we do in version one here. I've instead rewritten it in version one of cough.c to be just cough within a for-loop. All right, but there's an opportunity now to kind of start to design this a little more like the lesson we taught a moment ago, which is this-- suppose that I wanted to create a function called cough, let's consider for just a moment what it's going to look like. So if I want something to cough, I just need to use print f inside the function. And indeed I am. And in fact, all this time, any time you're printing something to the screen, a programmer would call that a side effect. It's not me handing back someone a value. It's me taking some action that might be visually obvious. But this function cough, does it return anything based on its first line? No, because its return type is void, which just means it's not handing me anything back. It might be doing something visually, but it's not handing me back a piece of paper like last week. Does it need any input? No. And so it's void here too. So this too is kind of over-engineering this problem. Right? I've made the program more complex, more lines of code, I haven't made it any more functional, but this would be a stepping stone, perhaps, for a broader context with more complicated code. But what about this? What have I done-- just glancing at this without looking at the comment at the very top of the file-- what have I fundamentally done here with my cough implementation that's different? Yeah, in back? AUDIENCE: Make it so you can have a character turn off. SPEAKER 1: Yeah. So this feels kind of nice. Right? It's like adding a feature to your program or your function, in this case. It still returns nothing. It might have a visual side effect, because it's calling print f. But now I have parametrized the function, which means I've specified taken input of type int and call it n, but I could call it anything I want. In fact, it could just be times to be even more explicit. And then I could just change this here. But the point is that this is how I create a function that takes input. And if you recall flipping through perhaps online in one of the walk-throughs, the fourth and final cough example, you'll notice here I've generalized my code further-- kind of abstracted it further. Like cough and sneeze, both are about like saying something or making some kind of sound. Save would be the corresponding Scratch block. And so what I did in this version, which we can just glance at, is cough is just like saying, [COUGH], cough, and meanwhile, sneezing is like saying, [ACHOO]. And so I've generalized the implementation of those by now implementing this generic function, say, which is interesting for today's purposes only because it still doesn't have a return type. But how many inputs does it have? AUDIENCE: Two. SPEAKER 1: Two. And so if you want to take in two arguments, just separate them with a comma. And if you want to then call that function, notice that you just call say, quote, unquote, for the first argument, common n, for the second argument. So again, we just have now the building blocks so that we can actually implement some of our own functions. All right. Any questions on these? So now let's peel back a layer if so. And the goal, ultimately, is next week's problem set is going to be on cryptogrophy-- the art of scrambling information. And specifically, the information will have you encrypt or decrypt is going to be text. And so that kind of invites the question today like well, what is going on underneath the hood with text beyond ASCII from week zero, and how can we actually start to manipulate it? So here is Zamyla's name. And in text, that might be inputted into like the get string function. And starting now, when you see a string like this-- Z-A-M-Y-L-A-- start thinking of it as though each of those characters is in a box of its own. And indeed, in a week or so's time, each of these boxes is going to represent very specifically a block of memory-- a bite of memory. So each of these letters, ultimately, will represent 8 bits. And we'll actually see what's going on underneath the hood in my computer. But for not it suffices just to look at Zamyla through this lens, whereby each of these letters is in its own box. And nicely enough in C we can access each of these boxes directly. So if you want to get the first letter of her name, super easy in C. If you want to get the last letter, super easy as well with a piece of new syntax. So I'm going to go ahead into CS50 IDE and open up the string zero dot C. And in this example here, there are a couple of new things going on. So first in line 19, we've seen this before-- get string. So just as a quick sanity check, if someone could offer up verbally a layman's explanation of what's going on in line 19. Like just translate this into English that a roommate not in CS50 might understand. Yeah. AUDIENCE: Have the user input a string and store it in a variable s. SPEAKER 1: Good. Have the user input a string and store it in a variable s. That's great. So on the right-hand side, we call get string. That returns a value that didn't get assigned from right-hand side to left-hand side into a variable called s that's designed to store a string. Exactly. So now line 22, per the comment in line 21, obviously prints that string one character per line. But how? So first of all, we initialize I to 0. And then how do we get to the end of Zamyla's name? Well, at the end of Zamyla's name, I could manually type in the last character of her name somehow, or the number of it. Right? If we go back here-- Z-A-M-L-- Y-L-A-- so I could type in. What's the index of Zamyla's last letter? If this is 0-- speaking like a programmer-- 0, 1, 2, 3, 4, 5, I heard-- so indeed, the last letter in Zamyla's name is the sixth, but if we count from 0, it's going to be number 5. So keep that in mind here. It turns out there's a function in C called strlen, and back in the day and to this day still, a lot of programmers choose to sync names for their functions that sound like the words they're trying to say. So strlen is string length. And so what would string length of S return when Zamyla is the input? AUDIENCE: Five. SPEAKER 1: Z-A-M-Y-L. Six. Right? What's the length of Zamyla's name? Right? And just in reality, six letters. Right? And so what does that mean for our loop? We're going to go from 0 up to six, which is going to give us five iterations. What do we do on each iteration? Well, percent C, someone guessed the other day, means a placeholder for what? AUDIENCE: Char. SPEAKER 1: Just a char. So a single character-- not multiple characters like a string. And then here's the new line that we've got printing out. And then here's the new syntax. If you want to print out the i-th character in the string S, so to speak, you can simply say the name of the string S, and then open square bracket, and then closed square bracket, with an i the middle. And it's kind of nice in that it kind of looks like a square just like the squares in which Zamyla's characters exist on that picture there. So if I actually run this now, let's see what happens. Make string 0 dot slash string 0, and then I'm going to type in Zamyla's name. There's no prompt, because I didn't use print f, but that's fine. I just know what to do. And indeed, it prints out Zamyla's name, one per line. Now let's be a little reckless. Suppose that I didn't know about strlen and I figured, all right, no one's going to have a name bigger than like 50 characters. Let's go ahead and recompile this and rerun it, and then type in Zamyla again. Logically, what is the program going to try to print? Z-A-M-Y-L-A then like 45 unknown bytes of memory. And indeed, we'll come back to this idea of memory. But just logically, if Zamyla's name is this long, as per the picture here, what we're saying is keep printing, keep printing, keep printing, keep printing, keep printing, all the way to the 50th character, which who knows what's going to happen. So let's actually take a look. Let's type in Zamyla. Interesting. We got lucky. Just a whole bunch of white space. Oh. There's one funky character. It looks kind of like a weird question mark there, but there is Zamyla's name. Let's get really reckless. How about we print out 500 blocks into the unknown? Let's go ahead and make this as well and then re-run. And let's full screen it, because we need to see more space. Zamyla. Got lucky again. Dare we get more reckless? Let's get more reckless. 50,000 characters. This is most surely not a good idea. All right. Make string 0. This will be our last demo. Zamyla. Ugh. Ugh. OK. So my memory is really empty right now, which is actually kind of convenient. What I'm trying to get to-- all right. And now I'm just going to get reckless. 500,000. Make-- let's full-screen it. Enter. Zamyla. There we go. I have no idea what that is, but it sounds bad. All right. And in fact, soon, if you're among the fortunate few in office hours and in problem set one, you might very well encounter this. Segmentation fault actually does have a well-defined meaning. It means some kind of mistake relating to a segment of memory. And in layman's terms, it means we touched memory-- we used RAM in my computer that I should not have had access to. And that's what's both powerful and also dangerous about C is that you actually have unfettered access to the entirety of your program's memory or bytes or RAM, more specifically. So even though Zamyla's name is only six characters long, I can still go anywhere in memory I want. And as an aside, if you've ever read some article over the years about some server or some program getting cracked or hacked that's taken advantage of something called a buffer overflow exploit that we'll actually talk about in a few weeks, that's generally referring to somehow tricking a computer into going well beyond the boundaries of memory that it should have, and finding something juicy in that memory-- a password, perhaps, a way of circumventing some serial number check, or just generally able to trick the computer is executing code that wasn't intended. But let's come back to reality for just a moment where this program was implemented with strlen, and introduce one thing up here. What's new among these top three lines? So string dot h. It turns out there's this library called String Dot H, or the String Library, whose header file, so to speak, is string dot h that gives me access to this strlen function. If I omit that, the compiler is going to yell at me in some form. But you know what? Now let's get really nuanced. In line 22, there's something kind of inefficient-- badly designed, arguably-- about this line of code. Think back to how for-loop are implemented and what steps happen again and again and again-- the initialization, the condition, the code that gets executed, then the increment or the change, then the condition, then the code, then the change, then the condition, then the code, then the change, and so forth. So what might be a little worrisome or poorly done here? Yeah, in blue. AUDIENCE: Strlen is called many, many times. SPEAKER 1: Yeah. So strlen is called many times, but what is the length of Zamyla's name the first time the loop executes? AUDIENCE: Six. SPEAKER 1: Six. Well, what is the length of her name the second time the code executes? AUDIENCE: Six. SPEAKER 1: All right. It's still six. Right? Zarla's name hasn't changed, even if I'm looking at only part of the letters in her name. And so the fact that I'm effectively asking this question, what's the length of Zamyla, what's the length of Zamyla, what's the length of Zamyla, six separate times, or seven even, is just stupid, because that's unchanging that answer. And so what I could actually do is this-- in string one I have a marginally better version here. There-- whoops-- string two I have a marginally better version wherein I do this-- instead of just initializing i to 0, I also with a comma declare a second variable called n-- I don't have to say int again. I should not, in fact. But I say n. And then I initialize n to the strlen of n, so that now how many times does strlen get executed in total? Just once. And so this is what we mean earlier about better design. Actually once your code is correct, going back and thinking through, am I using as little memory or as few seconds or milliseconds of computer time as possible to implement some problem? And I'm going to scroll up and just mention that there's this mention of null in this version, but we'll come back to that before long. Because for now, let's take a look at where this is going to lead us. So one, it turns out that now that we have the ability to look at individual characters, we can leverage something from week 0 that was very arcane and sort of uninteresting at the time. But now, and especially when we get to cryptography in a week, it's going to be pretty powerful. It turns out that with some data types-- ints and floats and chars and strings and other things-- some of them can be very easily converted to another. For instance, when we talked about ASCII some time ago-- here's the capital letters A through M, dot, dot, dot-- we said that there's a mapping between these letters and numbers. And in fact, it holds true for lowercase letters as well. Lowercase a is 97, capital a is 65. And there's a number in ASCII, which is just this mapping system for all of those other letters. So what does that mean? Well, I'm going to go ahead and open up real quickly something called ASCII 0, most of which is comments. And again online you can always glance through the comments. And take a look what this is going to do. So it's got a main function. I've hard-coded the numbers just for now, because I know what I'm doing. I know what I want to see here. And I've initialized I to 65. And I'm counting up through 26 letters total. And what am I going to print one line at a time if you can interpret this highlighted line? What gets printed? Yeah. AUDIENCE: Are you going to print the letter that corresponds to the map of the letter value and integer value? SPEAKER 1: Exactly. I'm going to print the letter corresponding to the integer value, and vice versa, as follows. Well this, someone said earlier, is just a placeholder for a char. It still is. This, of course, is a placeholder for an int-- not a new line. And now notice, my first value that I'm plugging in for that placeholder isn't just I. I'm saying, in parentheses, char I, which the parenthetical char is telling the compiler, treat I not as what it is, which is a number. Treat it as an actual character. Whereas the second value I'm plugging in-- I-- should just be a number. So if I compile this program-- so this is make ASCII 0, dot slash ASCII 0-- I just get this handy little chart that shows me all of the possible mappings without having to think it through or figure it out on my own. And I'm also printing out, notice the lowercase letters, because a few lines later, I also print out this mapping as well, which is just to say that once you understand what's going on underneath the hood, can you automatically convert back and forth. And in fact, if any of you ever did this in grade school or heard about someone mythically taking a note and passing it to his or her friend in class, but you scrambled the letters by like A becomes B, and B becomes C, or something more complicated than that, well, how would you go about implementing that as a kid? Well, you just kind of know A becomes B, B becomes C, but mathematically, what was that kid doing? What were you adding to each letter? Effectively, 1. So when you change A to B, that's kind of like changing 65 to 66, which mathematically means just add 1. And so if you were to implement that little deceptive technique for your teacher in code, you might do exactly that just by adding a single letter together. So before long, we're going to see how we can take advantage of that to actually genuinely scramble and unscramble information. In the meantime, know that we've started to introduce a couple other libraries here-- the string one today. And a very helpful site hopefully you'll find is called reference.cs50.net, which the teaching staff have put together, so that if you want to look up how strlen works, you can start typing the function's name, click strlen there, and then a less comfortable explanation is going to appear. Or if you want the official Linux-based explanation, you can click more comfy at top right, and it will present the same information, but in more complex terms. That's a useful resource to actually know what everything does. Next time we're going to take a look at Ovaltine and more, and introduce ourselves to the world of cryptography. Before then, we'll see you later this week. And now, Colton Ogden. See you on Wednesday. [MUSIC PLAYING] [MUSIC PLAYING] SPEAKER 1: What the [BLEEP] are you doing? SPEAKER 1: I am eating my dessert? How do you eat it? With your hands? [MUSIC PLAYING]