WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000 00:00:00.000 --> 00:00:03.444 [GENTLE ORCHESTRAL MUSIC PLAYING] 00:00:24.110 --> 00:00:26.840 DAVID MALAN: All right, this is CS50's Introduction 00:00:26.840 --> 00:00:28.190 to Programming with Python. 00:00:28.190 --> 00:00:32.009 My name is David Malan and this is our week on functions and variables. 00:00:32.009 --> 00:00:35.690 But odds are, many of you, most of you, have never actually programmed before. 00:00:35.690 --> 00:00:37.790 So let's start by doing just that. 00:00:37.790 --> 00:00:40.250 Let me go ahead here and open up my computer 00:00:40.250 --> 00:00:43.220 and on it, a program called Visual Studio Code or VS 00:00:43.220 --> 00:00:45.650 Code, which is just a very popular program nowadays 00:00:45.650 --> 00:00:47.220 for actually writing code. 00:00:47.220 --> 00:00:49.840 Now, you don't have to write code using this particular tool. 00:00:49.840 --> 00:00:51.590 In fact, all we need at the end of the day 00:00:51.590 --> 00:00:54.742 is a so-called text editor, a program for writing text. 00:00:54.742 --> 00:00:57.200 And, heck, if you really want, you could even use something 00:00:57.200 --> 00:00:59.180 like Google Docs or Microsoft Word. 00:00:59.180 --> 00:01:00.952 You'd have to save it in the right format, 00:01:00.952 --> 00:01:04.160 but really, at the end of the day, all you need is a program for writing text 00:01:04.160 --> 00:01:06.170 because that's what code is-- text. 00:01:06.170 --> 00:01:08.090 Now within this particular program, I'm going 00:01:08.090 --> 00:01:10.550 to have the ability to create one or more files 00:01:10.550 --> 00:01:12.500 via this top portion of the screen. 00:01:12.500 --> 00:01:14.810 And I'm going to do so by diving right in 00:01:14.810 --> 00:01:17.030 and doing this at the bottom of my screen. 00:01:17.030 --> 00:01:20.060 At the bottom of my screen is a so-called terminal window 00:01:20.060 --> 00:01:25.310 and this is a command line interface or CLI interface to the underlying 00:01:25.310 --> 00:01:29.340 computer, be it your Mac or your PC or even some server in the cloud. 00:01:29.340 --> 00:01:32.240 And what I'm going to do here is literally write, "code" and then 00:01:32.240 --> 00:01:36.530 the name of the file that I want to code, for instance, Hello.py. 00:01:36.530 --> 00:01:40.310 As we'll soon see, any program that you write in Python generally has a file 00:01:40.310 --> 00:01:44.210 name that ends in .py to indicate to the computer that it's indeed a program 00:01:44.210 --> 00:01:45.320 written in Python. 00:01:45.320 --> 00:01:48.440 Now you'll see here at the top of my screen, I have a blinking cursor, 00:01:48.440 --> 00:01:51.800 a line one-- which is where the very first line of my code is going to go-- 00:01:51.800 --> 00:01:55.730 and then just a tab that reminds me of the name of this file Hello.py. 00:01:55.730 --> 00:01:58.370 And without even knowing much Python, I'm 00:01:58.370 --> 00:02:00.770 going to write my very first program here as follows-- 00:02:00.770 --> 00:02:02.120 print("hello,world"). 00:02:08.396 --> 00:02:10.729 And you'll see that, at my keyboard, some of my thoughts 00:02:10.729 --> 00:02:11.604 were finished for me. 00:02:11.604 --> 00:02:14.870 I only had to type one parenthesis and the other one automatically appeared, 00:02:14.870 --> 00:02:18.590 and that's just the feature that we'll see of tools like this tool here. 00:02:18.590 --> 00:02:21.080 Now even if you've never programmed before, 00:02:21.080 --> 00:02:25.610 odds are you can guess, infer what this simple program is going to do. 00:02:25.610 --> 00:02:28.250 And it's only one line. print("hello,world"). 00:02:32.030 --> 00:02:33.830 Indeed, when I run this program ultimately, 00:02:33.830 --> 00:02:35.948 it's just going to say, Hello to the world. 00:02:35.948 --> 00:02:37.490 And, in fact, this is a very famous-- 00:02:37.490 --> 00:02:39.440 perhaps the most canonical-- program that you 00:02:39.440 --> 00:02:42.530 can write as your very first program in Python or any other language, 00:02:42.530 --> 00:02:44.280 and so that's what I've done here. 00:02:44.280 --> 00:02:48.230 But on my Mac, my PC, even my phone, I'm generally in the habit, 00:02:48.230 --> 00:02:51.170 like you, of running programs by double clicking an icon 00:02:51.170 --> 00:02:52.760 or just tapping on the screen. 00:02:52.760 --> 00:02:54.920 But I see no such icons here. 00:02:54.920 --> 00:02:58.730 And in fact, that's because my interface to at least my current Mac 00:02:58.730 --> 00:03:02.180 or PC or some server in the cloud, is again only a CLI-- 00:03:02.180 --> 00:03:04.340 command line interface-- which even though it 00:03:04.340 --> 00:03:07.820 might feel like it's a step back from the menus and buttons and icons 00:03:07.820 --> 00:03:10.730 that you and I take for granted every day, you'll find, we think, 00:03:10.730 --> 00:03:13.670 that it's ultimately a much more powerful interface and incredibly 00:03:13.670 --> 00:03:16.920 popular to use among programmers in the real world. 00:03:16.920 --> 00:03:20.245 So to run this program, I'm going to have to use a command 00:03:20.245 --> 00:03:23.120 and I'm going to move my cursor back down to the bottom of the screen 00:03:23.120 --> 00:03:25.790 here where previously I already ran one command-- 00:03:25.790 --> 00:03:30.410 the command Code which has the effect of opening VS Code in my computer, 00:03:30.410 --> 00:03:33.560 and then I passed in the name of the file that I wanted to code up. 00:03:33.560 --> 00:03:36.000 Now I have a chance to type a second command, 00:03:36.000 --> 00:03:38.090 and you'll see I see a second dollar sign. 00:03:38.090 --> 00:03:41.360 Now the dollar sign here doesn't indicate any kind of currency or money, 00:03:41.360 --> 00:03:43.340 it just is the symbol that's generally used 00:03:43.340 --> 00:03:46.610 to indicate your prompt-- where the command line interface wants 00:03:46.610 --> 00:03:47.990 you to put those commands. 00:03:47.990 --> 00:03:51.530 Now the command I can run here is going to be this-- 00:03:51.530 --> 00:03:55.310 I'm going to run Python of Hello.py. 00:03:55.310 --> 00:03:56.490 Now why is that? 00:03:56.490 --> 00:04:00.380 Well, it turns out that when I actually write code in a language like Python, 00:04:00.380 --> 00:04:02.120 it's of course stored in that file-- 00:04:02.120 --> 00:04:07.063 Hello.py, but I need to interpret the code top to bottom, 00:04:07.063 --> 00:04:09.230 left to right so that the computer knows what to do. 00:04:09.230 --> 00:04:10.940 Indeed, at the end of the day, even if you don't really 00:04:10.940 --> 00:04:12.920 know much about computers, you've probably 00:04:12.920 --> 00:04:16.790 heard the computers only understand zeros and ones, the so-called binary 00:04:16.790 --> 00:04:17.390 system. 00:04:17.390 --> 00:04:21.769 Well if that's the case, then something that says "print" and parentheses 00:04:21.769 --> 00:04:25.430 and quote unquote hello world, is not surely zeros and ones. 00:04:25.430 --> 00:04:27.750 We have to somehow translate it into the zeros and ones 00:04:27.750 --> 00:04:29.000 that the computer understands. 00:04:29.000 --> 00:04:33.360 Now fortunately, so long as you've installed such a program in advance, 00:04:33.360 --> 00:04:36.380 there's a program as well as a language called Python. 00:04:36.380 --> 00:04:39.390 So Python is not only a language in which we're going to write code, 00:04:39.390 --> 00:04:42.590 it's also a program otherwise known as an interpreter 00:04:42.590 --> 00:04:46.490 that you install for free on your own Mac or PC or some server in the cloud 00:04:46.490 --> 00:04:50.990 and you can then run that program, that interpreter, passing to it as input 00:04:50.990 --> 00:04:53.870 the name of your file like mine here, Hello.py. 00:04:53.870 --> 00:04:56.000 And then that program, that interpreter, will 00:04:56.000 --> 00:04:59.210 handle the process of reading it top to bottom, left to right 00:04:59.210 --> 00:05:02.210 and translating it effectively into those zeros and ones 00:05:02.210 --> 00:05:04.170 that the computer can understand. 00:05:04.170 --> 00:05:05.360 So let's do just that. 00:05:05.360 --> 00:05:07.190 Let me go back to VS Code here. 00:05:07.190 --> 00:05:11.030 I already typed out Python of Hello.py but I didn't get hit Enter. 00:05:11.030 --> 00:05:13.430 And that's what's now going to kick off this command 00:05:13.430 --> 00:05:16.190 and hopefully, if I didn't mess any of this up, 00:05:16.190 --> 00:05:20.370 I should see my very first program's output to the screen. 00:05:20.370 --> 00:05:23.480 And voila, hello, world. 00:05:23.480 --> 00:05:25.970 So if you too have typed exactly that same code 00:05:25.970 --> 00:05:28.400 and have executed exactly that same command, 00:05:28.400 --> 00:05:32.840 you will have written your very first program in this case in Python. 00:05:32.840 --> 00:05:34.790 Well now let's take a step back and consider, 00:05:34.790 --> 00:05:37.190 what is it that we actually just did and what 00:05:37.190 --> 00:05:38.930 is it we're looking here on the screen? 00:05:38.930 --> 00:05:41.450 Well first and foremost, in most any programming language, 00:05:41.450 --> 00:05:43.950 you tend to have access to what are called functions. 00:05:43.950 --> 00:05:46.460 A function is like an action or a verb that 00:05:46.460 --> 00:05:48.800 lets you do something in the program. 00:05:48.800 --> 00:05:52.730 And generally speaking, any language comes with some predetermined set 00:05:52.730 --> 00:05:57.097 of functions-- some very basic actions or verbs that the computer will already 00:05:57.097 --> 00:05:59.180 know how to do for you, that the language, really, 00:05:59.180 --> 00:06:00.530 will know how to do for you. 00:06:00.530 --> 00:06:04.640 And you, the programmer, the human, can use those functions at will 00:06:04.640 --> 00:06:07.020 to get the computer to do those things. 00:06:07.020 --> 00:06:11.835 Now the program in question here, Hello.py is using one function. 00:06:11.835 --> 00:06:13.460 And you could perhaps guess what it is. 00:06:13.460 --> 00:06:16.760 That function is, of course, going to be this function print 00:06:16.760 --> 00:06:19.430 and that print function, of course, doesn't 00:06:19.430 --> 00:06:22.340 print some preordained string of text. 00:06:22.340 --> 00:06:26.240 That is to say, it prints whatever it is you want it to print. 00:06:26.240 --> 00:06:29.600 And here too, do we have another piece of terminology in the world 00:06:29.600 --> 00:06:31.430 of programming, namely arguments. 00:06:31.430 --> 00:06:36.830 An argument is an input to a function that somehow influences its behavior. 00:06:36.830 --> 00:06:38.660 The people who invented Python, of course, 00:06:38.660 --> 00:06:40.790 didn't necessarily know what it is you and I 00:06:40.790 --> 00:06:43.850 are going to want to print to the screen, so they designed this print 00:06:43.850 --> 00:06:46.580 function using these parentheses with the ability 00:06:46.580 --> 00:06:49.340 to take as input some string of text, be it 00:06:49.340 --> 00:06:52.250 in English or any other human language, that is 00:06:52.250 --> 00:06:56.540 what you want this function ultimately to print onto the screen. 00:06:56.540 --> 00:06:59.640 And what is it that the program is ultimately doing on the screen? 00:06:59.640 --> 00:07:01.070 Well, it's printing, of course. 00:07:01.070 --> 00:07:03.230 It's showing us hello, world on the screen. 00:07:03.230 --> 00:07:05.743 And that's generally in programming known as a side effect. 00:07:05.743 --> 00:07:07.160 It can be visual, it can be audio. 00:07:07.160 --> 00:07:09.470 In this case, it's something that appears on the screen 00:07:09.470 --> 00:07:12.690 and functions, therefore, can indeed have these side effects. 00:07:12.690 --> 00:07:15.650 One of the things they can do as this verb or action is 00:07:15.650 --> 00:07:19.100 to display on the screen as a side effect, something like those words 00:07:19.100 --> 00:07:20.240 that we wanted-- 00:07:20.240 --> 00:07:21.870 hello, world. 00:07:21.870 --> 00:07:25.080 So that's my first program and, you know, I'm feeling pretty good. 00:07:25.080 --> 00:07:26.570 Everything worked as planned. 00:07:26.570 --> 00:07:28.490 I didn't make any mistakes, but, honestly, 00:07:28.490 --> 00:07:30.560 when you're learning how to program and even 00:07:30.560 --> 00:07:34.250 once you've learned how to program years later, you're going to make mistakes. 00:07:34.250 --> 00:07:36.615 And those mistakes, of course, are referred 00:07:36.615 --> 00:07:38.990 to a term you might already know, which is that of a bug. 00:07:38.990 --> 00:07:42.230 A bug is a mistake in a program and they can take so many forms. 00:07:42.230 --> 00:07:46.460 And take comfort, perhaps, in knowing that over the coming weeks, 00:07:46.460 --> 00:07:48.450 you're going to make so many mistakes. 00:07:48.450 --> 00:07:51.320 You're going to have so many bugs in your code, just like I did 00:07:51.320 --> 00:07:53.490 and just as I still do. 00:07:53.490 --> 00:07:55.610 And those bugs themselves are just mistakes 00:07:55.610 --> 00:07:57.230 that are problems for you to solve. 00:07:57.230 --> 00:07:59.540 And over the weeks to come, we're going to give you 00:07:59.540 --> 00:08:03.760 a lot of tools both mental and technical via which you can solve those problems. 00:08:03.760 --> 00:08:07.010 But just don't get discouraged if when writing your program for the first time 00:08:07.010 --> 00:08:11.630 it doesn't even work that first time, it will with time, with practice, 00:08:11.630 --> 00:08:12.810 and with experience. 00:08:12.810 --> 00:08:15.200 So let me deliberately now make a mistake 00:08:15.200 --> 00:08:18.710 that there was a non-zero chance I might have done accidentally already, 00:08:18.710 --> 00:08:19.760 but I got lucky. 00:08:19.760 --> 00:08:22.280 Let me go ahead and just suppose I forgot 00:08:22.280 --> 00:08:24.950 to include something like the closing parenthesis 00:08:24.950 --> 00:08:26.570 at the end of this line of code. 00:08:26.570 --> 00:08:30.451 The code is almost correct, it's like 99% of the way there, 00:08:30.451 --> 00:08:32.659 but now that I've pointed it out, it's pretty obvious 00:08:32.659 --> 00:08:34.820 that it's missing that closed parenthesis. 00:08:34.820 --> 00:08:39.530 But even little, seemingly minor details like that, that you and I as humans 00:08:39.530 --> 00:08:40.740 wouldn't really care about. 00:08:40.740 --> 00:08:44.300 And if you're sending an email or a text message, whatever, it's just a typo. 00:08:44.300 --> 00:08:45.605 It's not that big a deal. 00:08:45.605 --> 00:08:47.480 It is going to be a big deal to the computer. 00:08:47.480 --> 00:08:49.230 A computer is going to take you literally, 00:08:49.230 --> 00:08:53.210 and if you don't finish your thought in the way the language expects, 00:08:53.210 --> 00:08:55.380 it's not going to necessarily run at all. 00:08:55.380 --> 00:08:56.112 So let's do this. 00:08:56.112 --> 00:08:58.820 I'm going to go ahead here and clear my screen down at the bottom 00:08:58.820 --> 00:09:01.340 just so I can start fresh, and I'm going to go ahead and run 00:09:01.340 --> 00:09:05.420 this version of my program after having made that change by deleting 00:09:05.420 --> 00:09:06.410 the parenthesis. 00:09:06.410 --> 00:09:10.490 I'm going to go ahead and type Python again of Hello.py and this time 00:09:10.490 --> 00:09:13.040 when I hit Enter, I'm hoping I'm going to see hello, world, 00:09:13.040 --> 00:09:16.850 but here we have an error on the screen, a so-called syntax 00:09:16.850 --> 00:09:21.140 error, which refers to my having made a mistake at my keyboard. 00:09:21.140 --> 00:09:24.030 And this one, fortunately, is pretty straightforward. 00:09:24.030 --> 00:09:28.410 It indeed says that this open parenthesis was never closed. 00:09:28.410 --> 00:09:30.945 And so that's probably pretty intuitive. 00:09:30.945 --> 00:09:33.320 Now what I need to do, I need to, of course, to close it. 00:09:33.320 --> 00:09:36.530 Unfortunately, sometimes the error messages we'll see in the coming weeks 00:09:36.530 --> 00:09:38.840 are not going to be nearly that user-friendly. 00:09:38.840 --> 00:09:41.720 But there too again, with experience, with practice, will you 00:09:41.720 --> 00:09:44.360 get better at debugging such programs. 00:09:44.360 --> 00:09:46.650 Let me now make sure that I indeed fixed it correctly. 00:09:46.650 --> 00:09:50.420 Let me go ahead and run now Hello.py and hit Enter and, voila, 00:09:50.420 --> 00:09:51.890 we're back in business. 00:09:51.890 --> 00:09:55.430 Well let me pause here and see if we have any questions now 00:09:55.430 --> 00:10:02.480 about Python itself, writing, or running even the simplest of these programs. 00:10:02.480 --> 00:10:06.890 AUDIENCE: Could I write code inside a word or, for example, Microsoft Excel? 00:10:06.890 --> 00:10:09.473 And what's the barrier to doing that? 00:10:09.473 --> 00:10:11.390 DAVID MALAN: A really good question, and allow 00:10:11.390 --> 00:10:14.630 me to very explicitly say to the entire internet 00:10:14.630 --> 00:10:17.810 that you should not write code with Microsoft Word. 00:10:17.810 --> 00:10:20.480 I mentioned that only because it's a tool via which 00:10:20.480 --> 00:10:23.283 you can write text and code is, at the end of the day, just text. 00:10:23.283 --> 00:10:24.950 But it's not the right tool for the job. 00:10:24.950 --> 00:10:27.890 We don't need bold facing, underlining, paragraphs and the like. 00:10:27.890 --> 00:10:31.580 We generally want something much simpler than Microsoft Word or Google Docs. 00:10:31.580 --> 00:10:36.110 And so VS Code is an example of just a more general purpose text editor. 00:10:36.110 --> 00:10:39.110 Its purpose in life is to allow you, the human, to edit text. 00:10:39.110 --> 00:10:42.050 Nowadays these text editors come with many more features. 00:10:42.050 --> 00:10:44.600 In fact, you'll notice that even in my code here, 00:10:44.600 --> 00:10:47.570 even though it's just one line, there's a bit of color to it. 00:10:47.570 --> 00:10:49.910 The word "print" for me is appearing in blue. 00:10:49.910 --> 00:10:51.050 The parentheses are black. 00:10:51.050 --> 00:10:54.290 And we'll see as we write more lines of code, more and more of the lines 00:10:54.290 --> 00:10:56.630 will come to life in various colors. 00:10:56.630 --> 00:10:58.993 Now that's just one feature of a text editor. 00:10:58.993 --> 00:11:01.910 We'll see too that it has features like this built-in terminal window. 00:11:01.910 --> 00:11:05.120 It's going to have a built-in tool for debugging or finding problems 00:11:05.120 --> 00:11:05.780 with code. 00:11:05.780 --> 00:11:07.760 And it's just a very popular tool nowadays, 00:11:07.760 --> 00:11:09.560 but there are many, many others out there. 00:11:09.560 --> 00:11:11.900 You're welcome to use them for this course and beyond. 00:11:11.900 --> 00:11:14.120 We just happen to use this one in large part 00:11:14.120 --> 00:11:18.980 too because you can also use VS Code nowadays for free in the cloud. 00:11:18.980 --> 00:11:22.190 How about one other question here on programming with Python 00:11:22.190 --> 00:11:24.950 or hello, world or syntax more generally? 00:11:24.950 --> 00:11:28.850 AUDIENCE: Yeah I was trying to ask if it's not 00:11:28.850 --> 00:11:31.923 possible to run the computer using the terminal window? 00:11:31.923 --> 00:11:33.590 DAVID MALAN: I think I heard is it not-- 00:11:33.590 --> 00:11:37.530 if it's possible to run the program without the terminal window? 00:11:37.530 --> 00:11:38.030 Are you-- 00:11:38.030 --> 00:11:38.540 AUDIENCE: Yes, sir. 00:11:38.540 --> 00:11:39.870 DAVID MALAN: OK, you froze for me again. 00:11:39.870 --> 00:11:41.730 But let me infer what the question is. 00:11:41.730 --> 00:11:44.660 So in this environment, as I've configured my computer, 00:11:44.660 --> 00:11:48.320 I can only run these Python programs via the terminal window. 00:11:48.320 --> 00:11:51.140 Now that's good for me, the programmer, or the person who's 00:11:51.140 --> 00:11:53.390 trying to learn how to program, but it's not very good 00:11:53.390 --> 00:11:57.050 if you want to ship this software and have other people use your actual code. 00:11:57.050 --> 00:12:01.550 You can absolutely write programs and then allow other people to use, 00:12:01.550 --> 00:12:05.300 not a command line interface, but a graphical user interface or GUI-- 00:12:05.300 --> 00:12:08.390 G-U-I. This is just one mechanism and perhaps, I think, 00:12:08.390 --> 00:12:10.700 the best one with which to start writing code 00:12:10.700 --> 00:12:14.045 because eventually it's going to give us a lot more control. 00:12:14.045 --> 00:12:15.920 Allow me to forge ahead here, but please feel 00:12:15.920 --> 00:12:19.820 free to continue asking questions along the way if only via the chat. 00:12:19.820 --> 00:12:23.690 Let's consider now how we might go about improving this program. 00:12:23.690 --> 00:12:27.530 Let's go about improving this program to make it a little more interactive 00:12:27.530 --> 00:12:30.740 and not just assume that everyone is going to want to be greeted 00:12:30.740 --> 00:12:32.120 more generically as hello, world. 00:12:32.120 --> 00:12:35.120 Let's see if I can't get this program to say something like Hello, David 00:12:35.120 --> 00:12:40.280 or Hello, Jeremiah or Hello, Horatio or whatever the actual user's name is. 00:12:40.280 --> 00:12:43.670 Well to do this I'm going to go back up to Hello to pi 00:12:43.670 --> 00:12:46.950 and I'm going to add another line of code at the very top that simply says, 00:12:46.950 --> 00:12:52.490 for instance, what's your name, quote unquote with an extra space at the end. 00:12:52.490 --> 00:12:55.530 So I'm printing to the user asking them a question for some input, 00:12:55.530 --> 00:12:58.940 but now I need another function to actually get input from the user. 00:12:58.940 --> 00:13:02.550 And, perfectly, enough Python comes with a function named input. 00:13:02.550 --> 00:13:06.470 So here I'm going to go ahead and call a function input, open paren, 00:13:06.470 --> 00:13:07.400 close paren. 00:13:07.400 --> 00:13:11.000 And that's going to prompt the user with just a blinking cursor waiting 00:13:11.000 --> 00:13:12.440 for them to type something in. 00:13:12.440 --> 00:13:15.860 Now it turns out, if I read the documentation for the input function, 00:13:15.860 --> 00:13:18.210 it actually takes an argument itself. 00:13:18.210 --> 00:13:21.740 I don't need to use "print" separately and then prompt the user for input. 00:13:21.740 --> 00:13:25.100 So I can actually simplify this code before we even use it. 00:13:25.100 --> 00:13:28.430 I'm going to go ahead here and take that same string from print, 00:13:28.430 --> 00:13:30.800 put it as an argument to the input function, 00:13:30.800 --> 00:13:32.383 and get rid of the "print" altogether. 00:13:32.383 --> 00:13:34.967 And, in fact, that "print" would have added a new line anyway. 00:13:34.967 --> 00:13:37.340 So now I've just got a prompt where the user's cursor is 00:13:37.340 --> 00:13:41.030 going to end up blinking at the end of the line asking them, what's your name? 00:13:41.030 --> 00:13:46.580 In my terminal window I'm going to run Python of Hello.py, Enter. 00:13:46.580 --> 00:13:47.150 OK. 00:13:47.150 --> 00:13:48.150 We're making progress. 00:13:48.150 --> 00:13:51.280 It seems that this new function input is indeed prompting me, the human, 00:13:51.280 --> 00:13:51.780 for input. 00:13:51.780 --> 00:13:53.155 So I'm going to type in my name-- 00:13:53.155 --> 00:13:54.290 David-- and hit Enter. 00:13:54.290 --> 00:13:57.440 Unfortunately, it doesn't really do anything with my name, 00:13:57.440 --> 00:13:59.240 it just outputs it immediately. 00:13:59.240 --> 00:14:01.160 All right, well, I could fix this, right? 00:14:01.160 --> 00:14:05.480 I could go up to line 2 and I could change "world" to "David," 00:14:05.480 --> 00:14:10.310 and then back in my terminal window here I can do Python of Hello.py, Enter. 00:14:10.310 --> 00:14:11.150 What's your name? 00:14:11.150 --> 00:14:12.410 David, Enter. 00:14:12.410 --> 00:14:13.105 And there we go. 00:14:13.105 --> 00:14:14.480 All right now I'm up and running. 00:14:14.480 --> 00:14:17.520 Now my program is working as intended. 00:14:17.520 --> 00:14:21.410 Of course, this isn't really working as intended here. 00:14:21.410 --> 00:14:25.070 Let me go ahead and try pretending to be my colleague, Carter here. 00:14:25.070 --> 00:14:26.760 Well Carter's name is this. 00:14:26.760 --> 00:14:29.927 I'm going to go ahead and hit Enter and I'll see, of course, Hello, Carter-- 00:14:29.927 --> 00:14:32.520 well, obviously not, because I've hardcoded, so to speak, 00:14:32.520 --> 00:14:35.010 I've written literally my name inside of the string. 00:14:35.010 --> 00:14:40.040 So we need some way now of actually getting back what the user's input is 00:14:40.040 --> 00:14:41.780 and doing something with it ultimately. 00:14:41.780 --> 00:14:44.930 And for this we're going to leverage another feature of programming, 00:14:44.930 --> 00:14:47.510 specifically a feature of some functions, which is that they 00:14:47.510 --> 00:14:49.850 can have return values as well. 00:14:49.850 --> 00:14:52.700 If you think of input as being, again, this action, 00:14:52.700 --> 00:14:55.880 this verb-- you can actually personify it as maybe a person, 00:14:55.880 --> 00:14:58.130 like a friend of yours that you've asked a question of 00:14:58.130 --> 00:15:00.797 and you've asked your friend to go get input from someone else-- 00:15:00.797 --> 00:15:02.210 go ask that person their name. 00:15:02.210 --> 00:15:05.630 And if your friend comes back knowing that person's name, well, 00:15:05.630 --> 00:15:08.357 wouldn't it be nice if they handed that name back to you? 00:15:08.357 --> 00:15:10.940 That's kind of what we need metaphorically the function to do, 00:15:10.940 --> 00:15:15.200 is get the user's input and then hand it back to me so that I, the programmer, 00:15:15.200 --> 00:15:16.610 can do something with it. 00:15:16.610 --> 00:15:19.280 But if it's going to be handed back to me, 00:15:19.280 --> 00:15:23.060 I kind of want to put it somewhere so that I can then print it back 00:15:23.060 --> 00:15:23.720 on the screen. 00:15:23.720 --> 00:15:26.970 I need to do the equivalent of take out like a piece of paper or Post-It note, 00:15:26.970 --> 00:15:31.040 write down on this piece of paper what it is the human has said, 00:15:31.040 --> 00:15:34.650 so that I can then feed it into as input that print function. 00:15:34.650 --> 00:15:38.120 And to do that, we're going to need one more feature of programming, namely 00:15:38.120 --> 00:15:38.960 variables. 00:15:38.960 --> 00:15:42.410 And odds are, most everyone's familiar with variables from math class 00:15:42.410 --> 00:15:45.380 way back when-- x and y and z and the like. 00:15:45.380 --> 00:15:48.110 Well, programming has that same capability, this ability 00:15:48.110 --> 00:15:51.560 to create a variable-- in this case, in the computer's memory-- 00:15:51.560 --> 00:15:53.100 not just on a piece of paper. 00:15:53.100 --> 00:15:55.620 And that variable can store a value-- 00:15:55.620 --> 00:15:58.910 a number, some text, even an image or video or more. 00:15:58.910 --> 00:16:06.740 A variable is just a container for some value inside of a computer 00:16:06.740 --> 00:16:08.300 or inside of your own program. 00:16:08.300 --> 00:16:11.303 So how do I go about expressing myself in this way? 00:16:11.303 --> 00:16:13.220 Well I think what I'm going to do is introduce 00:16:13.220 --> 00:16:16.730 a variable that's a little more interestingly named than x or y. 00:16:16.730 --> 00:16:19.970 I could just say this-- x = input. 00:16:19.970 --> 00:16:23.780 But I'm going to use a better name than a typical mathematical variable here 00:16:23.780 --> 00:16:26.240 and I'm going to literally call my variable "name," why? 00:16:26.240 --> 00:16:29.073 Well in programming, because I have a whole keyboard in front of me, 00:16:29.073 --> 00:16:32.150 I can use more descriptive terms to describe what it is I'm writing. 00:16:32.150 --> 00:16:36.590 And now, though, there's an opportunity to consider a specific piece of syntax. 00:16:36.590 --> 00:16:39.470 We've seen parentheses, we've seen quotes, all of which 00:16:39.470 --> 00:16:42.020 are necessary when passing inputs to a function, 00:16:42.020 --> 00:16:47.810 but this equal sign here that's in between input on the right and name 00:16:47.810 --> 00:16:49.820 on the left is actually important. 00:16:49.820 --> 00:16:52.490 And it's technically not an equal sign per se. 00:16:52.490 --> 00:16:56.060 It doesn't mean equality as much as it means assignment. 00:16:56.060 --> 00:16:59.000 So in Python and many programming languages, 00:16:59.000 --> 00:17:01.610 a single equal sign is the assignment operator 00:17:01.610 --> 00:17:03.860 and what that means specifically is that, you 00:17:03.860 --> 00:17:08.839 want to assign from right to left whatever the user's input is. 00:17:08.839 --> 00:17:14.540 So the equal sign copies from the right to the left whatever the return 00:17:14.540 --> 00:17:17.420 value of the function on the right is. 00:17:17.420 --> 00:17:20.670 So again, the input function clearly gets input from the user. 00:17:20.670 --> 00:17:24.140 That's why I was able to type my name or Carter's, but it also 00:17:24.140 --> 00:17:29.390 sort of behind the scenes hands that value, that return value, back to me 00:17:29.390 --> 00:17:30.230 the programmer. 00:17:30.230 --> 00:17:33.680 And if I use an equal sign and a variable, no matter what I call it, 00:17:33.680 --> 00:17:38.460 I can store that input in that variable so as to reuse it later. 00:17:38.460 --> 00:17:40.670 So now, sitting in the computer's memory somewhere, 00:17:40.670 --> 00:17:44.870 is a container containing "David" quote, unquote or "Carter" quote, 00:17:44.870 --> 00:17:47.490 unquote, or whatever the human has typed in. 00:17:47.490 --> 00:17:49.280 But here it's easy to make a mistake. 00:17:49.280 --> 00:17:53.850 Suppose I decide to try to print that name and so 00:17:53.850 --> 00:17:57.800 I kind of on a hunch type in this, hello, name. 00:17:57.800 --> 00:18:00.440 Just kind of plugging in the name of the variable. 00:18:00.440 --> 00:18:05.300 Well let me go ahead here and run Python of Hello.py and hit Enter. 00:18:05.300 --> 00:18:07.040 That's going to prompt me for my name. 00:18:07.040 --> 00:18:08.207 And let me type in my name-- 00:18:08.207 --> 00:18:10.440 D-A-V-I-D. But I haven't hit Enter yet. 00:18:10.440 --> 00:18:15.350 And perhaps via the chat, what's going to happen here when I now hit Enter? 00:18:15.350 --> 00:18:17.840 I'm hoping it says, Hello, David. 00:18:17.840 --> 00:18:22.580 I'd be OK if it says Hello, world, but I don't want it to say what it's actually 00:18:22.580 --> 00:18:25.370 going to say and, yep, what we're seeing in the chat is, 00:18:25.370 --> 00:18:28.640 well, it's probably going to say literally Hello, name. 00:18:28.640 --> 00:18:30.030 So that's not quite right. 00:18:30.030 --> 00:18:34.250 So we need another way of printing out the value inside of that variable 00:18:34.250 --> 00:18:36.785 rather than just this word "name." 00:18:36.785 --> 00:18:38.910 Well let me try this in a couple of different ways. 00:18:38.910 --> 00:18:40.890 Let me try this as follows-- 00:18:40.890 --> 00:18:44.390 let me go ahead and maybe undo this because I've gotten pretty good already 00:18:44.390 --> 00:18:45.550 at saying Hello. 00:18:45.550 --> 00:18:48.050 So let's draw that line in the sand and just say, all right, 00:18:48.050 --> 00:18:50.360 let's get at least get Hello comma out the door. 00:18:50.360 --> 00:18:53.790 Let's now print name and just on a hunch, I'm going to try this. 00:18:53.790 --> 00:18:55.115 I'm going to use print again-- 00:18:55.115 --> 00:18:57.740 because you can use these functions as many times as you need-- 00:18:57.740 --> 00:19:02.660 and I'm going to pass to the print function the variable called name. 00:19:02.660 --> 00:19:04.730 But notice I'm being a little clever now. 00:19:04.730 --> 00:19:07.970 I'm not putting it in double quotes because we've seen already that double 00:19:07.970 --> 00:19:10.610 quotes means literally print out N-A-M-E. 00:19:10.610 --> 00:19:13.700 I'm getting rid of the quotes this time in hopes that, 00:19:13.700 --> 00:19:19.440 now by passing the variable called name to the function called print it will, 00:19:19.440 --> 00:19:23.480 in fact, go about printing the contents of that variable that is, 00:19:23.480 --> 00:19:24.808 its so-called value. 00:19:24.808 --> 00:19:26.600 All right, let's go ahead and do this here. 00:19:26.600 --> 00:19:29.030 Python of Hello.py, Enter. 00:19:29.030 --> 00:19:30.020 What's your name? 00:19:30.020 --> 00:19:30.590 David. 00:19:30.590 --> 00:19:35.520 And now, crossing my fingers still, I see Hello comma David. 00:19:35.520 --> 00:19:36.020 All right. 00:19:36.020 --> 00:19:38.090 So it's not the best program. 00:19:38.090 --> 00:19:40.670 I'm kind of cutting some corners here, so to speak. 00:19:40.670 --> 00:19:44.128 I'm saying Hello, David on two separate lines. 00:19:44.128 --> 00:19:45.920 So it's not as elegant, it's not as pretty, 00:19:45.920 --> 00:19:48.950 it's not as grammatically appropriate in English as just saying it 00:19:48.950 --> 00:19:52.820 all in one breath on one line, but at least I've solved the problem, just not 00:19:52.820 --> 00:19:54.020 very well yet. 00:19:54.020 --> 00:19:56.390 But let me take a step back now and perhaps introduce 00:19:56.390 --> 00:19:59.070 a couple of other concepts with which we should be familiar, 00:19:59.070 --> 00:20:03.260 which is as our programs get longer and they're no longer just one line or two 00:20:03.260 --> 00:20:07.370 or even three, eventually our programs are going to become dozens of lines, 00:20:07.370 --> 00:20:09.020 maybe even hundreds of lines long. 00:20:09.020 --> 00:20:11.990 Let's set the stage for success moving forward. 00:20:11.990 --> 00:20:14.840 It turns out that Python and a lot of programming languages 00:20:14.840 --> 00:20:17.120 also support something called comments. 00:20:17.120 --> 00:20:21.200 Comments are notes to yourself in your code 00:20:21.200 --> 00:20:24.260 and you include comments by way of a special symbol-- in Python 00:20:24.260 --> 00:20:26.150 it's going to be the hash symbol, typically-- 00:20:26.150 --> 00:20:27.980 and that allows you to write the equivalent 00:20:27.980 --> 00:20:30.950 of a note to yourself but in a way that's not going to break your code. 00:20:30.950 --> 00:20:33.380 The computer actually ignores your comment. 00:20:33.380 --> 00:20:36.030 It's just there for you, it's just there for your teacher, 00:20:36.030 --> 00:20:38.030 it's just there for your colleague with whom 00:20:38.030 --> 00:20:40.020 you're sharing ultimately that code. 00:20:40.020 --> 00:20:42.320 So if I go back to VS Code here and I just 00:20:42.320 --> 00:20:46.040 want to add some comments to this program to explain to my teacher, 00:20:46.040 --> 00:20:49.325 to myself, to my colleagues what this program is doing, 00:20:49.325 --> 00:20:50.700 well, let's go ahead and do that. 00:20:50.700 --> 00:20:54.020 I'm going to go at the very top of my program and on line 1 00:20:54.020 --> 00:20:56.990 now I'm going to move that original line of code down a bit, 00:20:56.990 --> 00:21:00.530 I'm going to add a hash, and I'm going to say something like this, 00:21:00.530 --> 00:21:03.210 ask user for their name. 00:21:03.210 --> 00:21:05.040 Now, I don't have to use that language. 00:21:05.040 --> 00:21:06.950 I don't have to use that text. 00:21:06.950 --> 00:21:08.910 I could use any human language whatsoever. 00:21:08.910 --> 00:21:10.250 It doesn't have to be English. 00:21:10.250 --> 00:21:14.120 But I'm going to now, below that, just say something like this-- 00:21:14.120 --> 00:21:16.012 say Hello to user. 00:21:16.012 --> 00:21:17.720 And you'll notice that VS Code by default 00:21:17.720 --> 00:21:19.302 is kind of graying out my comments. 00:21:19.302 --> 00:21:22.010 They're no longer blue, there's no red, there's no color in them. 00:21:22.010 --> 00:21:24.240 And that's just because they're notes to myself 00:21:24.240 --> 00:21:26.730 and the computer ultimately is going to ignore them. 00:21:26.730 --> 00:21:29.350 But what we have now is two comments-- ask user 00:21:29.350 --> 00:21:32.380 for their name and then a second comment, say Hello to user. 00:21:32.380 --> 00:21:35.590 And I've just kind of commented each chunk of code, 00:21:35.590 --> 00:21:40.180 like each line or lines plural of code, that are doing something noteworthy. 00:21:40.180 --> 00:21:40.750 Why? 00:21:40.750 --> 00:21:43.120 Well, tomorrow morning when I wake up having 00:21:43.120 --> 00:21:47.740 slept for quite some time, forgotten what it is I did the previous day, 00:21:47.740 --> 00:21:49.840 it's convenient with comments to just see 00:21:49.840 --> 00:21:52.510 in English or your own human language what 00:21:52.510 --> 00:21:55.810 it is this program is doing so that you don't have to read the code itself 00:21:55.810 --> 00:21:59.200 and, better yet, if there's maybe a mistake down the road, 00:21:59.200 --> 00:22:02.740 you can read what your intention was and then you can look at the code 00:22:02.740 --> 00:22:06.050 and figure out if your code is now doing what you intended. 00:22:06.050 --> 00:22:08.920 So this isn't really necessary for a program this small. 00:22:08.920 --> 00:22:11.287 It's pretty obvious with just one or two or three lines 00:22:11.287 --> 00:22:12.370 what the program is doing. 00:22:12.370 --> 00:22:14.668 It's just as fast to read the code than the comments, 00:22:14.668 --> 00:22:16.960 but getting into this habit is generally a good thing-- 00:22:16.960 --> 00:22:21.220 to comment your code every one or a few lines so as to remind yourself 00:22:21.220 --> 00:22:24.250 and others what it is your intent and your code is doing. 00:22:24.250 --> 00:22:26.590 What's nice about comments too is this-- 00:22:26.590 --> 00:22:30.940 comments can also serve to be sort of a to-do list for yourself. 00:22:30.940 --> 00:22:33.850 There's this notion in programming of pseudocode. 00:22:33.850 --> 00:22:35.350 Pseudocode isn't a formal thing. 00:22:35.350 --> 00:22:37.300 It's not one specific language. 00:22:37.300 --> 00:22:40.090 It's just using English or your own human language 00:22:40.090 --> 00:22:44.590 to express your thoughts succinctly, methodically, algorithmically, 00:22:44.590 --> 00:22:45.460 so to speak. 00:22:45.460 --> 00:22:48.070 But pseudocode, therefore, because it's not Python 00:22:48.070 --> 00:22:51.130 and it's not necessarily English, it just kind of allows 00:22:51.130 --> 00:22:53.520 you to outline your program even in advance. 00:22:53.520 --> 00:22:56.532 So for instance, if I wasn't sure today how 00:22:56.532 --> 00:22:58.240 I wanted to go about writing this program 00:22:58.240 --> 00:23:01.720 but I didn't know what I wanted to do, I could have started today 00:23:01.720 --> 00:23:04.570 by just writing this in Hello.py. 00:23:04.570 --> 00:23:07.870 No code, I could have written just a couple of comments to myself-- 00:23:07.870 --> 00:23:09.460 Step 1, ask user for their name. 00:23:09.460 --> 00:23:11.440 Step 2, say Hello to user. 00:23:11.440 --> 00:23:15.520 Then once I've outlined my program in pseudocode, then I can go in there 00:23:15.520 --> 00:23:18.190 and say, all right, how do I ask the user for their name? 00:23:18.190 --> 00:23:21.910 Well, I can do input "what's your name" question? 00:23:21.910 --> 00:23:26.080 And then on the left here, I can maybe put a variable and assign it to that. 00:23:26.080 --> 00:23:27.730 OK, how do I say Hello to the user? 00:23:27.730 --> 00:23:30.280 Well, I know I can use print to say things on the screen. 00:23:30.280 --> 00:23:32.920 Let me say hello, and let me-- 00:23:32.920 --> 00:23:35.210 OK, let me now print the person's name. 00:23:35.210 --> 00:23:38.960 So again, pseudocode is a nice way of structuring your to-do list, 00:23:38.960 --> 00:23:41.680 especially if you have no idea how to write the code, 00:23:41.680 --> 00:23:45.993 because it breaks a bigger program down into small bite-sized tasks. 00:23:45.993 --> 00:23:48.160 All right, let me pause here to see if there are now 00:23:48.160 --> 00:23:56.390 any questions on comments, pseudocode, return values, or variables. 00:23:56.390 --> 00:23:59.170 Any questions we can clear up here? 00:23:59.170 --> 00:24:02.500 AUDIENCE: Yeah, my question is does the function input 00:24:02.500 --> 00:24:06.843 work for any type of information, or only for words? 00:24:06.843 --> 00:24:08.510 DAVID MALAN: Yeah, really good question. 00:24:08.510 --> 00:24:12.070 So according to its documentation, and we'll look more at formal documentation 00:24:12.070 --> 00:24:14.290 soon, input is going to expect what's called 00:24:14.290 --> 00:24:16.900 a string, that is a sequence of text, be it 00:24:16.900 --> 00:24:19.030 in English or any other human language. 00:24:19.030 --> 00:24:23.660 But it's indeed going to be expecting text with which to prompt the user. 00:24:23.660 --> 00:24:24.340 A good question. 00:24:24.340 --> 00:24:26.632 How about another question from the group, if we could? 00:24:26.632 --> 00:24:30.520 AUDIENCE: I wanted to ask how would I make a several line comment? 00:24:30.520 --> 00:24:32.770 DAVID MALAN: Oh, how do you do many lines of comments, 00:24:32.770 --> 00:24:34.000 if I'm hearing you correctly? 00:24:34.000 --> 00:24:34.330 AUDIENCE: Yes. 00:24:34.330 --> 00:24:35.290 DAVID MALAN: Sure. 00:24:35.290 --> 00:24:38.380 You would just keep doing them like this. 00:24:38.380 --> 00:24:43.300 You just prefix each of the lines with a hash symbol, like I'm doing here. 00:24:43.300 --> 00:24:46.990 There is another technique for doing multi-line comments in Python that 00:24:46.990 --> 00:24:48.670 actually tend to have special meaning. 00:24:48.670 --> 00:24:53.650 You can do three double quotes like this and then anything in between here 00:24:53.650 --> 00:24:54.910 is a comment. 00:24:54.910 --> 00:24:55.960 That's another technique. 00:24:55.960 --> 00:24:57.502 Or you can use single quotes as well. 00:24:57.502 --> 00:25:00.257 But more on those, I think, another time. 00:25:00.257 --> 00:25:02.590 All right, well, you don't mind, let me forge ahead here 00:25:02.590 --> 00:25:05.290 and see how we might improve this program further 00:25:05.290 --> 00:25:07.570 and also introduce a few other features that we might 00:25:07.570 --> 00:25:10.100 want to take into account over time. 00:25:10.100 --> 00:25:13.270 So it turns out that we can certainly improve on this program 00:25:13.270 --> 00:25:17.020 because it's a little disappointing that I'm cutting this corner 00:25:17.020 --> 00:25:20.680 and saying Hello comma and then on a new line printing out name. 00:25:20.680 --> 00:25:21.700 Like we can do better. 00:25:21.700 --> 00:25:24.760 And most programs you use on your phone or your laptop certainly 00:25:24.760 --> 00:25:26.810 keep text together when people want. 00:25:26.810 --> 00:25:28.243 So how can we go about doing that? 00:25:28.243 --> 00:25:29.660 Well there's a few different ways. 00:25:29.660 --> 00:25:32.890 And in fact, the goal here is not so much to solve this one problem, 00:25:32.890 --> 00:25:35.290 but to demonstrate and emphasize that in programming-- 00:25:35.290 --> 00:25:38.080 Python and other languages-- there's so many ways 00:25:38.080 --> 00:25:40.690 sometimes to solve the same problem. 00:25:40.690 --> 00:25:42.830 And here's one way to solve this problem. 00:25:42.830 --> 00:25:48.100 Let me go in here and let me go ahead now and say hello, 00:25:48.100 --> 00:25:52.450 and let me just add to the end of that the user's name. 00:25:52.450 --> 00:25:54.980 So I'm using + in kind of an interesting way. 00:25:54.980 --> 00:25:56.560 This is not addition, per se. 00:25:56.560 --> 00:25:59.290 I'm not adding numbers, obviously, but I do 00:25:59.290 --> 00:26:04.840 kind of want to add the person's name to the string of text Hello comma. 00:26:04.840 --> 00:26:08.830 Well let me go now down to my terminal window and run Python of Hello.py 00:26:08.830 --> 00:26:10.000 again, Enter. 00:26:10.000 --> 00:26:10.750 What's your name? 00:26:10.750 --> 00:26:11.920 I'm going to type in David. 00:26:11.920 --> 00:26:12.940 Enter. 00:26:12.940 --> 00:26:14.260 OK, it's better. 00:26:14.260 --> 00:26:18.160 It's better, but there's a minor bug, albeit aesthetic here. 00:26:18.160 --> 00:26:20.830 There's missing space, but let's just use some intuition here. 00:26:20.830 --> 00:26:22.900 Well, if I'm missing the space after the comma, 00:26:22.900 --> 00:26:25.780 why don't I go ahead and just add it manually here. 00:26:25.780 --> 00:26:30.670 Let me now rerun the program Python of Hello.py, Enter, David, Enter. 00:26:30.670 --> 00:26:31.540 And there we go. 00:26:31.540 --> 00:26:33.400 Now we have something that looks a little prettier 00:26:33.400 --> 00:26:34.570 in terms of English grammar. 00:26:34.570 --> 00:26:36.640 Hello, comma, space, David. 00:26:36.640 --> 00:26:40.060 And now if we rewind, you might have noticed before 00:26:40.060 --> 00:26:45.100 or wondered why I had this seemingly extra space after my question mark, 00:26:45.100 --> 00:26:45.940 namely here. 00:26:45.940 --> 00:26:48.790 There's a space after the question mark but before the double quote 00:26:48.790 --> 00:26:50.332 and that was just for aesthetics too. 00:26:50.332 --> 00:26:53.315 I wanted to move the user's cursor one space to the right 00:26:53.315 --> 00:26:55.690 so that when I typed their name or they typed their name, 00:26:55.690 --> 00:26:59.650 it's not immediately next to that same question mark there. 00:26:59.650 --> 00:27:01.790 But there's other ways we can do this. 00:27:01.790 --> 00:27:05.080 It turns out that some functions, print among them, 00:27:05.080 --> 00:27:07.570 actually take multiple arguments. 00:27:07.570 --> 00:27:11.200 And it turns out that if you separate the inputs 00:27:11.200 --> 00:27:14.620 to a function-- the so-called arguments to a function-- with a comma, 00:27:14.620 --> 00:27:19.250 you can pass in not just one, but two, three, four, five, onward. 00:27:19.250 --> 00:27:24.970 So let me go ahead and pass in not just hello, comma, space, but that followed 00:27:24.970 --> 00:27:25.660 by name. 00:27:25.660 --> 00:27:27.880 And this is a little confusing potentially at first glance 00:27:27.880 --> 00:27:30.297 because now I've got two commas but it's important to note 00:27:30.297 --> 00:27:35.800 that the first comma is inside of my quotation marks, which is simply 00:27:35.800 --> 00:27:37.490 an English grammatical thing. 00:27:37.490 --> 00:27:40.270 The second comma here is outside of the quotes, 00:27:40.270 --> 00:27:44.170 but between what are now two separate arguments to print. 00:27:44.170 --> 00:27:46.270 The first argument is hello, comma, space. 00:27:46.270 --> 00:27:49.490 The second argument is the name variable itself. 00:27:49.490 --> 00:27:51.640 So let's see how this looks. 00:27:51.640 --> 00:27:53.620 Python of Hello.py, Enter. 00:27:53.620 --> 00:27:54.460 What's your name? 00:27:54.460 --> 00:27:55.060 David. 00:27:55.060 --> 00:27:56.050 Enter. 00:27:56.050 --> 00:27:57.910 OK, I've kind of over-corrected. 00:27:57.910 --> 00:28:00.040 Now I've got two spaces for some reason. 00:28:00.040 --> 00:28:02.080 Well, it turns out, and this is subtle, when 00:28:02.080 --> 00:28:07.960 you pass multiple arguments to print, it automatically inserts a space for you. 00:28:07.960 --> 00:28:10.270 This was not relevant earlier because I was 00:28:10.270 --> 00:28:16.510 passing in one big argument to print all at once by using that + operator. 00:28:16.510 --> 00:28:19.070 This time I'm passing in two because of the comma. 00:28:19.070 --> 00:28:23.210 So if I don't want that extra space, I don't need to pass in one myself, 00:28:23.210 --> 00:28:26.530 I can just do this and now notice, if I run this program again-- 00:28:26.530 --> 00:28:29.560 Python of Hello.py, type in my name David, 00:28:29.560 --> 00:28:32.620 now it looks grammatically like I might want. 00:28:32.620 --> 00:28:34.330 Now which of these approaches is better? 00:28:34.330 --> 00:28:37.840 This approach uses a function print with two arguments-- 00:28:37.840 --> 00:28:40.810 Hello, comma and the name variable. 00:28:40.810 --> 00:28:44.195 The previous version, recall, technically used one argument, 00:28:44.195 --> 00:28:45.820 even though it looked a little curious. 00:28:45.820 --> 00:28:49.270 It's one argument in the sense that the computer, just like mathematicians, 00:28:49.270 --> 00:28:51.950 are going to do what's inside of parentheses first. 00:28:51.950 --> 00:28:54.670 So if inside of parentheses you have this string of text-- 00:28:54.670 --> 00:28:58.350 hello, comma, and a space, which I need to add back. 00:28:58.350 --> 00:29:01.050 Then you have a +, which means not addition, per se, 00:29:01.050 --> 00:29:05.400 but concatenation-- to join the thing on the left and the thing on the right. 00:29:05.400 --> 00:29:08.400 This ultimately becomes the English phrase-- 00:29:08.400 --> 00:29:10.890 Hello, comma, space, David. 00:29:10.890 --> 00:29:14.400 And then what's being passed ultimately to the function 00:29:14.400 --> 00:29:18.870 is technically something like this, but it's doing it all dynamically. 00:29:18.870 --> 00:29:23.860 It's not me typing in David as I discreetly did earlier. 00:29:23.860 --> 00:29:27.930 It's figuring out dynamically what that value is after concatenating Hello 00:29:27.930 --> 00:29:30.900 with the value of name and then passing that ultimately 00:29:30.900 --> 00:29:33.750 to print as the sole argument. 00:29:33.750 --> 00:29:38.130 Let me pause here to see if there's any questions on numbers of arguments 00:29:38.130 --> 00:29:41.250 now to functions. 00:29:41.250 --> 00:29:43.950 AUDIENCE: Can we use a function many times 00:29:43.950 --> 00:29:48.765 to solve a certain problem which we can encounter many times in our code? 00:29:48.765 --> 00:29:49.640 DAVID MALAN: You can. 00:29:49.640 --> 00:29:52.700 You can use a function many different times to solve some problem. 00:29:52.700 --> 00:29:55.040 What we'll soon see, though, is if you find yourself 00:29:55.040 --> 00:29:58.620 as the programmer solving a problem the same way again, 00:29:58.620 --> 00:30:00.560 and again, and again, it turns out you'll 00:30:00.560 --> 00:30:02.450 be able to make your own function so that you 00:30:02.450 --> 00:30:07.130 don't have to keep reusing the basic ones that come with the language. 00:30:07.130 --> 00:30:10.890 AUDIENCE: I was curious about the comma and the + sign. 00:30:10.890 --> 00:30:15.320 So after + sign, can we give just one variable and after comma again we 00:30:15.320 --> 00:30:17.180 give multiple variable status? 00:30:17.180 --> 00:30:18.470 What is the difference? 00:30:18.470 --> 00:30:19.678 DAVID MALAN: A good question. 00:30:19.678 --> 00:30:21.320 So in the context of strings-- 00:30:21.320 --> 00:30:22.640 and I keep using that term. 00:30:22.640 --> 00:30:25.130 "String" is a technical term in a programming language 00:30:25.130 --> 00:30:29.570 and again, it means a sequence of text-- a character, a word, a whole paragraph, 00:30:29.570 --> 00:30:30.080 even. 00:30:30.080 --> 00:30:33.650 So the + operator is not just used, as we'll 00:30:33.650 --> 00:30:37.790 see, for addition of numbers in Python, like we do on paper pencil, 00:30:37.790 --> 00:30:41.760 but it also is used for concatenation of strings on the left and the right. 00:30:41.760 --> 00:30:44.180 If you did want to combine not just two strings-- 00:30:44.180 --> 00:30:46.310 left and right-- but a third and a fourth, 00:30:46.310 --> 00:30:51.380 you can absolutely keep using +, +, +, +, and chain them together 00:30:51.380 --> 00:30:52.460 just like in math. 00:30:52.460 --> 00:30:54.830 Eventually that's going to start to look a little ugly, 00:30:54.830 --> 00:30:57.080 I dare say, especially if your line of code gets long. 00:30:57.080 --> 00:31:00.200 So there's better ways that we'll actually soon see. 00:31:00.200 --> 00:31:01.670 And a good question as well. 00:31:01.670 --> 00:31:04.190 Well let me come back to the code here in question 00:31:04.190 --> 00:31:06.800 and see if we can show you just a couple of other ways 00:31:06.800 --> 00:31:10.520 to solve the same problem, along the way emphasizing that what we're technically 00:31:10.520 --> 00:31:12.980 talking about here, yes, are strings, but there's even 00:31:12.980 --> 00:31:15.170 a technical term for these strings in Python, 00:31:15.170 --> 00:31:19.700 it's just STR, so to speak, S-T-R for short, for string. 00:31:19.700 --> 00:31:22.220 As you may know if you programmed in other languages, 00:31:22.220 --> 00:31:26.270 people who invent programming languages like to be very succinct, to the point, 00:31:26.270 --> 00:31:29.780 so we tend to use fairly short phrases to describe things, 00:31:29.780 --> 00:31:31.370 not necessarily full words. 00:31:31.370 --> 00:31:33.920 So while you might say "string," technically 00:31:33.920 --> 00:31:37.070 in Python what we're really talking about, these sequences of text, 00:31:37.070 --> 00:31:38.300 are technically STRs. 00:31:38.300 --> 00:31:41.450 This is an actual type of data in a program. 00:31:41.450 --> 00:31:45.420 But we'll soon see that there's other types of data in programs as well. 00:31:45.420 --> 00:31:48.980 In fact, let's see if we can't improve this in one other way. 00:31:48.980 --> 00:31:52.550 I like the progress we've made by keeping everything on the same line-- 00:31:52.550 --> 00:31:55.490 Hello, David all on the same line. 00:31:55.490 --> 00:31:59.070 What more though could we do in terms of solving this problem? 00:31:59.070 --> 00:32:02.420 Well, it turns out that we didn't have to give up entirely 00:32:02.420 --> 00:32:03.800 with using print twice. 00:32:03.800 --> 00:32:07.460 Let me rewind a little bit and go back to that earlier version 00:32:07.460 --> 00:32:11.660 where I wasn't really sure how to solve this problem so I was using print once 00:32:11.660 --> 00:32:14.090 to print out just the Hello and the space and the comma. 00:32:14.090 --> 00:32:17.750 And then I used print again to print name. 00:32:17.750 --> 00:32:22.220 That's, strictly speaking, wasn't bad, but there was this visual side effect 00:32:22.220 --> 00:32:23.270 that I didn't like. 00:32:23.270 --> 00:32:26.540 It just looked ugly to have these two lines of text separate 00:32:26.540 --> 00:32:27.600 from one another. 00:32:27.600 --> 00:32:29.480 But there's another way to fix this. 00:32:29.480 --> 00:32:34.130 Clearly it seems to be the case that the print function is automatically 00:32:34.130 --> 00:32:36.110 outputting a blank line. 00:32:36.110 --> 00:32:39.380 It's moving the cursor automatically for me to the next line 00:32:39.380 --> 00:32:42.620 because that's why I'm seeing Hello on one line and David 00:32:42.620 --> 00:32:44.150 on the next and then my prompt-- 00:32:44.150 --> 00:32:46.530 the dollar sign-- on the line below that. 00:32:46.530 --> 00:32:48.800 So print seems to be presuming automatically 00:32:48.800 --> 00:32:51.230 that you want it to move the cursor to the next line 00:32:51.230 --> 00:32:53.040 after you pass it some argument. 00:32:53.040 --> 00:32:54.890 But you can override that behavior. 00:32:54.890 --> 00:32:58.400 Again, functions take arguments which influence their behavior, 00:32:58.400 --> 00:33:00.740 you just have to know what those arguments are. 00:33:00.740 --> 00:33:06.560 And it turns out that if we look at the documentation for Python's print 00:33:06.560 --> 00:33:09.980 function, we can actually look up at this URL here-- 00:33:09.980 --> 00:33:14.150 docs.python.org is where all of Python's official documentation lies. 00:33:14.150 --> 00:33:17.870 If I poke around, I can find my way to more specifically this URL 00:33:17.870 --> 00:33:22.970 here where I can find all of the available functions in Python 00:33:22.970 --> 00:33:24.630 and the documentation there for. 00:33:24.630 --> 00:33:26.900 And if I go a little more precisely, I can even 00:33:26.900 --> 00:33:30.230 find specific documentation for the print function itself. 00:33:30.230 --> 00:33:31.980 And rather than pull that up in a browser, 00:33:31.980 --> 00:33:36.050 I'm going to go ahead and highlight just one line from that same URL, which 00:33:36.050 --> 00:33:39.890 is this, and this is easily the most cryptic thing we've seen yet, 00:33:39.890 --> 00:33:42.717 but this is the official documentation for the print function. 00:33:42.717 --> 00:33:45.800 And one of the best things you can do when learning a programming language 00:33:45.800 --> 00:33:48.110 is, honestly, learn to read the documentation, 00:33:48.110 --> 00:33:51.920 because truly, all of the answers to your questions will in some way 00:33:51.920 --> 00:33:55.430 be there, even though, admittedly, it's not always obvious. 00:33:55.430 --> 00:33:57.290 And I will say too, Python's documentation 00:33:57.290 --> 00:34:01.460 isn't necessarily the easiest thing, especially for a first time or novice 00:34:01.460 --> 00:34:02.072 programmer. 00:34:02.072 --> 00:34:05.030 It too just takes practice, so try not to get overwhelmed if you're not 00:34:05.030 --> 00:34:06.292 sure what you're looking at. 00:34:06.292 --> 00:34:08.000 But let me walk you through this example. 00:34:08.000 --> 00:34:11.360 This again is a line of text from Python's official documentation 00:34:11.360 --> 00:34:12.690 for the print function. 00:34:12.690 --> 00:34:14.659 What this indicates as follows is this-- 00:34:14.659 --> 00:34:17.000 the name of this function is, of course print. 00:34:17.000 --> 00:34:20.570 Then there's a parenthesis over here and another close parenthesis way 00:34:20.570 --> 00:34:21.230 over there. 00:34:21.230 --> 00:34:23.570 Everything inside of those parentheses are 00:34:23.570 --> 00:34:27.270 the arguments, the potential arguments, to the function. 00:34:27.270 --> 00:34:30.830 However, when we're looking at these arguments 00:34:30.830 --> 00:34:34.400 in the documentation like this, there's technically a different term 00:34:34.400 --> 00:34:35.150 that we would use. 00:34:35.150 --> 00:34:37.920 These are technically the parameters to the function. 00:34:37.920 --> 00:34:41.900 So when you're talking about what you can pass to a function 00:34:41.900 --> 00:34:45.679 and what those inputs are called, those are parameters. 00:34:45.679 --> 00:34:48.080 When you actually use the function and pass 00:34:48.080 --> 00:34:51.650 in values inside of those parentheses, those inputs, 00:34:51.650 --> 00:34:53.580 those values are arguments. 00:34:53.580 --> 00:34:56.719 So we're talking about the exact same thing-- parameters and arguments are 00:34:56.719 --> 00:34:58.850 effectively the same thing, but the terms you 00:34:58.850 --> 00:35:01.520 use from looking at the problem from different directions. 00:35:01.520 --> 00:35:04.220 When we're looking at what the function can take versus what 00:35:04.220 --> 00:35:06.210 you're actually passing into the function. 00:35:06.210 --> 00:35:07.500 So what does this imply? 00:35:07.500 --> 00:35:10.610 Well this syntax is pretty cryptic, but at the moment, 00:35:10.610 --> 00:35:14.360 just know that an asterisk, a star, and then the word "objects" 00:35:14.360 --> 00:35:17.330 means that the print function can take any number of objects. 00:35:17.330 --> 00:35:20.540 You can pass in 0 strings of text, one string 00:35:20.540 --> 00:35:23.900 like I did, two strings like I did, or, technically, infinitely many 00:35:23.900 --> 00:35:27.170 if you really want, though that code is not going to look very good. 00:35:27.170 --> 00:35:31.130 After that we see a comma, then we see another parameter here 00:35:31.130 --> 00:35:34.400 called SEP, short for separator in English. 00:35:34.400 --> 00:35:38.640 And notice the equal sign and the single quote, space, single quote. 00:35:38.640 --> 00:35:42.350 So 'space' I don't know what that is yet, 00:35:42.350 --> 00:35:44.570 but I think we've seen a hint about it. 00:35:44.570 --> 00:35:46.430 Let's focus though for a moment on this-- 00:35:46.430 --> 00:35:50.720 the print function takes another parameter called end and the default 00:35:50.720 --> 00:35:54.560 value of that parameter is apparently, based on this equal sign and these 00:35:54.560 --> 00:35:57.020 quotes, /n. 00:35:57.020 --> 00:36:00.260 And what is /n, if you'd like to chime in in the chat? 00:36:00.260 --> 00:36:02.810 Anyone who's program before has probably seen this, 00:36:02.810 --> 00:36:07.070 though if you've never programmed before, this might look quite cryptic. 00:36:07.070 --> 00:36:12.530 Backslash n means new line, and it's a way textually 00:36:12.530 --> 00:36:15.710 of indicating if and when you want the computer effectively 00:36:15.710 --> 00:36:19.490 to move the cursor to the next line, create a new line of text. 00:36:19.490 --> 00:36:22.310 And so technically, if we read into the documentation, 00:36:22.310 --> 00:36:23.960 we'll see more detail on this. 00:36:23.960 --> 00:36:28.550 The fact that there's a parameter called end in the documentation for the print 00:36:28.550 --> 00:36:32.840 function, just means that by default this print function is going to end 00:36:32.840 --> 00:36:35.240 every line with /n. 00:36:35.240 --> 00:36:37.670 You don't literally see /n, you see a new line. 00:36:37.670 --> 00:36:40.320 You see the cursor moving to the next line. 00:36:40.320 --> 00:36:42.500 Now by that logic, let's move backwards. 00:36:42.500 --> 00:36:46.790 SEP four separator-- the default value of separator 00:36:46.790 --> 00:36:49.460 is apparently a single blank space. 00:36:49.460 --> 00:36:51.020 Well where have we seen that? 00:36:51.020 --> 00:36:55.190 Well recall in an earlier example when I passed in not just one but two 00:36:55.190 --> 00:36:57.210 arguments to the print function. 00:36:57.210 --> 00:37:00.300 Recall that they magically had a space between them. 00:37:00.300 --> 00:37:02.540 In fact, they had that space + my own space 00:37:02.540 --> 00:37:05.720 and that's why I deleted my space because at that point it was extra. 00:37:05.720 --> 00:37:09.620 So this just means that when you pass multiple arguments to print, by default 00:37:09.620 --> 00:37:11.750 they're going to be separated by a single space. 00:37:11.750 --> 00:37:14.570 By default, when you pass arguments to print, 00:37:14.570 --> 00:37:17.880 it's the whole thing is going to be ended with a new line. 00:37:17.880 --> 00:37:19.850 Now just by knowing this, and let me literally 00:37:19.850 --> 00:37:22.890 wave my hand at the rest of the documentation for another day, 00:37:22.890 --> 00:37:24.890 there's more things that print can do, but we're 00:37:24.890 --> 00:37:29.360 going to focus just on SEP and on END, let's see if we can't leverage this now 00:37:29.360 --> 00:37:31.010 to solve that original problem. 00:37:31.010 --> 00:37:34.250 The original problem was this, I don't like how Hello, David 00:37:34.250 --> 00:37:35.750 is on two different lines. 00:37:35.750 --> 00:37:38.420 Well that's happening again because print is automatically 00:37:38.420 --> 00:37:41.810 printing out a new line, so let's tell it not to do that. 00:37:41.810 --> 00:37:47.150 Let's tell it by passing a second argument to the first use of PRINT 00:37:47.150 --> 00:37:51.110 to say END = quote, unquote-- 00:37:51.110 --> 00:37:54.840 not /n, which is the default automatically. 00:37:54.840 --> 00:37:58.250 Let's make it quote, unquote nothing else. 00:37:58.250 --> 00:38:01.850 Let's override the default value so there is no new line. 00:38:01.850 --> 00:38:03.560 There's literally nothing there. 00:38:03.560 --> 00:38:05.250 And let's see what happens. 00:38:05.250 --> 00:38:08.270 Let me now go down to my terminal window and clear it. 00:38:08.270 --> 00:38:10.672 And I'm going to run Python of Hello.py, Enter. 00:38:10.672 --> 00:38:12.380 I'm going to type in my name, David and I 00:38:12.380 --> 00:38:16.280 think now everything is going to stay on the same line because-- 00:38:16.280 --> 00:38:22.460 and it did-- this line here, 5, is going to print out Hello, comma, space, 00:38:22.460 --> 00:38:24.710 but then nothing at the end of it because I 00:38:24.710 --> 00:38:26.450 changed it to be quote, unquote. 00:38:26.450 --> 00:38:29.210 The second line is going to print the name, David, 00:38:29.210 --> 00:38:32.780 or whatever the human's name is, and it will move the cursor to the next line 00:38:32.780 --> 00:38:36.230 because I didn't override the value of END there. 00:38:36.230 --> 00:38:39.710 Just to see this more explicitly, if you do something cryptic like, 00:38:39.710 --> 00:38:41.420 well I have no idea what's going on. 00:38:41.420 --> 00:38:44.120 Let me just put in temporarily three question marks here. 00:38:44.120 --> 00:38:46.040 We'll see the results of this too. 00:38:46.040 --> 00:38:49.202 Let me go back down to my terminal window, run Python of hello. py, 00:38:49.202 --> 00:38:49.910 what's your name? 00:38:49.910 --> 00:38:50.420 David. 00:38:50.420 --> 00:38:54.207 And now you see literally really ugly output, 00:38:54.207 --> 00:38:55.790 but you see literally what's going on. 00:38:55.790 --> 00:39:01.010 Hello, comma, space, then three question marks, END, that print statement, 00:39:01.010 --> 00:39:05.570 and then you see D-A-V-I-D. So not a good outcome, 00:39:05.570 --> 00:39:09.080 but it demonstrates just how much control we have here too. 00:39:09.080 --> 00:39:10.490 And let me rewind further. 00:39:10.490 --> 00:39:13.250 Recall that in our other version of this, 00:39:13.250 --> 00:39:18.710 when I passed in Hello, comma and name, they were separated by a single space. 00:39:18.710 --> 00:39:22.340 So Python of Hello.py, D-A-V-I-D, Enter. 00:39:22.340 --> 00:39:23.690 That just worked. 00:39:23.690 --> 00:39:27.950 Well what if we override the value of SEP for separator? 00:39:27.950 --> 00:39:31.730 Instead of being one space, we could say something 00:39:31.730 --> 00:39:35.030 like, question mark, question mark, question mark just to wrap 00:39:35.030 --> 00:39:37.110 our minds around what's going on there. 00:39:37.110 --> 00:39:41.300 Let me now do Python of Hello.py, D-A-V-I-D, Enter. 00:39:41.300 --> 00:39:42.650 And you see two. 00:39:42.650 --> 00:39:43.850 These two inputs-- 00:39:43.850 --> 00:39:47.840 Hello, comma and the name are now separated in an ugly way 00:39:47.840 --> 00:39:52.580 by three question marks because I've overridden the default behavior of SEP. 00:39:52.580 --> 00:39:54.803 And even though the documentation uses single quotes, 00:39:54.803 --> 00:39:56.720 I've been in the habit of using double quotes. 00:39:56.720 --> 00:39:58.580 In Python you can use either. 00:39:58.580 --> 00:40:01.620 Strictly speaking, it doesn't matter, but you should be consistent 00:40:01.620 --> 00:40:03.530 and I generally always use double quotes. 00:40:03.530 --> 00:40:08.240 Python's documentation, though, always uses single quotes. 00:40:08.240 --> 00:40:12.320 Questions now on these types of parameters? 00:40:12.320 --> 00:40:15.290 And allow me to propose that we give these an official name. 00:40:15.290 --> 00:40:19.220 Up until now, when we've been passing values to print, 00:40:19.220 --> 00:40:22.160 those are called positional parameters-- positional in the sense 00:40:22.160 --> 00:40:24.620 that the first thing you pass to print gets printed first. 00:40:24.620 --> 00:40:27.830 The second thing you pass to print after a comma gets printed second. 00:40:27.830 --> 00:40:28.710 And so forth. 00:40:28.710 --> 00:40:32.210 But there's also these things we've now seen called named parameters. 00:40:32.210 --> 00:40:37.550 Named SEP, separator, or END, E-N-D for the line ending. 00:40:37.550 --> 00:40:40.910 Those are named parameters because one, they're optional 00:40:40.910 --> 00:40:44.450 and you can pass them in at the end of your print statement, 00:40:44.450 --> 00:40:48.290 but you can also use them by name. 00:40:48.290 --> 00:40:51.050 AUDIENCE: This may be a weird question, but I was wondering, 00:40:51.050 --> 00:40:57.350 what if someone wants to add actually quotation marks within the quotation 00:40:57.350 --> 00:40:57.920 marks? 00:40:57.920 --> 00:40:59.600 DAVID MALAN: Yeah, I like how you think. 00:40:59.600 --> 00:41:01.880 This is what we would call a corner case, right? 00:41:01.880 --> 00:41:03.860 Just when we've made-- right, this is all 00:41:03.860 --> 00:41:06.823 sounding great, at least as programming goes, but, wait a minute, 00:41:06.823 --> 00:41:08.240 what if you want to print a quote? 00:41:08.240 --> 00:41:09.557 That's a really good question. 00:41:09.557 --> 00:41:11.390 Well, let's see if we can't figure this out. 00:41:11.390 --> 00:41:15.590 Suppose that I want to print out not just the user's name. 00:41:15.590 --> 00:41:16.940 Let me simplify this further. 00:41:16.940 --> 00:41:18.980 Let me go ahead and get rid of a lot of this, 00:41:18.980 --> 00:41:21.510 and let me just say something like, Hello-- 00:41:24.170 --> 00:41:26.240 maybe I'm being a little sarcastic here. 00:41:26.240 --> 00:41:28.310 Hello, (sarcastically) "friend." 00:41:28.310 --> 00:41:30.022 You know, in that kind of tone. 00:41:30.022 --> 00:41:31.730 Well this is not going to work, actually, 00:41:31.730 --> 00:41:36.260 because you are trying to use quotes to be like "friend" in finger quotes, 00:41:36.260 --> 00:41:38.070 but you're also trying to end the sentence. 00:41:38.070 --> 00:41:39.778 And if I try running this, let's do this. 00:41:39.778 --> 00:41:43.160 Python of Hello.py, you'll see that this is just invalid syntax. 00:41:43.160 --> 00:41:44.420 Perhaps you forgot a comma. 00:41:44.420 --> 00:41:45.920 And this is actually a bit annoying. 00:41:45.920 --> 00:41:48.822 Sometimes the error messages you see are misleading. 00:41:48.822 --> 00:41:50.780 Like the computer, the language, doesn't really 00:41:50.780 --> 00:41:52.488 know what's going on so it gives its best 00:41:52.488 --> 00:41:55.010 guess, but it's not necessarily correct. 00:41:55.010 --> 00:41:57.870 But I can solve this problem in a couple of ways. 00:41:57.870 --> 00:41:59.160 I can do this-- 00:41:59.160 --> 00:42:01.912 I can change my outermost quotes to single quotes. 00:42:01.912 --> 00:42:03.620 Because recall a moment again, I said you 00:42:03.620 --> 00:42:07.130 could use double quotes or single quotes so long as you're consistent. 00:42:07.130 --> 00:42:08.000 So that's fine. 00:42:08.000 --> 00:42:10.142 If you use single quotes on the outside, you 00:42:10.142 --> 00:42:13.100 can then use double quotes on the inside and you'll see them literally. 00:42:13.100 --> 00:42:17.000 So for instance, if I run Python of Hello.py, there we go. 00:42:17.000 --> 00:42:18.590 Hello, "friend." 00:42:18.590 --> 00:42:19.910 But there's another way. 00:42:19.910 --> 00:42:23.450 If you insist on using double quotes as you might want to, 00:42:23.450 --> 00:42:27.800 just to be consistent, you can also use that backslash character again. 00:42:27.800 --> 00:42:30.080 We saw the /n a moment ago. 00:42:30.080 --> 00:42:33.380 And that meant we don't want a literal n to be in the output, 00:42:33.380 --> 00:42:34.640 we wanted a new line. 00:42:34.640 --> 00:42:38.420 So the backslash actually represents what's called an escape character. 00:42:38.420 --> 00:42:40.430 An escape character is one that you can't just 00:42:40.430 --> 00:42:43.130 type necessarily once on your keyboard. 00:42:43.130 --> 00:42:45.270 You need to express it with multiple characters. 00:42:45.270 --> 00:42:50.920 So I can actually put backslashes in front of these inner double quotes 00:42:50.920 --> 00:42:52.920 so that the computer realizes, Oh wait a minute, 00:42:52.920 --> 00:42:57.560 those aren't quotes that finish or start the thought, they're literal quotes. 00:42:57.560 --> 00:43:02.420 So now let me go back to my terminal window, run Python of Hello.py, Enter. 00:43:02.420 --> 00:43:04.800 And now it's working as well. 00:43:04.800 --> 00:43:08.390 So escaping is a general technique that allows us to do that too. 00:43:08.390 --> 00:43:12.230 And if I may, let me rewind now on these examples 00:43:12.230 --> 00:43:14.810 and go back to where we left off with my code, 00:43:14.810 --> 00:43:18.200 I'm just undoing all of that, because I want to get back to the point 00:43:18.200 --> 00:43:23.820 ultimately of specifying now a final way of solving this problem. 00:43:23.820 --> 00:43:26.300 Well, it turns out that we have yet another way 00:43:26.300 --> 00:43:30.680 we can solve this problem, which is perhaps the most frequently done 00:43:30.680 --> 00:43:35.030 now or at least the most elegant when it comes to setting us up 00:43:35.030 --> 00:43:38.840 for longer and longer uses of strings. 00:43:38.840 --> 00:43:43.620 You can use a relatively new feature of Python that allows you to do this. 00:43:43.620 --> 00:43:47.397 You can literally put, not the name of the variable like that in your string, 00:43:47.397 --> 00:43:49.230 because we already saw this is wrong, right? 00:43:49.230 --> 00:43:52.340 If you do this, you will literally see Hello, comma, name. 00:43:52.340 --> 00:43:53.580 But what if I do this? 00:43:53.580 --> 00:43:58.070 What if I put curly braces or curly brackets around the variable's name? 00:43:58.070 --> 00:44:00.830 Notice VS Code is actually very subtly changing the color of it. 00:44:00.830 --> 00:44:03.590 So VS Code knows something interesting is going on here. 00:44:03.590 --> 00:44:08.060 Let me run this program, but I'm not done yet Python of Hello.py, Enter. 00:44:08.060 --> 00:44:09.650 D-A-V-I-D, Enter. 00:44:09.650 --> 00:44:13.430 OK, obviously not what I want, but I need to tell Python 00:44:13.430 --> 00:44:15.140 that this is a special string. 00:44:15.140 --> 00:44:18.470 This is what we're going to call a format string or an F string, 00:44:18.470 --> 00:44:21.660 a relatively new feature of Python in the past few years 00:44:21.660 --> 00:44:26.750 that tells Python to actually format stuff in the string in a special way. 00:44:26.750 --> 00:44:29.480 And the symbol via what you do this is a little weird, 00:44:29.480 --> 00:44:31.220 but this is what the world chose. 00:44:31.220 --> 00:44:35.390 If you put an F at the beginning of the string, 00:44:35.390 --> 00:44:40.160 right before the first quote mark, that's a clue to Python that, ooh, 00:44:40.160 --> 00:44:41.210 this is a special string. 00:44:41.210 --> 00:44:43.550 Let me format this in a special way for you. 00:44:43.550 --> 00:44:45.380 Let me now rerun the program. 00:44:45.380 --> 00:44:47.120 Python Hello.py, Enter. 00:44:47.120 --> 00:44:48.410 D-A-V-I-D, Enter. 00:44:48.410 --> 00:44:51.170 And now we see the goal this whole time-- 00:44:51.170 --> 00:44:52.395 Hello, David. 00:44:52.395 --> 00:44:55.520 We don't start with this way, because I think if we did this the first way, 00:44:55.520 --> 00:44:57.330 you'd be like, why are we doing this? 00:44:57.330 --> 00:44:58.850 What are all these magical symbols? 00:44:58.850 --> 00:45:02.370 But this is just yet another way to solve the same problem. 00:45:02.370 --> 00:45:04.940 But let me propose that we consider now yet 00:45:04.940 --> 00:45:06.920 other things we can do with strings. 00:45:06.920 --> 00:45:11.190 And it turns out that even as we've been doing some relatively simple operations 00:45:11.190 --> 00:45:14.665 here, we've generally been trusting that the user is going to cooperate 00:45:14.665 --> 00:45:17.790 and that is to say that they're going to actually type in what we want them 00:45:17.790 --> 00:45:18.450 to type. 00:45:18.450 --> 00:45:20.850 Now just because they type a string, though, doesn't mean 00:45:20.850 --> 00:45:22.410 it's going to look the way we want. 00:45:22.410 --> 00:45:24.510 You and I, honestly, as humans are actually 00:45:24.510 --> 00:45:27.840 in the habit-- on websites and apps-- of like accidentally hitting 00:45:27.840 --> 00:45:30.300 the spacebar a lot, either at the beginning of our input 00:45:30.300 --> 00:45:33.460 or at the end, maybe because the space bar tends to be so big. 00:45:33.460 --> 00:45:35.790 It's pretty common to get accidental spaces 00:45:35.790 --> 00:45:37.950 before or after some users' input. 00:45:37.950 --> 00:45:41.675 You and I are definitely in the habit of not necessarily capitalizing words 00:45:41.675 --> 00:45:42.300 like we should. 00:45:42.300 --> 00:45:45.122 If we're sending text messages, we're probably being a little quick 00:45:45.122 --> 00:45:46.830 and just sending everything in lowercase, 00:45:46.830 --> 00:45:49.913 for instance, if that's your style, if your phone's not fixing it for you. 00:45:49.913 --> 00:45:52.530 Maybe in a formal letter you would capitalize things properly. 00:45:52.530 --> 00:45:56.400 But you and I as humans, we can't really be trusted to type things in a nice way 00:45:56.400 --> 00:45:58.870 necessarily when using some piece of software, 00:45:58.870 --> 00:46:00.940 be it an app or a website or something else. 00:46:00.940 --> 00:46:04.560 But it turns out that strings themselves come 00:46:04.560 --> 00:46:06.450 with a lot of built-in functionality. 00:46:06.450 --> 00:46:09.300 You can see all of that in Python's own documentation here. 00:46:09.300 --> 00:46:12.600 The string data type that we've been talking about 00:46:12.600 --> 00:46:14.970 comes with a lot of functionality built in that 00:46:14.970 --> 00:46:18.360 means that we can manipulate the user's input to do more than just 00:46:18.360 --> 00:46:22.290 join it with something else like Hello, we can actually clean it up 00:46:22.290 --> 00:46:26.380 or reformat it in a way that hopefully looks a little better for us. 00:46:26.380 --> 00:46:29.070 So let me go back to my code here and let me just 00:46:29.070 --> 00:46:32.100 demonstrate what might happen if a user doesn't cooperate. 00:46:32.100 --> 00:46:35.490 If I go ahead here and run Python of Hello.py, Enter. 00:46:35.490 --> 00:46:38.890 Let me just sloppily hit the spacebar a few too many times. 00:46:38.890 --> 00:46:39.390 Why? 00:46:39.390 --> 00:46:40.890 I just wasn't paying attention. 00:46:40.890 --> 00:46:43.710 And now I'm going to type in my name D-A-V-I-D and, I don't know, 00:46:43.710 --> 00:46:45.510 I hit the spacebar a couple more times. 00:46:45.510 --> 00:46:46.620 Like it's kind of a mess. 00:46:46.620 --> 00:46:47.785 It's all lowercase. 00:46:47.785 --> 00:46:50.160 That's not going to necessarily look grammatically right. 00:46:50.160 --> 00:46:51.900 It's got spaces here and here. 00:46:51.900 --> 00:46:54.030 The program is going to print exactly that 00:46:54.030 --> 00:46:55.890 and that looks really bad, at least if we're 00:46:55.890 --> 00:46:57.900 prioritizing aesthetics and grammar. 00:46:57.900 --> 00:47:00.330 Like, why are there so many spaces after the comma? 00:47:00.330 --> 00:47:03.420 This is not a very nice way to greet your users. 00:47:03.420 --> 00:47:05.130 But we can clean this up. 00:47:05.130 --> 00:47:10.170 It turns out that built into strings, which, again, is this data type, so 00:47:10.170 --> 00:47:12.780 to speak, this type of data in Python-- 00:47:12.780 --> 00:47:15.730 is the ability to actually do things to that string. 00:47:15.730 --> 00:47:20.280 So let me do this, I can actually go ahead and do something like this-- 00:47:20.280 --> 00:47:23.820 name = name.strip. 00:47:23.820 --> 00:47:25.240 And what does this do? 00:47:25.240 --> 00:47:30.460 Remove white space from string. 00:47:30.460 --> 00:47:32.060 And what do I mean by this? 00:47:32.060 --> 00:47:33.910 Well, on the right-hand side, notice I've 00:47:33.910 --> 00:47:36.700 written the variable name called Name. 00:47:36.700 --> 00:47:40.120 I've then used a period or a dot, and then I 00:47:40.120 --> 00:47:42.520 seem to be doing what's a function, right? 00:47:42.520 --> 00:47:46.300 Any time we've seen a function thus far, we see the function's name-- print 00:47:46.300 --> 00:47:49.030 or input, then we see a parenthesis, then another parenthesis, 00:47:49.030 --> 00:47:50.678 and that's exactly what I see here. 00:47:50.678 --> 00:47:52.720 But I'm using this function a little differently. 00:47:52.720 --> 00:47:55.990 Technically, this function is-- in this context-- called a method. 00:47:55.990 --> 00:47:57.620 And what do I mean by that? 00:47:57.620 --> 00:48:00.250 Well, if Name is a string, a.k.a. 00:48:00.250 --> 00:48:03.130 STR, well it turns out, according to the documentation, 00:48:03.130 --> 00:48:07.630 there's a lot of functions that come with strings in Python. 00:48:07.630 --> 00:48:10.150 And you can access that functionality by using 00:48:10.150 --> 00:48:14.860 the name of a string like literally name here, then a period, then the name 00:48:14.860 --> 00:48:18.220 of the, function and then an open parenthesis and a closed parenthesis. 00:48:18.220 --> 00:48:21.320 Maybe some arguments inside of those parentheses, but in this case, 00:48:21.320 --> 00:48:22.900 it doesn't need any arguments. 00:48:22.900 --> 00:48:26.320 I just want to strip the space from the left and the space 00:48:26.320 --> 00:48:28.000 from the right of the user's input. 00:48:28.000 --> 00:48:29.210 But that's not enough. 00:48:29.210 --> 00:48:31.120 I want to remember that I've stripped off 00:48:31.120 --> 00:48:32.920 that white space on the left and the right, 00:48:32.920 --> 00:48:35.470 so I'm going to use the equal sign again here. 00:48:35.470 --> 00:48:38.590 And notice that just as before, this doesn't mean equality, 00:48:38.590 --> 00:48:40.940 this means assignment from right to left. 00:48:40.940 --> 00:48:43.900 So when this line of code here-- name.strip-- 00:48:43.900 --> 00:48:46.600 returns to me, a.k.a. 00:48:46.600 --> 00:48:49.123 a return value, it will return the same thing 00:48:49.123 --> 00:48:51.790 that the user typed in, but with no more white space to the left 00:48:51.790 --> 00:48:54.370 or to the white [CHUCKLES] to the right. 00:48:54.370 --> 00:48:56.860 So then the equal sign assignment is going 00:48:56.860 --> 00:49:00.190 to copy that value from the right to the left, 00:49:00.190 --> 00:49:04.820 thereby updating the value inside of my name variable. 00:49:04.820 --> 00:49:07.240 So you can not only assign values to variables, 00:49:07.240 --> 00:49:10.300 you can absolutely change the value of variables 00:49:10.300 --> 00:49:12.817 by just using the assignment operator, the equal sign again, 00:49:12.817 --> 00:49:15.400 and again, and again, and it will just keep copying from right 00:49:15.400 --> 00:49:17.810 to left whatever the new value should be. 00:49:17.810 --> 00:49:23.740 So now if I rerun this program, Python of Hello.py, Enter. 00:49:23.740 --> 00:49:25.930 I have D-A-V-I-- oop, let's do it again. 00:49:25.930 --> 00:49:29.170 Space, space, space, space, space. d-a-v-i-d in all lowercase, space, 00:49:29.170 --> 00:49:30.760 space, Enter. 00:49:30.760 --> 00:49:32.060 It's better. 00:49:32.060 --> 00:49:34.300 It hasn't fixed my capitalization, so I'm still 00:49:34.300 --> 00:49:38.050 being a little sloppy with the first D, But it has stripped off 00:49:38.050 --> 00:49:39.430 all of that extra space. 00:49:39.430 --> 00:49:41.170 Super minor detail, right? 00:49:41.170 --> 00:49:44.050 Like this isn't all that exciting, but it just 00:49:44.050 --> 00:49:47.440 speaks to the power of what you can do with just a single line of code. 00:49:47.440 --> 00:49:49.160 Now what else can I do here? 00:49:49.160 --> 00:49:51.610 Well I could capitalize the user's input. 00:49:51.610 --> 00:49:53.390 Let me go ahead and try this. 00:49:53.390 --> 00:49:59.810 It turns out that I could also do this-- name.capitalize. 00:49:59.810 --> 00:50:03.420 So let me go ahead and capitalize user's name. 00:50:03.420 --> 00:50:05.170 And again, I'm making comments and there's 00:50:05.170 --> 00:50:06.820 no one right way to write the comments. 00:50:06.820 --> 00:50:08.770 I'm just using some short English phrases here 00:50:08.770 --> 00:50:10.510 to remind myself of what I'm doing. 00:50:10.510 --> 00:50:12.190 What's now going on here? 00:50:12.190 --> 00:50:15.310 Well let me go ahead and run Python of Hello.py, Enter. 00:50:15.310 --> 00:50:19.240 Space, space, space, space, space, d-a-v-i-d, space, space, Enter. 00:50:19.240 --> 00:50:19.960 OK. 00:50:19.960 --> 00:50:21.580 Now it's looking prettier, right? 00:50:21.580 --> 00:50:24.640 No matter how the user typed in their name, even a little sloppily, 00:50:24.640 --> 00:50:25.720 I'm now fixing that. 00:50:25.720 --> 00:50:27.313 But let's try something. 00:50:27.313 --> 00:50:28.730 I'm getting a little curious here. 00:50:28.730 --> 00:50:29.830 How about this? 00:50:29.830 --> 00:50:33.910 Space, space, space, space, space, d-a-v-i-d space m-a-l-a-n-- 00:50:33.910 --> 00:50:35.530 I'll use my last name now-- 00:50:35.530 --> 00:50:36.640 Enter. 00:50:36.640 --> 00:50:42.100 OK, so ironically, "capitalize" is not really capitalizing everything we want. 00:50:42.100 --> 00:50:43.870 It's clearly capitalizing what? 00:50:43.870 --> 00:50:45.580 Just the very first letter. 00:50:45.580 --> 00:50:48.940 So it turns out that, again, there's other functions in Python 00:50:48.940 --> 00:50:49.960 that come with strings. 00:50:49.960 --> 00:50:54.670 And if we poke around the documentation, scrolling through a URL like that, 00:50:54.670 --> 00:50:58.540 I bet we'll find another solution, one of which is actually this. 00:50:58.540 --> 00:51:01.180 Let's actually change this to title. 00:51:01.180 --> 00:51:03.550 There's yet another function that comes with strings 00:51:03.550 --> 00:51:07.120 called Title that do title-based capitalization, just 00:51:07.120 --> 00:51:09.310 like a book or a person's name, capitalizing 00:51:09.310 --> 00:51:12.010 the first letter of each word. 00:51:12.010 --> 00:51:14.450 And this is just going to do a little more work for us. 00:51:14.450 --> 00:51:15.880 So let's go ahead and run this. 00:51:15.880 --> 00:51:18.700 And as an aside, I'm kind of tired now at this point 00:51:18.700 --> 00:51:22.130 of typing Python, Python, Python all the time. 00:51:22.130 --> 00:51:25.570 It turns out that when using a command line interface like this, 00:51:25.570 --> 00:51:28.000 you can actually go back through all of your old commands. 00:51:28.000 --> 00:51:30.280 What I just did a moment ago was I hit the up arrow. 00:51:30.280 --> 00:51:33.820 That immediately goes back through my history of all of the commands 00:51:33.820 --> 00:51:34.720 I've ever typed. 00:51:34.720 --> 00:51:37.960 So this is just a faster way now for me to repeat myself 00:51:37.960 --> 00:51:39.700 than typing everything manually. 00:51:39.700 --> 00:51:42.850 Let me go ahead and hit Enter, space, space, space, space, space, 00:51:42.850 --> 00:51:47.110 d-a-v-i-d m-a-l-a-n space, space, all lowercase, Enter. 00:51:47.110 --> 00:51:49.690 Now it's looking better. 00:51:49.690 --> 00:51:52.030 Now I've capitalized things and cleaned things up. 00:51:52.030 --> 00:51:53.200 But what about my code? 00:51:53.200 --> 00:51:55.930 I've got like eight lines of code now, four of which 00:51:55.930 --> 00:51:58.030 are comments, four of which are actual code. 00:51:58.030 --> 00:51:59.710 Do I really need this much? 00:51:59.710 --> 00:52:00.910 Well, not necessarily. 00:52:00.910 --> 00:52:03.520 Watch what I can also do in Python. 00:52:03.520 --> 00:52:07.100 Let me not bother capitalizing the user's name separately. 00:52:07.100 --> 00:52:08.170 Let me say this-- 00:52:08.170 --> 00:52:12.970 and capitalize user's name. 00:52:12.970 --> 00:52:15.370 I can chain these functions together. 00:52:15.370 --> 00:52:18.130 I can add Title to the end of this. 00:52:18.130 --> 00:52:19.600 And now what's happening? 00:52:19.600 --> 00:52:21.440 Well again, with a line of code like this, 00:52:21.440 --> 00:52:24.490 you first focus on what's to the right of the equal sign, 00:52:24.490 --> 00:52:26.470 then we'll get to the left of the equal sign. 00:52:26.470 --> 00:52:28.095 What's on the right of the equals sign? 00:52:28.095 --> 00:52:29.240 This line here. 00:52:29.240 --> 00:52:30.390 Well what does this mean? 00:52:30.390 --> 00:52:35.610 Get the value of the name variable, like D-A-V-I-D space, M-A-L-A-N. 00:52:35.610 --> 00:52:38.700 Then strip off the white space on the left and the right. 00:52:38.700 --> 00:52:40.920 That is going to return a value. 00:52:40.920 --> 00:52:44.790 It's going to return D-A-V-I-D space M-A-L-A-N without any white space 00:52:44.790 --> 00:52:45.720 to the left or right. 00:52:45.720 --> 00:52:47.940 What do you want to do with that return value? 00:52:47.940 --> 00:52:50.850 You want Python to title case it, that is 00:52:50.850 --> 00:52:54.330 go through every word in that resulting string 00:52:54.330 --> 00:52:57.000 and fix the first letter of the first word, the first letter 00:52:57.000 --> 00:52:58.390 of the second word, and so forth. 00:52:58.390 --> 00:53:00.330 And then-- now we can finish our thought-- 00:53:00.330 --> 00:53:05.580 copy the whole thing from right to left into that same name variable. 00:53:05.580 --> 00:53:06.330 And you know what? 00:53:06.330 --> 00:53:08.340 I can take this even one step further. 00:53:08.340 --> 00:53:11.400 Why don't we go ahead and do this if we want. 00:53:11.400 --> 00:53:16.890 Let me get rid of all of that, and let me just do strip and title 00:53:16.890 --> 00:53:18.270 all on that first line. 00:53:18.270 --> 00:53:21.380 And now we've gone from like eight lines of code to four. 00:53:21.380 --> 00:53:22.740 It's a lot tighter. 00:53:22.740 --> 00:53:23.880 It's a lot neater. 00:53:23.880 --> 00:53:26.250 And even though reasonable people might disagree, 00:53:26.250 --> 00:53:30.090 it's arguably better because it's just easier to read. 00:53:30.090 --> 00:53:32.670 Fewer lines of code, fewer opportunities for mistakes, 00:53:32.670 --> 00:53:37.350 it just allows me to move on with my next problem to solve. 00:53:37.350 --> 00:53:41.730 All right, let me pause here and see if there's any questions on these methods. 00:53:41.730 --> 00:53:45.540 A method is a function that's built in to a type of value, 00:53:45.540 --> 00:53:47.820 like these functions are. 00:53:47.820 --> 00:53:50.640 Or on F strings which we saw a moment ago. 00:53:50.640 --> 00:53:51.390 AUDIENCE: Yes, hi. 00:53:51.390 --> 00:53:52.410 Thanks, David. 00:53:52.410 --> 00:53:56.190 So is there a way to remove the spaces between the spaces 00:53:56.190 --> 00:53:57.430 that I might have added? 00:53:57.430 --> 00:53:58.680 DAVID MALAN: Short answer, no. 00:53:58.680 --> 00:54:01.060 If you read the documentation at that same URL earlier, 00:54:01.060 --> 00:54:05.090 you'll see that strip removes from the left and the right, but not in between. 00:54:05.090 --> 00:54:07.590 In fact, there's two other functions that come with strings. 00:54:07.590 --> 00:54:10.560 One is called L strip, the other is called R strip, 00:54:10.560 --> 00:54:12.378 that allow you to do one or the other. 00:54:12.378 --> 00:54:14.670 If we want to start getting rid of space in the middle, 00:54:14.670 --> 00:54:17.760 we're going to have to do a different trick altogether. 00:54:17.760 --> 00:54:22.380 AUDIENCE: How many functions can be combine like this dot strip, dot title, 00:54:22.380 --> 00:54:23.160 all combined. 00:54:23.160 --> 00:54:24.930 So how many we can combine? 00:54:24.930 --> 00:54:26.970 DAVID MALAN: Yeah, a really good question. 00:54:26.970 --> 00:54:30.177 Technically, as many as you want, but at some point 00:54:30.177 --> 00:54:32.760 your code is going to start to look really, really bad, right? 00:54:32.760 --> 00:54:35.302 Because the line of code is going to get really, really long. 00:54:35.302 --> 00:54:38.130 It's eventually going to maybe wrap around again and again. 00:54:38.130 --> 00:54:41.220 So at some point, you just kind of say like, uh-uh, that's too many. 00:54:41.220 --> 00:54:44.340 And you start breaking it up into multiple lines like I did. 00:54:44.340 --> 00:54:47.518 Maybe reassigning the value to the variable as needed. 00:54:47.518 --> 00:54:49.060 And this is actually a good question. 00:54:49.060 --> 00:54:52.830 If I can pivot, [INAUDIBLE] off your question, I mean, what do people think? 00:54:52.830 --> 00:54:55.770 If we could go ahead and put everyone's hands down for a moment. 00:54:55.770 --> 00:54:57.690 Let me ask this-- 00:54:57.690 --> 00:55:03.450 is the way I've done this now, with strip and title and input 00:55:03.450 --> 00:55:04.800 all in the same line-- 00:55:04.800 --> 00:55:07.290 better than my previous approach? 00:55:07.290 --> 00:55:10.830 In Zoom you can use the Yes icon or the No icon. 00:55:10.830 --> 00:55:14.370 If you think this version is better, say Yes. 00:55:14.370 --> 00:55:19.060 If you think this previous version was better, for instance, 00:55:19.060 --> 00:55:23.310 this one here where we had everything broken out, say No. 00:55:23.310 --> 00:55:26.610 And then we'll see why in just a moment. 00:55:26.610 --> 00:55:30.000 I proposed earlier that reasonable people can disagree 00:55:30.000 --> 00:55:32.730 and that's absolutely the case. 00:55:32.730 --> 00:55:35.520 Doing it one way or the other isn't necessarily best, 00:55:35.520 --> 00:55:37.800 at least if you can justify it. 00:55:37.800 --> 00:55:41.280 Let me go back to the most recent version here. 00:55:41.280 --> 00:55:45.360 All right so we're seeing a lot of Yeses and a lot of Nos. 00:55:45.360 --> 00:55:48.900 Why don't we go ahead and call on one of the Yeses, if we could. 00:55:48.900 --> 00:55:52.710 Someone who's voting Yes, why do you think the current version of this code 00:55:52.710 --> 00:55:57.330 is indeed better than the previous longer version of the code? 00:55:57.330 --> 00:55:59.110 AUDIENCE: I think it's more readable. 00:55:59.110 --> 00:56:03.030 So I can say, this is the name variable. 00:56:03.030 --> 00:56:07.360 It gets some input and then remove the space and give it a title. 00:56:07.360 --> 00:56:08.320 And there you go. 00:56:08.320 --> 00:56:09.600 You have a hello, name. 00:56:09.600 --> 00:56:10.860 DAVID MALAN: Yeah, I think that's pretty reasonable. 00:56:10.860 --> 00:56:12.660 It's very readable, at least if you're in the habit, 00:56:12.660 --> 00:56:14.660 as you are in English, of reading left to right. 00:56:14.660 --> 00:56:16.990 It just kind of flows very naturally as a result. 00:56:16.990 --> 00:56:18.943 The lines is not really that long. 00:56:18.943 --> 00:56:20.860 It's certainly fitting nicely onto the screen. 00:56:20.860 --> 00:56:21.870 So I think that's a good argument. 00:56:21.870 --> 00:56:23.310 How about a counterpoint, though? 00:56:23.310 --> 00:56:27.810 Someone who voted No, if we could call on someone who thinks this is worse. 00:56:27.810 --> 00:56:31.410 AUDIENCE: Because it's not readable at all. 00:56:31.410 --> 00:56:37.300 It seems like it's a very long line. 00:56:37.300 --> 00:56:39.170 So I think it's better to separate. 00:56:39.170 --> 00:56:39.920 DAVID MALAN: Yeah. 00:56:39.920 --> 00:56:41.580 I think that's persuasive too, right? 00:56:41.580 --> 00:56:43.050 It's getting a little longer. 00:56:43.050 --> 00:56:46.890 And even though my sentence here-- what's your name-- is relatively short, 00:56:46.890 --> 00:56:49.530 you could imagine that this could get even uglier quickly 00:56:49.530 --> 00:56:52.350 if I were asking a longer question of the user, that's 00:56:52.350 --> 00:56:56.070 going to make this line of code even longer and therefore less readable. 00:56:56.070 --> 00:56:59.970 It might be less obvious to me or my colleagues that I am calling strip 00:56:59.970 --> 00:57:01.530 or that I am calling title. 00:57:01.530 --> 00:57:03.870 It might be kind of an unexpected surprise. 00:57:03.870 --> 00:57:05.460 So I think that's reasonable too. 00:57:05.460 --> 00:57:07.570 In short, there is no right answer here. 00:57:07.570 --> 00:57:10.680 And in fact, part of the process of getting better at programming 00:57:10.680 --> 00:57:14.168 is getting your own sense of style or working for a company 00:57:14.168 --> 00:57:16.710 where they might prescribe which way is better than the other 00:57:16.710 --> 00:57:18.930 because they just want everyone doing the same thing, 00:57:18.930 --> 00:57:22.080 even though reasonable people might disagree. 00:57:22.080 --> 00:57:24.750 Ultimately though, so long as you have what's 00:57:24.750 --> 00:57:28.710 a pretty good argument in favor of one way or the other, like ultimately, 00:57:28.710 --> 00:57:29.820 that's what's important. 00:57:29.820 --> 00:57:32.160 If you're just doing things because you don't really know which one is better, 00:57:32.160 --> 00:57:33.180 that's not great. 00:57:33.180 --> 00:57:35.460 But if and when you start to acquire opinions 00:57:35.460 --> 00:57:38.610 and if your boss, if your teacher, if your colleague, your friend, 00:57:38.610 --> 00:57:41.312 can challenge you and say, wait, why did you do it like this? 00:57:41.312 --> 00:57:43.770 They might not agree with you, but at least have an answer, 00:57:43.770 --> 00:57:47.010 and that should be sufficiently persuasive in general. 00:57:47.010 --> 00:57:49.230 Now, strings come with a whole bunch of other methods 00:57:49.230 --> 00:57:53.310 as well, among which is one called split, which can, as the name suggests, 00:57:53.310 --> 00:57:57.030 split a string into multiple smaller substrings, so to speak. 00:57:57.030 --> 00:57:59.040 For instance, if the human here is in the habit 00:57:59.040 --> 00:58:02.130 of typing in their first name, then a space, and then their last name, 00:58:02.130 --> 00:58:05.070 and you want to go ahead and greet them only by first name, 00:58:05.070 --> 00:58:07.140 well we could actually leverage that single space 00:58:07.140 --> 00:58:09.930 between the first name and last name and split that string 00:58:09.930 --> 00:58:11.760 into two smaller substrings. 00:58:11.760 --> 00:58:12.820 How can we do this? 00:58:12.820 --> 00:58:14.820 Well, let me go ahead and in between these lines 00:58:14.820 --> 00:58:18.210 proactively comment that we're about to split user's 00:58:18.210 --> 00:58:22.230 name into first name and last name. 00:58:22.230 --> 00:58:25.920 And then let's go ahead and take that name variable, which currently contains 00:58:25.920 --> 00:58:28.590 something like, presumably, David, space, Malan, 00:58:28.590 --> 00:58:32.130 and let me go ahead and call split and pass in as the argument 00:58:32.130 --> 00:58:35.820 to split a single white space, thereby indicating that I indeed 00:58:35.820 --> 00:58:37.750 want to split on that character 00:58:37.750 --> 00:58:41.363 Now it turns out split is going to return a sequence of values, ideally 00:58:41.363 --> 00:58:42.780 a first name and then a last name. 00:58:42.780 --> 00:58:45.330 And we can actually, in Python, assign both of those values 00:58:45.330 --> 00:58:47.940 from that sequence at once to some variables. 00:58:47.940 --> 00:58:51.360 For instance, first comma last equals, and that's 00:58:51.360 --> 00:58:53.220 going to have the effect from right to left 00:58:53.220 --> 00:58:56.760 of putting the first such value in the first variable, the second such value 00:58:56.760 --> 00:58:57.880 in the second variable. 00:58:57.880 --> 00:59:01.350 So now on my last line of code, I can go in and say hello 00:59:01.350 --> 00:59:03.900 not to the full name, something like David Malan, 00:59:03.900 --> 00:59:06.540 I can just say Hello, first. 00:59:06.540 --> 00:59:10.200 All right, let's go ahead and clear my terminal window, run Python of Hello.py 00:59:10.200 --> 00:59:10.807 and hit Enter. 00:59:10.807 --> 00:59:13.890 I won't bother with any leading white space this time, but let me go ahead 00:59:13.890 --> 00:59:19.290 and type in David space Malan, and crossing my fingers as usual, Hello, 00:59:19.290 --> 00:59:21.720 David is what we now see. 00:59:21.720 --> 00:59:25.530 All right, so we've seen so much, so many examples thus far involving 00:59:25.530 --> 00:59:29.430 strings, but certainly programs and programming languages can 00:59:29.430 --> 00:59:32.080 manipulate other types of data as well. 00:59:32.080 --> 00:59:36.000 Let's go ahead and transition then to another very common type of data 00:59:36.000 --> 00:59:38.610 in Python, in programming more generally, namely 00:59:38.610 --> 00:59:41.160 integers, otherwise known in Python as INT-- 00:59:41.160 --> 00:59:46.080 I-N-T. So just as STR, S-T-R is short for string, so is INT in Python 00:59:46.080 --> 00:59:47.210 short for integer. 00:59:47.210 --> 00:59:48.210 Well, what's an integer? 00:59:48.210 --> 00:59:51.390 Well just like in math it's a number like negative 2, 00:59:51.390 --> 00:59:55.605 negative 1, 0, 1, 2, and all the way toward negative infinity, all 00:59:55.605 --> 00:59:56.980 the way toward positive infinity. 00:59:56.980 --> 00:59:59.040 But there's no decimal point in an integer. 00:59:59.040 --> 01:00:04.260 It's just a number like negative 2, negative 1, 0, 1, and 2 onward. 01:00:04.260 --> 01:00:05.160 That's an INT. 01:00:05.160 --> 01:00:09.360 Of course, in the world of mathematics, there's lots of symbols that we use. 01:00:09.360 --> 01:00:12.300 And we've seen + before, although we used it for a different purpose. 01:00:12.300 --> 01:00:15.030 But Python supports these symbols and more. 01:00:15.030 --> 01:00:18.090 And Python allows you to add numbers together +, 01:00:18.090 --> 01:00:21.580 subtract numbers, multiply numbers, divide numbers. 01:00:21.580 --> 01:00:25.380 And the only one here that might look a little strange to people or unfamiliar 01:00:25.380 --> 01:00:29.310 is this percent sign, but it doesn't mean percent in this context. 01:00:29.310 --> 01:00:32.400 If you use a single percent sign in a Python program, 01:00:32.400 --> 01:00:34.680 that's actually the so-called modulo operator, 01:00:34.680 --> 01:00:38.400 the operator that allows you to take the remainder after dividing 01:00:38.400 --> 01:00:40.210 one number by another. 01:00:40.210 --> 01:00:43.230 So we'll see examples of that before long, but the first four of these 01:00:43.230 --> 01:00:45.570 are perhaps quite, quite familiar. 01:00:45.570 --> 01:00:49.240 Well it turns out that in Python you cannot necessarily-- 01:00:49.240 --> 01:00:54.480 you don't necessarily have to keep writing code in a file like Hello.py 01:00:54.480 --> 01:00:56.700 and then running it in a terminal window. 01:00:56.700 --> 01:00:59.610 One of the features that many people like about Python 01:00:59.610 --> 01:01:02.250 is that it supports this so-called interactive mode. 01:01:02.250 --> 01:01:06.240 Like you can start writing Python code and immediately execute 01:01:06.240 --> 01:01:08.965 each of those lines interactively, especially 01:01:08.965 --> 01:01:11.340 if you don't care about saving all of your lines of code. 01:01:11.340 --> 01:01:14.590 You just want to execute code and get back some answers. 01:01:14.590 --> 01:01:18.400 So for instance, let me go back to VS Code here and let me close Hello.py 01:01:18.400 --> 01:01:22.050 and let me click on the little triangle over here in my terminal window just 01:01:22.050 --> 01:01:24.880 to make it much bigger just temporarily for a moment. 01:01:24.880 --> 01:01:30.450 So I'm not creating any .py file now, I'm just going to run Python by itself 01:01:30.450 --> 01:01:31.410 at my prompt. 01:01:31.410 --> 01:01:35.100 And you'll see when I do this, I get some cryptic looking output 01:01:35.100 --> 01:01:38.890 and the date and time at which the program was last updated, and so forth. 01:01:38.890 --> 01:01:43.710 But I ultimately get three triple brackets like this. 01:01:43.710 --> 01:01:46.740 Is the interactive mode for Python. 01:01:46.740 --> 01:01:52.050 So I'm running the Python interpreter and any time I type a line of code 01:01:52.050 --> 01:01:54.570 in the interpreter, it's going to execute it immediately. 01:01:54.570 --> 01:01:56.942 I don't have to keep running Python again and again. 01:01:56.942 --> 01:01:58.650 It's as though in the human world, if you 01:01:58.650 --> 01:02:01.635 were standing next to a human who speaks some other language, 01:02:01.635 --> 01:02:04.260 and you're just having a conversation with them back and forth, 01:02:04.260 --> 01:02:07.030 it's all happening-- the translation-- immediately. 01:02:07.030 --> 01:02:08.940 So what might I do in interactive mode? 01:02:08.940 --> 01:02:11.760 Well I could do something like 1 + 1, Enter. 01:02:11.760 --> 01:02:13.380 That's actually code, all right? 01:02:13.380 --> 01:02:16.590 You might not think of it as code, but if a bit of arithmetic and you 01:02:16.590 --> 01:02:21.060 know numbers, and you know +, that's valid Python code. 01:02:21.060 --> 01:02:23.537 And you can use Python really as a fancy calculator. 01:02:23.537 --> 01:02:24.870 But I could do other things too. 01:02:24.870 --> 01:02:28.020 If I want to print to myself Hello, world, 01:02:28.020 --> 01:02:30.750 I can also print out that line of code there too-- 01:02:30.750 --> 01:02:31.530 Hello, world. 01:02:31.530 --> 01:02:33.600 So it's interactive in the sense that the moment 01:02:33.600 --> 01:02:36.960 you execute a line of code, boom, you see the result. 01:02:36.960 --> 01:02:39.450 We're generally not going to do that because at least when 01:02:39.450 --> 01:02:42.810 teaching the language, we tend to want to do things incrementally 01:02:42.810 --> 01:02:45.513 and we want you to be able to see where it is we came from. 01:02:45.513 --> 01:02:48.180 And we want to be able to try things again and again, especially 01:02:48.180 --> 01:02:49.140 if we make mistakes. 01:02:49.140 --> 01:02:51.690 But know that this is indeed a feature of Python, 01:02:51.690 --> 01:02:54.250 this so-called interactive mode. 01:02:54.250 --> 01:02:57.015 But let's focus for a moment now, not just on that interactivity, 01:02:57.015 --> 01:02:58.890 but really on the fact that Python apparently 01:02:58.890 --> 01:03:03.310 supports integers and mathematics and some of those basic operations. 01:03:03.310 --> 01:03:06.430 And let's see if we can't make maybe our own little calculator. 01:03:06.430 --> 01:03:08.820 So let me go ahead and open up VS Code again, 01:03:08.820 --> 01:03:11.440 and I'm going to shrink down my terminal window, 01:03:11.440 --> 01:03:14.610 and I'm going to create a new file called Calculator.py. 01:03:14.610 --> 01:03:17.950 So to do that recall, I can type Code down here, 01:03:17.950 --> 01:03:21.540 and the name of the file I want to create, .py, Enter. 01:03:21.540 --> 01:03:23.550 That gives me a new tab up top. 01:03:23.550 --> 01:03:25.620 So I have already closed Hello.py. 01:03:25.620 --> 01:03:27.150 I'm now in Calculator.py. 01:03:27.150 --> 01:03:30.900 And let's just make a simple calculator that does some addition for me. 01:03:30.900 --> 01:03:33.690 But I'm going to do it in a file so that we can iterate on this 01:03:33.690 --> 01:03:36.607 and make changes for better or for worse over time. 01:03:36.607 --> 01:03:38.940 Let me go ahead and first declare a couple of variables. 01:03:38.940 --> 01:03:42.840 I'm going to do the mathematical thing of calling my first variable x, 01:03:42.840 --> 01:03:45.840 my second variable y, and then I'm going to give myself 01:03:45.840 --> 01:03:48.720 a third variable z = x + y. 01:03:48.720 --> 01:03:50.970 And then I'm going to go ahead and print out z. 01:03:50.970 --> 01:03:54.858 Now this program, admittedly not very exciting or interesting, 01:03:54.858 --> 01:03:57.900 in fact, it's a little less interesting than printing stuff on the screen 01:03:57.900 --> 01:04:01.110 like before with strings, but we'll build on this 01:04:01.110 --> 01:04:04.030 and see what other features exist in Python that we can leverage. 01:04:04.030 --> 01:04:07.410 So hopefully, if Python knows it's math as well as I do, 01:04:07.410 --> 01:04:13.140 when I run Python of Calculator.py, I should see hopefully that 1 + 2 01:04:13.140 --> 01:04:15.600 = indeed 3. 01:04:15.600 --> 01:04:18.510 All right, so not that surprising and not that interesting. 01:04:18.510 --> 01:04:20.730 And honestly this isn't the most useful program 01:04:20.730 --> 01:04:24.840 because it's always going to calculate 1 + 2 = 3. 01:04:24.840 --> 01:04:28.170 Let's at least make this program, say, a little more interactive, right? 01:04:28.170 --> 01:04:31.590 We already know from previous examples how we can get input from the user. 01:04:31.590 --> 01:04:33.540 Let's bring back that input function. 01:04:33.540 --> 01:04:37.380 And let's do this, let me go ahead now and at the top of my code, 01:04:37.380 --> 01:04:40.650 let's change x to not be the number 1 always, 01:04:40.650 --> 01:04:42.510 let's change it to be whatever the return 01:04:42.510 --> 01:04:45.690 value is of asking the user for x. 01:04:45.690 --> 01:04:48.730 And I can use any English or human language I want here. 01:04:48.730 --> 01:04:49.890 I'm going to say, what's x? 01:04:49.890 --> 01:04:52.410 Just like I asked before, what's your name? 01:04:52.410 --> 01:04:54.180 And I'm going to do the same thing for y. 01:04:54.180 --> 01:04:57.330 I'm going to use Input again, but this time change the question to be, 01:04:57.330 --> 01:04:58.728 what's y? 01:04:58.728 --> 01:05:01.770 All right, at this point, I think I'm going to leave the rest of the code 01:05:01.770 --> 01:05:02.730 the same. 01:05:02.730 --> 01:05:06.450 Z = x + y And then print z but what's nice 01:05:06.450 --> 01:05:10.140 now is that I think I have a nice interactive calculator. 01:05:10.140 --> 01:05:12.510 Right, now it's not going to do 1 + 2 all the time. 01:05:12.510 --> 01:05:16.330 It's going to do whatever the user types + whatever the user types. 01:05:16.330 --> 01:05:17.530 So let's try this. 01:05:17.530 --> 01:05:19.080 Let me go ahead and run that program. 01:05:19.080 --> 01:05:20.110 All right, let's do it. 01:05:20.110 --> 01:05:26.670 1 is going to be x, 2 is going to be y, and of course, everyone in agreement, 1 01:05:26.670 --> 01:05:30.762 + 2 = thr-- 01:05:30.762 --> 01:05:31.980 huh. 01:05:31.980 --> 01:05:36.040 What's going on there? 01:05:36.040 --> 01:05:40.720 Either your math class misled you or I have misled you. 01:05:40.720 --> 01:05:43.000 Why don't we call on someone here to see if you 01:05:43.000 --> 01:05:46.900 can't help us reason through what the bug is, what's the mistake? 01:05:46.900 --> 01:05:48.970 Anjali, if I'm saying it right. 01:05:48.970 --> 01:05:52.960 AUDIENCE: I think the issue is that it's concatenating strings because you 01:05:52.960 --> 01:05:54.935 use the + operator instead of adding. 01:05:54.935 --> 01:05:55.810 DAVID MALAN: Perfect. 01:05:55.810 --> 01:05:57.040 So perfect intuition. 01:05:57.040 --> 01:06:01.060 We've seen that + is used a little differently in the context of strings 01:06:01.060 --> 01:06:03.940 because it concatenates, that is, it joins the two strings, 01:06:03.940 --> 01:06:06.100 and that seems to Indeed be what's happening here, 01:06:06.100 --> 01:06:07.990 even though the user typed a number. 01:06:07.990 --> 01:06:09.910 But the interesting thing here is that, when 01:06:09.910 --> 01:06:13.660 you get user input, because they're using a keyboard on their Mac 01:06:13.660 --> 01:06:16.900 or PC or their phone, it is always going to be text. 01:06:16.900 --> 01:06:19.030 It might look like a number, but by default, 01:06:19.030 --> 01:06:21.850 it's coming from the keyboard as a string-- 01:06:21.850 --> 01:06:23.560 that is, as text. 01:06:23.560 --> 01:06:27.760 And so, how do we go about resolving this if ultimately we 01:06:27.760 --> 01:06:30.190 don't want to treat those inputs as strings, 01:06:30.190 --> 01:06:32.110 we want to treat them as actual numbers? 01:06:32.110 --> 01:06:35.050 Well we need another function and it turns out in Python 01:06:35.050 --> 01:06:39.610 that you can convert sometimes from one type of data to another type of data, 01:06:39.610 --> 01:06:43.880 for instance, from string to INT by doing something like this. 01:06:43.880 --> 01:06:46.690 Let me go back into my code and let me change 01:06:46.690 --> 01:06:51.730 x before adding it to y to be whatever the integer version of x 01:06:51.730 --> 01:06:56.030 is, + whatever the integer version of y is. 01:06:56.030 --> 01:06:59.950 So it turns out that INT is not only a type of data in Python, 01:06:59.950 --> 01:07:02.590 it's also a function, and it's a function 01:07:02.590 --> 01:07:05.410 that if you pass in an input, like a string, 01:07:05.410 --> 01:07:09.790 so long as that string looks like a number like 1 or like 2, 01:07:09.790 --> 01:07:13.450 it will convert it to an actual number that you can perform mathematics 01:07:13.450 --> 01:07:14.510 on instead. 01:07:14.510 --> 01:07:18.340 So if I now go back to my terminal window and run Python-- 01:07:18.340 --> 01:07:19.870 and let me show you another trick. 01:07:19.870 --> 01:07:21.580 "Calculator" is kind of a long word. 01:07:21.580 --> 01:07:22.930 It's a little tedious to type. 01:07:22.930 --> 01:07:26.470 Notice what I can do in my terminal window, in a command line 01:07:26.470 --> 01:07:27.460 interface in general. 01:07:27.460 --> 01:07:31.300 If I start typing C-A-L for calculator, I can actually 01:07:31.300 --> 01:07:33.700 hit Tab to finish my thought. 01:07:33.700 --> 01:07:36.550 So auto-complete is possible in a terminal window like this. 01:07:36.550 --> 01:07:39.663 Type the first letter or few letters and then, boom, with Tab, 01:07:39.663 --> 01:07:41.080 it'll finish your thought for you. 01:07:41.080 --> 01:07:44.770 Or you can go back in your history like I did with the Up and Down Arrows. 01:07:44.770 --> 01:07:46.570 Let me go ahead and execute this. 01:07:46.570 --> 01:07:47.270 What's x? 01:07:47.270 --> 01:07:47.770 1. 01:07:47.770 --> 01:07:48.290 What's x? 01:07:48.290 --> 01:07:48.790 2. 01:07:48.790 --> 01:07:49.880 And there we go. 01:07:49.880 --> 01:07:53.050 Now we have a general purpose calculator that's going to support 01:07:53.050 --> 01:07:57.280 not just the addition of 1 and 2, but now any two 01:07:57.280 --> 01:07:58.882 integers that the user types. 01:07:58.882 --> 01:08:00.340 And let me now improve this, right? 01:08:00.340 --> 01:08:03.190 We've seen how we can make improvements to code 01:08:03.190 --> 01:08:05.650 and I don't know if it's going to necessarily be better, 01:08:05.650 --> 01:08:07.000 but let's try this. 01:08:07.000 --> 01:08:09.730 Do I really need the z variable? 01:08:09.730 --> 01:08:13.630 It's worth noting that I'm creating a variable called z, 01:08:13.630 --> 01:08:16.720 and then I'm immediately using it on the next line of code. 01:08:16.720 --> 01:08:20.770 Now that's not that compelling, because if you're creating a variable 01:08:20.770 --> 01:08:23.470 and then immediately using it, but never again using it, 01:08:23.470 --> 01:08:26.890 did you really need to take the time to introduce another symbol 01:08:26.890 --> 01:08:30.279 and another variable just to use it once and only once? 01:08:30.279 --> 01:08:31.090 Well, maybe not. 01:08:31.090 --> 01:08:33.729 Maybe we don't really need z in this way. 01:08:33.729 --> 01:08:38.319 Maybe I should go and do something like this. 01:08:38.319 --> 01:08:41.140 Maybe I should get rid of z here. 01:08:41.140 --> 01:08:45.729 Maybe I should change this to be INT up here, change 01:08:45.729 --> 01:08:50.260 this to be INT up here, doing something that's pretty interesting now. 01:08:50.260 --> 01:08:53.680 Even though it's a bit of new syntax, notice that you 01:08:53.680 --> 01:08:56.380 can nest functions, so to speak. 01:08:56.380 --> 01:09:01.330 You can put one function call that is the use of a function 01:09:01.330 --> 01:09:04.540 inside of the use of another function so that the return 01:09:04.540 --> 01:09:09.040 value of the inner function becomes the argument to 01:09:09.040 --> 01:09:11.410 or the input to the outer function. 01:09:11.410 --> 01:09:14.510 Just like in math, if you have parentheses, parentheses, parentheses, 01:09:14.510 --> 01:09:16.218 your teacher probably taught you to focus 01:09:16.218 --> 01:09:18.430 on what's inside the innermost parentheses first 01:09:18.430 --> 01:09:19.603 and then work your way out. 01:09:19.603 --> 01:09:20.770 Same thing with programming. 01:09:20.770 --> 01:09:22.040 That's what's Python is going to do. 01:09:22.040 --> 01:09:24.729 It's going to look at what's inside of the parentheses first, 01:09:24.729 --> 01:09:26.920 it's going to get the answer, and then it's 01:09:26.920 --> 01:09:30.710 going to pass the return value to the outermost function. 01:09:30.710 --> 01:09:34.600 So what happens on line 1 now is that the input function gets called first, 01:09:34.600 --> 01:09:37.990 then the result of that, quote unquote one 01:09:37.990 --> 01:09:42.670 becomes the input to the INT function, and same on line 2. 01:09:42.670 --> 01:09:47.300 The output of what's y becomes the input to this INT function. 01:09:47.300 --> 01:09:49.479 And now there is no z. 01:09:49.479 --> 01:09:52.210 I could just do print x + y. 01:09:52.210 --> 01:09:56.410 And because I've taken the time to convert each of those strings 01:09:56.410 --> 01:09:58.720 to an integer, I think we're OK. 01:09:58.720 --> 01:10:01.570 So let me try this, Python of Calculator.py, Enter. 01:10:01.570 --> 01:10:05.170 1 and 2, and we're still getting 3. 01:10:05.170 --> 01:10:09.130 Not 12, or not 12, 1,2, we're indeed getting 3. 01:10:09.130 --> 01:10:11.350 And we've additionally gotten rid of the variable 01:10:11.350 --> 01:10:13.900 because we didn't necessarily need it, it seems, 01:10:13.900 --> 01:10:15.490 especially if only using it once. 01:10:15.490 --> 01:10:18.280 Well here too, let me put everyone's hands down for just a moment 01:10:18.280 --> 01:10:19.930 and let me ask as before-- 01:10:19.930 --> 01:10:26.530 this version now which uses INT around the invocations of input, 01:10:26.530 --> 01:10:30.640 and does not use z, is this better than the previous version? 01:10:30.640 --> 01:10:32.560 If you want to vote Yes, go ahead. 01:10:32.560 --> 01:10:35.270 Or if you prefer the old way, vote No. 01:10:35.270 --> 01:10:40.455 The old way, I'll undo all of this as we vote, instead looked like this. 01:10:43.510 --> 01:10:45.850 All right, and let me go back to now the newest version. 01:10:45.850 --> 01:10:48.040 Let's take a hand of the Yeses, someone who 01:10:48.040 --> 01:10:51.430 thinks this latest version is better. 01:10:51.430 --> 01:10:57.130 AUDIENCE: I think this way is better because it allows us to immediately see 01:10:57.130 --> 01:11:01.840 what the x and y variables are with integers 01:11:01.840 --> 01:11:04.660 and so we know what to expect from them. 01:11:04.660 --> 01:11:09.250 And also the print argument is more intuitive. 01:11:09.250 --> 01:11:12.330 We avoid too much clutter in the code. 01:11:12.330 --> 01:11:14.330 DAVID MALAN: I think those are all good reasons. 01:11:14.330 --> 01:11:15.370 It's nice and succinct. 01:11:15.370 --> 01:11:17.650 The lines of code are not very long. 01:11:17.650 --> 01:11:20.530 I don't need to know what z is because it doesn't exist. 01:11:20.530 --> 01:11:21.820 It just sees print x + y. 01:11:21.820 --> 01:11:22.390 I like that. 01:11:22.390 --> 01:11:25.990 But someone who prefers the older way where we did have z 01:11:25.990 --> 01:11:30.970 and we more explicitly passed individual variables to the INT function. 01:11:30.970 --> 01:11:32.050 AUDIENCE: Yeah, hi. 01:11:32.050 --> 01:11:36.100 I think that the earlier version is better because when-- 01:11:36.100 --> 01:11:39.370 I mean, if user input something else other than, 01:11:39.370 --> 01:11:43.570 let's say, I mean, let's say, they type 1 and 2, like, 01:11:43.570 --> 01:11:46.780 so it will be easier to debug. 01:11:46.780 --> 01:11:49.807 DAVID MALAN: This version or-- this version here or the old version? 01:11:49.807 --> 01:11:50.890 AUDIENCE: The old version. 01:11:50.890 --> 01:11:52.098 DAVID MALAN: OK, that's fair. 01:11:52.098 --> 01:11:57.190 And in fact, I'm being very careful today, as best I can, not to mess up. 01:11:57.190 --> 01:12:01.050 I have thus far only inputted integers when I'm expecting integers. 01:12:01.050 --> 01:12:02.800 And Raoul's actually pointing to something 01:12:02.800 --> 01:12:05.980 we'll come back to in the coming weeks, how do we actually handle errors? 01:12:05.980 --> 01:12:09.770 What if the user doesn't type in the number 1 or the number 2, or a number 01:12:09.770 --> 01:12:10.270 at all? 01:12:10.270 --> 01:12:13.390 What if they type in a word like cat, C-A-T? 01:12:13.390 --> 01:12:16.150 That's not a number, and I bet I can't convert it to an integer. 01:12:16.150 --> 01:12:18.110 But for today, I'm not going to focus on that. 01:12:18.110 --> 01:12:20.110 I'm just going to hope that the user cooperates. 01:12:20.110 --> 01:12:21.740 But that's not going to be the case. 01:12:21.740 --> 01:12:24.280 And so perhaps one way would set us up for more success 01:12:24.280 --> 01:12:26.020 when it comes to handling those errors. 01:12:26.020 --> 01:12:28.495 Now for today's purposes, which is better? 01:12:28.495 --> 01:12:29.650 Eh, I mean, I like both. 01:12:29.650 --> 01:12:32.440 And I think both of you made very valid arguments in there too, 01:12:32.440 --> 01:12:36.250 so long as you have a justification that feels pretty reasonable. 01:12:36.250 --> 01:12:37.930 I mean, that's what ultimately matters. 01:12:37.930 --> 01:12:41.500 But acquiring, again, a sense of the trade-offs here. 01:12:41.500 --> 01:12:43.180 Well, is this way better? 01:12:43.180 --> 01:12:44.885 If so, why or why not? 01:12:44.885 --> 01:12:46.760 Just understanding what those trade-offs are. 01:12:46.760 --> 01:12:51.460 But generally speaking, prioritizing readability is a very good thing. 01:12:51.460 --> 01:12:54.740 Making your code readable for someone else is a very good thing 01:12:54.740 --> 01:12:57.608 and very good for you too so that when you wake up the next morning, 01:12:57.608 --> 01:12:59.650 or you come back the next week, or the next year, 01:12:59.650 --> 01:13:02.290 you too can read your own code without having to waste 01:13:02.290 --> 01:13:04.270 time trying to remember what you did. 01:13:04.270 --> 01:13:08.500 And simplicity tends to be a good thing too-- keeping your code simple. 01:13:08.500 --> 01:13:10.960 So as you get more comfortable with programming, 01:13:10.960 --> 01:13:15.250 you might be tempted to try to combine an entire program into one long line. 01:13:15.250 --> 01:13:17.740 For instance, let me do just that. 01:13:17.740 --> 01:13:20.680 Technically speaking, we don't really need x in a variable. 01:13:20.680 --> 01:13:22.480 We don't really need y in a variable. 01:13:22.480 --> 01:13:24.460 We could also do this-- 01:13:24.460 --> 01:13:27.820 I could just get rid of x and y altogether. 01:13:27.820 --> 01:13:32.080 I could then now eliminate that and make it just one line of code. 01:13:32.080 --> 01:13:34.510 OK, so on some sense, you might be inclined to think, wow, 01:13:34.510 --> 01:13:35.740 that's really nice. 01:13:35.740 --> 01:13:38.410 You made it one simple line of code. 01:13:38.410 --> 01:13:40.520 I would argue this actually isn't that simple. 01:13:40.520 --> 01:13:43.180 Now I think I'm starting to nest too many things. 01:13:43.180 --> 01:13:46.330 I have to think about print and INT and input. 01:13:46.330 --> 01:13:49.150 I then have to notice that, OK, I've opened two parentheses, 01:13:49.150 --> 01:13:50.300 I've closed two of them. 01:13:50.300 --> 01:13:51.040 There's a +. 01:13:51.040 --> 01:13:53.680 You're making me think too much and any time you make me think, 01:13:53.680 --> 01:13:54.730 you're wasting time. 01:13:54.730 --> 01:13:58.360 And any time you complicate the look of the code like this, 01:13:58.360 --> 01:14:01.300 you're just going to increase the probability of mistakes 01:14:01.300 --> 01:14:04.270 and tactical mistakes or logical errors in your code. 01:14:04.270 --> 01:14:07.810 So if all the things we've done, this is the only one that I would argue, 01:14:07.810 --> 01:14:10.870 yes, it's one line and it's nice and compact. 01:14:10.870 --> 01:14:12.340 It's just not readable enough. 01:14:12.340 --> 01:14:15.850 I would shy away from doing this, especially since two of those function 01:14:15.850 --> 01:14:18.040 calls are getting input from the user. 01:14:18.040 --> 01:14:20.410 But there too, reasonable people might disagree, 01:14:20.410 --> 01:14:23.830 but that's the kind of visceral reaction you should have sometimes when 01:14:23.830 --> 01:14:28.300 code starts getting a little too complicated, a little too clever, 01:14:28.300 --> 01:14:31.450 perhaps, for its own good. 01:14:31.450 --> 01:14:34.270 All right, well it's not just integers we have access to. 01:14:34.270 --> 01:14:38.920 Let me propose that we transition from integers to one more data type here, 01:14:38.920 --> 01:14:40.360 namely a float. 01:14:40.360 --> 01:14:43.390 So again, a string is a sequence of text. 01:14:43.390 --> 01:14:46.570 An INT is an integer like negative 1, 0 and 1. 01:14:46.570 --> 01:14:50.860 A float is a number with a decimal point, properly called a floating point 01:14:50.860 --> 01:14:51.470 value. 01:14:51.470 --> 01:14:53.470 And you can think of the floating point as being 01:14:53.470 --> 01:14:56.740 the decimal that might be over here or over here with some number of digits 01:14:56.740 --> 01:14:57.820 to the left or the right. 01:14:57.820 --> 01:15:02.000 Mathematically, it's a real number, a number that has a decimal point in it. 01:15:02.000 --> 01:15:04.750 So that's a third type of data that Python supports. 01:15:04.750 --> 01:15:07.270 Right now our calculator is somewhat naively 01:15:07.270 --> 01:15:09.820 assuming that the user is only going to type in integers, 01:15:09.820 --> 01:15:12.970 but if I want to support floating point values too, 01:15:12.970 --> 01:15:15.070 I think I can just make a couple of tweaks. 01:15:15.070 --> 01:15:17.270 So I'm going to go back to VS Code here. 01:15:17.270 --> 01:15:20.890 And instead of just converting the user's input x and y to 01:15:20.890 --> 01:15:23.950 integers on line 1 and 2, let's just make a simple change. 01:15:23.950 --> 01:15:27.400 Let's actually convert it to a float on the first line 01:15:27.400 --> 01:15:30.640 and a float on the second line here. 01:15:30.640 --> 01:15:35.410 Now I think, if I go down to my terminal window and run Python of Calculator.py, 01:15:35.410 --> 01:15:39.040 let's type in a number like 1.2 with a decimal point 01:15:39.040 --> 01:15:42.100 and 3.4 with a decimal point, and there we go. 01:15:42.100 --> 01:15:44.510 We have 4.6 as the final answer. 01:15:44.510 --> 01:15:48.250 So that wouldn't have worked before if I was only expecting integers 01:15:48.250 --> 01:15:51.550 from the user, but now that I'm expecting floating point values 01:15:51.550 --> 01:15:56.180 and accommodating it, I can actually now do floating point arithmetic as well. 01:15:56.180 --> 01:15:59.020 But suppose that I don't really want the final answer 01:15:59.020 --> 01:16:03.160 to be a floating point value like 4.6. 01:16:03.160 --> 01:16:05.930 I would be happy if we just round to the nearest integer. 01:16:05.930 --> 01:16:08.800 So I want to support the user typing in floating point 01:16:08.800 --> 01:16:11.120 values with decimal points, but at the end of the day, 01:16:11.120 --> 01:16:15.760 I just want to round the result to the nearest possible integer, for instance. 01:16:15.760 --> 01:16:20.830 Well it turns out that here too Python comes with some functionality built in. 01:16:20.830 --> 01:16:23.620 And in fact, if we return to this URL from earlier 01:16:23.620 --> 01:16:26.560 wherein all of the Python built-in functions are listed, 01:16:26.560 --> 01:16:29.200 there's one called "round" which does exactly 01:16:29.200 --> 01:16:31.510 as we would expect, it takes as input a number 01:16:31.510 --> 01:16:36.860 and then rounds it for us, for instance, to the nearest integer. 01:16:36.860 --> 01:16:40.390 But if we look a little closer at that documentation as we can here-- 01:16:40.390 --> 01:16:41.710 I'll provide an excerpt-- 01:16:41.710 --> 01:16:45.400 this is what the function looks like in the documentation. 01:16:45.400 --> 01:16:48.550 And recall that earlier we looked at the documentation for print 01:16:48.550 --> 01:16:51.550 and this is similar in spirit that this shows us not just 01:16:51.550 --> 01:16:54.880 the name of the function but its available parameters, that is, 01:16:54.880 --> 01:16:57.850 inputs that we can provide when using this function. 01:16:57.850 --> 01:17:00.280 But this is a little cryptic too, just like Print was, 01:17:00.280 --> 01:17:01.640 and it adds some syntax. 01:17:01.640 --> 01:17:02.290 So let's see. 01:17:02.290 --> 01:17:04.630 The name of this function here is of course Round 01:17:04.630 --> 01:17:07.450 and its first argument is a number. 01:17:07.450 --> 01:17:10.548 Notice this time there's no star, there's no star objects 01:17:10.548 --> 01:17:11.590 like there was for print. 01:17:11.590 --> 01:17:16.000 The Round function takes just one number as its first argument, period. 01:17:16.000 --> 01:17:18.820 That's its positional parameter. 01:17:18.820 --> 01:17:20.420 But notice this syntax. 01:17:20.420 --> 01:17:22.720 And this is a convention in programming or technology 01:17:22.720 --> 01:17:26.260 more generally, generally speaking, when you see square brackets 01:17:26.260 --> 01:17:28.630 and documentation like this, this means that you're 01:17:28.630 --> 01:17:30.370 about to see something optional. 01:17:30.370 --> 01:17:32.350 And so what this means is that if you want 01:17:32.350 --> 01:17:37.480 to specify more precisely the number of digits that you want the round function 01:17:37.480 --> 01:17:43.760 to round to, you can specify it here by adding a comma and then that number. 01:17:43.760 --> 01:17:48.190 So if we read the documentation, if you don't specify a number of digits, 01:17:48.190 --> 01:17:52.000 you just specify the number to round, it rounds to the nearest integer. 01:17:52.000 --> 01:17:55.990 But suppose you want around to the tenths place, or the hundredths place 01:17:55.990 --> 01:17:58.330 that is one or two digits after the decimal point, 01:17:58.330 --> 01:18:04.167 you could additionally pass in comma 1 or comma 2 to be more precise. 01:18:04.167 --> 01:18:06.250 So that's what the documentation, there is saying. 01:18:06.250 --> 01:18:10.460 Let's see if we can't then translate this to some actual code for us. 01:18:10.460 --> 01:18:13.630 So if I go back now to VS Code and I consider 01:18:13.630 --> 01:18:18.350 that I want to go ahead and round x and y, I can do this in a couple of ways. 01:18:18.350 --> 01:18:22.630 I could do round x + y, but you know, I'd 01:18:22.630 --> 01:18:25.210 actually kind of prefer to break this now out into two lines. 01:18:25.210 --> 01:18:28.300 I don't have to, and reasonable people here might disagree, 01:18:28.300 --> 01:18:31.330 but I'd like to revert to a scenario where I'm printing z, 01:18:31.330 --> 01:18:34.270 so that I can just a little more clearly to myself, to others, 01:18:34.270 --> 01:18:38.890 say z = the rounded result of x + y. 01:18:38.890 --> 01:18:41.060 It's not necessarily the better way to do it, 01:18:41.060 --> 01:18:44.690 but I'm a little more comfortable with breaking out my thoughts one at a time, 01:18:44.690 --> 01:18:47.882 especially if I want to start commenting each of these chunks of code. 01:18:47.882 --> 01:18:49.840 All right, let me go down to my terminal window 01:18:49.840 --> 01:18:52.120 now and run Python of Calculator.py. 01:18:52.120 --> 01:18:52.840 What's x? 01:18:52.840 --> 01:18:54.490 Let's do 1.2 again. 01:18:54.490 --> 01:18:56.260 Then let's do 3.4. 01:18:56.260 --> 01:18:59.980 And now it was previously 4.6, but now it's 01:18:59.980 --> 01:19:04.540 been rounded up to the nearest integer, which of course is going to be 5. 01:19:04.540 --> 01:19:09.050 All right, what if I wanted to change this a little further? 01:19:09.050 --> 01:19:11.830 What if I wanted to support maybe really big numbers, 01:19:11.830 --> 01:19:15.872 big numbers, irrespective of rounding, let's just do something like this. 01:19:15.872 --> 01:19:17.830 Let me go ahead and run Python of Calculator.py 01:19:17.830 --> 01:19:22.270 again and let me just add 999 + 1. 01:19:22.270 --> 01:19:25.030 And notice, I don't have to type decimal points, 01:19:25.030 --> 01:19:27.340 even though I'm converting to float, my program 01:19:27.340 --> 01:19:30.840 will just allow me to type decimal points, but I don't need to oblige. 01:19:30.840 --> 01:19:34.110 The answer of course here should be, and is in fact, 1,000, 01:19:34.110 --> 01:19:35.670 whether or not we round. 01:19:35.670 --> 01:19:38.470 So that's just arithmetic with integers here. 01:19:38.470 --> 01:19:44.640 But in the US, we tend to format long numbers by putting commas 01:19:44.640 --> 01:19:47.580 after or before every triple of digits. 01:19:47.580 --> 01:19:50.660 Other countries flip it and they use periods and commas instead. 01:19:50.660 --> 01:19:51.660 That's a system setting. 01:19:51.660 --> 01:19:53.700 You can change that on your own Mac or PC 01:19:53.700 --> 01:19:57.000 or device for Python or any language, but for me, I'm 01:19:57.000 --> 01:20:01.200 using the US approach here, which is periods for decimal points 01:20:01.200 --> 01:20:02.940 and commas for separators. 01:20:02.940 --> 01:20:07.890 What if I wanted this to be outputted as 1,000? 01:20:07.890 --> 01:20:12.180 Just to make it a little more clear that it's 1,000 and not something like 100. 01:20:12.180 --> 01:20:14.580 That's even more useful when it's like one million-- 01:20:14.580 --> 01:20:18.060 1,000,000. 01:20:18.060 --> 01:20:19.950 Wouldn't it be nice if we could automatically 01:20:19.950 --> 01:20:21.540 output those numbers as well? 01:20:21.540 --> 01:20:23.700 Well, it turns out that we can. 01:20:23.700 --> 01:20:28.410 There is a way using Python to actually specify that we 01:20:28.410 --> 01:20:30.540 want to include commas like this. 01:20:30.540 --> 01:20:34.800 And here we have an opportunity to bring back our old friend, the F string. 01:20:34.800 --> 01:20:37.440 First, let me do something that's not that productive. 01:20:37.440 --> 01:20:38.760 First let me do this. 01:20:38.760 --> 01:20:41.610 Let me print out the value of z, but wait a minute. 01:20:41.610 --> 01:20:44.850 I can't just say "z" because that's literally going to print z 01:20:44.850 --> 01:20:45.820 on the screen. 01:20:45.820 --> 01:20:49.050 So let me wrap it with those curly braces like I did before, 01:20:49.050 --> 01:20:50.550 but that too was not enough. 01:20:50.550 --> 01:20:54.060 I literally needed to add an F at the beginning of my string 01:20:54.060 --> 01:20:56.940 to tell Python that this is an F string, a format string. 01:20:56.940 --> 01:21:01.650 That now is going to print out, not very interestingly, just the value of z 01:21:01.650 --> 01:21:02.320 itself. 01:21:02.320 --> 01:21:06.270 So I'm going to great lengths just to print z when really I could have just 01:21:06.270 --> 01:21:07.890 passed z as the sole argument. 01:21:07.890 --> 01:21:11.820 But just to ensure that I haven't broken it, let's do this again. 01:21:11.820 --> 01:21:14.190 999 + 1, Enter. 01:21:14.190 --> 01:21:15.300 OK, it's still 1,000. 01:21:15.300 --> 01:21:16.950 So I didn't make anything worse. 01:21:16.950 --> 01:21:20.460 But notice-- and this syntax is unfortunately a bit cryptic-- 01:21:20.460 --> 01:21:22.380 notice that I can actually do this. 01:21:22.380 --> 01:21:27.450 I can put a colon after the z and I can put a comma thereafter. 01:21:27.450 --> 01:21:29.763 This looks very cryptic, admittedly, and even I 01:21:29.763 --> 01:21:32.430 have to constantly look things like this up in the documentation 01:21:32.430 --> 01:21:33.750 to remember the syntax. 01:21:33.750 --> 01:21:35.460 But here, let me run it again. 01:21:35.460 --> 01:21:41.250 Python of Calculator.py, 999 1 and now notice 01:21:41.250 --> 01:21:43.928 that the number has been automatically formatted for me. 01:21:43.928 --> 01:21:45.720 If I were in a different country or locale, 01:21:45.720 --> 01:21:49.620 I could absolutely override this to use periods instead of commas or vise 01:21:49.620 --> 01:21:50.290 versa. 01:21:50.290 --> 01:21:52.990 But in this case here, it's just happening for me automatically. 01:21:52.990 --> 01:21:56.310 So there too we see a hint of what it means to really format a string. 01:21:56.310 --> 01:21:57.720 There's even more power-- 01:21:57.720 --> 01:22:00.633 more powerful capabilities built into that. 01:22:00.633 --> 01:22:02.550 All right, let me pause here to see if there's 01:22:02.550 --> 01:22:10.200 any questions now on floats, on rounding, or on this use of F strings. 01:22:10.200 --> 01:22:11.700 AUDIENCE: Yes, so I have a question. 01:22:11.700 --> 01:22:14.760 So when using floats, is there like a cap 01:22:14.760 --> 01:22:16.860 to how many decimal points it can have? 01:22:16.860 --> 01:22:18.360 DAVID MALAN: A really good question. 01:22:18.360 --> 01:22:21.150 So floats, yes, and this is a problem we'll revisit before long. 01:22:21.150 --> 01:22:25.590 Floats cannot represent numbers infinitely precisely. 01:22:25.590 --> 01:22:28.112 In a nutshell, because computers only have so much memory. 01:22:28.112 --> 01:22:29.820 They only have a finite amount of memory. 01:22:29.820 --> 01:22:34.200 You and I only have a finite amount of hardware inside of the computer, 01:22:34.200 --> 01:22:36.540 so at some point, they're going to have to round. 01:22:36.540 --> 01:22:38.190 Right now I'm rounding automatically. 01:22:38.190 --> 01:22:40.732 Effectively computers will eventually have to do that for us, 01:22:40.732 --> 01:22:44.010 but we'll see that as a fundamental problem before long. 01:22:44.010 --> 01:22:47.385 Allow me to turn back just for a few final examples on float 01:22:47.385 --> 01:22:50.010 before we introduce a few final examples that allow us not just 01:22:50.010 --> 01:22:52.290 to use functions, but to make our own. 01:22:52.290 --> 01:22:56.940 Let me propose that we also try our hands at a bit of division here. 01:22:56.940 --> 01:22:59.250 Let me propose that we modify this calculator now 01:22:59.250 --> 01:23:01.740 to still take a couple of floats, but let's now just do 01:23:01.740 --> 01:23:04.050 something a little simpler than-- 01:23:04.050 --> 01:23:07.085 a little different from this, just doing x divided by y. 01:23:07.085 --> 01:23:09.210 And let me go ahead and get rid of my format string 01:23:09.210 --> 01:23:12.383 and just keep it simple for now, printing out z instead. 01:23:12.383 --> 01:23:13.800 And what are we going to see here? 01:23:13.800 --> 01:23:15.092 Well just some simple division. 01:23:15.092 --> 01:23:19.920 So Python of Calculator.py, let's do something like 2 divided by 3, 01:23:19.920 --> 01:23:21.960 and of course I get 0.66666. 01:23:21.960 --> 01:23:25.600 And to Ethan's question a moment ago, it does seem to be finite. 01:23:25.600 --> 01:23:30.180 It's not rounding in a weird way here, but I only seem to see so many digits. 01:23:30.180 --> 01:23:34.170 That's an inevitability of using a float in this way. 01:23:34.170 --> 01:23:37.620 By contrast, just so you know, integers nowadays in Python 01:23:37.620 --> 01:23:39.690 can be as big as you want them to be. 01:23:39.690 --> 01:23:41.910 Unlike other languages, there is no upper bound 01:23:41.910 --> 01:23:44.550 on how big an INT can be now in Python, but there 01:23:44.550 --> 01:23:48.225 is a bound on just how precise a floating point value can be. 01:23:48.225 --> 01:23:50.850 All right, now that I've got some simple division working here, 01:23:50.850 --> 01:23:52.380 let's go ahead and round this. 01:23:52.380 --> 01:23:57.060 It would be nice to round this really long number 0.6666666 and so forth 01:23:57.060 --> 01:23:59.190 to maybe just two decimal places. 01:23:59.190 --> 01:24:02.460 We've seen how to do this with round, though, at least in its documentation. 01:24:02.460 --> 01:24:04.980 Let's just round this not to the nearest INT, 01:24:04.980 --> 01:24:09.810 by passing in just x divided by y, which is one argument, once the math is 01:24:09.810 --> 01:24:13.350 done inside of the parentheses, I don't want to pass in just one argument. 01:24:13.350 --> 01:24:17.100 I want to pass in two so that I can specify n digits, 01:24:17.100 --> 01:24:21.030 number of digits, which you'll recall was the second parameter for round. 01:24:21.030 --> 01:24:23.240 Let me go ahead and run Python of Calculator.py. 01:24:23.240 --> 01:24:24.240 I'll do the same thing-- 01:24:24.240 --> 01:24:27.300 2 and then 3, 0.67. 01:24:27.300 --> 01:24:31.130 So here too we see a way of rounding now, not just to a nearest integer, 01:24:31.130 --> 01:24:34.160 but to a nearest number of digits. 01:24:34.160 --> 01:24:36.300 But there's another way to do this here. 01:24:36.300 --> 01:24:40.920 And in fact, this evokes our F string example again. 01:24:40.920 --> 01:24:42.270 Let me go ahead and change this. 01:24:42.270 --> 01:24:45.740 Suppose that you didn't remember the round function or, for some reason, 01:24:45.740 --> 01:24:46.940 you didn't want to use it. 01:24:46.940 --> 01:24:49.340 You instead want to just use a format string. 01:24:49.340 --> 01:24:50.510 Well, let's go there. 01:24:50.510 --> 01:24:55.280 Let me do "z" but let me surround it with those curly braces. 01:24:55.280 --> 01:24:58.850 Let me add the F at the beginning, and again, this is not interesting yet. 01:24:58.850 --> 01:25:02.300 This is just going to print out z, but I'm adding a lot more complexity 01:25:02.300 --> 01:25:03.920 to turn it into an F string. 01:25:03.920 --> 01:25:08.940 But notice I can do something else after my variable name, after the colon. 01:25:08.940 --> 01:25:11.300 If this were going to be a big integer, I 01:25:11.300 --> 01:25:15.200 might want to use a comma like before to separate each triple of numbers 01:25:15.200 --> 01:25:15.950 with commas. 01:25:15.950 --> 01:25:16.580 But I don't. 01:25:16.580 --> 01:25:20.120 I'm going to use a different sequence of characters. 01:25:20.120 --> 01:25:25.190 I'm going to say 0.2F and this too is one of these very cryptic things I have 01:25:25.190 --> 01:25:28.040 to constantly look up because I forget if I don't use it that often. 01:25:28.040 --> 01:25:32.030 So don't be intimidated if this looks especially weird, but this is, 01:25:32.030 --> 01:25:33.950 according to the documentation, the way you 01:25:33.950 --> 01:25:37.830 specify using an F string how many digits you want to print. 01:25:37.830 --> 01:25:39.980 So let me run this version of the calculator. 01:25:39.980 --> 01:25:43.170 Type in 2 and then 3, we get the exact same thing. 01:25:43.170 --> 01:25:45.350 But again, this is just consistent with my claim 01:25:45.350 --> 01:25:49.580 that in programming we can so very often solve the same problem 01:25:49.580 --> 01:25:51.030 in multiple ways. 01:25:51.030 --> 01:25:56.240 This is just now the F string approach to that very same problem. 01:25:56.240 --> 01:25:57.630 All right, which one is better? 01:25:57.630 --> 01:25:58.310 It depends. 01:25:58.310 --> 01:26:00.200 In this case, they're pretty equivalent. 01:26:00.200 --> 01:26:03.260 You can imagine, though, it being useful to use a function sometimes 01:26:03.260 --> 01:26:07.340 so that you can pass in an argument like n digits as that second argument, 01:26:07.340 --> 01:26:10.700 or you can imagine just deciding in advance that you want 0.2 01:26:10.700 --> 01:26:13.370 and then writing it like this. 01:26:13.370 --> 01:26:17.300 Let's transition now from focusing on strings and on integers and on 01:26:17.300 --> 01:26:19.880 floats to focusing now on functions themselves. 01:26:19.880 --> 01:26:21.860 We began today by focusing on how you can 01:26:21.860 --> 01:26:24.230 use functions that come with Python. 01:26:24.230 --> 01:26:26.990 But wouldn't it be nice if you could invent your own functions, 01:26:26.990 --> 01:26:29.330 especially if, to our point earlier, you find 01:26:29.330 --> 01:26:32.210 yourself solving the same kind of problem again and again? 01:26:32.210 --> 01:26:34.700 It's nice that Python comes with the print function 01:26:34.700 --> 01:26:37.130 because it's really useful to be able to print things on the screen, 01:26:37.130 --> 01:26:40.130 but wouldn't it be nice if you could print specific things on the screen 01:26:40.130 --> 01:26:42.170 by just calling your own function? 01:26:42.170 --> 01:26:44.100 Well let me propose that we do this. 01:26:44.100 --> 01:26:49.760 Let me go back to VS Code here and let me propose that we go back to Hello.py. 01:26:49.760 --> 01:26:52.820 I'm going to reopen Hello.py where we left it before 01:26:52.820 --> 01:26:54.620 and I'm going to go ahead now and propose 01:26:54.620 --> 01:26:58.460 that we consider how we can start improving this further by making 01:26:58.460 --> 01:26:59.330 our own function. 01:26:59.330 --> 01:27:03.380 I have written so many programs today that just say Hello 01:27:03.380 --> 01:27:05.360 and each time I'm using print. 01:27:05.360 --> 01:27:08.090 But wouldn't it have been nice if, from the beginning of today, 01:27:08.090 --> 01:27:12.620 we could just call a function called Hello that just says Hello for us? 01:27:12.620 --> 01:27:15.080 Now the authors of Python years ago didn't 01:27:15.080 --> 01:27:18.020 think that we need a special function just to say Hello, 01:27:18.020 --> 01:27:19.820 but I would like that to exist. 01:27:19.820 --> 01:27:21.980 I'm saying Hello so many times, I just want 01:27:21.980 --> 01:27:23.600 to be able to call a function Hello. 01:27:23.600 --> 01:27:25.550 So I'm going to start from scratch here. 01:27:25.550 --> 01:27:27.680 I'm going to delete all of my code from earlier 01:27:27.680 --> 01:27:32.510 and I'm going to pretend for the moment that a function called Hello exists. 01:27:32.510 --> 01:27:34.250 And I'm going to do just as I did before. 01:27:34.250 --> 01:27:36.740 I'm going to get the user's name with the input function, 01:27:36.740 --> 01:27:39.110 asking what's your name, question mark. 01:27:39.110 --> 01:27:42.230 And now I'm going to call a function Hello 01:27:42.230 --> 01:27:45.260 and then I'm going to print out the user's name. 01:27:45.260 --> 01:27:50.190 Now I will admit, Hello doesn't exist, so bad things are about to happen, 01:27:50.190 --> 01:27:51.440 but let's see what. 01:27:51.440 --> 01:27:53.210 Let me go down to my terminal window. 01:27:53.210 --> 01:27:55.700 Let me run Python of Hello.py. 01:27:55.700 --> 01:27:59.030 I think the first line is going to be OK because that worked before. 01:27:59.030 --> 01:28:01.280 And indeed, it's prompting me for my name. 01:28:01.280 --> 01:28:02.780 So let me type in David. 01:28:02.780 --> 01:28:05.090 The second line of code is apparently calling 01:28:05.090 --> 01:28:08.840 a function that looks like it's called Hello, because why is it a function? 01:28:08.840 --> 01:28:11.820 It has a parenthesis and a closed parenthesis immediately after it. 01:28:11.820 --> 01:28:14.300 And that's what every function we've used has looked like. 01:28:14.300 --> 01:28:16.340 But Python is not going to recognize this one. 01:28:16.340 --> 01:28:18.890 When I hit Enter now, I get a name error. 01:28:18.890 --> 01:28:21.950 Name "Hello" is not defined, did you mean Help? 01:28:21.950 --> 01:28:26.120 I didn't, although it's opportune that's what I need at this point is some help, 01:28:26.120 --> 01:28:29.540 but I am encountering this error because why? 01:28:29.540 --> 01:28:31.440 The function just doesn't exist. 01:28:31.440 --> 01:28:33.350 So how do I make this function exist? 01:28:33.350 --> 01:28:39.440 Well I need to create it myself using this key word, DEF, DEF for define. 01:28:39.440 --> 01:28:43.610 So here too, just as STR is short for string and INT is short for integer, 01:28:43.610 --> 01:28:45.830 DEF is short for define. 01:28:45.830 --> 01:28:50.330 If and when you want to define, create, invent your own functions, 01:28:50.330 --> 01:28:53.870 you can do so using now this keyword in Python. 01:28:53.870 --> 01:28:58.310 So let me go back to my code here and let me propose that we define this 01:28:58.310 --> 01:28:59.900 perhaps in this way. 01:28:59.900 --> 01:29:02.660 At the very top of my file, I'm going to first take 01:29:02.660 --> 01:29:05.150 a moment to define a function called Hello 01:29:05.150 --> 01:29:10.430 using DEF Hello, open parenthesis, close parenthesis, colon. 01:29:10.430 --> 01:29:15.110 What this means now is that Python is going to treat every line of code 01:29:15.110 --> 01:29:20.240 that I indent underneath this one as the meaning of this new function, Hello. 01:29:20.240 --> 01:29:23.030 So DEF is important as is the space. 01:29:23.030 --> 01:29:26.577 I get to choose the name of the function and I'm choosing to call it Hello. 01:29:26.577 --> 01:29:29.660 The parentheses with nothing inside means that this function at the moment 01:29:29.660 --> 01:29:32.540 is not going to take any inputs, no arguments there too. 01:29:32.540 --> 01:29:35.810 The colon means, stay tuned for some indentation. 01:29:35.810 --> 01:29:38.750 Everything that's indented beneath this line of code 01:29:38.750 --> 01:29:40.310 is going to be part of this function. 01:29:40.310 --> 01:29:42.920 It's going to be a super short function-- one line of code-- 01:29:42.920 --> 01:29:46.040 it's just going to print out "Hello." 01:29:46.040 --> 01:29:51.830 But now on lines 1 and 2, I have invented my own function Hello. 01:29:51.830 --> 01:29:54.740 Notice these dots that have now magically appeared here. 01:29:54.740 --> 01:29:56.660 This is just a setting of my text editor, 01:29:56.660 --> 01:30:00.470 VS Code in this case, that's just making super explicit to me that I've 01:30:00.470 --> 01:30:04.160 hit the space bar four times, or equivalently the Tab key once, 01:30:04.160 --> 01:30:07.018 which is converted automatically to four spaces. 01:30:07.018 --> 01:30:10.310 Generally speaking, I'm going to need to make sure that all of my indented code 01:30:10.310 --> 01:30:14.150 lines up now so that Python knows that it's all part of the same thing. 01:30:14.150 --> 01:30:16.770 But it's easy in this case because it's just a single line. 01:30:16.770 --> 01:30:20.810 But now, thanks to lines 1 and 2, the function Hello 01:30:20.810 --> 01:30:24.920 will absolutely exist when I'm ready to use it on line 6. 01:30:24.920 --> 01:30:29.180 So let me go down to my terminal window and run Python of Hello.py, Enter. 01:30:29.180 --> 01:30:30.570 Here comes my name again. 01:30:30.570 --> 01:30:35.120 And now when I hit Enter, I now see Hello, David. 01:30:35.120 --> 01:30:37.190 All right, we've kind of regressed though, right? 01:30:37.190 --> 01:30:39.960 This is not nearly as pretty as it once was. 01:30:39.960 --> 01:30:44.840 I think we can probably do better than this by improving things further. 01:30:44.840 --> 01:30:47.510 Why don't we consider, though, how we might 01:30:47.510 --> 01:30:50.480 say parameterize this same function? 01:30:50.480 --> 01:30:55.010 That is to say, can we customize Hello to maybe take the user's name as input 01:30:55.010 --> 01:31:00.020 so that we can say, not only Hello, but the person's name all on one line, all 01:31:00.020 --> 01:31:01.070 in one breath? 01:31:01.070 --> 01:31:02.450 Well I think we can do this. 01:31:02.450 --> 01:31:05.400 Let me propose that we do this as follows. 01:31:05.400 --> 01:31:10.100 Let me go ahead and up in my code, let me inside of these parentheses, 01:31:10.100 --> 01:31:12.350 let me come up with my own parameter name. 01:31:12.350 --> 01:31:14.510 I have complete choice here and I'm going 01:31:14.510 --> 01:31:17.780 to say that the name of my parameter will be the word To. 01:31:17.780 --> 01:31:18.500 Why? 01:31:18.500 --> 01:31:22.970 Because I want my function to sound like the verb it represents-- 01:31:22.970 --> 01:31:23.690 Hello. 01:31:23.690 --> 01:31:25.610 But who do you want to say Hello to? 01:31:25.610 --> 01:31:27.860 Well I'm going to call my parameter for this function 01:31:27.860 --> 01:31:30.860 To, just because in English, it kind of sounds nice to me. 01:31:30.860 --> 01:31:32.900 Hello To, who do you want to say Hello to? 01:31:32.900 --> 01:31:36.050 That's why I'm calling this parameter To instead of something 01:31:36.050 --> 01:31:38.360 simpler like x or y or z. 01:31:38.360 --> 01:31:40.798 All right, well what do I want to do with the word To? 01:31:40.798 --> 01:31:42.590 Well I can do a couple of different things. 01:31:42.590 --> 01:31:45.320 We've seen like so many different ways to implement Hello. 01:31:45.320 --> 01:31:48.000 Let me just add a comma there for grammar's sake. 01:31:48.000 --> 01:31:52.700 And then let me put the word To after that as the second argument 01:31:52.700 --> 01:31:53.715 to the function Hello. 01:31:53.715 --> 01:31:56.090 There's other ways we can do this and we've seen so many, 01:31:56.090 --> 01:31:58.940 but this one looks a little clear to me, I'll say. 01:31:58.940 --> 01:32:00.380 What's going to happen next? 01:32:00.380 --> 01:32:03.470 Well I don't think I need this extra print line here. 01:32:03.470 --> 01:32:07.040 I think what I'm going to do is this, I'm going to go ahead here 01:32:07.040 --> 01:32:12.740 and print out not the person's name manually, I'm going to instead say, 01:32:12.740 --> 01:32:15.410 Hello parentheses name. 01:32:15.410 --> 01:32:16.880 So what am I now doing? 01:32:16.880 --> 01:32:20.690 On lines 1 and 2 I'm defining my very own function called Hello, 01:32:20.690 --> 01:32:23.240 but this time that function has been designed 01:32:23.240 --> 01:32:26.750 to take a parameter, a single parameter, as input. 01:32:26.750 --> 01:32:29.810 And I'm using the value of that parameter which 01:32:29.810 --> 01:32:33.470 I called To to plug into print so that I see not only 01:32:33.470 --> 01:32:35.780 Hello but also that person's name. 01:32:35.780 --> 01:32:37.070 What am I doing on line 5? 01:32:37.070 --> 01:32:39.140 Same as always, I'm just getting the user's name. 01:32:39.140 --> 01:32:42.140 Line 6, I'm not only calling Hello, I'm passing 01:32:42.140 --> 01:32:46.500 as input the name variable as an argument 01:32:46.500 --> 01:32:48.912 so that that's what gets passed into Hello. 01:32:48.912 --> 01:32:50.870 And what's happening here is essentially this-- 01:32:50.870 --> 01:32:54.710 even though the variable is called Name here, when the function 01:32:54.710 --> 01:33:00.920 itself is called, the computer assumes that same value is now called To. 01:33:00.920 --> 01:33:04.760 So Name is essentially copied to another variable called 01:33:04.760 --> 01:33:11.420 To so that in the context of Hello, I can say Hello to that variable instead. 01:33:11.420 --> 01:33:15.140 And we'll see in a moment what happens if we don't keep those straight. 01:33:15.140 --> 01:33:17.600 Let me go ahead and run Python of Hello.py, Enter. 01:33:17.600 --> 01:33:18.540 What's your name? 01:33:18.540 --> 01:33:20.060 And now I'm crossing my fingers. 01:33:20.060 --> 01:33:20.840 Enter. 01:33:20.840 --> 01:33:21.750 There we go. 01:33:21.750 --> 01:33:25.700 We're back in business, but now I have my own custom function called Hello 01:33:25.700 --> 01:33:28.550 that's allowing me to say Hello to a specific person. 01:33:28.550 --> 01:33:30.980 And here's where now things can get really fancy. 01:33:30.980 --> 01:33:34.220 What if you wanted your Hello function to say Hello to someone specific, 01:33:34.220 --> 01:33:37.070 but, you know what, if you don't know who you want to say Hello to, 01:33:37.070 --> 01:33:38.840 you want to say Hello to the whole world, 01:33:38.840 --> 01:33:41.300 you can give parameters default values. 01:33:41.300 --> 01:33:42.060 We've seen that. 01:33:42.060 --> 01:33:45.530 Recall that with print there was a default value for SEP, 01:33:45.530 --> 01:33:46.550 for the separator. 01:33:46.550 --> 01:33:49.700 There was a default value for END, the line ending. 01:33:49.700 --> 01:33:52.280 We can do that too, and here's the syntax. 01:33:52.280 --> 01:33:56.390 If you want the value of this parameter by default, 01:33:56.390 --> 01:34:00.620 if not provided by the programmer, to be equal to "world," 01:34:00.620 --> 01:34:05.155 you literally do that in the same line you're defining the function. 01:34:05.155 --> 01:34:07.280 And I'll admit, it's starting to look more cryptic, 01:34:07.280 --> 01:34:10.580 but I'm still just defining a function called Hello, it 01:34:10.580 --> 01:34:13.820 takes a parameter called To, but I'm assigning it 01:34:13.820 --> 01:34:19.340 with the equal sign a default value of "world," just in case the programmer 01:34:19.340 --> 01:34:22.310 doesn't call Hello with an argument. 01:34:22.310 --> 01:34:23.660 And we can see this here. 01:34:23.660 --> 01:34:26.750 Let me change my code to use Hello in two ways. 01:34:26.750 --> 01:34:31.880 On line 5, I'm going to very simply call Hello, no arguments. 01:34:31.880 --> 01:34:33.710 Then on line 6, I'm going to get the name. 01:34:33.710 --> 01:34:36.320 Line 7, I'm going to call Hello with an argument. 01:34:36.320 --> 01:34:39.060 So you'll see Hello now being used in two ways. 01:34:39.060 --> 01:34:41.960 Let me go ahead and run Python of Hello.py. 01:34:41.960 --> 01:34:43.310 I'll type in my name. 01:34:43.310 --> 01:34:44.630 Oh, interesting. 01:34:44.630 --> 01:34:47.120 Notice I already see Hello, world, but that's 01:34:47.120 --> 01:34:52.070 expected because line 5 happens before line 6, but once I type my name, 01:34:52.070 --> 01:34:55.940 now the program is going to be a little more polite and say hello to me 01:34:55.940 --> 01:34:57.180 personally. 01:34:57.180 --> 01:35:01.550 So there too, we see with relatively simple but new syntax 01:35:01.550 --> 01:35:05.990 how you can implement functionality very similar in spirit to what the print 01:35:05.990 --> 01:35:07.860 function gave us automatically. 01:35:07.860 --> 01:35:10.940 Now you have control over doing that yourself. 01:35:10.940 --> 01:35:12.980 But let me now make this point too. 01:35:12.980 --> 01:35:15.530 One of the whole points of defining your own functions 01:35:15.530 --> 01:35:18.680 is one, just to avoid having to repeat yourself again and again. 01:35:18.680 --> 01:35:21.890 You don't have to actually keep reinventing the wheel 01:35:21.890 --> 01:35:24.480 and keep using the print function again, and again, and again, 01:35:24.480 --> 01:35:25.850 if you just want to say Hello. 01:35:25.850 --> 01:35:29.780 Wouldn't it be nice now if I could move this code 01:35:29.780 --> 01:35:34.010 that I wrote for defining the Hello function, and just to be dramatic, 01:35:34.010 --> 01:35:37.760 I'm going to hit Enter a whole lot of times, 50 lines down, 01:35:37.760 --> 01:35:41.240 and put my definition of Hello way further down in this file. 01:35:41.240 --> 01:35:41.840 Why? 01:35:41.840 --> 01:35:44.720 Well, just for in the spirit of out of sight, out of mind, 01:35:44.720 --> 01:35:48.800 because if I now rewind to the start of my program, now 01:35:48.800 --> 01:35:51.240 you can take for granted that, oh, Hello is a function. 01:35:51.240 --> 01:35:51.740 Why? 01:35:51.740 --> 01:35:54.740 Because it's there on line 1 and it has an open parenthesis and a closed 01:35:54.740 --> 01:35:57.560 parenthesis, which, up until now has meant, call this function. 01:35:57.560 --> 01:36:00.200 And then on line 2 we're getting a variable from the user 01:36:00.200 --> 01:36:04.620 by typing in their name and then we're calling Hello, passing in that value. 01:36:04.620 --> 01:36:07.790 Well at this point, I can just take for granted that Hello exists, 01:36:07.790 --> 01:36:11.360 even if it's way down further in the file or, as we'll see in future weeks, 01:36:11.360 --> 01:36:13.970 even if it's in a different file altogether. 01:36:13.970 --> 01:36:15.500 But there's a problem here. 01:36:15.500 --> 01:36:19.190 And let me go ahead and run this version of Hello.py. 01:36:19.190 --> 01:36:23.270 Notice that as soon as I run the interpreter, Python of Hello.py, 01:36:23.270 --> 01:36:26.360 I see a name error, name Hello is not defined. 01:36:26.360 --> 01:36:28.280 Again, did you mean Help? 01:36:28.280 --> 01:36:29.480 Well, again, fitting. 01:36:29.480 --> 01:36:33.500 I do need some help here, but I didn't mean to call the function Help. 01:36:33.500 --> 01:36:36.650 The problem here, though, is that Python is just taking me literally. 01:36:36.650 --> 01:36:40.610 I have defined my function Hello all the way down here, 01:36:40.610 --> 01:36:42.500 but I'm trying to use it way up here. 01:36:42.500 --> 01:36:43.465 And that's not allowed. 01:36:43.465 --> 01:36:45.590 Python's interpreter is going to take you literally 01:36:45.590 --> 01:36:47.810 and if you use a function, it must already 01:36:47.810 --> 01:36:50.390 exist by the time you are calling it. 01:36:50.390 --> 01:36:51.600 So how do I fix this? 01:36:51.600 --> 01:36:53.270 Well, apparently I can't do that. 01:36:53.270 --> 01:36:57.440 I have to define any functions I want at the very top of my file, 01:36:57.440 --> 01:36:59.720 but that too could get me into a bit of trouble 01:36:59.720 --> 01:37:04.640 eventually because if I constantly have to define a function above where I want 01:37:04.640 --> 01:37:07.010 to use it, you're kind of writing code in reverse, 01:37:07.010 --> 01:37:09.218 you're constantly writing functions up here, up here, 01:37:09.218 --> 01:37:12.450 up here, as opposed to writing your code logically, top to bottom. 01:37:12.450 --> 01:37:16.190 So let me fix this in a more standard way, which is to do this. 01:37:16.190 --> 01:37:20.990 Generally speaking, you do want to put the main part of your code 01:37:20.990 --> 01:37:22.530 at the top of your file. 01:37:22.530 --> 01:37:27.110 And in fact, I'm going to go so far as to define my function, called Main. 01:37:27.110 --> 01:37:29.540 It's not a requirement, but it's in data convention, 01:37:29.540 --> 01:37:31.910 and this just connotes to the reader that this 01:37:31.910 --> 01:37:33.620 is the main part of my program. 01:37:33.620 --> 01:37:38.030 I'm going to get rid of my empty Hello call now and only pass in one version 01:37:38.030 --> 01:37:39.110 with Hello, name. 01:37:39.110 --> 01:37:42.260 And then down here, a couple of lines further down, 01:37:42.260 --> 01:37:45.030 I'll actually define my Hello function. 01:37:45.030 --> 01:37:47.870 Unfortunately, now that I've reordered the functions in this way, 01:37:47.870 --> 01:37:51.890 by putting the main part of my code at the top and Hello at the bottom 01:37:51.890 --> 01:37:55.310 so that my logic kind of flows top to bottom, if I go ahead and run 01:37:55.310 --> 01:37:57.680 Python of Hello.py, Enter. 01:37:57.680 --> 01:38:00.290 Nothing whatsoever happens. 01:38:00.290 --> 01:38:02.630 If I do it again, nothing whatsoever happens. 01:38:02.630 --> 01:38:04.520 Well, why in the world is this? 01:38:04.520 --> 01:38:06.740 Well, just because I've defined a function called 01:38:06.740 --> 01:38:09.230 Main and I've defined a function called Hello, 01:38:09.230 --> 01:38:11.420 doesn't mean that I've actually called-- 01:38:11.420 --> 01:38:13.340 that is used-- either of them. 01:38:13.340 --> 01:38:16.970 Yes, I'm using Hello inside of Main, but no one 01:38:16.970 --> 01:38:20.210 is telling Python to actually use or call Main. 01:38:20.210 --> 01:38:24.770 So in order to tidy this up, the last thing I need to do in this file, 01:38:24.770 --> 01:38:28.100 it seems, is actually call my main function. 01:38:28.100 --> 01:38:30.890 And, in fact, by calling my main function in this way, 01:38:30.890 --> 01:38:33.890 it gets me out of trouble because now I'm defining Main first 01:38:33.890 --> 01:38:35.450 but I'm not calling Hello yet. 01:38:35.450 --> 01:38:38.760 I'm defining Hello next, but I'm not calling Hello next. 01:38:38.760 --> 01:38:42.170 I only at the very end of this file call Main 01:38:42.170 --> 01:38:45.090 which has the effect of running this code up here, 01:38:45.090 --> 01:38:47.690 which has the effect of running this code down here, 01:38:47.690 --> 01:38:50.870 and it allows me therefore to organize my file 01:38:50.870 --> 01:38:55.520 and order my functions in any way I want, including Main at the very top, 01:38:55.520 --> 01:38:59.930 and solving ultimately that problem of Python not knowing what's going on. 01:38:59.930 --> 01:39:02.780 Now it's important to note that I defined my function 01:39:02.780 --> 01:39:05.690 Hello as taking an argument To and then I 01:39:05.690 --> 01:39:08.390 passed into that function the value of the variable 01:39:08.390 --> 01:39:11.570 that I wanted to say Hello to, that is the variable called Name. 01:39:11.570 --> 01:39:14.420 Because suppose I had done something a little bit differently. 01:39:14.420 --> 01:39:17.670 Suppose that I hadn't defined Hello is taking an argument, 01:39:17.670 --> 01:39:21.560 so I just remove mention of To and its default value "world." 01:39:21.560 --> 01:39:25.070 And I go back up to my main function and I just 01:39:25.070 --> 01:39:28.193 call Hello itself without passing in any arguments. 01:39:28.193 --> 01:39:30.360 And now let me go ahead and make my one more change, 01:39:30.360 --> 01:39:32.760 one more mistake technically, let me go ahead 01:39:32.760 --> 01:39:37.720 and just try to naively print out the value of Name in the Hello function. 01:39:37.720 --> 01:39:40.380 So now to be clear, in my main function on line 2, 01:39:40.380 --> 01:39:43.740 I'm defining my variable called Name and assigning it the return value 01:39:43.740 --> 01:39:45.480 of the input function from the user. 01:39:45.480 --> 01:39:47.010 I'm then just calling Hello. 01:39:47.010 --> 01:39:50.700 In my Hello function, which now no longer takes any arguments, 01:39:50.700 --> 01:39:54.180 I am calling print, passing in Hello comma, 01:39:54.180 --> 01:39:56.970 and then immediately passing in Name, the variable 01:39:56.970 --> 01:39:58.740 into which I got the user's input. 01:39:58.740 --> 01:40:02.232 But the catch is that name exists now only in Main. 01:40:02.232 --> 01:40:05.190 And so watch what happens when I try to run this version of the program 01:40:05.190 --> 01:40:07.170 with Python Hello.py. 01:40:07.170 --> 01:40:08.220 I hit Enter. 01:40:08.220 --> 01:40:10.500 I'm prompted for my name, D-A-V-I-D, Enter. 01:40:10.500 --> 01:40:11.340 And, argh! 01:40:11.340 --> 01:40:12.450 A name error. 01:40:12.450 --> 01:40:15.400 Name "Name" is not defined. 01:40:15.400 --> 01:40:19.050 So it turns out that this is actually an issue of what's called scope. 01:40:19.050 --> 01:40:23.970 Scope refers to a variable only existing in the context in which you defined it. 01:40:23.970 --> 01:40:28.080 So insofar as I define this variable, Name in my main function, 01:40:28.080 --> 01:40:31.020 I can only use that variable in my name function. 01:40:31.020 --> 01:40:34.380 I can't use it as I've tried to here in my Hello function. 01:40:34.380 --> 01:40:36.930 It doesn't exist in that so-called scope. 01:40:36.930 --> 01:40:42.010 And so this is why now, if I rewind and undo all of those changes, 01:40:42.010 --> 01:40:45.690 you'll see that I'm deliberately passing Main from my main function 01:40:45.690 --> 01:40:47.340 into my Hello function. 01:40:47.340 --> 01:40:50.260 And now in the Hello function, it technically has a different name. 01:40:50.260 --> 01:40:52.380 It's called To in that context, but that's fine. 01:40:52.380 --> 01:40:55.950 It's completely up to each individual function to name its own variables 01:40:55.950 --> 01:40:58.230 or name its own arguments, but this is a way now 01:40:58.230 --> 01:41:01.630 that I'm handing to the Hello function the value of that variable 01:41:01.630 --> 01:41:04.530 so it can be printed by Hello as well. 01:41:04.530 --> 01:41:07.410 And there's one final flourish we can add here. 01:41:07.410 --> 01:41:10.590 Now that we've implemented Hello, you'll notice that Hello only 01:41:10.590 --> 01:41:12.120 has a so-called side effect. 01:41:12.120 --> 01:41:14.580 It only prints out something to the screen. 01:41:14.580 --> 01:41:19.980 Well, what if I also want my function to not have a side effect, per se, 01:41:19.980 --> 01:41:22.300 but actually hand me back a value? 01:41:22.300 --> 01:41:25.740 Recall that the input function returns a value, 01:41:25.740 --> 01:41:27.510 the string that the user typed in. 01:41:27.510 --> 01:41:30.060 Recall that the INT function returns a value. 01:41:30.060 --> 01:41:33.960 The float function returns a value that was passed into it. 01:41:33.960 --> 01:41:37.260 Well you can use one final keyword here, literally 01:41:37.260 --> 01:41:40.890 Return to return a value explicitly yourself. 01:41:40.890 --> 01:41:43.890 In fact, let me go back to VS Code here, and I 01:41:43.890 --> 01:41:47.820 think we'll return our attention to Calculator.py 01:41:47.820 --> 01:41:53.190 and see if we can't implement one other version of Calculator.py that actually 01:41:53.190 --> 01:41:56.410 has our own function that even returns a value. 01:41:56.410 --> 01:41:59.800 So I'm going to go ahead and open up calculator/py 01:41:59.800 --> 01:42:03.100 and I think this time I'm going to throw everything away as before, 01:42:03.100 --> 01:42:06.600 and I'm just going to start practicing what we're preaching here. 01:42:06.600 --> 01:42:09.120 Define a function called Main which is now going 01:42:09.120 --> 01:42:11.070 to be the main part of my function. 01:42:11.070 --> 01:42:13.980 Let's go ahead and now declare a variable called x, 01:42:13.980 --> 01:42:19.350 and assign it to the converted version of the user's input after asking them, 01:42:19.350 --> 01:42:20.430 what's x? 01:42:20.430 --> 01:42:23.490 So again, a line of code quite like we've done before. 01:42:23.490 --> 01:42:27.023 And suppose now that what I want to do is square this value. 01:42:27.023 --> 01:42:29.190 I want to take the number that the user has typed in 01:42:29.190 --> 01:42:30.840 and raise it to the power of 2. 01:42:30.840 --> 01:42:32.790 So 2 squared would be 4. 01:42:32.790 --> 01:42:34.410 3 squared would be 9. 01:42:34.410 --> 01:42:36.840 4 squared would be 16, and so forth. 01:42:36.840 --> 01:42:39.450 Well how do I go about implementing a function literally 01:42:39.450 --> 01:42:42.960 called Square which actually doesn't come with Python built-in? 01:42:42.960 --> 01:42:45.660 Well, let me assume for the moment that it does exist, and let 01:42:45.660 --> 01:42:47.530 me say something like this-- 01:42:47.530 --> 01:42:50.670 let me go ahead and say that printing, how 01:42:50.670 --> 01:42:57.720 about x squared is comma square of x. 01:42:57.720 --> 01:42:59.170 So what have I done? 01:42:59.170 --> 01:43:02.710 I've defined a function called Main and I've implemented two lines. 01:43:02.710 --> 01:43:05.190 The first of these lines prompts the user for a value 01:43:05.190 --> 01:43:09.330 x and converts it to an INT and stores it in a variable called x. 01:43:09.330 --> 01:43:12.930 On line 3, I then say x squared is and then 01:43:12.930 --> 01:43:16.620 I pass a second argument to the print function, whatever the return 01:43:16.620 --> 01:43:18.780 value is of a square function. 01:43:18.780 --> 01:43:22.230 But squared doesn't exist and I'll show you this here, 01:43:22.230 --> 01:43:30.090 if I now call Main at the bottom and I run Python of Calculator.py, 01:43:30.090 --> 01:43:35.100 I'll see that x is 2 and then I see a whole bunch of errors, a name error, 01:43:35.100 --> 01:43:37.090 name Square is not defined. 01:43:37.090 --> 01:43:39.810 So this isn't a typo here, it's just the function doesn't exist. 01:43:39.810 --> 01:43:41.790 But I think I can make it exist here. 01:43:41.790 --> 01:43:45.180 Let me go ahead and define another function called Square. 01:43:45.180 --> 01:43:47.400 This one's going to take in a number and I'm 01:43:47.400 --> 01:43:50.370 going to call it generically n, as many a programmer would, 01:43:50.370 --> 01:43:52.260 just to represent any old number. 01:43:52.260 --> 01:43:56.010 And then what do I want to do in order to square n? 01:43:56.010 --> 01:43:59.380 Well a number squared is really just itself times itself, 01:43:59.380 --> 01:44:00.720 so I'm going to do this-- 01:44:00.720 --> 01:44:02.340 n times n. 01:44:02.340 --> 01:44:06.180 But it's not enough just to do the math yourself, n times n. 01:44:06.180 --> 01:44:09.990 You're going to have to return the actual value n times n 01:44:09.990 --> 01:44:11.970 and that's our new keyword here. 01:44:11.970 --> 01:44:14.100 When I now do this, watch what happens. 01:44:14.100 --> 01:44:16.230 Python of Calculator.py, Enter. 01:44:16.230 --> 01:44:20.250 X say shall be 2, x squared is 4. 01:44:20.250 --> 01:44:24.020 Let me go ahead now and say x is now 3. 01:44:24.020 --> 01:44:26.010 X squared is now 9. 01:44:26.010 --> 01:44:30.060 So I've implemented my very own function that returns the square of a value 01:44:30.060 --> 01:44:33.180 and because I'm using the return keyword, that 01:44:33.180 --> 01:44:36.120 ensures that I can pass the return value of this, just 01:44:36.120 --> 01:44:40.140 like the return value of input or INT or float, to another function, 01:44:40.140 --> 01:44:41.460 like print instead. 01:44:41.460 --> 01:44:44.520 And here too there's going to be so many ways to solve this same problem. 01:44:44.520 --> 01:44:47.490 I can actually raise n to the power of 2. 01:44:47.490 --> 01:44:49.620 We've not seen this syntax before, but if you 01:44:49.620 --> 01:44:54.220 use two asterisks like this, two stars, that raises the thing on the left 01:44:54.220 --> 01:44:55.590 to the power on the right. 01:44:55.590 --> 01:44:58.290 Or it turns out there is in Python a function called 01:44:58.290 --> 01:45:00.480 POW for raising something to the power that 01:45:00.480 --> 01:45:04.200 takes two arguments, the first of which is the number, the second of which 01:45:04.200 --> 01:45:05.140 is the exponent. 01:45:05.140 --> 01:45:09.810 So there too, there's just so many ways to actually solve that same problem 01:45:09.810 --> 01:45:11.290 as well. 01:45:11.290 --> 01:45:13.020 So ultimately, what have we done here? 01:45:13.020 --> 01:45:15.960 We first introduced functions-- these actions or verbs, many of which 01:45:15.960 --> 01:45:19.000 come built into Python that you can just use in your own code. 01:45:19.000 --> 01:45:22.290 We then introduced variables via which you could store those return values 01:45:22.290 --> 01:45:24.120 and then maybe do something more with it. 01:45:24.120 --> 01:45:25.350 At the end of the day too. 01:45:25.350 --> 01:45:28.260 You now have the ability to create, to invent your own functions 01:45:28.260 --> 01:45:30.750 to solve simple problems like Hello, or in the weeks 01:45:30.750 --> 01:45:36.590 to come-- much more sophisticated, more challenging, more fun problems as well.