CS50 for Business - Lecture 3 - Practicing Programming

CS50 for Business - Lecture 3 - Practicing Programming

Machine-readable: Markdown · JSON API · Site index

Поделиться Telegram VK Бот
Транскрипт Скачать .md
Анализ с AI

Оглавление (35 сегментов)

Segment 1 (00:00 - 05:00)

Hello world. My name is David Malan, and today we'll be practicing programming. Now we're not going to aspire in just a few hours together to turn you into programmers. Indeed, that's something that can take quite some time, but we will familiarize you with some of the underlying principles of and skills related to programming itself so that you're more conversant in what programmers do. You can ask more informed questions and frankly, you'll have a better understanding of how software around us ultimately works. Now, ultimately this might very well whet your appetite to learn all the more about programming. And indeed you'll get some of the fundamentals today, so a foundation on which you can build. Now I say we'll be practicing programming because we kind of sort of did a bit of this already in the course's first lecture. Recall that I acted out this algorithm of finding someone like John Harvard in the phone book, and then we translated what I did sort of intuitively that third and final algorithm to this so-called pseudo code, which were terse English instructions that really captured step by step the algorithm that I was purporting. To implement, but we did this because there were a few salient ideas within this pseudo code alone. And to be clear, pseudo code is not some formal language. It's just my own inclination to use short English phrases to state what I was doing. You might have used slightly different words. a language other than English, but pseudo code is a nice way of just expressing your thoughts akin to a how a computer might expect step by step, a la algorithms more generally. And recall that we highlighted a few of the key phrases here. So pick up open. To look at, call, open to and quit. We're all actions, calls to action, verbs, if you will, and we call those the other day functions. And today we're going to see all the more functions in actual code as well. We then took a look at if ES if, Ls if, and ETS, which were representative of conditional forks in the road via which you can decide to go this way or this other way metaphorically inside of a computer. But how do you decide which direction to go? Well, those were the boolean expressions named after a mathematician. Bull, whereby the answer to a boolean expression must be true or false, or if you prefer yes or no. So person is on page, person is earlier in book, person is later in book were all questions that I might have asked myself in order to determine should I be searching to the left or to the right or maybe right there in front of me already. Lastly, we saw this phrase, go back to, which was representative of what we're again going to call a loop, some kind of sick. structure that makes me do something again and again, probably not forever, but until some condition is true like one of those boolean expressions a moment ago. So these functions and conditionals and boolean expressions and loops and more are going to underlie most all of today's programs and indeed in what's called procedural programming, you see these kinds of ideas everywhere whether it's in pseudo code like this or as we'll see today where we'll spend much of our time, a language, a popular. Language called Python. Now of course pseudo code is not one standard, but when it comes to actually programming computers themselves, we do tend to need to standardize how we're expressing ourselves. Now this is already beginning to evolve with AI and natural language processing, where increasingly you can in fact just use your English words, not unlike pseudocode to command a computer to do something, but somehow or other the computer is then translating what you have said into the underlying building blocks that. We will spend our time on today. So these ideas, these fundamentals aren't going anywhere. And indeed among the values of learning how to program is that you do learn to think, I dare say, more methodically. You can break down problems into smaller problems and ultimately be a better problem solver. And if and when those processes get boring to you, easy for you, I mean that's a good time at which to outsource it, so to speak, to the uh the AIs of the world and let them do those tasks for you. But for now we're going to focus on. Exactly these fundamentals and really talk about code, the instructions that humans write in order to instruct a computer to do something step by step. So it's a translation into text, typically an algorithm which could be expressed as we've already seen in other ways like pseudo code. Unfortunately, computers, as you might recall, only understand zeros and ones, the so-called binary system, and inside of the computer's memory or RAM, there's so many of these zeros and ones, and some of those zeros and ones might represent. Uh, numbers as we've seen or letters or maybe colors or images or videos or sound or really anything else, but those zeros and ones ultimately need to be understood by the underlying computer, the so-called CPU, the central processing unit or brain

Segment 2 (05:00 - 10:00)

and in fact, not all of those zeros and ones are just data files, for instance. Some of those zeros and ones might actually be instructions, so. Speak and very simple instructions typically like add two numbers together or subtract 2 numbers or load something from memory into the CPU or store something from the CPU into memory. That is to say, when you have a CPU inside of the computer, among the things it does is these very low level instructions, and those instructions have been standardized by companies like Intel and Apple and AMD and others. So each computer. Has a so-called instruction set, a set of commands represented in zeros and ones that it and it alone understands. So unfortunately this is not going to be very fun for us to write if practicing programming is going to be practicing a whole bunch of zeros and ones, I'd claim that by looking at these zeros and ones you probably can't glean what this program does. If a computer were to read these zeros and ones top to bottom, left to right, what does it do? Of course it prints out Hello world, a very friendly greeting to the human user. Now no normal person can actually grok what's on the screen here. It would be painstaking to go through all of these zeros and ones and look up what they mean, but computers, of course, can understand this right away. But I think it would be nicer for you and me at least if we don't have to bother writing what we're going to start calling machine code, the zeros and ones that computers ultimately understand. It's going to be a lot more pleasant and a lot more productive for you and I to write what the world calls source code. So when people say code, they generally mean source code specifically, and this means the code, the text that the humans write and then feed into the computer somehow to get it converted at the end of the day. To zeros and ones. So for instance, here is one form of source code. This is a language broadly known as assembly language. If it looks a bit cryptic to you, it does and always has for decades. In fact, I had to write this in school myself, a different variant thereof, and I've forgotten most of the fun most of the specifics, but this is how people program for quite some time, just beyond the days of punch cards for those of you familiar with those. Once we had a keyboard in front of us that we could store data in digitally, we were essentially storing. Instructions and data like this, but there are some insights we can glean like push cue seems to sound like push move cue, probably move, maybe moving things around in memory, calling, which is a vernacular that we'll soon see popping, which is a phrase that we've actually seen in the context of data structures and stacks and then perhaps some familiar words, most important of which is this phrase down here hello, comma world, which is going to be exactly the phrase I claim that those zeros and ones output. So even though you might not believe me. It is a lot easier to implement Hello World, a program that just prints that on the screen, in assembly language certainly than it would have been to implement it by hand using zeros and ones, AKA machine code. But even this decades ago, humans realized, yeah, we can do it, especially with a lot of practice, but this isn't very pleasant to write in and frankly it's not very readable by others. Unless they too are very learned in the language. So over time humans began to abstract on top of these lower level languages on top of the machine code, assembly code, so we had more modern languages like this one here. This is a popular omnipresent still language known as C that similarly just prints out hello world. It too is a bit cryptic. Like I don't know what hash includes standard IO in angled brackets and then these parentheses and curly braces. Like there's a lot of syntax going on here, a lot of text, a lot of punctuation, if you will, but at the end of the day this program too is going to just print to the screen Hello world. But with a lot less effort than it would have taken me to implement that same program. In assembly language and way less effort than it would have taken for me to implement it in zeros and ones. That is machine code. But there's other variants of this same program. In fact, Hello world is written can be written in most any programming language. Here, for instance, is a inspired language called C++, which came a bit later. Here is a language called Java that similarly is quite popular, but here too the key detail is that same phrase is in there. But here too, both with C++ and Java, there's a lot. Overhead syntactically. And so what's nice about the language that we're going to spend a lot of our time with today in particular is that Python, a very popular language nowadays, not just for writing code more generally, but specifically for crunching numbers, analyzing data, cleaning up data, or implementing web applications and more, Python really tends to be simpler than a lot of programming languages, and that's one of the reasons behind its popularity. Case in point, if you want to implement a program in Python. That prints to the screen quite simply Hello world. Well, you just write this Print open parentheses quote unquote hello world. Now

Segment 3 (10:00 - 15:00)

to be fair, there's still some syntax there. There's parentheses, there's double quotes, but I dare say this is the easiest of the versions to write, but Python itself is nonetheless very powerful. It's just the humans that invented it and have evolved it over time have tried to make it read as much like English as is possible with one of these programming languages. So if you're curious to see what other programming languages exist in the wild, you can actually go to Wikipedia to such URLs as this, and you'll see dozens, hundreds, some even thousands of programming languages via which you can write not just Hello World, but any other program. And in fact, if you're curious to see Hello world. Specifically at this website here is a massive list of implementations of Hello World in bunches of languages. In fact, it's kind of a fun way to get a quick sense of what other languages look like, albeit for implementing something relatively simple like printing to the screen. All right, so if we now have source code at our disposal in any of these languages, but soon we'll focus indeed on Python, how do we actually get the computers to understand that source code if again all they understand at the end of the day is machine code, the underlying zeros and ones? Well, there's a few different paradigms that the world has had over the years to achieve precisely that goal. For instance, if we draw an abstract drawing here with the CPU, the computer's brain, or Central processing unit all along the bottom here. I've got 3 columns ready to go here because I'm going to propose that we consider 3 different ways of getting source code to be understood by computers. Why? Well, again, it's a lot more fun and pleasant for you and I to write code in Python, it would seem, than in machine code 0s and 1s. So how can we get from one to the other? Well, one common paradigm is to do this. You need to get to machine code at the end of the day because that is what is understood by the underlying. CPU, but you and I again would like to focus on writing source code. So how do we get from source code to machine code? Well, years ago, humans invented, if you will, wrote software called a compiler, and there's many compilers in the world, but at one point there was one first compiler, and its purpose in life was simply to translate one language into another. In this case, it might have translated the source code, for instance, written in C, into the underlying. machine code zeros and ones and compilers really more broadly just convert one language to another so we can convert among all of the languages we've discussed thus far down to assembly language down to those zeros and ones. Their purpose in life really is to make your life and mine easier, allowing you and I to think at and write code at a fairly high level of abstraction, if you will. Give me print hello world on the screen without having to worry about the underlying zeros and ones. Someone else. than me, put in the time to write code that implemented a compiler so that I can just run the compiler by like double clicking an icon or typing some command in my computer to convert my source code into machine code. And the upside of this is that even though it might take a moment, a second, a few seconds, maybe a few minutes for massively large projects to convert source code to machine code, once it's saved as zeros and 1's, it's going to be really fast on my Mac, my PC, or my phone. And in fact this is the paradigm that C still follows, and C, even though it's an older language now by decades, still incredibly omnipresent because it fits in nicely to this model of compiling down to very fast zeros and ones. Moreover, you can leave it to the computer scientists of the world and the software developers to write really good code for the compiler itself so that the compiler turns even your messy code, your inefficient code into something even faster underneath the hood. Now that's not the only way because I'll claim that it's a little annoying to have to write your code, compile your code, run your code, make a change to your code, recompile your code, run your code, and repeat and repeat. It's just another step. And indeed if it takes a few seconds, it just gets annoying over time. So there's other models that some languages tend to follow whereby you and I can write source code, but we don't bother converting it to machine code per. Say we just feed it into an interpreter and an interpreter is just another piece of software that's been designed to understand the language top to bottom, left to right, if you will, and understand and interpret what it wants you to do. So if it sees print, it's gonna print on the screen. If it sees move, it's gonna move something around in memory. If it sees uh save, it's gonna save a file to disk. In other words, the interpreter's just going to translate much like a human interpreter translating between two spoken human languages converts one input to a corresponding output. And long story short, this model just tends to be convenient if nothing else, because you can write your code and then interpret your code. That is, run it straight away. You can change your code, you can reinterpret it. That is rerun it. So you eliminate. This sort of middle step

Segment 4 (15:00 - 20:00)

but there's going to be a trade off, as is always the case. Interpreting a program tends to be slower than actually compiling a program and then running it. So it indeed might depend on your goals, which you want to optimize for. And yet increasingly we have this third model that we'll look at here whereby you and I get to write source code. We run it through a compiler and that compiler converts the source code into what we'll. Generally called bytecode, and bytecode is just an intermediate representation. It's not really zeros and ones, but it's closer to zeros and ones, if you will, which just means it's even easier to take it that final mile and get it into the zeros and ones that the machine expects. But what you do is you actually feed that bytecode not directly into the CPU but into what's generally called a virtual machine. A virtual machine might be something you're familiar with in the corporate world, for instance, whereby. Might have familiarity with products like VMware and similar where you can run Windows on a Mac or you can run multiple operating systems on the same computer or you can connect to a remote desktop somehow or other, but virtual machines are very commonly used even on laptops and desktops and phones and other devices to take as input bytecode code that someone else output it in an intermediate representation, not quite zeros and ones, and those zeros and ones are understood by. Virtual machine and the virtual machine is just always running in this case on the CPU and so it's effectively interpreting the bytecode. And here's where we won't get too lost in the weeds because all of these models do have some overlap. I'm saying I'm using interpreted and compiling sort of both in this middle column, but what's nice about this middle column, which is increasingly common, is a lot of these steps are automated so you don't actually have to manually compile your source code. Into bytecode you just run your code with some command or some click of a button and all of this just kind of happens automatically. Moreover, what often happens too is the bytecode is cached that is saved somewhere on your hard drive or maybe in the cloud so that the compilation step doesn't have to happen again if you haven't actually changed the source code. So in short, what you're really seeing in this simple picture alone is the evolution of programming paradigms over the years. Where humans and businesses have realized, hey, how can we speed up our code when it's running and how can we speed up the writing of the code before we even run it and so you're seeing an evolution of how these all work and indeed AI is just one another level of abstraction on top of this whereby you don't even write the source code, you just say the English or some other human language and then somehow or other all of these other steps would seem to happen automatically underneath the hood for you. So today we're going to focus primarily on Python, a very popular and relatively simple programming language. The goal is again not to make you completely comfortable with the language, but with the ideas that it implements, because the ideas that Python implements and offers to you and me as programmers is generally representative of features you would see in many other. Programming languages as well. And indeed this is the case in general for software engineers. You might take a course in learning some programming language. You might study a particular programming language and then another, but at some point you just start to teach yourself new languages as by reading documentation or asking some AI or asking some colleague or looking at other. Examples because once you've seen a range of programming languages, maybe Python among them, you'll start to notice patterns, similar paradigms, similar features, and even though the syntax, the text that you type looks a little different, most of that is not intellectually interesting, it's the ideas underlying it that are, and indeed we'll focus today primarily on the ideas while still having some fun with the code itself along the way. So this is what I want to write as my very first program and printing out Hello world to the screen is sort of every programmer's first program canonically, but how can I actually make that happen? Well, of course I've just typed it on the screen here in a slide, and that's fine, but I should really be typing it in a better place, a program that's designed to actually understand what it is I'm typing, not just display it. And a very popular tool for just that nowadays is called Visual Studio Code. It's largely open source software backed by Microsoft. That is increasingly popular not just to develop for Windows computers but Macs for Linux devices, for phones, it's a very popular text editor, so to speak, that shares features what are generally called integrated development environments or IDEs because if you add in lots of plugins and lots of other features, this program in particular can do a lot for you, and there are many alternatives and you can certainly use any number of the alternatives, but we for this course will provide you with a cloud-based version thereof if only so that you don't have to deal. The inevitable technical support headaches of trying to install something, configure it, getting it to work on your computer and your version of an operating system, which often tends to get in the way of actually learning the interesting stuff. So we'll get you started as in the course's assignments with a cloud-based version that just works

Segment 5 (20:00 - 25:00)

