1 00:00:00,000 --> 00:00:12,510 2 00:00:12,510 --> 00:00:13,870 >> ROB: All right. 3 00:00:13,870 --> 00:00:16,770 Welcome to the first section. 4 00:00:16,770 --> 00:00:17,480 I'm Rob. 5 00:00:17,480 --> 00:00:18,806 >> JOSEPH: I'm Joseph. 6 00:00:18,806 --> 00:00:21,540 >> ROB: So we'll dive right in. 7 00:00:21,540 --> 00:00:23,420 First thing to talk about is the Appliance. 8 00:00:23,420 --> 00:00:27,150 So hopefully most of you have downloaded it already. 9 00:00:27,150 --> 00:00:37,180 But you can see the instructions at cs50.net/appliance. 10 00:00:37,180 --> 00:00:38,430 Oh god, now I'm self-conscious. 11 00:00:38,430 --> 00:00:44,590 12 00:00:44,590 --> 00:00:45,430 I still hear it. 13 00:00:45,430 --> 00:00:47,232 >> JOSEPH: Wow, it sounds like it's disoriented. 14 00:00:47,232 --> 00:00:52,460 >> ROB: So some people have been having issues with it, so don't wait until 15 00:00:52,460 --> 00:00:54,940 the last minute of the problem set to try and solve the Appliance and 16 00:00:54,940 --> 00:00:56,320 finding out that it's not working. 17 00:00:56,320 --> 00:00:59,010 >> JOSEPH: And if something's not working and you need help, you can go to 18 00:00:59,010 --> 00:01:03,390 cs50.net/discussion where we have a forum where you 19 00:01:03,390 --> 00:01:04,110 can post your questions. 20 00:01:04,110 --> 00:01:06,655 And we'll get to them eventually. 21 00:01:06,655 --> 00:01:07,490 >> ROB: All right. 22 00:01:07,490 --> 00:01:12,180 So this is what the Appliance looks like. 23 00:01:12,180 --> 00:01:15,480 Again, it's just a completely separate operating system running within 24 00:01:15,480 --> 00:01:19,440 whatever operating system you are running on your laptop. 25 00:01:19,440 --> 00:01:24,450 And the main things you'll be using are gedit. 26 00:01:24,450 --> 00:01:28,050 So hopefully this has already become a familiar site. 27 00:01:28,050 --> 00:01:29,470 The terminal. 28 00:01:29,470 --> 00:01:31,890 >> And you can also run Chrome within the Appliance. 29 00:01:31,890 --> 00:01:33,860 There have been a couple of people who have reported internet 30 00:01:33,860 --> 00:01:35,390 not work in the Appliance. 31 00:01:35,390 --> 00:01:38,090 And some of them have just assumed that there isn't supposed to be 32 00:01:38,090 --> 00:01:39,190 internet in the Appliance. 33 00:01:39,190 --> 00:01:40,750 But yes, there is supposed to be internet. 34 00:01:40,750 --> 00:01:44,000 35 00:01:44,000 --> 00:01:46,410 >> I'll say it right now, but it doesn't really mean anything. 36 00:01:46,410 --> 00:01:50,680 If the internet isn't working, this is what you tend to need 37 00:01:50,680 --> 00:01:52,180 to run to fix it. 38 00:01:52,180 --> 00:01:55,602 If you are having internet issues, don't remember it, just post it on 39 00:01:55,602 --> 00:01:57,560 Discuss, and we'll say, run that. 40 00:01:57,560 --> 00:02:00,420 But the internet should be working. 41 00:02:00,420 --> 00:02:06,650 >> So the only other thing-- yeah, nothing else is really relevant. 42 00:02:06,650 --> 00:02:08,979 But I just wanted to point out that-- 43 00:02:08,979 --> 00:02:13,290 see in this bottom-right corner. 44 00:02:13,290 --> 00:02:16,530 So each of your Appliances should have an IP address. 45 00:02:16,530 --> 00:02:22,350 And later in the semester, this IP address will become more relevant when 46 00:02:22,350 --> 00:02:27,230 you're working on the web p-set, because you'll be able to access the 47 00:02:27,230 --> 00:02:32,310 website you're working on from your local Chrome by using this IP address. 48 00:02:32,310 --> 00:02:35,400 >> But what I like to use the IP address for-- and you don't have to do this, I 49 00:02:35,400 --> 00:02:37,460 just want to point it out-- 50 00:02:37,460 --> 00:02:39,540 is here. 51 00:02:39,540 --> 00:02:42,910 So this is a terminal window on my Mac, this is not in the 52 00:02:42,910 --> 00:02:44,580 Appliance at all. 53 00:02:44,580 --> 00:02:47,190 And you can look up what this command does. 54 00:02:47,190 --> 00:02:51,855 But I'm going to SSH directly to my Appliance. 55 00:02:51,855 --> 00:02:53,410 I don't know what the IP is. 56 00:02:53,410 --> 00:02:54,300 >> JOSEPH: 168-- 57 00:02:54,300 --> 00:02:56,080 >> 168.224.1.0. 58 00:02:56,080 --> 00:02:59,950 >> ROB: So once I'm done with this, log in. 59 00:02:59,950 --> 00:03:05,450 Now, basically, this is identical to a terminal window within my Appliance. 60 00:03:05,450 --> 00:03:10,280 So I pretty much never actually worked from within the Appliance itself. 61 00:03:10,280 --> 00:03:12,550 I just always have it running in the background minimized 62 00:03:12,550 --> 00:03:15,890 and SSHed into it. 63 00:03:15,890 --> 00:03:24,270 >> The issue with this is you are not going to be able to use gedit easily 64 00:03:24,270 --> 00:03:25,600 directly from this. 65 00:03:25,600 --> 00:03:31,500 But if you want to be a real cool hacker, then you should get used to a 66 00:03:31,500 --> 00:03:34,220 command line text editor anyway. 67 00:03:34,220 --> 00:03:39,620 So Vim and Emacs and Nano, all of these are different alternatives. 68 00:03:39,620 --> 00:03:41,560 Nano tends to be the easiest. 69 00:03:41,560 --> 00:03:45,006 And I think it has no syntax highlighting. 70 00:03:45,006 --> 00:03:47,620 Oh, no, it totally does. 71 00:03:47,620 --> 00:03:49,870 So you can use Nano, because that one's pretty easy. 72 00:03:49,870 --> 00:03:52,000 >> You see all these commands at the bottom. 73 00:03:52,000 --> 00:03:54,750 This little carrot symbol. 74 00:03:54,750 --> 00:03:57,620 If you haven't seen it before, you'll probably see it a lot now. 75 00:03:57,620 --> 00:04:02,350 It generally means the control carrot, like the bottom-left of your keyboard 76 00:04:02,350 --> 00:04:04,130 control character. 77 00:04:04,130 --> 00:04:07,260 So here it's telling me down here-- 78 00:04:07,260 --> 00:04:08,710 oh, it's not cut off if I zoom in. 79 00:04:08,710 --> 00:04:11,040 So Control, X is how I'm going to exit. 80 00:04:11,040 --> 00:04:14,710 And it says I can hit Y for Yes, for saving, N for No. 81 00:04:14,710 --> 00:04:17,190 So that's Nano. 82 00:04:17,190 --> 00:04:22,860 >> Vim and Emacs tend to be slightly more complicated and overwhelming. 83 00:04:22,860 --> 00:04:28,840 But you can get used to it, and then you'll love it. 84 00:04:28,840 --> 00:04:30,590 So that's that. 85 00:04:30,590 --> 00:04:31,720 >> JOSEPH: No need to do that. 86 00:04:31,720 --> 00:04:31,840 >> ROB: Yeah. 87 00:04:31,840 --> 00:04:37,510 You are free to use gedit for the remainder of the semester. 88 00:04:37,510 --> 00:04:40,630 So any appliance-related questions? 89 00:04:40,630 --> 00:04:42,820 Or do you have any thoughts on what else needs to be spoken about about 90 00:04:42,820 --> 00:04:43,610 the appliance? 91 00:04:43,610 --> 00:04:43,996 Yes. 92 00:04:43,996 --> 00:04:47,720 >> SPEAKER 1: When you SSHed into your thing, was the password Crimson? 93 00:04:47,720 --> 00:04:48,390 >> ROB: Yeah. 94 00:04:48,390 --> 00:04:50,170 The password for pretty much everything in the Appliance is going 95 00:04:50,170 --> 00:04:52,473 to be Crimson. 96 00:04:52,473 --> 00:04:56,517 >> SPEAKER 2: Install like a real IDE on the appliance, will it work? 97 00:04:56,517 --> 00:04:59,200 98 00:04:59,200 --> 00:05:07,290 >> ROB: I imagine Eclipse does have a Fedora version, in which case, yes, 99 00:05:07,290 --> 00:05:08,420 you can do that. 100 00:05:08,420 --> 00:05:10,875 It's probably not really worth it. 101 00:05:10,875 --> 00:05:11,742 >> SPEAKER 2: OK. 102 00:05:11,742 --> 00:05:15,924 So it's probably easier if I wanted to use Eclipse, just use the native and 103 00:05:15,924 --> 00:05:17,646 then upload to-- 104 00:05:17,646 --> 00:05:21,090 >> ROB: Oh, that is also probably easier. 105 00:05:21,090 --> 00:05:24,046 But you can get it working within the Appliance. 106 00:05:24,046 --> 00:05:27,740 >> JOSEPH: And for the camera, the question was, can you install another 107 00:05:27,740 --> 00:05:29,490 IDE inside of the Appliance? 108 00:05:29,490 --> 00:05:31,520 >> ROB: Eclipse being an example of an IDE. 109 00:05:31,520 --> 00:05:34,800 110 00:05:34,800 --> 00:05:36,050 Any other Appliance questions? 111 00:05:36,050 --> 00:05:38,250 112 00:05:38,250 --> 00:05:38,680 All right. 113 00:05:38,680 --> 00:05:44,920 >> So we will now move on to command line interface-related things, so CLI. 114 00:05:44,920 --> 00:05:47,990 And again, I'm just going to work in here, because this is identical to 115 00:05:47,990 --> 00:05:52,780 working within a terminal window within the Appliance. 116 00:05:52,780 --> 00:05:54,160 How's that font looking? 117 00:05:54,160 --> 00:05:55,970 Is that big enough? 118 00:05:55,970 --> 00:05:57,000 All right. 119 00:05:57,000 --> 00:06:02,480 >> So there are a lot of commands that you should get pretty used to 120 00:06:02,480 --> 00:06:04,490 throughout the semester. 121 00:06:04,490 --> 00:06:09,480 The big two for navigating are ls, list the files in this directory; and 122 00:06:09,480 --> 00:06:11,380 cd, so change directory. 123 00:06:11,380 --> 00:06:18,390 So I can change to desktop and then a very common pattern is cd to a 124 00:06:18,390 --> 00:06:22,550 directory and immediately ls what's in the directory. 125 00:06:22,550 --> 00:06:25,540 >> People also sometimes don't realize that Tab completion is a thing. 126 00:06:25,540 --> 00:06:28,370 So like cd, vh, and then I hit Tab. 127 00:06:28,370 --> 00:06:30,790 I almost never type out the entire thing. 128 00:06:30,790 --> 00:06:32,920 And then if I keep hitting Tab again, it'll automatically 129 00:06:32,920 --> 00:06:33,670 start listing for me. 130 00:06:33,670 --> 00:06:37,000 So I can cd vhosts, local host. 131 00:06:37,000 --> 00:06:39,880 And that's just going to-- 132 00:06:39,880 --> 00:06:43,380 in case you have not heard the term before, directory is just another word 133 00:06:43,380 --> 00:06:45,170 for folder. 134 00:06:45,170 --> 00:06:49,930 So now if you see-- 135 00:06:49,930 --> 00:06:51,810 let's bring that to the top. 136 00:06:51,810 --> 00:06:55,380 >> So now if you see in parentheses, you see the little tilde, slash, vhost , 137 00:06:55,380 --> 00:06:56,810 slash, local host. 138 00:06:56,810 --> 00:07:00,040 So the tilde, that refers to my home directory. 139 00:07:00,040 --> 00:07:03,090 It's a directory you're in when you SSH in. 140 00:07:03,090 --> 00:07:05,660 It's the directory you're in when you open up a terminal. 141 00:07:05,660 --> 00:07:08,650 It's where you start. 142 00:07:08,650 --> 00:07:13,110 And so I'm inside of my home directory, and I'm inside of the vhost 143 00:07:13,110 --> 00:07:14,475 directory inside of my home directory. 144 00:07:14,475 --> 00:07:19,670 And then I'm inside of the local host directory inside of that. 145 00:07:19,670 --> 00:07:23,740 >> So some other useful things with cd-- 146 00:07:23,740 --> 00:07:29,220 or well, in general, so dot always refers to the current directory. 147 00:07:29,220 --> 00:07:31,130 Cd, dot is a pretty worthless command. 148 00:07:31,130 --> 00:07:35,150 But that's changing to the current directory. 149 00:07:35,150 --> 00:07:38,230 A more useful one in terms of cd is dot, dot, which is 150 00:07:38,230 --> 00:07:40,220 just go up one directory. 151 00:07:40,220 --> 00:07:43,360 >> And note that these-- 152 00:07:43,360 --> 00:07:48,610 I want to say aliases, but these symbols, dot, and dot, dot, those work 153 00:07:48,610 --> 00:07:51,740 for pretty much any command you're going to be thinking of running. 154 00:07:51,740 --> 00:07:55,370 So like cd is probably where you'll be using the most, but these aren't 155 00:07:55,370 --> 00:07:56,780 things that just cd understands. 156 00:07:56,780 --> 00:07:59,980 It's pretty much something your entire command line understands. 157 00:07:59,980 --> 00:08:01,932 A lot of programs understand dot and dot, dot. 158 00:08:01,932 --> 00:08:04,830 159 00:08:04,830 --> 00:08:09,090 >> So the other useful ones-- cd, dash. 160 00:08:09,090 --> 00:08:13,460 So that is going to bring me to the last directory that I was in. 161 00:08:13,460 --> 00:08:15,980 So sometimes I'll do something like, oh, I'm working in here. 162 00:08:15,980 --> 00:08:21,110 And I see some error with something, and I'll go investigate it by going to 163 00:08:21,110 --> 00:08:24,020 some random directory somewhere. 164 00:08:24,020 --> 00:08:25,260 And I don't know if it'll let me in there. 165 00:08:25,260 --> 00:08:25,720 It will. 166 00:08:25,720 --> 00:08:27,615 So then I do whatever I want in this directory. 167 00:08:27,615 --> 00:08:28,950 Blah, blah, blah, blah, blah. 168 00:08:28,950 --> 00:08:31,770 And I was like, all right, I want to go back to where I was. 169 00:08:31,770 --> 00:08:34,490 cd, dash, and it brings me right back. 170 00:08:34,490 --> 00:08:39,970 >> So I'm going to throw a lot of these at you today. 171 00:08:39,970 --> 00:08:43,730 I don't expect you to memorize all of them. 172 00:08:43,730 --> 00:08:46,170 It's kind of just know that they exist. 173 00:08:46,170 --> 00:08:48,690 And then later on when you're like, hmm, I want to go back to the 174 00:08:48,690 --> 00:08:51,870 directory that I was just at, oh, wait, something like that exists. 175 00:08:51,870 --> 00:08:53,980 You don't have to just type in the entire directory again. 176 00:08:53,980 --> 00:08:56,090 >> JOSEPH: And eventually you will just use them over and over again, and 177 00:08:56,090 --> 00:08:57,830 it'll become muscle memory. 178 00:08:57,830 --> 00:09:00,090 >> ROB: Yeah. 179 00:09:00,090 --> 00:09:02,930 So how I said before, that tilde is your home directory. 180 00:09:02,930 --> 00:09:04,820 So I can cd, tilde. 181 00:09:04,820 --> 00:09:07,280 But I don't even have to do that if I just-- 182 00:09:07,280 --> 00:09:09,760 I'll go back to the directory so it's not a pointless example. 183 00:09:09,760 --> 00:09:14,560 But if I just do cd, that's also the same as, go to my home directory. 184 00:09:14,560 --> 00:09:18,380 185 00:09:18,380 --> 00:09:19,880 I do Command, K. 186 00:09:19,880 --> 00:09:24,015 >> JOSEPH: You can also type clear, the word, and it should clear it. 187 00:09:24,015 --> 00:09:28,650 >> ROB: And I think also Control, L also does it. 188 00:09:28,650 --> 00:09:29,690 So lots of different ways. 189 00:09:29,690 --> 00:09:34,070 I think there are some differences where clear and Control, L will just 190 00:09:34,070 --> 00:09:37,280 really push it to the top and I can still scroll back. 191 00:09:37,280 --> 00:09:40,580 Command, K literally destroys everything, and you 192 00:09:40,580 --> 00:09:42,960 cannot scroll back up. 193 00:09:42,960 --> 00:09:45,530 At the very least, that's how it works in iTerm2. 194 00:09:45,530 --> 00:09:48,690 I don't know how other things-- 195 00:09:48,690 --> 00:09:49,360 oh. 196 00:09:49,360 --> 00:09:55,450 >> With SSHing, so if you are on Windows, you're going to have to download PuTTY 197 00:09:55,450 --> 00:10:02,360 in order to SSH since Windows does not have like a built-in SSH tool. 198 00:10:02,360 --> 00:10:06,150 From Macs, you can just SSH directly from a terminal window. 199 00:10:06,150 --> 00:10:08,755 200 00:10:08,755 --> 00:10:09,690 OK. 201 00:10:09,690 --> 00:10:11,840 Questions? 202 00:10:11,840 --> 00:10:19,260 >> With ls, so something to get used to with most of these commands is-- 203 00:10:19,260 --> 00:10:20,060 well, I'll just do one. 204 00:10:20,060 --> 00:10:21,310 Ls, dash, l. 205 00:10:21,310 --> 00:10:26,330 So dash, l is what we're going to call a flag to ls. 206 00:10:26,330 --> 00:10:30,770 And a lot of these commands have flags that you can pass to them. 207 00:10:30,770 --> 00:10:35,020 So in this case, dash, l is a flag that tells it to give me a full 208 00:10:35,020 --> 00:10:37,850 listing of all the information of these files. 209 00:10:37,850 --> 00:10:44,790 >> So we see here that desktop was modified on July 30 at 12:54. 210 00:10:44,790 --> 00:10:47,160 Downloads was modified at September 6. 211 00:10:47,160 --> 00:10:52,350 These are the current size and bytes of these directories. 212 00:10:52,350 --> 00:10:54,412 You don't have to understand all of this. 213 00:10:54,412 --> 00:11:00,380 >> This stuff on the left, these drwx's, that will become much more relevant 214 00:11:00,380 --> 00:11:02,290 later when you have to deal with-- 215 00:11:02,290 --> 00:11:05,900 that has to do with who has permissions to look at these files. 216 00:11:05,900 --> 00:11:09,880 And so if you weren't the only user on this computer, you would be able to 217 00:11:09,880 --> 00:11:13,345 say, OK, I should be the only one allowed to look at this file or I'm 218 00:11:13,345 --> 00:11:14,870 going to allow everyone to look at this file. 219 00:11:14,870 --> 00:11:17,710 So someone else on my computer can look at this file. 220 00:11:17,710 --> 00:11:22,190 221 00:11:22,190 --> 00:11:25,600 I don't even know what this-- what does this do? 222 00:11:25,600 --> 00:11:26,840 >> JOSEPH: I'm not quite sure, actually. 223 00:11:26,840 --> 00:11:27,705 >> ROB: No idea. 224 00:11:27,705 --> 00:11:30,530 >> JOSEPH: But if you don't know, there is a helpful command that you can use 225 00:11:30,530 --> 00:11:31,680 to tell you what the output means. 226 00:11:31,680 --> 00:11:33,780 And if you type in man before the command-- 227 00:11:33,780 --> 00:11:35,000 so M-A-N. ROB: Man. 228 00:11:35,000 --> 00:11:37,690 So man is another one that is very useful. 229 00:11:37,690 --> 00:11:39,540 And man, ls. 230 00:11:39,540 --> 00:11:47,320 So the man pages, they have both commands that you're going to be using 231 00:11:47,320 --> 00:11:50,330 at the command line, and they also have functions that will be relevant 232 00:11:50,330 --> 00:11:52,530 with C. So you can man-- 233 00:11:52,530 --> 00:11:53,720 and I ignored 3. 234 00:11:53,720 --> 00:11:57,410 But man 3 printf is going to bring up the C version of printf. 235 00:11:57,410 --> 00:12:01,030 But if I just do man printf, this is going to bring up the command printf 236 00:12:01,030 --> 00:12:03,540 that happens at the command line. 237 00:12:03,540 --> 00:12:05,730 >> So man, ls. 238 00:12:05,730 --> 00:12:09,030 The man pages can be pretty overwhelming. 239 00:12:09,030 --> 00:12:12,770 Here, though, you'll see this listing of all of these flags that ls 240 00:12:12,770 --> 00:12:14,300 understands. 241 00:12:14,300 --> 00:12:17,876 So if we go to dash, l, and-- 242 00:12:17,876 --> 00:12:19,300 I'm just going to throw this at you. 243 00:12:19,300 --> 00:12:23,050 But in order to search, you want to first hit the question 244 00:12:23,050 --> 00:12:24,780 mark or slash button. 245 00:12:24,780 --> 00:12:26,040 So slash. 246 00:12:26,040 --> 00:12:29,000 >> And then I can search for whatever I want. 247 00:12:29,000 --> 00:12:33,780 So I'm going to slash for dash, l. 248 00:12:33,780 --> 00:12:35,110 And there it was. 249 00:12:35,110 --> 00:12:37,450 So use a long listing format. 250 00:12:37,450 --> 00:12:40,060 That doesn't help me figure out what that particular column meant, but I 251 00:12:40,060 --> 00:12:44,480 assume somewhere in here it would explain that. 252 00:12:44,480 --> 00:12:48,740 So use the man pages for any command that you don't immediately understand. 253 00:12:48,740 --> 00:12:51,080 >> I'm pretty sure you can even man, man. 254 00:12:51,080 --> 00:12:53,070 An interface to the online reference manuals. 255 00:12:53,070 --> 00:12:57,700 256 00:12:57,700 --> 00:13:03,570 Oh, one last one that's maybe slightly relevant is ls, dash, a. 257 00:13:03,570 --> 00:13:08,490 So notice if I just do ls, I get these five files. 258 00:13:08,490 --> 00:13:11,480 If I do ls, dash, a, I get a lot more files. 259 00:13:11,480 --> 00:13:15,350 So the thing in common between all these new files is the dot beforehand. 260 00:13:15,350 --> 00:13:21,220 >> So the convention is that a file that begins with a dot is hidden. 261 00:13:21,220 --> 00:13:25,300 So you don't want to see that file, you don't want to have it mess with 262 00:13:25,300 --> 00:13:26,750 your directory listing. 263 00:13:26,750 --> 00:13:30,020 It's only when you explicitly ask, all right, ls, dash, a, show me. 264 00:13:30,020 --> 00:13:32,830 The a stands for all files, including hidden ones. 265 00:13:32,830 --> 00:13:37,260 266 00:13:37,260 --> 00:13:39,270 So some other commands. 267 00:13:39,270 --> 00:13:41,323 Oh, questions at that point? 268 00:13:41,323 --> 00:13:41,746 Yes. 269 00:13:41,746 --> 00:13:45,914 >> SPEAKER 3: When you do ls, a, what's the dot, dot? 270 00:13:45,914 --> 00:13:46,870 >> ROB: Oh. 271 00:13:46,870 --> 00:13:48,780 So this is what I was talking about. 272 00:13:48,780 --> 00:13:50,890 It's the same thing where I can like cd, dot, dot. 273 00:13:50,890 --> 00:13:56,790 So technically, dot and dot, dot are files that exist in every single 274 00:13:56,790 --> 00:14:03,620 directory where the dot file refers to the current directory. 275 00:14:03,620 --> 00:14:06,930 So if I cd, dot, I'm just going to stay in the directory. 276 00:14:06,930 --> 00:14:10,870 And dot, dot always refers to the previous directory one level up. 277 00:14:10,870 --> 00:14:18,200 So if I go into logs and ls, dash, al, I'll see dot, dot. cd to dot, dot 278 00:14:18,200 --> 00:14:20,390 brings me to the previous directory. 279 00:14:20,390 --> 00:14:24,530 280 00:14:24,530 --> 00:14:25,780 Yeah. 281 00:14:25,780 --> 00:14:27,160 282 00:14:27,160 --> 00:14:28,110 OK. 283 00:14:28,110 --> 00:14:33,070 >> So another pretty important command is rm. 284 00:14:33,070 --> 00:14:35,650 So that's what we're going to use to remove. 285 00:14:35,650 --> 00:14:38,100 And let me actually do another command first. 286 00:14:38,100 --> 00:14:39,610 So mkdir. 287 00:14:39,610 --> 00:14:42,770 Mkdir is how you can create directories. 288 00:14:42,770 --> 00:14:47,530 And I'll create a temporary directory and go into that temporary directory. 289 00:14:47,530 --> 00:14:49,590 And as expected, it's empty. 290 00:14:49,590 --> 00:14:53,680 But if I ls, dash, a, I still have dot and dot, dot, because dot refers to 291 00:14:53,680 --> 00:14:54,480 the current directory. 292 00:14:54,480 --> 00:14:56,170 And dot, dot refers to the previous directory. 293 00:14:56,170 --> 00:14:58,700 And those will always exist no matter the directory you are in. 294 00:14:58,700 --> 00:15:01,910 295 00:15:01,910 --> 00:15:09,010 >> And this is a completely unnecessary command, but touch. 296 00:15:09,010 --> 00:15:11,880 I'm just using it, because it's an easy way to create files. 297 00:15:11,880 --> 00:15:16,180 So touch a, touch b, touch c is just going to create three files called a, 298 00:15:16,180 --> 00:15:17,845 b, and c that are completely empty. 299 00:15:17,845 --> 00:15:20,450 300 00:15:20,450 --> 00:15:24,980 So the point of me creating those in the first place is just so that rm is 301 00:15:24,980 --> 00:15:26,250 how we can remove them. 302 00:15:26,250 --> 00:15:27,850 So rm, a. 303 00:15:27,850 --> 00:15:30,960 It's going to ask me, remove regular empty file a? 304 00:15:30,960 --> 00:15:33,170 And then I'll say Yes. 305 00:15:33,170 --> 00:15:39,090 >> So if I know for sure that I want to erase that file without having to be 306 00:15:39,090 --> 00:15:44,500 prompted, remove regular empty file?, then rm, dash, f is going to be the 307 00:15:44,500 --> 00:15:48,230 flag that says, force the remove without even prompting me, oh, are you 308 00:15:48,230 --> 00:15:49,710 sure you want to delete the file? 309 00:15:49,710 --> 00:15:50,810 Yes, I'm sure. 310 00:15:50,810 --> 00:15:56,050 So rm , dash, fb will just do it without asking. 311 00:15:56,050 --> 00:15:57,950 >> So let's make some more directories. 312 00:15:57,950 --> 00:16:03,670 mkdir, tmp2, cd, tmp2, touch a, touch b. 313 00:16:03,670 --> 00:16:04,300 OK. 314 00:16:04,300 --> 00:16:08,180 So now I want to remove tmp2 as a directory. 315 00:16:08,180 --> 00:16:10,316 So rm tmp2. 316 00:16:10,316 --> 00:16:12,920 You cannot remove tmp2, it is a directory. 317 00:16:12,920 --> 00:16:21,370 So the issue here is that rm does not immediately work on directories. 318 00:16:21,370 --> 00:16:26,530 It's only meant for files like non-directory files. 319 00:16:26,530 --> 00:16:30,800 >> And so what we can do here is rm, dash, r. 320 00:16:30,800 --> 00:16:35,160 That stands for recursively, which might not mean anything to you yet. 321 00:16:35,160 --> 00:16:38,280 But when you get to recursion, it'll mean more. 322 00:16:38,280 --> 00:16:43,540 So rm, dash, r, tmp2 is going to recursively go into that directory. 323 00:16:43,540 --> 00:16:45,540 So descend into directory tmp2? 324 00:16:45,540 --> 00:16:47,330 Yes, let's go into that. 325 00:16:47,330 --> 00:16:49,360 Do we want to remove tmp2/a? 326 00:16:49,360 --> 00:16:49,745 Yes. 327 00:16:49,745 --> 00:16:51,830 Do we want to remove tmp2/b? 328 00:16:51,830 --> 00:16:52,840 Yes. 329 00:16:52,840 --> 00:16:55,170 Now do we want to remove the directory tmp2? 330 00:16:55,170 --> 00:16:56,040 Yes. 331 00:16:56,040 --> 00:16:58,410 And so now the directory and everything inside 332 00:16:58,410 --> 00:16:59,660 of it has been removed. 333 00:16:59,660 --> 00:17:02,850 334 00:17:02,850 --> 00:17:07,250 >> There is technically a command rmdir that you can use to remove 335 00:17:07,250 --> 00:17:11,670 directories, but it only works on empty directories anyway. 336 00:17:11,670 --> 00:17:14,109 And to see that, let's just do mkdir, tmp2 again. 337 00:17:14,109 --> 00:17:15,940 Tmp2, touch a. 338 00:17:15,940 --> 00:17:16,800 OK. 339 00:17:16,800 --> 00:17:22,770 So if I try to remove dirtmp2, it'll say, directory not empty. 340 00:17:22,770 --> 00:17:29,540 So I pretty much never use the remove dir command anyway, because rm, dash, 341 00:17:29,540 --> 00:17:35,140 r will work on empty directories and non-empty directories. 342 00:17:35,140 --> 00:17:37,760 >> And also, if I don't want to have to go through that whole process of 343 00:17:37,760 --> 00:17:40,720 descending into the directory and removing each individual file, rm, 344 00:17:40,720 --> 00:17:44,190 dash, rf, tmp2. 345 00:17:44,190 --> 00:17:45,670 And now it's gone. 346 00:17:45,670 --> 00:17:51,220 >> Something to be careful about is rm, dash, rf. 347 00:17:51,220 --> 00:17:53,660 And it scares me to even type it, because if I accidentally 348 00:17:53,660 --> 00:17:55,090 hit Enter or something. 349 00:17:55,090 --> 00:18:02,735 So rm, dash, rf, tilde would, without prompting me, the f does not prompt 350 00:18:02,735 --> 00:18:05,670 me, it will automatically remove my entire home directory and 351 00:18:05,670 --> 00:18:06,780 everything in it. 352 00:18:06,780 --> 00:18:11,460 So you may think that's a stupid thing to do. 353 00:18:11,460 --> 00:18:12,830 And well, it is. 354 00:18:12,830 --> 00:18:18,600 >> But it can happen very easily by accident if, say, I wanted to remove 355 00:18:18,600 --> 00:18:21,640 my slash, vhost directory. 356 00:18:21,640 --> 00:18:26,610 And just in quick typing, I accidentally do this. 357 00:18:26,610 --> 00:18:31,880 That will remove recursively both my home directory and the vhost directory 358 00:18:31,880 --> 00:18:35,450 in this particular directory that just happens to not exist right now. 359 00:18:35,450 --> 00:18:39,520 But this would still remove my entire home directory. 360 00:18:39,520 --> 00:18:43,090 At least by not having an f, it would prompt me first. 361 00:18:43,090 --> 00:18:45,670 And I'd be like, oh, no, I don't want to do that. 362 00:18:45,670 --> 00:18:50,570 But people, slash, including me tend to get into the 363 00:18:50,570 --> 00:18:53,090 habit of always rf-ing. 364 00:18:53,090 --> 00:18:58,713 Even regular files that I can just rm, c, I tend to just rm, dash, rf, c. 365 00:18:58,713 --> 00:19:01,330 Just be careful when you're rf-ing. 366 00:19:01,330 --> 00:19:03,160 >> SPEAKER 4: What does C do? 367 00:19:03,160 --> 00:19:11,570 >> ROB: C is I'm talking about that C file in this directory, that rm, c. 368 00:19:11,570 --> 00:19:15,730 >> JOSEPH: And more dangerously, if you use a star, it refers to everything in 369 00:19:15,730 --> 00:19:16,450 the directory. 370 00:19:16,450 --> 00:19:20,040 So what I commonly tend to do is I will go into a directory and I want to 371 00:19:20,040 --> 00:19:21,510 remove all the files in there. 372 00:19:21,510 --> 00:19:23,640 So rm, dash, rf, star. 373 00:19:23,640 --> 00:19:25,700 >> ROB: Yeah. 374 00:19:25,700 --> 00:19:26,780 Rm, dash, rf, star. 375 00:19:26,780 --> 00:19:29,530 >> JOSEPH: And if you're not careful what directory you're in-- 376 00:19:29,530 --> 00:19:33,340 I wasn't in temp, but I was accidentally in my home directory, 377 00:19:33,340 --> 00:19:35,450 then I'll remove everything in my home directory. 378 00:19:35,450 --> 00:19:39,095 And I've actually done that before, and I think you've done this before or 379 00:19:39,095 --> 00:19:40,640 Jay has done that before. 380 00:19:40,640 --> 00:19:42,480 >> ROB: I've accidentally removed-- 381 00:19:42,480 --> 00:19:44,480 so ignore that command for a bit. 382 00:19:44,480 --> 00:19:45,800 >> JOSEPH: Not fun. 383 00:19:45,800 --> 00:19:52,650 >> ROB: So in the slash bin directory is a bunch of binary files where there'll 384 00:19:52,650 --> 00:19:54,840 be familiar ones like clang. 385 00:19:54,840 --> 00:20:00,740 Well, clang and basically all of these things that I'm running at the command 386 00:20:00,740 --> 00:20:02,060 line are in this slash bin directory. 387 00:20:02,060 --> 00:20:03,090 >> JOSEPH: Like ls is in here. 388 00:20:03,090 --> 00:20:06,285 >> ROB: So dot, slash, ls would list this directory. 389 00:20:06,285 --> 00:20:08,120 >> JOSEPH: Rm is also in this directory. 390 00:20:08,120 --> 00:20:12,770 >> ROB: I have accidentally rm, rf-ed bin, which removed any command I could 391 00:20:12,770 --> 00:20:14,380 possibly ever want. 392 00:20:14,380 --> 00:20:18,085 Which then I just reinstall a new Appliance at that point. 393 00:20:18,085 --> 00:20:20,170 >> JOSEPH: So be very careful when you use this command. 394 00:20:20,170 --> 00:20:21,120 >> AUDIENCE: [INAUDIBLE]? 395 00:20:21,120 --> 00:20:22,640 >> ROB: Yes. 396 00:20:22,640 --> 00:20:24,135 That's also a bad habit to get into. 397 00:20:24,135 --> 00:20:27,920 398 00:20:27,920 --> 00:20:30,170 If you notice, I'm now-- 399 00:20:30,170 --> 00:20:33,580 well, you can't notice, but my zoom-in maybe can. 400 00:20:33,580 --> 00:20:35,360 So I'm now root@appliance. 401 00:20:35,360 --> 00:20:39,790 So jharvard is the user we want you to always be using. 402 00:20:39,790 --> 00:20:43,820 Root is the user that has permission to do absolutely anything. 403 00:20:43,820 --> 00:20:50,260 >> So notice when I'm jharvard, if I try to cd-- 404 00:20:50,260 --> 00:20:52,461 what's a directory that? 405 00:20:52,461 --> 00:20:53,980 Oh, root is a good example. 406 00:20:53,980 --> 00:20:54,950 So cd, root. 407 00:20:54,950 --> 00:20:56,030 Permission denied. 408 00:20:56,030 --> 00:21:00,060 Because if we look at this listing-- 409 00:21:00,060 --> 00:21:02,410 and again, you don't have to entirely understand this. 410 00:21:02,410 --> 00:21:09,210 But these three dashes are saying that do not let any other 411 00:21:09,210 --> 00:21:11,120 user into this directory. 412 00:21:11,120 --> 00:21:14,540 And the directory happens to be owned by user root. 413 00:21:14,540 --> 00:21:20,310 >> So the fact that I am jharvard and no one who is not root is allowed into 414 00:21:20,310 --> 00:21:23,490 this directory, that means that I'm going to get permission denied when I 415 00:21:23,490 --> 00:21:25,160 try to cd into it. 416 00:21:25,160 --> 00:21:31,370 So when I am root, I have permission to do absolutely anything, including 417 00:21:31,370 --> 00:21:34,660 delete essential files to the Appliance and 418 00:21:34,660 --> 00:21:36,640 destroy the entire thing. 419 00:21:36,640 --> 00:21:41,240 >> So it's a bad habit to get into just wandering around your 420 00:21:41,240 --> 00:21:43,650 operating system as root. 421 00:21:43,650 --> 00:21:46,520 I do it anyway. 422 00:21:46,520 --> 00:21:48,710 Questions? 423 00:21:48,710 --> 00:21:52,230 And I'll exit root, stay as jharvard. 424 00:21:52,230 --> 00:21:54,510 OK. 425 00:21:54,510 --> 00:21:55,820 >> More relevant commands. 426 00:21:55,820 --> 00:22:03,975 So going back into our temp, the mv command stands for move. 427 00:22:03,975 --> 00:22:05,450 You can move a. 428 00:22:05,450 --> 00:22:07,610 Now we want to call it b, so now it's called b. 429 00:22:07,610 --> 00:22:10,650 Or maybe we want to move b up one directory. 430 00:22:10,650 --> 00:22:12,730 So now this directory's empty. 431 00:22:12,730 --> 00:22:15,410 I'll go back to my home directory, and we see that b is in here, because the 432 00:22:15,410 --> 00:22:19,230 home directory was one directory up from the directory that b had been in. 433 00:22:19,230 --> 00:22:24,710 434 00:22:24,710 --> 00:22:26,580 >> There's also cp. 435 00:22:26,580 --> 00:22:33,210 So cp is copy super section, dot, text. 436 00:22:33,210 --> 00:22:35,750 I can call it s, dot, text. 437 00:22:35,750 --> 00:22:39,780 Now we have both super section, dot, text; and s, dot, text. 438 00:22:39,780 --> 00:22:41,340 This also works on directories. 439 00:22:41,340 --> 00:22:44,040 440 00:22:44,040 --> 00:22:46,560 I rf-ed a single file. 441 00:22:46,560 --> 00:22:48,200 So cp-- 442 00:22:48,200 --> 00:22:51,710 well, first let's try cp, tmp, tmp2. 443 00:22:51,710 --> 00:22:53,220 So omitting directory tmp. 444 00:22:53,220 --> 00:22:57,440 So similar to rm, the default behavior is to not work on directories. 445 00:22:57,440 --> 00:23:01,570 >> And again, similar to rm, the default behavior-- well, getting it to work 446 00:23:01,570 --> 00:23:04,230 with directories is a, dash-r away. 447 00:23:04,230 --> 00:23:09,240 So copy recursively the temp directory into tmp2. 448 00:23:09,240 --> 00:23:13,700 And so now we have both tmp and tmp2, and that isn't that helpful since tmp 449 00:23:13,700 --> 00:23:16,814 was empty in the first place. 450 00:23:16,814 --> 00:23:18,660 Tmp2. 451 00:23:18,660 --> 00:23:22,680 >> Now let's copy tmp into tmp2. 452 00:23:22,680 --> 00:23:27,900 And we see that tmp2 also has the file a, because the directory and 453 00:23:27,900 --> 00:23:32,220 everything inside of that directory was copied. 454 00:23:32,220 --> 00:23:36,000 And that can be somewhat helpful if, say you're working 455 00:23:36,000 --> 00:23:38,860 on problem set one-- 456 00:23:38,860 --> 00:23:41,320 or actually, later problem sets are even more important, because there 457 00:23:41,320 --> 00:23:43,660 will be a whole bunch of files and things. 458 00:23:43,660 --> 00:23:47,010 >> But you just want to, for a split second, you're like, all right, I'm 459 00:23:47,010 --> 00:23:50,210 going to try something different. 460 00:23:50,210 --> 00:23:57,860 Let me just copy my entire pset1 directory into pset1 backup so that if 461 00:23:57,860 --> 00:24:01,490 I end up screwing things up, I can go back into my backup directory. 462 00:24:01,490 --> 00:24:07,340 There are more appropriate ways of versioning backing up your code, but 463 00:24:07,340 --> 00:24:10,610 this is always a quick way to just make sure you have a copy of something 464 00:24:10,610 --> 00:24:11,860 that you're about to modify. 465 00:24:11,860 --> 00:24:16,974 466 00:24:16,974 --> 00:24:27,090 >> So echo is also a one-off command that kind of sillily will just print to the 467 00:24:27,090 --> 00:24:31,540 command line exactly what you wanted to echo. 468 00:24:31,540 --> 00:24:32,680 So echo hi. 469 00:24:32,680 --> 00:24:35,420 We'll just print hi. 470 00:24:35,420 --> 00:24:38,030 Echo hello world. 471 00:24:38,030 --> 00:24:39,800 We'll print hello world. 472 00:24:39,800 --> 00:24:44,350 That comes into use when you start combining commands. 473 00:24:44,350 --> 00:24:48,300 >> And again, don't expect you to entirely understand this yet, but it's 474 00:24:48,300 --> 00:24:49,910 something to see. 475 00:24:49,910 --> 00:24:52,470 And then if you're Googling for examples or you realize you want to do 476 00:24:52,470 --> 00:24:55,030 something, it can be helpful. 477 00:24:55,030 --> 00:24:59,020 So let's, as an example, so ls, dash, l. 478 00:24:59,020 --> 00:25:01,160 So here I see the output of ls, dash, l. 479 00:25:01,160 --> 00:25:06,560 And I say, OK, I want to store that into a file. 480 00:25:06,560 --> 00:25:11,620 All of this output here, I want to put into a separate file. 481 00:25:11,620 --> 00:25:16,080 >> So this little greater than symbol is what we're going to call. 482 00:25:16,080 --> 00:25:18,570 We're redirecting the output into a file. 483 00:25:18,570 --> 00:25:21,680 Let's call the file blah, because that's what I tend to always call it. 484 00:25:21,680 --> 00:25:26,430 So now we see we have a file blah right here. 485 00:25:26,430 --> 00:25:30,270 And if I open it up, I'll see it's exactly the output from the command 486 00:25:30,270 --> 00:25:31,990 that I just ran. 487 00:25:31,990 --> 00:25:36,020 And similarly, you can-- 488 00:25:36,020 --> 00:25:41,260 if this was output to a file, this is get input from a file. 489 00:25:41,260 --> 00:25:45,790 490 00:25:45,790 --> 00:25:47,050 What is a command that I-- 491 00:25:47,050 --> 00:25:49,620 >> JOSEPH: I think you can use less or more, probably. 492 00:25:49,620 --> 00:25:53,031 >> ROB: But how about just less blah? 493 00:25:53,031 --> 00:25:53,930 I don't know. 494 00:25:53,930 --> 00:25:57,870 If you come into this scenario, like there's psets that it's useful for. 495 00:25:57,870 --> 00:25:59,950 >> JOSEPH: You can pipe it into echo. 496 00:25:59,950 --> 00:26:02,920 Pipe the file into echo to see it. 497 00:26:02,920 --> 00:26:04,060 >> ROB: It's pipe. 498 00:26:04,060 --> 00:26:04,860 >> JOSEPH: Sorry. 499 00:26:04,860 --> 00:26:06,190 >> ROB: All right. 500 00:26:06,190 --> 00:26:12,720 So this is output to a file. 501 00:26:12,720 --> 00:26:18,700 This is get the text from the file and hand it over to the program. 502 00:26:18,700 --> 00:26:20,560 And you'll also see this guy. 503 00:26:20,560 --> 00:26:24,410 So this is kind of doing both at once. 504 00:26:24,410 --> 00:26:28,310 And actually, I'll introduce two new commands just to make use of it. 505 00:26:28,310 --> 00:26:33,060 >> History is a handy command that is just going to print out a listing of 506 00:26:33,060 --> 00:26:34,940 anything I've ever run a command line. 507 00:26:34,940 --> 00:26:38,290 So we see here everything that I have been running this entire time. 508 00:26:38,290 --> 00:26:39,540 Lots of ls's. 509 00:26:39,540 --> 00:26:41,570 510 00:26:41,570 --> 00:26:48,470 >> And another useful command is grep that its purpose is to search over 511 00:26:48,470 --> 00:26:52,060 text looking for patterns, well, looking for whatever you 512 00:26:52,060 --> 00:26:53,310 want it to look for. 513 00:26:53,310 --> 00:26:59,770 And so a handy use here is, say we want to grab the history. 514 00:26:59,770 --> 00:27:03,860 And I want to look for the commands where I-- what's a 515 00:27:03,860 --> 00:27:05,000 useful one to look for? 516 00:27:05,000 --> 00:27:06,898 >> JOSEPH: [INAUDIBLE]? 517 00:27:06,898 --> 00:27:09,710 >> ROB: Or let's just look for all touches, for whatever reason. 518 00:27:09,710 --> 00:27:13,850 So this is what it will look like. 519 00:27:13,850 --> 00:27:15,560 And you don't have to completely understand that. 520 00:27:15,560 --> 00:27:20,570 But the idea is here, history is giving the same output it did here 521 00:27:20,570 --> 00:27:25,030 where it's printing out the entire history of everything I've ever run. 522 00:27:25,030 --> 00:27:27,030 We are then passing that-- 523 00:27:27,030 --> 00:27:30,230 so instead of printing it to the screen, we want to pass that to the 524 00:27:30,230 --> 00:27:34,640 command grep which is looking for all instances of the word touch. 525 00:27:34,640 --> 00:27:40,280 >> And so using this combination of the tools history and grep, I can see, OK, 526 00:27:40,280 --> 00:27:44,820 here's all of the commands I've ever run, and here's a somewhat common one. 527 00:27:44,820 --> 00:27:45,510 We're at the bottom. 528 00:27:45,510 --> 00:27:47,930 And it's also giving me the command I just ran that had the 529 00:27:47,930 --> 00:27:51,240 word touch in it. 530 00:27:51,240 --> 00:27:58,500 But the pipe is a pretty useful thing for combining multiple programs. 531 00:27:58,500 --> 00:28:04,670 And actually, it's a shortcut for let me output history to file blah, and 532 00:28:04,670 --> 00:28:10,190 let me grep using the file blah as what I want to look over. 533 00:28:10,190 --> 00:28:13,460 So the pipe is just a shortcut for those two commands. 534 00:28:13,460 --> 00:28:13,950 Yes. 535 00:28:13,950 --> 00:28:15,306 >> SPEAKER 4: [INAUDIBLE]? 536 00:28:15,306 --> 00:28:16,556 >> ROB: Yes. 537 00:28:16,556 --> 00:28:20,142 538 00:28:20,142 --> 00:28:21,110 What is-- 539 00:28:21,110 --> 00:28:21,858 Oh. 540 00:28:21,858 --> 00:28:24,820 Let's test. 541 00:28:24,820 --> 00:28:29,170 So cat, dog, fish. 542 00:28:29,170 --> 00:28:33,770 So I want to grep. 543 00:28:33,770 --> 00:28:37,680 Dash, r, again, is going to be recursively, so I want to descend down 544 00:28:37,680 --> 00:28:38,870 all directories. 545 00:28:38,870 --> 00:28:43,210 I want to recursively grep for all-- and let me temporarily get 546 00:28:43,210 --> 00:28:44,460 this out of the way. 547 00:28:44,460 --> 00:28:48,650 548 00:28:48,650 --> 00:28:50,740 Ignore me. 549 00:28:50,740 --> 00:28:51,360 OK. 550 00:28:51,360 --> 00:28:56,740 >> So I want to temporarily grep for all instances of the word fish. 551 00:28:56,740 --> 00:29:00,510 And so here what I'm doing is grepping recursively for the word fish. 552 00:29:00,510 --> 00:29:05,410 And star means over all of these files in this directory. 553 00:29:05,410 --> 00:29:08,930 And so it gave me a Permission Denied, because it isn't allowed to read that 554 00:29:08,930 --> 00:29:10,060 particular file. 555 00:29:10,060 --> 00:29:14,040 But it found fish in the file, test. 556 00:29:14,040 --> 00:29:18,450 >> I could also say, specifically, I only want to look in the file blah, in 557 00:29:18,450 --> 00:29:19,580 which case it won't find anything. 558 00:29:19,580 --> 00:29:20,990 I only want to look in the file, test. 559 00:29:20,990 --> 00:29:22,240 It will find fish. 560 00:29:22,240 --> 00:29:25,980 561 00:29:25,980 --> 00:29:29,260 That is a pretty useful command to know in general. 562 00:29:29,260 --> 00:29:31,640 There are some alternatives to grep that are supposed to be more 563 00:29:31,640 --> 00:29:36,780 programmer friendly, but I tend to still fall back on grep. 564 00:29:36,780 --> 00:29:38,030 Questions? 565 00:29:38,030 --> 00:29:39,965 566 00:29:39,965 --> 00:29:40,919 OK. 567 00:29:40,919 --> 00:29:42,520 >> Are there other commands? 568 00:29:42,520 --> 00:29:45,270 Oh. 569 00:29:45,270 --> 00:29:48,370 Just a one-off one that I always find to be fun is cal. 570 00:29:48,370 --> 00:29:55,610 So notice when I'm in this lovely full-screen mode, I have no like top 571 00:29:55,610 --> 00:29:56,720 toolbar or anything. 572 00:29:56,720 --> 00:29:59,530 So cal just gives me a nice little calendar that's right 573 00:29:59,530 --> 00:30:02,380 now cut off, I assume. 574 00:30:02,380 --> 00:30:04,770 But nice little command. 575 00:30:04,770 --> 00:30:06,540 >> JOSEPH: It is [INAUDIBLE]. 576 00:30:06,540 --> 00:30:09,170 Other commands that you might have seen include clang and make. 577 00:30:09,170 --> 00:30:11,180 We'll go over them in more detail later. 578 00:30:11,180 --> 00:30:13,400 But if you've been working on the PSET, you should be 579 00:30:13,400 --> 00:30:15,160 familiar with those. 580 00:30:15,160 --> 00:30:16,640 >> ROB: All right. 581 00:30:16,640 --> 00:30:18,520 Questions on command line things? 582 00:30:18,520 --> 00:30:22,450 583 00:30:22,450 --> 00:30:23,260 All right. 584 00:30:23,260 --> 00:30:27,416 So let's move on to some C-related stuff. 585 00:30:27,416 --> 00:30:28,666 Variables math. 586 00:30:28,666 --> 00:30:39,078 587 00:30:39,078 --> 00:30:40,060 OK. 588 00:30:40,060 --> 00:30:45,230 So just like we had math in Scratch, you can also use math in C. 589 00:30:45,230 --> 00:30:49,270 >> Before we get to that entirely, so variables. 590 00:30:49,270 --> 00:30:53,920 Remember that whenever you declare a variable like int x or float y, you 591 00:30:53,920 --> 00:30:56,710 have to give it type before the variable name. 592 00:30:56,710 --> 00:31:03,020 So types we've seen so far are int, float, double, long long, which I 593 00:31:03,020 --> 00:31:06,150 don't actually know if we've seen that so far. 594 00:31:06,150 --> 00:31:07,700 >> There are some other ones. 595 00:31:07,700 --> 00:31:09,990 We've see char. 596 00:31:09,990 --> 00:31:13,920 There's short, which is like it's the opposite of long long where it's 597 00:31:13,920 --> 00:31:16,650 smaller than an integer. 598 00:31:16,650 --> 00:31:18,580 We have also seen string. 599 00:31:18,580 --> 00:31:23,070 So what is special about string? 600 00:31:23,070 --> 00:31:25,350 Why would I say it's not quite like int? 601 00:31:25,350 --> 00:31:27,030 >> SPEAKER 4: It doesn't really exist. 602 00:31:27,030 --> 00:31:27,990 >> ROB: Yeah. 603 00:31:27,990 --> 00:31:31,820 So the only reason we have string is because when you do 604 00:31:31,820 --> 00:31:33,215 hash, include cs50.h. 605 00:31:33,215 --> 00:31:36,530 606 00:31:36,530 --> 00:31:42,670 And we'll see examples of this later-- oh, that does not handle that well-- 607 00:31:42,670 --> 00:31:46,160 where cs50.h is doing something along the lines of type 608 00:31:46,160 --> 00:31:49,230 def, char star, string. 609 00:31:49,230 --> 00:31:53,280 >> And so that's saying that we don't even know what a char star is yet. 610 00:31:53,280 --> 00:31:56,770 But this is saying we want string. 611 00:31:56,770 --> 00:32:00,250 Any place you've been using string, you could have been using char star, 612 00:32:00,250 --> 00:32:04,670 which actually is a type that exists in the C language. 613 00:32:04,670 --> 00:32:06,680 But we'll get to that. 614 00:32:06,680 --> 00:32:07,860 Oh, and it goes right back. 615 00:32:07,860 --> 00:32:10,170 Neat. 616 00:32:10,170 --> 00:32:15,370 >> So same thing with bool where true and false. 617 00:32:15,370 --> 00:32:22,510 That is not really a built-in type in C. Instead, it's just, does this have 618 00:32:22,510 --> 00:32:23,740 the value zero? 619 00:32:23,740 --> 00:32:26,200 Then we'll just consider it to be false. 620 00:32:26,200 --> 00:32:27,350 Does this have the value-- 621 00:32:27,350 --> 00:32:30,530 well, does this have any value that isn't zero? 622 00:32:30,530 --> 00:32:32,200 Then we'll consider it to be true. 623 00:32:32,200 --> 00:32:35,940 So one is true, two is true, anything nonzero is true. 624 00:32:35,940 --> 00:32:38,710 625 00:32:38,710 --> 00:32:42,790 So those are those. 626 00:32:42,790 --> 00:32:47,624 Questions on declaring variables and variable types and all that? 627 00:32:47,624 --> 00:32:48,100 Yeah. 628 00:32:48,100 --> 00:32:52,384 >> SPEAKER 4: For long long, in the book, it said it had to be long long int. 629 00:32:52,384 --> 00:32:54,288 But will just long long work? 630 00:32:54,288 --> 00:32:58,210 631 00:32:58,210 --> 00:33:01,470 >> ROB: So these type modifiers. 632 00:33:01,470 --> 00:33:04,170 So int x. 633 00:33:04,170 --> 00:33:07,710 So we can also say unsigned int x. 634 00:33:07,710 --> 00:33:09,640 We can say short int x. 635 00:33:09,640 --> 00:33:12,570 We can say long long int x. 636 00:33:12,570 --> 00:33:17,250 But pretty much any of those things I just said, unsigned int, short int, 637 00:33:17,250 --> 00:33:21,480 long long int, you can get rid of the int and it will just assume 638 00:33:21,480 --> 00:33:22,510 that you meant int. 639 00:33:22,510 --> 00:33:26,045 So unsigned x, which just means-- 640 00:33:26,045 --> 00:33:29,400 you know how normally with an int, you can say x equals negative 3? 641 00:33:29,400 --> 00:33:31,636 With an unsigned int, you can't. 642 00:33:31,636 --> 00:33:34,480 >> JOSEPH: And again, for the camera, the question was, what's the difference 643 00:33:34,480 --> 00:33:37,796 between long long int and just long long? 644 00:33:37,796 --> 00:33:38,410 >> ROB: Yeah. 645 00:33:38,410 --> 00:33:42,850 So I will almost never write long long int. 646 00:33:42,850 --> 00:33:44,100 I will write long long. 647 00:33:44,100 --> 00:33:47,770 648 00:33:47,770 --> 00:33:50,636 >> JOSEPH: Any questions? 649 00:33:50,636 --> 00:33:51,886 >> ROB: OK. 650 00:33:51,886 --> 00:33:56,180 651 00:33:56,180 --> 00:34:02,390 So silly little reminder of that's how we declare a variable and initialize 652 00:34:02,390 --> 00:34:04,450 the variable and declare another variable and initialize 653 00:34:04,450 --> 00:34:05,870 it all in one step. 654 00:34:05,870 --> 00:34:09,370 So the declaration of the variable and the initialization variable don't have 655 00:34:09,370 --> 00:34:11,120 to but can be on the same line. 656 00:34:11,120 --> 00:34:15,409 657 00:34:15,409 --> 00:34:20,060 >> So we have the standard math operators that you're used to-- 658 00:34:20,060 --> 00:34:22,199 plus, minus, divide, times. 659 00:34:22,199 --> 00:34:24,389 There's also modulo, which we'll see. 660 00:34:24,389 --> 00:34:29,060 There is not, at least in C, a built-in power 661 00:34:29,060 --> 00:34:31,765 exponentiation caret operator. 662 00:34:31,765 --> 00:34:33,770 Well, there is a caret operator, but it's not power. 663 00:34:33,770 --> 00:34:34,239 >> JOSEPH: But it's not exponentiation, yes. 664 00:34:34,239 --> 00:34:36,210 >> ROB: Do not use the caret to assume that it means 665 00:34:36,210 --> 00:34:39,980 like squared or whatever. 666 00:34:39,980 --> 00:34:42,289 So some things to keep in mind about division. 667 00:34:42,289 --> 00:34:46,282 668 00:34:46,282 --> 00:34:48,880 I'll stand. 669 00:34:48,880 --> 00:34:51,315 So declared initialize answer. 670 00:34:51,315 --> 00:34:54,670 So we're saying float answer equals 1 divided by 10. 671 00:34:54,670 --> 00:34:57,500 Print answer to two decimal places. 672 00:34:57,500 --> 00:35:02,180 >> And this is the sort of thing that I would man printf to figure out that 673 00:35:02,180 --> 00:35:05,110 what the heck does %, dot, 2f mean? 674 00:35:05,110 --> 00:35:07,930 And that just means, well, ignoring the 0.2. 675 00:35:07,930 --> 00:35:10,420 And %, f is what we use to print to float. 676 00:35:10,420 --> 00:35:15,370 The 0.2 is saying, print that float to two decimal places. 677 00:35:15,370 --> 00:35:19,600 So this program has a bug, and you might have seen this before in some 678 00:35:19,600 --> 00:35:20,870 prior CS course. 679 00:35:20,870 --> 00:35:22,170 But what is that bug? 680 00:35:22,170 --> 00:35:23,050 >> SPEAKER 5: Zero. 681 00:35:23,050 --> 00:35:24,130 >> ROB: Yeah. 682 00:35:24,130 --> 00:35:29,630 So when we say, answer equals 1 divided by 10, we want the 683 00:35:29,630 --> 00:35:31,610 answer to be 0.1. 684 00:35:31,610 --> 00:35:37,450 But 1 divided by 10, 1 is an integer, 10 is an integer. 685 00:35:37,450 --> 00:35:41,060 And so when we do an integer divided by an integer, we're going to get back 686 00:35:41,060 --> 00:35:42,190 an integer. 687 00:35:42,190 --> 00:35:43,660 So 1 divided by 10 is 0.1. 688 00:35:43,660 --> 00:35:46,760 >> Since it needs to give us an integer, it's just going to throw away that 689 00:35:46,760 --> 00:35:49,410 decimal place and say that the answer is 0. 690 00:35:49,410 --> 00:35:55,314 And so when we print answer here, it's going to print 0.00. 691 00:35:55,314 --> 00:35:58,430 >> JOSEPH: And just as a note, it actually throws away what's after the 692 00:35:58,430 --> 00:35:59,390 decimal point. 693 00:35:59,390 --> 00:36:03,180 So if you instead had 6 divided by 10, you might think that it would give you 694 00:36:03,180 --> 00:36:05,200 0.6 and then you would round up to 1. 695 00:36:05,200 --> 00:36:10,520 But actually, what happens when it type tasks it is that it drops what is 696 00:36:10,520 --> 00:36:11,470 after the decimal point. 697 00:36:11,470 --> 00:36:13,020 So 0.6 does become 0. 698 00:36:13,020 --> 00:36:13,370 >> ROB: Yeah. 699 00:36:13,370 --> 00:36:15,160 And we'll say truncate for that. 700 00:36:15,160 --> 00:36:21,760 So whenever you cast to an int, the decimal is truncated. 701 00:36:21,760 --> 00:36:23,980 So the fix for that-- there's actually two. 702 00:36:23,980 --> 00:36:27,890 And I'm going to do that second, because this one is a much easier fix. 703 00:36:27,890 --> 00:36:32,670 >> So one fix is use floats in the division. 704 00:36:32,670 --> 00:36:34,720 And really, you only have to make one of them a float. 705 00:36:34,720 --> 00:36:37,400 But it's somewhat clearer just to make both of them floats. 706 00:36:37,400 --> 00:36:41,170 So 1.0 divided by 10.0 is dividing two floats. 707 00:36:41,170 --> 00:36:43,970 So the answer will end up being a float, and so you will 708 00:36:43,970 --> 00:36:48,050 correctly print 0.10 here. 709 00:36:48,050 --> 00:36:52,220 >> Something that doesn't work so well about that is, well, sure, it was easy 710 00:36:52,220 --> 00:36:56,240 enough to convert 1 to a float by making it 1.0. 711 00:36:56,240 --> 00:37:02,180 But what if instead we had two integers like int x equals 1 and int y 712 00:37:02,180 --> 00:37:05,660 equals 10, and then we wanted to do x divided by y? 713 00:37:05,660 --> 00:37:10,420 So it isn't easy to just do x.0 or something. 714 00:37:10,420 --> 00:37:12,790 >> So the fix to that is casting. 715 00:37:12,790 --> 00:37:19,780 So casting is a way in C to convert from one variable type to another. 716 00:37:19,780 --> 00:37:22,320 So here, 1 is an integer. 717 00:37:22,320 --> 00:37:27,050 And by putting this float in front of it, we are casting 1 to a float. 718 00:37:27,050 --> 00:37:30,350 And so this will convert the 1 to a 1.0. 719 00:37:30,350 --> 00:37:33,380 And this will convert the 10 to a 10.0. 720 00:37:33,380 --> 00:37:36,790 >> And then things behave similarly to the previous version we just showed 721 00:37:36,790 --> 00:37:42,190 where, as expected, we get 0.10 and it'll print that. 722 00:37:42,190 --> 00:37:44,120 And we can do this with variables, too. 723 00:37:44,120 --> 00:37:47,376 So we can say, float x divided by float y. 724 00:37:47,376 --> 00:37:48,626 >> JOSEPH: Any questions? 725 00:37:48,626 --> 00:37:54,182 726 00:37:54,182 --> 00:38:00,090 >> ROB: So just like in regular math, we have operator precedence. 727 00:38:00,090 --> 00:38:06,960 So in math class, you're more likely to call it order of operations. 728 00:38:06,960 --> 00:38:09,890 Here, the official term is operator precedence. 729 00:38:09,890 --> 00:38:15,230 But the operator precedence, or most operators, is as you would expect. 730 00:38:15,230 --> 00:38:22,660 >> So just like in math, 2 times 10 is going to be grouped more closely than 731 00:38:22,660 --> 00:38:25,410 this 10 divided by 2 and then 2. 732 00:38:25,410 --> 00:38:29,745 The order of operations, it will do 2 times 10, 10 divided by 2, and then 733 00:38:29,745 --> 00:38:32,720 it'll do 20 plus 5 plus 2. 734 00:38:32,720 --> 00:38:37,020 So it's as expected, and you can use parentheses to group expressions. 735 00:38:37,020 --> 00:38:41,063 You cannot use square brackets to group expressions. 736 00:38:41,063 --> 00:38:41,544 Yeah? 737 00:38:41,544 --> 00:38:43,468 >> SPEAKER 5: Could you actually just go back one second? 738 00:38:43,468 --> 00:38:47,316 Can you cast an int to a string? 739 00:38:47,316 --> 00:38:53,330 >> ROB: So in C, you can cast anything you want to anything you want. 740 00:38:53,330 --> 00:38:55,600 That doesn't mean it's a good thing to do. 741 00:38:55,600 --> 00:38:59,760 So when you cast an int to a string, that means-- 742 00:38:59,760 --> 00:39:03,240 and we'll get into this much more thoroughly-- 743 00:39:03,240 --> 00:39:03,720 >> JOSEPH: Much later. 744 00:39:03,720 --> 00:39:06,840 >> ROB: I didn't want to say much later, so I tried to change my sentence. 745 00:39:06,840 --> 00:39:13,370 We'll get into it much more thoroughly later where really when you have a 746 00:39:13,370 --> 00:39:14,810 string variable-- 747 00:39:14,810 --> 00:39:17,160 so a string can be arbitrarily long, right? 748 00:39:17,160 --> 00:39:21,850 And we've been saying that an int is four bytes and long long is eight 749 00:39:21,850 --> 00:39:23,620 bytes and a float is four bytes. 750 00:39:23,620 --> 00:39:29,520 So a string, just like an int, only has a certain number of bytes to it. 751 00:39:29,520 --> 00:39:31,800 And that will be four bytes. 752 00:39:31,800 --> 00:39:34,750 >> But a string can be pretty arbitrarily long, right? 753 00:39:34,750 --> 00:39:40,190 So hello world already, if that's 10 characters or whatever, that's already 754 00:39:40,190 --> 00:39:42,670 going to be over the 4 bytes I can fit into a string. 755 00:39:42,670 --> 00:39:51,140 And so how strings really work is that they are where in memory that string 756 00:39:51,140 --> 00:39:52,380 is being kept. 757 00:39:52,380 --> 00:39:57,290 >> And so over here, when I say string x equals hello world, inside of x is 758 00:39:57,290 --> 00:40:01,840 just saying, oh, hello world is stored at this particular place in memory. 759 00:40:01,840 --> 00:40:07,060 So if we try to cast an integer to a string, then we're trying to interpret 760 00:40:07,060 --> 00:40:10,500 some random part of memory as a string. 761 00:40:10,500 --> 00:40:14,465 And that almost always breaks things. 762 00:40:14,465 --> 00:40:17,040 >> JOSEPH: But if that confuses you, we'll be covering it 763 00:40:17,040 --> 00:40:17,550 more in depth later. 764 00:40:17,550 --> 00:40:17,850 >> ROB: Yeah. 765 00:40:17,850 --> 00:40:20,540 This is where you're going to get into pointers. 766 00:40:20,540 --> 00:40:25,485 And that is a significant chunk of two weeks of this course. 767 00:40:25,485 --> 00:40:28,275 >> SPEAKER 6: Does it work like objects in other languages or not really? 768 00:40:28,275 --> 00:40:34,050 >> ROB: So in other languages, objects would be represented using pointers. 769 00:40:34,050 --> 00:40:37,070 770 00:40:37,070 --> 00:40:38,793 It's not the same thing, though. 771 00:40:38,793 --> 00:40:42,110 772 00:40:42,110 --> 00:40:42,910 Any thoughts? 773 00:40:42,910 --> 00:40:43,760 >> JOSEPH: No. 774 00:40:43,760 --> 00:40:44,185 No thoughts. 775 00:40:44,185 --> 00:40:44,980 >> ROB: OK. 776 00:40:44,980 --> 00:40:46,994 >> JOSEPH: Next. 777 00:40:46,994 --> 00:40:48,255 >> ROB: Just go with that. 778 00:40:48,255 --> 00:40:48,670 All right. 779 00:40:48,670 --> 00:40:51,120 So modulo. 780 00:40:51,120 --> 00:40:53,900 Just like we have plus, minus, divide, and multiply. 781 00:40:53,900 --> 00:40:56,720 So modulo is one you may not have seen before. 782 00:40:56,720 --> 00:40:59,540 And it just says, give me the remainder of. 783 00:40:59,540 --> 00:41:02,850 So 55 % 10. 784 00:41:02,850 --> 00:41:06,840 The remainder of doing 55 divided by 10 would be 5. 785 00:41:06,840 --> 00:41:09,630 So 55 % 10 is 5. 786 00:41:09,630 --> 00:41:12,260 And 3 % 5 would be 3. 787 00:41:12,260 --> 00:41:14,180 8 % 8 will be 0. 788 00:41:14,180 --> 00:41:15,903 16 % 15 will be 1. 789 00:41:15,903 --> 00:41:20,670 >> JOSEPH: One thing to note with this, too, is it might not work as expected 790 00:41:20,670 --> 00:41:22,700 if you use a negative number. 791 00:41:22,700 --> 00:41:26,215 So negative 5 % 4, some people might think that is-- 792 00:41:26,215 --> 00:41:28,890 793 00:41:28,890 --> 00:41:33,808 what would you think negative 5 % 4 would be? 794 00:41:33,808 --> 00:41:34,792 >> SPEAKER 5: One. 795 00:41:34,792 --> 00:41:37,920 >> JOSEPH: So some people say one, some people say negative one. 796 00:41:37,920 --> 00:41:38,450 But what-- 797 00:41:38,450 --> 00:41:40,820 >> ROB: I wouldn't even have said one of those. 798 00:41:40,820 --> 00:41:42,370 >> JOSEPH: Two, sorry. 799 00:41:42,370 --> 00:41:43,240 Some people say-- 800 00:41:43,240 --> 00:41:43,450 >> ROB: Three. 801 00:41:43,450 --> 00:41:43,800 >> JOSEPH: Three? 802 00:41:43,800 --> 00:41:44,890 >> ROB: Negative-- 803 00:41:44,890 --> 00:41:45,950 what was the-- negative five-- 804 00:41:45,950 --> 00:41:47,100 >> JOSEPH: Three, three, three. 805 00:41:47,100 --> 00:41:48,450 Sorry. 806 00:41:48,450 --> 00:41:51,910 Because modulo, generally, when you've seen it elsewhere, it usually means 807 00:41:51,910 --> 00:41:54,000 return a positive number, right? 808 00:41:54,000 --> 00:42:01,160 >> ROB: So when we say in math, % 10's, they tend to want to give you-- 809 00:42:01,160 --> 00:42:05,980 if we mod by 10, then we expect to get a number between 0 and 9. 810 00:42:05,980 --> 00:42:09,860 In here, that is not the case that you will get negative numbers returned. 811 00:42:09,860 --> 00:42:15,898 >> JOSEPH: So negative 5 % 4 would be negative 1. 812 00:42:15,898 --> 00:42:19,325 >> ROB: But it's rare that you're mod-ing negative numbers to begin with. 813 00:42:19,325 --> 00:42:25,490 814 00:42:25,490 --> 00:42:25,970 Skip this. 815 00:42:25,970 --> 00:42:27,314 >> JOSEPH: Yeah. 816 00:42:27,314 --> 00:42:29,420 >> ROB: Meh. 817 00:42:29,420 --> 00:42:29,990 OK. 818 00:42:29,990 --> 00:42:36,400 So one last thing to point out about floats is it's a dangerous behavior, 819 00:42:36,400 --> 00:42:39,850 but floats are not an exact representation. 820 00:42:39,850 --> 00:42:46,190 So going back to bytes again, remember that an int is always four bytes and a 821 00:42:46,190 --> 00:42:47,830 float is always four bytes. 822 00:42:47,830 --> 00:42:51,340 So Lucas's example is pretty good. 823 00:42:51,340 --> 00:42:55,730 >> So think of 1 divided by 3. 824 00:42:55,730 --> 00:42:57,800 So 0.3333333. 825 00:42:57,800 --> 00:43:03,540 If I only have 32 bits, how can I store 0.33333 exactly? 826 00:43:03,540 --> 00:43:07,250 And maybe, for whatever reason, you say, all right, well, let's just say 827 00:43:07,250 --> 00:43:13,210 that this particular 1011001, let's just say that should be 0.333333. 828 00:43:13,210 --> 00:43:16,960 Well, you only have a finite number of those bits, so it's impossible to 829 00:43:16,960 --> 00:43:22,550 represent every single floating point value given just 32 bits. 830 00:43:22,550 --> 00:43:25,580 >> Well, it's impossible to represent any floating point value given infinite-- 831 00:43:25,580 --> 00:43:28,480 well, given any finite number of bits. 832 00:43:28,480 --> 00:43:38,265 So the issue here is, well, when we used to print to two decimal places, 833 00:43:38,265 --> 00:43:42,000 we did correctly get the answer 0.10. 834 00:43:42,000 --> 00:43:47,510 But underneath the hood, it's really being stored as close as possible to 835 00:43:47,510 --> 00:43:51,790 0.10 as those bits can represent. 836 00:43:51,790 --> 00:43:53,200 Is this on the next slide? 837 00:43:53,200 --> 00:43:53,830 Or is it not? 838 00:43:53,830 --> 00:43:54,660 >> JOSEPH: Yeah, it's that. 839 00:43:54,660 --> 00:43:55,750 >> ROB: Blegh, blegh. 840 00:43:55,750 --> 00:43:57,760 >> JOSEPH: Yeah, you can just pull the notes up a bit. 841 00:43:57,760 --> 00:43:59,700 >> ROB: I'm just going to zoom in on the last on that. 842 00:43:59,700 --> 00:44:00,950 Oh my gosh, that's [INAUDIBLE]. 843 00:44:00,950 --> 00:44:06,089 844 00:44:06,089 --> 00:44:08,300 So that number. 845 00:44:08,300 --> 00:44:12,300 That is what will be printed if we run that program. 846 00:44:12,300 --> 00:44:20,340 And notice that's not really a big deal if we're only caring about like 847 00:44:20,340 --> 00:44:21,920 two to three decimal places. 848 00:44:21,920 --> 00:44:26,700 Like we only originally printed 0.10, and that's why we saw nothing wrong. 849 00:44:26,700 --> 00:44:31,380 But once we start getting into the exact, exact number that it's 850 00:44:31,380 --> 00:44:35,660 representing, we see that it can't exactly represent 0.1. 851 00:44:35,660 --> 00:44:40,900 >> And part of the problem here is like, all right, that's fine, but, well, 852 00:44:40,900 --> 00:44:46,120 first, what if we tried to do, answer equals equals 0.1? 853 00:44:46,120 --> 00:44:49,200 Is that going to return true or false? 854 00:44:49,200 --> 00:44:51,850 And so it's hard to say. 855 00:44:51,850 --> 00:44:53,330 I think it actually might return true. 856 00:44:53,330 --> 00:44:55,265 Will it first-- 857 00:44:55,265 --> 00:44:56,180 I don't know. 858 00:44:56,180 --> 00:45:00,090 The answer is once you start dealing with floating point values, you pretty 859 00:45:00,090 --> 00:45:05,150 much should not be using equality because of this imprecision. 860 00:45:05,150 --> 00:45:09,470 >> And for all you know, it's the hundredth decimal place that the 861 00:45:09,470 --> 00:45:13,670 floating point was not able to correctly handle. 862 00:45:13,670 --> 00:45:18,180 And so equality will just fail even though the number-- if you had been 863 00:45:18,180 --> 00:45:24,450 using exact numbers, the numbers should have been exactly the same. 864 00:45:24,450 --> 00:45:27,790 It's over the course of like 50 calculations using these floating 865 00:45:27,790 --> 00:45:30,270 point values, the error can build up and up and up, and 866 00:45:30,270 --> 00:45:31,125 things just get wrong. 867 00:45:31,125 --> 00:45:33,870 >> JOSEPH: And there have been really famous examples of this happening. 868 00:45:33,870 --> 00:45:37,190 Like NASA engineers have gotten this wrong, causing rockets to explode in 869 00:45:37,190 --> 00:45:38,665 the air after they've been launched. 870 00:45:38,665 --> 00:45:41,490 And lots of issues like that. 871 00:45:41,490 --> 00:45:41,956 So yeah. 872 00:45:41,956 --> 00:45:45,218 >> SPEAKER 6: When you say 0.3 f, does it truncate the rest? 873 00:45:45,218 --> 00:45:46,468 Or does it round up or down? 874 00:45:46,468 --> 00:45:48,800 875 00:45:48,800 --> 00:45:50,200 >> ROB: Will printf round it? 876 00:45:50,200 --> 00:45:52,180 >> JOSEPH: I think printf truncates. 877 00:45:52,180 --> 00:45:52,640 >> ROB: OK. 878 00:45:52,640 --> 00:45:59,890 So we can similarly go in the opposite direction of this where, in this case, 879 00:45:59,890 --> 00:46:03,320 the closest it could represent 0.1 was with this number. 880 00:46:03,320 --> 00:46:06,820 The closest it might be able to represent 0.2 is in the opposite 881 00:46:06,820 --> 00:46:11,420 direction, 0.199999996356 or something. 882 00:46:11,420 --> 00:46:17,480 So if we went in that direction of things, then printf 0.3 f would return 883 00:46:17,480 --> 00:46:20,866 1.99 instead of 2.00. 884 00:46:20,866 --> 00:46:22,960 >> JOSEPH: And I'm not entirely sure on that. 885 00:46:22,960 --> 00:46:25,430 You might want to write a small, little program to just check that. 886 00:46:25,430 --> 00:46:29,370 >> ROB: Though, what we are sure of is that if you tried to cast that to an 887 00:46:29,370 --> 00:46:33,660 int, and casting to an int is going to cause it to truncate the decimal, if 888 00:46:33,660 --> 00:46:38,140 you try to cast 1.9999999 to an int, you'll get 1. 889 00:46:38,140 --> 00:46:41,440 And so you should generally use the round function in the math library. 890 00:46:41,440 --> 00:46:44,190 891 00:46:44,190 --> 00:46:45,440 Questions? 892 00:46:45,440 --> 00:46:47,660 893 00:46:47,660 --> 00:46:48,982 OK. 894 00:46:48,982 --> 00:46:54,000 >> JOSEPH: So moving on to conditions and Boolean expressions. 895 00:46:54,000 --> 00:46:58,120 So you have seen these before. 896 00:46:58,120 --> 00:47:07,420 And actually, let me make sure my computer's in the right format here. 897 00:47:07,420 --> 00:47:08,670 Space. 898 00:47:08,670 --> 00:47:10,630 899 00:47:10,630 --> 00:47:13,870 Sorry, we're going to have to deal a little bit with cutoff at the edges. 900 00:47:13,870 --> 00:47:15,830 >> But yeah, you guys have seen this before in Scratch. 901 00:47:15,830 --> 00:47:19,930 So this right here is an expression which is used in 902 00:47:19,930 --> 00:47:21,250 a conditional statement. 903 00:47:21,250 --> 00:47:23,930 So answer greater than zero will tell you true or false. 904 00:47:23,930 --> 00:47:26,530 And these are really important, because they allow us to introduce 905 00:47:26,530 --> 00:47:28,670 logic into our code. 906 00:47:28,670 --> 00:47:32,820 >> So for example, this is a program written in Scratch that asks the user 907 00:47:32,820 --> 00:47:36,980 for an integer and tells them whether the integer that they gave you was a 908 00:47:36,980 --> 00:47:38,690 positive or negative number. 909 00:47:38,690 --> 00:47:42,980 And the conversion over here to see is you first print out the statement, 910 00:47:42,980 --> 00:47:43,870 give me an integer. 911 00:47:43,870 --> 00:47:45,980 And then you ask them for an integer. 912 00:47:45,980 --> 00:47:49,870 >> And then you use conditional logic over here to check whether that number 913 00:47:49,870 --> 00:47:52,030 was actually greater than zero or not. 914 00:47:52,030 --> 00:47:58,960 So here we have a Boolean expression inside of a conditional If statement. 915 00:47:58,960 --> 00:48:00,660 Is there any questions? 916 00:48:00,660 --> 00:48:03,030 Are there any questions about that? 917 00:48:03,030 --> 00:48:03,950 OK. 918 00:48:03,950 --> 00:48:06,140 >> So there's more than just greater than, of course. 919 00:48:06,140 --> 00:48:10,385 You can construct Boolean expressions using most of the sorts of things you 920 00:48:10,385 --> 00:48:11,150 would think of in math. 921 00:48:11,150 --> 00:48:12,370 So greater than. 922 00:48:12,370 --> 00:48:13,740 That should be a less than. 923 00:48:13,740 --> 00:48:14,990 Sorry. 924 00:48:14,990 --> 00:48:18,520 925 00:48:18,520 --> 00:48:19,760 And the spacing. 926 00:48:19,760 --> 00:48:22,971 >> ROB: God forbid you leave it. 927 00:48:22,971 --> 00:48:23,620 >> JOSEPH: All right. 928 00:48:23,620 --> 00:48:25,950 So greater than, less than, greater than, or equal to, less 929 00:48:25,950 --> 00:48:27,070 than, or equal to. 930 00:48:27,070 --> 00:48:31,980 We use double equals to check for equality, because single equals means 931 00:48:31,980 --> 00:48:32,810 assignment, right? 932 00:48:32,810 --> 00:48:33,140 Yes. 933 00:48:33,140 --> 00:48:37,130 And then we can also do not equals by using exclamation mark, equals. 934 00:48:37,130 --> 00:48:41,530 >> And this exclamation mark symbol can also be extended so that if you want 935 00:48:41,530 --> 00:48:44,050 to invert any sort of Boolean expression, you can do that. 936 00:48:44,050 --> 00:48:48,530 So this will evaluate to true only if the answer is less 937 00:48:48,530 --> 00:48:51,240 than or equal to zero. 938 00:48:51,240 --> 00:48:53,950 Any questions on that? 939 00:48:53,950 --> 00:48:55,180 OK. 940 00:48:55,180 --> 00:48:58,840 >> So you can also combine these expressions using logical And and 941 00:48:58,840 --> 00:48:59,790 logical Or. 942 00:48:59,790 --> 00:49:03,530 So this is just the And symbol, which should be Shift, 7. 943 00:49:03,530 --> 00:49:07,720 And this is the pipe symbol, which is not a lower case L. It's the one 944 00:49:07,720 --> 00:49:09,440 that's right above your Enter key. 945 00:49:09,440 --> 00:49:12,870 So you use two of these to symbolize logical And the logical Or. 946 00:49:12,870 --> 00:49:18,180 >> So this will only return true if answer is one, two, three, or four. 947 00:49:18,180 --> 00:49:23,030 And this will only return true if answer is beyond that on either side. 948 00:49:23,030 --> 00:49:26,190 So it's not one, two, three, or four. 949 00:49:26,190 --> 00:49:28,385 And the way you would use that in an expression-- 950 00:49:28,385 --> 00:49:29,990 >> ROB: Or a zero or a five. 951 00:49:29,990 --> 00:49:32,200 >> JOSEPH: Zero or a five. 952 00:49:32,200 --> 00:49:32,380 Sorry. 953 00:49:32,380 --> 00:49:33,320 Yes, yes, yes. 954 00:49:33,320 --> 00:49:34,180 OK. 955 00:49:34,180 --> 00:49:38,980 And over here now, the same way you would use that expression, a smaller 956 00:49:38,980 --> 00:49:42,000 expression side of an If conditional statement, you would also use it the 957 00:49:42,000 --> 00:49:47,800 same way by just putting it inside of the parentheses of the If statement. 958 00:49:47,800 --> 00:49:54,020 So this printf will only fire if answer is one, two, three, or four. 959 00:49:54,020 --> 00:49:56,002 Any questions on combining expressions? 960 00:49:56,002 --> 00:50:00,450 961 00:50:00,450 --> 00:50:04,240 >> So there's another conditional construct we call an If/Else. 962 00:50:04,240 --> 00:50:08,120 So basically, this now means, OK, If something I wanted to check was not 963 00:50:08,120 --> 00:50:11,600 true, then go to the Else and perform that other action. 964 00:50:11,600 --> 00:50:15,570 So in this particular case, I asked the user for an integer. 965 00:50:15,570 --> 00:50:17,790 Is the integer greater than zero? 966 00:50:17,790 --> 00:50:18,310 Yes? 967 00:50:18,310 --> 00:50:20,100 Well, then they picked a positive number. 968 00:50:20,100 --> 00:50:22,320 If not, then it must have been negative or a zero. 969 00:50:22,320 --> 00:50:27,530 So you picked a negative number or a zero in this case. 970 00:50:27,530 --> 00:50:29,235 Yes. 971 00:50:29,235 --> 00:50:30,485 Or a zero. 972 00:50:30,485 --> 00:50:36,320 973 00:50:36,320 --> 00:50:39,300 >> And then we also have If/Else, If and Else. 974 00:50:39,300 --> 00:50:45,640 So this lets us execute a sequence of things only if the first ones fail. 975 00:50:45,640 --> 00:50:49,540 So in this case, now we're making the last one you pick zero. 976 00:50:49,540 --> 00:50:53,080 So if they neither picked a positive nor a negative number, then they must 977 00:50:53,080 --> 00:50:53,640 have picked zero. 978 00:50:53,640 --> 00:50:56,720 So it just goes down the chain like this. 979 00:50:56,720 --> 00:50:59,960 >> So an example of how an If is different from-- 980 00:50:59,960 --> 00:51:02,590 an If/Else is different from just a sequence of Ifs. 981 00:51:02,590 --> 00:51:07,680 And this is a common question that people ask is, well, if you get like a 982 00:51:07,680 --> 00:51:11,265 95 in CS50, what will this program tell you? 983 00:51:11,265 --> 00:51:12,600 >> SPEAKER 5: You got an A. 984 00:51:12,600 --> 00:51:13,490 >> JOSEPH: Yes. 985 00:51:13,490 --> 00:51:14,960 You got every single one of those right. 986 00:51:14,960 --> 00:51:17,130 You got an A, you got a B, you got a C and a D, right? 987 00:51:17,130 --> 00:51:19,770 So all of these get evaluated in order. 988 00:51:19,770 --> 00:51:23,570 So while a 95 is greater than 90, it's also greater than 80, it's also 989 00:51:23,570 --> 00:51:25,790 greater than 70, and it's also greater than 60. 990 00:51:25,790 --> 00:51:27,620 So you got all of those grades. 991 00:51:27,620 --> 00:51:31,630 And I assume you would only want the A. 992 00:51:31,630 --> 00:51:34,060 >> The way to fix that is to replace those with Else/If's. 993 00:51:34,060 --> 00:51:37,540 So in this scenario, it sees that 95 is greater than 90, and then it does 994 00:51:37,540 --> 00:51:38,885 not evaluate the rest of the statements. 995 00:51:38,885 --> 00:51:41,900 996 00:51:41,900 --> 00:51:43,150 Any questions about that? 997 00:51:43,150 --> 00:51:48,580 998 00:51:48,580 --> 00:51:52,470 >> So there's another conditional sort of structure that we have here which we 999 00:51:52,470 --> 00:51:53,390 call a switch statement. 1000 00:51:53,390 --> 00:51:57,390 So this allows you to basically check what the value of a number you put 1001 00:51:57,390 --> 00:51:59,000 into the switch statement is. 1002 00:51:59,000 --> 00:52:03,200 So in this scenario, we're switching on n, and we're saying, oh, if n is 1003 00:52:03,200 --> 00:52:04,710 one, then print that statement. 1004 00:52:04,710 --> 00:52:07,910 And then break, which means exit out of the switch statement. 1005 00:52:07,910 --> 00:52:12,670 >> If it wasn't one, then, well, just eventually check all of those cases. 1006 00:52:12,670 --> 00:52:16,280 And so it checks if it's one or two or three, and it prints accordingly. 1007 00:52:16,280 --> 00:52:19,780 And what this default keyword down here means is if they didn't enter any 1008 00:52:19,780 --> 00:52:21,690 of those, then say Invalid. 1009 00:52:21,690 --> 00:52:25,910 So let's say I ask for n and the user gives me four. 1010 00:52:25,910 --> 00:52:29,470 Well, it matches none of those cases, so it will print out what's in the 1011 00:52:29,470 --> 00:52:30,540 default section. 1012 00:52:30,540 --> 00:52:31,180 Yes, question? 1013 00:52:31,180 --> 00:52:32,614 >> SPEAKER 5: Can you use Boolean expressions instead of 1014 00:52:32,614 --> 00:52:33,570 one, two, or three? 1015 00:52:33,570 --> 00:52:36,940 >> JOSEPH: So the question is can you use Boolean expressions instead of one, 1016 00:52:36,940 --> 00:52:37,940 two, and three? 1017 00:52:37,940 --> 00:52:40,520 And in C, I believe you cannot do that. 1018 00:52:40,520 --> 00:52:44,320 But in other languages, which you might encounter at the end of the 1019 00:52:44,320 --> 00:52:46,460 semester like JavaScript, you can. 1020 00:52:46,460 --> 00:52:50,050 Well, you would have to compute first that value and then use it in the 1021 00:52:50,050 --> 00:52:50,650 switch statement. 1022 00:52:50,650 --> 00:52:50,930 Yeah? 1023 00:52:50,930 --> 00:52:54,760 >> ROB: So part of the benefit of switch statements is think of if you did this 1024 00:52:54,760 --> 00:52:58,680 as an If/Else, so like if n equals equals one or whatever. 1025 00:52:58,680 --> 00:53:00,300 Else/If n equals equals two, whatever. 1026 00:53:00,300 --> 00:53:01,960 Else/If n equals equals three. 1027 00:53:01,960 --> 00:53:05,930 So the way the program would run is it would sequentially go down that list 1028 00:53:05,930 --> 00:53:07,500 and check, is n one? 1029 00:53:07,500 --> 00:53:08,040 Nope. 1030 00:53:08,040 --> 00:53:09,070 Is n two? 1031 00:53:09,070 --> 00:53:09,490 Nope. 1032 00:53:09,490 --> 00:53:10,940 Is n three? 1033 00:53:10,940 --> 00:53:11,710 Yeah. 1034 00:53:11,710 --> 00:53:12,610 Do this. 1035 00:53:12,610 --> 00:53:15,270 >> Whereas with switch statements, it's actually able to compile it to be 1036 00:53:15,270 --> 00:53:16,360 really fast. 1037 00:53:16,360 --> 00:53:19,550 And as soon as it says switch, it says, all right, n is two, I am 1038 00:53:19,550 --> 00:53:23,060 immediately going to jump to where I am supposed to start executing. 1039 00:53:23,060 --> 00:53:26,080 I'm not going to first check, is n one, is n two? 1040 00:53:26,080 --> 00:53:28,860 It can immediately start doing what it's supposed to do. 1041 00:53:28,860 --> 00:53:33,830 >> And because of that, it can't take Boolean conditions. 1042 00:53:33,830 --> 00:53:36,480 Or else it would have to do the sequential, like, all right, is n 1043 00:53:36,480 --> 00:53:37,820 greater than zero? 1044 00:53:37,820 --> 00:53:41,140 Else is n greater than 10 or whatever. 1045 00:53:41,140 --> 00:53:44,780 >> JOSEPH: In this case, if you used If/Else, If's, then the switch would 1046 00:53:44,780 --> 00:53:47,792 run approximately three times faster than the If/Else, If. 1047 00:53:47,792 --> 00:53:53,060 1048 00:53:53,060 --> 00:53:56,040 We can organize the switch in such a way that we don't break 1049 00:53:56,040 --> 00:53:57,520 after each of the cases. 1050 00:53:57,520 --> 00:54:00,960 So in this case, I'm partitioning the numbers that we choose into one and 1051 00:54:00,960 --> 00:54:04,250 two being not high numbers and three being a high number. 1052 00:54:04,250 --> 00:54:08,290 >> So in this case, if n is one or two, it will hit the case and then it will 1053 00:54:08,290 --> 00:54:10,640 fall through, because there is no break. 1054 00:54:10,640 --> 00:54:11,610 And it will end up here. 1055 00:54:11,610 --> 00:54:15,360 So if we pick one, it will do the printf and then break so that none of 1056 00:54:15,360 --> 00:54:17,610 this is executed. 1057 00:54:17,610 --> 00:54:21,870 And of course, if they enter in three or something else, then it will skip 1058 00:54:21,870 --> 00:54:25,320 those and not go there, and it will execute instead the 1059 00:54:25,320 --> 00:54:27,490 corresponding line. 1060 00:54:27,490 --> 00:54:29,390 Are there any questions about that? 1061 00:54:29,390 --> 00:54:29,780 Yes? 1062 00:54:29,780 --> 00:54:32,642 >> SPEAKER 4: Would you get an error if you had a break after case one but it 1063 00:54:32,642 --> 00:54:34,550 didn't have something for it to do? 1064 00:54:34,550 --> 00:54:37,820 >> JOSEPH: So the question is would you get an error if you have a break after 1065 00:54:37,820 --> 00:54:39,730 case one but there's nothing to do? 1066 00:54:39,730 --> 00:54:41,520 And the answer is no. 1067 00:54:41,520 --> 00:54:43,172 You won't actually get an error. 1068 00:54:43,172 --> 00:54:44,590 Yeah, mm hmm. 1069 00:54:44,590 --> 00:54:54,540 >> So as sort of a little change here, I'm going to put a printf here. 1070 00:54:54,540 --> 00:54:55,790 Whoops. 1071 00:54:55,790 --> 00:55:00,994 1072 00:55:00,994 --> 00:55:04,880 So what would this print if I put one in as input? 1073 00:55:04,880 --> 00:55:07,530 1074 00:55:07,530 --> 00:55:07,770 Yeah. 1075 00:55:07,770 --> 00:55:10,360 It would tell you it didn't take a high number twice, right? 1076 00:55:10,360 --> 00:55:13,500 Because it would hit that first case, it wouldn't break, and it would fall 1077 00:55:13,500 --> 00:55:15,730 through to the second case. 1078 00:55:15,730 --> 00:55:16,950 Any questions about that? 1079 00:55:16,950 --> 00:55:18,280 >> ROB: Did you have another question? 1080 00:55:18,280 --> 00:55:20,840 >> JOSEPH: OK, cool. 1081 00:55:20,840 --> 00:55:22,400 All right. 1082 00:55:22,400 --> 00:55:25,780 So there is something else we call a ternary operator which is basically an 1083 00:55:25,780 --> 00:55:29,010 alternate syntax to doing If and then Else. 1084 00:55:29,010 --> 00:55:30,470 And it lets you do it all on one line. 1085 00:55:30,470 --> 00:55:34,110 So in this particular program, I'm asking the user for n. 1086 00:55:34,110 --> 00:55:37,190 And if n is greater than 100, I tell them they picked a high number. 1087 00:55:37,190 --> 00:55:39,560 Else I tell them they picked a low number. 1088 00:55:39,560 --> 00:55:43,030 >> So we can use this really long syntax, string, S, and then check if n is 1089 00:55:43,030 --> 00:55:45,260 greater than 100 and assign it accordingly. 1090 00:55:45,260 --> 00:55:49,450 But we can make this much more concise by using this ternary operator syntax 1091 00:55:49,450 --> 00:55:52,090 which involves a question mark and a colon. 1092 00:55:52,090 --> 00:55:55,070 So the question mark is essentially asking a question, right? 1093 00:55:55,070 --> 00:55:56,625 >> ROB: Maybe zoom in on that. 1094 00:55:56,625 --> 00:55:57,372 >> JOSEPH: Yes. 1095 00:55:57,372 --> 00:56:00,210 Good point. 1096 00:56:00,210 --> 00:56:02,550 So this is the ternary operator. 1097 00:56:02,550 --> 00:56:06,100 I first ask the question, is n greater than 100? 1098 00:56:06,100 --> 00:56:09,770 If it is, then I execute the first part before the colon. 1099 00:56:09,770 --> 00:56:13,360 If it's not, then I execute the second part after the colon. 1100 00:56:13,360 --> 00:56:16,640 So if n is greater than 100, then it picks high and puts 1101 00:56:16,640 --> 00:56:18,360 that into string s. 1102 00:56:18,360 --> 00:56:22,170 If n is less than 100, it picks low and then puts that into string s. 1103 00:56:22,170 --> 00:56:30,186 So that will condense this big chunk down into just that one line. 1104 00:56:30,186 --> 00:56:32,010 >> SPEAKER 5: Is that popular? 1105 00:56:32,010 --> 00:56:36,070 >> JOSEPH: Yes, it is quite popular for things where essentially you want to 1106 00:56:36,070 --> 00:56:38,700 do an assignment based on some sort of condition. 1107 00:56:38,700 --> 00:56:43,110 And in this case, we were trying to assign a value to string s. 1108 00:56:43,110 --> 00:56:44,840 It's not so-- 1109 00:56:44,840 --> 00:56:47,670 I guess I don't really prefer it in other cases. 1110 00:56:47,670 --> 00:56:49,390 But it's especially useful for this assignment. 1111 00:56:49,390 --> 00:56:54,490 >> ROB: That is a pretty common pattern where you have some variable that 1112 00:56:54,490 --> 00:56:58,200 you're going to say, if something, set this variable to one value; else, set 1113 00:56:58,200 --> 00:56:59,810 this variable to another value. 1114 00:56:59,810 --> 00:57:03,360 And that is the scenario where use a ternary. 1115 00:57:03,360 --> 00:57:05,220 >> JOSEPH: And you're saving lots of lines, right? 1116 00:57:05,220 --> 00:57:08,090 And it just makes your code arguably a little bit more readable. 1117 00:57:08,090 --> 00:57:08,635 Yes, question? 1118 00:57:08,635 --> 00:57:12,384 >> SPEAKER 6: For a ternary, could you go, string s equals s, question mark? 1119 00:57:12,384 --> 00:57:15,280 And then you could have, say, five different options. 1120 00:57:15,280 --> 00:57:18,310 And depending on what the number of n was, would you choose one of those? 1121 00:57:18,310 --> 00:57:22,210 >> JOSEPH: So the question is, is there a sort of syntax where you can do string 1122 00:57:22,210 --> 00:57:25,910 s equals n, and then have more than two options after that question mark? 1123 00:57:25,910 --> 00:57:29,740 And a simple answer is no, there's not really a good way to do that unless 1124 00:57:29,740 --> 00:57:33,850 you want to nest multiple ternary operators inside of each other. 1125 00:57:33,850 --> 00:57:38,050 >> You could do like n greater than 100, question mark, and then another 1126 00:57:38,050 --> 00:57:41,850 ternary operator, n greater than 50, question mark, and nest it that way. 1127 00:57:41,850 --> 00:57:45,240 But in that scenario, your code's getting kind of unreadable and messy, 1128 00:57:45,240 --> 00:57:47,920 and it might be better to just go to an If/Else statement at that point. 1129 00:57:47,920 --> 00:57:54,530 >> ROB: And also, as a side note, PHP incorrectly implements the ternary 1130 00:57:54,530 --> 00:57:58,053 operator such that nested ternaries don't even work as they should. 1131 00:57:58,053 --> 00:57:58,840 >> JOSEPH: Yeah. 1132 00:57:58,840 --> 00:58:01,170 So it gets a little bit confusing, especially when you go 1133 00:58:01,170 --> 00:58:02,145 to different languages. 1134 00:58:02,145 --> 00:58:04,810 >> ROB: It's confusing enough that languages are wrong about it. 1135 00:58:04,810 --> 00:58:08,030 1136 00:58:08,030 --> 00:58:11,510 >> JOSEPH: So actually, just to clarify, does everyone know what that 1137 00:58:11,510 --> 00:58:13,900 %s does over here? 1138 00:58:13,900 --> 00:58:15,650 Any questions about that? 1139 00:58:15,650 --> 00:58:19,760 I guess just for the camera, the %s basically lets us put a placeholder 1140 00:58:19,760 --> 00:58:20,790 for a string. 1141 00:58:20,790 --> 00:58:23,920 And then at the end, we specify that the variable we want to put into this 1142 00:58:23,920 --> 00:58:25,500 place holder is s. 1143 00:58:25,500 --> 00:58:27,730 So that basically takes s and it puts it in here. 1144 00:58:27,730 --> 00:58:32,130 And then it will print out, you picked a high or you picked a low number. 1145 00:58:32,130 --> 00:58:33,770 OK. 1146 00:58:33,770 --> 00:58:36,970 >> So loops allow you to perform things in circular motions, right? 1147 00:58:36,970 --> 00:58:40,300 You might have encountered this in Scratch in the form of Forever loops 1148 00:58:40,300 --> 00:58:45,650 or Repeat Until or Repeat a particular number of times. 1149 00:58:45,650 --> 00:58:47,540 So why is this good for us? 1150 00:58:47,540 --> 00:58:51,500 Well, in C, let's say we have this song implemented in Scratch that 1151 00:58:51,500 --> 00:58:53,450 sings, this is the song that never ends. 1152 00:58:53,450 --> 00:58:55,710 It just goes on and on and on forever and forever. 1153 00:58:55,710 --> 00:58:59,395 Well, you can't really make a program that has an infinite number of printf 1154 00:58:59,395 --> 00:59:00,850 statements in it, right? 1155 00:59:00,850 --> 00:59:04,900 >> So in this particular scenario, one way that you could make this work and 1156 00:59:04,900 --> 00:59:09,330 to make it print forever is to instead use a While loop. 1157 00:59:09,330 --> 00:59:13,640 So a While loop will execute what's in the body of the two braces that 1158 00:59:13,640 --> 00:59:17,250 belongs to it based on what the condition is. 1159 00:59:17,250 --> 00:59:21,170 So in this particular example before, if we want to print this forever, what 1160 00:59:21,170 --> 00:59:23,590 might we do? 1161 00:59:23,590 --> 00:59:25,190 Well, sure, right? 1162 00:59:25,190 --> 00:59:32,290 >> So this sort of combines the idea of some Boolean expression 1163 00:59:32,290 --> 00:59:33,610 along with a loop. 1164 00:59:33,610 --> 00:59:35,780 And we learned about Boolean expressions earlier. 1165 00:59:35,780 --> 00:59:39,650 So whenever the condition inside of that While remains true, this loop 1166 00:59:39,650 --> 00:59:41,480 will execute on and on and on. 1167 00:59:41,480 --> 00:59:44,640 And in this case, if we just supply it with true, this causes an infinite 1168 00:59:44,640 --> 00:59:49,310 loop which prints the song on and on and on as we desired before without 1169 00:59:49,310 --> 00:59:52,410 having a program that has an infinite number of printf statements, which is 1170 00:59:52,410 --> 00:59:55,220 not possible. 1171 00:59:55,220 --> 00:59:57,810 >> So more compellingly, though, you can use this with a 1172 00:59:57,810 --> 00:59:59,710 variable and a condition. 1173 00:59:59,710 --> 01:00:04,420 So let's say we want to repeat the phrase, totally loopy, 10 times. 1174 01:00:04,420 --> 01:00:08,380 So what you can do with a While loop is you can first initialize a counter 1175 01:00:08,380 --> 01:00:10,860 variable outside of the While loop to 10. 1176 01:00:10,860 --> 01:00:14,360 And then basically, each time you go through the While loop, you print out 1177 01:00:14,360 --> 01:00:19,090 the statement and then you decrease the counter variable until at the end, 1178 01:00:19,090 --> 01:00:23,020 at some point, once we subtract I enough times, 1 from I enough times-- 1179 01:00:23,020 --> 01:00:27,290 and just to clarify, I minus minus means I equals I minus 1. 1180 01:00:27,290 --> 01:00:31,280 >> That will basically bring I down to the point where once I hit zero, this 1181 01:00:31,280 --> 01:00:35,260 condition is no longer true and so it exits out of the loop. 1182 01:00:35,260 --> 01:00:37,045 So totally loopy only prints 10 times. 1183 01:00:37,045 --> 01:00:39,550 1184 01:00:39,550 --> 01:00:41,080 Any questions about a While loop? 1185 01:00:41,080 --> 01:00:44,580 1186 01:00:44,580 --> 01:00:46,790 OK. 1187 01:00:46,790 --> 01:00:50,550 >> So there is a way we can do what we just did in a more concise manner with 1188 01:00:50,550 --> 01:00:51,715 what we call a For loop. 1189 01:00:51,715 --> 01:00:55,750 So a For loop consists of an initialization, a condition, and an 1190 01:00:55,750 --> 01:00:58,950 update, just like we had before in this While loop. 1191 01:00:58,950 --> 01:00:59,890 So let's take a look. 1192 01:00:59,890 --> 01:01:02,900 In this While loop, we had an initialization, then we had a 1193 01:01:02,900 --> 01:01:04,260 condition that we checked. 1194 01:01:04,260 --> 01:01:06,450 And then we had an update step at the top. 1195 01:01:06,450 --> 01:01:10,060 >> With a For loop, this basically takes these three things and condenses it 1196 01:01:10,060 --> 01:01:11,370 down into one line. 1197 01:01:11,370 --> 01:01:15,130 So the first thing that it does in the For loop is the initialization. 1198 01:01:15,130 --> 01:01:19,090 And then you do a semicolon, and then you do the condition, which is I 1199 01:01:19,090 --> 01:01:22,200 greater than zero goes over there, and then the update step. 1200 01:01:22,200 --> 01:01:26,470 So this gets performed at the very end of the loop body. 1201 01:01:26,470 --> 01:01:28,790 So these two programs are essentially equivalent. 1202 01:01:28,790 --> 01:01:31,960 1203 01:01:31,960 --> 01:01:33,870 >> Any questions? 1204 01:01:33,870 --> 01:01:37,000 So what is one difference between these two? 1205 01:01:37,000 --> 01:01:38,000 Can anyone point it out? 1206 01:01:38,000 --> 01:01:40,480 It might be a bit subtle. 1207 01:01:40,480 --> 01:01:41,930 It's just a very small difference. 1208 01:01:41,930 --> 01:01:42,330 Yes? 1209 01:01:42,330 --> 01:01:49,008 >> SPEAKER 5: You wouldn't be able to use the I variable outside of the For loop 1210 01:01:49,008 --> 01:01:49,962 [INAUDIBLE]? 1211 01:01:49,962 --> 01:01:50,900 >> JOSEPH: Exactly. 1212 01:01:50,900 --> 01:01:53,550 So this is something we'll get to later called variable scope. 1213 01:01:53,550 --> 01:01:56,610 But essentially, this int I lives outside of this While loop. 1214 01:01:56,610 --> 01:01:59,800 So once this While loop is done executing, I'll be able to use I later 1215 01:01:59,800 --> 01:02:00,880 on in the program. 1216 01:02:00,880 --> 01:02:05,430 >> Whereas with this For loop, this int I is scoped inside of this For loop. 1217 01:02:05,430 --> 01:02:10,240 And because it is inside of this portion of the For loop, that starts 1218 01:02:10,240 --> 01:02:13,200 at the parentheses and ends with the curly brace over there. 1219 01:02:13,200 --> 01:02:16,120 Anything that's declared inside of here cannot be used outside. 1220 01:02:16,120 --> 01:02:20,420 So if I try to use I outside, it'll tell me, undeclared symbol. 1221 01:02:20,420 --> 01:02:22,420 And essentially, I wouldn't be able to use it. 1222 01:02:22,420 --> 01:02:28,460 >> ROB: And well, 10 years ago, in literally all cases, curly braces are 1223 01:02:28,460 --> 01:02:31,140 what you used to determine the scope of a variable. 1224 01:02:31,140 --> 01:02:37,240 So in there, int I equals 10 is declared inside of this 1225 01:02:37,240 --> 01:02:38,520 set of curly braces. 1226 01:02:38,520 --> 01:02:42,530 And so then as long as you try to use I before this curly brace, it's fine. 1227 01:02:42,530 --> 01:02:47,090 1228 01:02:47,090 --> 01:02:51,460 You might see when you type make, you see dash, dash, std, equals, c99. 1229 01:02:51,460 --> 01:02:57,100 >> So that is a later version of C that GCC has implemented that also gives 1230 01:02:57,100 --> 01:02:58,740 this shortcut. 1231 01:02:58,740 --> 01:03:03,505 So this used to not be allowed in C. And you can see why, because this int 1232 01:03:03,505 --> 01:03:07,600 I is outside of this curly brace but it's still considered to be in the 1233 01:03:07,600 --> 01:03:09,750 scope of these curly braces. 1234 01:03:09,750 --> 01:03:14,120 But this is a very convenient thing, and so it is a good extension. 1235 01:03:14,120 --> 01:03:15,370 >> JOSEPH: Any questions? 1236 01:03:15,370 --> 01:03:17,550 1237 01:03:17,550 --> 01:03:19,260 OK. 1238 01:03:19,260 --> 01:03:22,820 So what's more useful is that sometimes you want sort of dynamism in 1239 01:03:22,820 --> 01:03:23,410 your loop, right? 1240 01:03:23,410 --> 01:03:26,350 You don't want to just necessarily print totally loopy all the time, you 1241 01:03:26,350 --> 01:03:28,650 want to count down from 10 or something. 1242 01:03:28,650 --> 01:03:32,010 And so you can use the counter variable inside of that loop as well. 1243 01:03:32,010 --> 01:03:35,530 And in this case, this program just counts down from 10 all the way down. 1244 01:03:35,530 --> 01:03:39,260 And what does it not print? 1245 01:03:39,260 --> 01:03:42,790 It doesn't print zero, right, because when-- 1246 01:03:42,790 --> 01:03:45,460 Yes, it also does not print 11. 1247 01:03:45,460 --> 01:03:49,200 >> So it does not print zero, because when I is zero, remember, it evaluates 1248 01:03:49,200 --> 01:03:52,170 the condition before it goes on to execute the loop body. 1249 01:03:52,170 --> 01:03:56,820 And when I is zero, this is false, so it does not print out counting down 1250 01:03:56,820 --> 01:04:00,200 zero, it just prints out counting down 10 all the way down to 1. 1251 01:04:00,200 --> 01:04:03,420 If we actually wanted it to print zero, then we would put an equal sign 1252 01:04:03,420 --> 01:04:04,750 after this greater than sign. 1253 01:04:04,750 --> 01:04:09,400 1254 01:04:09,400 --> 01:04:10,130 OK. 1255 01:04:10,130 --> 01:04:16,410 >> So one way to do input validation, which is when you ask the user to do 1256 01:04:16,410 --> 01:04:18,620 something, you want to make sure they follow your instructions, is to use 1257 01:04:18,620 --> 01:04:19,400 the While loop, right? 1258 01:04:19,400 --> 01:04:22,990 So in this particular case, I'm asking for a positive number and then I'm 1259 01:04:22,990 --> 01:04:23,810 waiting for input. 1260 01:04:23,810 --> 01:04:28,210 >> And then I checked While the input is less than zero, keep asking them. 1261 01:04:28,210 --> 01:04:32,100 So as long as they give me a number that is not positive, keep asking, 1262 01:04:32,100 --> 01:04:33,600 keep asking, keep asking. 1263 01:04:33,600 --> 01:04:35,860 But what is sort of weird about this? 1264 01:04:35,860 --> 01:04:38,570 Or what doesn't seem optimal about this structure right here? 1265 01:04:38,570 --> 01:04:44,282 1266 01:04:44,282 --> 01:04:44,758 Anyone? 1267 01:04:44,758 --> 01:04:45,234 Yes? 1268 01:04:45,234 --> 01:04:47,614 >> SPEAKER 6: You're repeating the instruction twice. 1269 01:04:47,614 --> 01:04:48,100 >> JOSEPH: Right. 1270 01:04:48,100 --> 01:04:50,090 So we have two printf statements here, right? 1271 01:04:50,090 --> 01:04:53,440 So there is a way we could get this just down to one that would make our 1272 01:04:53,440 --> 01:04:57,170 code easier to read and a little bit more clean. 1273 01:04:57,170 --> 01:05:00,180 And then we wouldn't have to have Get in twice as well. 1274 01:05:00,180 --> 01:05:03,740 And one way you can do this is by using a Do-While loop. 1275 01:05:03,740 --> 01:05:07,670 >> And a Do-While loop is basically a different form of a While loop where 1276 01:05:07,670 --> 01:05:11,460 whatever is within the curly braces gets executed at least once. 1277 01:05:11,460 --> 01:05:14,840 So in here, I declare, int input, outside first. 1278 01:05:14,840 --> 01:05:18,100 And then I just say, do this instruction while input 1279 01:05:18,100 --> 01:05:19,140 is less than zero. 1280 01:05:19,140 --> 01:05:20,530 So it hits the Do first. 1281 01:05:20,530 --> 01:05:24,190 It will always execute this at least once, so it will always ask the user 1282 01:05:24,190 --> 01:05:25,960 for input at least once. 1283 01:05:25,960 --> 01:05:29,390 And then it evaluates that input, and it goes on in a circle. 1284 01:05:29,390 --> 01:05:30,135 Yes, question? 1285 01:05:30,135 --> 01:05:32,602 >> SPEAKER 6: Is there a way to do it [INAUDIBLE] types, like if you say, 1286 01:05:32,602 --> 01:05:34,268 GetString, and somebody [INAUDIBLE] 1287 01:05:34,268 --> 01:05:35,220 is there a way to [INAUDIBLE] 1288 01:05:35,220 --> 01:05:40,060 >> JOSEPH: So the question is, is there a way to do input validation if the user 1289 01:05:40,060 --> 01:05:41,850 does not put in the right type of variable? 1290 01:05:41,850 --> 01:05:44,460 So if we ask for an int and they give us a string instead. 1291 01:05:44,460 --> 01:05:49,110 And in the functions that we implement for you, GetInt, GetString in all of 1292 01:05:49,110 --> 01:05:52,680 those functions, they actually already do that sort of basic type input 1293 01:05:52,680 --> 01:05:54,120 validation under the hood. 1294 01:05:54,120 --> 01:05:57,390 So if you're using the functions that we gave you, you don't really have to. 1295 01:05:57,390 --> 01:06:01,380 >> But if you want to look more into how you can actually do that, you can look 1296 01:06:01,380 --> 01:06:03,360 under the hood at the file I/O-- 1297 01:06:03,360 --> 01:06:07,990 not file, the standard I/O functions like a reading from standard input and 1298 01:06:07,990 --> 01:06:08,580 standard output. 1299 01:06:08,580 --> 01:06:10,630 And you can get a better sense of how you might do that. 1300 01:06:10,630 --> 01:06:13,670 >> ROB: One issue, though, is specifically with the example you 1301 01:06:13,670 --> 01:06:17,070 said, you expect a string and I enter an int. 1302 01:06:17,070 --> 01:06:20,110 How would you tell the difference between intentionally wanting the 1303 01:06:20,110 --> 01:06:23,130 string 123 versus wanting the int 123? 1304 01:06:23,130 --> 01:06:29,230 So string, it's pretty much there's no validation, it's just whatever they 1305 01:06:29,230 --> 01:06:31,600 entered you will interpret as a string. 1306 01:06:31,600 --> 01:06:35,790 >> Int is easier, because no matter the input you take from the user, you are 1307 01:06:35,790 --> 01:06:37,470 always taking a string. 1308 01:06:37,470 --> 01:06:40,650 And so that string you can then check, are all of these 1309 01:06:40,650 --> 01:06:44,218 actually numeric digits? 1310 01:06:44,218 --> 01:06:45,170 >> JOSEPH: OK. 1311 01:06:45,170 --> 01:06:46,420 Any questions about a Do-While loop? 1312 01:06:46,420 --> 01:06:49,170 >> ROB: Oh, and this is also-- 1313 01:06:49,170 --> 01:06:55,130 going back to scope, a somewhat common mistake is trying to use some local 1314 01:06:55,130 --> 01:06:59,540 variable from within this Do-While loop inside of this condition. 1315 01:06:59,540 --> 01:07:02,850 And actually, if we just got rid of this and said, int input equals 1316 01:07:02,850 --> 01:07:06,990 GetInt, then the compiler will yell at us, because input does not exist 1317 01:07:06,990 --> 01:07:08,900 outside of the scope of these curly braces. 1318 01:07:08,900 --> 01:07:10,792 >> JOSEPH: And that's why we need this lineup here. 1319 01:07:10,792 --> 01:07:13,620 1320 01:07:13,620 --> 01:07:14,630 OK. 1321 01:07:14,630 --> 01:07:17,530 So you can also break out of a loop early if you want to. 1322 01:07:17,530 --> 01:07:21,240 So this is a different way of implementing what we just implemented. 1323 01:07:21,240 --> 01:07:24,340 And instead of using the condition within the parentheses, we're using an 1324 01:07:24,340 --> 01:07:26,920 If statement inside of the body of the Do-While loop. 1325 01:07:26,920 --> 01:07:30,000 >> And basically, when the input is finally greater than zero, we will 1326 01:07:30,000 --> 01:07:31,000 break out of the loop. 1327 01:07:31,000 --> 01:07:33,420 And so we will go all the way down here. 1328 01:07:33,420 --> 01:07:37,920 And you can see that this would probably be preferred in this 1329 01:07:37,920 --> 01:07:39,870 scenario, because it's a little bit cleaner and a little 1330 01:07:39,870 --> 01:07:41,380 bit easier to read. 1331 01:07:41,380 --> 01:07:45,210 Whereas this, you sort of have extra lines in it. 1332 01:07:45,210 --> 01:07:47,890 It's just a little bit uglier, I guess, in a sense. 1333 01:07:47,890 --> 01:07:48,530 Yes, question? 1334 01:07:48,530 --> 01:07:52,178 >> SPEAKER 4: Will break only get you out of one set of braces? 1335 01:07:52,178 --> 01:07:53,080 >> JOSEPH: Right. 1336 01:07:53,080 --> 01:07:58,100 So the question is will break only get you out of one loop? 1337 01:07:58,100 --> 01:07:59,280 And the answer is yes. 1338 01:07:59,280 --> 01:08:04,290 So if you have nested For loops, for example, if I have For int I equals 0 1339 01:08:04,290 --> 01:08:09,040 until 10 and then For int J equals 0 until 10, if I break out of the inner 1340 01:08:09,040 --> 01:08:12,310 loop, I will still go to the outer loop. 1341 01:08:12,310 --> 01:08:15,760 So it'll keep performing the operations on the outside. 1342 01:08:15,760 --> 01:08:17,640 Any questions about that? 1343 01:08:17,640 --> 01:08:18,000 Yes? 1344 01:08:18,000 --> 01:08:21,760 >> SPEAKER 5: But break only functions for curly braces, not for other 1345 01:08:21,760 --> 01:08:22,230 statements? 1346 01:08:22,230 --> 01:08:22,700 [INAUDIBLE] 1347 01:08:22,700 --> 01:08:27,620 >> JOSEPH: So the question is will break only function for loops as opposed to 1348 01:08:27,620 --> 01:08:29,014 other statements like If? 1349 01:08:29,014 --> 01:08:32,950 And yes, that is the case, because you're breaking out of a loop, right, 1350 01:08:32,950 --> 01:08:33,630 in a sense. 1351 01:08:33,630 --> 01:08:37,215 >> ROB: In the vast majority of cases, it's this is the sort of If something, 1352 01:08:37,215 --> 01:08:37,660 then break. 1353 01:08:37,660 --> 01:08:41,580 So you don't have to break to apply to the If that is wrapping around it. 1354 01:08:41,580 --> 01:08:45,250 And also, this isn't much of a loop, but remember that switches are also 1355 01:08:45,250 --> 01:08:46,340 broken out of by breaks. 1356 01:08:46,340 --> 01:08:48,390 We saw breaks being used with switches before. 1357 01:08:48,390 --> 01:08:52,189 >> JOSEPH: And you can also use them in While loops and For loops. 1358 01:08:52,189 --> 01:08:54,560 Any questions? 1359 01:08:54,560 --> 01:08:55,830 OK. 1360 01:08:55,830 --> 01:08:57,779 So next up is functions. 1361 01:08:57,779 --> 01:09:01,500 So you might have used one of these BYOB blocks in your Scratch project. 1362 01:09:01,500 --> 01:09:04,569 And this basically allows you to define a set of 1363 01:09:04,569 --> 01:09:05,680 instructions to be followed. 1364 01:09:05,680 --> 01:09:09,569 >> And what I mean by that is let's think back to math, right, algebra. 1365 01:09:09,569 --> 01:09:13,370 You have what we call a function of x, some variable, and let's say this 1366 01:09:13,370 --> 01:09:16,080 function is f of x equals x plus 5. 1367 01:09:16,080 --> 01:09:20,410 So you can think of f of x as this black box that takes 15 in and then 1368 01:09:20,410 --> 01:09:22,590 produces 20. 1369 01:09:22,590 --> 01:09:26,630 >> So more generally, a function is something that takes some inputs and 1370 01:09:26,630 --> 01:09:27,880 then produces some outputs. 1371 01:09:27,880 --> 01:09:31,920 1372 01:09:31,920 --> 01:09:32,960 And why are functions good? 1373 01:09:32,960 --> 01:09:35,189 They're good for a number of reasons. 1374 01:09:35,189 --> 01:09:40,470 So does someone want to take a stab at what organization means? 1375 01:09:40,470 --> 01:09:42,630 In terms of why functions are helpful? 1376 01:09:42,630 --> 01:09:43,090 Yes? 1377 01:09:43,090 --> 01:09:44,735 >> SPEAKER 4: It makes your code more readable. 1378 01:09:44,735 --> 01:09:45,399 >> JOSEPH: Right. 1379 01:09:45,399 --> 01:09:47,670 So one of the things is it makes your code more readable, right? 1380 01:09:47,670 --> 01:09:53,710 Instead of having like int x equals x times x times x, I can have cube of x, 1381 01:09:53,710 --> 01:09:57,190 which is more readable and more understandable to a reader. 1382 01:09:57,190 --> 01:10:01,150 >> Organization is also in terms of splitting up your code into manageable 1383 01:10:01,150 --> 01:10:05,610 portions, so that instead of trying to implement this all in one long section 1384 01:10:05,610 --> 01:10:09,070 in main, you can sort of split it up into like, OK, let's write a function 1385 01:10:09,070 --> 01:10:11,910 to cube something, let's write a function to square something. 1386 01:10:11,910 --> 01:10:15,950 That way you can split it up into tiny, little parts that you can tackle 1387 01:10:15,950 --> 01:10:18,944 as opposed to trying to tackle a big problem all at once. 1388 01:10:18,944 --> 01:10:21,806 >> ROB: Or even tiny, little parts that you and a partner can tackle. 1389 01:10:21,806 --> 01:10:22,283 >> JOSEPH: Yeah. 1390 01:10:22,283 --> 01:10:23,855 >> ROB: So instead of both of you trying to implant one 1391 01:10:23,855 --> 01:10:27,170 function at the same time. 1392 01:10:27,170 --> 01:10:28,800 >> JOSEPH: Simplification. 1393 01:10:28,800 --> 01:10:30,050 Anyone want to take a guess? 1394 01:10:30,050 --> 01:10:33,080 1395 01:10:33,080 --> 01:10:33,410 Yes? 1396 01:10:33,410 --> 01:10:34,675 >> SPEAKER 5: More repetition. 1397 01:10:34,675 --> 01:10:35,260 >> JOSEPH: Right. 1398 01:10:35,260 --> 01:10:39,210 So one thing that you can do with simplification is that it's sort of on 1399 01:10:39,210 --> 01:10:42,520 the same lines as re-usability is that once I write a cube function, I can 1400 01:10:42,520 --> 01:10:45,410 just use that over and over and over again in my program instead of typing 1401 01:10:45,410 --> 01:10:49,610 x times x times x over and over and over again. 1402 01:10:49,610 --> 01:10:52,980 And simplification here also just means it makes your code sort of 1403 01:10:52,980 --> 01:10:55,900 easier to debug once you split this up into functions. 1404 01:10:55,900 --> 01:10:58,250 Because then you can localize where your problems sort of are. 1405 01:10:58,250 --> 01:11:00,910 1406 01:11:00,910 --> 01:11:02,160 Any questions? 1407 01:11:02,160 --> 01:11:04,200 1408 01:11:04,200 --> 01:11:06,540 >> So another idea is abstraction, right? 1409 01:11:06,540 --> 01:11:07,390 This black box. 1410 01:11:07,390 --> 01:11:11,360 Like do you know what GetInt does to receive input from the user? 1411 01:11:11,360 --> 01:11:12,510 We haven't really told you, right? 1412 01:11:12,510 --> 01:11:15,670 All we've told you is GetInt does exactly what it says it does. 1413 01:11:15,670 --> 01:11:18,440 So even if we don't tell you how it works, you still know. 1414 01:11:18,440 --> 01:11:21,670 >> So in this particular case, this is a quadruple function which does 1415 01:11:21,670 --> 01:11:24,520 different things to an input to produce an output. 1416 01:11:24,520 --> 01:11:28,050 And you can quadruple a number by multiplying it by four. 1417 01:11:28,050 --> 01:11:30,790 Or you can what we call bit shift it by two. 1418 01:11:30,790 --> 01:11:32,960 And we'll cover this a little bit later. 1419 01:11:32,960 --> 01:11:36,570 And there's no need to know how this function actually works as long as it 1420 01:11:36,570 --> 01:11:37,640 works as stated. 1421 01:11:37,640 --> 01:11:40,740 >> So under the hood, I could be like, return input times 1422 01:11:40,740 --> 01:11:41,690 eight divided by two. 1423 01:11:41,690 --> 01:11:42,510 And you wouldn't know, right? 1424 01:11:42,510 --> 01:11:44,970 All you need to know is it does what it says. 1425 01:11:44,970 --> 01:11:48,070 So that's the useful thing about abstraction. 1426 01:11:48,070 --> 01:11:52,910 >> And another thing is sort of this idea of localizing your code to one 1427 01:11:52,910 --> 01:11:54,280 particular section. 1428 01:11:54,280 --> 01:11:57,450 So if you do have a problem, you don't have to go all over your code trying 1429 01:11:57,450 --> 01:11:58,730 to fix where the problem was. 1430 01:11:58,730 --> 01:12:00,990 So in this case, I implemented cube wrong. 1431 01:12:00,990 --> 01:12:02,820 I thought cube was multiplying by three. 1432 01:12:02,820 --> 01:12:05,760 >> So in this case, this is one program that just has multiplying by three 1433 01:12:05,760 --> 01:12:06,750 everywhere. 1434 01:12:06,750 --> 01:12:10,910 And there is another program that has factored cube out into a function. 1435 01:12:10,910 --> 01:12:14,040 And so now if I want to fix my mistake here, I have to fix every single line 1436 01:12:14,040 --> 01:12:15,620 of code in this program. 1437 01:12:15,620 --> 01:12:19,190 Whereas on the other hand, if I use the function, I only need to change 1438 01:12:19,190 --> 01:12:20,650 what was wrong in one place. 1439 01:12:20,650 --> 01:12:25,330 1440 01:12:25,330 --> 01:12:28,730 >> So in computer science, we call inputs and outputs. 1441 01:12:28,730 --> 01:12:31,640 Inputs are called parameters or arguments, and outputs are called 1442 01:12:31,640 --> 01:12:32,950 return values. 1443 01:12:32,950 --> 01:12:39,000 And we will see how this helps us sort of define a function in a second. 1444 01:12:39,000 --> 01:12:41,430 So this is a function definition for cubing. 1445 01:12:41,430 --> 01:12:45,110 So it takes an input, and then it returns that number times 1446 01:12:45,110 --> 01:12:47,020 itself three times. 1447 01:12:47,020 --> 01:12:48,020 So let's break this down. 1448 01:12:48,020 --> 01:12:53,090 >> So we have a function header, which basically consists of three things. 1449 01:12:53,090 --> 01:12:56,050 So we have the parameters, which are, as I said before, the 1450 01:12:56,050 --> 01:12:57,680 inputs into this function. 1451 01:12:57,680 --> 01:12:59,300 And then we give the function a name. 1452 01:12:59,300 --> 01:13:00,740 In this case, it's called cube. 1453 01:13:00,740 --> 01:13:03,860 And then we specify what the type of the return value is. 1454 01:13:03,860 --> 01:13:06,760 >> So in this case, my cube function takes in an integer and it also 1455 01:13:06,760 --> 01:13:07,890 returns an integer. 1456 01:13:07,890 --> 01:13:11,510 So if I pass in two, two is an integer, it returns eight to me, which 1457 01:13:11,510 --> 01:13:13,250 is an integer. 1458 01:13:13,250 --> 01:13:15,420 So return type name parameters. 1459 01:13:15,420 --> 01:13:16,670 Questions about that? 1460 01:13:16,670 --> 01:13:19,440 1461 01:13:19,440 --> 01:13:24,230 >> And then the return value is actually specified at the end by saying return 1462 01:13:24,230 --> 01:13:27,540 and then returning whatever contains the return value. 1463 01:13:27,540 --> 01:13:30,940 So in this case, if we put it all together, a function takes in 1464 01:13:30,940 --> 01:13:35,100 parameters, it's called something, and it returns something that is the type 1465 01:13:35,100 --> 01:13:36,350 that we say it was going to be. 1466 01:13:36,350 --> 01:13:39,830 1467 01:13:39,830 --> 01:13:41,080 Any questions? 1468 01:13:41,080 --> 01:13:43,710 1469 01:13:43,710 --> 01:13:45,080 >> So how do we use a function? 1470 01:13:45,080 --> 01:13:49,230 Well, we write a function and then we use it in our program, right? 1471 01:13:49,230 --> 01:13:51,565 So I called it cube, and then I can use cube. 1472 01:13:51,565 --> 01:13:54,200 >> But what's important to note is that order matters. 1473 01:13:54,200 --> 01:13:58,100 If I have cube below main, it's going to run into cube. 1474 01:13:58,100 --> 01:14:00,360 And at this point, there's nothing called cube in the program, and it's 1475 01:14:00,360 --> 01:14:02,550 just going to be like, I have no idea what cube is. 1476 01:14:02,550 --> 01:14:05,060 >> So it will tell you, implicit declaration of function. 1477 01:14:05,060 --> 01:14:06,690 That's the error that shows up. 1478 01:14:06,690 --> 01:14:10,230 And so in this case, cube is below main, so it's not going 1479 01:14:10,230 --> 01:14:12,006 to know about it. 1480 01:14:12,006 --> 01:14:14,724 >> SPEAKER 5: So main is usually the last function defined? 1481 01:14:14,724 --> 01:14:17,290 >> JOSEPH: So the question is, is main usually the last 1482 01:14:17,290 --> 01:14:18,170 thing that you'd define? 1483 01:14:18,170 --> 01:14:19,730 And no. 1484 01:14:19,730 --> 01:14:22,280 It's because we usually like main to be at the top, right? 1485 01:14:22,280 --> 01:14:24,640 Because that's the first thing you want the programmer opening the 1486 01:14:24,640 --> 01:14:25,640 program to see. 1487 01:14:25,640 --> 01:14:29,950 And so how do we solve this issue of we want main to be at the top, but the 1488 01:14:29,950 --> 01:14:33,750 functions that we want, we want them to be below main yet be able to use 1489 01:14:33,750 --> 01:14:34,930 them inside of main? 1490 01:14:34,930 --> 01:14:36,870 >> Well, we use what we call a function prototype. 1491 01:14:36,870 --> 01:14:40,830 So what a function prototype essentially is is it first takes what 1492 01:14:40,830 --> 01:14:45,060 the signature or the function header of what we want to implement down 1493 01:14:45,060 --> 01:14:47,420 here, and we put it at the top of a program. 1494 01:14:47,420 --> 01:14:51,400 >> So in this case, we say that, well, later on in our program, we're going 1495 01:14:51,400 --> 01:14:55,010 to make a promise to implement this function called int cube, which takes 1496 01:14:55,010 --> 01:14:56,260 an integer input. 1497 01:14:56,260 --> 01:15:00,870 So now, because that is above main, main, it's going to say, oh, well, 1498 01:15:00,870 --> 01:15:03,910 later in the program, that's going to be there so I can refer to it, so I'll 1499 01:15:03,910 --> 01:15:05,230 just let it go through for now. 1500 01:15:05,230 --> 01:15:07,660 >> And then at the bottom, we implement cube. 1501 01:15:07,660 --> 01:15:11,180 And then main will just say, well, it will sort of link 1502 01:15:11,180 --> 01:15:12,250 these two symbols together. 1503 01:15:12,250 --> 01:15:14,320 And we'll cover what that means later on. 1504 01:15:14,320 --> 01:15:17,090 And so it'll know that this is the cube function that it should use. 1505 01:15:17,090 --> 01:15:19,630 1506 01:15:19,630 --> 01:15:23,383 >> ROB: The [INAUDIBLE] about wanting main at the bottom or 1507 01:15:23,383 --> 01:15:24,880 top, I've seen both. 1508 01:15:24,880 --> 01:15:28,630 There are things that just like to put main at the bottom. 1509 01:15:28,630 --> 01:15:32,520 But once a project gets particularly big, usually main is in a 1510 01:15:32,520 --> 01:15:34,290 file all its own. 1511 01:15:34,290 --> 01:15:38,170 And at that point, like the int cube line would-- 1512 01:15:38,170 --> 01:15:42,460 inside of stdio.h are a bunch of lines just like that int 1513 01:15:42,460 --> 01:15:44,010 cube int input line. 1514 01:15:44,010 --> 01:15:50,170 >> And so those prototypes are things you tend to put into header files, at 1515 01:15:50,170 --> 01:15:52,140 which point, it doesn't matter. 1516 01:15:52,140 --> 01:15:54,700 Well, it doesn't matter. 1517 01:15:54,700 --> 01:15:56,070 Those always go at the top. 1518 01:15:56,070 --> 01:15:59,490 And if main isn't a file all its own, you don't have to worry about putting 1519 01:15:59,490 --> 01:16:02,360 individual function prototypes in the file. 1520 01:16:02,360 --> 01:16:05,370 >> JOSEPH: And we'll get to that a little bit later when Rob starts talking 1521 01:16:05,370 --> 01:16:06,380 about compiling. 1522 01:16:06,380 --> 01:16:09,480 And so there's also a difference between parameter and argument. 1523 01:16:09,480 --> 01:16:12,500 And parameter is just what we call these inputs when 1524 01:16:12,500 --> 01:16:13,820 we define the function. 1525 01:16:13,820 --> 01:16:16,950 And we call it an argument when we actually pass it into the function. 1526 01:16:16,950 --> 01:16:19,600 >> So in this case, this is a parameter, as we said before. 1527 01:16:19,600 --> 01:16:24,130 And when we actually use it over there, cube of x, then x itself is 1528 01:16:24,130 --> 01:16:25,910 what we call an argument to the function cube. 1529 01:16:25,910 --> 01:16:28,150 >> ROB: So parameter's arguments are-- 1530 01:16:28,150 --> 01:16:33,270 there is this distinction, very confused interchangeably. 1531 01:16:33,270 --> 01:16:37,090 At this point, to me, it's like one of those words that when I see it out in 1532 01:16:37,090 --> 01:16:41,190 the wild, I can't help but immediately question whether they are using it in 1533 01:16:41,190 --> 01:16:44,120 the correct context, because the difference is subtle enough that just 1534 01:16:44,120 --> 01:16:45,500 everyone tends-- 1535 01:16:45,500 --> 01:16:48,530 I almost always say argument regardless of what I mean. 1536 01:16:48,530 --> 01:16:51,230 1537 01:16:51,230 --> 01:16:54,630 >> JOSEPH: And functions are also useful for what we call side effects. 1538 01:16:54,630 --> 01:16:59,230 So a function can take no inputs, and it can also produce no outputs. 1539 01:16:59,230 --> 01:17:03,280 So in this particular case, I am defining a subroutine that has no 1540 01:17:03,280 --> 01:17:03,970 return value. 1541 01:17:03,970 --> 01:17:07,730 And in order to specify that, we use what we call a void over here. 1542 01:17:07,730 --> 01:17:10,890 And so the side effect of this function is that it just prints stuff 1543 01:17:10,890 --> 01:17:11,920 out to the page. 1544 01:17:11,920 --> 01:17:13,840 It doesn't actually take any inputs, and it doesn't 1545 01:17:13,840 --> 01:17:15,360 actually produce any outputs. 1546 01:17:15,360 --> 01:17:18,230 >> But this could be useful in the sense if you want to, for example, debug 1547 01:17:18,230 --> 01:17:21,530 something in your program, if you want to write a little subroutine that 1548 01:17:21,530 --> 01:17:25,160 prints out, let's say, the contents of memory or something. 1549 01:17:25,160 --> 01:17:29,800 And so these side effects are sometimes useful outside the context 1550 01:17:29,800 --> 01:17:33,010 of just like inputs and outputs. 1551 01:17:33,010 --> 01:17:34,260 Any questions? 1552 01:17:34,260 --> 01:17:37,270 1553 01:17:37,270 --> 01:17:44,240 >> And to end this particular segment, what does this program do? 1554 01:17:44,240 --> 01:17:47,420 I'll give you guys a couple of seconds to read through it. 1555 01:17:47,420 --> 01:17:52,720 1556 01:17:52,720 --> 01:17:56,880 At a very basic level, what we want to say is that it swaps x and y, right? 1557 01:17:56,880 --> 01:18:00,090 >> So how many of you actually think this will swap x and y? 1558 01:18:00,090 --> 01:18:02,160 Raise your hand. 1559 01:18:02,160 --> 01:18:02,760 No one. 1560 01:18:02,760 --> 01:18:03,070 OK. 1561 01:18:03,070 --> 01:18:06,720 Who thinks that it will not swap x and y? 1562 01:18:06,720 --> 01:18:09,120 And the sum of that was not the entire room. 1563 01:18:09,120 --> 01:18:10,440 So some people are not sure. 1564 01:18:10,440 --> 01:18:10,920 OK. 1565 01:18:10,920 --> 01:18:11,630 That's reasonable. 1566 01:18:11,630 --> 01:18:16,450 >> So let's go through what happens when you actually call functions first in 1567 01:18:16,450 --> 01:18:18,320 order to answer this question. 1568 01:18:18,320 --> 01:18:21,430 So this is what memory sort of looks like. 1569 01:18:21,430 --> 01:18:23,860 This is sort of like a simplified model of what memory looks like when 1570 01:18:23,860 --> 01:18:24,800 you run a program. 1571 01:18:24,800 --> 01:18:27,270 So there's something called the stack down here and 1572 01:18:27,270 --> 01:18:28,330 something called the heap. 1573 01:18:28,330 --> 01:18:30,950 And these grow towards the middle of memory. 1574 01:18:30,950 --> 01:18:33,860 >> So in this particular case, when you call a function, it 1575 01:18:33,860 --> 01:18:35,680 gets put on the stack. 1576 01:18:35,680 --> 01:18:38,900 And then whatever is contained in that function stays in what we call that 1577 01:18:38,900 --> 01:18:40,550 function's stack frame. 1578 01:18:40,550 --> 01:18:44,500 And so to get a nice visualization of this, let's-- for example, we had the 1579 01:18:44,500 --> 01:18:45,960 program main earlier. 1580 01:18:45,960 --> 01:18:47,820 And inside of main, we called cube. 1581 01:18:47,820 --> 01:18:50,650 So main would first go on the stack frame, because it's the first function 1582 01:18:50,650 --> 01:18:51,640 that's called. 1583 01:18:51,640 --> 01:18:55,740 >> And then when cube is called inside of main, it gets put on top of main 1584 01:18:55,740 --> 01:18:57,790 inside of memory. 1585 01:18:57,790 --> 01:19:02,090 So what you'll notice here is that cube has its own parameters and its 1586 01:19:02,090 --> 01:19:02,950 own locals. 1587 01:19:02,950 --> 01:19:06,720 So when you actually pass something to a function, the parameters that it 1588 01:19:06,720 --> 01:19:09,910 gets are copies of what was passed in from main. 1589 01:19:09,910 --> 01:19:14,140 >> And to sort of explain this, let's walk through a program. 1590 01:19:14,140 --> 01:19:16,960 So we have the stack; this is just the stack portion. 1591 01:19:16,960 --> 01:19:21,240 And what we do is we first initialize x and y to one and two. 1592 01:19:21,240 --> 01:19:22,400 So we have these little boxes. 1593 01:19:22,400 --> 01:19:25,310 They're sitting in main's stack frame on the stack. 1594 01:19:25,310 --> 01:19:26,580 They contain one and two. 1595 01:19:26,580 --> 01:19:28,820 >> Now we call swap. 1596 01:19:28,820 --> 01:19:33,940 What happens is we pass x and y into swap, and swap creates its own copies 1597 01:19:33,940 --> 01:19:36,520 of those variables to use inside of its stack frame. 1598 01:19:36,520 --> 01:19:39,920 So now over there, we have a, which contains the value that x had; and b, 1599 01:19:39,920 --> 01:19:41,620 which contains the value that y had. 1600 01:19:41,620 --> 01:19:42,670 So one, two. 1601 01:19:42,670 --> 01:19:47,130 >> And you'll notice that this is separate from x and y inside of main. 1602 01:19:47,130 --> 01:19:51,390 So we now create a temporary variable to contain a. 1603 01:19:51,390 --> 01:19:56,100 We set a equal to b, so it changes from one to two. 1604 01:19:56,100 --> 01:19:59,340 And then we set b equal to temp, which is one. 1605 01:19:59,340 --> 01:20:01,640 >> And then now we exit out of this function. 1606 01:20:01,640 --> 01:20:04,310 1607 01:20:04,310 --> 01:20:07,410 When you exit out of the function, the stack frame gets popped off the stack. 1608 01:20:07,410 --> 01:20:08,270 We call it push. 1609 01:20:08,270 --> 01:20:12,750 You push a stack frame onto the stack and you pop if off the stack. 1610 01:20:12,750 --> 01:20:16,080 And so what happens is everything that was in that stack frame sort of just 1611 01:20:16,080 --> 01:20:17,280 goes up in flames. 1612 01:20:17,280 --> 01:20:19,180 And so that no longer exists. 1613 01:20:19,180 --> 01:20:20,470 >> But what do we notice? 1614 01:20:20,470 --> 01:20:23,690 We never actually changed the values of x and y, right? 1615 01:20:23,690 --> 01:20:26,530 So those stayed local to main. 1616 01:20:26,530 --> 01:20:29,900 And by passing things into swap, we actually never changed those values. 1617 01:20:29,900 --> 01:20:31,260 And what do we call this? 1618 01:20:31,260 --> 01:20:33,040 We call this passing by value. 1619 01:20:33,040 --> 01:20:36,860 >> So in C, when you pass things into functions, it passes them by value and 1620 01:20:36,860 --> 01:20:40,160 makes a copy of them for the function to use. 1621 01:20:40,160 --> 01:20:43,980 And we'll learn about something called passing by reference later, but that's 1622 01:20:43,980 --> 01:20:45,390 a way you can solve this problem. 1623 01:20:45,390 --> 01:20:47,080 But we won't worry about that until later. 1624 01:20:47,080 --> 01:20:52,200 >> ROB: And actually, that term, passing by reference, so C doesn't even have 1625 01:20:52,200 --> 01:20:54,270 passing by referencing. 1626 01:20:54,270 --> 01:20:56,760 C exclusively has passing by value. 1627 01:20:56,760 --> 01:20:59,630 No matter what you do, you are always passing a copy of something. 1628 01:20:59,630 --> 01:21:03,395 It's just that, like I sort of mentioned that before with pointers 1629 01:21:03,395 --> 01:21:07,690 and that a string is really just four bytes pointing to someplace in memory. 1630 01:21:07,690 --> 01:21:11,890 >> Well, if I have this string and it's telling me that is where the string-- 1631 01:21:11,890 --> 01:21:15,470 well, if I have this pointer to this place in memory, then I can pass a 1632 01:21:15,470 --> 01:21:19,160 copy of that pointer to a function, and that function still knows where in 1633 01:21:19,160 --> 01:21:19,780 memory it is. 1634 01:21:19,780 --> 01:21:22,950 So both of these pointers are pointing to the same place in memory, and 1635 01:21:22,950 --> 01:21:26,460 that's how we're going to be able to modify things beyond the 1636 01:21:26,460 --> 01:21:29,852 current stack frame. 1637 01:21:29,852 --> 01:21:31,040 >> JOSEPH: Do you want to do compiling? 1638 01:21:31,040 --> 01:21:31,820 >> ROB: No, it's 5:30. 1639 01:21:31,820 --> 01:21:32,910 >> JOSEPH: OK. 1640 01:21:32,910 --> 01:21:35,040 It is 5:30. 1641 01:21:35,040 --> 01:21:35,360 OK. 1642 01:21:35,360 --> 01:21:39,280 So we will cover compiling I guess in the next section, or your section 1643 01:21:39,280 --> 01:21:42,795 leader will at that point. 1644 01:21:42,795 --> 01:21:43,272 And-- 1645 01:21:43,272 --> 01:21:44,630 >> ROB: Any questions? 1646 01:21:44,630 --> 01:21:46,760 >> JOSEPH: Any questions? 1647 01:21:46,760 --> 01:21:47,150 Yes? 1648 01:21:47,150 --> 01:21:52,469 >> SPEAKER 5: Using strings from CS50, any functions that we want to use for 1649 01:21:52,469 --> 01:21:53,880 those, that'll be like C functions. 1650 01:21:53,880 --> 01:21:59,050 CS50 hasn't gone in and made any additional. 1651 01:21:59,050 --> 01:22:01,850 >> ROB: Correct. 1652 01:22:01,850 --> 01:22:08,155 Any of the C like [INAUDIBLE], you would use those on our strings. 1653 01:22:08,155 --> 01:22:12,400 >> JOSEPH: And one last thing I want to mention is that we have a style guide 1654 01:22:12,400 --> 01:22:13,130 for this class. 1655 01:22:13,130 --> 01:22:13,360 >> ROB: Oh, yeah. 1656 01:22:13,360 --> 01:22:15,270 >> JOSEPH: So if you've come from a programming background before, you 1657 01:22:15,270 --> 01:22:17,750 might have certain conventions when you're writing code like putting 1658 01:22:17,750 --> 01:22:20,950 braces on the same line or particular ways of indenting 1659 01:22:20,950 --> 01:22:22,240 or naming your variables. 1660 01:22:22,240 --> 01:22:26,870 In this class, we want to follow a specific style guide just because, 1661 01:22:26,870 --> 01:22:31,100 well, if you go out and work in industry, you're going to be expected 1662 01:22:31,100 --> 01:22:34,780 to follow the style guide of the company at which you go to. 1663 01:22:34,780 --> 01:22:38,040 >> Like for example, Facebook I think has a particular sort of naming 1664 01:22:38,040 --> 01:22:38,760 convention. 1665 01:22:38,760 --> 01:22:42,570 And there's differences between camel casing variables and just like 1666 01:22:42,570 --> 01:22:44,610 separating them with underscores. 1667 01:22:44,610 --> 01:22:52,170 And also, I think most importantly, like for example, indentation, right? 1668 01:22:52,170 --> 01:22:56,440 >> We do curly braces start where the condition is, and they 1669 01:22:56,440 --> 01:22:57,730 are on the next line. 1670 01:22:57,730 --> 01:23:01,230 And we also put curly braces in even if it's only one line. 1671 01:23:01,230 --> 01:23:06,100 And a lot of times, there are ways to do it where you can leave these braces 1672 01:23:06,100 --> 01:23:08,380 off if it's only one line under the If statement. 1673 01:23:08,380 --> 01:23:12,070 But in this class, we want to follow a specific style guide just so you get 1674 01:23:12,070 --> 01:23:13,550 used to that sort of thing. 1675 01:23:13,550 --> 01:23:16,410 >> ROB: Yeah, and Style 50 is going to enforce this style guide, and we're 1676 01:23:16,410 --> 01:23:18,080 going to use Style 50 to grade your code. 1677 01:23:18,080 --> 01:23:25,150 So it makes things easier for us and hopefully shouldn't make things that 1678 01:23:25,150 --> 01:23:30,120 much worse for you given the standardized style shouldn't be that 1679 01:23:30,120 --> 01:23:31,460 unrealistic. 1680 01:23:31,460 --> 01:23:36,000 >> JOSEPH: And finally, to find the style guide, go to manual.cs50.net/style. 1681 01:23:36,000 --> 01:23:37,725 And yeah. 1682 01:23:37,725 --> 01:23:40,575 >> SPEAKER 4: Are you going to enforce any characters per line? 1683 01:23:40,575 --> 01:23:42,480 >> ROB: Yes. 1684 01:23:42,480 --> 01:23:45,405 >> JOSEPH: Sorry, guys. 1685 01:23:45,405 --> 01:23:47,680 >> ROB: That's like one of the only ones. 1686 01:23:47,680 --> 01:23:50,420 At this point, I am OK with 120. 1687 01:23:50,420 --> 01:23:52,460 I'm OK with saying 120 characters per line. 1688 01:23:52,460 --> 01:23:53,830 I understand there being some limit. 1689 01:23:53,830 --> 01:23:57,130 I think 80 is so small, but we're enforcing it. 1690 01:23:57,130 --> 01:24:00,260 >> JOSEPH: Personally, I think with C, 80 characters is more OK. 1691 01:24:00,260 --> 01:24:04,160 Once you start getting to other languages like JavaScript and PHP, not 1692 01:24:04,160 --> 01:24:08,860 so reasonable to just limit it to 80 characters. 1693 01:24:08,860 --> 01:24:09,260 OK. 1694 01:24:09,260 --> 01:24:12,780 Well, that was the super section. 1695 01:24:12,780 --> 01:24:14,750 Does anyone want candy? 1696 01:24:14,750 --> 01:24:16,000 >> SPEAKER 4: Yes. 1697 01:24:16,000 --> 01:24:18,667