[User] Please transcribe this text

[Assistant] Also helpful is if you realize that you've made a change that you didn't mean to and you want to go back to a previous commit.


[User] Please transcribe this text

[Assistant] Then in that case, you can use a command called git reset, which has a number of different possible ways to use it. But git reset in effect will take the current state of the repository and revert it back to an older state of the repository, for example.


[User] Please transcribe this text

[Assistant] So a couple of ways you can use it are like this. You can do git reset dash dash hard, meaning hard reset, reset everything.


[User] Please transcribe this text

[Assistant] Back to, and then you can plug in a commit hash. So git log, as you might recall from before, gave you the commit hashes for each of the various different commits. If I want to go back to one particular commit, I can say git reset dash dash hard, and then the commit message I want to, or the commit hash that I want to go back to, and I'll go back to that commit.


[User] Please transcribe this text

[Assistant] Alternatively, I could say something like git reset dash dash hard origin slash master. And recall that origin slash master is the version of my repository that's currently on GitHub. So if I want to take my current version of the repository and reset it back to whatever is on GitHub, then I can use a command like this in order to do so.


[User] Please transcribe this text

[Assistant] So you run git reset followed by a commit hash and that will reset the current state of your repository back to whatever state it was in previously.


[User] Please transcribe this text

[Assistant] And there are a number of other git commands as well that can be quite helpful as you begin working with larger and larger projects. But these are some of the most helpful and some of the ones you'll use the most often are just adding files that you want to keep track of. Git commit to say I would like to make a save. I would like to save the current state of all of these files.


[User] Please transcribe this text

[Assistant] Push and pull to be able to upload changes and download changes that have been made to your repository. And then some helpful commands like reset and log and status just to give you information about your repository and get you back to an older state of the repository if you need to.


[User] Please transcribe this text

[Assistant] But as we begin to work on more and more projects, and especially as we begin to work on more sophisticated projects, you may find that just keeping track of one change after another isn't nearly as powerful as you might like it to be. And so we can explore what might happen in a hypothetical situation where you begin making some changes to a git repository, for example. So let's imagine you make your first commit.


[User] Please transcribe this text

[Assistant] So you start working on a new feature, then you continue working on that new feature, but then you realize suddenly, you know what, there was a bug in the original code that I made way back here and you want to go back and fix that bug.


[User] Please transcribe this text

[Assistant] But now we're sort of in a tricky spot that we want to fix the bug, but we're in the middle of working on a new feature. So what do we do? We could go back to this and try and fix the bug. But then what happens to the new feature? The problem is that this structure just change after change after change is very linear. It only goes one after another after another.


[User] Please transcribe this text

[Assistant] And oftentimes when you're working on a project, it's not going to operate in a very linear fashion. You're not always working on one thing that immediately follows the thing before it. You might be fixing multiple bugs while working on multiple new features and you want some way of being able to work on all of those things simultaneously and to easily be able to switch between them.


[User] Please transcribe this text

[Assistant] And so that is where branching comes into hand. Branching is a Git's way of working on different parts of the repository at the same time.


[User] Please transcribe this text

[Assistant] And so you might imagine a situation unfolding more along these lines. You make your first commit, you start to make changes, you make more changes, and when you decide that you'd like to start working on a new feature, for example, rather than keep making changes in one after another after another on this same branch, so to speak,


[User] Please transcribe this text

[Assistant] I can create a new branch. I can branch off and say you know what? Let's create a new branch and start working on a new feature there. And then keep working on that new feature there.


[User] Please transcribe this text

[Assistant] And if I realize later on down the road that, you know what, there was a bug way back at this commit, then I can go back to this commit and create a new branch where I go ahead and fix that bug. And now I have two different branches, each of which might have different code on it, one of which I've been fixing a bug, one of which I've been working on a new feature on, for example. Generally, each of those branches is going to have a name.


[User] Please transcribe this text

[Assistant] So the master branch is your default branch, which is generally going to contain the up to date stable version of your code.


[User] Please transcribe this text

[Assistant] And as you're working on newer things, newer additional features, you might have some feature branch where you're working on some other feature, for example.


[User] Please transcribe this text

[Assistant] And at any given time though, your focus is only on one of these two branches. And where your focus is, what the current state of your repository is, is designated by something we call the head.


[User] Please transcribe this text

[Assistant] So if head is pointing to master, that means your repository right now is working on this branch where you fix the bug.


[User] Please transcribe this text

[Assistant] But you can change the head. You can switch what branch you want to look at and you can check out the feature branch and say, let's look at that branch and begin working on that as well. And you can begin working on these different branches by switching where your head is, switching from one branch to another and then back again.


[User] Please transcribe this text

[Assistant] And only when you're satisfied, that you know what, this bug is fixed and this feature is in a satisfactory place, then after all of that, we can merge those changes back together so that everything comes back onto this unified master branch that now has all of the latest code.


[User] Please transcribe this text

[Assistant] And that's the real power of Git branching, this ability to say that I would like to be working on multiple things simultaneously and be working on a feature without disrupting the master version of the code.


[User] Please transcribe this text

[Assistant] So let's now take a look at an example of how we might go about doing that.


[User] Please transcribe this text

[Assistant] So here in my hello.html file, I've been adding some style to this h1. I added a color of blue. And let's say that I would like to make some changes. I would like to move the styling outside of inline styling. And I'd instead like to move it up into the head section of my web page, because we decided earlier that was slightly better design for a web page like this.


[User] Please transcribe this text

[Assistant] I could make those changes immediately, but I can instead, if I expect I might be working on multiple changes, I could move on to a different branch and branch off into something else in order to work on these new changes. And so here are some of the key commands to know about this.


[User] Please transcribe this text

[Assistant] If I type git branch, that will tell me what branch I'm currently on and what branch has exist in my repository.


[User] Please transcribe this text

[Assistant] So here, for example, I type git branch and I see that I just have a single branch called master and the star on the left hand side tells me that this is the branch that I am currently on, the only branch that there is.


[User] Please transcribe this text

[Assistant] If I want to check out a new branch, I can type git checkout.


[User] Please transcribe this text

[Assistant] And if it's a new branch, I'll type git checkout dash b, and then the name of the new branch.


[User] Please transcribe this text

[Assistant] So I typed git checkout dash b style and git gives me a message. I have switched to a new branch called style. And now if I type git branch again,


[User] Please transcribe this text

[Assistant] You'll see that now I have two branches. I have the master branch, which is the branch I was originally on. And now I have the style branch, which is this new branch, which I am on now as indicated by the star on the left hand side.


[User] Please transcribe this text

[Assistant] So now that I'm on this new branch, I can feel free to make any changes that I want, and nothing I do is going to mess up what is on the master branch, so long as I stay on this branch. So I can say, alright, let's experiment with removing this style, and let's add a style tag to the top, where I can say that I would like my h1 to have a color of blue, for example.


[User] Please transcribe this text

[Assistant] So I've made a whole bunch of changes and I would like to now commit those changes. I'll say git commit move style properties. That's the change that I've made.


[User] Please transcribe this text

[Assistant] But I've only made those changes to the style branch. Again, if I run git branch, you'll see that I'm currently on the style branch where I've moved the style information up here to the top of my page.


[User] Please transcribe this text

[Assistant] But I can switch branches by using git checkout. Git checkout allows me to switch between branches. We used git checkout dash B to create a new branch. But if you're switching to a branch that already exists, I can just say git checkout master, for example, to switch my current branch from the style branch to the master branch.


[User] Please transcribe this text

[Assistant] So I run git checkout master. Now I'm on the master branch.


[User] Please transcribe this text

[Assistant] And now you'll see if I go back to the file, now I'm back to the inline styling without the styling up here in the head section of the page.


[User] Please transcribe this text

[Assistant] If I check out the style branch again, then the file immediately goes back. Now I have the style code up here in the style section of the page and not inline.


[User] Please transcribe this text

[Assistant] So these changes have only been made to one part of the page. So now, I'll check out master again.


[User] Please transcribe this text

[Assistant] And maybe I want to make some other changes on my master branch. Maybe I realize that I want to remove this extra punctuation. You know what? Two exclamation points was too many. We'll remove, now we just have one. And now I'll commit these changes. I'll say git commit and remove punctuation.


[User] Please transcribe this text

[Assistant] And now I've removed the punctuation only from the master branch.


[User] Please transcribe this text

[Assistant] So this master branch now has just a single exclamation point here, but it still does have the inline styling.


[User] Please transcribe this text

[Assistant] So now what I'd like to do is merge in those changes that I made from the other branch. I'd like to take what I was working on in the style branch and merge it into this current version of the repository on my master branch. And in order to do that, the command we'll use is called git merge.


[User] Please transcribe this text

[Assistant] So git merge, notice that I'm currently on the master branch. But if I run git merge and then style.


[User] Please transcribe this text

[Assistant] That is going to take whatever's on the style branch and attempt to merge it into my current branch.


[User] Please transcribe this text

[Assistant] But there's a merge conflict. Now this won't happen all the time when you merge. Sometimes Git will be smart enough to know that if one change has been made to one part of a file and one change has been made to another part of a file, when you merge those changes back together, Git will resolve those merge conflicts automatically.


[User] Please transcribe this text

[Assistant] But in this case, that wasn't the case because both my style branch and my master branch made changes to the same line of code. And we'll see why if I go back here.