but you can also download for free tools like Visual Studio Code onto your own Mac or PC and actually get it up and running locally without any need for internet or the course's own infrastructure. And this is what we're about to see. A screenshot thereof. This is Visual Studio code as it might look if you have created a file called by convention hello. i. i. py indicates that this is a file that's just text, but that's written in a language called Python, and other languages like C might use a. c file extension. Languages like Java might use. and the like. So. pi is for Python. Now there's essentially 1234 main components of the screen here. So. At the left is the so-called activity bar, which is essentially the menu where you have bunches of icons, this one being the File Explorer, that let you access different features of the software. I'll generally hide that on my computer just to free up some space, but you'll see it by default. Over here is the so-called Explorer, which shows you all of the files in your account. Now, when I took this screenshot, I had already created one such file called hello. ie, and that's why we see it right here. When you first fire up VS code for short, AKA Visual Studio code, you. You might not see anything in that window, or you might see even more depending on how you start the software. Now up here is the actual file I created. It has a tabbed interface just like today's browsers do, and you have print hello world there in that file, a single line of code on line one. Now notice it's color coded. This is purple, this is blue, and then the rest of it is black. That's not something I did manually. This isn't a word processing program like Microsoft Word or Google Docs or the like where I highlighted things and then chose a color from a menu. This is what's called syntax highlighting, and this is one of the features of software like VS Code, again, Visual Studio Code, whereby it knows this is a Python file because I told it in the file name and because programming languages are standardized with certain keywords and certain punctuation or syntax, it knows that print is going to be soon what we're going to call a function, and the blue parentheses are pure syntax that make clear what it is we want to print to the screen. So more on that and more colors to come. Now down here lastly is the most esoteric feature of VS code and really programming environments in general, known as a terminal window. This gives you a prompt here represented as a dollar sign. Sometimes it looks like a hash symbol or it can be anything else, but we'll standardize on a dollar sign here and this is essentially where your cursor will just be waiting and blinking, waiting for you to type a command, because what you're seeing down here is generally what's known as a command line interface or CLI. And even though this might seem a step backwards, maybe reminiscent for some of you of the old DOS days before there was Windows, it turns out. That it's wonderfully useful and wonderfully efficient to be able to type commands to get work done quickly as opposed to clicking on menus and dragging icons, which is fine, which is certainly much more user friendly, but doing things that the keyboard for many dare say most programmers just tends to be faster and more productive by spending a lot more of your time in a command line interface or CLI. So the terminal gives you just that a CLI. This whole thing though, of course, is graphical in nature, a graphical. User interface or GUI for short. So you'll see here I haven't actually hit enter yet, but I've typed out at my prompt Python space hello. ie, and I'm about to hit enter before I took this screenshot. Now what have I typed here and why? Well, this is clearly the same name as the file, hello. ie, and here I am saying the word Python explicitly. Well, it turns out by design and a little confusingly, The program you use to run a program written in Python is also called Python itself. So if you think back to that mental model from a moment ago, Python is the name of the interpreter that we are using in order to run my code ultimately now. is a bit of a simplification because there's still going to be a virtual machine involved typically when you install Python on a system, but I think that's the simplest way to think about it. Python is the interpreter that's going to read my code top to bottom, left to right, and interpret what I mean and what the computer should do in response. All right, so let's go about doing this. Instead of a screenshot. I'm going to open up the cloud-based version thereof, and I'm going to put it into dark mode just so that the code pops a little bit more on the screen. And the only thing that's different about my interface right now is that in advance I've downloaded some code for this lecture specifically in a source 3 folder, aka directory at top left. So My File Explorer, I have source 3 and then the name of my unique code space here as these things tend to be called, but your number or your code space might be somewhat differently named. But for the most part, your interface will look largely the same. You might have some more icons, some more buttons, some more features. I've actually turned off as much as I can to actually simplify things and in fact

Segment 6 (25:00 - 30:00)

I'm going to go ahead and hide my so-called activity. Bar and Explorer so as to really distill our screen here into the absolute minimum. Room for the code I'm going to write in those tabs and my terminal window at the bottom so I can run it. And sometimes, at least if my code gets long, I might even hide the terminal just so we can focus on the code alone, but with a keyboard shortcut, I'll, I'll pull it back up just as you might at home ultimately too. So how can I go about writing my first program? Well, what I'm going to do here at the bottom of the screen is run code space hello. ie. Now I'm going to go ahead and hit enter What I'm going to see here is a blinking prompt next to the line number one. Now that number is not actually in the file. That's just VS code being helpful and numbering my lines for me automatically. Now we saw already multiple times what this program should look like, so let me repeat that. Print parenthesis quote unquote, hello world close there at the end, to be clear. Now VS Code's trying to be helpful. It's starting a second line for me even though I haven't moved the cursor there, and that's fine. You'll find that these text editors and IDEs or integrated development environments more generally, not only give you features like syntax highlighting, color coding things for you, they also sometimes try to anticipate what it is you're about to type. And in fact, what I've done is also in advance try to disable as many of those features. As possible really to focus on developing today some muscle memory and some instinct for what you should type, not just let the computer or AI type for you. Longer term, once you actually have your footing with Python or any programming language, I think it's good to actually enable features that empower you to be all the more productive, be it AI or otherwise, but for now we're going to focus indeed on these fundamentals. So that's it. The file has saved itself by design automatically because that's how we've configured VS code here, and now it's time to run the program. Now there's different ways to run programs. Sometimes you can click a little play icon if you want, or you can actually do it in a command line interface. And again, to develop some muscle memory today and to really emphasize the steps that are happening writing code and running code, I'm going to tend to use my CLI command line interface or terminal window down here. So I just ran a moment ago a code command followed by the name of the file that I wanted to code that is right. That's specific to VS code has nothing to do with Python per se, but again, I've standardized on the file name ending in. ie. If I want to now interpret this program and have it say hello world to me, I can do this Python space, hello. ie, enter, and voila. I've just written and run or executed my very first. Python program. Of course it's only ever going to say hello world. If I run Python of hello. ie again, it's going to give me exactly the same output. Now it's fun the first time, sort of mildly interesting the second time, diminishing returns thereafter. Let's make this program more interesting by introducing another function there too, because we've seen already that print is apparently a function. Indeed it's a call to action, it's a verb that apparently the Python interpreter understands because that's how it printed out Hello world on the screen. But it'd be nice if it could do more than just print out Hello world, Hello world again and again. Well, let's introduce another function that comes with Python itself, and you would only know this by taking a class, reading a book, reading up on some online resource on what functions come with the language. I'm going to go back over to my terminal window here. I'm going to clear my terminal just to keep things a little clean, but that's just erasing the commands I previously wrote. Now I'm going to go ahead and introduce another feature to the same program. I'm going to go ahead and first. What I wrote earlier just because I think we're past that. I'm going to zoom in a bit more just so you can see this a little more clearly. And what I'm going to do now is go ahead and type input, which is going to be the name of a function that indeed comes with Python. I'm going to use quotes inside of these parentheses to then prompt the user with a question. For instance, if I want to prompt the user, say for their name, I could say, What's your name? question mark. I'm going to leave a space at the end so that the cursor moves over ever so slightly. Then I'm going to go ahead and print out quote unquote hello, comma. at the bottom. Huh, what do I print? Well, maybe it's David who's going to run this program, so maybe I could print out quote unquote David is the answer to that question, but that doesn't really make sense. The whole point of this program, I claim, is to make it more dynamic and more interesting than just Hello world and certainly more interesting than Hello David, and the like. So what I'd like to propose is that this input function, which I claim is going to ask the user that question. I'm going to make sure that I save the answer to that question somewhere, and I'm going to type something like this name equals input parentheses quote unquote what's your name? And this equal sign is actually something you shouldn't think of as equality as

Segment 7 (30:00 - 35:00)

much as you should assignment in programming languages like Python. This equal sign means do whatever's on the right hand side first and then copy that value from right to left and store it. In this thing here now, what's this thing? I came up with this word myself, but it makes sense because I'm prompting the user for their name. I could have called this thing anything I want because it's a variable. A variable is a storage container for a value, be it a piece of text or something else. I could indeed call it anything I want mathematicians like X's and Y's and Z's, but it would be a little less clear to the reader and to me tomorrow or a few days from now what it is that's. In that variable, if I just call it X or Y or Z, so by convention stylistically it's good practice when programming to give your variables good names, and that just makes it clearer to you, the writer, and to future people, the readers thereof. Now on line 2, I've gotten ready to say hello, comma, so I've got my English grammar set up. Now what I can do down here is call print again and pass to it another input which is going to be. The variable itself, named however I saw fit. What's gonna happen now at the end? If I go ahead and run Python of hello. ie again and hit enter, now I'm not gonna see Hello world, I'm gonna see what's your name? And a space and then my cursor where I can type my name. So now I'm going to go ahead and type in for instance David enter and I'll be greeted with dynamically hello David. If someone else were to walk up to the keyboard and run this program again, Pythonfellow. ie, perhaps it's our old friend John Harvard. Well John might type in his name. And then hit enter and now we see hello John. So what we've seen here are not only variables, but what we're going to call arguments. Arguments are inputs to functions that alter their behavior and syntactically, the way you provide an argument to a function is just as we have now several times inside of those parentheses after the function's name, you provide the input thereto, quote unquote. Hello world, quote unquote, what's your name or no quotes and the name of a variable. Indeed, those quotes are clearly now important when you just want to use English or some other human language and have that display on the screen, you need to encase it in quotes, double quotes as I did. You can also use single quotes if you prefer, so long as you don't have any apostrophes or things that might confuse Python thereafter. But if you provide those inputs. In quotes, that makes clear to Python that oh, you want me to print out this whole thing and it won't confuse that input for what could actually be a variable instead. In fact, I did not use the quotes around name because again name is a storage container for the value the user previously typed in, so I want print to print out the value of that variable, not quote unquote name per se. But do think, and I admit the aesthetics here aren't the prettiest. In fact, you can see he John on two separate lines, which isn't all that elegant. Let me go ahead and propose that we kind of clean this up sort of visually on the screen, and we can do this in a few ways. And let me propose one of the simplest first. If I want to keep the hello John and the hello David on the same line, let me change my code a bit. Just for clarity, I'm going to clear my terminal window just to hide the previous commands. I'm going to get rid of line 3 altogether and then up here inside of the parentheses on line 2, I'm going to use the plus operator, so to speak, the plus sign as we know it from math, and then I'm going to go ahead and type the variable name there. Now my program's a little shorter, but it's actually a little better as follows. Let me go ahead now and run Pythono hello. ie and hit enter. I'll be prompted again for my name, so I'll type in David, Enter, and I think I should see on one line. Oh, so close. Hello, David, without a grammatical space in there. So I think that's an easy fix. And in fact, it stands to reason that the fact space is missing because I didn't tell the computer what to do. And here is just the simplest, stupidest example of why precision is so important in programming. The computer is meant to do exactly what you tell it to do. And unlike pseudocode and unlike humans who might read that pseudocode who might Between the lines, so to speak, and make certain assumptions about what you mean because you're just they're just a reasonable person. The computer is only supposed to do and is only designed to do exactly what you tell it to do. So if you omit the space as I did, it's not going to give you a space. So that's fine. I'm going to go ahead and hit the space bar now inside of the quotes, no other changes. I'm going to rerun Python of hello. ie and hit enter, type in my name again, and now we're back in business. Hello, David, exactly as I intended it all this time. Well, what more could I do here? Well, it turns out that some functions take multiple arguments, and print is one of them. We've seen that we can pass print one argument, and that was true of the input function too. But what's nice about print is that you can pass in two arguments

Segment 8 (35:00 - 40:00)

34, more, even 0 if you really want. So let me go ahead and do just that. Let me go back to VS code here and point out that what's been happening thus far is this plus operator is doing something. For which we have a term of art, it's doing concatenation. Concatenation is the joining of two pieces of text, one on the left, one on the right, and the one on the left is clearly text because it's in quotes. The one on the right is the value of the variable which we know is going to be text like DAVID or J O H N for either of our names. And so this concatenation operator is doing this. It's taking hello, it's taking the name, joining them together, that is concatenating them together, and that is the. Argument that print is receiving as input and therefore displaying on the screen. But because I've read the documentation, I can actually change this to pass print 2 arguments and maybe just kind of clean this up a little bit. Let me go down to my terminal here, run Pythono hello. ie now. Notice there's no plus operator, but there is another comma. Hit enter. What's your name? DAVID and ah, so close. Now again, the computer's taking me very literally. Why? Well, I still have the space here. But it turns out if you dig into the documentation for the print function, you'll see actually that when you pass in not one but 2 arguments to the print function, you'll get a space for free. It is designed when you pass in two or more arguments to separate them by default with a single space. I would only know that from having been told it, reading the documentation or the like, so that's fine. I can fix this by reverting to the original version because now I'm getting the space automatically by nature. Of how the function works. So if I run this one more time, Python of hello. ie enter, type in my name David. Now it looks exactly as I intend and all we're doing now is demonstrating that you can have not just one but 2 or 3 or it turns out is we'll eventually see even zero arguments as well. All right, so how would you know any of that? I keep referring to the documentation. Well, among the nice things about Python is that it is actually very thoroughly documented and if you go to this URL here, you can see the official documentation for Python, which actually evolves over time as the language itself. Evolves and gains new features and therefore newer version numbers as well and I took a look at that documentation at some point I'm like, oh, the print function does take multiple arguments if I so choose, and that's how I knew to do that. In fact, I also know as a result that I can do this too. If I want to move the printing of the name to its own line, I can do that. I didn't have to abort altogether what was my line 3. If I would really like to pass in. Name as the variable to as the argument to my function print that's fine, but recall that previously this did not work out well for us where I simply had the space and then nothing after it because it put hello here and then the name David or John on the second line. But if I read the documentation, I'll actually see that I can pass in another type of argument. To the print function too. I can use my comma again. I can say end equals and for instance, quote unquote, because it turns out again per the documentation, the print function will end every line of text automatically with a new line, and we actually glimpsed this ever so briefly in the assembly code earlier. It turns out in programming the way you express a new line, the hitting of the enter key or the return key on your keyboard, is you sometimes don't have to hit it. You can textually. A backslash and then a lowercase n and Python and other languages know that oh the human wants me to move the cursor to the new line, the next line below it. By default, the documentation for print says exactly this that the line will end by default with backslash N. That's why the cursor got to move and made hello David and hello John kind of messy. But if I override that and say no, end each line with nothing, quote unquote, with nothing in between. I can change that behavior too. Let me go ahead and run Python of hello. ie again, type in my name, and it's not going to be that exciting an outcome. It's still going to look the same way, but it's going to achieve the exact same result yet another way. And this too is thematic in programming whereby simply by writing code in different ways you can. achieve the same outcome, not unlike in English where you can express the same idea in different ways using different nouns and verbs and the like, some of them better, some of them worse, but in code here we can indeed achieve and solve the same problem in many different ways. Now over time, and if you study programming and aspire to be a software engineer, you'll. Learned that there are in fact better ways to write some code because not only is code evaluated typically on the quality of its style like your choice of variable names and whether or not it's pretty to read and you've used white space that is space bar characters in appropriate places

Segment 9 (40:00 - 45:00)

well, it stands to reason that it's got to be correct, otherwise what's the point of writing it if you're not actually solving the problem correctly. But design is another seemingly subjective measure of code quality and in fact this is why a lot of companies in the real world actually have what are called code reviews whereby when you write code that you want your company to use in its product, typically there'll be another human or nowadays an AI that at least gives you some qualitative feedback on it and says, hm, you could maybe do this a little better. It will give you suggestions it might approve or even deny. The submission of your code to the system. So writing good code is not only correct but a matter of design as well. Now what we're seeing here in my code is a use of arguments indeed, but the first of these arguments is what we're going to now refer to as a positional parameter. It is an argument that has meaning because it came first in this case, if you will. This. Argument though is what we're going to generally call a named parameter. The word end exists because the human who invented the print function in Python decided that there will be a parameter whose name is END, the value of which by default is backslashn, the new line character, but that we can change in this way. So this is a long way of saying that Python supports not only what we'll call positional parameters, but also. Named parameters as well, and this is a bit of a subtlety, but when you know a function takes inputs, it is said to take parameters. When you actually use those parameters by passing in values, you're passing in arguments. So when you invent the function, they're called parameters, but when you use arguments. But for the most part they refer to one and the same thing, and humans will often slip and use them interchangeably as well. Now let me go back to my code here and propose that we can solve this yet another way, in fact, maybe the best way, if you will, or the most conventional way. Let me clear my terminal here and let me go back up to this line of code and 93 and get rid of both and propose that we actually do all of this in one elegant line. I'm going to go ahead and print, quote unquote, hello, comma and then let me just print out the person's name like this. I like this because it's keeping everything on one line. I've got the hello comma. I've got the variable's name. Let's go ahead and run it. Python of hello. ie. Enter DAVID. Some of you might see already where this is going, and even if not, think for just a moment about what I might have done wrong on line too. You're about to see the first, probably many bugs, mistakes in software, intentional or otherwise, because when I hit enter now, I'm not going to see hello David. I'm going to see literally. Hello common name. Now that stands to reason because I literally put NAME inside of those quotes, but there is a way to fix this. It turns out, and this is a newer feature of Python, I can put in curly braces, as they're called, the name of that variable, which coincidentally is named. But again, I could have called it X or Y or Z. That just would have been bad style. But I now need to make one other change because if I run this version of the program and type my name, Python's still going to take me literally, and this time weirdly print out hellocom name in curly braces. I need to tell Python that this text is actually a little bit special, and I want it to format the text for me. I want to go ahead and specify it before the double quote here of letter F. Notice that the curly braces actually changed color because VS code knows what I'm up to. So now I'm going to run this a third time, Pythono hello. ie, type in my name and now I get hello. David. So this is a very subtle detail, this F that I'm putting before the string, and frankly after programming all these years, I think this is a weird looking feature. It still feels very unnatural to me to squeeze a letter F in between the parenthesis and the quote, but this is a feature that's been adopted for some time and is the way that you can use what are called format strings in Python. Now what more can we do with this program? We can actually, now that we have some of these basics in mind, we can actually kind of add more features still. Let me clear my terminal window here and let me propose that if I run this a bit lazily, maybe with my caps lock key on, I might do something silly like this. We all kind of know someone in our lives that tends to write in all caps. Um, this just looks bad. And in fact, if this isn't a silly little program but it's maybe a form. On a web page from which I'm collecting data from users like I don't want some users' names capitalized properly, some all uppercase, some all lower case. It would be nice to maybe canonicalize, standardize what the capitalization of these texts are. So I can actually do that in a few ways and also solve other problems. For instance, suppose I'm really difficult and when I run this program, I weirdly type the space bar 3 times and then I type in. My name and then I hit the space bar again in Mayland. So not that I would do this, but you'd be surprised. We collect a lot of data for this course and others. So many people weirdly hit the space bar before they start typing or after, and what this is going to do in this case is kind of mess up

