1 00:00:00,000 --> 00:00:03,472 [MUSIC PLAYING] 2 00:00:03,472 --> 00:00:05,460 3 00:00:05,460 --> 00:00:09,770 SPEAKER: Well, hello, one and all, and welcome to our short on for loops. 4 00:00:09,770 --> 00:00:12,480 If you're familiar with the Mario video game series, 5 00:00:12,480 --> 00:00:16,990 you might be familiar with Princess Peach and her castle, Peach's Castle. 6 00:00:16,990 --> 00:00:20,460 And we'll imagine together that Princess Peach is inviting some guests to join 7 00:00:20,460 --> 00:00:24,440 her at a ball at Peach's Castle at 7:00 PM this evening. 8 00:00:24,440 --> 00:00:26,580 Now, thankfully, Peach has automated the process 9 00:00:26,580 --> 00:00:28,570 of writing letters to her guests. 10 00:00:28,570 --> 00:00:31,530 In fact, we have here a function called write_letter, 11 00:00:31,530 --> 00:00:36,610 which takes in two arguments, one called receiver and one called sender. 12 00:00:36,610 --> 00:00:39,330 And notice how the purpose write_letter is 13 00:00:39,330 --> 00:00:42,540 to return to us a fully written and formatted letter 14 00:00:42,540 --> 00:00:45,380 to a receiver from the sender. 15 00:00:45,380 --> 00:00:48,150 In particular, we're using Python f-strings here 16 00:00:48,150 --> 00:00:52,590 to interpolate the values of receiver and sender. 17 00:00:52,590 --> 00:00:57,900 For instance, if our receiver were to be Mario, as it is on line 2 here, 18 00:00:57,900 --> 00:01:01,560 and our sender were to be Princess Peach, well, we should see, 19 00:01:01,560 --> 00:01:05,230 at the end of this, a letter that says "Dear Mario," 20 00:01:05,230 --> 00:01:09,680 and then some text down below, "Sincerely, Princess Peach." 21 00:01:09,680 --> 00:01:12,550 And then we'll take that letter and print it out to our terminal 22 00:01:12,550 --> 00:01:15,000 to make sure everything is all correct. 23 00:01:15,000 --> 00:01:17,118 So let's see what happens if we run this program. 24 00:01:17,118 --> 00:01:18,910 I'll go ahead and open up my terminal here. 25 00:01:18,910 --> 00:01:22,430 And I'll run python of letters.py. 26 00:01:22,430 --> 00:01:25,790 I'll give us a bit more space so we can see all the letters fly by here. 27 00:01:25,790 --> 00:01:30,440 If I hit Enter, we'll see some letters being printed out to each of our guests 28 00:01:30,440 --> 00:01:30,940 here. 29 00:01:30,940 --> 00:01:35,270 We see we invited Mario first. 30 00:01:35,270 --> 00:01:36,490 That seems good. 31 00:01:36,490 --> 00:01:41,230 Invited Luigi next, Daisy as well, and finally Yoshi. 32 00:01:41,230 --> 00:01:43,810 So this program seems to work. 33 00:01:43,810 --> 00:01:46,990 But there's a question of how well it's designed. 34 00:01:46,990 --> 00:01:50,710 I were to show you again what this program looks like, 35 00:01:50,710 --> 00:01:54,340 let's think of some scenarios where this might get a little tedious. 36 00:01:54,340 --> 00:01:57,310 Let's say we're only inviting four guests now, 37 00:01:57,310 --> 00:02:01,810 but we also want to invite other folks, too, in which case, our guest list 38 00:02:01,810 --> 00:02:03,380 gets pretty long. 39 00:02:03,380 --> 00:02:06,280 And to do that, I need to copy and paste, copy 40 00:02:06,280 --> 00:02:10,720 and paste to add new letters to new characters as well. 41 00:02:10,720 --> 00:02:13,000 Now, if you find yourself in this kind of situation 42 00:02:13,000 --> 00:02:16,570 where you're repeating something for each maybe guest you have, 43 00:02:16,570 --> 00:02:19,880 you might think to use something like a for loop. 44 00:02:19,880 --> 00:02:21,850 A for loop, in fact, is great when you know 45 00:02:21,850 --> 00:02:25,780 how many times you want to iterate or you want to do something, like write 46 00:02:25,780 --> 00:02:30,310 a letter, for each person or each thing you have in some list, like a guest 47 00:02:30,310 --> 00:02:31,840 list, in this case. 48 00:02:31,840 --> 00:02:36,760 So let's actually make ourselves a guest list and write a for loop 49 00:02:36,760 --> 00:02:41,120 to write a letter for each person on that guest list. 50 00:02:41,120 --> 00:02:45,040 Well, in main here, why don't I go ahead and update this program 51 00:02:45,040 --> 00:02:51,410 to instead keep track of a list that we're going to call names. 52 00:02:51,410 --> 00:02:55,570 And this names list will be our guest list for the ball. 53 00:02:55,570 --> 00:02:58,010 I'll go ahead and maybe add a few names to the guest list. 54 00:02:58,010 --> 00:03:04,630 I'll go ahead and add Mario here and Luigi as well, Daisy too-- 55 00:03:04,630 --> 00:03:07,700 Daisy-- and and Yoshi, just like this. 56 00:03:07,700 --> 00:03:12,220 And now I have a guest list of names I'm hoping to invite. 57 00:03:12,220 --> 00:03:14,120 Well, now what should we do? 58 00:03:14,120 --> 00:03:17,740 We know we want to write a letter for each person that 59 00:03:17,740 --> 00:03:20,120 is going to be in this list. 60 00:03:20,120 --> 00:03:23,260 So I think I can actually get rid of this code down below here 61 00:03:23,260 --> 00:03:26,800 and instead think about how I could use a for loop. 62 00:03:26,800 --> 00:03:30,160 Well, one way to use a for loop, as we saw in lecture, 63 00:03:30,160 --> 00:03:35,570 is to use numbers and iterate over every number in some range of numbers. 64 00:03:35,570 --> 00:03:38,380 So I could write some code like this-- for i, 65 00:03:38,380 --> 00:03:41,530 which is usually the name we give to some variable that is iterating, 66 00:03:41,530 --> 00:03:44,950 changing on each iteration-- for i in-- 67 00:03:44,950 --> 00:03:47,410 and then the Python range function. 68 00:03:47,410 --> 00:03:54,730 And range will give us a list of numbers from 0 up to but not including the value 69 00:03:54,730 --> 00:03:57,650 we pass in as input to range. 70 00:03:57,650 --> 00:04:04,360 So in effect, maybe I want i here to iterate, let's say, from 0, maybe 71 00:04:04,360 --> 00:04:09,490 the zeroth index of this list, to 1, the first index of this list, 72 00:04:09,490 --> 00:04:16,899 to 2, the second index of this list, and then to 3, the third index of this list, 73 00:04:16,899 --> 00:04:19,990 again, indexing from 0 with Mario here. 74 00:04:19,990 --> 00:04:25,300 So to do that, I can actually pass in to range here the length of our list. 75 00:04:25,300 --> 00:04:29,800 Here, I'm saying, len of names, which in this case is 4. 76 00:04:29,800 --> 00:04:33,597 But range will give us 0, 1, 2, and 3. 77 00:04:33,597 --> 00:04:34,680 Let's try this out though. 78 00:04:34,680 --> 00:04:37,150 I'll go ahead and print i down below. 79 00:04:37,150 --> 00:04:44,980 And ideally, I'll see 0, 1, 2, and 3, each of the indices in this list here. 80 00:04:44,980 --> 00:04:48,550 I'll go ahead and run python of letters.py. 81 00:04:48,550 --> 00:04:52,040 And we'll in fact see 0, 1, 2, and 3. 82 00:04:52,040 --> 00:04:54,320 That seems to work just as well. 83 00:04:54,320 --> 00:04:57,650 But of course, we don't want to invite these numbers to our party. 84 00:04:57,650 --> 00:05:00,680 We want to invite Mario, Luigi, Daisy, and Yoshi. 85 00:05:00,680 --> 00:05:06,500 So one way to approach this is to use i to index into our list. 86 00:05:06,500 --> 00:05:07,810 I could do something like this. 87 00:05:07,810 --> 00:05:10,660 I could say names bracket i. 88 00:05:10,660 --> 00:05:13,920 And on each iteration, again, i will change. 89 00:05:13,920 --> 00:05:17,200 First, it will be 0, then 1, then 2, then 3, 90 00:05:17,200 --> 00:05:20,560 giving us different names in our list here. 91 00:05:20,560 --> 00:05:23,370 I wanted to go ahead and run letters.py again. 92 00:05:23,370 --> 00:05:26,970 And we'll see, now, the names we're hoping to invite. 93 00:05:26,970 --> 00:05:30,540 And this is promising because I think I can actually use these as input 94 00:05:30,540 --> 00:05:33,360 to the write_letter function. 95 00:05:33,360 --> 00:05:34,510 Let's try this. 96 00:05:34,510 --> 00:05:40,230 If I were to go ahead and print not just names bracket i but the result 97 00:05:40,230 --> 00:05:46,260 write_letter given names bracket i as the receiver and "Princess Peach" 98 00:05:46,260 --> 00:05:51,690 as the sender, I think we'd start to get the same letters we saw last time. 99 00:05:51,690 --> 00:05:53,790 Notice a few things first here, though. 100 00:05:53,790 --> 00:05:57,750 Again, i will update on each iteration of our loop-- 101 00:05:57,750 --> 00:06:02,910 that is, from one traversal or time, going from top to bottom 102 00:06:02,910 --> 00:06:05,410 in this indented code here. 103 00:06:05,410 --> 00:06:08,230 What will actually stay the same is "Princess Peach" here, 104 00:06:08,230 --> 00:06:10,520 the name that will be the sender. 105 00:06:10,520 --> 00:06:13,150 That will not change on each iteration, because it doesn't 106 00:06:13,150 --> 00:06:16,480 depend on anything in our loop itself. 107 00:06:16,480 --> 00:06:18,080 So let's go ahead and run this. 108 00:06:18,080 --> 00:06:20,410 I'll run Python of letters.py. 109 00:06:20,410 --> 00:06:24,820 And we'll see the same letters down below here as well. 110 00:06:24,820 --> 00:06:28,580 So same results, but what have we given ourselves here? 111 00:06:28,580 --> 00:06:31,940 I'm not able to make this program much more flexible, much more adaptable. 112 00:06:31,940 --> 00:06:34,160 How would you invite additional guests? 113 00:06:34,160 --> 00:06:38,960 We could very quickly, let's say, add a guest, like Bowser. 114 00:06:38,960 --> 00:06:41,500 Everyone is invited here. 115 00:06:41,500 --> 00:06:44,260 And we could print out a letter for Bowser, just 116 00:06:44,260 --> 00:06:49,610 like that, no copying and pasting, just adding Bowser's name to our guest list. 117 00:06:49,610 --> 00:06:53,590 Now let's uninvite Bowser, actually, and think through some ways 118 00:06:53,590 --> 00:06:57,740 to improve the design of even this little segment of code here. 119 00:06:57,740 --> 00:06:59,185 Now, this works. 120 00:06:59,185 --> 00:07:01,030 It's actually pretty well designed. 121 00:07:01,030 --> 00:07:04,030 But I think we could make it a little more readable, maybe stylistically 122 00:07:04,030 --> 00:07:04,840 better too. 123 00:07:04,840 --> 00:07:07,900 And we could do that using a feature of Python, which is we 124 00:07:07,900 --> 00:07:11,750 can actually iterate over any kind of list directly. 125 00:07:11,750 --> 00:07:13,970 This is a list here. 126 00:07:13,970 --> 00:07:16,420 Names is a list of, in this case, names. 127 00:07:16,420 --> 00:07:20,830 So we can actually use it as the second part of our for loop. 128 00:07:20,830 --> 00:07:23,740 We could say, for i in names. 129 00:07:23,740 --> 00:07:26,980 And in this case, i will actually temporarily 130 00:07:26,980 --> 00:07:32,150 refer to each of the items in our list, or the names in our names list. 131 00:07:32,150 --> 00:07:36,700 i will first be Mario, then Luigi, then Daisy, then Yoshi, 132 00:07:36,700 --> 00:07:39,130 updating on each iteration. 133 00:07:39,130 --> 00:07:40,810 But I don't need to use i. 134 00:07:40,810 --> 00:07:42,610 In fact, I can give it any name I like as 135 00:07:42,610 --> 00:07:45,230 long as I am consistent with that name. 136 00:07:45,230 --> 00:07:49,450 I could say something more English-like, like, for name in names, 137 00:07:49,450 --> 00:07:51,410 because we have a list of names, plural. 138 00:07:51,410 --> 00:07:55,010 But each item is a single name, singular. 139 00:07:55,010 --> 00:07:58,120 So now on the inside of my for loop, well, 140 00:07:58,120 --> 00:08:02,530 there's no longer an i variable to use to index into names. 141 00:08:02,530 --> 00:08:05,920 But I've conveniently given myself now this variable called 142 00:08:05,920 --> 00:08:08,260 name that I can just use. 143 00:08:08,260 --> 00:08:13,130 Again, first name will be Mario, then Luigi, then Daisy, then Yoshi, 144 00:08:13,130 --> 00:08:17,060 updating on each iteration as we loop through our for loop. 145 00:08:17,060 --> 00:08:20,470 And once we get to the end, once there are no more names, 146 00:08:20,470 --> 00:08:24,070 we'll simply stop looping and exit our program. 147 00:08:24,070 --> 00:08:25,250 Let's try it here. 148 00:08:25,250 --> 00:08:28,000 I'll go ahead and run python of letters.py. 149 00:08:28,000 --> 00:08:33,370 And we'll see the same results but now with a bit better English syntax 150 00:08:33,370 --> 00:08:37,880 and probably better stylistically as writing programs like these. 151 00:08:37,880 --> 00:08:42,400 So for loops, again, are powerful when you know how many times you want to loop 152 00:08:42,400 --> 00:08:45,100 or when you want to do something for each item you have 153 00:08:45,100 --> 00:08:47,770 in some list or, more generally, some iterable, 154 00:08:47,770 --> 00:08:49,880 something can be iterated over. 155 00:08:49,880 --> 00:08:51,860 This was our short on for loops. 156 00:08:51,860 --> 00:08:54,390 We'll see you next time. 157 00:08:54,390 --> 00:08:55,000