[User] Please transcribe this text

[Assistant] You'll notice that in the merged version, we do see this style tag at the head of the page. No problems, no conflict there, because that was just lines that have been added to this page so there was no conflict.


[User] Please transcribe this text

[Assistant] The conflict comes up here, which is where in my version on the master branch, I removed this punctuation mark, whereas in the version on the style branch, which we can see here by the word style, we removed the inline styling. So we need to resolve these somehow and what I'll ultimately do


[User] Please transcribe this text

[Assistant] Is just get rid of these style markers, or the conflict markers.


[User] Please transcribe this text

[Assistant] And say, you know what, I would like for the updated version not to have either, not to have the inline styling and not to have the additional punctuation. So I have now made those changes. I have resolved the merge conflict and now I can commit. I fixed the merge conflicts.


[User] Please transcribe this text

[Assistant] And that's the general workflow now of how branching in Git ultimately works. When you're working on something new,


[User] Please transcribe this text

[Assistant] Sometimes you'll have to deal with merge conflicts, though certainly not always. And if you're careful about where you make changes and trying to be careful not to make modifications to the same line of code in two different places, you can reduce the likelihood of actually getting a merge conflict. Because Git ultimately is quite smart about how it tries to deal with these sorts of issues.


[User] Please transcribe this text

[Assistant] And finally, we'll take a look at a couple of features of GitHub specifically that can be quite helpful if you begin to work on larger projects that have many different moving pieces. The first of which is forking a GitHub repository. So let's go to a GitHub repository and look at the GitHub repository for Bootstrap, for example.


[User] Please transcribe this text

[Assistant] So Bootstrap, which is the CSS library that we took a look at.


[User] Please transcribe this text

[Assistant] Last time is a library that gives us easy access to a whole bunch of different CSS features and the entire thing is open source, meaning all of the code for Bootstrap is publicly available for anyone to look at and more importantly for anyone to contribute to.


[User] Please transcribe this text

[Assistant] That it's not just one person that's been working on all of Bootstrap, but it's a community-driven repository that many people can be working on adding new features and making fixes to Bootstrap's code and collaborating on them by taking advantage of the features of Git.


[User] Please transcribe this text

[Assistant] So if you find a Git repository that you would like to contribute to, or if you want other people to be able to contribute to your repository, one thing you can do is fork that repository.


[User] Please transcribe this text

[Assistant] And by forking, we mean making your own copy of the original repository. And so up here in the upper right hand corner of GitHub's page is a button called fork. And we can see that right now about 68,000 people have already forked Bootstrap's repository, made a copy of the repository into their own GitHub account.


[User] Please transcribe this text

[Assistant] And so we could fork it ourselves just by clicking on this button called fork.


[User] Please transcribe this text

[Assistant] The reason we might do that is that Bootstrap's repository, while it is public, doesn't allow anyone to just push to it. That would be probably unsafe if anyone in the world could just update Bootstrap's master code. But what you can do is copy the code, make a fork of it,


[User] Please transcribe this text

[Assistant] Make changes to it on your own, push and pull to it. And then, when you feel like you've made a contribution that you would like to send back to Bootstrap,


[User] Please transcribe this text

[Assistant] You can open what's called a pull request that you are requesting that your code be pulled in to bootstrap's code. And we can look, for example, at bootstrap's pull request tab.


[User] Please transcribe this text

[Assistant] It looks like right now, there are 71 open pull requests. There are 71, uh, people that have made some fixes or made some changes to Bootstrap's code, and you can submit a pull request to say that you would like to, uh, take those changes and merge them back in with Bootstrap's actual code.


[User] Please transcribe this text

[Assistant] And the people that maintain Bootstrap's code in this particular repository can review those pull requests, provide feedback, ask for additional changes. And then when everyone's satisfied, they can merge those changes into Bootstrap's actual code.


[User] Please transcribe this text

[Assistant] And this is one of the key benefits of open source software, the ability for multiple people to be working on the same piece of code and for a community to be able to collaborate on finding bugs, on figuring out what changes to make, on figuring out how to improve upon an existing repository and make it better moving forward.


[User] Please transcribe this text

[Assistant] And one final thing worth noting about GitHub is an additional feature known as GitHub Pages.


[User] Please transcribe this text

[Assistant] In, uh, GitHub, is let's create a new repository.


[User] Please transcribe this text

[Assistant] That we'll call, it should generally be your username.github.io is the conventional name for your GitHub pages site. Though it can have other names, you'll just have to manually turn on GitHub pages. And we'll go ahead and create this repository now.


[User] Please transcribe this text

[Assistant] If you create a GitHub repository called yourusername.github.io, it will automatically be supporting GitHub pages. And what that means is that I can take this URL and I can clone it. So I can say git clone followed by this URL. I've cloned an empty repository, but I can go into this repository and add some files to it.


[User] Please transcribe this text

[Assistant] So if you push your changes to a repository called yourusername.github.io, then if you take a look at the settings and scroll down, you'll see that GitHub pages is by default, uh, ready to be published.


[User] Please transcribe this text

[Assistant] And now, if I click on this URL, myusername.github.io, you'll see, deployed to the internet such that anyone can go to this URL and see it, they'll see a big heading that says, this is my GitHub pages website, because this is the way the browser is rendering the HTML that I pushed to my GitHub pages repository.


[User] Please transcribe this text

[Assistant] And the advantage of doing this is that it's very easy now to be able to quickly update my website. All I need to do is if I make a new change, I can commit that change.


[User] Please transcribe this text

[Assistant] Push that change to GitHub, and when GitHub detects that I've made a push to my GitHub pages repository, then it will update my website that anyone in the world can access by going to myusername.github.io.


[User] Please transcribe this text

[Assistant] And this allows you to leverage all of these features of Git, the ability to branch, the ability to work on different features of your webpage at different times, and revert back to different versions of the code as well.


[User] Please transcribe this text

[Assistant] So all in all, Git has given us a number of very powerful tools. It's given us the ability now to be able to very quickly and very easily.


[User] Please transcribe this text

[Assistant] Keep track of any changes we make to code, keep track of when a piece of code is updated and to quickly revert back and look at old versions of that code if need be. And in particular, it's given us the ability to take our code and work together with other people on it, such that we can be working on multiple parts of the same project and someone else working on the same project


[User] Please transcribe this text

[Assistant] You can also be working on multiple parts of the same project on different branches and it's very easy then to sync up our changes in order to work together.


[User] Please transcribe this text

[Assistant] And so Git is a very popular tool used not only in the world of web programming, but especially whenever dealing with any kind of larger project where multiple people might be working on the same thing simultaneously, Git will enable us to more easily develop our web applications over the course of this term.


[User] Please transcribe this text

[Assistant] Next time, we'll take a look at Python, which is one of the first programming languages that we'll use as we continue on our journey towards building more sophisticated web applications. I'll see you then.


[User] Please transcribe this text

[Assistant] Python is a very powerful language that makes it very easy to build applications quickly because there are a lot of features that are built into the language that just make it convenient for quick and productive development. So one of the goals of today is to introduce you to the Python programming language if you haven't seen it before.


[User] Please transcribe this text

[Assistant] And even if you have seen it before, to give you a taste for what the language has to offer, exploring some of the more advanced features and some of the techniques we can use using Python to be able to develop applications all the more effectively.


[User] Please transcribe this text

[Assistant] So we begin with our very first Python program, just a program that says hello world. We're going to be writing it in a text file. And the program just looks like a single line, just like this.


[User] Please transcribe this text

[Assistant] And if you've used other programming languages before, like C or Java or other languages, this probably looks pretty familiar syntax wise. But just to break it down, we have a function called print built into the Python programming language for us.


[User] Please transcribe this text

[Assistant] And like many other programming languages, functions in Python take their arguments inside of parentheses. So inside of these parentheses are the argument or the input to the print function.


[User] Please transcribe this text

[Assistant] Which in this case is just the words hello world followed by an exclamation point.


[User] Please transcribe this text

[Assistant] So here's how we can actually take this program and run it. I'm gonna go into my text editor and create a new file that I'll call hello.py. .py or .py is the conventional extension for Python programs.


[User] Please transcribe this text

[Assistant] So I'll create a file called hello.py, inside of which will just be the Python code that we just saw a moment ago. We'll call the print function. And as an argument or the input to the print function, I'll say, hello, world!


[User] Please transcribe this text

[Assistant] Now, in order to run this program, we're going to use a program in our terminal that also just so happens to be called Python.


[User] Please transcribe this text

[Assistant] Python is what you might call an interpreted language, meaning we're going to run a program called Python, which is an interpreter that is going to read our .py file line by line, executing each line, and interpreting what it means in a way that the computer can actually understand.


[User] Please transcribe this text

[Assistant] So we'll run Python, followed by the name of the program that we'd like to interpret. In this case, hello.py. And when we run this program, we see that the words hello world are printed to the terminal, and that's it. That's the end of the program. And that's the very first program that we've written using the Python programming language. So now already, we've seen a couple of features of Python.


[User] Please transcribe this text

[Assistant] The ability to interpret Python, there's no need to compile it into a binary first in order to run a Python program. We've seen functions and we've also seen strings, just text that we can provide in quotation marks that we can provide as input to other functions or manipulate in other ways. And we'll see some examples of string manipulation a little bit later.