Segment 10 (45:00 - 50:00)

the appearance of this when you spit it back out with the print function. So I can clean up some of these mistakes pretty easily. Let me actually go up to My code here. Let me actually specify the following. Let me go ahead and give myself another variable. We'll call it new name, but I'm going to clean this up further too. I'm going to set this equal to the function the name variable, but I'm going to go ahead and use a dot and the word strip and then 2 parentheses. This is another function called strip that weirdly for now you call. that is invoke or use by using a dot on whatever value you want to strip white space from and by whitespace I mean the space bar, the tab key, or certain other characters as well, but this is going to get rid of spaces to the left and to the right of what the human typed in because this is going to partially clean up that mess. If I run Python of hello. ie, type in space space, David space space, mail and enter. Not that, huh. Nothing happened here, but this too stands to reason, and I didn't intend to make this mistake. This stands to reason why, because the name variable I'm printing is still called name. If I want to print out the new variable name, I want to change what's in the curly braces to new name. And to be clear, what's happening on line too is a little new but not entirely new. The strip function here is new and it's operating on this variable called name, but the equal sign is not new. That's the assignment operator. That means copy from the right, the stripped version of the name over to the left, and the thing on the left now is another variable whose name I invented. I could have called it X or Y or Z, but I gave it a slightly better name than that. And now on line 3 I'm using that variable's value. Let me go ahead now and run Python of hello. ie. Enter, type in space space, David space space, male, and I've at least now solved the problem. Partially, but suppose the user's a little difficult and runs that program again, and in fact it's getting a little tedious to keep running Python of hello. ie, so you can actually use your up arrow on money keyboards whereby you'll scroll back in time through your history of commands. So if you ever see me typing seemingly instantly, I'm just using the up arrow, maybe the down arrow, or some other tricks to rerun some past commands more quickly. So now I'm going to go ahead and enter. I'm going to do space space, and I'm going to yell, David Malan, enter, and that too looks pretty stupid. How can I go about fixing this? Well, there's another command, another function I can use. Let me do this, and we'll clean this up soon too. Newer name equals the new name. title open parenthesis close parenthesis. That is to say, it turns out that Python also comes with a title function that you can use on. Variables like this such that if they're text you're going to get title case back instead and title case is like on the cover of a book where the first letter of every word is capitalized automatically for you and everything else is forced to lowercase, if only to standardize capitalization in your system. How does this now look? Well, let me go ahead and rerun using the up arrow trick. Enter, type in space space, all caps David Malan, enter. And now darn it, I did it again. How am I getting the same thing? Well, I need to print out newer name. Let me now go back down to my terminal, run Python of helloapa yet again, space, David. Maly enter and now it's getting more interesting. I haven't fixed all of the problems and we'll leave one as maybe an at-home exercise, but I've at least standardized what the name looks like. So if I'm storing this in a database or in some server somewhere, it's at least going to be cleaner than the all capitalized version or even if the user typed no uppercase characters, it would automatically capitalize. The D and the M again. Now I can clean this up, and this is not good practice what I'm doing, creating a new variable, a new variable every time I change something. I can actually do a little bit better than this in a few different ways, but the simplest is to notice this if you sort of draw some inspiration from transitivity or certain mathematical operations, you'll see that name is going to contain as a variable this whole time the value that the human typed in. And that name already has a strip function associated with it, but so does the text that the human typed in. So instead of calling stripped down here on line 2, let me actually go and delete all of line 2. And at the end of line 1, let me put the dot there, then run strip open parenthesis. Parenthesis and notice you still need the parentheses because I'm calling that is using a function, but strip it seems doesn't take any input in those parentheses. It takes no parameters if you will, but it knows what to strip white space from because of that dot operator which is referring to the value right before it. And I can do one better than this. I can get rid of this line and go back to line 1 and add title, and I can kind of chain functions together in this way, which is just if nothing else tightening up my code, it's getting rid of like those stupidly named additional variables

Segment 11 (50:00 - 55:00)

that weren't really adding much intellectually to my program, and I'd argue that line one is still pretty short. It certainly fits on my screen, roughly half of the screen, so I haven't. Really made my code harder for other people in the future to read and understand, so I kind of like this. And now I can go back into line 2 and tighten this up, just print out the name so that down here if I clear my terminal and rerun Pythono hello. ie, type in if I want space space, David space space, Main in all caps, it's at least going to improve some of those problems here. But here's the catch with uh with programming. Sometimes good intentions might not yield the best result, and in fact I can probably contrive an input for which this is not going to be the intended behavior. Let me go ahead and clear my terminal again, run it here, and maybe let's type in a character like Ronald McDonald. All right, interesting. Only insofar as its name has three capital letters here, which is fine. Ronald McDonald typed his name correctly, I'd argue in this case, but as soon as Ronald hits enter, notice what this program does. So like, ah, so close, but there's going to be this trade off sometimes. You might have fixed one problem, but you've introduced another, kind of the whack a mole game if familiar. I've sort of fixed it over here, but darn it, now there's a new problem over here, and there's absolutely ways to fix this, but I would encourage you as you exit this lecture. to keep an eye out in the real world for weird behavior like that because it just means that some human like me made a mistake and introduced a bug into their code that didn't actually work as they intended. Now how do you know about strip and title and all of this? Well, it turns out in that same documentation you can look up all of the documentation for functions related to text and henceforth I'm gonna start calling text by its term of art strings or STR for short. And in fact that's why you. STR in this particular URL. If you go to that URL, you'll see all of the functions that are associated with strings in Python, strings of text, if you will, strip and title among them. But just for fun, let me go back to VS code here and just show you a couple of other things that we might do. For instance, if we wanted to not only strip out the white space, at least from the ends, I still haven't figured out how to get rid of the white space between David and Mayen. Strip does not do that for me. Let me go ahead down here after clearing my terminal. And propose that I'd really like to greet people very familiarly with by their first name only, even if they type in their full name. Well, I can do that. On line 2 here, let me insert a blank line and do this. Let me go ahead and say, give me a variable called first. last separating them by commas in Python and set both of those equal at the same time, which Python can do for me too, to name. slit and split the human's name on a single white space. So for now the human's going to have to cooperate, no more hitting lots of space bars and weird areas, but now what I'm going to do is instead of printing out the whole name, I'm going to print. Out just the first by grabbing this variable's value but ignoring this one and split, if we read its documentation in Python's own docs, you'll see that it will split, of course, on a single space and give me hopefully in this case two variable values back. Python of hello. ie enter David Malan. I'll cooperate and just capitalize everything with good space. Saying hello David. Well, isn't that nice that it's treating me as a friend already? So here too, a lot of things can go wrong. Your mind is probably wandering to friends of yours, maybe your own name that has three words in it or more might not necessarily work as we intend, but at least we've got things going with additional features now as well. And in fact, as a teaser, turns out that Python doesn't support just these strings. Of text or STR for short. Python and a lot of languages support different types of data as well. So here for instance is a brief list of just some STR, which is stir for string, but Python and other languages also support what we're going to see as ins or integers, boos for boolean values, not boolean expressions in this context, but boolean values, namely true. And false, and that's it. Floats, which refers to what are called floating point values, which are real numbers that have a decimal point in them and possibly digits after the decimal point, and then there's a bunch of others as well. In fact, among the others, as we're gonna see. It's not just boolean values, floating point values, integers, and strings, but also ranges, which is going to give me back a range of numbers from one to another number, lists of numbers, ts. ts might be like X Y or latitude longitude combinations, dics or dictionary objects which associate keys with values as you might recall from our discussion of data structures. And sets like in math will contain a whole bunch of values but no duplicates by default. So Python supports all of these different types of values. Let's actually start to play with some of them here. Let me go back to VS code and let's transition to a new program altogether. I'm going to close my hello hello. ie tab.

Segment 12 (55:00 - 60:00)

I'm going to clear my terminal window and let's go ahead and code up a brand new file. instead. I'm going to code up a file called calculator. ie and let's make our own mini calculator just to play around this time, not with strings or stirrs but ins or integers. All right, here we go. This time I think it's appropriate to use simple variable names like X and I'll set it equal to 1 for the sake of discussion. Why set it equal to 2 for the sake of discussion. Let me give a third variable called Z. I'll set it equal to x plus y, and then I'm going to print out the value of Z. So it's a super simple calculator. All it does is add these two numbers together and then print them out, but it's going to illustrate how we can manipulate integers indeed as well. Notice that in this case, The plus is hopefully going to do math in the intended way, and indeed you have plus, you have minus, you have division, you have multiplication and other mathematical operators supported in Python. Let me go down here now and run Python of calculator. ie this time, my new file, hit enter and whew, my first calculator seems to work. I dare say 3 is the correct answer to that problem. Now this calculator. Doesn't do all that much of interest yet. It's only ever going to add 1 and 2. Let's get some input from the user and make things more interesting. So up here instead of the 1 instead of the 2, let's use our old friend, the input function, and ask the user what's X mark space. And down here use the input function and say what's why. That is to say, let's make a very user friendly calculator that asks the human what input they want. Then down here I can still add x + y and set it equal to Z. I can still go ahead and print Z, so let's run Python of calculator. ie again. This time I'm prompted for X, and just to prove that it still works, let's type in 1 for X and now 2 for Y. And when I hit enter, Z will get the value, presumably the 33. Huh, what's going on here? I seem to have yet another one of these bugs, mistakes in my code, like, suffice it to say 1 + 2 is not 12 and never has been. So what's happening? Well, it's no accident that we're getting. 12 because it's not really 12, it's really 12. In fact, if you go back up here and you think about what we did in hello. ie when we use the input function, we were asking the human for text, that is to say, a string, and storing it in a variable. Previously the variable was called name, now it's called X, but that doesn't change the fact that it still came from the keyboard and there. For it is text, same for Y, same for Z as a result. This plus is not going to be the arithmetic plus operator from grade school math. It's gonna be again that concatenation operator. It's the right symbol, but in the context of having a string to the left and right, X and Y respectively, it's going to join them together instead of actually adding them together. So how do we fix this? Well, we can do this in a few different ways, but we need another function, and it turns out Python also comes with an IT function named after the data type which will allow me to pass in an argument that is a string and get back the corresponding number. So if you will, per our discussion in the very first lecture, it's going to convert a Unicode text the corresponding number that you see, not necessarily A to 65, but rather, The number that you're seeing on the screen or that the human has typed in. So let me go ahead and write in open parenthesis close parenthesis around the X in open parenthesis, Y. Now let me go down here, rerun Python of calculator. i. I'll again type in 1. 2, and this time I get the intended value of 3. Here too, let's tighten this up. Let's make this a little better because frankly I don't really need to do this on line 4 if I'm trying to store in X a numeric value, why don't I go ahead and do this? Let me revert this change and just leave this as X + Y because that's arithmetic. But up here, let's do this for the first time. Let's pass as input. To one function, the output of another function by nesting them in this way. Let me do the same on online too, and let me call your attention now to the additional parentheses. Inside of the parentheses is first and foremost what's X mark quote unquote. That's the input to no pun intended, the input function. However, the input function we've seen returns whatever the human typed in at the keyboard, that value instead of immediately getting copied from right to left, is going to immediately be passed in as the input to this in function so that it can convert it per its documentation to the corresponding actual integer. Same is going to happen down here for Y. So what's now in X and Y respectively are 2 ins, not two stirs, so to speak. They the same, but they're going to be treated in a way that lends themselves now to correct math. Now all I've done here is really tighten things up by not using IT Online 4, but if I again run Python of calculator. ie typing in 1 and then 2

Segment 13 (60:00 - 65:00)

I'm still going to get 3. And I still have the same result. Now, what if I want to add other numbers together? Well, I can actually do this with floats as well. If I want to add numbers with decimal points, I can change in up here to floats. float. And now, after clearing my terminal, let me rerun Python of calculated up high, and let's do 1. 1 plus 2. 2. Now I'm going to get back 3. 3, and that looks correct too. Or does it The astute might have just noticed that wait a minute, 3. 3 is correct and I see a lot of zeros, but then way over here there's this weird anomaly which I did not learn in grade school math that 1 + 2 + 2 should equal, I would think, 3. 3 and that's it, but we seem to have a curiosity there that's happening. And let's see if we can't dig into that. In fact, let me go back to my code up here. Let me go ahead now and maybe we can ignore the problem. Let's go ahead and just round. Into this result first. So it turns out that Python comes with a round function. You can find it in its documentation such that now if I run Python of calculator. pi with 1. 1 and 2. 2, should be 3. 3, but if rounded, it's 3. All right, so I'm kind of like ignoring the problem by just rounding away from it, but that's not really legitimate. It is an opportunity to tighten this code a little bit more. I don't really need, frankly Z anymore. If I already know what the value is X plus y, rounded or not, let's tighten this up. And let's just pass to print as before the output of one function round as the input to the print function. It doesn't change the behavior, but it gets rid of a third and seemingly unnecessary variable that was z a moment ago. Let's rerun this down in my terminal again, run it as 1. 1, 2. 2, and we've still got our 3, but the program's a little tighter this time around. But let's now do this. Let's actually format it with some commas and a Useful way. For instance, if I run this program as is and let's go ahead and run like 999 this time plus 1, I'm going to get back 1000. But in the US it's common to separate triples of digits with commas. In other countries you might use dots instead, but in this case it's going to use whatever the default is on my system if I make this change. Instead of rounding here as before, let's give me back my Z just so I can see this more clearly. Then I'm going to go ahead this time and print out, quote unquote, and this is going to look weird, the value of Z inside of Curly braces, and I'm going to specify to Python that I want you to format this variable's value with the little F, AKA format string. Let's rerun this Python of calculator. 999 and 1. OK, still working as intended, so I really just made it look uglier and weirder for no good reason yet. Turns out if you read the documentation, you'd know that you can actually include a bit not obviously a colon after your variable's name and then a comma if you want the print function to format it beautifully for you with those commas, for instance. So let me go ahead and rerun this now 999 and. Now I get a formatted integer 1000 with a comma, and again, whether you get a comma or some other symbol will simply depend on how your system's configured. All right, let's now dig into not just addition but another operator. I claim that we can do multiplication, subtraction, and also division. Let me clear my terminal window here. Let me go ahead and simplify this just for the moment to say print. To say print of Z itself, but instead of rounding X + Y, let's just do something simple like X divided by Y. Make sure that division indeed works as I claim. Run Python of calculator. pi. Let's do 1/3, so 1 divided by 3. That's looking pretty good. All right, I don't know what was going on with that errant 3 a moment ago when we added 1. 1 plus 2. 2, but problem seems to have gone away. That's not really the best approach to programming. Like if something happened once, probably eventually going to happen again. But we're going to have to poke around further to see what's going on. So for instance, let's do this just as before, let's really dig into what is being calculated when I do 1 divided by 3. Let's not just print the Z, let's print out a formatted version of the Z as before, and as of now that hasn't changed anything. It's not going to look any different just yet, but let me go in here and use a colon rather. than use a comma now because I don't care for now about large numbers anymore. Let me do a 2F, which is syntax that's going to tell Python to format the value of Z using a decimal point and two digits thereafter. And the F in this context confusingly means it's a floating point value. The F out here before the double quotes call just means, Hey, Python, here comes a formatted string. All right, if I go down.

