1 00:00:00,790 --> 00:00:03,190 The following content is provided under a Creative 2 00:00:03,190 --> 00:00:04,730 Commons license. 3 00:00:04,730 --> 00:00:07,030 Your support will help MIT OpenCourseWare 4 00:00:07,030 --> 00:00:11,390 continue to offer high quality educational resources for free. 5 00:00:11,390 --> 00:00:13,990 To make a donation or view additional materials 6 00:00:13,990 --> 00:00:17,880 from hundreds of MIT courses, visit MIT OpenCourseWare 7 00:00:17,880 --> 00:00:18,840 at ocw.mit.edu. 8 00:00:30,000 --> 00:00:32,790 ANA BELL: All right everyone, let's get started. 9 00:00:32,790 --> 00:00:35,410 So good afternoon. 10 00:00:35,410 --> 00:00:40,230 So this is the 3rd lecture of 6.0001 and 600. 11 00:00:40,230 --> 00:00:42,150 As always, please download slides and code 12 00:00:42,150 --> 00:00:44,010 to follow along. 13 00:00:44,010 --> 00:00:46,540 So a quick recap of what we did last time. 14 00:00:46,540 --> 00:00:51,095 Last time, we talked about strings as a new object type, 15 00:00:51,095 --> 00:00:53,040 as sequences of characters. 16 00:00:53,040 --> 00:00:56,857 And then we introduced two new concepts 17 00:00:56,857 --> 00:00:58,440 that allowed us to write slightly more 18 00:00:58,440 --> 00:00:59,520 complicated programs. 19 00:00:59,520 --> 00:01:03,950 So we introduced branching, with these keywords, if, elif, else. 20 00:01:03,950 --> 00:01:05,700 And branching allowed us to write programs 21 00:01:05,700 --> 00:01:09,600 that, us, as programmers, could introduce decisions 22 00:01:09,600 --> 00:01:11,250 into our programs. 23 00:01:11,250 --> 00:01:13,470 And then we introduced two different kinds of loops, 24 00:01:13,470 --> 00:01:14,632 while loops and for loops. 25 00:01:14,632 --> 00:01:16,590 And those also added a little bit of complexity 26 00:01:16,590 --> 00:01:18,852 to our programs. 27 00:01:18,852 --> 00:01:21,310 Today, we're going to talk a little bit more about strings. 28 00:01:21,310 --> 00:01:23,400 So we're going to see a couple of more operations 29 00:01:23,400 --> 00:01:26,490 that you can do on strings and string objects. 30 00:01:26,490 --> 00:01:28,620 And then we're going to talk about three 31 00:01:28,620 --> 00:01:30,750 different algorithms, a guess and check 32 00:01:30,750 --> 00:01:32,970 algorithm, an approximate solution 33 00:01:32,970 --> 00:01:38,390 algorithm, and a bisection method algorithm. 34 00:01:38,390 --> 00:01:39,710 So let's dive right in. 35 00:01:39,710 --> 00:01:41,720 We'll talk a little bit about strings, first. 36 00:01:41,720 --> 00:01:45,050 So strings, we thought of them as sequences of characters, 37 00:01:45,050 --> 00:01:50,300 case sensitive, as we saw in programs we wrote last lecture. 38 00:01:50,300 --> 00:01:52,730 And strings are objects. 39 00:01:52,730 --> 00:01:56,930 And we can do all of these operations on string objects, 40 00:01:56,930 --> 00:02:00,966 like test if they're equal, less than, greater than, and so on. 41 00:02:00,966 --> 00:02:04,140 It turns out, we can do more than just concatenate two 42 00:02:04,140 --> 00:02:08,190 strings together or do these little tests on them. 43 00:02:08,190 --> 00:02:11,650 So we're going to start introducing the idea 44 00:02:11,650 --> 00:02:13,689 of a function or a procedure. 45 00:02:13,689 --> 00:02:15,480 And we're going to see more about functions 46 00:02:15,480 --> 00:02:18,900 and how you can write your own functions next lecture. 47 00:02:18,900 --> 00:02:22,000 But for today, you can think of a function 48 00:02:22,000 --> 00:02:24,490 as sort of a procedure that does something for you. 49 00:02:24,490 --> 00:02:26,195 Someone already wrote this. 50 00:02:26,195 --> 00:02:27,820 So the first one we're going to look at 51 00:02:27,820 --> 00:02:30,770 is a pretty popular function. 52 00:02:30,770 --> 00:02:35,240 And when applied on a string, this function, called len, 53 00:02:35,240 --> 00:02:36,990 will tell you the length of a string. 54 00:02:36,990 --> 00:02:39,320 So that's going to tell you how many characters 55 00:02:39,320 --> 00:02:42,230 are in the string. 56 00:02:42,230 --> 00:02:44,730 And characters are going to be letters, digits, 57 00:02:44,730 --> 00:02:46,570 special characters, spaces, and so on. 58 00:02:46,570 --> 00:02:49,440 So it's just going to count how many characters 59 00:02:49,440 --> 00:02:50,970 are in a string. 60 00:02:50,970 --> 00:02:53,980 So if I have the string s is equal to "abc"-- 61 00:02:53,980 --> 00:02:57,360 remember a string is in quotation marks-- then, 62 00:02:57,360 --> 00:03:03,480 if I do this, if I write this expression, len s, here, 63 00:03:03,480 --> 00:03:06,070 since it's an expression, it has a value. 64 00:03:06,070 --> 00:03:08,310 So it evaluates to a certain value. 65 00:03:08,310 --> 00:03:10,290 And by definition, it's going to tell me what 66 00:03:10,290 --> 00:03:12,745 the length of the string, which is 3 characters long. 67 00:03:19,810 --> 00:03:21,469 Another thing that we can do on strings 68 00:03:21,469 --> 00:03:23,260 is, since they're a sequence of characters, 69 00:03:23,260 --> 00:03:25,960 I might want to get what character is 70 00:03:25,960 --> 00:03:27,920 at a certain position. 71 00:03:27,920 --> 00:03:33,070 So we do this using this fancy word called indexing. 72 00:03:33,070 --> 00:03:35,680 But pretty much what indexing into a string means 73 00:03:35,680 --> 00:03:38,920 is you're going to tell Python, I 74 00:03:38,920 --> 00:03:42,010 want to know the character, at this certain position 75 00:03:42,010 --> 00:03:45,640 or at this certain index, inside my sting. 76 00:03:45,640 --> 00:03:49,780 So once again, let's use this string, s is equal to "abc." 77 00:03:49,780 --> 00:03:51,730 And let's index into it. 78 00:03:51,730 --> 00:03:56,050 So in computer science, we start from 0, counting by convention. 79 00:03:56,050 --> 00:03:58,540 Notice, we had a problem set 0 in this class. 80 00:03:58,540 --> 00:03:59,540 Python is no different. 81 00:03:59,540 --> 00:04:05,710 So in Python, you start indexing at position 0. 82 00:04:05,710 --> 00:04:08,950 Or you start indexing at 0. 83 00:04:08,950 --> 00:04:13,630 So the first character, in your string, we say is at position 0 84 00:04:13,630 --> 00:04:15,170 or at index 0. 85 00:04:15,170 --> 00:04:17,860 The next character in the string is at index 1. 86 00:04:17,860 --> 00:04:20,079 And the next character in the string is at index 2. 87 00:04:23,370 --> 00:04:25,050 In Python, it turns out, you can also 88 00:04:25,050 --> 00:04:27,710 use negative numbers to index. 89 00:04:27,710 --> 00:04:35,760 And if you index into the string with negative 1, for example, 90 00:04:35,760 --> 00:04:38,280 that means that you want the last character in the string. 91 00:04:38,280 --> 00:04:40,020 So the last character in your string 92 00:04:40,020 --> 00:04:43,106 is always going to be at position negative 1, 93 00:04:43,106 --> 00:04:45,300 the second-to-last character is at negative 2, 94 00:04:45,300 --> 00:04:47,520 third-to-last character is at negative 3, 95 00:04:47,520 --> 00:04:50,034 and so on and so on. 96 00:04:50,034 --> 00:04:51,450 So the way you index into a string 97 00:04:51,450 --> 00:04:54,570 is with these square brackets, here. 98 00:04:54,570 --> 00:04:56,520 And this is the notation. 99 00:04:56,520 --> 00:05:00,570 So if I want the character at position 0 or at index 0, 100 00:05:00,570 --> 00:05:03,979 I say s, which is the string I want to index into. 101 00:05:03,979 --> 00:05:05,520 And then, inside the square brackets, 102 00:05:05,520 --> 00:05:07,910 I say what index I want. 103 00:05:07,910 --> 00:05:12,710 So s at index 0 is going to be the value "a." s at index 1 104 00:05:12,710 --> 00:05:17,200 is going to be the value "b," and so on and so on. 105 00:05:17,200 --> 00:05:21,380 And we can also do negative indexing, as well. 106 00:05:24,330 --> 00:05:25,230 I added this in here. 107 00:05:25,230 --> 00:05:27,360 If you do try to index into a string 108 00:05:27,360 --> 00:05:29,880 beyond the limits of the string-- 109 00:05:29,880 --> 00:05:31,830 and we can even try this out, just 110 00:05:31,830 --> 00:05:35,490 to show you that it's not the end of the world if we do that. 111 00:05:35,490 --> 00:05:41,130 If we have s is equal to "abc," and we have s at position 20, 112 00:05:41,130 --> 00:05:43,660 for example, obviously, my string 113 00:05:43,660 --> 00:05:47,000 is only length 3, so what's at position 20? 114 00:05:47,000 --> 00:05:48,610 I get an error. 115 00:05:48,610 --> 00:05:51,400 I call this angry text, here, in Python. 116 00:05:51,400 --> 00:05:53,440 But really, the most relevant thing to note 117 00:05:53,440 --> 00:05:57,670 is these last couple of lines here. 118 00:05:57,670 --> 00:06:01,370 This tells you what line is problematic. 119 00:06:01,370 --> 00:06:05,440 So s at position 20 has an issue. 120 00:06:05,440 --> 00:06:08,800 And this last line here tells me what actual error I have. 121 00:06:08,800 --> 00:06:10,510 So it's an index error, which means 122 00:06:10,510 --> 00:06:12,700 I'm trying to index too far into the string, 123 00:06:12,700 --> 00:06:14,670 because it only has three characters. 124 00:06:22,230 --> 00:06:25,260 So it's nice to be able to get a single character out 125 00:06:25,260 --> 00:06:26,340 of my string. 126 00:06:26,340 --> 00:06:29,310 But sometimes, I might want to get a substring. 127 00:06:29,310 --> 00:06:32,640 So I want to start at the first character 128 00:06:32,640 --> 00:06:34,500 and go halfway into the string, or I 129 00:06:34,500 --> 00:06:38,232 want to take a few characters in between, 130 00:06:38,232 --> 00:06:40,690 or I want to skip every other letter or something like that 131 00:06:40,690 --> 00:06:42,580 in my string. 132 00:06:42,580 --> 00:06:46,480 So if I want to do this slightly more complicated interaction 133 00:06:46,480 --> 00:06:52,540 with strings, we call that slicing, slicing into a string. 134 00:06:52,540 --> 00:06:56,050 And this notation here should seem a little bit familiar, 135 00:06:56,050 --> 00:06:59,710 because we saw it last lecture when we did it with range. 136 00:06:59,710 --> 00:07:02,844 We had a start, stop, and a step. 137 00:07:02,844 --> 00:07:04,510 The notation was a little bit different, 138 00:07:04,510 --> 00:07:07,210 because, in range, we had open-close parentheses 139 00:07:07,210 --> 00:07:09,370 and commas in between. 140 00:07:09,370 --> 00:07:13,930 But except for that, this sort of works the same. 141 00:07:13,930 --> 00:07:17,620 The start is the index, starting from 0, 142 00:07:17,620 --> 00:07:20,110 from where you want to slice into this string. 143 00:07:20,110 --> 00:07:23,200 The stop is the stop index. 144 00:07:23,200 --> 00:07:25,780 So you're going to go up until stop minus 1 145 00:07:25,780 --> 00:07:27,430 and take that index. 146 00:07:27,430 --> 00:07:32,030 And then the step is how many letters you wish to take. 147 00:07:35,240 --> 00:07:37,400 So this is the full notation here. 148 00:07:37,400 --> 00:07:39,260 But sometimes, you can not give it 149 00:07:39,260 --> 00:07:44,552 a third sort of number in here. 150 00:07:44,552 --> 00:07:46,010 So if you only give it two numbers, 151 00:07:46,010 --> 00:07:49,217 then, to Python, that represents just the start and the stop. 152 00:07:49,217 --> 00:07:50,800 And by default, step is going to be 1. 153 00:07:53,910 --> 00:07:57,500 And there's a lot of other things you can do with strings. 154 00:07:57,500 --> 00:08:00,350 You can omit numbers and just leave colons in Python. 155 00:08:03,160 --> 00:08:07,640 By definition, the way that whoever wrote slicing 156 00:08:07,640 --> 00:08:10,360 had decided, if you omit numbers, 157 00:08:10,360 --> 00:08:14,650 then it's going to be equivalent to these things here. 158 00:08:14,650 --> 00:08:17,490 So we slice using square brackets, just like indexing. 159 00:08:17,490 --> 00:08:21,330 Except now, we can give it two numbers. 160 00:08:21,330 --> 00:08:31,490 So with this string, s, if we slice into the string s, 161 00:08:31,490 --> 00:08:35,990 we start from index 3 and go up until index 6. 162 00:08:35,990 --> 00:08:47,280 So if we have abcdefgh, this is position 0, 1, 2, 3, 4, 5, 6, 163 00:08:47,280 --> 00:08:47,780 7. 164 00:08:50,470 --> 00:08:52,510 And you just count. 165 00:08:52,510 --> 00:08:58,920 So s, starting from 3 and going till 6, is going to start here, 166 00:08:58,920 --> 00:09:00,910 3. 167 00:09:00,910 --> 00:09:04,450 So it's going to come up with-- sorry d. 168 00:09:04,450 --> 00:09:06,640 And then we're going to take e. 169 00:09:06,640 --> 00:09:08,620 And then we're going to take f. 170 00:09:08,620 --> 00:09:10,630 And since we're going until stop minus 1, 171 00:09:10,630 --> 00:09:14,170 we're not going to take g. 172 00:09:14,170 --> 00:09:17,050 Because this is position 6, and we're going until 6 minus 1. 173 00:09:22,020 --> 00:09:26,240 The next one here, 3, 6, 2 is going every other one. 174 00:09:26,240 --> 00:09:29,820 So we start at 3, and then we skip every other one, 175 00:09:29,820 --> 00:09:33,290 so we go d but not e, and then f, and then stop. 176 00:09:37,630 --> 00:09:43,620 If you do s and then nothing inside except colons, 177 00:09:43,620 --> 00:09:45,990 notice that you're going to have s, and then 178 00:09:45,990 --> 00:09:49,470 nothing, and then colon, nothing, colon, nothing. 179 00:09:49,470 --> 00:09:52,440 So nothing for start, nothing for stop, nothing for step. 180 00:09:52,440 --> 00:09:56,310 And that's just going to value it to the string, itself. 181 00:09:56,310 --> 00:10:00,870 It's the same as 0 to the length s going every step. 182 00:10:00,870 --> 00:10:02,970 This one might actually be useful. 183 00:10:02,970 --> 00:10:05,400 It reverses the string automatically for you. 184 00:10:05,400 --> 00:10:07,200 So with this one little line here, 185 00:10:07,200 --> 00:10:10,210 you can get the inverse of your string. 186 00:10:10,210 --> 00:10:11,460 And that's equivalent to that. 187 00:10:14,400 --> 00:10:16,640 So the minus 1 represents starting from the end 188 00:10:16,640 --> 00:10:20,020 and going back every letter. 189 00:10:20,020 --> 00:10:23,140 And then this one's a little bit more complicated but also 190 00:10:23,140 --> 00:10:23,785 not too bad. 191 00:10:30,020 --> 00:10:33,707 So as we're doing these string slices, 192 00:10:33,707 --> 00:10:35,540 again, if you're unsure what something does, 193 00:10:35,540 --> 00:10:37,220 just type it into Spider. 194 00:10:37,220 --> 00:10:38,892 And you might be surprised. 195 00:10:38,892 --> 00:10:39,600 You might not be. 196 00:10:39,600 --> 00:10:41,183 But it's a good way to check yourself, 197 00:10:41,183 --> 00:10:45,640 to make sure you're understanding what's happening. 198 00:10:45,640 --> 00:10:48,310 One thing I want to mention, and it's 199 00:10:48,310 --> 00:10:50,540 good to keep this in the back of your mind. 200 00:10:50,540 --> 00:10:52,180 We're going to come back to this as we 201 00:10:52,180 --> 00:10:56,290 start talking about slightly more complicated object types. 202 00:10:56,290 --> 00:10:58,412 But strings are immutable. 203 00:10:58,412 --> 00:11:00,370 So just keep this word in the back of your mind 204 00:11:00,370 --> 00:11:01,980 as we go through this class. 205 00:11:01,980 --> 00:11:05,560 And what I mean by this is that an actual string object, 206 00:11:05,560 --> 00:11:09,040 once it's created, cannot be modified. 207 00:11:09,040 --> 00:11:11,410 This might not mean anything right now. 208 00:11:11,410 --> 00:11:14,940 But let me just draw a little something. 209 00:11:14,940 --> 00:11:17,574 Let's say I have this string, s is equal to hello. 210 00:11:17,574 --> 00:11:18,990 Remember, in the first lecture, we 211 00:11:18,990 --> 00:11:21,080 drew a diagram sort of like this. 212 00:11:21,080 --> 00:11:22,890 This is my memory. 213 00:11:22,890 --> 00:11:25,990 I have this object "hello." 214 00:11:25,990 --> 00:11:29,360 And this object, "hello" is bound to this variable s. 215 00:11:29,360 --> 00:11:36,340 So now I can access the object "hello" using this variable s. 216 00:11:36,340 --> 00:11:39,490 Now you might think, well, since I could index into a string, 217 00:11:39,490 --> 00:11:43,600 I might be able to just say something like, s at position 0 218 00:11:43,600 --> 00:11:45,490 is equal to y. 219 00:11:45,490 --> 00:11:48,160 And that will just change the little h into a y, 220 00:11:48,160 --> 00:11:49,845 and I'll have a new object. 221 00:11:49,845 --> 00:11:51,970 Well strings are immutable, which means, in Python, 222 00:11:51,970 --> 00:11:53,320 you're not actually allowed to do this. 223 00:11:53,320 --> 00:11:55,444 And it gives you an error if you do try to do that. 224 00:11:58,200 --> 00:12:03,954 If you want the variable s to point to the string, Y-E-L-L-O, 225 00:12:03,954 --> 00:12:08,210 you could just say s is equal to Y-E-L-L-O. 226 00:12:08,210 --> 00:12:10,970 Or you could do string operations like this. 227 00:12:10,970 --> 00:12:13,520 And this takes the y and it concatenates it 228 00:12:13,520 --> 00:12:18,020 to the string s, all of the elements 229 00:12:18,020 --> 00:12:21,434 starting from position 1, which is e, l, l, o. 230 00:12:21,434 --> 00:12:24,570 So this makes Y-E-L-L-O. 231 00:12:24,570 --> 00:12:26,490 Now internally, what happens when 232 00:12:26,490 --> 00:12:28,230 I write this line is Python says, 233 00:12:28,230 --> 00:12:31,330 OK, I'm going to break my bond with this original object 234 00:12:31,330 --> 00:12:32,520 "hello." 235 00:12:32,520 --> 00:12:36,610 I'm going to bind my string variable 236 00:12:36,610 --> 00:12:40,050 s to the new object "yello." and this other, old object 237 00:12:40,050 --> 00:12:42,460 still is in memory somewhere. 238 00:12:42,460 --> 00:12:47,210 But it's an entirely different object that I've created here. 239 00:12:47,210 --> 00:12:49,200 Again, it might not mean anything right now, 240 00:12:49,200 --> 00:12:51,080 but just keep this in the back of your mind, 241 00:12:51,080 --> 00:12:52,590 strings are immutable. 242 00:12:59,450 --> 00:13:01,880 So the next thing I want to talk about 243 00:13:01,880 --> 00:13:06,600 is a little bit of recap on for loops. 244 00:13:06,600 --> 00:13:09,080 And we're going to see how we can apply for loops, very 245 00:13:09,080 --> 00:13:12,620 easily, to write very nice, readable code when 246 00:13:12,620 --> 00:13:14,510 dealing with strings. 247 00:13:14,510 --> 00:13:18,380 So remember that for loops had a loop variable. 248 00:13:18,380 --> 00:13:22,310 My loop variable being this var, here, in this particular case. 249 00:13:22,310 --> 00:13:24,500 It can be anything you want. 250 00:13:24,500 --> 00:13:27,260 And this variable, in this particular case, 251 00:13:27,260 --> 00:13:32,530 iterates over this sequence of numbers, 0, 1, 2, 3, 4. 252 00:13:32,530 --> 00:13:36,670 So the very first time through the loop, var has a value of 0. 253 00:13:36,670 --> 00:13:38,600 It does the expressions in the loop. 254 00:13:38,600 --> 00:13:41,604 As soon as they're done, var takes the value 1. 255 00:13:41,604 --> 00:13:43,270 It does all the expressions in the loop. 256 00:13:43,270 --> 00:13:45,940 And then var takes the value 2, and it does that all 257 00:13:45,940 --> 00:13:48,220 the way up until 0, 1, 2. 258 00:13:48,220 --> 00:13:53,430 And the last time it goes around is with var is equal to 3. 259 00:13:53,430 --> 00:13:55,740 And remember, we said that we can customize our range 260 00:13:55,740 --> 00:13:58,110 in order to start from a custom value 261 00:13:58,110 --> 00:14:01,590 to end at a different value and to skip certain numbers. 262 00:14:04,790 --> 00:14:07,370 So, so far, we've only been using for loops 263 00:14:07,370 --> 00:14:08,620 over a sequence of numbers. 264 00:14:08,620 --> 00:14:11,780 But actually, for loops are a lot more powerful than that. 265 00:14:11,780 --> 00:14:16,970 You can use them to iterate over any sequence of values 266 00:14:16,970 --> 00:14:21,830 not just numbers but also strings. 267 00:14:21,830 --> 00:14:28,540 So here are two pieces of code, this one and this one here. 268 00:14:28,540 --> 00:14:31,095 These two pieces of code both do the exact same thing. 269 00:14:33,620 --> 00:14:37,070 To me, possibly to you, this one looks 270 00:14:37,070 --> 00:14:40,000 a lot more readable than this one, just at a first glance. 271 00:14:43,110 --> 00:14:46,710 If I were to read this one, just using the keywords 272 00:14:46,710 --> 00:14:54,120 and variables here, it would sound like broken English. 273 00:14:54,120 --> 00:14:56,880 But you could decipher what I'm trying to say. 274 00:14:56,880 --> 00:15:01,590 For a char in a string s, if the char is equal to "i" 275 00:15:01,590 --> 00:15:07,065 or a char is equal to "u," print "There is an i or a u." 276 00:15:07,065 --> 00:15:09,330 It sounds weird, but you could probably 277 00:15:09,330 --> 00:15:11,850 tell what I was trying to do here. 278 00:15:11,850 --> 00:15:14,130 Whereas up here, it's a little more 279 00:15:14,130 --> 00:15:15,630 complicated to tell what I'm doing. 280 00:15:15,630 --> 00:15:17,730 You have to sort of think about it a little bit. 281 00:15:17,730 --> 00:15:20,490 For some index in this range of numbers, 282 00:15:20,490 --> 00:15:23,850 0 through the length of the string 283 00:15:23,850 --> 00:15:28,890 s, if s, at position index, is an "i" or s at position index 284 00:15:28,890 --> 00:15:33,160 is a "u" print, "There is an i or a u." 285 00:15:33,160 --> 00:15:36,940 Both of these codes just go through the string s. 286 00:15:36,940 --> 00:15:40,000 And if it encounters a letter that's an i or a u, 287 00:15:40,000 --> 00:15:42,010 it's just going to print out this string here. 288 00:15:42,010 --> 00:15:44,560 But this bottom one is a lot more pythonic. 289 00:15:44,560 --> 00:15:48,460 It's an actual word created by the Python community. 290 00:15:48,460 --> 00:15:52,785 And it just looks pretty, right? 291 00:15:52,785 --> 00:15:55,724 You can tell what this code's supposed to do. 292 00:15:55,724 --> 00:15:57,890 Whereas this one is a little bit harder to decipher. 293 00:16:01,620 --> 00:16:04,200 So that's sort of an illustration of a for loop 294 00:16:04,200 --> 00:16:06,990 over a sequence of characters. 295 00:16:06,990 --> 00:16:10,530 So char is going to be a loop variable, still. 296 00:16:10,530 --> 00:16:13,920 And the loop variable, instead of iterating over 297 00:16:13,920 --> 00:16:17,220 a set of numbers, it's going to iterate over every character 298 00:16:17,220 --> 00:16:19,170 in s, directly. 299 00:16:19,170 --> 00:16:22,890 And char is going to be a character. 300 00:16:22,890 --> 00:16:24,461 It's going to be a letter. 301 00:16:28,900 --> 00:16:31,690 So here's a more complicated example. 302 00:16:31,690 --> 00:16:34,690 I wrote this code a couple of years ago. 303 00:16:34,690 --> 00:16:37,870 And it was my attempt at creating robot cheerleaders , 304 00:16:37,870 --> 00:16:40,480 because I needed some motivation. 305 00:16:40,480 --> 00:16:44,410 And then I googled, last night, "robot cheerleaders," 306 00:16:44,410 --> 00:16:46,030 and was not disappointed. 307 00:16:46,030 --> 00:16:47,020 Created this GIF. 308 00:16:47,020 --> 00:16:49,046 It looks pretty cool. 309 00:16:49,046 --> 00:16:50,920 And it looks like they kind of stole my idea. 310 00:16:50,920 --> 00:16:53,300 But that's fine. 311 00:16:53,300 --> 00:16:56,107 So let's look at what this code's supposed to do. 312 00:16:56,107 --> 00:16:56,940 I'm going to run it. 313 00:17:05,467 --> 00:17:07,550 I'm going to run it, and then we'll go through it. 314 00:17:12,200 --> 00:17:14,520 All right, it prints out, "I will cheer for you! 315 00:17:14,520 --> 00:17:15,670 Enter a word." 316 00:17:15,670 --> 00:17:20,530 You know what, I like robots, so I'll put in "ROBOTS." 317 00:17:20,530 --> 00:17:22,900 How enthusiastic am I about robots? 318 00:17:22,900 --> 00:17:25,940 Let's say 6. 319 00:17:25,940 --> 00:17:29,060 So what this is going to print is-- it's a cheerleader, 320 00:17:29,060 --> 00:17:32,270 right? "Give me an r, r." "Give me an o, o." "Give me a b, b," 321 00:17:32,270 --> 00:17:33,830 and so on and so on. 322 00:17:33,830 --> 00:17:34,980 "What does that spell? 323 00:17:34,980 --> 00:17:35,750 ROBOTS." 324 00:17:35,750 --> 00:17:39,320 And it's going to print it 6 times, because I'm 6 out of 10 325 00:17:39,320 --> 00:17:41,480 enthusiastic about robots. 326 00:17:41,480 --> 00:17:43,742 So that's pretty much what that code's supposed to do. 327 00:17:43,742 --> 00:17:45,950 And you can write it using what we've learned so far. 328 00:17:48,700 --> 00:17:50,270 Now let's go through it a little bit. 329 00:17:50,270 --> 00:17:52,570 And I'm going to show you just how easy it 330 00:17:52,570 --> 00:17:57,220 is to convert this code using a for loop over characters. 331 00:17:57,220 --> 00:18:03,680 Right now, what it does is it asks the user for input, 332 00:18:03,680 --> 00:18:07,180 so a word and a number. 333 00:18:07,180 --> 00:18:09,220 And then it does this thing, here, right? 334 00:18:09,220 --> 00:18:12,810 First, it uses a while loop. 335 00:18:12,810 --> 00:18:16,740 And second, it uses indexing. 336 00:18:16,740 --> 00:18:20,820 And what tips you off that it's using indexing 337 00:18:20,820 --> 00:18:24,240 is it's using the square bracket, here, into the word. 338 00:18:28,260 --> 00:18:30,480 And obviously, it's using a while loop. 339 00:18:30,480 --> 00:18:34,672 And it has to first create a counter, initialize it. 340 00:18:34,672 --> 00:18:36,630 And then, down here, it's going to increment it 341 00:18:36,630 --> 00:18:38,010 inside the while loop. 342 00:18:38,010 --> 00:18:40,770 If you remember, that's sort of what 343 00:18:40,770 --> 00:18:44,290 we need to do for while loops. 344 00:18:44,290 --> 00:18:47,050 So it's going to start at 0, and it's just basically going 345 00:18:47,050 --> 00:18:50,650 to go through index i is equal to 0, 1, 2, 3 4, which 346 00:18:50,650 --> 00:18:53,980 is going to go all the way to the end of the word, whatever 347 00:18:53,980 --> 00:18:56,710 the user typed in, in this case "ROBOTS." 348 00:18:56,710 --> 00:19:00,190 It's going to get the character at that position. 349 00:19:00,190 --> 00:19:05,470 word at position i is going to be a character. 350 00:19:05,470 --> 00:19:14,850 This line here is just for the cheerleading to make sense. 351 00:19:14,850 --> 00:19:17,400 It's just to take care of letters that 352 00:19:17,400 --> 00:19:20,340 make sense to use an, right? 353 00:19:20,340 --> 00:19:22,980 So give me a b, give me an b. 354 00:19:22,980 --> 00:19:25,500 So give me an b does not make sense, right? 355 00:19:25,500 --> 00:19:28,860 So that's just taking care of that. 356 00:19:28,860 --> 00:19:31,500 And I'm using this in keyword to check 357 00:19:31,500 --> 00:19:35,370 whether the character-- so the character, r, for example, 358 00:19:35,370 --> 00:19:39,240 in robots-- is inside an letters. 359 00:19:39,240 --> 00:19:41,490 And an letters I've defined up here, which is these 360 00:19:41,490 --> 00:19:43,440 are all the letters that make sense 361 00:19:43,440 --> 00:19:48,080 to put an an before the letter. 362 00:19:48,080 --> 00:19:50,460 So give me an r for example, here, on the right. 363 00:19:55,950 --> 00:19:58,220 And so if it makes sense to use an before the letter, 364 00:19:58,220 --> 00:20:03,990 use that, and otherwise use just an a. 365 00:20:03,990 --> 00:20:06,120 And after I'm done, I say, "What does that spell?" 366 00:20:06,120 --> 00:20:10,470 And then it's just a for loop that goes times many times 367 00:20:10,470 --> 00:20:12,890 and prints out the word and the exclamation mark. 368 00:20:23,000 --> 00:20:26,870 So this code might have been a little bit more intuitive 369 00:20:26,870 --> 00:20:29,060 if I rewrote it or if I'd originally 370 00:20:29,060 --> 00:20:33,800 written it with a for loop. 371 00:20:33,800 --> 00:20:36,800 So this part here, the while loop and indexing 372 00:20:36,800 --> 00:20:38,870 and creating my original counter, 373 00:20:38,870 --> 00:20:41,990 we can get rid of that. 374 00:20:41,990 --> 00:20:46,260 And we can replace it with this, for char in word. 375 00:20:46,260 --> 00:20:49,380 I'm originally using char, so I can use char 376 00:20:49,380 --> 00:20:51,570 as my loop variable again. 377 00:20:51,570 --> 00:20:55,290 And simply, I'm just going to iterate over the word, itself. 378 00:20:57,870 --> 00:20:59,970 So now, instead of having this mess here, I 379 00:20:59,970 --> 00:21:03,480 have a one-liner that says, for every character in my word, 380 00:21:03,480 --> 00:21:04,740 do all this stuff here. 381 00:21:04,740 --> 00:21:06,240 So that remains the same. 382 00:21:06,240 --> 00:21:08,730 And then I don't even need to increment a counter variable, 383 00:21:08,730 --> 00:21:10,170 because I'm not using while loops anymore. 384 00:21:10,170 --> 00:21:11,400 I'm just using a for loop. 385 00:21:14,070 --> 00:21:20,400 So the code becomes-- delete that-- for char in word. 386 00:21:20,400 --> 00:21:23,220 And then delete that. 387 00:21:23,220 --> 00:21:25,192 And that does the exact same thing. 388 00:21:25,192 --> 00:21:26,400 And it's a lot more readable. 389 00:21:30,570 --> 00:21:34,770 So this was our toolbox at the beginning of this course. 390 00:21:34,770 --> 00:21:38,006 We are two and half, I guess, lectures in. 391 00:21:38,006 --> 00:21:39,630 These are the things we've added to it. 392 00:21:39,630 --> 00:21:42,540 We know integer, floats, Booleans. 393 00:21:42,540 --> 00:21:46,230 We know a bit of string manipulation, math operations. 394 00:21:46,230 --> 00:21:48,870 We added, recently, these conditionals and branching 395 00:21:48,870 --> 00:21:51,810 to write slightly more interesting programs. 396 00:21:51,810 --> 00:21:53,910 And now we have loops, for and while loops 397 00:21:53,910 --> 00:21:57,094 to add interesting and more complicated programs. 398 00:21:57,094 --> 00:21:59,010 So with these, the second part of this lecture 399 00:21:59,010 --> 00:22:02,070 is going to be looking at three different algorithms. 400 00:22:02,070 --> 00:22:03,750 That's the sort of computer science part 401 00:22:03,750 --> 00:22:06,180 of this class, Introduction to Computer Science 402 00:22:06,180 --> 00:22:08,370 and Programming using Python. 403 00:22:08,370 --> 00:22:10,050 Don't let the word algorithm scare you. 404 00:22:14,520 --> 00:22:16,710 They're not that complicated. 405 00:22:16,710 --> 00:22:19,950 You just have to sort of think a little bit about them. 406 00:22:19,950 --> 00:22:22,560 And you'll be able to get them. 407 00:22:22,560 --> 00:22:25,200 So we're going to look at three algorithms, all 408 00:22:25,200 --> 00:22:27,090 in the context of solving one problem, which 409 00:22:27,090 --> 00:22:28,996 is finding the cube root. 410 00:22:28,996 --> 00:22:30,709 The first algorithm is guess and check, 411 00:22:30,709 --> 00:22:33,000 then we're going to look at an approximation algorithm, 412 00:22:33,000 --> 00:22:36,720 and then a bisection search. 413 00:22:36,720 --> 00:22:39,900 So the first is the guess and check method. 414 00:22:39,900 --> 00:22:44,840 You might have done this, in math, in high school. 415 00:22:44,840 --> 00:22:47,410 The guess and check method is also sometimes called 416 00:22:47,410 --> 00:22:48,460 exhaustive enumeration. 417 00:22:48,460 --> 00:22:49,270 And you'll see why. 418 00:22:49,270 --> 00:22:53,380 So given a problem, let's say, find the cube root of a number, 419 00:22:53,380 --> 00:22:55,940 let's say you can guess a starting value for a solution. 420 00:22:59,050 --> 00:23:00,800 The guess and check method works if you're 421 00:23:00,800 --> 00:23:03,270 able to check if your solution is correct. 422 00:23:03,270 --> 00:23:06,440 So if your guess is originally 0, you can say, 423 00:23:06,440 --> 00:23:12,080 is 0 cubed equal to the cube of whatever I'm trying 424 00:23:12,080 --> 00:23:13,247 to find the cube root of? 425 00:23:13,247 --> 00:23:15,080 So if I'm trying to find the cube root of 8, 426 00:23:15,080 --> 00:23:17,590 is 0 cubed equal to 8? 427 00:23:17,590 --> 00:23:19,500 No. 428 00:23:19,500 --> 00:23:21,270 So the solution is not correct. 429 00:23:21,270 --> 00:23:23,190 If it's not correct, guess another value. 430 00:23:23,190 --> 00:23:26,370 Do it systematically until you find a solution 431 00:23:26,370 --> 00:23:32,270 or you've guessed all the possible values, 432 00:23:32,270 --> 00:23:34,020 you've exhausted all of your search space. 433 00:23:36,560 --> 00:23:39,460 So here's a very simple guess and check code that finds 434 00:23:39,460 --> 00:23:41,470 the cube root of a number. 435 00:23:41,470 --> 00:23:43,420 So I'm trying to find the cube root of 8. 436 00:23:43,420 --> 00:23:45,730 So my cube is 8. 437 00:23:45,730 --> 00:23:47,980 I'm going to have a for loop that says, 438 00:23:47,980 --> 00:23:50,710 I'm going to start from 0. 439 00:23:50,710 --> 00:23:53,980 And I'm going to go all the way up to-- 440 00:23:53,980 --> 00:23:59,079 So I'm going to start from 0 and go all the way up to 8. 441 00:23:59,079 --> 00:24:01,120 For every one of these numbers, I'm going to say, 442 00:24:01,120 --> 00:24:04,900 is my guess to the power of 3 equal to the cube 8? 443 00:24:04,900 --> 00:24:09,220 And if it is, I'm going to print out this message. 444 00:24:09,220 --> 00:24:14,090 Pretty simple, however, this code is not very user friendly, 445 00:24:14,090 --> 00:24:14,590 right? 446 00:24:14,590 --> 00:24:17,860 If the user wants to find the cube root of 9, 447 00:24:17,860 --> 00:24:20,830 they're not going to get any output, because we never 448 00:24:20,830 --> 00:24:25,390 print anything in the case of the guess 449 00:24:25,390 --> 00:24:28,122 not being a perfect cube. 450 00:24:28,122 --> 00:24:31,440 or the cube not being a perfect cube. 451 00:24:31,440 --> 00:24:34,300 So we can modify the code a little bit 452 00:24:34,300 --> 00:24:37,869 to add two extra features. 453 00:24:37,869 --> 00:24:39,660 The first is we're going to be able to deal 454 00:24:39,660 --> 00:24:43,800 with negative cubes, which is kind of cool. 455 00:24:43,800 --> 00:24:46,740 And the second is we're going to tell the user, 456 00:24:46,740 --> 00:24:48,930 if the cube is not a perfect cube, 457 00:24:48,930 --> 00:24:50,530 hey, this cube is not a perfect cube. 458 00:24:50,530 --> 00:24:52,680 So we're not going to silently just fail, 459 00:24:52,680 --> 00:24:56,120 because then the user has some sort of feedback 460 00:24:56,120 --> 00:24:58,040 on their input. 461 00:24:58,040 --> 00:25:01,000 So let's step through this code. 462 00:25:01,000 --> 00:25:05,950 We have, first of all, a for loop just like before. 463 00:25:05,950 --> 00:25:13,070 And we're going to go through 0 to 8 in this case. 464 00:25:13,070 --> 00:25:14,820 We're using the absolute value, because we 465 00:25:14,820 --> 00:25:17,655 might want to find the cube root of negative numbers. 466 00:25:20,320 --> 00:25:24,160 First thing we're doing is doing this check here. 467 00:25:27,400 --> 00:25:32,260 Instead of guessing whether the guess to the power of 3 468 00:25:32,260 --> 00:25:34,180 is equal to the cube, we're going 469 00:25:34,180 --> 00:25:36,190 to check if it's greater or equal to, 470 00:25:36,190 --> 00:25:39,370 and we're going to do that for the following reason. 471 00:25:39,370 --> 00:25:42,160 So if we're trying to find the cube root of 8, 472 00:25:42,160 --> 00:25:47,360 for example, versus a cube root of 9-- this is 8 473 00:25:47,360 --> 00:25:51,290 and this is 9-- what is this code going to do? 474 00:25:51,290 --> 00:25:54,320 It's going to first guess 0. 475 00:25:54,320 --> 00:25:58,320 0 cubed is not greater or equal to 8. 476 00:25:58,320 --> 00:26:00,240 1 cubed is not greater or equal to 8. 477 00:26:00,240 --> 00:26:01,950 2 cubed is greater or equal to 8, 478 00:26:01,950 --> 00:26:05,760 so here, once we've guessed 2, we're going to break. 479 00:26:05,760 --> 00:26:10,080 Because we found a number that works. 480 00:26:10,080 --> 00:26:11,790 And there's no need to keep looking. 481 00:26:11,790 --> 00:26:16,710 Once we've found the cubed root of this number 8, 482 00:26:16,710 --> 00:26:20,400 there's no need to keep searching the remainder, 3, 4, 483 00:26:20,400 --> 00:26:21,320 5, 6, 7, 8. 484 00:26:24,380 --> 00:26:26,690 Sort of the same idea when we're trying 485 00:26:26,690 --> 00:26:29,114 to find the cube root of 9. 486 00:26:29,114 --> 00:26:30,280 We're going to start with 0. 487 00:26:30,280 --> 00:26:34,410 0 to the power of 3 is less than 9. 488 00:26:34,410 --> 00:26:35,830 1 to the power of 3 is less 9. 489 00:26:35,830 --> 00:26:37,760 2 to the power of 3 is less than 9. 490 00:26:37,760 --> 00:26:40,370 When we get to 3 to the power of 3, 491 00:26:40,370 --> 00:26:42,110 that's going to be greater than 9. 492 00:26:42,110 --> 00:26:54,950 So this code tells us, once we've 493 00:26:54,950 --> 00:26:58,340 picked a number that's beyond the reasonable number 494 00:26:58,340 --> 00:27:02,480 of our cubed root, of our cube, the cubed root of our cube, 495 00:27:02,480 --> 00:27:04,827 then we should stop. 496 00:27:04,827 --> 00:27:07,160 Because, again, it doesn't make sense to keep searching. 497 00:27:07,160 --> 00:27:10,220 Because if 3 to the power of 3 is already greater than 9, 498 00:27:10,220 --> 00:27:12,470 4 to the power of 3 is also going to be greater than 9 499 00:27:12,470 --> 00:27:14,720 and so on. 500 00:27:14,720 --> 00:27:19,250 So once we break here, we either have guess being 2 501 00:27:19,250 --> 00:27:22,020 or guess being 3 depending on what cube we're trying to find. 502 00:27:25,120 --> 00:27:29,620 And if the guess to the power or 3 is not equal to the cube, 503 00:27:29,620 --> 00:27:32,870 then, obviously, the cube was not a perfect cube. 504 00:27:32,870 --> 00:27:34,990 So that's this case here, if we were looking 505 00:27:34,990 --> 00:27:38,740 at at the cube root of 9. 506 00:27:38,740 --> 00:27:40,780 And otherwise, this part here just looks 507 00:27:40,780 --> 00:27:46,240 at whether we should make it a positive or a negative cube. 508 00:27:46,240 --> 00:27:49,865 So if our original cube was less than 0, then, 509 00:27:49,865 --> 00:27:51,740 obviously, the cube root of a negative number 510 00:27:51,740 --> 00:27:52,940 is going to be a negative number, 511 00:27:52,940 --> 00:27:54,480 and, otherwise, it's just our guess. 512 00:27:59,149 --> 00:28:00,690 So that's the guess and check method, 513 00:28:00,690 --> 00:28:03,000 slightly more feature-rich program 514 00:28:03,000 --> 00:28:05,340 for guessing the cube root. 515 00:28:05,340 --> 00:28:09,630 But that only tells us the cube root of perfect cubes 516 00:28:09,630 --> 00:28:12,690 and doesn't really give us anything else, any more 517 00:28:12,690 --> 00:28:13,450 information. 518 00:28:13,450 --> 00:28:17,270 So sometimes, you might want to say, well, 519 00:28:17,270 --> 00:28:19,370 I don't care that 9 is not a perfect cube, 520 00:28:19,370 --> 00:28:22,610 just give me a close enough answer. 521 00:28:22,610 --> 00:28:25,220 So that's where approximate solutions come in. 522 00:28:25,220 --> 00:28:29,342 So this is where we're OK with having a good enough solution. 523 00:28:29,342 --> 00:28:30,800 So in order to do that, we're going 524 00:28:30,800 --> 00:28:32,810 to start with a guess and then increment that 525 00:28:32,810 --> 00:28:34,120 guess by some small value. 526 00:28:37,020 --> 00:28:40,800 Start from 0 and start incrementing by 0.001 527 00:28:40,800 --> 00:28:42,470 and just go upwards from there. 528 00:28:42,470 --> 00:28:47,880 And at some point, you might find a good enough solution. 529 00:28:47,880 --> 00:28:52,650 In this program, we're going to keep guessing as long as we're 530 00:28:52,650 --> 00:28:55,310 not close enough. 531 00:28:55,310 --> 00:28:57,900 And close enough is going to be given by this epsilon 532 00:28:57,900 --> 00:29:00,570 value in the program. 533 00:29:00,570 --> 00:29:05,900 So as long as the guess cubed minus the cube-- so how far 534 00:29:05,900 --> 00:29:07,820 away are we from the actual answer-- 535 00:29:07,820 --> 00:29:11,210 is greater than some epsilon, keep guessing, 536 00:29:11,210 --> 00:29:13,960 because the solution is not good enough. 537 00:29:13,960 --> 00:29:15,880 But once this is less than epsilon, 538 00:29:15,880 --> 00:29:19,140 then we've reached a good enough solution. 539 00:29:19,140 --> 00:29:21,840 So two things to note with approximate solutions. 540 00:29:21,840 --> 00:29:23,660 So you can get more accurate answers 541 00:29:23,660 --> 00:29:25,910 if your step size is really, really small. 542 00:29:25,910 --> 00:29:27,699 If you're incrementing by 0.0001, 543 00:29:27,699 --> 00:29:29,990 you're going to get a really good approximate solution, 544 00:29:29,990 --> 00:29:31,573 but your program will be a lot slower. 545 00:29:35,100 --> 00:29:39,660 Same sort of idea with epsilon, you can change epsilon. 546 00:29:39,660 --> 00:29:42,300 If you change epsilon to be a bigger epsilon, 547 00:29:42,300 --> 00:29:44,130 you're sacrificing accuracy, but you're 548 00:29:44,130 --> 00:29:46,195 going to reach a solution a lot faster. 549 00:29:49,380 --> 00:29:52,901 So here's the code for the approximate solution of a cube 550 00:29:52,901 --> 00:29:53,400 root. 551 00:29:53,400 --> 00:29:55,710 It might look intimidating, but, look, 552 00:29:55,710 --> 00:29:59,730 almost half this code is just initializing variables. 553 00:29:59,730 --> 00:30:03,250 So we're initializing, this is the cube 554 00:30:03,250 --> 00:30:04,800 we want to find the cube root of. 555 00:30:04,800 --> 00:30:06,090 We pick an epsilon of this. 556 00:30:06,090 --> 00:30:08,010 We start with a guess of 0. 557 00:30:08,010 --> 00:30:10,202 We start with an increment of 0.0001. 558 00:30:10,202 --> 00:30:12,660 And just for fun, let's keep track of the number of guesses 559 00:30:12,660 --> 00:30:14,243 that it takes us to get to the answer. 560 00:30:17,710 --> 00:30:21,255 This is similar to the guess and check from before. 561 00:30:26,672 --> 00:30:27,380 It's not similar. 562 00:30:27,380 --> 00:30:30,320 Well this part is similar to the guess and check from before. 563 00:30:30,320 --> 00:30:33,770 So we're going to take the guess to the power of 3 564 00:30:33,770 --> 00:30:35,040 minus the cube, right? 565 00:30:35,040 --> 00:30:38,490 So that's how far away are we from the actual answer? 566 00:30:38,490 --> 00:30:40,560 And we're going to say, if that's not good 567 00:30:40,560 --> 00:30:42,060 enough-- so if we're still greater 568 00:30:42,060 --> 00:30:46,050 than or equal to the epsilon-- then keep guessing. 569 00:30:46,050 --> 00:30:49,160 So we're going to be stuck in this loop, where 570 00:30:49,160 --> 00:30:51,830 we keep guessing values, until we've 571 00:30:51,830 --> 00:30:53,330 reached a guess that's good enough, 572 00:30:53,330 --> 00:30:57,190 so until we're less than epsilon. 573 00:30:57,190 --> 00:30:59,210 And way we keep guessing is just with this line, 574 00:30:59,210 --> 00:31:04,010 right here, which says, increment my guess 575 00:31:04,010 --> 00:31:07,500 by increment, and increment being this really small value. 576 00:31:07,500 --> 00:31:08,470 That make sense? 577 00:31:11,445 --> 00:31:12,820 So I'm going to keep incrementing 578 00:31:12,820 --> 00:31:15,580 my guess by that small value. 579 00:31:15,580 --> 00:31:18,100 Before I go on, I'm going to run the code. 580 00:31:18,100 --> 00:31:21,460 And we're going to discover a small issue with it. 581 00:31:32,580 --> 00:31:34,590 So with 27, we're going to run it. 582 00:31:34,590 --> 00:31:37,110 Perfect, it took me 300 guesses. 583 00:31:37,110 --> 00:31:40,490 But 2.99999 is close to the cube root of 27. 584 00:31:43,370 --> 00:31:47,830 We can find the cube root of this guy here. 585 00:31:47,830 --> 00:31:50,850 And it took me 20,000 guesses, but I figured out 586 00:31:50,850 --> 00:31:55,170 that 200.99999, so 201, is close to the cube 587 00:31:55,170 --> 00:31:56,490 root of that large number. 588 00:32:06,160 --> 00:32:07,210 I should have done this. 589 00:32:07,210 --> 00:32:08,918 This is going to be a giveaway, you guys. 590 00:32:08,918 --> 00:32:10,450 Sorry. 591 00:32:10,450 --> 00:32:12,700 Then we're going to have-- let's say 592 00:32:12,700 --> 00:32:15,510 I want to try cube of 10,000. 593 00:32:15,510 --> 00:32:17,870 So 10,000 is not a perfect cube. 594 00:32:17,870 --> 00:32:20,530 So we can run the code. 595 00:32:20,530 --> 00:32:26,340 And with 8,120,601 I had already gotten an answer. 596 00:32:26,340 --> 00:32:28,980 But with 10,000, I'm not getting an answer yet, right? 597 00:32:28,980 --> 00:32:32,490 So I'm thinking that there might be something wrong. 598 00:32:32,490 --> 00:32:34,710 So I'm going to stop my code. 599 00:32:34,710 --> 00:32:37,500 So I just hit Control C, because I feel like I've 600 00:32:37,500 --> 00:32:38,610 entered an infinite loop. 601 00:32:38,610 --> 00:32:41,990 And, in fact, I have. 602 00:32:41,990 --> 00:32:45,570 So what ended up happening is this problem here. 603 00:32:45,570 --> 00:32:47,900 So I'm going to draw something. 604 00:32:50,600 --> 00:32:58,500 According to the code, I'm going to start from 0, 605 00:32:58,500 --> 00:33:03,030 and I'm going to increment my guesses, like that. 606 00:33:03,030 --> 00:33:06,030 With every little increment, I'm going to make a new guess. 607 00:33:06,030 --> 00:33:08,066 I'm going to take that guess to the power of 3. 608 00:33:08,066 --> 00:33:09,690 I'm going to subtract the cube, and I'm 609 00:33:09,690 --> 00:33:12,270 going to figure out if I'm less than epsilon. 610 00:33:12,270 --> 00:33:18,830 This is the epsilon that I want to be in, this little bit here. 611 00:33:18,830 --> 00:33:21,080 So with every new guess, I might be, 612 00:33:21,080 --> 00:33:23,940 maybe-- so this is where I want to be, 613 00:33:23,940 --> 00:33:26,150 within this little boundary here. 614 00:33:26,150 --> 00:33:29,270 With every new guess, I might be here. 615 00:33:29,270 --> 00:33:33,450 With the next guess, over here, I might be here. 616 00:33:33,450 --> 00:33:36,390 When I make another guess, I might be here. 617 00:33:36,390 --> 00:33:39,090 So I'm getting close to being within epsilon. 618 00:33:39,090 --> 00:33:41,100 But maybe with my next guess, I'm 619 00:33:41,100 --> 00:33:45,060 going to hop over my epsilon and have made too big of a guess. 620 00:33:48,990 --> 00:33:52,410 So just because of the way the numbers 621 00:33:52,410 --> 00:33:55,950 were chosen in this example, just to illustrate this, 622 00:33:55,950 --> 00:33:59,265 using an increment of 0.01, a with finding the cube of 10,000 623 00:33:59,265 --> 00:34:02,220 and epsilon of 0.1, it turns out that, as I'm 624 00:34:02,220 --> 00:34:03,750 doing all these calculations, I'm 625 00:34:03,750 --> 00:34:12,590 going to skip over this perfect sort of epsilon difference. 626 00:34:12,590 --> 00:34:14,800 So first, I'm going to be too small. 627 00:34:14,800 --> 00:34:16,449 And then I'm going to be too large. 628 00:34:16,449 --> 00:34:20,260 And once I've become too large or too far away from epsilon, 629 00:34:20,260 --> 00:34:22,090 the guesses I continue to make are just 630 00:34:22,090 --> 00:34:26,659 going to be even farther away from epsilon. 631 00:34:26,659 --> 00:34:28,459 And I'm not going to get to my answer. 632 00:34:28,459 --> 00:34:30,875 And that's why I've reached an infinite loop in this code. 633 00:34:33,570 --> 00:34:36,330 All I'm doing in this code is checking 634 00:34:36,330 --> 00:34:41,920 whether my guess cube minus cube is less than epsilon. 635 00:34:41,920 --> 00:34:43,630 The only thing I need to do here is 636 00:34:43,630 --> 00:34:45,370 sort of add this little clause, here, 637 00:34:45,370 --> 00:34:51,420 that says, oh, by the way, also check that I'm less than cube. 638 00:34:54,380 --> 00:34:58,400 Because this is just like we did in the very first program, 639 00:34:58,400 --> 00:35:04,989 when I'm checking 0, 1, 2, 3, 4, 5, 6, 7, 8, 640 00:35:04,989 --> 00:35:06,780 when I'm trying to find the cube root of 8. 641 00:35:14,150 --> 00:35:17,352 Once I've reached 8, I'm going to stop. 642 00:35:17,352 --> 00:35:18,560 And it's the same thing here. 643 00:35:22,140 --> 00:35:23,580 So I just added this little clause 644 00:35:23,580 --> 00:35:25,920 that says, well, while I'm greater 645 00:35:25,920 --> 00:35:27,840 than or equal to epsilon and I'm still 646 00:35:27,840 --> 00:35:30,150 less than the actual cube, just keep searching. 647 00:35:30,150 --> 00:35:35,400 But once I've reached the cube, then stop searching. 648 00:35:35,400 --> 00:35:38,130 And with 10,000, you can see that I 649 00:35:38,130 --> 00:35:41,130 failed to actually find-- so that's what this part, here, 650 00:35:41,130 --> 00:35:41,910 does. 651 00:35:41,910 --> 00:35:45,220 It tells me I've failed to find the cube 652 00:35:45,220 --> 00:35:46,950 root with those particular parameters. 653 00:35:51,198 --> 00:35:53,920 The last thing we're going to look at is bisection search. 654 00:35:53,920 --> 00:35:57,275 And to illustrate this, I'm going to need one volunteer. 655 00:35:57,275 --> 00:35:58,900 And you're going to play a game with me 656 00:35:58,900 --> 00:36:00,160 in front of the whole class. 657 00:36:00,160 --> 00:36:01,870 And there will be a prize. 658 00:36:01,870 --> 00:36:02,710 There go the hands. 659 00:36:06,310 --> 00:36:08,245 In the blue shirt, right there. 660 00:36:08,245 --> 00:36:08,890 Cool. 661 00:36:08,890 --> 00:36:12,670 So the prize is going to be, once again, this. 662 00:36:12,670 --> 00:36:17,450 I promise I don't have millions of these, Google glasses. 663 00:36:17,450 --> 00:36:18,880 I also don't work for Google. 664 00:36:18,880 --> 00:36:21,220 I just happened to get a couple. 665 00:36:21,220 --> 00:36:24,910 So the game is this. 666 00:36:24,910 --> 00:36:27,790 I'm going to ask you to pick a number, a whole number, 667 00:36:27,790 --> 00:36:30,500 between 0 and 100. 668 00:36:30,500 --> 00:36:32,350 And I'm going to try to guess it. 669 00:36:32,350 --> 00:36:34,090 And you need to make it hard for me. 670 00:36:34,090 --> 00:36:36,631 And you need to make it so hard for me that I cannot guess it 671 00:36:36,631 --> 00:36:40,570 within 10 guesses. 672 00:36:40,570 --> 00:36:42,880 And if you can do that, if I cannot guess it within 10 673 00:36:42,880 --> 00:36:44,700 guesses, you get this. 674 00:36:48,310 --> 00:36:50,920 And I'm going to draw out what I do as we go along. 675 00:36:50,920 --> 00:36:53,350 So do you have your number? 676 00:36:53,350 --> 00:36:53,920 Yes? 677 00:36:53,920 --> 00:36:54,544 AUDIENCE: Yeah. 678 00:36:54,544 --> 00:36:56,110 ANA BELL: Perfect. 679 00:36:56,110 --> 00:36:57,070 Let me erase that. 680 00:36:57,070 --> 00:36:58,778 Actually, I should've probably kept that, 681 00:36:58,778 --> 00:37:00,880 because I'll still use it. 682 00:37:00,880 --> 00:37:04,810 There's the numbers, 0 to 100. 683 00:37:04,810 --> 00:37:07,315 Is your number 50? 684 00:37:07,315 --> 00:37:08,780 AUDIENCE: No. 685 00:37:08,780 --> 00:37:10,110 ANA BELL: 50 Was my guess. 686 00:37:10,110 --> 00:37:11,570 So I've made one guess. 687 00:37:11,570 --> 00:37:14,002 Is your number higher or lower than 50? 688 00:37:14,002 --> 00:37:14,710 AUDIENCE: Higher. 689 00:37:14,710 --> 00:37:15,940 ANA BELL: Higher. 690 00:37:15,940 --> 00:37:21,050 Is your number-- my next guess is going to be 75. 691 00:37:21,050 --> 00:37:24,352 And the reason I'm guessing 75 is because-- what's your name? 692 00:37:24,352 --> 00:37:25,060 AUDIENCE: Sophie. 693 00:37:25,060 --> 00:37:25,615 ANA BELL: What's that? 694 00:37:25,615 --> 00:37:26,230 AUDIENCE: Sophie. 695 00:37:26,230 --> 00:37:27,030 ANA BELL: Sophie. 696 00:37:27,030 --> 00:37:29,820 Sophie said, 50 was too low. 697 00:37:29,820 --> 00:37:32,650 So I immediately know that it cannot be any less than 50. 698 00:37:32,650 --> 00:37:35,730 So I've already eliminated half of the numbers. 699 00:37:35,730 --> 00:37:37,260 So my next guess is 75. 700 00:37:37,260 --> 00:37:40,020 Is your number 75? 701 00:37:40,020 --> 00:37:41,652 Is your number lower or higher? 702 00:37:41,652 --> 00:37:42,360 AUDIENCE: Higher. 703 00:37:45,060 --> 00:37:47,970 ANA BELL: Since it's higher, I'm eliminating this half here. 704 00:37:47,970 --> 00:37:52,255 Is your number-- so between 75 and 100. 705 00:37:52,255 --> 00:37:53,880 Oh, boy, you're putting me on the spot. 706 00:37:53,880 --> 00:37:54,379 What's that? 707 00:37:54,379 --> 00:37:55,010 AUDIENCE: 87. 708 00:37:55,010 --> 00:37:57,480 ANA BELL: 87, thank you. 709 00:37:57,480 --> 00:37:58,580 87? 710 00:37:58,580 --> 00:37:59,340 AUDIENCE: No. 711 00:37:59,340 --> 00:38:00,453 ANA BELL: Higher or lower? 712 00:38:00,453 --> 00:38:01,180 AUDIENCE: Lower. 713 00:38:01,180 --> 00:38:02,140 ANA BELL: Lower. 714 00:38:02,140 --> 00:38:04,790 So since it's lower, I'm eliminating that half. 715 00:38:07,540 --> 00:38:10,780 Is your number 81? 716 00:38:10,780 --> 00:38:12,454 Higher or lower? 717 00:38:12,454 --> 00:38:13,120 AUDIENCE: Lower. 718 00:38:15,732 --> 00:38:18,190 ANA BELL: So she said, lower, so I'm eliminating that half. 719 00:38:20,810 --> 00:38:22,450 Is your number 78? 720 00:38:22,450 --> 00:38:24,770 Oh, boy, that's really hard. 721 00:38:24,770 --> 00:38:26,850 78, OK. 722 00:38:26,850 --> 00:38:27,600 Higher or lower? 723 00:38:27,600 --> 00:38:30,080 AUDIENCE: Lower. 724 00:38:30,080 --> 00:38:31,455 ANA BELL: Is your number 76? 725 00:38:31,455 --> 00:38:32,080 AUDIENCE: Yeah. 726 00:38:32,080 --> 00:38:32,950 ANA BELL: Yay. 727 00:38:32,950 --> 00:38:35,327 All right, perfect, 76 was the number. 728 00:38:35,327 --> 00:38:36,660 So how many guesses have I made? 729 00:38:36,660 --> 00:38:43,790 One, two, three, four, five, six-- I made six guesses. 730 00:38:43,790 --> 00:38:47,461 So I did get it under 10. 731 00:38:47,461 --> 00:38:48,210 But you know what? 732 00:38:48,210 --> 00:38:50,720 The game was rigged. 733 00:38:50,720 --> 00:38:54,462 So you get the prize anyway, just because I rigged the game. 734 00:38:54,462 --> 00:38:55,139 Here you go. 735 00:38:55,139 --> 00:38:55,680 Pass it down. 736 00:38:55,680 --> 00:38:56,513 AUDIENCE: Thank you. 737 00:38:56,513 --> 00:38:57,890 ANA BELL: Thank you. 738 00:38:57,890 --> 00:39:02,010 So notice, in bisection search, what I did was I 739 00:39:02,010 --> 00:39:04,860 eliminated half the search space with every guess. 740 00:39:04,860 --> 00:39:07,140 I said, well, she said it's higher or lower, 741 00:39:07,140 --> 00:39:09,960 so I definitely cannot be in the other search space, right? 742 00:39:09,960 --> 00:39:12,520 If I was doing approximate solution or, in this case, 743 00:39:12,520 --> 00:39:16,040 guess and check, I would be asking Sophie, is your number 744 00:39:16,040 --> 00:39:20,310 0, 1, 2, 3, 4, and so on? 745 00:39:20,310 --> 00:39:23,610 So with guess and check, it would have taken me 746 00:39:23,610 --> 00:39:29,220 76 guesses to get to the number, whereas, with this bisection 747 00:39:29,220 --> 00:39:34,200 search, that I just did, it only took me 6. 748 00:39:34,200 --> 00:39:35,240 Isn't that cool? 749 00:39:35,240 --> 00:39:40,840 So that means that the larger the space actually 750 00:39:40,840 --> 00:39:44,020 is, that I need to search, the better it 751 00:39:44,020 --> 00:39:46,490 is to use bisection search, this bisection search method. 752 00:39:49,060 --> 00:39:51,410 So that's basically what I'm illustrating here. 753 00:39:51,410 --> 00:39:54,580 So we have our original search space. 754 00:39:54,580 --> 00:39:56,740 We're going to choose a guess halfway, eliminate 755 00:39:56,740 --> 00:39:58,180 half of the guesses. 756 00:39:58,180 --> 00:40:01,780 Then we're going look in the remaining interval, 757 00:40:01,780 --> 00:40:04,878 eliminate half the guesses, and so on and so on. 758 00:40:08,850 --> 00:40:10,865 So then this is the code for bisection search. 759 00:40:14,550 --> 00:40:16,720 Also looks intimidating, but it's not so bad. 760 00:40:16,720 --> 00:40:18,720 So we're initializing a bunch of stuff up here. 761 00:40:18,720 --> 00:40:20,970 The most important couple of things we're initializing 762 00:40:20,970 --> 00:40:26,940 are, first of all, this high and this low boundaries. 763 00:40:26,940 --> 00:40:29,970 So with the guessing game, the low boundary was 0, 764 00:40:29,970 --> 00:40:34,741 and the high boundary was 100. 765 00:40:34,741 --> 00:40:36,240 When we're looking at the cube root, 766 00:40:36,240 --> 00:40:38,670 the low boundary is going to be 0, 767 00:40:38,670 --> 00:40:42,960 and the high boundary is going to be just my cube, 768 00:40:42,960 --> 00:40:46,320 because a guess to the power of 3 cannot be any greater than 769 00:40:46,320 --> 00:40:48,370 cube. 770 00:40:48,370 --> 00:40:50,590 And then, I'm just going to do the same procedure 771 00:40:50,590 --> 00:40:52,256 that I did with the guessing game, which 772 00:40:52,256 --> 00:40:56,540 is I'm going to make my guess, be halfway in between. 773 00:40:56,540 --> 00:41:00,460 So with this guessing game, I had to sort of choose, 774 00:41:00,460 --> 00:41:02,230 if there were four numbers in between, 775 00:41:02,230 --> 00:41:04,250 should I go higher or lower? 776 00:41:04,250 --> 00:41:06,400 Well, when we're doing by bisection search, 777 00:41:06,400 --> 00:41:08,492 here, we don't care about that. 778 00:41:08,492 --> 00:41:10,450 We're just going to do floating point division, 779 00:41:10,450 --> 00:41:17,530 because we want decimal numbers. 780 00:41:17,530 --> 00:41:19,780 So I have a low boundary and a high boundary. 781 00:41:19,780 --> 00:41:21,830 And I figured out my halfway point. 782 00:41:24,630 --> 00:41:27,240 Then I have this while loop here. 783 00:41:27,240 --> 00:41:35,530 A while loop is similar to the approximation method, where, 784 00:41:35,530 --> 00:41:38,120 as long as I don't have a guest that's good enough-- 785 00:41:38,120 --> 00:41:40,000 so this, depicted by this greater or equal 786 00:41:40,000 --> 00:41:42,550 to epsilon-- as long as my guess is not good enough, 787 00:41:42,550 --> 00:41:44,180 I'm going to keep guessing. 788 00:41:44,180 --> 00:41:45,972 That's what this while loop is saying. 789 00:41:45,972 --> 00:41:47,805 So if the guess to the power of 3 minus cube 790 00:41:47,805 --> 00:41:50,620 is not good enough, keep guessing. 791 00:41:50,620 --> 00:41:56,340 And the way I keep guessing is this part, here, 792 00:41:56,340 --> 00:42:01,170 says, my guess was too low. 793 00:42:01,170 --> 00:42:03,510 So if my guess was too low, set the low boundary 794 00:42:03,510 --> 00:42:05,280 to be the guess. 795 00:42:05,280 --> 00:42:08,370 Because I don't care about all of the other numbers 796 00:42:08,370 --> 00:42:10,620 that are much lower than me. 797 00:42:10,620 --> 00:42:12,410 So set the low to be the guess. 798 00:42:12,410 --> 00:42:15,510 That's what that line is doing. 799 00:42:15,510 --> 00:42:19,160 And otherwise, my guess was too high. 800 00:42:19,160 --> 00:42:20,570 That's what this else is doing. 801 00:42:20,570 --> 00:42:22,430 So set the high to be the guess, because I 802 00:42:22,430 --> 00:42:26,690 don't care about numbers any higher than my guess. 803 00:42:26,690 --> 00:42:28,460 Once I have these new boundaries, 804 00:42:28,460 --> 00:42:31,380 I make another guess, again, halfway 805 00:42:31,380 --> 00:42:34,467 in between the new boundary points. 806 00:42:34,467 --> 00:42:36,300 So essentially, I'm just halving my interval 807 00:42:36,300 --> 00:42:38,714 with every single guess. 808 00:42:38,714 --> 00:42:40,380 And that's what the while loop is doing. 809 00:42:40,380 --> 00:42:44,690 And then I print out the remaining part. 810 00:42:44,690 --> 00:42:50,450 So notice the search space originally being N, 811 00:42:50,450 --> 00:42:52,277 we're halving it with each guess. 812 00:42:52,277 --> 00:42:53,735 So the first guess divides it by 2, 813 00:42:53,735 --> 00:42:56,070 the second guess divides it by 4, and so on. 814 00:42:56,070 --> 00:42:59,300 So by the time we get to the k-th guess, 815 00:42:59,300 --> 00:43:03,727 N/2k, the k-th guess, let's say that's the actual answer we're 816 00:43:03,727 --> 00:43:04,310 interested in. 817 00:43:04,310 --> 00:43:07,170 There's only one value in that little interval. 818 00:43:07,170 --> 00:43:09,440 And that's the answer we want. 819 00:43:09,440 --> 00:43:13,130 So 2 to the k is equal to N. And then 820 00:43:13,130 --> 00:43:14,960 how many guesses did we make? 821 00:43:14,960 --> 00:43:21,150 k is equal to log base 2 of N. So when 822 00:43:21,150 --> 00:43:24,920 we are playing the guessing game of 100, my end was 100. 823 00:43:24,920 --> 00:43:29,940 Log base 2 of 100 is 6.-something, I think. 824 00:43:29,940 --> 00:43:31,740 So in fact, I could have said, if I 825 00:43:31,740 --> 00:43:35,760 don't guess it within seven guesses, 826 00:43:35,760 --> 00:43:36,940 you would have won as well. 827 00:43:36,940 --> 00:43:39,060 So that's why the game was rigged. 828 00:43:39,060 --> 00:43:41,730 So the guess, notice, it converges 829 00:43:41,730 --> 00:43:44,490 on the order of log base N instead 830 00:43:44,490 --> 00:43:48,582 of just linearly in terms of N. So that's why it's so powerful. 831 00:43:48,582 --> 00:43:50,040 One last thing I want to mention is 832 00:43:50,040 --> 00:43:53,460 the code I showed only works for positive cubes. 833 00:43:53,460 --> 00:43:57,600 And that's because of the following. 834 00:43:57,600 --> 00:44:00,900 So I have this 0 and 1. 835 00:44:00,900 --> 00:44:03,780 Let's say I'm trying to find the cube root of 0.5. 836 00:44:03,780 --> 00:44:08,060 When I first set my initial boundaries, my low is this one, 837 00:44:08,060 --> 00:44:10,680 and my high is this one. 838 00:44:10,680 --> 00:44:12,480 But what's the cube root of 0.5? 839 00:44:12,480 --> 00:44:15,069 Is it within this boundary or is it outside this boundary? 840 00:44:15,069 --> 00:44:16,360 AUDIENCE: Outside the boundary. 841 00:44:16,360 --> 00:44:17,485 ANA BELL: I heard, outside. 842 00:44:17,485 --> 00:44:18,700 It's like 0.7 something. 843 00:44:18,700 --> 00:44:20,170 So it's out here. 844 00:44:20,170 --> 00:44:21,700 So with this particular code, I'm 845 00:44:21,700 --> 00:44:26,170 going to be halving my interval in between those numbers, 846 00:44:26,170 --> 00:44:28,150 but I'll never get to an answer. 847 00:44:28,150 --> 00:44:32,790 Because the actual cube root of 0.5, or numbers less than 1, 848 00:44:32,790 --> 00:44:34,700 is going to be outside that boundary. 849 00:44:34,700 --> 00:44:37,450 So there's a small change you can make to the program, which 850 00:44:37,450 --> 00:44:38,650 will fix that. 851 00:44:38,650 --> 00:44:39,700 And that's in the code. 852 00:44:39,700 --> 00:44:42,370 I didn't put it in, but it's a very small change, a small if 853 00:44:42,370 --> 00:44:43,450 statement. 854 00:44:43,450 --> 00:44:45,860 So that's it. 855 00:44:45,860 --> 00:44:50,130 All right, thank you. 856 00:44:50,130 --> 00:44:54,380 [APPLAUSE]