[User] Please transcribe this text

[Assistant] Like many other programming languages, Python also supports variables. And in order to assign a new value to a variable, the syntax looks a little something like this. If I have a line like a equals 28, what that's going to mean is take the value 28 and assign it, store it inside of this variable called a.


[User] Please transcribe this text

[Assistant] Now, unlike other languages like C or Java, which you might be familiar with, where you have to specify the type of every variable you create. I have to say like int a to mean a is an integer.


[User] Please transcribe this text

[Assistant] Python doesn't require you to tell you what the types of each of these variables actually are. So we can just say a equals 28. And Python knows that because this number is an int, that it's going to represent the variable a as an int. And it knows it's able to infer what the types of any of these values happen to be.


[User] Please transcribe this text

[Assistant] So all of the values do indeed have types, you just don't explicitly need to state them. So for example, this here, the number 28, is of type int. It's an integer. A number like 1.5 has a decimal in it. It's a floating point number. So that in Python is what we might call a float type.


[User] Please transcribe this text

[Assistant] Is what we would call the str type, short for string. We also have a type for boolean values, things that can be either true or false. In Python, those are represented using a capital T true and a capital F false. Those are of type bool.


[User] Please transcribe this text

[Assistant] And also, we have a special type in Python called the none type.


[User] Please transcribe this text

[Assistant] Which only has one possible value, this capital N, none. And none is a value we'll use whenever we want to represent the lack of a value somewhere. So if we have a function that is not returning anything, it is really returning none, effectively. And so you might imagine that none can be useful if ever you want a variable to represent the absence of something.


[User] Please transcribe this text

[Assistant] So lots of different possible types, and there are more types than just this, but here's a sampling of the possible variables and types that might exist inside of this link.


[User] Please transcribe this text

[Assistant] So now let's try and actually use a variable in order to do something a little bit more interesting inside of our program. And we'll write a program that's able to take input from the user in order to say hello to them, for example. So I'll create a new file. We'll call it name.py.


[User] Please transcribe this text

[Assistant] And to start, I'd like to prompt the user for input. I'd like to prompt the user to, for example, type in their name.


[User] Please transcribe this text

[Assistant] So how might we do that? Well, just as there is a print function that is built into Python that just prints out whatever the argument happens to be,


[User] Please transcribe this text

[Assistant] Python also has a built-in function called input that prompts the user for input and asks them to just type in some input. So let's provide some input and ask the user to type in their name, for example.


[User] Please transcribe this text

[Assistant] And then, we can save the result, the output of that function, inside of a variable, and in this case I'll save it inside of a variable, that in this case also just happens to be called name.


[User] Please transcribe this text

[Assistant] Now we can run the program. I can run the program by going into my terminal and typing python name.py.


[User] Please transcribe this text

[Assistant] I'll press return, and we'll see the program prompts me to type in my name. I see name colon space, which is that string I provided as the argument to the input function. And this now prompts me to type in my name, so I will. And after that, nothing seems to happen so far.


[User] Please transcribe this text

[Assistant] So now I'd like to do something with that input. I typed in my name, I'd like to say, like, hello, for example, to myself.


[User] Please transcribe this text

[Assistant] So I'll go back into this program, and now what I can do is I can say print


[User] Please transcribe this text

[Assistant] This plus operator in Python does a number of different things. If I have two numbers, it'll add those two numbers together. But with two strings, plus can actually concatenate or combine two strings together. So I can combine hello comma space with whatever the value of name happens to be. So now I'll rerun this program. Python name.py. Type in my name.


[User] Please transcribe this text

[Assistant] And now we see Hello Brian as the output of the program.


[User] Please transcribe this text

[Assistant] So this is one way that you can manipulate strings in Python.


[User] Please transcribe this text

[Assistant] Another way that's quite popular in later versions of Python 3 is a method known as using F strings, short for formatted strings. And in order to use F strings in Python, it's going to be a similar but slightly different syntax. Instead of just having a string in double quotation marks, we'll put the letter F before the string.


[User] Please transcribe this text

[Assistant] And inside of the string, I can now say hello, comma. And then if in a formatted string, if I want to plug in the value of a variable, I can do so by specifying it in curly braces. So what I'll say here is inside of curly braces, name.


[User] Please transcribe this text

[Assistant] And so what's going on here is I am telling this formatted string to substitute right here the value of a variable. So I prompted the user for input to type in their name. We took their name, saved it inside of this variable called name.


[User] Please transcribe this text

[Assistant] And now here in this print statement on line two, I'm printing out a formatted string that is hello comma and then in curly braces here I'm saying plug in the value of the variable name.


[User] Please transcribe this text

[Assistant] And so that is going to have the effect of taking whatever name was provided as input and printing it out. And this is a slightly more efficient way of being able to quickly create strings by plugging in values into those strings. So now I'll see the exact same behavior if I run python name.py and prompted to type in my name.


[User] Please transcribe this text

[Assistant] Like Brian, and then I see the result. Hello, Brian, for example.


[User] Please transcribe this text

[Assistant] And so those are a couple of ways that we can deal with strings, manipulating strings, and combining strings using this technique.


[User] Please transcribe this text

[Assistant] So in addition to variables, Python also supports all of the same other features that are core to many procedural programming languages, such as conditions, for example. So let's take a look at an example now of seeing whether a number is positive or negative or zero, for example. So I'll create a new file that I'll call conditions.py.


[User] Please transcribe this text

[Assistant] And inside of conditions.py, I'll first prompt the user to type in some input. I'll say input number to mean, you know, type in a number.


[User] Please transcribe this text

[Assistant] And we'll save that input inside of a variable that I'm just gonna call n.


[User] Please transcribe this text

[Assistant] And so what's going on here is I have a Python condition. And the way a Python condition works is it begins with this keyword, a keyword like if.


[User] Please transcribe this text

[Assistant] Followed by a Boolean expression, some expression that's going to evaluate to true or false, or something kind of like true or false. We can be a little bit loose about that, as we may see later. And then a colon means, all right, here is the beginning of the body of the if state.


[User] Please transcribe this text

[Assistant] And in Python, the way we know that we're inside the body of an if statement or inside the body of any other block of code is via indentation.


[User] Please transcribe this text

[Assistant] The indentation isn't strictly required by the computer to be able to parse and understand what's inside the program. In Python, it's different. The indentation is required because the indentation is how the program knows what code is inside of the if statement and what code is outside of the if statement.


[User] Please transcribe this text

[Assistant] So we have if n is greater than zero, colon, and then everything indented underneath the if is all of the body of the if statement. It is the lines of code that will execute if this condition, this Boolean expression, n greater than zero, happens to be true. So if n is greater than zero, we'll print out n is positive.


[User] Please transcribe this text

[Assistant] And then, we can add an additional condition. I can say something like, well I could say something like else, print n is not positive.


[User] Please transcribe this text

[Assistant] But I can be a little bit more specific than that. Here is sort of two branches, one if n is greater than zero, and one else case to handle all of the other possible scenarios. But really what I'd like to do is perform a second check. In other languages this might be called an else if, like if this condition is not true, but this other condition is true.


[User] Please transcribe this text

[Assistant] Python abbreviates this to just LF, E-L-I-F, just short for else if.


[User] Please transcribe this text

[Assistant] So the idea here now is that if n is greater than zero, we perform some task. L if, in other words, if it's not greater than zero, then we check to see if it is less than zero, in which case we print out that n is negative.


[User] Please transcribe this text

[Assistant] Else, if neither of those two conditions are true, it's not positive and it's not negative, the only remaining possibility is that n is zero, so we can print out that n is zero.


[User] Please transcribe this text

[Assistant] So we might like for this program to work, but watch what happens if I now try and run conditions.py, even though logically in our heads and looking at it now, it probably seems pretty logical. If I run python conditions.py,


[User] Please transcribe this text

[Assistant] And type in a number. I'll type in the number 5, for example, to see what happens.


[User] Please transcribe this text

[Assistant] Alright, something weird just happened, and this is our very first Python exception.


[User] Please transcribe this text

[Assistant] An error that happens because something didn't quite go right inside of our Python program. And over time you'll begin to learn how to parse this exception and understand what it means and where to begin to debug. But learning how to read these exceptions and figure out how to deal with them is definitely a very valuable skill on your way to becoming a Python developer. And so let's see if we can figure out what this exception is saying.


[User] Please transcribe this text

[Assistant] Oftentimes I start by looking at the bottom. I see that there is a type error.


[User] Please transcribe this text

[Assistant] That is the type of the exception that has happened. There are a lot of exceptions that can go wrong in Python, things that we can do that cause errors. In this case, it's a type error, which generally means that there's some mismatch of types that Python expected something to be of one type, but it turned out to be a different type. So let's try and understand what this might be.


[User] Please transcribe this text

[Assistant] Which says greater than sign, not supported between instances of str, short for string, and int.


[User] Please transcribe this text

[Assistant] So what does that mean? Well, I guess it means that the greater than symbol that checks if one thing is greater than another doesn't work if you're comparing a string to an integer.


[User] Please transcribe this text

[Assistant] And that's probably pretty reasonable. It doesn't really make sense to say a string is greater than or less than an integer. When we're talking about greater than or less than, usually we're talking about numbers. So they should both be integers, for example.