Segment 14 (65:00 - 70:00)

To my terminal here and rerun Python of calculator. ie 1 divided by 3. This time I only see the two decimal points. But I did this because I wanted to kind of poke around further and see more digits. By default we got a few without using this formatting trick. Suppose I want to see a lot of digits, like 50 digits after the decimal point. Let's really dig in to what 1/3 actually is. If I do 1, I do 3. Oh my God. So what has just happened here? 0. 3333333. I'm on board at this point. Like this feels like 13 and how I was taught in grade school. What the heck is this going on at the latter half of the digits? It's just random noise. Well, this is actually a fundamental problem with many programming languages, if not most, whereby they're vulnerable to what we'll call floating point imprecision. even if you're doing a relatively simple arithmetic operation like 1 divided by 3 that we all know is 0. 3 with a line over it, which means an infinite number of 3s, well, there's part of the problem. We can't really represent an infinite number of digits if we only have a finite number of bits inside of the computer. In fact, if you think back. On that chip of memory, no matter how many bits are in there, they're certainly finite. There's only so many bits, so we certainly can't use an infinite number of bits to give us an infinite number of threes. But this doesn't just happen to numbers that recur infinitely many times in this way. This really happens to an infinite number of numbers. And if you think about it, if you only have a finite amount of memory, but in the world, there's an infinite number of numbers, certainly real numbers that have decimal points because you can always add another digit, another digit to come up with more. It just stands to reason that if you have a device with finite memory, you cannot represent infinitely many values. At some point you have to decide, uh uh, I cannot represent data to that level of precision. And that's what you're seeing here. Python in this particular case can give us a whole bunch of significant digits, but it can't give us as many as 50, it would seem. At that point, it essentially starts rounding to the nearest value that it can represent, and that's because of the underlying representation of binary digits using indeed zeros and ones, events here as a fraction as we see it here. So what does this mean? It means that computers are inherently vulnerable to imprecise math. They can and will make mathematical mistakes unless you somehow defend against this. In fact, there's many examples in popular culture of movies of digits being rounded incorrectly. lots of payoff for the characters. There's lots of examples in the real world of sometimes very perilous implications of mathematical operations, meaning that devices misbehave or operate incorrectly. This is simply the nature of the beast when it comes to representing information at the end of the day with just a finite number. Of zeros and ones, so best to use some piece of software that gives you enough precision, best to use as many bits as you can, but not to expect an infinite number. This is not a bug with Python. This is a limitation of computers with finite resources like these and how we are representing in binary the underlying numbers. Whew. All right. Before we transition to some of those other building blocks beyond functions, let's play with just a few other features by going back to my terminal window here and clearing it. Let's actually go back to hello. ie, and I can do that by using that same code command as before. Or to be clear, if I reopen my Explorer, notice I have not only the folder I came with today. So 3. I also have Hello. ie, which we made earlier, as well as calculator. ie. So instead of using the code command again, I can also just click on this like any Mac or PC. But let me go ahead and close my Explorer again. Let me delete the command I was about to run, and let me propose that we can actually implement our own functions too, and that'll put a cherry on top. Top of this discussion of functions. I'm not limited to only those functions that Python has given us themselves. Rather, I can invent my own. For instance, if I'm running a program like this, name equals input, quote unquote, what's your name? question mark. Well, I can go ahead and maybe say hello to the user like this. Then I can go ahead and print out their name. So wouldn't it be nice if Python came with a hell function that just said hello, comma or however I want to format it? Unfortunately, if I run this Python of hello. ie, it's going to give me an error, and I'd like to avoid that error because in this case when I type in my name, David, I'm going to get back this name error. Name hello is not defined. Did you mean help? I mean, ironically, I kind of do mean help now, but hello does not exist, doesn't come with Python. But that's OK because I can define this function myself. In fact, let me move my curse. to the top of the file and at the very top of the file, let's go ahead and use a new keyword that comes with Python

Segment 15 (70:00 - 75:00)

called deaf for define. Let me define a function called hello by saying the name I want to invent 2 empty parentheses in this case, and then a colon, and then on the next line indented 4 spaces by convention and notice I didn't have to hit the space bar. VS code is smart enough and we've configured it to know that I want to indent automatically 4 spaces that whenever you call hello, I want you to say. Print quote unquote hello, and I can toss the comma in there, but I'm just gonna, yeah, I'll toss the comma in there as before. If I now go down to my terminal again and run Python of hello. ie, because I've defined on lines 1 and 2 a hello function, I can now use it on line 6 as before. I can type in my name David and now I will see if less than beautifully hello David. So I've been. In my own function and what's nice about programming is that if you were really enamored with what I just did, you could borrow this code and use it in your own programs. I could save the Hello function in a separate file, share it with you, maybe install it on some shared system, and you could stand on my shoulders and never have to worry about inventing that function again. And that's true of all of the functions that come with Python. You and I don't have to figure out how to print things to the screen or get user input from the keyboard. Someone else smarter than us years ago did that already just as I've now invented this so called hello function. But this is cool too. I can write my own functions that take arguments that take inputs as follows. If I want my hello function to say hello to a specific person, well, in these parentheses, instead of leaving them empty, I can come up with any variable name that I want like 2. Because who do you want to say hello to, and then down here that value can simply be passed in, for instance, as before. And then down here what I can do is when I call the hello function, let's pass in as input the name variable and get rid of my own print on line 7. If I now rerun Pythono hello. ie, oh, I do have a mistake here. What have I done wrong here? Ah, notice syntax error, my first. Also not intended, but what's missing? I forgot that if I want to pass in two arguments to print, I need another comma. And to be clear, this is a different type of comma. Everything in between the quotes here is a string in Python. and that comma in white is a grammatically appropriate comma because you say hello, comma so and so in English. This comma outside of the quotes though means something special to Python recall. It means hey Python, here comes the second input to the Python to the print function. All right, so with that accidental bug fixed, and in fact this time Python's got me spot on, perhaps I forgot a comma. I did. Let's go ahead and clear my terminal, rerun Python if I load. ie, type in my name, and now hello David, we're back in business. So with this relatively simple feature Def and the syntax I just typed. I can actually give myself the ability to pass an inputs to my own function in this case one, but I could have even done more if appropriate. Moreover, I can even give these functions default arguments, which is a powerful feature of Python. If someone uses the hell function but forgets to pass in a name or doesn't care to, that's fine. On line one, I can say that the default value of 2. Is gonna be how about world and that doesn't mean it's always gonna say hello world, but only if I don't pass in a name. So let me run this again and type in my name David enter and it says indeed hello David. But notice if I change my code and don't bother asking the. anymore for a name. Therefore I need no variable. Let's go ahead and rerun it again, hit enter, and we get Hello world by default. It just works. So here too you're seeing how other humans implemented probably the print function, the uh input function, and bunches of others as well. So one last detail now when it comes to defining functions. This is getting a little messy even though this is a tiny little program because the main part of my program is arguably down here. The point of this program is to say hello. I don't really care about defining the function. Like that's not the first thing I want to see when I open this file. what the code is doing at the end of the day and It's calling the hello function. So you know what, just to be neat and tidy, I want to put this function sort of out of sight, out of mind. I'm going to arbitrarily hit enter a whole bunch of times, paste it way down below in my file, then scroll up just so I can make the point unnecessarily dramatically that this program only exists to say hello. Problem is I introduced a new bug, Python of hello. ie E. I get another one of these trace backs, which is sort of tracing back in time what I did wrong. This time it's a different type of error. It's a name error. And again, Python's a little mistaken. It says it's not defined. Did I mean help? sort of, but not in this case. Why is that? Well, if you think about it now, methodically, line one tells the computer to call a hello function.

Segment 16 (75:00 - 80:00)

But line, 42 tells the computer what hello even means, happening way too late. You got to define the function first. And then use it just like I did previously, but then I'm gonna get into this messy situation where every time I want to invent a function, it's got to go at the top of my file and then the actual code I'm writing that's of interest is at the bottom of my file. It's stylistically, it's just a little annoying if nothing else, but that's OK because it's actually conventional in Python to do this. When you define your functions, sure, put them lower down in the file, though not 42 lines down, which was unnecessarily extreme, but go ahead and define also a main function inside of which is all the stuff you care about, in this case, calling hello. Then at the bottom of this file call the main function. Now this feels like we've added a lot of complexity for not much upside, but it's actually indeed conventional to do this because now anyone reading your code, whether it's you tomorrow or a colleague down the line, they'll say, OK, what's the main part of this program? I got it. It's calling a hello function. Only if they care to understand how hello works do they need to bother looking at this code and by convention. And they're not going to care what the very last line of code is if it just calls main because it just kick starts the whole process. But why is it in this order? Because on line 1 you're defining Ma. On line 5 you're defining hello, but you're not using either of those until on line 9 you call Maine, which in turn on line 2 calls hello, which in turn prints out hello so and so. So again, a whirlwind tour, but just demonstrating how it would be conventional now to write our own programs here. And it doesn't have to be for just strings. In fact, let's do one last one with our calculator. Let me close this tab. Let me run code of calculator. ie to reopen my most recent version of the calculator, and let's actually do this. Let's completely change what I did here so as to do the following. Let's go ahead and define a function called Square, whose purpose in life is to take an integer, call it N for number as inputs, and then just return N times N. So this is yet another keyword, but it reads pretty straightforwardly. The purpose in life of this function that I've defined to be called square takes an input N and returns an output of N times N. So what is this return keyword? We haven't used it, but it's been used. Used by like the input function. The input function gets input from the human's keyboard and then it allows us to copy it from right to left into a variable. That's because the input function is returning a value to me, the programmer, whereas the print function typically just as a side effect, so to speak, it visually prints something on the screen. The input functions arguably more powerful and that it hands me back something that I can use. And maybe even reuse if I store indeed in a variable. So the return keyword just says return to me whatever the value is of n times n, that is to say N squared using this syntax here. And those of you with some prior programming experience might know there's other ways to implement this. I'm keeping it simple with just the multiplication operator. Now let me practice what I've preached and define also a main function at the very top here. Inside of that, let's finally use our friend X equals. Let's get the input from the human, asking them what's X question mark. Wait a minute, let's not mess this up again. Let's proactively convert their input to an integer because the whole point of this exercise is math. And then let's go ahead and print out something like print X2d is, and then after that, let's call the square function passing in X and let print automatically spit out. X squared is then a space as we've seen by default and the square of X itself. So let's give this a try. Python of calculator. pi enter uh oh darn, another bug also not intentional. What did I do wrong here though? Nothing seemed to happen and indeed if I run it again, enter, still nothing happens. It's because I'm defining two functions, main and square respectively, but I'm never actually kick starting the process by calling one of them. So let me go back down to my terminal here, rerun it again. Ah, there we go. What's X? Let's go ahead and do 2, the square of which should hopefully indeed be 4. Those then were functions. We've still got some conditionals and loops ahead. Let's go ahead and take a break and we'll be back with that and more. All right, we are back. So those then are functions, some of which come with the language itself, some of which I have now invented myself. And while the names of functions might differ across languages, most any of the languages you'll encounter in the wild will have this underlying functionality, this ability to use these calls to action to achieve function. that someone else implemented for you and we'll see more hints of that down the line today. But let's turn our attention now to another one of the constructs in that their pseudo code that we did in our first lecture, namely conditional, those proverbial forks in the road that allow me to do something conditionally based on the answer to a boolean expression. So how might we do this? Well, let me go over to VS code here and let me go ahead and

Segment 17 (80:00 - 85:00)

create a file called say conditionals. pi just to make clear what we're focusing on this time around. So conditionals. ie is going to give me an empty tab up top and let's go ahead and do some quick math, but not to the extent we did earlier. Let's do x equals in of input, quote unquote, what's x mark. Then on the next line, let's do Y equals in. Input quote unquote what's y question mark and then below that, let's now tell the user whether X is greater than or less than or equal to y. In other words, let's decide with a conditional what to say. Well, the way I can express this in Python is as follows. Literally I can say if I can then say X. is less than y using familiar mathematical syntax. Then I put a coin and then below that indented, as we've seen before, 4 spaces by convention, I'm going to go ahead and print out sort of a statement of the obvious X is less than Y close quote. Else if X is greater than Y, colon, let's go ahead and print out the obvious now. X is greater than Y. Else, if X is equal toy, go ahead and print out that same statement, quote unquote X is equal. To why. All right, pretty straightforward. It seems to be a program that not only gets input from the user X and Y respectively, and then does something with X and Y by asking these questions. I've got 123 boolean expressions here that's going to determine what gets printed out to the screen. But I'm not going to run it yet because I kind of see a bug on the horizon. This one's a little subtle, but perhaps you see it too. I don't love line 8 at the moment because thus far, even though in the real world the equal sign means equals, the equality of say two values, we've already seen that in programming, at least in Python and a lot of languages, it means assignment, copy from the right to the left this value, and that's not what I intend here. In fact, if I did run this, Python's not going to like or let me do this. I think I need another operator for testing equality, and this is going to look a little weird, but what humans came up with years ago, including for Python, is equals equals. So we sort of painted ourselves into a corner by using equals for assignment because at some point someone then realized, oh my gosh, how do we compare two values for equality? So someone proposed, well, let's use 2 equal signs and crazy enough, there's some languages that use 3 equal signs for get something more. This is where we'll stop for Python just at the tube. So now I'm going to go ahead and run this and we'll see if it works. Pythonoconditionals. pi enter. Let's type in a number like 1. And then a number like 2, the former of which is less than the latter, and indeed that's what I got. Let's rerun it and let's reverse it. X for 2, Y for 1, and X is indeed greater than Y. Let's run it one more time. Let's type in 1, and in fact X is equal to y in this case. So pretty good, pretty straightforward. And here's a perfect example of where Python reads like English, and this is among the reasons that people like it. So this code is correct, I'll claim, but it's not very well designed. Again, making the distinction between the style of your code, the correctness of your code, and the design of your code is sort of among the characteristics of what makes code good or bad. Ultimately. I don't like this at the moment, and I, I think I can, I think I and perhaps even you can infer why this isn't the best design, because if it does read like English, it's clear that I'm asking myself three questions, but is that really necessary? Because logically if X and Y are integers, which they're going to be based on lines 1 and 2, well X is either going to be less than Y or greater than Y or equal toy, right? That's the three options here. But notice this subtlety if X is less than Y, if that's true, if that Boolean expression is true, I'm going to print out X is less than Y. But if that's true, why am I wasting everyone's time also asking if X is greater than Y and if X is equal toy, because I already know at line 4 that no, it's less than Y. So it would seem that this code is arguably poorly designed because I'm wasting time, maybe my own because I wrote all this code, but really the computers because I'm asking you to answer three questions when sometimes the first answer suffices for the whole problem. So I can actually clean this up a little bit. Improved the design using slightly strange syntax, but let me go up to my code here after clearing my terminal and let me change this if to an LF, which is short for in English Ls if. It's a little weird, honestly, I always forget if it's L if or Ls if because it varies by language, but it's indeed L if here, which is short for the logical notion of LTs if. And I'm going to do this down here, which now has the logical upside of short circuiting this whole conditional if the first condition is the first boolean expression is true, or even if the second boolean expression is true. We're only going to bother asking this question if

Segment 18 (85:00 - 90:00)