[User] Please transcribe this text

[Assistant] Here is the line that triggered the exception, if n is greater than zero.


[User] Please transcribe this text

[Assistant] So what's the exception here? Well, 0 is obviously an integer, because that just is an integer. And so if greater than thinks that it's comparing a string with an integer, then n somehow must be a string. Even though I typed in the number 5, it must still think n is a string. So why might that be? Let's take a look at the code again and see if we can figure out what's going on.


[User] Please transcribe this text

[Assistant] Well, it seems that this input function doesn't care what you type in, it's always going to give you back a string. N somehow is ending up as a string.


[User] Please transcribe this text

[Assistant] Which is pretty reasonable because the input function has no idea whether I typed in a number or whether I typed in a letter or I typed in other characters altogether. So input doesn't know to give back its data in the form of an int or in the form of a float or in any other form. So by default, it's just going to return a string. What characters did the user type in as their input?


[User] Please transcribe this text

[Assistant] So what I'd like to do now in order to make this program work the way I want it to is take this and convert it into an integer or cast it into an integer, so to speak.


[User] Please transcribe this text

[Assistant] And the way that I can do that is by using a function in Python called int that takes anything and turns it into an integer. So here I can say int.


[User] Please transcribe this text

[Assistant] And then as the argument to the int function, the input to the int function, I'm just going to include this whole expression, input number.


[User] Please transcribe this text

[Assistant] So I'm going to ask the user to input a number. They type in some text. The input function gives me back a string and that string is going to serve as the input to the int function.


[User] Please transcribe this text

[Assistant] Which then gets saved inside of this variable called n.


[User] Please transcribe this text

[Assistant] So now that we know that n is indeed an integer, let's try and run this program again.


[User] Please transcribe this text

[Assistant] Doesn't seem to have worked, and it didn't work because I didn't save the file. So I'll go ahead and save the file, try it again.


[User] Please transcribe this text

[Assistant] And otherwise, if it isn't either positive or negative, then we know that n is 0.


[User] Please transcribe this text

[Assistant] And so here was our first exposure to conditions in Python, the ability to have multiple different branches and do different code depending on some expression that we're going to evaluate to either be a true expression or a false expression.


[User] Please transcribe this text

[Assistant] Alright, so let's take a look at some of the other features that are going to be present inside the Python language. And one of the most powerful features of Python are its various different types of sequences, data types that store values in some sort of sequence or some collection of values altogether. So I'll go ahead and create a new file that we'll call sequences.py.


[User] Please transcribe this text

[Assistant] And there are a number of different types of sequences that all obey similar properties. Uhm, but one of the types of sequences is a type we've already seen, which is just a string, for example.


[User] Please transcribe this text

[Assistant] So if I have a name, and the name is something like Harry for instance, and this sequence allows me to access individual elements inside of the sequence.


[User] Please transcribe this text

[Assistant] And in order to do so, it's much like an array in other languages if you've experienced them before, but I can print out name square bracket zero.


[User] Please transcribe this text

[Assistant] This square bracket notation takes a sequence, some ordered sequence of elements, and gets me access to one particular element inside of that sequence. And so if I have a string like name, and I say name square bracket zero, the effect of that is going to be take this long sequence and get me the zeroth


[User] Please transcribe this text

[Assistant] In many programming languages and in programming more generally, we often start counting things at zero. So the very first item in the sequence is item zero. The second item is item one. So it's easy to get slight off by one errors there, but just know that item zero of the name should be the first character in the name.


[User] Please transcribe this text

[Assistant] And I can see that for sure. If I run Python, I'll save this file.


[User] Please transcribe this text

[Assistant] Run python sequences.py, and what I get is just the first character of Harry's name, which in this case is the letter H.


[User] Please transcribe this text

[Assistant] If I instead ask to print out character 1, which will be the second character in the name, if I rerun the program, now I get the letter A.


[User] Please transcribe this text

[Assistant] And this type of indexing works for many different types of sequences, not just a string, which so happens to be a sequence of characters, but other types as well. Python, for example, has a type for lists of data. So if I have a sequence of any type of data that I want to store, I can store that information inside of a list in Python.


[User] Please transcribe this text

[Assistant] So maybe instead of storing one name, I have multiple names that I want to store. So I want to store names like Harry and Ron and Hermione, for example.


[User] Please transcribe this text

[Assistant] So now I have three names all stored in a sequence inside of a Python list.


[User] Please transcribe this text

[Assistant] And I can, you know, I can print out all of the names, for example, just to print out all of the names to see what the value of the variable names is equal to. And we'll see that when I do that, I get a printout of the contents of that list, Harry, Ron, Hermione, in that particular order. But you could also, much as you could index into a string,


[User] Please transcribe this text

[Assistant] Index into a list to say get me just the very first item inside of this names list, which in this case when I run the program is going to just be


[User] Please transcribe this text

[Assistant] So there are a number of different sequence types you can use in order to represent data. Another one just so happens to be called a tuple.


[User] Please transcribe this text

[Assistant] And a tuple is often used if you have a couple of values that aren't going to change, but you need to store a pair of values, like two values together or three values together or something like it. You might imagine that if you're writing a program to deal with, uh, graphing in two dimensions, for example.


[User] Please transcribe this text

[Assistant] You might want to represent a point as an x value and a y value. And you could create two variables for it. I could say, you know, let me just say a coordinate x is going to be equal to 10.0 and coordinate y is equal to 20.0.


[User] Please transcribe this text

[Assistant] But now I'm creating two variables for what's really one.


[User] Please transcribe this text

[Assistant] Unit that just so happens to have two parts. And so to represent this, we can use a tuple in Python and just say something like coordinate


[User] Please transcribe this text

[Assistant] So whereas in lists we use square brackets to denote where the list begins and where the list ends, in a tuple we just use parentheses to say we're grouping a number of values together, we're grouping one value 10.0 with a second value 20.0. And now we can pass around these two values as a single unit


[User] Please transcribe this text

[Assistant] Just by referencing them using a single name, which in this case is...


[User] Please transcribe this text

[Assistant] So there are a number of different types of these various different sequences, uhm, and some of those sequences we'll take a look at are these data structures here.


[User] Please transcribe this text

[Assistant] So list, for example, is a sequence of mutable values, which we took a look at, and mutable just meaning we can change the elements in the list. If I have a list, I can add something to the end of the list. I can delete something from the list. I can modify the values inside the list.


[User] Please transcribe this text

[Assistant] A tuple on the other hand is a sequence of immutable values. Those values can't change. You can't add another element to the existing tuple. You'd have to create a new tuple in order to do so.


[User] Please transcribe this text

[Assistant] And there are other data structures that exist as well. A couple that we'll take a look at in a moment include sets, which are a collection of unique values. So if you're familiar with sets from the world of mathematics, it's a very similar idea that whereas a list in a tuple keeps things in a particular order,


[User] Please transcribe this text

[Assistant] A set does not keep things in any particular order. It's just a collection.


[User] Please transcribe this text

[Assistant] And in particular, all of the values need to be unique. In a list or in a tuple, you might have the same value appearing multiple times. In a set, every value appears exactly once.


[User] Please transcribe this text

[Assistant] And there's some advantages to set some ways that you can make your programs more efficient by using sets. If you know that you just need a collection, if you don't care about the order, if something is only going to show up exactly once at most, then you can use a set.


[User] Please transcribe this text

[Assistant] Potentially make your programs a little more efficient and a little more elegantly designed.


[User] Please transcribe this text

[Assistant] And finally, one other data structure that's quite powerful and that's going to come up a number of times during this course is a dictionary in Python shortened to just a dict, which is the collection of what we're going to call key value pair.


[User] Please transcribe this text

[Assistant] And the way I like to think of this is with an actual physical dictionary that you might find in a library that maps words to their definitions. In a physical dictionary, you open up the dictionary and you look up a word and you get the definition.


[User] Please transcribe this text

[Assistant] An addict in Python is going to be very similar. It's going to be a data structure where I can look something up by one keyword or one value and get some other value as a result. We call the thing that I'm looking up the key and we call what I get when I do the looking up


[User] Please transcribe this text

[Assistant] The value. So we keep pairs of keys and values. In the case of an actual dictionary in the real world, the key is the word that we want to look up and the value is its definition. But we can use this more generally in Python any time we want to map something to some other value such that we can very easily look up that value inside of this data structure. So we'll see examples of dictionaries as well.


[User] Please transcribe this text

[Assistant] So let's now explore the first of these data structures, these lists, to explore what we can do by taking advantage of the features that are given to us by a Python list, for example.


[User] Please transcribe this text

[Assistant] And as I start to write multiple lines of code, especially as my Python programs start getting longer, it can be a good idea to document what it is that I'm doing. So I can say, let me add a comment to this particular line of code, just so I know what it is that I've done in this line of code. And in Python, there are a couple of different ways to create a comment, but the simplest way


[User] Please transcribe this text

[Assistant] It's just to use the pound sign or the hashtag. As soon as you include that, everything after that for the remainder of the line is a comment. The interpreter is going to ignore that comment so you can say whatever you want. It's more for you, the programmer.


[User] Please transcribe this text

[Assistant] And for someone who's reading your program, to be able to look at the program, understand what it's saying, and figure out what they need to do about it. So I can just say, define a list of names, for example. Just to make it clear to me what it is that I have done inside of this line of code. So I can print out that list of names, as we've done before.