the first and even the second questions have false answers. So why, to be clear, we're only going to execute this if we got back false answers for the first two boolean expressions, and we're all going to execute this line if we got back a false for the first. So we're saving a little bit of time. Now, the astute might notice too that Still poorly designed because if it's not less than X, if X isn't less than Y and X isn't greater than Y, well, obviously it's equal to Y. So why are you wasting the computer's time still asking that third question? So I can tighten this up further. Let me get rid of this LF entirely and use a slightly different keyword, literally Es colon. Now what I effectively have is a program that checks if X is less than Y and if so, it prints out as much and that's it because it wouldn't make sense to even ask yourself the question else if because we already have a true answer to our question. However, if we do get down here and X is greater than Y, then I will print out X is greater than Y. But if that 2 is not. True, then and only then will I bother executing this third and final line. So it's a subtle difference, but certainly if you're executing this code a lot again and again, saving those milliseconds, those nanoseconds can certainly add up over time, certainly for much larger programs than these. So still correct but better designed this time around. All right, well, what else can I do? Well, if I don't really care about greater than or less than, I just care about equal to or not equal to, I can express this program a little bit differently. Let me introduce the following syntax. If X is less than Y or X is greater than Y, well, let's just go ahead and say, Print out X is not equal toy. El if that expression is not true, then go ahead and OK X is equal to y. So I'm joining these two boolean expressions together to give me one larger boolean expression, if you will, because I'm asking in one breath, in one line, if X is less than Y or X is greater than Y, they that means necessarily that they're not equal, else it's going to be the case that they are. There's another way to do this though. I don't have to check for greater than and less than what I can actually do is just this. I can use not equals. Now that's not a key that's easily accessible on most keyboards. And so what most programming languages do, Python among them, is you use an exclamation point in this context pronounced bang and then an equal sign. So bang equals means not equals, and so you're asking yourself if X does not equal Y, then print out X is not equal to y. Other. print out X is equal to y. Of course we can invert this, as we've seen already. We can go ahead and change it to if x equals y, then say X is equal to Y, L is X is not equal toy, you can invert the logic, which is better. It really depends on what you think is going to be the common case or however your brain works, whatever you think reads best, but we can express both of those comparisons in that same way. All right, not all that interesting just to compare numbers that people are typing in. This isn't like a very real world problem, but more real world would be checking a user's answer to some question, maybe prompting them whether or not they agree to some terms and conditions, which is something we constantly do in software it seems. So let me go ahead and close this one. Let's create another file to keep this code separate called agree. to implement our own little agreement form. Let's go ahead and do this. declare in advance a variable called answer, so I can call it anything I want. Set it equal to the return value of the input function. Again, functions like input and even my own function for squaring can return a value if by design. And so I can say something like, do you agree question mark, and I can prompt the user to give me a yes or no answer. If they type yes, well, let's check for that. If the answer they give me equals yes, then print out, for instance, quote unquote, agreed. Else go ahead and print out, say quote unquote not agreed just to make clear. Now in practice, checking or not checking a box or saying yes or no is probably going to have a more interesting effect on the software like you can use it or not. In this case we're just going to print visually to the screen whether or not they've agreed. Down in my terminal window, let me run Pythonore. ie. Enter do I agree? Sure, yes. OK, it seems to work. Let me go ahead and run it. Do I agree? No. OK. No, not agreed. Let me run it again. Do I agree? Sure. hm but sure is OK, and I bet I could have expressed myself differently. In fact, all right, fine, maybe it needs a literal yes, so let's run it again. Uh, do you agree? Yes, emphatically, huh? Still not agreed. Do I agree? Yes. Still not agreed. OK, maybe I just want to be a little lazy. Why? All right, so this program, while correct, if the user must type in YES in all lower case

Segment 19 (90:00 - 95:00)

is not very user friendly. It's certainly not allowing the user to type in a few reasonable instincts, although sure is probably pushing the line. How can I go about changing this a little bit plus make it a little more robust against user input? Well, we can do a couple of things. Let me go up to line one and drawing some inspiration from our name example earlier for saying hello, let me at least strip off whitespace because if the user accidentally, as sometimes happens, hits the space bar, let's at least avoid that problem even though I didn't exhibit that behavior here. And you know what, instead of A title casing things, which seems weird for a response like yes. Let's go ahead and force everything to lowercase. And indeed if we check the documentation for string functions in Python, there is in fact a function called lower that forces the string to lowercase. The upside of this now is the following If I clear my terminal and rerun this program, I can obviously still type in yes, agreed. If I run it again and emphatically say yes in all caps, that also now is recognized as agreed. Why? Because the value I'm storing in my answer variable has not only been stripped of whitespace on the left and the right, it's also been forced to lowercase no matter how the user typed it in. And then I'm very deliberately checking for a lower case because I know it's going to be lowercase at this point because of what I did on line one. So that's better than before, and let's make it even better. We've seen how we can use or, so why don't we at least tolerate a more terse answer or the answer equals Y lower case because it too would be forced to lowercase. Now I at least have some more flexibility. Now if I really want to go to town, I could also check for quote unquote sure or other English expressions, but that seems like it's a little ridiculous. I could be even a little lazier instead of checking for yes or why. It'd be nice maybe to support, for instance, yeah, even though maybe being unreasonable, we can check for that too, maybe a little more lazily. I can do if the answer starts with a y. I don't care what the user says. Go ahead and assume agreement. Let me clear my terminal, rerun this again. I can type in yes. Clear my terminal, run Y. Uh, sorry, didn't bother clearing my terminal. Let me go ahead and rerun agreedie again. Type in yeah, agreed, but of course there's weird corner cases like yeah, no, still that's going to be misinterpreted now as agreement. So not to say you should tolerate even weird inputs like this, but how to do so really boils down to these basic building blocks of now functions coupled with conditionals. All right, well, what if we want to do something again and again, and we saw this in the example of searching a phone book. I might want to check to the left or to the right, and then I again and again want to divide and conquer that problem. So it certainly stands to reason that in general might be valuable to implement code that loops, that cycles again and again, so I don't have to write so many lines of code. I can write a few lines and effectively just reuse them again and again. Suppose that we want to implement like a virtual cat who's designed to meow on the screen. Well, let me go back to VS code, clear my terminal and close agree. ie, and let's go ahead this time and create, say, cat. ie. In cat. ie I can get it to meow pretty easily, I think. Let's go ahead and just print out meow, and if I want to implement a very happy cat that meows like 3 times, well let me copy and paste that 2 more times, and there's my cat meowing 3 times. Indeed, if I run Python ofca. ie, I've got meow, meow. If that's my goal, this code is correct. It's reasonably well styled because it's hard to go wrong when I've just got 3 lines there. But here too it's arguably not well designed. Why? Well, I literally resorted to copy paste, and while that was convenient and a little faster than typing it out 3 times, suggests usually that you're doing something wrong. Ideally, when writing code, you should be keeping it simple and not repeating yourself. After all, that's why functions were invented, as we've seen, and it turns out why loops were invented so that you could repeat yourself in code as opposed. To typing it all out manually yourself. So what's bad about this? Well, it does indeed meow 3 times, but why do I have the same darn line 3 identical times? This is going to be fraught eventually with possible bugs. Not now. It's kind of hard to screw this up, but if you consider these 3 lines representative of down the line, more sophisticated lines of code, what if I misspell one of those meows or I go in and change this program to a dog and it says woof instead of meow, but I forget one of the meows and. Still says and so it's a dog that's meowing like a cat, like bad things, albeit contrived, could go wrong, and that's going to happen ever more frequently when your code base is much longer and not just three lines of code. So in general, you never want to write the same line of code twice if you can avoid it or unless you have a good reason to. So why don't I just write this line of code once and then use some kind of loop?

Segment 20 (95:00 - 100:00)

Now there's a bunch of ways I can do this. We saw in our pseudo code for the phone book we can just say go back to a specific line. That's not something I can really do in Python. And in general that's not the best technique nowadays. We have better building blocks in code and languages like Python to do so, even though the first examples, I dare say, will look a little cryptic. Let me go back up to my cat here, delete all that code, and let me decide in advance that I want to do this 3 times. So I'm going to give myself a variable. I'll call it I for integer and set it equal to 3 just so that I can sort of keep track in my computer's memory in this variable how many times I want it to meow. Now I can do this while I does not equal 0, go ahead and print out quote unquote meow. So this seems logical. I set the variables value to 3. I check so long as it doesn't equal 0, and while it's not equal to 0, I do the following. So this while keyword is the first example in Python code of inducing a loop. It's a special keyword defined in the language. You could read that documentation that tells you if you provide a Boolean expression. After the word while, similar in spirit to a conditional, which just checks the bullying expression once, a loop is going to check it again and again on each pass through or iteration, so to speak, on each iteration of that there loop. But I don't want to just do this as is because something had better be keeping track of how many fingers I still want to have up. I want to go from. 3 to 2 to 1 and then 0. So I need to do this programmatically, and one way to do this would be on line 4, after I'm me, change the value of i to equal whatever the current value of I is minus 1. That is to say decrement I. Now this looks a little weird at first glance because it's saying like I equals i minus 1. Like how is that mathematically possible, but again, a single equal sign is the assignment operator. Copy the value I minus 1. And store it into the left hand side, which happens to be I itself. So if I is 33 minus 1 is 2, so I now becomes on line 4 the value 2. And then what happens is Python knows automatically to go back up to line 2, if only because everything here is indented, so it's pretty. Clear that this is inside the loop and this is the beginning of the loop itself. 2 does not equal 0, so it's going to meow again. Then we're going to decrement I again. So now I is going to equal 11 does not equal 0, so we're going to meow again and we're then going to decrement I. So it's now 0. is equal to 0, so this loop now terminates. There's no more lines of code to execute, so that's it. I've meowed 123 times simply by using a variable to kind of very mechanically, if you will, keep track of what it is I want to do. Now I don't have to do it this way. If you prefer not to count down, but you prefer to count up, I could do it as follows I equals 1. And then while I is heck, less than or equal to 3, there's no easy sign on a typical keyboard, so in many languages, Python among them, you do a less than sign, and then an equal sign to express that or the opposite, if you prefer. For greater then, then I can go ahead and meow just as before, but this time I have to be a little careful. I have to say I equals I plus 1 and increment I. So I'm starting at 1, I'm going to 2, I'm going to +33 equals 3, so that's it at that point. Indeed, if I go back to my terminal here and run either version, I'm going to now get a cat that meows as before, 3 times. There's a little trick though here that's worth noting. I don't have to start counting at 1 like us humans in the real world. In fact, it's conventional, as we've seen already for computers and in turn computer scientists to start counting from 0. After all, that's the smallest value other than negatives that you can represent with some number of bits. So even though it might be a little against your instincts, tends to be more conventional to start counting at 0, and then while you could change this to less than or equal to 2, I don't like the semantics of that because 3 is the goal. Why are we talking about 2? So a better way to express this is if you start counting at 0, count up to 3, but not through 3. Change your boolean expression to be I less than 3, so that if you start at 0, go to 1, go to 2. Once you hit 33 is not less than 3, so you'll stop at that point. So we've just shifted our range, if you will, from 1 indexed, starting at 1 to 0 indexed, starting at 0. We can actually tighten this up a little bit. It's so common in programming to add numbers like this to increment numbers that shorthand notation for line 4 is actually this I plus equals 1 has the exact same effect, but it's slightly fewer keystrokes, and it's a little quicker to read and therefore pretty conventional to use instead of the more verbose, I equals I plus 1.

Segment 21 (100:00 - 105:00)

This is correct. This is well designed. It's conventional. It's hard to find fault, but it's not the only way to implement a loop in Python. In fact, it's conventional to use not just the wild keyword, but if you prefer another keyword called 4. So how might I do this? The 4 keyword works a little differently, and it's a little tighter, fewer lines of code as a result. You can say the following 4 I in the following list of values 01, and 2, for instance, go. Ahead and print meow. To be clear, if I go down to my terminal and rerun this works exactly the same, but what's going on? Well, here we have an example of not just integers 01 and 2, but the square brackets around them imply that this is a different type of data altogether. This is a so-called list in Python of integers, which was one of the other data types that I alluded to earlier when we talked about ins floats, and more. So this is saying very tersely, I'll admit. For I in the following list of three values do the following. So what essentially is happening here automatically without you having to do as much work as with the while loop on the first iteration through this loop, I will be automatically set to 0. On the second iteration of this loop, I. Be automatically set to 1. On the 3rd iteration of this loop, I will be automatically set to 2. Now that's not that useful because I'm not actually using I anywhere, but this is indeed the conventional way to do something with a 4 loop to iterate over some number of values. But correct as this is, works exactly the same as the Y loop. It's not well designed, I would claim at the moment. Now why is that? Well, imagine the extreme scenario. You don't want meow 3 times, but maybe the cat's like really hungry and so it meows 30 times or 300 times. Are you really going to enumerate 34567. 89, not to mention 300 in that box there. Probably not. There's got to be a better way, and there is. Another one of the types in Python that we alluded to briefly earlier is that you can have a range of values very easily. In fact, if you want a range of three values, you can literally say range of three values range parentheses 3, and that will essentially. Hand you back a list of three values. By convention, the list is actually going to be 01 and 2, even if you don't care about the values, but it's gonna do some more efficiently by handing you back one number at a time on each iteration of this loop. And what's nice is if you do want 30. Such values or 300, you just change the number. You don't crazily enumerate all 300 or 30 of those values there. So I think we're on track now for an even better example and here just to make clear, if it's rubbing you the wrong way that we're declaring a variable I. But we're not really using it. We're sort of using the side effect of it doing this thing again and again. A minor subtlety in Python is that when you don't care about the value of a variable, you can actually name it something like underscore, which isn't really a special character. It's a valid character to use in the name of a variable, but it's just a visual clue to you down the line and any colleagues who might look at this code. OK. He's got a variable there but doesn't care about its value, just its functionality, the fact that this gives me the result of iterating 3 times. I don't always do this myself. Many programmers would still just use I for integer, which is a very common name for a variable for which you are incrementing in this way with an index value, so to speak, but either approach would work well. But as with all code, there's other ways to do this too. And in fact, a very neat one liner would actually be this print, quote unquote, meow, and then similar to how we use plus in a curious way before to do concatenation on strings, you can actually use the multiplication operator to do concatenation multiple times. If I want to concatenate that is joined together the word meow 3 times, I could do something like this. Now this isn't quite what I want yet. Python. of cat now. This is a bit of a step backwards, meow meow. OK, maybe the cat's very hungry or whatever, but that's not really what I wanted. So it's missing the new lines alone. How might I fix this? Well, recall that you can represent a new line with backslash n. It would not be correct to just go up there and hit enter because the code kind of looks weird now. Something went wrong like, no, it's conventional to just do backslashn inside of the double quotes. Then I can multiply that by 3 and let's see what happens. Pythonoca. ie again. There we have it, meow, meow. but subtlety, there's this weird blank line. Well, why is that? Well, you're getting 3 copies of meow and a new line, but then recall what print does automatically. Print itself always gives you a new line at the end unless you tell it that you don't want it. So I can use another lesson learned and use that named parameter and set it equal to the empty string, quote unquote, so to speak, rerun cat. ie. And now we're back in business.

Segment 22 (105:00 - 110:00)