[User] Please transcribe this text

[Assistant] And we'll see that when I print out that list of names, what I get is, oh, let me run.


[User] Please transcribe this text

[Assistant] List.py. What I get is this list, Harry, Ron, Hermione, and Ginny. Uhm, but I could also print out, as we've seen before, just the first of those names. Say, you know, print out just name square bracket zero, in which case I'm going to get just Harry, for example.


[User] Please transcribe this text

[Assistant] But now, recall that a list is mutable. I can modify the elements that happen to exist inside of this list. So I could say names.append, a new name, something like Draco, for example.


[User] Please transcribe this text

[Assistant] And so lists have a number of built-in methods or functions, which are functions that I can run on an existing list to access particular elements of the list or to modify the list in particular ways. And in the case of a list, the append method is a method or function that I can run that just adds a value to the end of an existing list. So I've added Draco to the list.


[User] Please transcribe this text

[Assistant] And there are a number of other methods that I can use on lists. One of which is, for example, sorting a list. No need to write your own sorting algorithm in order to sort a sequence of objects. In Python,


[User] Please transcribe this text

[Assistant] There is a built-in sort method that works on lists where I can just say names.sort that will automatically sort everything in the list. And now if I print out all of those names, go to print them out and get rid of this old print statement.


[User] Please transcribe this text

[Assistant] Now we see that we get five names that are printed out, because I had four elements originally in this list, but then I added a fifth one. And notice now that they are actually in alphabetical order, starting with Draco, ending with Ron, because I was able to sort the list by modifying the order in which those elements actually show up.


[User] Please transcribe this text

[Assistant] And so lists can definitely be quite powerful. Anytime you need to store elements in order, a list is definitely a useful tool that Python gives to you.


[User] Please transcribe this text

[Assistant] If you don't care about the order of the elements though, and if you know that all the elements are going to be unique, then you can use a set, which is another Python data structure that works in similar ways, though the syntax is slightly different.


[User] Please transcribe this text

[Assistant] So let's do an example with those. I'll create a new file, call it sets.py. And let me first create an empty set.


[User] Please transcribe this text

[Assistant] And we can do that by just saying s equals, s is going to be the variable that will store my set. And I'll say set and then parentheses. That will just create an empty set that just so happens to have nothing inside of it.


[User] Please transcribe this text

[Assistant] Now we'll add some elements to the set. So I can say s.add. Let's add the number one to the set.


[User] Please transcribe this text

[Assistant] Let's add the number two, let's add the number three, and let's add the number four.


[User] Please transcribe this text

[Assistant] We see that inside the set are four values, one, two, three, and four. They happen to be in order, but sets are not naturally ordered, they're not going to always keep track of what the order is going to be. But I could add, for example, if I add three again to the set,


[User] Please transcribe this text

[Assistant] When I print out the contents of the set, it still just contains the elements 1, 2, 3, 4. No element ever appears twice in the set, following with the mathematical definition of a set, where no element ever appears more than once inside of a set.


[User] Please transcribe this text

[Assistant] You can also remove elements from sets as well. So if I wanted to remove the number 2 from the set, for example, I could say s.remove2 and then print out s to say print out whatever happens to be inside of that set now.


[User] Please transcribe this text

[Assistant] So sets allow you to add to them, remove from them, and also all sequences, whether they be strings or lists or sets, allow you to get how many elements are in the set by taking advantage of a function built into Python called len.


[User] Please transcribe this text

[Assistant] So len will give you the length of a sequence, so the number of items inside of a list, or the number of characters inside of a string, or the number of elements inside of a set.


[User] Please transcribe this text

[Assistant] And so, if I wanted to print out how many elements are in the set, I might do something like this. In a formatted string, say the set has some number of elements.


[User] Please transcribe this text

[Assistant] And how do I know how many elements? Well again, inside of these curly braces I can include any expression in Python that I would like to substitute into this string.


[User] Please transcribe this text

[Assistant] So what I've done here is I've said with len of s, I would like to calculate the length of the set s. In other words, how many elements are actually inside of that set. And then using this curly brace notation, I'm saying take that number and plug it into this string. So we can see the set has some number of elements, for example. So now if I run this program.


[User] Please transcribe this text

[Assistant] PythonSets.py, I see that I get these three elements that happen to be inside of the set right now, which is one and then three and then four, and then it tells me that the set has three elements inside of it, which is the number of elements that are in the set right now.


[User] Please transcribe this text

[Assistant] So now we've seen a number of different language features inside of Python. We've seen variables, we've seen conditions so that we can conditionally do things if something is true, if something else is true, and we've seen some of the data structures that are core to the way Python works. Lists and sets and tuples and other data structures can be helpful too.


[User] Please transcribe this text

[Assistant] And now let's take a look at another feature of the Python programming language common to many programming languages, the idea of looping. If I want to be able to do something multiple times.


[User] Please transcribe this text

[Assistant] I'll go ahead and create a new file called loops.py. And let's just create a simple loop. The simplest loop we could create in Python is just one that's going to count a bunch of numbers. So in order to do that, what I could say is something like this. For i in 1, 2, 3, 4, 5.


[User] Please transcribe this text

[Assistant] So here's the basic syntax for a Python loop. And here's what seems to be going on.


[User] Please transcribe this text

[Assistant] Over here on the very first line, I have a Python list as denoted by those square brackets that contains six numbers 012345.


[User] Please transcribe this text

[Assistant] And the way Python interprets this is to say, go through this list one element at a time, and for each element call that element i. We could have called it anything, but in this case i is just a conventional choice for a number that keeps incrementing. And we're going to print out now the value of i for each iteration of this loop. So we can try this out now and run


[User] Please transcribe this text

[Assistant] In practice, though, if we wanted to count all the way up to five or print six numbers, for example, this is fine for now. But if we wanted to print like a hundred numbers or a thousand numbers, this is going to start to get tedious. So Python has a built-in function called range, where I can say for i in range six,


[User] Please transcribe this text

[Assistant] To achieve exactly the same thing. Range 6 means get me a range of 6 numbers. So if we start at 0, it's going to go from 0 all the way up to 5. And then we can print out each one of the elements inside of that sequence. So if I rerun python loops.py, we get 0, 1, 2, 3, 4, 5.


[User] Please transcribe this text

[Assistant] So loops enable us to loop over any type of sequence. So if the sequence is a list, I can say something like, if I have a list of names, like Harry and Ron and Hermione.


[User] Please transcribe this text

[Assistant] And this is my list of names. I can have a loop that says that for each name in my list of names, let's print out that name, for example.


[User] Please transcribe this text

[Assistant] So we have a list. The list is called names. We're looping over it one element at a time and printing it out.


[User] Please transcribe this text

[Assistant] Now if I run the program, I see three names printed one on each line, and you can do this for other sequences as well.


[User] Please transcribe this text

[Assistant] Maybe I have just a single name that is called Harry.


[User] Please transcribe this text

[Assistant] And now I could have a line that says, you know, for every character in that name, print the character.


[User] Please transcribe this text

[Assistant] If the name is the sequence, the sequence of individual characters, because it's a string, then when I loop over that string, I'll be looping over each individual character in that string, so I can run the program and see one on each line, each of the letters that just so happens to be inside of Harry's name.


[User] Please transcribe this text

[Assistant] So now we've seen conditions, we've seen loops, and we've seen a number of different data structures. We've seen lists and sets as well as tuples.


[User] Please transcribe this text

[Assistant] The last important data structure that we're going to be taking a look at are Python dictionaries, which as you'll recall are some mapping of keys to values. If I want to be able to look something up, I can use a Python dictionary just as a data structure to be able to store these sorts of values.


[User] Please transcribe this text

[Assistant] So I'll create a new file called dictionaries.py.


[User] Please transcribe this text

[Assistant] And maybe I want to create a dictionary that is going to keep track of, say, what house each of the students at Hogwarts happen to be in. So I might have a dictionary called houses.


[User] Please transcribe this text

[Assistant] And the way we specify a dictionary is by specifying a key colon of value when we're defining a dictionary for the first time. So I might say Harry.


[User] Please transcribe this text

[Assistant] And so what this line of code is doing is it is creating a new dictionary. This dictionary is called houses. And inside this dictionary I have two keys, two things that I can look up. I can look up Harry or I can look up Draco.


[User] Please transcribe this text

[Assistant] And when I look up those keys, I get the value that follows their colon. So after Harry, if I look up Harry, I get Gryffindor. If I look up Draco, I get Slytherin, for example.


[User] Please transcribe this text

[Assistant] So now, if I wanted to print out what house Harry is in,


[User] Please transcribe this text

[Assistant] Take the house's dictionary and the square bracket notation is how I look something up inside of a dictionary. It's similar to how we use square brackets to look up a specific element inside of a list to say like get me element zero or element one.


[User] Please transcribe this text

[Assistant] In this case, we're using a Python dictionary to say, take the house's dictionary and look up Harry's value, which hopefully should be Gryffindor. And we'll see that if we look up, run python dictionaries.py, we do get Gryffindor as the value of Harry's house.


[User] Please transcribe this text

[Assistant] We can add things to this dictionary as well using the same syntax in the same way that I use square brackets to access the value inside of a dictionary. If I want to change the value in a dictionary or add something new to it, I could say houses and Hermione and say that Hermione is also in Gryffindor, for example.