So now I'm not even using a loop per se. I'm just using another feature of Python to do this a little more cleverly, a little more succinctly, which is fine if it reads well to you. At the same time, this looks more cryptic, so it might be better arguably to go with either of the former designs, the for loop or the while loop, which might just be more explicit and readable to the user, and that is a reasonable metric for code. Quality is it readable? Yes or no? is maybe more important is does it use as few lines as possible, which verges sometimes on being too arcane to be helpful. All right, what if I don't want the user to just assume that the cat's gonna meow 3 times and that's it for the cat meowing? Let's go ahead and let the user tell us how many times the cat will meow. So how might I do this? A very conventional way to ask the human. For a number, uh, is the following. Uh, I can do something like N equals in input, quote unquote, what's N, and just ask the user for this value, and then I can go ahead and as before, do like 4. I in range of not 3, but N passing in that variable's value as the input to the range function, and then I can go ahead and print meow. I'm going to go down here and run Python of cat. i. Enter what's N3 still works as intended, but if I run it again and type in 4, now I get 4 meows. Now if I go ahead and run it again, maybe I'll be a little weird and type in 0. OK, that's correct, if strange. Let me run it again. Type in -1. OK, that's a little weird, but also I got no meows. But wouldn't it be nice if I could prompt the user again for a number if they don't give me one that makes sense? If they give me 0, why are you wasting my time even playing this game? If they give me a negative number, that makes no logical sense. So let's actually use a loop to force the user to give me a correct value. So let me go ahead and propose this. I could. Do something like this. If N is less than 1, which is not what I want, then I can prompt the user again. But wait a minute, if N is still less than 1, OK, fine, ask the user again. What if they're still not obliging? OK, if N is less than 1, well, you can see that this will never. And logically, or if it does, you're only going to prompt them 34 times and that's it. What if I want to prompt them again and again, ad nauseam until they finally cooperate and give me a number. Well, let's not do what I'm doing there and copy pasting. Let's do this. While true is a common way to do this in Python. So this is a little weird at first glance because True is always true, so you're saying while true is true, do the following. I'm deliberately inducing what we'll call an infinite loop, but I'm going to break out of it as soon as I can. Inside of this loop, the first thing I'm going to do is set N equal to N, passing in the input return value of what's N question mark, and then. If n is less than 1, or logically if you prefer, if N is less than or equal to 0, which is the same thing when we're dealing with integers, go ahead and, OK, just continue, do that loop again. El if n is not less than or equal to 0, go ahead and break out of this loop. So these two keywords related specifically to loops allow me to break out of the loop prematurely, if you will. The condition here, the boolean expression, is never going to change. So on the one hand, I'm deliberately, and this is conventional, inducing an infinite loop, but I'm using a boolean expression elsewhere to decide when it's time to break out of this thing or continue on again. So to be clear, continue does not mean go down the line 8. It means continue in this loop. Continue in this loop because the user in this case is not giving me what I want. Now this is a little silly though to use 4 lines of code to express this. It is Not necessary to explicitly use the word continue. So rather what would be better is to flip the logic and say this if and only if n is greater than 0, go ahead and break. Same exact functionality, just as correct, too fewer lines, arguably more readable because again continue is not explicitly necessary. It's implicit that you'll just keep looping again and again until such time as you actually do break out. So now if I run this version. In my terminal with Python of Capi, type in 3 for N still works. Type in 4 for N still works as well. So some languages have other constructs that allow you to do this in Python, this is canonical to actually induce an infinite loop like this and then break out of it if and when you are ready. Unfortunately, you can get yourself into a little bit of trouble with these here infinite loops. Suppose for instance that I do something intentional or foolish like this. Let me go ahead and close out my CA, open up my calculator from before, and let's reinvent this calculator just to count up.

Segment 23 (110:00 - 115:00)

I'm going to set I equal to 0. I'm going to then say while true, because I just learned this trick. I'm going to print out the value of I and then I'm going to increment the value of I by 1. All right, so what does this do? This is sort of counting up from zero on up toward infinity, but because there's no brake, there's no conditional or boolean expression inside of the loop, it's never going to stop incrementing. So let's see what happens. I'm going to actually increase the size of my terminal window by clicking this little carrot symbol and then run Python of calculator. ie here, hit enter, and you'll see. That Python's counting up pretty darn fast. We're in the hundreds of thousands already. Before long we'll be in the millions. If we really run down the clock, we'll eventually reach the billions, the trillions, and so forth. This loop is going to run forever. And interestingly enough, in some languages this loop would weirdly stop on its own because many programming languages are vulnerable to another fundamental problem with computing of integer overflow, which is similar in spirit. To floating point and precision, which recall refer to real numbers potentially being infinitely many, and so it's not really possible to represent perfectly precisely all of those numbers if you only have a finite number of bits and indeed the artifacts we were seeing of the weird digits after the threes, for instance, were a symptom of how the numbers are ultimately stored in binary in the system. Integer overflow obviously relates to integers specifically because if you only have a finite number. Of bits, but you keep incrementing the number incrementing the number. If you think back to lecture zero's discussion of binary, eventually you're going to carry the 1 and all of the other digits are going to be 0. But if you don't have another bit, light bulb, if you don't have another switch, if you don't have more memory, somehow or other you might actually come all the way around to 0 or heck, if you support negative numbers, you might end up in the negative range instead. Now nicely, the latest versions of Python do not suffer from this problem, and while this might make the lecture all too long, this should never stop unless something else goes wrong. I will not be vulnerable in this version of Python to integer overflow, but it is in fact a problem that plagues other languages in particular, and we can rather see it if we revert back to some of our earliest examples of 123 on the screen. For instance, if I start incrementing 123, I of course. Go to 124, 125, 67, and onward. Eventually I will carry the 1, so to speak, because I can't write 10 for a single digit, so I carry the 1 and I put down a 0 there, and then the middle digit of course becomes a 3. But once I get up to like 999 and add one more, thereby incrementing this number, you carry the 1, but if there is no 4th bit, no 4th light bulb or memory, well, I'm going to. go from 999 to the number 0. So it would seem this is in fact what effectively happened with some systems, though not as many as the world feared in Y2K when our clocks rolled over from the year 1999 to 2000 because at the time so many systems in the world were using just two digits, the last two digits of years to keep track of years, and so 99 rolled over not to 100, let alone 2000, but to 00 instead. So this is a fundamental issue with again finiteness and what Python nicely does, as do libraries and other languages, is it just gives you another bit if you need it, and hopefully you're never gonna need such big numbers that the computer itself runs out of memory, otherwise there's probably a different or better way to tackle that problem. So this is never going to stop, at which point I've kind of lost control. Over my keyboard, it is not uncommon to accidentally induce infinite loops, especially while learning programming. Know that Control C is your friend to interrupt processes like this. Indeed, on my keyboard, if I hit Control C, sometimes multiple times, I will send a keyboard interrupt, at which point I see a cryptic trace back, but it's not an error with my code. It's because I interrupted Python itself, but now I'm back at my prompt and can do something more here as well. All right, well, how else might I use loops, not just for printing things and doing things like this. Let me go ahead and shrink my terminal window again. Let me close my calculator and let's do a little something with the names of some schools. So let me go into my terminal and do Python, or rather code of schools. ie. And let's go ahead and give myself a list of 3 schools similar to how I gave myself a list of 3 numbers, but now it makes more sense because I do care about these specific values. So I'm going to create a variable called schools. Python list using those square brackets, and inside of those square brackets I'm going to put 3 values. I could Put 012, but those are obviously not schools, so I'm going to put, let's say Harvard, quote unquote, MIT, quote unquote, and Oxford. So three values in this here list

Segment 24 (115:00 - 120:00)

and I can now print out each of those three schools as follows. Here's a bit of new syntax. I can use print. I can use the name of the variable. And if I want to print out the first element of that list, I can again use square brackets, but in a slightly different way I can put the number 0 there because again, computers and programmers tend to start counting from or thinking from 0 on up. So the first Element of the list in Python here is indeed the zero element, not the one element. So I'm deliberately using 0. Then I can go about printing out schools 1. schools bracket 2. If I go down to my terminal, run Pythonoschools. ie and hit enter, it's not an interesting program, but it does show me how I can 1 on line one store the names of three schools as strings and on lines 34, and 5, print out the first of those, the second of those, the 3 of those. Now even though lines 434, and 5 aren't. Really copy paste because they ever so slightly differ. There's obviously a pattern here. I'm going from 0 to 1 to 2. So there's some synergy with the looping we did earlier with I and incrementing it so we can actually be a little smarter here. And in fact, Python gives us a way to do this even without worrying about I. I can actually use a 4 loop like this. For school in schools, so much like range handed me back a bunch of values, schools is already a bunch of values. So using this terse syntax in Python for school in schools, though I could call this anything I want, I could say for X in schools, for I in schools, but semantically in English at least kind of makes sense to iterate over an a. List called schools one at a time, so the singular of schools is of course school. I just kind of like how this sounds and indeed I'd argue this reads like English more so than I or something arbitrary would. Inside of this loop, that's then gonna print out, not 0 or 1 or 2 because who cares about those numbers here I can just print out school. And so as before, what Python's doing for me is it's automatically setting this variable school to the first value, then to the second value. Then to the 3rd value, and Python knows how many values there are because there it is, and I put it in the computer's memory, it's gonna automatically terminate this loop after those 3 iterations without any need for arithmetic or numbers or variables like I. So that's a Python list. What more might I want to do? Well, I could go about doing something like this. Let me go ahead and erase all this code, clear my terminal here, and let me propose to store my schools with a bit more information. Be kind of nice to associate the schools with the the cities in which they live. And so for that it's kind of like on the. On the board as in the first lecture, maybe we draw a table with two columns, maybe the school's name on the left and the city on the right. Well, we can achieve that recall in our discussion of data structures with what we generally call a dictionary. A dictionary is a collection of key value pairs, maybe names and numbers, words and definitions, or something else. In this case, it could be school and city. So how might I give myself a dictionary? Well, recall that in Python there are other data types, not just ins and floats and lists. There are dict objects or dictionaries whereby I can use syntax like this. I can reinvent my school's variable to equal, not using square brackets because it's not a list per se now. It's going to be a dictionary, and the syntax is a little weird, but the convention is to do this a curly brace, and then just to make room for these schools, I'm going to move the other curly brace to another line. Then inside of these curly braces I'm gonna say the first school's name, then a colon, then the city it is in, which is Cambridge, then a comma, then hit enter and VS code is nicely indenting for me. Now I'm gonna go ahead and put MIT, then a colon, then MIT is down the road also in Cambridge. Then I'm gonna go ahead, put a comma, and in this. One Oxford, which a little amusingly, Oxford is in Oxford, so we can keep that one simple as well. So we've got two schools in Cambridge, one in Oxford, and just for parallelism, I'll put a comma here. It's not strictly necessary, but stylistically programmers nowadays tend to like the uniformity of ending lines like these with commas, even though nothing's coming after it. It's just a stylistic convention. So how now can I print out not the names of these schools because they're still right there on the screen for me, how do I print out where each of these schools is? Well, the syntax is similar to before, but instead of numbers I'm going to use words. So I'm gonna say for instance that um the first city is whatever the value is of the school's variable at the Harvard location. The second city is going to be the schools variable at the MIT and the 3rd value is gonna be schools at the Oxford location. Down here I'm gonna run in my terminal

Segment 25 (120:00 - 125:00)

schools. ie again enter and I'll see Cambridge, Oxford. So I've seen each of the values of those corresponding keys. Now at the moment this is a very simple program. It's just. Storing three schools in this way, but dictionaries are a wonderfully versatile way of associating data with more data, keys with values, names with numbers, words with dictionaries. It goes on and on the list of possibilities. So this is syntactically how you can implement that idea in Python of what we already explored as a data structure on the board or in the real world, the physical concept of phone books, dictionary. Are themselves and beyond. How can I make this a little more user friendly and maybe even loop over all of these things? Well, even without numbers involved, I can use a for loop as follows for each school in that school's variable. Go ahead and print out how about the school name first, then let's use the print functions feature of accepting multiple arguments. Let me go ahead and print out, uh, for instance, uh, let's say. Uh, is In with quotes around it, then let me go ahead and print out schools bracket school, which is a little weird, but again, schools is the variable that has everything. I'm using square brackets to access the value of a specific key in lists we did something similar. We use square bracket. Gets to access the value at a certain numeric index 0 or 1 or 2. Here a dictionary is sort of a generalization of that idea where now your keys are strings instead of mere integers like they were in a list. So if I did this right, let me try running Python of schools. Do i again, and I should have full, full fledged sentences. Ah, a little longer than I want. There's some weird spacing in there. Why is that? Well, I didn't need to put the space here or the space here because I get those for free. Recall that there's a default separator in Python that gives me a space. We can also override that. There is a named parameter for the print function that lets you change. That too, but I'm just going to get rid of the superfluous white space. Let me go ahead and clear my terminal to run this cleanly as Pythonoschools. ie, and there we have it. Three phrases that state the truth. Harvard is in Cambridge, MIT is in Cambridge, and Oxford is in Oxford. Again, demonstrative of how we might simply store a whole bunch of key value pairs. Now thus far we've had a lot of examples simply for example's sake, but I think it's time to transition to maybe some real world examples and then build on top of the code that others have written still by introducing yet other features of Python. But first, let's take a short break and we'll be back with some real world applications thereof. All right, let's now translate some of these building blocks to a real world problem such as the game of Super Mario Brothers, one of my favorites growing up, and This is a game that's composed of some obstacles, some coins, and some other features. For instance, this here seems to be a brick wall composed of 3 bricks, top to bottom. Let's, using some Asky art, so to speak, pure text, implement the tiniest portion of the screen, namely those 3 bricks. How might we do it using some of our building blocks thus far? Well, let me go back over to BS code. Let me go ahead and create a new file appropriately called, say, Mario. ie, and in this file, Let's just print out 3 bricks. Now the easiest way to do this would be to print out, quote unquote, a hash mark, and I can use any symbol here, but this looks the closest to, I would say, one of those bricks and just copy paste it 3 times. You probably know where this is going. This is probably not the best solution, but let's at least try it. Python of Mario. ie and we get brick, and we get our 3 brick wall. All right, I don't like this for reasons we explored earlier, which is that copy pasting, it's sort of like. vulnerable to mistakes down the line and it's just kind of unnecessary to have this kind of redundancy of identical lines like these. So how else might I do it? Well, we've seen before that I can go ahead and do 4 I or if I don't care about the variable name for underscore in the range of 3, because I do care about 3 in this case, let's go ahead and just print out a single hash. If I run this version of the program again with 3 hashes, I get exactly the same as before. Well, what if I want to pick off a different part of the problem and for instance want to consider something like this? In this screen here we actually have some question marks in the sky, 4 of them in a row instead of in a column. What are some of the ways in which I could implement this idea? Well, I dare say I could again use some kind of loop, but just to keep things interesting, why don't we go ahead and use one of our, uh, more clever one-liners, and in this case I could. Do quite simply print out quote unquote a question mark 4 times. Now if I go down to my terminal and clear it, run Python of Mario. ie, I think I'll get exactly those 4 question marks one at a time. Notice I'm not getting 4 new lines because I didn't do explicitly backslash N, but I am getting 1 new line for free because print at the very end by default always moves the cursor down to a new line for me. Well, how might we do something even more interesting than that?

Segment 26 (125:00 - 130:00)

Well, if you go underground in one of the levels of Mara, you start to see a lot of bricks like this. And if we sort of arbitrarily focus on maybe just these here, this looks to my eye like a 3 by 3 grid of bricks, so it's 2 dimensional now instead of 1 dimensional. We haven't really had an occasion to explore possibilities like these, so let me again go back to VS code. I'll clear my terminal here and let me propose that we could solve this problem in a few different ways, one of which is as follows 4 underscore or this time I'll be explicit, I in range of 3. Because I want to iterate over 3 rows and 3 columns, uh, for each of these and let me think of I as maybe being the rows initially I think this will work out best for each of those rows iterate from J in the range of 3 as well and then inside of that. That nested for loop, which we haven't seen before, let's go ahead and print out a hash but not yet a new line because I only want to print out a new line down here and recall that some functions can indeed take 0 arguments, print among them, and per the documentation, if you call print with no arguments, all you get is the new line. So at first glance, this is admittedly a bit cryptic, but let's think about what this means for I in range of 3. So this first line is telling Python to do something 3 times. Well, what do you want to do on the first pass of those 3 things? Well, for J in range 3, well, this too is telling Python to do something 3 things. So you're trying to do 3 things. 3 times that's going to give me a 3x3 of something eventually. So what do I want to do on that inner nested loop on line 2? Well, I want to print out a single hash but no new line. Why? Because I know if I'm iterating 3 times, this inner loop is going to iterate again and again each time printing a hash symbol but no line ending. Once though I'm done with the loop here on lines 2 and 3, I do want a new line because I want to move to the next row of bricks, so I do print out just a blank line and then notice the indentation. I'm going to go back to the second iteration and eventually the third outer iteration of the outer loop. To make this a little more clear, I can move away from I and J, which are reasonable conventions I, J, K, If you get more than 3 levels of nesting, probably doing something wrong and there's a better way to do it. But I and J, maybe K is sometimes reasonable depending on the problem. What could I do to make this more clear? Well, semantically, I could just give these variables. better names like for row in range and for call or explicitly if you prefer for column in range, this would allow me to sort of annotate my code implicitly in a way that makes me realize, OK, the outer loop is for rows, the inner loop is for columns, got it, even though technically I'm not really using those variable names in this case. So let's go ahead and run this down here. If I run Python of Mario. ie enter, there it is, my 3x3 grid. It's not quite as square as the actual bricks were in Mario. That's just because these hash symbols are a little taller than they are wide, but it is in fact a 3 by 3 grid. Now, arguably I could solve this problem so many different ways, but let me propose just one way that might help you think about how to solve problems like these, because I already have, of course, after years of programming experience, and instinct for how to do things, and I knew that I'd probably just want to nest two loops with each other in this way. But what if you didn't know that and you wanted to approach the problem a little more methodically and break down a big scary problem like printing out a two dimensional. Grid, which we've never done before, into a smaller problem that you are more comfortable with. Well, to print out this same pyramid, let me go into VS code here after clearing my terminal, and let me do something super easy. Let me go ahead and define a function called print row, right? I don't yet know how to deal with a two dimensional structure, but I'm pretty sure I can figure out how to print a row. So I'm going to define a function called print row. It's going to take as an argument. A width parameter so that I can tell it 345, whatever it is inside of this function I'm going to print out a single hash times that width. So if it's 3, I get 3 of them. If it's 4, I get 4 of them, but I've designed this function to be dynamic and take as input how many bricks I actually want. So that's it. And I think even at this point in the story, if you're new to all of this, hopefully you're on board with the reality that this line of code on line 2 indeed is going to print that many hash symbols, and I've packaged it up now in a function called print row so that I can use this again and again. Now why is this useful? Well, let me propose some abstraction out of sight, out of mind. Let me hit enter an arbitrary number of times to bring us back down to line 42, but we'll undo that eventually. Let me go back here to the top of my file to find a function called main that represents the main part of my code

Segment 27 (130:00 - 135:00)

and then in there let me do something more familiar like 4 I in range of 3. So do the following 3 times, please print a row. With 3 bricks. So I've decomposed the problem of printing a two dimensional structure into arguably a smaller problem of just printing 3 rows. I don't know or have to care at this point how rows are implemented. Why? Because I did that earlier and it's all the way down here and I've abstracted away what print row means. Now I can clean this up and get rid of all these gratuitous line breaks and at the bottom of this file kick start the whole process by calling main itself, but I think this might just be an alternative way. Thinking about the problem by breaking it down into smaller parts and plucking off each part in turn. Now if I go ahead here and run Python of Mario. ie and enter, there's my 3 by 3 grid, and I could go one step further and make this even fancier and instead of hard coding 3 and then 3 in 2 places because that is duplication and that's what a programmer might call a magic value like you're hard coding that is typing permanently the number 3, but why and why is it in multiple places? So I could factor that out. I could put it in a Variable or I can ask the user what number they want. There are ways to solve that, but for now the key point here is that when faced with a larger problem, what programmers typically do is they try to decompose larger problems into one or more smaller problems as well, otherwise known as hierarchical decomposition, and it's really a problem solving technique that lets you distill big problems into small ones that you can solve such that the composition of those solutions gives you the solution to the problem you actually care about. So what then are some other problems we might care about? Well, so many programmers have come before us, and indeed there are in the world what are called libraries, software that other people have written that you and I can use. Sometimes you have to pay for it, sometimes you don't, sometimes you can download it. Sometimes it comes with the system already. It entirely depends, but there's a wonderfully vibrant community of open source software, especially, or OSS for short, which refers to source code that other people have written. That under some terms and conditions sometimes you can use, but you can also read the source code. It hasn't been compiled into zeros and ones or obfuscated into bytecode of some form. You can actually look at the code, the upside of which is that you can gain some comfort perhaps that, OK, this code does what the person says it does because you can literally visually audit it yourself or have a more technical colleague do the same. You can also make changes to the code if you really want, and if allowed by the license under which you can use the software, you can fix bugs in mistakes in the software or by contributing them back to the community. So this is one of the most powerful things about the world of software is just how frequently we all stand on each other's shoulders, not just using functions that came with the language itself like Python's print function and input function and more, but also by installing or downloading other people's software. Third party software, so to speak, that we can similarly incorporate into our own programs. So libraries are an incredibly powerful technique and even within organizations and companies, might you have your software engineers write your own libraries of code that other employees can use too so that you can write code once and reuse it thereafter and not solve the same problem again and certainly not copy paste past solutions to future problems just to reuse that code. So let's do a few examples thereof. Let me go back into VS code now and move away from Mario and toward a program say called Generate via which I might want to generate some random values maybe like simulating, flipping a coin if I want to make a decision somehow randomly. Let me code up a file called generate. i. Let me in my new tab now do something like this. Turns out that Python itself comes with out of the box, so to speak, a library called the Random library, a module or more or depending on the library in question, a package more broadly that allows you to import that functionality into your own program, and it's installed somewhere else on the system already came with in this case Python itself. What might I use this for? Well, let me declare a variable called coin in order to simulate a coin flip. I will set this equal to the random library's choice function, which comes with it, and I know this from the documentation, the choice function takes as input a list of possible values from which you want to choose, like quote unquote heads and quote unquote tails. And then given that the length of that list is 2, by design, the random. choice function will give you back a return value of heads or tails 50%. Of the time each. If you passed in a third value, you'd get back each with 1/3 probability over time. Suppose I want to then see the result. I can quite simply print out this coin value and see if this function works as intended. Let me increase the size of my terminal here. Let me run Pythonogenerate. ie and see what the first coin toss is

Segment 28 (135:00 - 140:00)

tails. heads, tails, and so forth. And if we did this an infinite number of times, it really should work out to be statistically 50/50. Now that said, random is a bit of a misnomer. It's not truly random because at the end of the day these devices need to be programmed by humans. They can't just come up with a random number like we humans can off the top of our heads. They need to be told what to do. So these numbers are technically pseudo random numbers, sort of random numbers that statistically, if properly implemented, should be indistinguishable from actual random numbers. So what programmers could use to achieve pseudorandomness is looking at the current. Time of the computer's clock and basing the choice of random value on that, taking into account ambient information like ambient noise or temperature or something else that doesn't necessarily follow a pattern. And so with high probability, can these pseudo random number generators give you the distribution of values you want, even though technically they're not truly random. That said, what else might we want to generate? Well, if we want to go ahead and write this same program a little more succinctly, we don't have to import the entire random library. We can actually import only what we want. So for instance, I can do this. Let me clear my terminal window and back up into my code. Let me go ahead and say from the random library, import the choice function only. Now I do not need to use this dot notation, which we've seen in other contexts as well, to specify that. Choices associated with random. Now I've just imported the symbol, the name choice from the random library so that I have direct access to it as well. How else might I use this library? Well, if I want to use something like another function, I can import the random in function, rand in for short, whereby instead of choosing among heads and tails, let's do something like choose a random number between 1 and 10. So here I could do rand. In and then inside of its arguments I can pass in a lower bound and an upper bound and now let me go ahead and change the variable name to something more appropriate for an integer like number rerun Pythonogenerate. pi and I get 1. I get 3. I get 3, I get 10, I get 9, and so forth. If I run this again and again, I should get each of those values with equal probability over time. What more can I do? Well, what if I want to implement? a sort of card game here. Well, let's start as we did before. Let's import the whole random library this time. Let's declare a few cards, as you might see in the casino, some of whose values are Jack, for instance, and Queen and King, and we'll keep it simple with just those 3 cards. Then let's go ahead and use the random library's shuffle function to shuffle those cards, that is randomly order them. Then for each card. In that cards variable that's just been shuffled, go ahead and print that card one at a time. Let's now see what we see on the screen. If I run now, Python of generate. ie enter, I get Queen Jack King. If I run it again, Queen King Jack. But Jack, if I run it yet again. And Jack, king queen. So if we only run it a few times, we might in fact see a coincidence of the same values being outputted. But again, if you give me forever, you will see that uniform distribution. Well, what else can we do? Well, we can actually implement pretty powerful statistical techniques, even simple ones too, with very few lines of code. For instance, let me go ahead and code up a file called average. Dot i in order to calculate the average of some value by importing this time the statistics library instead of random. Then let's go ahead and print some statistics like for instance statistics. mean for the average of values of these two values, for instance, 100 that I just got in my exam. And maybe a 90, which I got on the previous one. Now this should be pretty easy to do in one's head calculating the average of these, but if you had a whole list of lots of numbers and ones that aren't as mathematically straightforward as 190 on a 100 point scale, let's go ahead and see what the program can do for me. Running Python of averagepi. And there I have it, 95. It just took care of the math for me, much like Excel and Apple Numbers and Google spreadsheets can as well. Well, what more can we do with Python using these libraries? Well, we haven't used this yet, but I have been using this feature. I have many times now run the Python command and the code command, and with those commands, I have been passing command line. arguments. So we've seen that word before. Functions can take arguments, but commands in your terminal window at that prompt can also take arguments as well, called in that context command line arguments. How can I write my own program that like Python itself and the code command takes an argument right at the terminal without having to prompt the user with the Put function. Well, I can do this in a few ways.

Segment 29 (140:00 - 145:00)

Let me go into my terminal here. Let's code up a program called Name. ie to get the user's name. Let's import the system library, which comes with Python 2, and let's do this. Print out, quote unquote, hello, my name is just like a name tag, and then close com sis. orgv1. Now this is cryptic for sure, but the system library gives me access to like system level functionality. RV is a variable that exists inside of that library, a list, if you will, an argument vector that contains all of the words that the human has typed at the prompt. So in fact, watch what happens now. If I were on Pythonofna. ie but without waiting to be prompted, type in my name right away. I and my code will be able to access DAVID as the value of sis. RV1. Why? Because RGV, AKA argument vector is a list of values. Those values are all of the words the human has typed at the prompt, and it's a list in Python, so I can use square brackets to index into the right location. If I hit enter now, I'll say hello, my name is David. But why did I use 1 instead of 0? Well, I literally mean all of the words that the human types in after the Python command itself. If I change 1 to a 0, rerun the same exact command with my name, I'll instead see hello, my name is name. ie because that's the name of the file. So the first word after the Python command that's. is in location 0. The next one is in location 1. Insofar as I care about the latter, it was in fact correct for me to use sys. rv1. So that's how the code command and the Python command itself effectively are gaining access to the file names that you want to create or interpret. Now things can go wrong, and let me induce that. Let me clear my terminal window. Let me run Python of name. ie, but forget about typing my name. Enter and I get another one of these trace backs, an error message that says something went wrong, and this time it's an index error. List index out of range and notice per these squiggles Python is trying to draw my attention to where the issue probably is. Now I've done this mistake a lot. I've written a lot of Python code. I know this means that location one. That is index one must not exist. Why? Ah, because I didn't type anything in. Now I could just rerun the program and cooperate and type in David, but this is not very user friendly software. You should not have to expose a scary looking error message to the user for them to cooperate properly. Like this is why we write better code. So among the ways to fix this is as follows. If I go back into my code, turns out in Python. There's a technique for catching what just happened, and what just happened is generally called an exception. Something exceptional happened and in this case exceptional is not a good thing. It means something happened that shouldn't have. It was out of the norm. But you can try to execute lines of code in Python and catch any such exceptions as follows. Instead of just blindly running this line of code, let me literally try to run this line of code, indenting it underneath that try keyword, except if there's an error, specifically an index error, otherwise known as an exception. In which case, you know what, go ahead and warn the user too few arguments, quote unquote. So now the effects will still be the same. The program's not going to work as I intend, but at least I'm telling the user in an explanatory way why it's not working. So if I again run Pythono Name. ie with David at the prompt, it works as intended. If I run the same command with. Out my name and hit enter, at least I don't get this scary looking message. So if you're in the habit of the real world of running some software and once in a while you do see some scary looking message, maybe not in a black and white window like this, but a modal, a dialogue window pops up with some cryptic error message or in a browser, it's not so much your fault as it is the fault of the programmer who didn't catch that error somehow. And explain it in a more user friendly way. All right, well, what more can we do here? Well, I could certainly hedge against this in different ways just to tie a lot of our ideas together instead of just blindly trying to do this, I could do something like this if the length of the cys. orgv. is less than 2. Well, I know already that there's too few arguments, so let's just tell the user without even trying anything. Let's print out quote unquote too few arguments. How about though else if the length of sys. orgv Is greater than 2. Well, I don't even know what's going on there. Maybe they typed their last name. Maybe they typed some nonsense. Let's just go ahead and say too many arguments and just not tolerate it at all. El now go ahead and safely print out hello, my name is quote unquote sis. RV1. In other words, in Python there's at least 2 different models here. You can try to do something and catch the error if it happens

Segment 30 (145:00 - 150:00)

or you can code more defensively, check if the thing you're worried about has happened, and then do or don't do something else as a result. So if I run this now and run Python of name. ie with nothing, I get too few arguments. If I run it with my name, I get hello, my name is David. If I run it with my name and last name, that is too many arguments at this point. All right, let's have a little fun with libraries that don't come with Python, libraries that I had to install in advance. I'm gonna go ahead and run code of say. ie so that I can get this program to say something. I'm going to now go ahead and import the library called cow Say per its documentation. That's how I import it. I'm going to then create a variable called name, set it equal to the input function's return value when asked of the user what's your name question mark. And now per the documentation I'm going to do cosa. cal. Quote unquote hello name, but I want to format this string as always, so I'm gonna put my F in front of the first quote. So I think this is going to use the library to say hello David or hello so and so. Uh, let me go ahead and increase my terminal window here and clear it and run Python of say. ie and see what this library does. Enter. Absolutely nothing. So it seems that even though I read about this library online, CA say it's actually not a module that's installed indeed in advance. It doesn't come with Python itself, but it is free and open source, so I can install it. And while there's different ways to do this, what I'm going to do on this system is PI install. Cow say, which would often be in its documentation too, and I clearly just missed that step. Once the program is installed, I can go ahead and rerun Python of say. ie. Enter. Here we go. Ask my name, crossing fingers perhaps which will help, and there I have it, an adorable cow saying something to me on the screen. However, I did spend a bit of time reading the documentation further, and it turns out that this cow say library doesn't just have cows saying things, you can have other things as well. Let me clear my terminal and shrink it again. Let me go back into my code instead of a cow. I read up that there's a T. rex, a Tyrannosaurus rex as well. Let me go back to my terminal and make it large. Let me rerun Python of Seta Pi. Let me go ahead and type in my name again and enter. And now we have too big to fit on the screen, even a Tyrannosaurus. that is also telling me hello and there's other Easter eggs in there if you'd like to poke around and read up on what it can do, but that's just now a little fun with a third party library that I did in fact have to install myself. Now on the one hand, this is great and fun and hopefully this library didn't do anything bad, but that's actually the risk too. Just because something is documented online, just because it's free and or open source doesn't mean the code is actually safe. And so in industry and enterprises, you might actually want to hesitate. Before just running a command like I did and installing something onto your system or more uh worrisomely your entire systems as well. So this is where lessons in cybersecurity can come into play, but more on those two another time. So but for now, beware and for more reasons than one. Well, what more can we do with third party libraries? Well, let me clear my terminal and shrink it again. Let's close out this cow and actually now create a program that uses the iTunes API. So long story. Short, there's a lot of companies and individuals out there that offer what are called APIs, application programming interfaces, and these are standardized ways of talking to someone else's system, someone else's code, and providing input and getting output for yourself that you can incorporate into your own program or product. For instance, iTunes, the music service, actually has an API via which you can search for music albums using keywords. In fact, what I'm going to do here is run a program called write a program called iTunes. ie. And in this program I'm going to do a couple of things. One, I'm going to import the SIS library as before so I can take command line arguments, and I'm also going to import the requests library, which is a library via which I can make HTTP requests, that is web requests as though I'm a browser but in code. So that is to say I can actually visit websites using code and not my mouse and a browser. I can see. being a browser, if you will, with this library. Let me now go ahead and just do a sanity check here, so to speak, and say if the length of cys. orgv does not equal to, then go ahead and just exit entirely. I'm going to use another function entirely called exit in the system library, and I know from its documentation this is just going to abort my program right now in the event that the user has not provided the right number of command line. Now this is going to be a mouthful, but what I'm going to type now is the following. I'm going to give myself a variable called response because I want a web server's response. I'm going to set it equal to this requests library's get function. It turns out that get is an operative word when it comes to browsers getting data from a server, so I'm going to use an identically named function here.