[User] Please transcribe this text

[Assistant] And so this line of code here says, take the house's dictionary.


[User] Please transcribe this text

[Assistant] And look up Hermione in the house's dictionary. And when you do, that should be set equal to this value here, Gryffindor. So we took that value and we are going to assign it to Hermione inside of the dictionary, such that now if we wanted to, we could print out Hermione's house as well.


[User] Please transcribe this text

[Assistant] Run the program and see that Hermione is also in Gryffindor.


[User] Please transcribe this text

[Assistant] So anytime we want to be able to map some value to some other value, whether we're mapping people to what house they happen to be in or we're mapping users to some information about those users inside of our web application, dictionaries are going to be very, very powerful tools for us to be able to do that.


[User] Please transcribe this text

[Assistant] The next Python language feature we'll take a look at are functions in Python that are going to be some way for us to write our own functions that take an input and produce some output.


[User] Please transcribe this text

[Assistant] We've already seen a number of different functions that already exist in Python. We've seen the input function that takes an input from the user. We've seen the print function that takes some text or some other information and prints it to the screen. But if we want to define our own functions, we can do so as well.


[User] Please transcribe this text

[Assistant] So here, I'll go ahead and write a new program called functions.py.


[User] Please transcribe this text

[Assistant] And let's write a function that takes a number and squares it. So the square of 10 is 10 times 10 or 100. I would like a function that very easily takes a number and returns its square.


[User] Please transcribe this text

[Assistant] The way I define a function in Python is using the def keyword, def short for define. And here I can say let me define a function called square.


[User] Please transcribe this text

[Assistant] And then in parentheses, what inputs it takes. In this case, square just takes a single input that I'm going to call x. But if there were multiple inputs, I could separate them with commas, like x, y, z, for a function that took three inputs, for example. But in this case, there's just a single input, x.


[User] Please transcribe this text

[Assistant] And the square function could have any logic in it indented underneath the square function, but ultimately this function is fairly simple. All it's going to do is return x times x, x multiplied by itself.


[User] Please transcribe this text

[Assistant] So let's try and parse out what's going on here. Line 4 says for i in range 10, do some loop 10 times, looping from 0 all the way up to 9. And for each time we loop, we're going to print something out. We're going to print out the square of, plug in the value of i here, is, plug in the value of calling our square function using i as input.


[User] Please transcribe this text

[Assistant] So that is going to have the result of running this loop 10 times and printing out this line 10 different times, each with a different value of i.


[User] Please transcribe this text

[Assistant] So I can run pythonfunctions.py, and here's what I see. The square of 0 is 0, square of 1 is 1, 2 is 4, so on and so forth, all the way up to the square of 9 is 81. So we've now written a function and been able to use it.


[User] Please transcribe this text

[Assistant] But ideally when we write functions, we'd like to not just be able to use them in the same file, but for others to be able to use them as well. And so how can we do that?


[User] Please transcribe this text

[Assistant] Well, in order to do that, you can import functions from other Python modules or files, so to speak. So let me create a new file called squares.py, for example.


[User] Please transcribe this text

[Assistant] So then instead of running this loop here, let's instead run this loop in squares.py. Again, separating out different parts of my code. I have one file that defines the square function inside of functions.py, and then another file called squares.py where I'm actually calling the square function. Now if I try to run python squares.py,


[User] Please transcribe this text

[Assistant] You'll notice I'll run into an error. Here's another error you'll see quite frequently. It's a name error, another type of exception, which here says the name square is not defined. Meaning I'm trying to use a variable or a function name or something else that doesn't actually have a definition. I've never said what square is.


[User] Please transcribe this text

[Assistant] And that's because by default Python files don't know about each other. If I want to use a function that was defined inside of another file, I need to import it from that file.


[User] Please transcribe this text

[Assistant] Functions was the name of this file, functions.py, and I'm saying from that Python module, I would like to import the square function as a function that I would like to use. Now I can run Python.


[User] Please transcribe this text

[Assistant] Squares.py, and we get the output that we expect. No more exception.


[User] Please transcribe this text

[Assistant] I've now been able to import something from another module and access it this way.


[User] Please transcribe this text

[Assistant] So this is one way to import, to literally say from functions, import a square function, import a particular name that is defined inside of functions.py. Another way I could have done this is just to say import functions. Just import that whole module.


[User] Please transcribe this text

[Assistant] But then I would need to say instead of just square, I would need to say functions dot square to mean go inside the functions module and get the square function and run that function. And this would operate in exactly the same way.


[User] Please transcribe this text

[Assistant] So a couple of different options. I either import the entire module, in which case I use this dot notation to say access a particular part of that module, or I say from functions import square to just import the name square into this file entirely so that I can just use the word square whenever I want to. And this works not just


[User] Please transcribe this text

[Assistant] For modules that we have written, but also Python comes with a number of built in modules. If you want to write programs that interact with CSV files, which are a spreadsheet file format.


[User] Please transcribe this text

[Assistant] I can import Python's built-in CSV module to get access to a whole bunch of CSV related features. There are a whole bunch of math related features you can get by importing the math module.


[User] Please transcribe this text

[Assistant] So on and so forth. And there are additional Python modules and packages that you can install that other people have written, and then you just import them when the time comes. And next time, as we take a look at Django, this is one of the techniques that we're going to be looking at, is using functions that have been written by people that are not ourselves.


[User] Please transcribe this text

[Assistant] So that now is modules and how we can use modules to be able to import functions in order to allow for certain behavior. And this is one way that we can program using the Python programming language. But another key technique that Python supports that are supported by a number of other programming languages as well.


[User] Please transcribe this text

[Assistant] Is an idea of object oriented program. A special type of programming or programming paradigm, so to speak, which is a way of thinking about the way that we write program and an object oriented programming. We think about the world in terms of objects.


[User] Please transcribe this text

[Assistant] Where objects might store information, store some data inside of them, and also support the ability to perform types of operations, some sort of actions or methods or functions as we might call them, that can operate on those objects.


[User] Please transcribe this text

[Assistant] So now we're gonna take a look at some of the object-oriented capacities that the Python programming language is going to give us the ability to have.


[User] Please transcribe this text

[Assistant] So Python comes with a number of built-in types. It has types for lists, it has types for sets, and so on and so forth. Let's imagine, though, that we want to create a new type in Python. Some way of


[User] Please transcribe this text

[Assistant] Representing other types of data, for example, uh, two dimensional points, things we talked about before, something that has an x value and a y value.


[User] Please transcribe this text

[Assistant] Now, as we've already discussed, you could do this using a tuple, just using one number, comma, another number. But we could create an entire class of objects to be able to represent this data structure as well. And so that's what we'll take a look at now, is how to create a class in Python. So I'll create a new file called classes.py.


[User] Please transcribe this text

[Assistant] And all a class is, is you can think of a class as a template for a type of object. We are going to define a new class called point, and then after we've defined what a point is, we will be able to create other points. We'll be able to create points that store x and y values, for example. And so what do we need in order to create a class?


[User] Please transcribe this text

[Assistant] Well, we need some way to say that when I create a point, what should happen?


[User] Please transcribe this text

[Assistant] And in Python this is defined using what's called a magic method called underscore underscore init.


[User] Please transcribe this text

[Assistant] And underscore underscore init is a method or function that is going to automatically be called every time that I try to create a new point. And this function takes a couple of arguments.


[User] Please transcribe this text

[Assistant] All functions that operate on objects themselves, otherwise known as methods, are going to take the first argument called self. And this argument self


[User] Please transcribe this text

[Assistant] represents the object in question and this is going to be important because we don't just want a single variable called x to store the points x coordinate or a single variable called y to store the y coordinate because two different points might have different x and different y values and we want to be able to store those separately.


[User] Please transcribe this text

[Assistant] And we're going to store them inside of the object itself. So this variable self references the object that we are currently dealing with. And it might change depending on which point we happen to be interacting with at any given time.


[User] Please transcribe this text

[Assistant] What other inputs does a point need? Well, a point also needs an x value and a y value. So when we create a point, we're going to provide to that point an x value and a y value.


[User] Please transcribe this text

[Assistant] Now what do we need to do in order to store all this data inside of the point? Well, recall that self is representing the point itself.


[User] Please transcribe this text

[Assistant] And so if we want to store data inside of that point, allow the point to store its own x and y values, then we need to store that data inside of the self, so to speak.


[User] Please transcribe this text

[Assistant] And these values x and y, they could be called anything. They could just be called like input 1 and input 2, for example. And then you would just reflect them here. The important thing is that these two input values are being stored inside of the point itself in properties that we're going to call x and y.


[User] Please transcribe this text

[Assistant] Alright, so that was a little bit abstract, but now let's see how we could actually use this. If I want to create a new point called p, I can say p equals point, and then


[User] Please transcribe this text

[Assistant] The self argument is going to be provided automatically, I don't need to worry about that. But I do need to provide input 1 and input 2, the x value and the y value.


[User] Please transcribe this text

[Assistant] So I'll go ahead and provide an x value of 2 and a y value of 8, for example. So now I've created this point.


[User] Please transcribe this text

[Assistant] And now that I have a point, I can print out information about the point. I can print out the x value of the point and I can print out the y value of the point. Again, I'm using this dot notation to say go into the point and access data that is stored inside of that point. Access its x value and access its y value.


[User] Please transcribe this text

[Assistant] So what we have here is a function called init that creates a point by storing the two inputs inside of the object, inside of a property called x and a property called y, such that later I can create a point which calls this init function implicitly.


[User] Please transcribe this text

[Assistant] And after we've created the point, I can access the data inside of it. I can say print out whatever p dot x is equal to, print out whatever p dot y is equal to as well.


[User] Please transcribe this text

[Assistant] So that was a fairly simple example of creating a class, just creating a class for representing a point, an x and a y value.


[User] Please transcribe this text

[Assistant] Let's look at a more interesting example. Let's imagine that we're trying to write a program for an airline where the airline needs to keep track of booking passengers on a flight and making sure that no flight gets overbooked. We don't want more passengers on the flight than there is capacity on that flight.


[User] Please transcribe this text

[Assistant] So let's define a new class that we're gonna call flight. And this time the init method is just going to take a single argument other than the self, which is the capacity. Every flight needs some sort of capacity to know how many people can fit on the plane.


[User] Please transcribe this text

[Assistant] And so I'll store that inside of a value called self.capacity equals capacity.


[User] Please transcribe this text

[Assistant] And what other information do we need to store about a flight? Well, a flight has a capacity and it also has all of the passengers on the flight. And so we could represent this in a number of ways, but we know that lists can be used in order to store a sequence of values. So we'll go ahead and just create a list that will store in self dot passengers.


[User] Please transcribe this text

[Assistant] That is going to be equal to the empty list. So we start out with an empty list of passengers.


[User] Please transcribe this text

[Assistant] So now, if I want to create a flight, I can say flight equals, and then capital F flight, that's the name of the class,


[User] Please transcribe this text

[Assistant] And then provide a capacity. I can say capacity of three to mean three people can go on this flight, but no more than three. That is the capacity because that is the argument that's specified inside of this init function. And when I do so, I'm automatically going to get this empty list of passengers.


[User] Please transcribe this text

[Assistant] So now, let's think about what methods or what functions we might care about performing when it comes to a flight.


[User] Please transcribe this text

[Assistant] So one reasonable function to add would be a function that says, all right, let's add a passenger to the flight if I want someone new to go on this flight. So how might I go about doing that? Well, let's define a new method, also known as a function, to this flight class called add


[User] Please transcribe this text

[Assistant] Passenger. This method can be called whatever we want. Because this is a method that's going to work on an individual object, we need some way of referencing that object itself, so we'll use the keyword self again.


[User] Please transcribe this text

[Assistant] And when we add a passenger, we need to add a passenger by their name. So I need to specify their name as well. Such that now here,


[User] Please transcribe this text

[Assistant] How do I get access to the passengers list? Well, I have access to the self, the object itself, and I store the passengers inside of self in self dot passenger, an attribute of this object.


[User] Please transcribe this text

[Assistant] And self.passengers is a list that initially starts out as an empty list. But if I want to add something to the end of a list, we've already seen that in order to do that, I can say self.passengers.append name.


[User] Please transcribe this text

[Assistant] So that adds someone new to the end of this passenger's list.


[User] Please transcribe this text

[Assistant] Now, what could potentially go wrong here? Well, every time we call this addPassenger function, what's going to happen is we are going to append to the end of this passengers list this name.


[User] Please transcribe this text

[Assistant] But we haven't taken into consideration the capacity of the flight. Ideally, our add passengers function shouldn't let someone be added to a flight if the flight is already at capacity.


[User] Please transcribe this text

[Assistant] So there are a number of things we could do here. We could just check it inside of this function. But just for good measure, let's create a new function. Let's add a new function called open seats.


[User] Please transcribe this text

[Assistant] That is going to return the number of open seats that are on the plane.


[User] Please transcribe this text

[Assistant] Other than self, there are no other inputs that we need to calculate how many open seats there are. The only thing we need to know in order to calculate open seats is we need to know the capacity.


[User] Please transcribe this text

[Assistant] Minus however many passengers there are. Remember self.passengers is our list of all the passengers. And anytime we have a sequence to get the length of that sequence, I can say len, or length of that sequence, to say get me the number of passengers that there are.


[User] Please transcribe this text

[Assistant] So now we have this function called open seats, which will return capacity minus the number of passengers and tell us how many open seats there are.


[User] Please transcribe this text

[Assistant] So this is equivalent to me saying in this case, like, if self.openseats == 0, meaning there are no open seats, a more pythonic way, so to speak, of expressing this idea is just saying, if not self.openseats. In other words, if there aren't any more open seats,


[User] Please transcribe this text

[Assistant] Then what should we do? We should return. And maybe you might imagine this add passenger function returns true if it was able to successfully add a passenger and false otherwise.


[User] Please transcribe this text

[Assistant] So in this case, I can return false to say, you know what, there aren't enough open seats. Let me return false from this function to indicate that there was some sort of error. But otherwise, if there are open seats, we can add the passenger and return true.


[User] Please transcribe this text

[Assistant] To mean that everything was okay. We were able to add the passenger successfully.


[User] Please transcribe this text

[Assistant] So now we have these three functions in it that creates a new flight, add passenger that adds a new passenger to that flight, and open seats, which tells us how many open seats there are. And now let's use those functions to actually add some passengers to this flight. Let me get a list of people. We'll say Harry, Ron, Hermione, and Ginny. And now let me loop over all of those people. For every person in that list of people, let's try to


[User] Please transcribe this text

[Assistant] And we can save the result in a variable called success, for example.


[User] Please transcribe this text

[Assistant] So what's going on here? We have a list of people, four people, and for each of those people we're going to try and add the passenger to the flight. Calling flight.addPassenger, calling this method, passing as input the person's name, and save the result, true or false, in this variable called success.


[User] Please transcribe this text

[Assistant] If success is true, we print out we've added them successfully, otherwise we print out there are no available seats for that person. So now we can try running this program. I'll run python classes.py.


[User] Please transcribe this text

[Assistant] And now we see we've added Harry, Ron, and Hermione to the flight successfully, but the flight had a capacity of three, which means there are no available seats for Ginny, which we get as the error message on the fourth line.


[User] Please transcribe this text

[Assistant] And if you're really trying to optimize, you might notice that you don't really need this variable. I could just take this entire expression, flight.addPassengerPerson, and put it in the condition itself.


[User] Please transcribe this text

[Assistant] I can say, try and add a passenger. Add passenger will return true or false. And if it returns true, that means it was a success. And then I can print out that we've added the person to the flight successfully.


[User] Please transcribe this text

[Assistant] So that is a brief look at object oriented programming. This technique within Python and other programming languages to represent objects like this particular flight and then to manipulate those objects using methods like the add passenger method that takes a flight and adds people to it at least as long as there is available capacity on that flight.


[User] Please transcribe this text

[Assistant] It's one of the many powerful features of Python that we'll be definitely taking a look at later in the term and using as we go about building these web applications.


[User] Please transcribe this text

[Assistant] Now there are a couple of final examples that are just worth taking a look at just to give you some exposure to some of the other features that are available in Python.


[User] Please transcribe this text

[Assistant] One thing that will be coming up soon is the idea of decorators. And just as we can take a value in Python like a number and modify the value, decorators are a way in Python of taking a function and modifying that function, adding some additional behavior to that function. So I'll create a new file called decorators.py.


[User] Please transcribe this text

[Assistant] Just to demonstrate what we can do with decorators. And the idea of a decorator is a decorator is going to be a function that takes a function of input and returns a modified version of that function as output.


[User] Please transcribe this text

[Assistant] So unlike other programming languages where functions just exist on their own and they can't be passed in as input or output to other functions, in Python, a function is just a value like any other. You can pass it as input to another function, you can get it as the output of another function. And this is known as a functional programming paradigm, where functions are themselves values.


[User] Please transcribe this text

[Assistant] So let's create a function that modifies another function by announcing that the function is about to run and that the function has completed run, just to demonstrate.


[User] Please transcribe this text

[Assistant] So this announce function will take as input a function f, and it's going to return a new function. And usually this function wraps up this function f with some additional behavior, and for that reason it's often called a wrapper function. So we might call this wrapper.


[User] Please transcribe this text

[Assistant] About to run the function, just to announce that we're about to run the function. That's what I want my announce decorator to do. Then let's actually run the function f, and then let's print done with the function.


[User] Please transcribe this text

[Assistant] So what my announce decorator is doing is it's taking the function f and it's creating a new function that just announces via a print statement before and after the function is done running.


[User] Please transcribe this text

[Assistant] And then at the end we'll return this new function, which is the wrapper function.


[User] Please transcribe this text

[Assistant] So this right here is what we might call a decorator. A function that takes a function, modifies it by adding some additional capabilities to it, and then gives us back some output.


[User] Please transcribe this text

[Assistant] And so now here, I can define a function called hello that just prints hello world, for example.


[User] Please transcribe this text

[Assistant] And then to add a decorator, I use the at symbol. I can say at announce to say add the announced decorator to this function. And then I'll just run the function hello, and we'll see what happens. I'll run python decorators.py.


[User] Please transcribe this text

[Assistant] And I see about to run the function, then hello world, then done with the function.


[User] Please transcribe this text