Segment 31 (150:00 - 155:00)

Just because it's a long line, I'm going to hit enter and move. The parentheses onto separate lines so that I can put the whole URL on a line of its own, and I'm going to say HTTPS in iTunes. Apple. com/ear question mark entity equals song because I want to search for songs and I'm going to limit it to just one response, even though I might get back many songs, I'm just gonna get the first and the search term that I'm gonna search for after making limit equal to one. And the search term I'm going to search for is gonna be whatever the human has typed out at the command line, which I know from before is insist. RV1. So in other words, I'm using Python code to construct a URL, most of which I know in advance, but I don't know the keyword that the human's going to type in advance, but I do know that it's supposed to per Apple's documentation come after this equal sign after the word term. And in fact limit equals one. I know from the documentation will do just that. It will limit. Responses to just one song and the type of things I'm gonna be searching for are songs indeed. And so these ampersands just separate what curiously are yet another example of key value pairs using equal signs now instead of Python's own colons, but we're inside of a big string URL which is a different beast altogether. So now at the bottom of this code I'm going to just print out what that response is specifically using a function called JSON, which stands for JavaScript Object Notation. And in the world of APIs, application programming interfaces, JSON is an incredibly common format for sending. Data from a server to a client, whether that client is a browser or in this case an actual program. It's a text-based format. It's all about key value pairs that you can have lists or so called arrays in it as other as well as other values. This is not a useful program yet. I'm just going to dump to the screen what I'm getting back from Apple's Server. So what I'm going to do now is go back to my terminal and make it larger so we can see as much as possible. I'm going to run iTunes. ie, but I do need to give it an argument and let's go ahead and search for someone like Taylor Swift, quote unquote, and I want to pass in her whole name, so I'm indeed going to pass it in quotes at the command line, so it ends up entirely in RV1 instead of in RV1 and 21 word per each. Enter. Now this is kind of a mess. There's a lot to see on the screen here, but allow me to draw your attention to a few features. One, there's colons all over the place. Now, even though this is JavaScript object notation, which is a different language altogether, JavaScript, we're dealing with Python, many languages use the same syntax for certain things, so it's actually similar in this case to Python. But there's some other similar syn. 2. I see a curly brace here. here and the corresponding ones later. I see a square bracket here and the corresponding one later. So even though as is, this is very hard to read, it turns out that what Apple has responded with is indeed JavaScript object notation, but specifically the data they've responded with are essentially dictionaries and lists. key value pairs and lists of values, and JavaScript happens to use the same syntax, curly braces and square brackets for the same concepts. JavaScript happens to call them objects and arrays. Python dicts and lists, but the ideas are exactly the same. Now I can actually clean this up. Let me clear my terminal window. Let me go back to my code. And let me, having read the documentation, pass in another argument here, uh, to print than just this. Instead of passing in response. JON, let me call JSON. Dumps for dump string response. json and specifically indent. Uh, please 2 spaces. Now I'm going to go up here and import now the JSON library, which is a feature of Python that just gives me access to JSON related functions just to clean this up. This is not useful programmatically. This is useful for us, the humans. Let me go back to the terminal and make it bigger, run Python of. iTunes. ie. I'll type in again in quotes Taylor Swift, and now I'm going to get back, I think the same response, but it will be pretty printed, so to speak, with nice indentation and white space all over the place just so that we can see a little more clearly what's going on. Now it's still too big to fit on the screen, but let me scroll down. So that I can see the very top and ah here's what I got back. I got back a curly brace first, which means here comes a dictionary of key value pairs. What's the first key? Result count, the value of which is one. That makes sense because I told the API to limit me to one response. What's the next key, quote unquote results. What's the value of that key? Well, per The square bracket here, it's a list of values. What's the first value? Well, according to this curly brace, the first and only value is itself a dictionary of more key value pairs.

Segment 32 (155:00 - 160:00)

Hence, you're seeing my claim that these key value pairs and these dictionaries more generally are wonderfully convenient mechanisms for sharing data. The first key. Perry has a rapper type of track. Don't quite know what that means, but I'm sure the documentation would reveal the kind of song, the kind of response I understand. It's a song. Apparently this is Taylor Swift's unique identifier as an integer. This is the collection to which this song belongs. The artist's name is indeed Taylor Swift. The collection name is Taylor Swift, the bonus track version. And so forth. And there's a lot of other key value pairs here, but long story short, if I were trying to implement my own piece of software that somehow uses music data in this way and let's users search for it, I could do exactly this and I could print out in this case exactly these. Results. In fact, let's make one change here. Let me clear my terminal window and shrink it and let me go back into my code here and instead of limiting the results to one, let's go ahead and get rid of that so that I actually get back more than a. Single results. Then down here I'm going to change my code slightly and not just dump the result. We're going to do this a little more elegantly. I'm going to create my own variable called O for object, which is conventional, and set it equal to that JSON response, though as always I could call these variables anything, but I'm doing this so that I can iterate over the results therein. So for each result in that dictionary's results keyword. I'm going to go ahead and print out that results track name. In other words, I have, having looked at the format of that JSON response earlier and having checked the documentation, I know that there is a results key and in turn a track name key, the values of which I'm interested in. So let me go back to my terminal and make it bigger. Run Python of iTunes. ie, quote unquote Taylor Swift, enter, and I now see a. Whole bunch of track names, song titles by Taylor Swift, at least based on that keyword search alone. So you can imagine now making this much more feature for. You can make your own streaming media service, it would seem, if you could link directly to those songs on iTunes, but it's all a matter of using some code that I wrote, using libraries of code that other people wrote, and in this case using a documented API provided by someone else, in this case Apple. Well, what more can we do? Well, let me go ahead and do this. I'm going to actually switch from my cloud-based version of BS code to my own Mac, inside of which I have my own terminal window. And any of you that have Mac OS and even Windows, if you install some additional tools, you can have your own terminal window on your Mac or PC via which you have your own command line interface or CLI. I've made it look like the one we've been using, but now the code is running on this actual laptop, not somewhere else in the cloud. In here on my Mac's own command line interface, I'm inside of a folder that already has 4 files 2 images and 2 files of Python code. The images contain faces that might already be familiar to you. In fact, if I go ahead and on my own Mac open this image called Office. JPEG, you'll see these faces here. Now among them are quite a few faces, and it might be nice to sort of recognize each of those faces individually. Now how To do this, well, odds are you can detect sort of two eyes, a nose, a mouth, 2 ears in general, but I don't really know yet how to write that code. But indeed, if I've installed a library in advance, I can write maybe less code that allows me to use someone else's logic to achieve this goal. So in fact, let me go back to my own command line interface, my own terminal window, and using a program other than BS code, I'm going to go ahead and show you what Inside of this file, the file itself is called detect. ie, and here we have just a few lines of code, the top of which are some comments from which the code came, and you'll see near the top of the file I'm importing from the PIL, the Python image library, some kind of image related feature. I'm then importing seemingly magically face recognition as a feature. Thereafter I'm creating a variable called image and I'm somehow loading an image file. Called Office. JPEG. Thereafter I'm declaring a variable called face locations, and I'm somehow using the face recognition library to find all of the face locations in that image, passing it in as an argument. Then I've got a for loop and somehow or other I'm iterating over all of the locations in that image that would seem to be a human face, and I'm going to show each of those faces in turn. So how's this going to work? Well, let me go back to my terminal Windows prompt and let me go ahead and run Python of detect. ie, thereby running the code on my own Mac. I'm going to hit enter. It's going to analyze the photo and take just a moment, and you'll see quite rapidly all of these little images opening up that represent some excerpted faces. Let me go ahead and scroll through each of these. And you can perhaps identify each character in turn and somehow or other this third party library has detected what it knows to be

Segment 33 (160:00 - 165:00)

faces based on seemingly common patterns among them. But we can do more than that. For instance, suppose that we have per this library a known face that we're looking for. We don't have to just look for two eyes, a nose, a mouth, and two ears. We can look for a specific face even if it's not quite the same photo. In fact, in my terminal window, let's go ahead and open up a picture of the office's own Toby, whose mug shot looks a bit like this. He's in that photo, but not necessarily posing that way. Let me close that image, go back to my terminal window, and this time run Python of recognizeie because I now want to recognize. Specific phase. I won't open up this whole file because there's more lines of code here, but most of them rely on this third party library having done the heavy listing for us. I'm going to go ahead and enter the code is opening both of the images now, and there it goes. If I zoom in here, it is not only found Toby, it has identified him by drawing a green box thereupon. So not too bad for just some lines of code on top of a third party library to get all of this functionality myself. Let me now go back into my terminal window and this time let's write a program that uses another third party library this time to synthesize speech. Instead of VS code, I'm again going to use a lighter weight program within my terminal environment called VI or VIM, and let's create this file as follows. At the top of the file. Let's go ahead and import Python text to speech version 3, which indeed is the library I've pre-installed. Let's create a variable called engine because this is a text to speech engine. Let's go ahead and set that equal to the library's in it function, which simply initializes the library doing whatever it is the programmers needed to do. Let's use that engine's save function to quite simply say for now hello world and then per the documentation, let's call engine. ru and wait since it might take a moment for it to actually synthesize and then say these two words. Let me save that file and return to my prompt. Let me go ahead now and run Pythonospeech. ie and let's have a listen. Hello world. Well, that took quite a while to synthesize that speech as short as it was, but it did in fact synthesize it accordingly. Well, let's go ahead and make a change and make it a little more interesting. Let me go back into speech. ie, and this time, let me have it say hello to someone's name. So before I actually say hello world, let's ask the user, as we've long done, to for the. own name with name equals input quote unquote what's your name? question mark. Then down here let's actually substitute in that person's name and then over here format the string accordingly. Let's save out of this file rerun Pythonofspeech. ie. I'm prompted in a moment after the library's done initializing with this familiar now phrase What's your name David? And let's have a listen to this. Hello David. There we go. So much of the time was spent initially initialized in the library, but once we provide that input, it actually synthesized it quite quickly. So a simple example, and I, as a programmer might have no idea how I convert text to speech, but the third party library. Did so long as it's installed. Now, what else can I do? Well, I can even have my computer start listening to me in a few different ways. Let's do another example here again using this program called VI or VM to implement Listen. ie lastly. I'm gonna go ahead here. And at the top of the file I'm going to ask the user for some words which I'll store in a variable called words. I'm going to set it equal to the return value of the input function that simply asks the user to say something, not very descript. Then let's go ahead and actually I'll insert a new line just to force the cursor onto a new line this time, and I'm going to force the user's input to all lower case. Then let's go ahead and do this. If the user has said the word hello in their words, then go ahead and print out, for instance, after. Indenting four spaces, hello to you too. In other words, conditionally, if the word hello is in the words that came back from the user, greet them as well. Now in is not a keyword we've used in this way, but it does allow me to check if a string on the left is in the string on the right. How else might we proceed? Well, if they don't say something like hello, but maybe they say L if how are you? In their words, then let's go ahead and print out, say I am well, thanks. Else if the user has said something like goodbye in their words, let's go ahead and print out reasonably goodbye to you too. Else if they didn't say any of those things, and we don't know really what they said in this version, we can print out something like huh, because it's not yet recognized. All right, if I now save this file and return to my prompt and type listen. ie

Segment 34 (165:00 - 170:00)

I can now listen textually for the user's prompts. Let me go ahead and say something like, hello there. Oh, hello to you too. Let me run it again. Hello there, how are you? question mark. Here again we get hello to you too, even though I did say how are you? it came after the hello, so that makes sense because that boolean expression was asked first. So if we ask the same question alone, let me clear my screen and run it again. I now can say. Uh, hey, how are you? And because we're not looking for hey, it will know that we've said how are you. If now I'm getting a little bored with this, I might run it again and say goodbye now, and it will say goodbye to me now too. And of course if I type in anything else, it will say huh, because I haven't actually written some code for that. Well, let me propose that we this time use a third party library that allows me to write just a little more code, but to actually My microphone allow me, the human to verbalize what I have in mind, similar in spirit to your Google Assistant or Alexa or Siri or some other device nowadays. I'm going to go now into the same file and delete everything we've done, and I'm going to go ahead and import this time speech recognition. Thereafter I'm going to create a variable called recognizer, I could call it anything I want, set it equal to speech recognition. And recogniser, which I know from the documentation is how I start using speech recognition. I'm then gonna say the following, with the speech recognitions microphone. As my source, which again I know only from the documentation, I'm going to say the same thing as before, say something, asking the user for just that. I don't need the backslash N because I'm not using input this time, but the print function itself. Next, I'm going to go ahead and declare a variable called audio and set it equal to that recognizers listen function passing in the source to listen to, namely my microphone. After all of that, I'm just going to tell the user what they said just to prove that this works. I'm gonna print out you said coin, and then rer. recognize Google audio. All right, how now is this going to recognize my speech essentially by sending the request off to Google? Let me save this file, run after clearing my screen, Python of Listen. ie. Definitely gonna cross my fingers this time and hit enter. Hello world. And it worked. Let's try once more. How are you? So it's detecting my own human words, so it would seem that if thanks to the speech recognition library, I have the ability to understand human words, I can combine a couple of these ideas now and search for some of those same words. Among the words that came out of my mouth, so let's actually do this. Let's go back into Listen. ie. Let's go ahead now and not just spit out you said, but instead let's go ahead and store in a variable called words the recognizers use of the recognize Google function passing in that same audio and now as before if hello is in words. Then go ahead and print hello to you too, if, how are you? is in words, let's go ahead and print out, quote unquote, I am well, thanks. if quote unquote goodbye is in words, then let's go ahead and print out quote unquote goodbye to you too. El as before, if we just don't recognize any of the words they're in, we can print out something like huh, or handle that differently. All right, let me save this version now and go back to my terminal, clearing it again and running once more listen. ie and we'll try again. Hello world. And now it's detected and recognized what I've said. Let's try another. Hey, how are you? I am well, thanks, and final flourish, thanks so much. Goodbye. And that works too. Let's add one final flourish and demonstrate with yet another library, this one that comes with Python, how we can not only detect and recognize audio, we can also now extract individual pieces of information much like today's voice assistants can. Let me go back into Listen. ie and let me import at the top of this another library called RE for regular expression, a very fundamentally powerful feature of not only Python, but many. Languages as well that allows us to use patterns to find or extract information from strings of text. In fact, what I'm going to do down here now is this I'm going to delete all of these conditionals and boolean expressions

Segment 35 (170:00 - 172:00)

and what I'm now going to do is this create a variable called matches, set it equal to that regular expression library's search function. I'm going to search for my name is, but I'm going to expect that any human who says that is probably going to say literally. Name next. I'm going to use a pattern which is representative of a regular expression. We're using dot star where the dot in this context represents any character and the star or asterisks represents zero or more of those characters, and then I'm going to close that quote. So this is going to be a pattern that looks for someone saying my name is and I'm going to try to extract from that the name right after and I'm going to pass in his input the words that they've said. If there are such matches, I am then going to Print out, for instance, hey, comma and then inside of my curly braces here, the first such match 0 contains another value, but matches 1 per the documentation for the RE library will indeed contain the first match that I care about. I'll go ahead and complete my thought there, close my parenthesis, and at the beginning, cause I want to format this string, add our familiar F. Else if there are no matches, I guess we'll just have to make do and say something like, Hey you. And leave it as follows. All right, with one final flourish, let's go ahead and run this version here after clearing my screen, Listen. ie and hit enter. Hello there, nice to meet you. My name is David. Hey David, as our final flourish. This then was all about practicing programming, a crash course if you will, in Python specifically, but programming more generally. Python is indeed representative of quite a few languages out there, and it is indeed so very popular nowadays for data science, for websites, and so much more, and we hope that it serves for you as representative of not only what you can do with code, but probably what some of your colleagues, friends, or family members are already doing every day and makes you all the more conversant in discussing just that and more with them.

Другие видео автора — CS50

Ctrl+V

Экстракт Знаний в Telegram

Экстракты и дистилляты из лучших YouTube-каналов — сразу после публикации.

Подписаться

Дайджест Экстрактов

Лучшие методички за неделю — каждый понедельник