[Assistant] So again, why did that work? It's because our hello function, the just printed hello world, is wrapped inside of this announce decorator. Where what the announce decorator does is it takes our hello function as input,


[User] Please transcribe this text

[Assistant] And gets us a new function that first prints an alert warning that we're about to run the function, actually runs the function, and then prints another message.


[User] Please transcribe this text

[Assistant] So a bit of a simple example here, but there's a lot of power in decorators for being able to very quickly take a function and add capability to it. You might imagine in a web application, if you only want certain functions to be able to run if a user is logged in,


[User] Please transcribe this text

[Assistant] You can imagine writing a decorator that checks to make sure that a user is logged in and then just using that decorator on all of the functions that you want to make sure only work when a user so happens to be logged in. So decorators are a very powerful tool that web application frameworks like Django can make use of just to make the web application development process a little bit easier as well.


[User] Please transcribe this text

[Assistant] Let's take a look at a couple other techniques that exist within Python. One is how we might be able to more efficiently represent functions. So let's imagine that I now have, I'm gonna call this lambda.pi for a reason you'll see in a moment.


[User] Please transcribe this text

[Assistant] Yet despite the grim tone, this prophecy sets into motion what is perhaps the greatest love story ever told— an epic journey that encompasses both the human and the divine.


[User] Please transcribe this text

[Assistant] But for Dante to reach benevolent salvation, he must first find his way through hell.


[User] Please transcribe this text

[Assistant] This landscape of torture is the setting for Inferno, the first in a three-part narrative poem written by Dante Alighieri in the 14th century.


[User] Please transcribe this text

[Assistant] Casting himself as the protagonist, Dante travels deeper and deeper into Hell's Abyss, witnessing obscene punishments distinct to each of its nine realms.


[User] Please transcribe this text

[Assistant] Violence and fraud to the horrific ninth circle of treachery where sinners are trapped under the watchful eyes of Satan himself.


[User] Please transcribe this text

[Assistant] The following two parts, Purgatorio and Paradiso, continue Dante's journey as he scales the Mount of Purgatory and ascends the nine celestial spheres of heaven.


[User] Please transcribe this text

[Assistant] Written together over ten years, these three sections comprise the divine comedy and allegorical imagining of the soul's journey towards God.


[User] Please transcribe this text

[Assistant] But Dante's Divine Comedy is more than just religious allegory. It's also a witty, scathing commentary on Italian politics.


[User] Please transcribe this text

[Assistant] A soldier and statesman from Florence, Dante was staunchly faithful to God, but often critical of the Roman Catholic Church. He particularly disliked its rampant nepotism and practice of simony— the buying and selling of religious favors such as pardons from sin.


[User] Please transcribe this text

[Assistant] Many groups took advantage of these corrupt customs, but few supported them as much as the Guelfineri, or Black Guelphs. This was a political and religious faction which sought to expand the pope's political influence.


[User] Please transcribe this text

[Assistant] Verdante was a member of the Guelphi Bianchi, or White Guelphs, who believed Florence needed more freedom from Roman influence.


[User] Please transcribe this text

[Assistant] As a public representative for the white Guelphs, Dante frequently spoke out against the pope's power, until the black Guelphs leveraged their position to exile him from Florence in 1302.


[User] Please transcribe this text

[Assistant] But rather than silencing him, this lifelong exile led to Dante's greatest critique of all.


[User] Please transcribe this text

[Assistant] Dishonored and with little hope of return, the author freely aired his grievances with the Church and Italian society.


[User] Please transcribe this text

[Assistant] Writing the Divine Comedy in Italian rather than the traditional Latin of the educated elite, Dante ensured the widest possible audience for his biting political commentary.


[User] Please transcribe this text

[Assistant] In the Inferno's circle of the wrathful, Dante eagerly witnesses sinners tear black-gwell Filippo Argenti limb from limb.


[User] Please transcribe this text

[Assistant] In the circle of fraud, Dante converses with a mysterious sinner burning in the circle's hottest flames. He learns that this is Pope Nicholas III, who tells Dante that his two successors will take his place when they die, all three guilty of simony and corruption.


[User] Please transcribe this text

[Assistant] Despite the bleak and sometimes violent imagery in Inferno, the Divine Comedy is also a love story.


[User] Please transcribe this text

[Assistant] Though Dante had an arranged marriage with the daughter of a powerful Florentine family, he had also been unrequitedly in love with another woman since he was nine years old, Beatrice Portinari.


[User] Please transcribe this text

[Assistant] Despite allegedly meeting just twice, she became Dante's lifelong muse, serving as the inspiration and subject for many of his works. In fact, it's Beatrice who launches his intrepid journey into the pits of hell and up the terraces of Mount Purgatory.


[User] Please transcribe this text

[Assistant] Portrayed as a powerful, heavenly figure, she leads Dante through Paradiso's concentric spheres of heaven until he is finally face-to-face with God.


[User] Please transcribe this text

[Assistant] In the centuries since its publication, the Divine Comedy's themes of love, sin, and redemption have been embraced by numerous artists, from Auguste Rodin and Salvador Dali to Ezra Pound and Neil Gaiman.


[User] Please transcribe this text

[Assistant] And the poet himself received his own belated earthly redemption in 2008, when the city of Florence finally revoked Dante's antiquated exile.


[User] Please transcribe this text

[Assistant] Next, find out why you should read the Tolstoy classic War and Peace.


[User] Please transcribe this text

[Assistant] A garrulous grandmother and a roaming bandit face off on a dirt road.


[User] Please transcribe this text

[Assistant] A traveling handyman teaches a deaf woman her first word on an old plantation.


[User] Please transcribe this text

[Assistant] From her farm in rural Georgia, surrounded by a flock of pet birds, Flannery O'Connor scribbled tales of outcasts, intruders, and misfits staged in the world she knew best, the American South.


[User] Please transcribe this text

[Assistant] She published two novels, but is perhaps best known for her short stories, which explored small town life with stinging language, offbeat humor, and delightfully unsavory scenarios.


[User] Please transcribe this text

[Assistant] The names of her characters are equally sly. Take the story, the life you save may be your own.


[User] Please transcribe this text

[Assistant] Where the one-handed drifter Tom Shiflett wanders into the lives of an old woman named Lucy Nell Crater and her deaf and mute daughter.


[User] Please transcribe this text

[Assistant] At first, we may be suspicious of Shiflett's motives when he offers to help around the house, but O'Connor soon reveals the old woman to be just as scheming as her unexpected guest and rattles the reader's presumptions about who has the upper hand.


[User] Please transcribe this text

[Assistant] For O'Connor, no subject was off limits. Though she was a devout Catholic, she wasn't afraid to explore the possibility of pious thought and un-pious behavior coexisting in the same person.


[User] Please transcribe this text

[Assistant] In her novel, The Violent Barrett Away, the main character grapples with the choice to become a man of God, but also sets fires and commits murder.


[User] Please transcribe this text

[Assistant] The book opens with a reluctant prophet in a particularly compromising position.


[User] Please transcribe this text

[Assistant] Francis Marion Tarwater's uncle had been dead for only half a day when the boy got too drunk to finish digging his grave.


[User] Please transcribe this text

[Assistant] This leaves a passerby to drag the body from the breakfast table where it was still sitting and bury it with enough dirt on top to keep the dogs from digging it up.


[User] Please transcribe this text

[Assistant] Though her own politics are still debated, O'Connor's fiction could also be attuned to the racism of the South.


[User] Please transcribe this text

[Assistant] In Everything That Rises Must Converge, she depicts a son raging at his mother's bigotry.


[User] Please transcribe this text

[Assistant] But the story reveals that he has his own blind spots and suggests that simply recognizing evil doesn't exempt his character from scrutiny.


[User] Please transcribe this text

[Assistant] Even as O'Connor probes the most unsavory aspects of humanity, she leaves the door to redemption open a crack.


[User] Please transcribe this text

[Assistant] In A Good Man is Hard to Find, she redeems an insufferable grandmother for forgiving a hardened criminal, even as he closes in on her family.


[User] Please transcribe this text

[Assistant] Though we might balk at the price the woman pays for this redemption, we're forced to confront the nuance in moments we might otherwise consider purely violent or evil.


[User] Please transcribe this text

[Assistant] O'Connor's mastery of the grotesque and her explorations of the insularity and superstition of the South led her to be classified as a Southern Gothic writer.


[User] Please transcribe this text

[Assistant] O'Connor died of lupus at the age of 39, after the disease had mostly confined her to her farm in Georgia for 12 years.


[User] Please transcribe this text

[Assistant] During those years, she penned much of her most imaginative work.


[User] Please transcribe this text

[Assistant] Before I get you to lift all of your lids, I'll tell you this.


[User] Please transcribe this text

[Assistant] One of you is in for a very big surprise.


[User] Please transcribe this text

[Assistant] This is a good moment for you just to stop and go hang on, I'm here for a reason. Yeaah, and be proud. And know that through the tough times, hold on to these times. Because that is great cooking and you deserve to be here.


[User] Please transcribe this text

[Assistant] Sashi, there's always this issue when contestants, you know, they've got a strength. Yours is definitely Malaysian style. They just want to prove something to us that they can cook other things. A lot of them fall over.


[User] Please transcribe this text

[Assistant] You, my friend, definitely 100% have not. Thank you so much.