navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Python 3 Essential Training
John Hersey

Python 3 Essential Training

with Bill Weinman

 


Due to its power, simplicity, and complete object model, Python has become the scripting language of choice for many large organizations, including Google, Yahoo, and IBM. In Python 3 Essential Training, Bill Weinman demonstrates how to use Python 3 to create well-designed scripts and maintain existing projects. This course covers the basics of the language syntax and usage, as well as advanced features such as objects, generators, and exceptions. Example projects include a normalized database interface and a complete working CRUD application. Exercise files accompany the course.
Topics include:
  • A Python 3 quick start for experienced developers
  • Creating functions and objects
  • Using Python’s built-in objects and classes
  • Repeating code with loops and iterators
  • Understanding and using conditional expressions
  • Creating sequences with generators
  • Reusing code with objects and libraries
  • Handling errors with exceptions

show more

author
Bill Weinman
subject
Developer, Web, Programming Languages, Web Development
software
Python 3
level
Beginner
duration
6h 36m
released
Jul 29, 2010

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



1. Introduction
Welcome
00:04Hi! I'm Bill Weinman, and I'd like to welcome you to Python 3 Essential Training.
00:08Python is a modern object-oriented programming language that's well-suited for a
00:12variety of uses, from simple scripts to complex web applications.
00:17In this course, I'll show you how to use Python and how to take advantage of its
00:21unique and powerful features.
00:23I'll start by giving you an overview of Python, so that you can get
00:26started right away.
00:27This quick start is designed for the experienced programmer who wants to
00:31leverage their existing knowledge to start using Python quickly and with as
00:35little detail as necessary.
00:36Then we'll get right into the details of the language, its syntax and structure,
00:40exception handling, functions, classes and Python's powerful object model.
00:45I'll show you how to do common tasks in Python, including file layout, databases
00:49and web development, and I'll show you how to use modules to leverage your work
00:53and the work of others to get your projects done faster and with less effort.
00:57Finally, I'll walk you through some real-world examples of working Python
01:01code, so you can see how the pieces fit together and to help you get started
01:05on your own projects.
01:07This course is designed for programmers.
01:09If you already have some programming experience in at least one other modern
01:13language, this course is for you.
01:15I've been a programmer since the `70s, and I've used many different languages
01:18over the years, and I'm really excited about Python.
01:21I'm glad to be able to share this knowledge and experience with you, so that you
01:26can write better applications today.
01:28Now, let's get started with Python 3 Essential Training.
Collapse this transcript
Understanding prerequisites for Python
00:00In order to get the most out of this course, there are a few things you're going to need.
00:04First of all, you need a basic understanding of programming.
00:08This means that you need experience writing working code in a modern
00:12programming language,
00:13for example, Perl, PHP, Java, JavaScript, C++, or any modern programming
00:21language, and you need some understanding of object-oriented programming.
00:25You don't necessarily need to be an expert, but you need to at least have an
00:29understanding of what it is, and why it is.
00:32You will need to have a text editor.
00:35A text editor is not a word processor.
00:37When you edit text using a word processor, the word processor adds other
00:41information to the file, information about formatting, layout, fonts, things like these.
00:47These things will make the program not work.
00:49You cannot edit program code in a word processor.
00:53You need a plain text text editor and there are lots of them available on every platform.
00:57For the purposes of this course, we're going to be using an integrated
01:00development environment called Eclipse for our text editor.
01:04You do not need to use Eclipse.
01:07Use whatever text editor you're comfortable with.
01:09Use whatever coding environment you're comfortable with.
01:12The reason that I'm using Eclipse in this course is for the purposes of instruction.
01:16It runs on every platform and it allows me to demonstrate running the code in
01:21the same environment.
01:22You don't need to use an integrated environment like that.
01:25You can use a plain text editor.
01:27Finally, you'll need a system with Python 3 installed, and I strongly recommend
01:32Python 3.1 or later.
01:34The examples in this course are using Python 3.1.
01:38Python 3 is a significant upgrade from Python 2.
01:41Code written in Python 2 will not necessarily work in Python 3, and vice versa.
01:48It's essentially the same language, but there are some significant differences,
01:51and this course is about Python 3.
01:54Python 3 is easy to get and to install. Installers are available for most
01:58operating systems, and you can find an installer for your operating system
02:02at this URL.
Collapse this transcript
Using the exercise files
00:00If you're a premium member of the lynda.com Online Training Library, or if you're
00:04watching this tutorial on a DVD-ROM, you have access to the exercise files used
00:09throughout this title.
00:10The exercise files are organized by chapter, and I suggest that you copy them to
00:15your desktop and work with them from there.
00:17Each chapter has number of files in it.
00:20For example, here in the Chapter 6, there are three files, and by and large these
00:24files are Python scripts code.
00:26We'll be using these files from inside of Eclipse.
00:29Eclipse is an integrated development environment, and I'll show you how to
00:33import the files into Eclipse in the movie on installing Eclipse.
00:36You do not have to use Eclipse to follow along with this title.
00:40You can use whatever editor or whatever development environment you choose.
00:44I use Eclipse because it's platform- independent, and it's portable, and it's
00:49easy to use for teaching, but you do not have to use Eclipse to follow along in this title.
00:54Whenever I open a file in this title, I start by making a copy of the file and
00:59then work with the working copy.
01:01I do this by dragging the file while holding down the Control key on a PC or the
01:06Command key on a Mac and then let it go, and this will give me an opportunity to
01:12choose a name for the copy, and I typically use the same name with a dash and the
01:17name working, and end it with .PY.
01:21By doing this and working with the working copy, the original files are left
01:25unchanged, and this way you can go through the exercises again at a later time if
01:30you choose to do that.
01:31If you don't have access to the exercise files, you can follow along from
01:34scratch, or with your own assets.
01:37So, let's get started.
Collapse this transcript
2. Python Quick Start
Getting started with "Hello World"
00:00As we start the Python Quick Start, we're going to use the traditional
00:05"Hello, World!" program.
00:07And purpose of "Hello, World!" is not an exercise to find the simplest form of
00:13code in a particular language, or anything like that.
00:16It's actually to learn about the development environment, to learn about what we
00:19call the development cycle:
00:21what it takes to edit, and to test, and to change, and to test and to run code
00:28in a particular environment.
00:30And so for this purpose we use the simplest form of a program itself, so that
00:35that can get out of the way and then we can focus on the environment.
00:38In this case, I've this up here on the screen in Eclipse.
00:42And this is Eclipse using Pydev, which is a Python development environment that
00:45runs inside of Eclipse.
00:47Eclipse is an integrated development environment originally written for
00:51developing in Java, but it has plug- ins for a lot of different languages.
00:54And Pydev is actually a pretty good plug-in for the Python language.
01:00And so, we'll be using this throughout this course.
01:02You do not have to use Eclipse, and if you have some other development
01:07environment that you prefer, or you just want to use an editor and a command line,
01:12that's perfectly fine.
01:13You can do all of the exercises; you do not need to use Eclipse.
01:17The reason that I'm using Eclipse is because it's convenient for the purpose of teaching.
01:22I've got everything that I need right up here on the screen.
01:24I can run code, I get the results of code, and it works well for the purpose of
01:29teaching, but you don't need to use it for your development work.
01:33And you do not need to use it to follow along in the exercises.
01:37In Eclipse, if I want to run this Hello, World!,
01:40I simply click on this Run button up here, and it'll ask me, How I want to run it?
01:45and I'm going to select Python Run.
01:47I only need to do this the first time I run a script.
01:49So I'm going to say OK.
01:52And here we have the result down here: "Hello, World!"
01:56If I were running this in another environment and I actually have this script
02:00loaded up here on a Unix Server -
02:02this is my Unix Server -
02:04there is the script, you see it's exactly the same.
02:09And if run it I say ./hello.py, and it runs it.
02:15An important part of this is this shebang line.
02:19If we look here in Eclipse, we see this shebang line here.
02:23In many environments, mostly Unix- based environments, but this includes
02:28Macintosh and it includes many, many web servers that are running Unix-based
02:32operating systems, like Linux or PSD,
02:35this shebang line is actually very important.
02:38It's called a shebang line because it's starts with a hash and then has an
02:42exclamation mark, which is sometimes called a bang.
02:45And then after that it has the path to the interpreter that will be used to run the script.
02:53When the script is executed and the shell sees it, it will look here for the
02:58interpreter and then use that to run the script.
03:01So sometimes you'll see a bash up here, or Perl, or something like that.
03:05And all that's doing is it's telling the shell to use that interpreter to run
03:10whatever script is there.
03:11For Python, it's going to be something like this.
03:14It might be #!/usr/bin/python3.
03:16It might be #!/usr/local/bin/python3.
03:21It might be #!/usr/bin/env python3, something like that.
03:31In this case, I'm using #!/usr/bin/python3 because I know that, that works in the
03:35environments that I'm using.
03:37And if it doesn't, then I'll make a symbolic link or something and make it work.
03:40So if you're running this on a Unix-based operating system,
03:42you'll want to do ls -l and look at the file permissions, and make sure that it has
03:49executable permissions.
03:51If it doesn't, you can make it executable by typing chmod, or as we pronounce it
03:57chmod 755, which makes it editable and executable for your user ID, and then
04:06the name of the file.
04:08And that will make it executable.
04:10And then you can execute it with ./ or however it is that you do that on your system.
04:16So that is the development environment that we will be using.
04:20For the most part, we're going to using Eclipse.
04:23And so we'll be running scripts like this.
04:26Save it and Run it.
04:27It'll run here in the Console.
04:30So you're going to want to take the opportunity, using this "Hello, World!"
04:33script, to learn about the development cycle and whatever environment you're
04:37using, especially if it's not Eclipse, to follow along with the exercises
04:42in this course.
Collapse this transcript
Selecting code with conditionals
00:00So, continuing with our Python Quick Start, let's take a look at how
00:04conditionals work in Python.
00:06I am going ahead and make a copy of this conditionals.py, and it's a good idea
00:11to work with copies.
00:13I am just going to name this conditionals -working. We'll go ahead and open that.
00:24There we have an example of a conditional, a very simple conditional. It's if and else.
00:31And you'll notice that the assignment - it's really cool.
00:33In Python, you can assign multiple values at a time, so this assigns a 0 to a and
00:38assigns 1 to b. So that makes a nice little test for the conditional. If a is
00:42less than b, which it is, then it will print this.
00:46You'll also notice, in Python, you do the replacement, and this is Python 3;
00:51Python 2 works differently.
00:53In Python 3, these curly braces will be replaced by the values in the format, and
00:58we'll get more into how this works exactly, and some of the details of it, later
01:03on when we talk about strings.
01:06But in fact this format is a method of the string object.
01:12Any place where you have a string, it allows you to do these kinds of
01:15replacements; it's very useful.
01:18So, when we run this - and we'll get this one because a is less than b, and unless
01:24we were to change these values and then maybe we could get this one.
01:26So let's go ahead and run it, and I'll run it here in Eclipse, and I'll select
01:31Python Run, and there we go.
01:34a is less than b, and see there is the value 0 and 1.
01:38If I change this, if I make this say a 5, and I save that and run it, a is not
01:44less than b anymore.
01:46So the syntax of the conditional is, if, and then you have the condition, and you have a colon.
01:53This is how blocks work in Python. You'll see this same type of syntax and
01:58loops and functions and classes, where you have the colon and then you have code that's indented.
02:06There aren't any braces signifying a block of code.
02:10Blocks are actually called suites in the Python documentation, and they
02:15simply consist of code that is indented under the level of whatever it is
02:20that's controlling it.
02:21So here we are controlling it with a conditional, and we have the colon, and then
02:24we have this code indented.
02:26Now four spaces of indenting is considered standard in Python.
02:31It's actually not required.
02:32I can make this one space and do the same down here and it would still work,
02:38save and run, but four is traditional.
02:43So we are just going to go ahead and go with the tradition here and save that
02:48and run it, and there we have it.
02:51Python also has conditional expressions. If you are familiar with any C-based
02:55languages, you'll be familiar with something that might look like this, where you
02:58would say print, and you would have a condition a < b and a question mark, and then one value, and a colon,
03:08and then another value.
03:10If the condition were true, you would get the first one; if the condition were
03:13false, you would get the second one.
03:15Python has something like this, but it works very differently.
03:18Here, you would say "foo" if a < b else "bar".
03:26If I save that and run it, then we get bar because a is not less than b. If I put
03:33this back to a 0, like we had it originally, and save and run,
03:38now we get foo because a is less than b. So this is how conditional
03:42expressions work in Python.
03:45A lot of the syntax that you will see here is a little bit different than in
03:50other C-based languages.
03:52And that's because the designers of Python, they didn't consider themselves be
03:56beholden to tradition, and instead they wanted to do things that seem to flow
04:01better or make sense in some way.
04:04And actually, this does have its own set of reason in that you have print "foo"
04:09just like you would have if you didn't have a condition.
04:12You only really care about having the condition if you have another value.
04:16So you have this whole if-else all in one place, and it's spelled out; it's not
04:22punctuation marks that might just be hard to remember or hard to read.
04:28It's very clear: "foo" if a < b else "bar"; it's kind of readable.
04:33So that is how conditions work in Python 3.
04:37You have the traditional if-else, and you have the conditional expressions.
Collapse this transcript
Repeating code with a loop
00:00There are two fundamentals types of loops in Python. There is while loops and for
00:05loops, and let's start by looking at the while loop.
00:09So we'll take our whileloop.py and make a little copy of it, and call
00:16it whileloop-working.
00:21Go ahead and open that, and you'll see this is a simple Fibonacci series.
00:26It's a common exercise for while loops.
00:29So here we are assigning two values to a and b: 0 and 1. The 0 will get assigned
00:34to a, and the 1 will get assigned to b. We say while b < 50 and we go ahead and
00:41do things we'll make b grow in a Fibonacci series and we print it each time
00:48using the print function.
00:50So if I go ahead and run this and select the Python Run, you'll see here we get
00:57the Fibonacci series.
00:59So while loops just work like that. They say while, and then there is a condition.
01:04And as long as this condition is true, the while loop will continue to execute.
01:10And as soon as this condition becomes not true, then the while loop will end
01:14and execution will continue after it if there is any code after it, which in
01:18this case we don't have.
01:19Down here I could say print ("Done") and if I save that and run it, you'll see we get Done
01:27at the end.
01:29You'll notice that the print ("Done") is not indented. If I were to indent it
01:34here, then it would become part of the loop.
01:36But by having it back here, at the same indention level as the while statement
01:42itself, then it is no longer part of this suite of code that is controlled by the while loop.
01:50So that's how while loops work.
01:54Let's take a look at for loops.
01:58Go ahead and make a copy of forloop.py, and I'll name it forloop-working
02:10and we'll open that.
02:11What a for loop does is it works with what's called an iterator.
02:15An iterator is an object that each time you call it,
02:18it gives you the next value.
02:21So in this case, we open a file and it's this lines.txt, which we can see right
02:27here; it just has five lines of text.
02:29Then for line in fh, that's the file handle, which is actually an object and it
02:37has this method readlines, which is an iterator.
02:41So for each time this fh.readlines is called, it will put the next value in the
02:48line variable, which will be the next line of text, and then we'll print it.
02:52So when I run it, we get these lines of text.
02:58Now, you'll notice that there is an extra line ending, an extra new line, in
03:03each one of these, and that's because the print function puts a new line at the
03:07end, and each of these lines actually has a new line at the end of it, so we get two for each one.
03:14If you hover the mouse in Eclipse, you hover the mouse over the print function,
03:18you get a little bit of documentation for it.
03:19You'll notice that there is an end option, and it defaults to having this new line.
03:24So if I just say end= ' ', empty string like that and I save it and run it,
03:32now, we don't have that effect anymore.
03:35So, the for loop works likes this.
03:39It calls an iterator, and its values get put in this variable here.
03:45It has a colon, like all the control structures in Python, and the block of code
03:50underneath it is indented.
03:53So for each line of readlines, it will take the line, put it in the line variable,
03:57and then print it, just like we see here.
04:00So that's how for loops work in Python, and those are the two types of loops that
04:05we'll see in Python.
04:06We have while loops, which are traditional, conditional loops, and for loops,
04:11which work with iterators.
Collapse this transcript
Reusing code with a function
00:00One very common way to reuse code in Python is the use of a function, so let's
00:05take a look at how functions are used in Python.
00:08We'll go ahead and make a working copy of function.py.
00:12I'm going to call this function-working.py.
00:15Save that and open it up.
00:19Then I'll go ahead and maximize this, so we can look at this code.
00:24Here, we have a function definition.
00:26def is the keyword. It says this is going to define a function.
00:31isprime is the name of the function, and n, in this case, is a parameter.
00:36We can have multiple parameters, separated by commas.
00:40We'll get into more of the details of how this works.
00:42This is the Quick Start.
00:43It's going to show you in a nutshell, if you're an experienced programmer, how
00:47to create functions.
00:48We'll get into the details later on in the course.
00:51In this case, this is a simple function for testing if a number is a
00:54prime number or not.
00:55It checks if it's 1.
00:57It checks if it's divisible evenly by other factors, and otherwise it says,
01:02this is a prime number.
01:05So all of this code that is the body of the function is indented, as is how
01:11blocks of code are done in Python.
01:13And it's introduced with this colon.
01:15So you have the def, the name of the function, parenthesis, any parameters
01:20inside the parenthesis, and a colon, and then indented code for the body of the function.
01:27Down here, we call it.
01:28Here, we're calling it inside a for loop.
01:30And we simply call it by referencing the name and putting any parameters inside.
01:35Now in this case, the parameter is a variable called n, which happens to be the
01:40same as what I call it up here.
01:42We could have used an x, or any other legal variable name down here, but just so
01:47you know that this n is different than this n.
01:51All right, so let's go ahead and run it.
01:56We'll select Run up here and Python Run.
02:00And there we have a list of all of these prime numbers.
02:06So 1 is special.
02:072 is a prime number.
02:083 is a prime number.
02:104 is not a prime number, because it's divisible evenly by 2, and et cetera,
02:16et cetera, prime numbers and not prime numbers.
02:21So this function is getting called over and over inside of this loop.
02:26And we only have to have the code there once.
02:28And that, of course, is the value of a function or a subroutine.
02:32So that's how functions are defined and used in Python.
02:36And of course, they're used quite a bit, and we'll see a lot more examples of
02:40this as we go through the course.
Collapse this transcript
Creating sequences with generator functions
00:00Generator functions are an incredibly useful pattern in Python.
00:05What a generator function does is it actually creates an iterator.
00:09Let's take a look at how this works.
00:12We can make a working copy of generator.py.
00:15I'm going to call it generator-working.py.
00:21Go ahead and open that up and take a look.
00:25This is the generator here.
00:26Now it calls this isprime, which is very similar to the one that we used in
00:30our functions example, except instead of the Print statements, it returns
00:34False if it's not prime, and it returns True if it is prime. So that's a
00:38little utility function.
00:40This one here, it looks, at first glance, like a normal function, and in fact, it
00:45is, except it has this yield statement.
00:50Yield is like return.
00:51It returns a value.
00:53You see here we have return False, return True. Those return those Boolean values.
00:59This one here returns a number,
01:01and it returns this number only if isprime returns true, so it returns the next
01:07prime number, but it uses yield instead of return.
01:12And what yield does is it returns a value, but then the next time the function
01:16is called, it continues execution after the yield.
01:20So in this case, we have this while loop.
01:23And it checks to see if the number is prime.
01:28If it's not, it increments and checks the next one.
01:31And if it is, it yields.
01:34And that will return a value.
01:36And then the next time this function is called, it'll just continue here,
01:39incrementing and looking for the next one.
01:42And so this actually, because of these of yield, it returns an iterator object,
01:47that is suitable for use in a for loop.
01:50And here we have a for loop, and for n in primes,
01:54and so it calls this primes function.
01:56There is the primes function.
01:58And for each iteration, it'll put the value in n. And it'll print it out, and it
02:04tests to see if it's greater than 100. Then it breaks out of the loop.
02:08And so this uses this generator function as an iterator.
02:13And it will print a list of prime numbers.
02:15Let's go ahead and take a look at this as it works. We'll run it.
02:21And here we have a complete list of all the prime numbers up to 97.
02:29So you can see that this is incredibly useful.
02:32And we'll some more examples of it as we go through the course.
02:36So this is a generator function, and what it generates is an iterator that's
02:40suitable for use in a for loop, just like any iterator in the Python language.
Collapse this transcript
Reusing code and data with a class
00:00Object-oriented programming is a very powerful model for reusing code.
00:06Let's take a look at how objects and classes are defined and used in Python.
00:12We'll start with this simpleoop.
00:14oop stands for Object-oriented programming.
00:17We'll make a working copy of this, and we'll go ahead and open the working copy.
00:27And let's just take a look at what's in here right now.
00:32This is a class, and a class, in Python, as in many object-oriented paradigms, a
00:39class is the definition that is used to create an object.
00:43It's sometimes called a blueprint.
00:45So objects are instances of classes.
00:50So when you take a class, here's the class that we've defined up here, class
00:55Fibonacci, and you assign it to a variable, that's called instantiating, or
01:01creating an instance, of that class,
01:03and the instance itself, in this case,
01:05it's just called f, that instance is called an object.
01:10An object is an instance of a class.
01:13So the class is the definition, and here we have class, and it's named Fibonacci,
01:18and it has these parentheses, and we'll talk later about what goes in the
01:21parentheses if anything. Right now nothing needs to go into them.
01:24The colon introduces the blocks or suites of code that are indented, and
01:30therefore part of the class definition.
01:33And here, we have two functions defined as part of this class.
01:38And each of these functions, you'll notice that its first argument is self.
01:43And here we have one that's just got self, and here we have one that's got self
01:47and some other variables.
01:50self is the common name for that first argument.
01:53It doesn't have to be self.
01:54It's traditionally self.
01:56And what it is is a reference to the instantiated object.
02:01So when we use the object f, and here we're calling a method or a function
02:07inside of the object f, that's what this dot notation does, f.series().
02:12It calls the series function or method, but it calls the copy of it that's part
02:18of the object, the instantiated object.
02:21And its first argument is actually a reference to the object f. And so, we can
02:28assign and use variables that are encapsulated within that object and that are
02:34actually carried around.
02:36So if we had different instances of the same class, they would have separate
02:41variables, separate values in self.a and self.b. This init function, or method, is
02:49actually special. This is called a Constructor.
02:52And this gets called when f gets assigned.
02:57So f gets assigned Fibonacci, and that creates an object called f, which is an
03:05instance of Fibonacci.
03:07As that object is created, init is called, and init is called with a reference to
03:14self and with these variables, and here we have 0 and 1.
03:19You can define these however you want to because you're writing this
03:22constructor. The constructor is optional.
03:25If you don't need it, you don't need to create it.
03:28But in this case, we used a constructor so that we could demonstrate how this works.
03:33And what this is doing here is it simply creating some default initial values
03:37for a and b, which are going to used as part of the Fibonacci series.
03:42And then we have this second method, or function, and this one is actually a
03:49generator. You see it uses the yield statement.
03:53And so that generates an iterator, which is used here in this for loop, and so
03:58for r in f.series() is going to give us a series of all the Fibonacci numbers
04:02that are less then 100.
04:05So let's go ahead and run it, and there we have our Fibonacci series up to 89,
04:14which is the last Fibonacci number that is less than 100.
04:18So here we have defined a class called Fibonacci, we have instantiated it,
04:24creating an object, called f, and in that object, we called this generator function
04:31and we got a series of Fibonacci numbers.
04:34So that is a simple example of a class and an object in Python.
Collapse this transcript
Greater reusability with inheritance and polymorphism
00:00The object model in Python is really very powerful and well-designed.
00:04And Python does support inheritance and polymorphism.
00:08So let's take a look at an example of how we do inheritance and polymorphism in Python.
00:14First, we'll make a working copy of oop2.py, and we'll open our working copy, and
00:29here we have a number of classes, and you'll see we have these animals:
00:34Dog, Person and Duck. And each of these inherits AnimalActions.
00:42So AnimalActions has the code in it.
00:47It has these four methods:
00:49quack, feathers, bark and fur. And you will notice that each of these methods is
00:53defined on one line.
00:54So because each of these methods has just one line of code, you can do it all on one line.
00:59You have the def keyword, and then you have the name of the method and then the code.
01:05In this case, it's return self.strings 'quack'.
01:09This notation here is because strings is a dictionary, and we'll get into that
01:15later on in the course when we talk about data types. But these strings,
01:20self.strings, are actually defined in the classes that inherit AnimalActions,
01:27and so this is an example of inheritance.
01:31This is also an example of data abstraction, because each of these classes
01:36has different data.
01:38So here we have the duck, and it has these four strings in it:
01:42quack, feathers, bark and fur. And the duck says quack. The duck has gray
01:47and white feathers. The duck cannot bark. The duck has no fur. And then we
01:51have a Person, which also inherits AnimalActions, and the Person has quack,
01:56feathers, bark and fur.
01:58But for quack, instead of saying quack, the person imitates a duck.
02:02The person takes a feather from the ground and shows it for feathers.
02:05For bark, the persons says woof.
02:08For fur, the person puts on a fur coat, and then we have dog, which also has
02:12quack, feathers, bark and fur, and does dog-like things with these.
02:17So this allows us to abstract all of this data, and to use it in exactly the same
02:23way in each of these classes.
02:25Because each of these classes inherits AnimalActions, these methods become
02:30available in each of these other classes.
02:33So when I create a duck object, here we have donald = Duck,
02:40that duck object will have these dictionary strings, Quaaaaak!
02:46The duck has gray and white feathers, and it will also have these action methods:
02:51quack, feathers, bark and fur.
02:53And so I can call duck.quack and I can call duck.feathers.
02:59The beauty of this is that I can also define a Person, john, and I can call
03:07in_the_forest, where it's expecting a duck, I can call it with john.
03:12And so here we have an iterator. We are calling for o in ( donald, john, fido),
03:16so o will be sequentially don and john and fido.
03:20john is a person; john is not a duck.
03:22But in_the_forest(o) calls in the forest with john and in_the_forest expects a
03:30duck object, so it calls duck.quack and duck.feathers.
03:34Well, john implements - because john is a person, a person inherits AnimalActions,
03:40and it implements quack and feathers.
03:43So this is called polymorphism.
03:45And let's see how this works.
03:48Remember, we are going to be calling in the doghouse and in the forest for each
03:54of these three objects:
03:55donald, john and fido.
03:57A Duck, a Person and a Dog.
03:58First, we'll call in the forest for each of them, and then we'll call in the
04:02doghouse for each of them.
04:04So I am going to run this.
04:09And we'll take a look at the results.
04:10In the forest, we have Quaaaak!
04:13And the duck has gray and white feathers.
04:15So we are calling Quaaaak!
04:17and feathers for each of these.
04:20We are calling Quaaaak!
04:21and feathers also for the person, and it says the person imitates a duck, and
04:24the person takes the feather from the ground and shows it, and also for the dog,
04:29and then in the doghouse, the duck cannot bark, the duck has not fur, the person says woof!
04:33the person puts on a fur coat and then for the dog Arf!
04:36and the dog has white fur with black spots.
04:40So this is an example of polymorphism and inheritance in Python.
04:48Now real quick, I want to also show you this example that's been rewritten as a Model-View-Controller.
04:54Model-View-Controller is a very common pattern in object-oriented programming,
05:00and I just want to show you that we can do exactly the same thing and actually
05:04separate it out a little bit further.
05:07In this case, we are not bothering to define the data for that which doesn't
05:12apply for each of these.
05:14So the dog doesn't quack,
05:16so I am not having a string for dog.
05:19So this is the modeling, and we have the model for the duck and the person and
05:25the dog, and each of these inherits AnimalAction. And in this context, we don't
05:29really care about the implementation of AnimalActions, because all that matters
05:33is that we are modeling each of these types of objects.
05:40The view is the implementation of how do we view each of these things?
05:47So we have these four methods:
05:48bark, fur, quack and feathers. And they each call doAction with the word bark,
05:54fur, quack and feathers.
05:55And then doAction is a local method, and you will notice it has this underscore.
06:01That doesn't make it special in Python, but it does tell the person who is
06:05reading it that this is something that's just going to be called internally.
06:09You are not going to want to call this on the object.
06:11You are just going to want to call it from inside of the object, or inside of the class.
06:16So this gets called from each of these methods. And if the action is not found in
06:22the strings, then it has a default that it does, where it says, this animal name
06:26has no action. And so that allows us to model these, and to actually expand them,
06:35and define more actions, and to not have to worry about doing a whole lot of
06:41extra modifications to the parent class. And then the controller is, of course,
06:48how we call all of this stuff, which is pretty much the same.
06:51So this does exactly the same thing. If I go ahead and run this, we'll see that
06:57our result is exactly the same, but what we have here is a refined version of the
07:05same thing using a model, view and controller pattern.
07:09It's a contrived example, but this is commonly how we can do object-oriented
07:14programming in Python 3.
Collapse this transcript
Handling errors with exceptions
00:00Error reporting in Python is done with something called exceptions.
00:04Exceptions are an object- oriented way of handling errors.
00:09So let's take a look how this works in Python.
00:12Go ahead and make a working copy of exceptions.py. We'll call it
00:17exceptions-working.py.
00:19So let's go ahead and open our working copy, and we will notice that we have a
00:26script here that opens a file and reads the lines and prints the lines.
00:30The problem is is that it's spelled the filename wrong, and so when we run this,
00:35we will get an error, and we see there is the error.
00:38And you will notice that error is in red. That's because Python sends its default
00:42error messages out to standard error, which is printed in red in Eclipse, but
00:47what we want to do is want to be able to catch that error and do something
00:51intelligent within our scripts.
00:53We are going to do this with 'try,' and we will go ahead and indent this code
00:59under 'try' and accept.
01:02Now we will just print, 'something bad happened,' and then we can go ahead and
01:10continue to execute and say print 'after badness.' And so when we run this, go
01:19ahead and save it and run it, something bad happened and after badness.
01:24We can see that we caught the error, we did something, and we continued after that.
01:30Now we actually print the error message that Python gives us. We can say
01:34except IOError as e and I can say something bad happened and put the error
01:41message in parentheses here.
01:44.format (e)), and when I save that and run it, something bad happened (Error 2 No
01:52such file or directory,
01:53and now we know exactly what the problem was. We could set a flag. We could mere
02:00some different code. We can do anything different that we want to. We have the
02:04full reporting of Python's errors as this variable e
02:10So this is how Python handles errors.
02:12It throws these exceptions, and this is how we catch them and how can do
02:17something intelligent with them.
02:18We will see a lot more examples of this as we go through the rest of the course.
Collapse this transcript
3. Setting Up Python
Installing Python 3 and Eclipse for Windows
00:00Let's take a look at how you can install Python and the Eclipse environment on a Windows PC.
00:06I am using a Windows 7 PC here. This same procedure should work for any kind of modern Windows.
00:13This is the download page for Python 3.1.2. Use the downloader or installer for
00:19whatever version of Python is the latest.
00:22If I scroll down here, you will see that there is downloads available for a
00:26number of operating systems. I am going to pick the one for this Microsoft
00:30Windows box, and I have already actually downloaded this, so I have got that
00:35already in my Download folder.
00:37Let's also go ahead and download Eclipse.
00:39Now in order to install Eclipse, you must have Java installed, and you should
00:43probably have the latest Java installed.
00:46So I strongly recommend that you make sure that your computer has Java, and it's
00:51the latest version of Java.
00:53Windows machines do not necessarily come with Java already installed.
00:56So you need to make sure that you have Java installed before you install Eclipse.
01:00Eclipse is designed to be a development environment for the Java language.
01:05We are using it here to develop in Python because it has a lovely plug-in
01:09available for Python development, and that works really well.
01:12Here, on the download page for Eclipse, you will notice that there are a lot of
01:15choices, and any one of these will actually work. We are going to install the
01:20basic Eclipse Classic.
01:23Most of the time, when you hover over this link here whatever operating system
01:27you are working with, it will get the proper download for your operating system.
01:31If you are not sure, you can select the one that you want from this list over here.
01:35So let's go ahead and get started with the installation.
01:38First, we are going to install Python, and that involves double-clicking on this
01:42installer, and I will say Run.
01:45I'm going to go ahead and Install for all users, and I am going to install it in the
01:49default location, and I want to make a note where that is.
01:53That's Python31 folder, right off of the C disk.
01:58Again, I am going to accept the defaults. It's installing everything, and we want
02:02that, and then it just goes ahead and does its thing.
02:07Now let's go ahead and run IDLE and make sure that it works.
02:11There it is, so now we know that we have Python 3.1.2 installed, and it's working.
02:18Now we are going to install Eclipse.
02:20Eclipse comes to us in a zip file, so I am going to Extract All just to this
02:26default location in my Downloads folder.
02:31Now we have the eclipse folder, so I am just pressing Ctrl+N to open another
02:37Explorer window, and we'll come down here and find Program Files, and I am going to
02:43install it on Program Files (x86) because I don't loaded the 32 bit version.
02:47You can put it in the other one if you want to, and I am just going to drag this over
02:52here and move it to Program Files.
02:54So I don't want it to go in one of these other folders, so I am going to
02:58actually drag it into this part of the window here where it says move to Program
03:01Files, and I will Continue and authorize, and there it is.
03:06I will open this up, and there is eclipse.exe. I am going to pin it to the Start menu.
03:14Now, there it is in my Start menu.
03:18So I can close this window, I can close this window, and I no longer need this
03:25empty folder here. I will just go ahead and delete that.
03:29Now it's time to start Eclipse. There is still quite a bit left to do here. I am
03:35accepting that and running it.
03:36I am going to accept the default location for my workspace. I am going to say
03:42use this as a default so you don't ask me again. And you can put your workspace
03:46wherever it makes sense for you. And now we are running Eclipse but it's not
03:50ready to use at all yet.
03:52First thing we need to do is we need to install Pydev. That's the development
03:57environment for Python. And under the Help menu, you will see there is a
04:01selection for Install New Software, and before we can even type something in
04:06here, we need to click on this Available Software Sites preferences and Add a new software site.
04:14The URL for this is pydev.org/updates.
04:20We are going to call this Pydev, and say OK, and OK.
04:27Then up here, we can just start typing Pydev, and we will see that it comes up, so
04:31we select that, and it says Pending, and then we check on the one that says Pydev.
04:38You probably don't need this Mylyn Integration unless you know that you do, and
04:43if you are using Mylyn, by all means, go ahead and add that.
04:46So now I am going to say Next, and it found it, and so I am going to select that
04:50and press Finish. And now it's installing the Pydev development environment for
04:55Python within Eclipse.
04:58Say OK to the unsigned content warning, and it is strongly recommended -
05:02it says so right there - that you restart Eclipse, and there is no reason not to,
05:08so we will just say OK.
05:08All right, we are getting closer. So now we have some configuring to do.
05:14We are going to open the Preferences, which is under the Window menu, and we are
05:18going to come down here to Pydev and click on the little arrow, and then you
05:22are going to click on Interpreter - Python, and we are going to need to add our
05:28Python interpreter.
05:29So we will click New, and we will click Browse and remember where Python is.
05:35It's under the C drive and in Python 3.1, and there is our Python interpreter.
05:40Click Open, and we will just name this Python 3.1 and say OK.
05:46Now you will get this Selection Needed window. You just take the defaults and
05:51select OK Once you have all of this, you select OK, and this will take a few minutes.
05:57Now that you have configured the Python interpreter, you can create your first project.
06:02So under the File menu, you hover over New and you come down here and you select Project.
06:09Under the Selection Wizard, you click on the little arrow next to Pydev and you
06:13select a Pydev project and click Next, and you want to give it a Project name.
06:18I am going to call this Python 3 Essential Training, and you want your Grammar Version
06:26should be 3.0, and your Interpreter will be 3.1 Interpreter.
06:31Project type should be Python and click Finish, and it says it's the Pydev
06:36perspective. You can say Yes for that, and over here in the Perspectives, slide
06:41this over and right-click on the Java and click Close and slide it back over,
06:46unless you are actually going to be working in Java, in which case, you might
06:49want to leave that.
06:50So now we are going to add a folder to our project. I'm going to right-click on
06:55Python 3 Essential Training, and I am going to say New > Folder. I am going to
06:59click on Advanced and Link to folder in the file system, and then I am going to
07:03browse, and I am going to find my exercise files for this course and I put that in my desktop,
07:09and there is Exercise Files, and I will select OK, and so Link to folder in the
07:14file system is checked, and the parent is this Python 3 Essential Training. I am
07:19going to say Finish and there is my Exercise Files.
07:22So this did not copy the Exercise Files into my Project folder;
07:26It simply linked to it. And so, almost there. We are going to go back into the
07:30Preferences, and under Pydev and under Editor, we are going to find this
07:36thing called Hover.
07:38If Show docstrings is checked, you might want to uncheck it; you can try it both ways,
07:43but for my purposes in demonstrating, I have unchecked it.
07:47Feel free to try it both ways and see how that works for you.
07:50So what this does is when you hover over an object in Python, it shows the
07:55entire documentation.
07:56It pops up on the screen, and personally I find that this gets in the way.
07:59You may find it helpful.
08:01So feel free to try it both ways. I have got it unchecked on mine.
08:05Finally, under General > Editors > Text Editors, you want to make sure that
08:11Show line numbers is checked, because that's going to be useful.
08:14So we will select OK, and feel free to look through the Preferences and
08:19experiment with some of the other options. And now we are going to go ahead and
08:22just load up our Hello World program and run it. And so I will select Python Run
08:29and OK, and there we have it.
08:31So we have installed Python, we have installed Eclipse, and we have installed the
08:36Pydev development environment, and we have configured it so we can use it for
08:40Python development, and you can use this environment to follow along with the
08:43exercises in this course.
Collapse this transcript
Installing Python 3 and Eclipse for Mac
00:00So now we are going to install Python and Eclipse on a Mac.
00:04So this is the Python download page, and you will see I have already downloaded
00:08Python 3.1.2 Mac OS X Installer Disk Image.
00:13So if you are on a Mac, that's the one that you want to download.
00:17If the version number is a little bit higher, if it's a later version, go ahead
00:20and install the later version. That should work just fine.
00:24Then you want to download from the Eclipse download page, and Eclipse is written
00:29in Java, and it's actually a Java development environment, and so you will see
00:33that there are a lot of different choices.
00:35If you are a Java developer and you want to install one of these other ones,
00:38that's fine. Go ahead and do that.
00:40For my purposes, I am just getting the Eclipse Classic, because I am really just
00:43using it for Python development today. And you'll notice that when I run the
00:47mouse over this, it highlights the one for Mac OS X Cocoa, and that's really the
00:51one that you want to install.
00:53So I have already downloaded that as well, and here is my Downloads folder, and I
00:57have got the Eclipse downloaded, and I have the Python downloaded.
01:01So go ahead and close the browser, and we are going to start by installing Python.
01:07So I will double-click on the installer, and I will double-click on the
01:10Python.mpkg, and I will say Continue, and Continue, and Continue,
01:16and Agree, and Install.
01:19I am going to install this in default location. Type in my Password.
01:22Mac OS X already comes with Python installed, but it's Python 2, and so you
01:28really need to install Python 3 for this course, because this course is about Python 3.
01:33That installation is done, and I can unmount this, and I just want to go ahead
01:40and go out to my Applications folder, and then I will find Python 3.1 folder, and
01:48in there, you'll find IDLE. And I am going to drag that to my Doc because we are
01:53going to be using that.
01:55I will go ahead and we'll open it, so it's Python 3.1.2, and that's what we are looking for.
02:00So Python is installed and working on this Mac.
02:03I will Quit IDLE, and we are going to go ahead now and install Eclipse.
02:08So I am going to double-click on the Eclipse installer, and this is going to
02:12unarchive it. And it will unarchive the tar file, which is inside of the gz file.
02:17And I have got this folder, and all I need to do with at this point is drag this
02:20whole folder to my applications folder and I come in here, and I am going to find
02:24the folder called Eclipse, and inside of that folder there is the Eclipse
02:28application. I am going to drag that to my dock and run it.
02:33So you go ahead and open that.
02:35Now there are a few things we need to do to configure Eclipse. First thing, we
02:39are going to select a workspace. I am going to allow the default; you are
02:42welcome to use whatever folder works for you.
02:44I am going to select the check box to use it as a default, so it doesn't ask me again.
02:48Now before I do anything else, when Eclipse starts up, under the Help menu, I am
02:53going to go to Install New Software, and I am going to select this link. This is
02:58Available Software Sites, and I am going to add one, and this is for Pydev, and
03:04the URL is pydev.org/updates, with an s at the end.
03:10Say OK, and we see that gets added there, and I say OK, and then all I need
03:16to do is select that is go up here and type Pydev, and just the first couple of
03:21letters, and I will get this here, and I can double-click on that, Pending, and it finds Pydev.
03:27So you want to check Pydev. You don't need to check the Mylyn integration, unless
03:32you know what that is, and you are going to be using that. And I will select Next,
03:37PyDev for Eclipse, and Next. And I want to accept the terms of the license and
03:43Finish, and here we go.
03:45This should take just a moment. At the security warning, you want to say OK, and
03:50it is strongly recommended that you restart Eclipse. There is no reason not to.
03:54So I am just going to select Yes, and Eclipse will restart.
03:58So now I am going to go ahead, and I am going to go to the Workbench. That's this
04:01icon over here at the right, and I am going to maximize this on my workspace.
04:05You will see over here we have Java selected.
04:08I am going to select Other and Pydev and OK, and because I am not going to
04:13be doing any Java development, I am just going to right-click on Java and select Close.
04:18Then I can move this over, and there is my Pydev Workspace.
04:22Now before we get started, we need to go into Preferences, and under Pydev and
04:29Interpreter Python, we need to add our Python Interpreter, and this is so Pydev
04:35knows where to look for Libraries, what sort of Grammar to use, things like that.
04:40So I am going to go ahead and add it. I am going. It's under browse user > local > bin >
04:48python 3.1, and that's an alias, and it's supposed to be. And so when I say OK, it
04:54actually goes and it finds what the alias was pointing at.
04:57Under interpreter name, I am just going to type Python 3.1.
05:00I am going to say OK, and it will say OK.
05:04Now if you are also going to be doing Python 2 development, you might want to
05:08add that interpreter as well.
05:10I know I am not going to be, so I am going to leave it like this.
05:13So now I say OK, and it goes and it finds all of the frameworks, and it finds all
05:17the libraries, and it does all of this stuff, and now that's installed.
05:21So we are getting closer. At this point, we want to go back into the
05:24Preferences, and under Pydev and under Editor, see this thing that says Hover,
05:31and see it's a Show docstrings?
05:33I uncheck that. I find that very distracting.
05:36It's up to you if you want to uncheck that or not.
05:39What it does is whenever you hover over an object in Python, it will show you the
05:44entire documentation, and it will pop up for that object.
05:47I am sure some people find that very helpful. I find that it gets in the way, so I uncheck that.
05:52Also, up here in General and under Editors and Text Editors, I want to
05:59check, Show line numbers.
06:00I find that very useful, and I think you will too. So now we say OK.
06:05Over here in the Pydev Package Explorer, right-click and say New > Project, and
06:11select Pydev and select Pydev Project and Next.
06:16And under Interpreter, you want to select the Python 3.1 Interpreter, and under
06:21Grammar Version, you want to select 3.0, and make sure it says Python for the
06:26project type, and type in the name of project.
06:29I am going to call this Python 3 Essential Training, and select Finish.
06:35Now I have this project here, and I want to right-click on the project and say,
06:41New > Folder, and the parent folder will already be selected as Python 3
06:45Essential Training, and then select the Advanced button and select Link to folder in the system.
06:51Now I am going to select Browse, and on my desktop, I have my Exercise Files folder.
06:58So you want to select that wherever it is you put yours. I find the desktop to
07:01be very convenient for this.
07:02I am going to press Open.
07:04And so what this will do is this will add my Exercise folders to this Project
07:09folder without actually copying the folder. And so it will be just linked to the
07:14folder, and it will use it in place without making another copy of it.
07:18So I am going to say Finish, and there it is.
07:21Now just open up Chapter 02 and double- click on hello.py. And the first time you
07:28open something up after just installing Eclipse and Pydev and everything, it
07:32might take in a moment, and then there it is. We have our Hello, World!
07:37It's a very simple Python program.
07:39The whole purpose of this program is just as an exercise in getting your
07:43development environment running, so it's exactly what it is designed for.
07:46So when I select Run, it will ask me to Run As, and I will select Python Run,
07:52and say OK, and there we have it. There is our result: Hello, World!
07:56So this tells us that Python is installed, that Eclipse is installed, that Pydev
08:01is installed, Python Interpreter is configured within Eclipse and Pydev, and the
08:07entire environment is running.
08:08So now you have a working Eclipse environment where you can follow along with
08:12the exercises and do your own Python development.
Collapse this transcript
4. General Syntax
Creating a main script
00:00As we go through the examples in this course, and as you look at scripts that you
00:04find from different sources, and as you write your own scripts, you are going to
00:08notice a few things that are constant in how these scripts are constructed.
00:14If we look at the syntax.py file here in our 04 Syntax folder in Exercise Files,
00:21you will notice a few things.
00:23First of all, at the very top, there is this line with a Pound sign, which is
00:27the Comment Indicator in Python and an exclamation point and then a path to
00:33the Python Interpreter.
00:35This is used in environments that run the script from a shell, UNIX-based
00:40environments like a Mac or Linux environment, and one of the beauties of a
00:45scripting language like Python is that your script can run in a number of
00:49different environments without change.
00:52So it's important that you leave this as the first line of the file.
00:56Now this path here that starts with the first slash must be the path to
01:01the Python Interpreter.
01:02Now this is a very common path: /user/bin/ python3, that will work in a lot of environments.
01:07If you try to run this in UNIX- based environments and you find that it
01:10doesn't work, one thing that you'll want to look at is this path to see if the
01:15path needs to change.
01:16Another thing that you will notice is this line down here at the end.
01:20What this does is it allows us to run the script with the functions in any
01:25order that we want.
01:27Without this line and without the main execution of the script being inside a
01:33function called main, then you wouldn't be able to run functions that are
01:37defined after the function is called.
01:40In other words, if I put a function in here, and I say def egg():
01:47and print("egg") now I'll need to call the egg here, egg() and save and run,
01:57you will notice that that runs.
02:00Now if I were to take out this def main
02:04and just make this like that without it being in any function at all, and we will
02:10get rid of this, so you might want to just call egg from here and then define
02:17egg down there, that will not work.
02:19That will give us a syntax error because egg is not defined at the point where we call it.
02:24So what this allows us to do is to define functions after they are called, and
02:31this is actually very useful and very common, so you will see this construct in a
02:36lot of the scripts that you encounter.
02:40If we just have it this way, it would serve the same purpose.
02:44The reason for this part of it here is it allows this to only be run when this
02:49file is called as the main module.
02:52Later on in the course, we will get into writing modules, and modules typically
02:57contain classes and functions.
02:59A lot of times when you write a module you are going to want to have a test
03:03suite at the end of the module, and this allows you to put that in a main
03:09function, and it will only run if the module is called as the main module.
03:13It won't run when the module is included in other modules.
03:18So you will see this pattern a lot, and that's basically what it does and what
03:23it's for, and it's just a good idea to always stick it in your scripts.
Collapse this transcript
Understanding whitespace in Python
00:00Whitespace is significant in Python in ways that you may not be accustomed to,
00:04if you are familiar with other scripting languages.
00:08Let's go ahead and make a working copy of syntax.py, and we can look at
00:12whitespace in Python. Call it syntax-whitespace.py.
00:20Go ahead and open that up, and you will notice that this main function consists
00:26of one statement, a print statement, and that print statement is indented four
00:30spaces, ands that actually tells Python that this print statement is associated
00:37with this main function.
00:40It's actually the body of the main function.
00:43Four spaces are traditional in Python.
00:45You can use two. You can use one. It will work just as well.
00:49It does have to be consistent. In other words, if I have more than one line here,
00:54and if that other line is indented, say three spaces instead of four, if I save
01:06that and run it, you will see that I get a syntax error, and it says unindent
01:11does not match any outer indentation level.
01:14So Python got confused. We indented this one four spaces, we indented this one
01:19three spaces and it just got confused.
01:22It didn't know what to do with that. So the indention has to be the same amount.
01:27Save that and run it, and we will see that that works.
01:30Now if I take this second line and I indent it back at the same level as the
01:35function definition, then it is no longer part of the body of that function.
01:40So what will happen when I run this is it will actually see this line, this is
01:44another line, before the syntax file and the reason for that is because that will
01:50get executed on the first pass through here before we call main.
01:53main gets called at the end of the file.
01:56So this line will be printed first and then this line.
02:00So we will save that, and we will run it, and you see this is another line, and
02:05then this is the syntax file.
02:07So, by bringing the indentation out to the same level as the definition, it is
02:13now no longer part of the body of that function.
02:15We will go ahead and indent that again and save it and run it, and we see that it
02:21works as we expect with this second line after the first line.
02:25So indentation as whitespace is significant in Python because Python doesn't use
02:31curly braces, or any other characters, to indicate the body of a function, or what
02:38they a call suite - what we might call a block of code that's - associated with a
02:42particular control structure.
02:43These indents are used for conditionals. They are used for classes.
02:48They are used for any place where you might need to associate a block of text
02:52with a particular control structure.
02:54Now there is one circumstance where the indentation and the whitespace is not
02:59actually significant.
03:00If you have just one line of code in a particular structure - and that's all there
03:06is, there is not more than one line of code - that one line of code can be on the same line
03:11as the control structure itself.
03:13So if I put this print here - and I can put a space, or not put a space, or put several
03:17spaces - it will work exactly the same.
03:19I save this and run it, you see that it still works. Just like this 'if'
03:25statement down here has one line of code, which is the function call for main,
03:30now this function definition for main has just one line of code, the print, and
03:35in this case the whitespace is not significant.
03:37I can have five spaces, I can have one space, and it still runs just the same.
03:42That's a special case for whether its just one line of code in a
03:46particular structure.
03:49Under most circumstances, where you have a function, or a class, or something like
03:53that, and you have more than one line of code, you will see the indentation used,
03:58and four spaces is traditional, and the indentation has to be consistent all the
04:04way through the block or the suite of code.
Collapse this transcript
Commenting code
00:00Comments in Python are quite simple. Let's take a look.
00:05We'll start by making a working copy of comments.py,
00:09and we'll call it comments-working.py.
00:14We'll go ahead and open the working copy.
00:16And here we have a little program that generates a list of prime numbers.
00:21Now, you'll notice that at the top of the file, we have a number of lines that
00:26are introduced by a Pound sign.
00:28I call it a Pound sign some people called the Hash Mark, or that tick-tack-toe-
00:32looking thingie, whatever we call it.
00:35That is the symbol that indicates a comment in Python.
00:39So everything starting with the Pound sign, and all the way to the end of the
00:43line, is ignored by the Python interpreter.
00:46So all these are comments.
00:48You'll notice that we don't have any comments in the rest of the code.
00:51And this is a piece of code that may very well benefit from some comments.
00:56So for example, this line here, I might have a comment that says # generate a
01:07list of prime numbers.
01:10And now when somebody comes back and looks at the code later on he'll, see this:
01:15for n in primes generate a list of prime numbers.
01:17Oh, well I guess that's what that does.
01:20Now, when you're reading comments you want to be careful that you don't just
01:24trust the comment, that you actually look at the code and make sure that the
01:27code actually does what you think it does.
01:29Use the comment as a guideline, but oftentimes as people are writing code they
01:35might put in a comment and then maybe change the code later, forget to change
01:39the comment, or perhaps their terminology is a little bit different than what you're expecting.
01:45So comments are very useful.
01:46The purpose of comments is to make the code more readable by human beings,
01:51because something like this here, I wrote it, so I know what it does, but you're
01:57looking at it and you might say, hmm, what algorithm is he using to generate
02:01these prime numbers?
02:03And so a couple of little comments might make it a lot more readable. For example,
02:07I can say # one is never prime by definition.
02:14And over here I might say # found a divisor, not prime.
02:25And over here, because we have a generator function and a lot of people who
02:31aren't familiar with Python might not know what a generator function is,
02:36I can say, # yield makes this a generator.
02:42And it'll at least give somebody a clue. They can look that up if they don't
02:46know what that means.
02:48So the principle here is to use comments to make the code a little bit more clear.
02:54There is a danger, of course, if you use too many comments, if you comment every
03:00line, or if you comment way too many things.
03:02The comments might become a distraction.
03:04But just keep in mind that the purpose of the comment is to make the code more
03:08clear to somebody who is reading it for the first time and may not be familiar
03:12with the algorithm that you are using.
03:14So comments in Python are introduced by a Pound sign or Hash Mark.
03:19And everything from that Pound sign to the end of the line is ignored by the
03:25interpreter, and therefore considered a comment.
Collapse this transcript
Assigning values
00:00Assignments in Python are handled with the assignment operator, which is the Equal sign.
00:06Let's go ahead and make a working copy of syntax.py.
00:11I'll call it syntax-working.py.
00:14And we'll open that working copy, and we'll go ahead and create an assignment.
00:19So I'll have a variable called a, and I will assign it the value 1.
00:24Now what this does in Python is it actually defines the variable a, and it
00:31creates an integer type variable, and it puts the value 1 in it.
00:37And so in the print statement, I can print a.
00:41And if I go ahead and save this and run it, we'll see that we get the value 1 printed.
00:49If instead I were to put a string there, say "one" spelled out, run that then
00:58we get a one here.
00:59We can look at the type of the variable that was created by using the type function.
01:06And so this will print the type and the value.
01:09Save that and run it.
01:10See that that's a Class String, it's the type.
01:14In fact everything in Python is an object, and objects have classes, and so the
01:19type of a thing is typically the name of the class.
01:24And so if I make this a number again and save that and run it, we'll see that we
01:30get a variable of the <class 'int'>.
01:33So if a variable has not been assigned before, then the assignment operator
01:39actually creates the object.
01:42And it creates it of the appropriate type, or the appropriate class.
01:46You can assign multiple objects at the same time. You can say a, b = 0, 1, and
01:55then if I print(a, b), then I'll get both of those values, the 0 and the 1.
02:03Interestingly, you can even do something like this, where you're actually
02:13swapping these values.
02:14You can use the same variables on the right and the left-hand side of the Equal
02:19sign, and you can pretty much do this safely under most circumstances.
02:23So here we'll get a 1 and 0 when we run this, 1, 0.
02:30There are some types of objects in Python that are sets of values, or sequences
02:35of values, called lists, and tuples, and things like that.
02:39For example, if we say a = (1, 2, 3, 4, 5), by putting them in the parentheses,
02:51this makes this into a tuple.
02:54And if we save this and run it, you see that we get all of those values.
02:58Now, when you use print on an aggregate type, on a set, or a tuple, or something
03:02like that, it actually tries to print it in a form that would be acceptable
03:07syntax in Python for creating that object.
03:11And so for example, another aggregate type is the list, which has square brackets.
03:16And if I define it like that, then the print statement will print it like that.
03:23So the assignment operator is used for assigning a value in Python,
03:30and it will also create an object if that object has not already been created.
Collapse this transcript
Selecting code and values with conditionals
00:00There are two different types of conditionals in Python.
00:03There is conditional execution, and there is conditional values.
00:07Let's take a look at what these look like.
00:09We'll make a working copy of syntax.py, call it syntax-conditionals.py.
00:19Go ahead and open our working copy, and we'll start in here by defining a
00:25couple of variables. We'll just call them a and b, and give them values of 0 and 1.
00:31And then we'll say if a < b, and we'll print a is less than b. We can get rid of this line here.
00:48So what we have here - I'm going to save that - is an assignment for assigning two values,
00:540 and 1, two variables, a and b. And then we're testing if a is less than b, and
00:59so this is a conditional statement.
01:01And it has colon here, and that colon means there is going to be a suite, or a
01:06block of code, that is indented under that level.
01:09And so here we have just a print statement, so that's the only statement in that
01:14suite, and it will only print if a is actually less than b. So if I save this
01:21and run it, we get a is less than b in our result.
01:26If I change this 0 here to a 1, then we will get nothing in our result.
01:32It won't print anything, you see. There's nothing there.
01:35Now, I can handle that exceptional case, and I can say else:
01:41print(a is not less than b), and save that and run it, and now we see a is not
01:50less than b because, in fact a is equal to b. So this is the common if and else
01:57in Python. You also have an else if, which in Python is spelled like this, elif.
02:07And you need another condition, else if a > b, and we'll print a is greater than
02:18b, and then our else. For else, we know that if it's not less than and if it's
02:23not greater than then it is equal, a = b.
02:29So, if we save this and run it, of course we get a = b, and if we make the a a
02:36larger number than the b, and save that and run it, then we get a > b.
02:41So, this is the conditional execution form of conditionals in Python.
02:46We have the if clause, we have the else if, and you can have a string of else
02:50ifs, if you want to.
02:51And we have the else, for if the case where none of the ifs and else ifs
02:56are evaluated to true.
02:59There is another form of conditional in Python, which is the conditional
03:03expression, or the conditional value.
03:06So we'll start with our same assignment (a, b = 0, 1).
03:10We'll say (s = "less than" if a < b else "not less than) and then we'll go
03:23ahead and print(s).
03:27So what this does is this is a conditional expression.
03:32We have a value that's getting assigned only if this condition is true;
03:37otherwise, this other value would be assigned.
03:41You may have seen this in other languages done with question marks and colons,
03:45and the designers of Python felt that that was too obscure and too difficult to
03:50read and decided instead to use syntax that's much easier to read, and in
03:54fact, this is much easier to read.
03:57It's very clear from just looking at this that (s = "less than" if a < b else
04:03"not less than), and otherwise, we'll say "not less than".
04:06Let's go ahead and save it and run it, and we see that we get the word less
04:10than, and if I make this a 1, now it's now less that anymore, and I'll run that,
04:17and it says "not less than".
04:19So that is the conditional value, or the conditional expression in Python.
04:24So Python has two different types of conditionals.
04:26It's got conditional Execution, which is with the traditional if, elif, and else,
04:32and it has conditional expressions, which don't use the question mark and colon
04:38syntax of some other C-based languages, which instead use the same keywords if
04:43and else. It is actually a whole lot easier to read.
Collapse this transcript
Creating and using functions
00:00Functions, or subroutines, are a very common form of reusable code, so let's look
00:06at how functions are done in Python.
00:09We'll make a working copy of syntax.py.
00:12We'll call this syntax-functions.py.
00:18Go ahead and open our working copy.
00:19We'll notice, of course, that main here is a function.
00:24And the purpose of that is not so much reusability as it is modularity in
00:28allowing us to create more functions, and be able to run them from main.
00:33So let's go ahead and create a function here.
00:39And I'll just call it func.
00:42And we'll print out a range of numbers.
00:47
00:52And in my print statement I am going to say end= ' '.
00:57And that way instead of putting each number on a separate line, we'll put them
01:01all in the same line, separated by spaces.
01:03And I'll put another print after it, an empty one to print a new line.
01:09And so I'll save that, and I'll call the function from in main.
01:14And we'll just call it instead of this print function here, we'll just say func.
01:19And that's all we need to do to call our function.
01:21So we'll save it and run.
01:24And we see we are printing out this sequence of 10 numbers.
01:28And this is, in fact, how the range function works.
01:31It prints out everything not including the number of the range.
01:35So it's 10 numbers staring at 0.
01:39Now if I wanted to call the function again, I would just say func again, and I can
01:43do that several times.
01:45And each time it will run this same block of code.
01:48So I save it and I run it, and that's how a function works.
01:53So let's look at how we define the function.
01:55The def keyword is for defining the function.
01:58That means that what comes next is going to be the name of the function, so
02:01there is the name, and then there is a set of parentheses where we would put
02:05arguments, or parameters.
02:07And the colon says that this is going to be followed by a block of code, or a
02:11suite of codes, as it's called in Python.
02:14And then we have the suite of code itself.
02:18The suite of code is indented under the definition of the function, and in this
02:22case of course, we're using the traditional four spaces of indenting, like that.
02:29Inside the parentheses we could put arguments.
02:33So for example, if I put an argument called a there, then I could say a, 10.
02:40So it would start at the number a in its range here, and so here I could use a 1,
02:47and here I could use a 3, and here I could use a 5.
02:50And it would use that as an argument to the range function.
02:54What that does is it defines a starting point for the range.
02:58And so if I save that and run it, then we see we have one that starts with 1, one
03:02that starts with 3, and one that starts with 5.
03:05And so this argument in the parentheses is used inside the function in this way.
03:12We can give the argument a default value by saying a=0.
03:17Well, let's give it something different so we can see. Let's say a=7.
03:22And if in this middle one I don't put an argument, then that will be the default
03:27argument that's used.
03:28It'll default to 7.
03:30So if I save this and run it, you see that the middle one starts at 7.
03:35So there are a lot of other things we can do with functions and with function
03:39arguments, and we'll cover those later in our chapter on functions.
03:42But this is, in a nutshell, how you define a function in Python, and how you
03:47call and use that function, and how you can use arguments when you call and
03:52use that function.
Collapse this transcript
Creating and using objects
00:00Python is fundamentally an object-oriented language.
00:03In fact, in Python 3 everything is an object.
00:08So let's look at how we can create our own objects.
00:11We'll start by making a working copy of syntax.py. I'll call this syntax-objects.py.
00:20And we'll open our working copy.
00:22Now we'll go into a lot more detail on objects later on.
00:25The point here is just to get a handle on the syntax of creating objects.
00:30So we'll go ahead and start by defining a class.
00:34Now a class is the definition that's used when creating an object in Python.
00:39So we'll use the class keyword, and we'll call this class Egg.
00:45And the first thing we'll define inside of the class is a constructor.
00:50And a constructor in Python is a method, or a function inside the class, and has a
00:54special name which is __init__, like that.
01:00And all methods within classes have self as the first argument.
01:05This is a reference to the object itself.
01:08And it's traditionally called self.
01:10It's not required, but it's a really, really good idea to always call it self.
01:14And following self can be arguments that can be used in constructing the object.
01:19And in this case we are going to say how do you want your eggs?
01:22And so it'll be a kind of eggs, and we'll call it kind, and we'll give it a
01:26default value of fried.
01:31And then we will assign this value to an object variable.
01:35And object variables are referenced to the object itself, so we'll say self.kind
01:43= kind, and that will create an object variable that will be carried around and
01:48encapsulated in the object.
01:50And so each instance of this class, each object, can have a different value for kind.
01:57Now let's define a method for finding out what kind.
02:02And we'll call this whatKind, and it has self as the only argument.
02:10And we'll simply return self.kind.
02:14Now we have a class.
02:16It's a very simple class, and it doesn't do anything terribly useful, but it's
02:19good as an example of the syntax of how you create a class.
02:24And now we'll go ahead and create an object.
02:26Now an object is an instance of a class.
02:28You can think of the class as like the blueprint.
02:31This defines how the object is created, and the object itself is an instance.
02:37The object is an encapsulation of all of the methods and the variables that are
02:42inside of the class.
02:44And so we'll say fried = Egg, like that.
02:51And that will create a object called fried, based on the class, Egg.
02:57And you notice we don't have anything in the parentheses, so it will use this
03:00default value when it creates or constructs the object.
03:05The constructor is called every time you create an object.
03:09So here we've created an object with the assignment operator.
03:12And so the first thing it'll do is it'll call this Constructor, and it'll
03:16assign this default value.
03:17We can also create a scrambled egg, like this.
03:23
03:29And so when we print these out, later on we can say print(fried.whatKind()).
03:40And if we save this and run it, it says that it's a fried egg.
03:46Instead of the fried kind, I used the scrambled kind, and this is just this different
03:52object, but it's using exactly the same interface.
03:56If I save it and run it,
03:58now we have a scrambled egg.
04:00So this is just a very simple and a very simplistic example of how an object is created.
04:07We have a definition, which is called a class, and this defines the blueprint of
04:13how these objects are made.
04:14And then we have a couple of objects that are created using that class.
04:21And so these are considered instances of that class, or objects.
04:26And these objects are completely functional, and they contain data, and they
04:31contain code in the form of these methods, and that is how you define and
04:36create objects in Python.
Collapse this transcript
5. Variables, Objects, and Values
Understanding variables and objects in Python
00:00Everything in Python 3 is an object: variables, functions, even code;
00:07all of these things are actually objects.
00:11In Python every object has an ID, a type, and a value.
00:17The id is a unique identifier that identifies a particular instance of an object.
00:22This cannot change for the life of the object.
00:26The type identifies the class of an object, and again this cannot change for
00:31the life of the object.
00:33The value is the contents of the object, including whatever variables, or methods,
00:39or properties the object may have.
00:41Mutable objects can change their value; immutable objects cannot.
00:47Let's take a look in an example of an object. This is idle.
00:51It's the graphical interface of the Python shell.
00:54Python comes with this in graphical environments like Windows and Mac.
01:00And if you are in a non-graphical environment, an environment with just a
01:03command line, you can just run the Python by interpreter with the command line
01:07and you'll get exactly the same interface.
01:10So let's go ahead and create a variable.
01:12For example, let's create an object.
01:14We'll call it x, and we'll assign it the number 42.
01:18So we type x by itself.
01:21The Python shell here will give us the value of x. So that's its value.
01:27Its id is this number, and the size of the number, what the number looks like is
01:33going to be different depending on what your implementation is.
01:36Generally, it's like an address.
01:38It is a unique identifier that identifies this particular object.
01:43And the type of x is class int.
01:47And you remember everything in Python is an object, and so objects have class.
01:52Their type is a class.
01:55And so in this case it's an integer.
01:58All variables in Python are first- class objects, and what that means is that
02:04what might look like a simple variable may actually be something more complex.
02:09It could be an object that's been defined in a library,
02:12it could be a built-in object, it can be any sort of a thing, and it will
02:17oftentimes have attributes and methods, and we'll get into the details of
02:21that later on in the course.
02:23But for now what's important to understand is that everything in Python is an
02:26object, including variables, and as we look at variables and we look at the types
02:31of variables and how we use them, you need to realize that they are objects, and
02:36we'll oftentimes be using syntax like this v.attribute or v.method to access the
02:42attributes and the methods within those objects.
Collapse this transcript
Distinguishing mutable and immutable objects
00:00Objects in Python may be mutable or immutable.
00:04Mutable objects may change value; immutable objects may not.
00:09Some immutable objects at times may look like they are changing their values.
00:13They are not actually changing their values though. The distinction is visible
00:16using the id function.
00:19Integers, container objects, strings, things like these may appear to be
00:24changing values when they are not.
00:26For example, here in the Python shell, we can create an object, and we'll call it x,
00:32and we'll assign a number to it, 42.
00:35Integers are immutable objects in Python, and if we look at the value, we see that it's 42.
00:39If we look at its type, we see that its type is int.
00:44If we look at the id, we see that it has this unique identifier.
00:51Now if I change the value of x, and remember it's an immutable object so I cannot
00:56change the value of an integer, but I assign x = 43,
01:00what I've actually done is I've changed this variable x to refer to a different integer.
01:07Variables in Python are references to objects.
01:10So this reference is now referring to a different object.
01:14If I type id of x, you'll see I get a different identifier.
01:19If I type x, I see that it's 43.
01:21If I assign x back to 42 and take its id, you'll see that this id is now exactly
01:30the same as the one up there.
01:33So I did not actually change the immutable value. I simply changed the variable
01:39to refer to a different object.
01:41This is an important distinction, and it's one that may take a while for you
01:45to get your head around, but we'll cover some of those as we get into this in more detail.
01:49There will be times when something that you want to do, like change the value of
01:54a string or to insert objects in a tuple, you may find that you need to use a
02:00different type, a mutable type instead of an immutable type, in order to be able
02:05to accomplish where it is you are trying to accomplish.
02:08In fact, most fundamental types in Python are immutable. Numbers, strings, and
02:13tuples are the fundamental types that are immutable.
02:17Mutable objects include lists, dictionaries and some other objects, depending
02:21upon their implementation.
02:23So as you create your code in Python, simply be aware that there are some
02:27types that are immutable -
02:29and these are typically the more fundamental types - and other types that are mutable.
02:33And as we get into the details of these types, we'll talk about the things you
02:36can and cannot do with mutable and immutable objects.
Collapse this transcript
Using numbers
00:00There're basically two different kinds of numbers in Python.
00:04Let's go ahead and make a working copy of variables.py,
00:07and we'll look at them, variables-numbers.py.
00:15We'll open our working copy.
00:18And we'll go ahead and define a variable.
00:23And we'll give it a value.
00:26And then we'll print that variable and save and run.
00:32And you see we get that value.
00:35So what we have here is an integer type.
00:39So if I type num and I'll also have num, so we'll get both the type and the value,
00:48we'll go ahead and run that,
00:49and we see that its class is int, and its value is 42.
00:53If I say 42.0, now its type is going to be <class 'float' > 42.0.
01:00So those are the two different kinds of numbers in Python.
01:04You have integers, and you have floating point numbers.
01:08If I take an integer like this, and I say 42/ 9, I'm no longer going to have an integer.
01:15If I save this and run it, we'll see that I have class 'float' and that it is this
01:21real number with a whole lot of digits after the decimal point.
01:25If I want to get an integer division, I can use two slashes instead of one.
01:31And now what I'll get, instead of 4.66666, I will get just 4.
01:37You'll notice that it is not rounded up.
01:41So if I want it to be rounded, I can type round and get back the floating point
01:48division and save that and run it,
01:53and now we have it rounded up. It's a 5.
01:55I can give another argument to round it to how many digits I want it to round to.
01:59I can save that and run it.
02:01And now we have 4.67.
02:04In addition to the integer division with the two slashes, remember it was like this -
02:11if I save that and run it, we get the 4 -
02:14I might also want the remainder, which is also called modulo, and that's with the % sign.
02:22So if I save that and run it, I have 6. That's the remainder after you do that 42/9.
02:29It's 4 with a remainder of 6.
02:34If I have a floating point number, say 42.9, but I want to make sure that
02:41it's actually going to be read as an integer, I can say int of, like this, and
02:47save that and run it,
02:49and I get just the 42 part.
02:52Likewise, if I have an integer number and I want the floating point
02:58representation of it, I can say float like that and save that and run it.
03:04And I actually get a floating point representation of the integer 42.
03:09Float and int are actually object constructors.
03:13These are constructors for those classes.
03:16So when I say float 42, what I'm actually doing is I'm creating an object of
03:20type float, and I'm giving it an initial value of 42.
03:25That's getting passed to the constructor.
03:27So those are the basic ways that you can use and create integers and floating
03:31point numbers in Python 3.
Collapse this transcript
Using strings
00:00Python has some very powerful facilities for working with strings.
00:04And in fact, in Python 3, they become refined, and in some cases even more powerful.
00:10Let's get right into strings, and we'll start by making a working copy of variables.py.
00:16And we can call this variables-strings.py,
00:21go ahead and open that working copy,
00:24and we'll start by defining a String.
00:27I'll just call it s, and I'll say 'This is a string!' and we'll go ahead, and
00:34we'll print(s) and save that and run it.
00:41And there we have the string.
00:42Strings in Python are immutable objects,
00:47and they're created with either single quotes or double quotes.
00:52And so if we change those single quotes to double quotes, we'll see - if we
00:55save and run, we'll see that we get exactly the same result.
01:01You can use Escape characters in a string, as you can in many languages.
01:06So if I put in here a \n, that'll introduce a new line in the middle of the string.
01:12And if I save that and run it, we see that there is a new line now between the a
01:17and the s of string.
01:19On the other hand, if I want this \n to actually be a part of the string, rather
01:24than getting replaced with a new line, I can put the letter r before the
01:29definition of the string like that,
01:32and if I save that and run it, I get the \n as part of the string.
01:37This is called a raw string, and the place where this gets used the most is when
01:42creating regular expressions.
01:44And we'll get into regular expressions in some detail in another chapter.
01:49In addition to these sorts of Escapes with the backslashes, you can also do some
01:55formatting and replacing of variables in the string.
01:59For example, if I create a number and call this, say n, and give it a value of
02:0642, I could put that 42 right in the middle of the string here.
02:12And I'm going to show you the Python 3 way to do this.
02:16And we'll look briefly at the Python 2 way to do it as well, because you'll see that a lot.
02:21For all your new code, you want to use the Python 3 way, which is with the
02:25format method of the string object, because the Python 2 way is going to go away.
02:32It's considered obsolescent, and it will be dropped in the next version of Python.
02:37So I'm going to save this and run.
02:39And you'll see what this does.
02:40This actually inserts the value of n in the middle of the string.
02:46We have these curly braces here, and those get replaced with the format.
02:54So format is a method of the string object.
02:59And so this literal string is actually an object.
03:02Remember, everything in Python is an object.
03:05We can use this objecty-referencing operator, this period, to access a method
03:10of that object, and do this variable replacement.
03:15So this is very powerful, and this is very common.
03:18And you'll see it done this way in new Python 3 code.
03:22In Python 2 code, you'll see it's done this other way.
03:24I'm going to put %s here, and over here a % sign and the letter n. And so we'll
03:36save that and we'll run it.
03:39And you see we get the same result.
03:41This is the way that it was done in Python 2.
03:44And this is a bit of a hack.
03:46It's perfectly valid, and you'll see it a lot.
03:49You'll even see it some in Python 3 code that's written by people who are used
03:53to Python 2, and that's fine.
03:56The reason you don't want to use this construct is because it is considered
04:00obsolescent, and it will be dropped in the next version of Python.
04:05So you'll see this, you want to know what it does, but the right way to do it in
04:10Python 3 is to use the new format method of the string object.
04:20And that will look like this.
04:21I'll save that and run it.
04:23And that's how that works.
04:25There's one more way I want to show you for defining a string, and this is
04:29using the triple quotes.
04:31And you can triple either the single quotes or the double quotes.
04:34So I can either do it this way, or instead of these triple quotes, I can do it
04:42this way with the double quotes, like this.
04:45And you'll see it's done both ways.
04:47I tend to use the singles tripled instead of the doubles tripled.
04:51Now what this does is it allows you to have a string that spans several lines.
04:58And so, what I'll often do is I'll start with a backslash and a new line and go
05:06all the way back to the end of the line like that,
05:09and this will allow me to just have line after line of text and more text,
05:20and to have it actually started at the beginning of it.
05:21I'll explain what this does in a moment.
05:23Let's save this and run.
05:24And then you can see what this does.
05:26This is useful if you have lines and lines and lines of text.
05:30And so the way you do this is with three quotes, either single quotes or double
05:36quotes, at the beginning and the end.
05:37And the result will be a string that has the new lines, and it's all formatted
05:41exactly like you type it in.
05:43What this here does, this backslash and a new line, is that it escapes the new
05:49line, so that it doesn't actually show up in the string.
05:53If I didn't have this, and I save this and run it - that's scrolled out of the way -
06:01there you see that we get a black line at the beginning, because this blank line
06:04here is actually inserted in the string.
06:07The way to get that not to happen is to use the backslash before it.
06:11The backslash has to be the very last character on the line, so that it's escaping
06:15the new line and not a space or something.
06:18So I save that and I run it,
06:20and you can see that we don't have a scrollbar over here.
06:22This is actually at the top,
06:25and there is no new line at the beginning of the string.
06:27So that's the triple quote way of defining strings.
06:31And that's often used in docstrings in function, which we'll get to later on in
06:36the chapter on functions.
Collapse this transcript
Aggregating values with lists and tuples
00:00Python has several sequential types that look like lists of things,
00:05and we're going to look at a few of them right now.
00:07Let's make a working copy of variables.py and we'll call this variables-lists.py.
00:17And we'll open that working copy.
00:19So let's create a variable.
00:21And we'll just call it x. And we'll assign it a list of values in
00:26parentheses (1, 2, 3).
00:29And we'll go ahead and we'll print(x).
00:31What print will do with this is it will try to print it in a way that Python
00:35could actually create one if it needed to.
00:39And so it has it in the parentheses just like that.
00:42So let's print the type of it, also.
00:45Save that and run it.
00:47So the class is tuple.
00:49So this is a tuple.
00:52And a tuple is created with parentheses.
00:54And a tuple is an immutable object.
00:57So I can't insert things.
00:59I can't append things. I can't delete things.
01:01Once I've created it, I've created it.
01:03And I can't change it.
01:05So this is useful for a lot of stuff.
01:07Perhaps you just to operate on a fixed list of things.
01:11In fact, most of time, when you need a list of something, you're probably not
01:16going to need an immutable list.
01:17And to use a tuple is going to be faster than to use immutable list.
01:22On the other hand, if we create this with the square brackets, then we get the list type.
01:27I'll save this and run it.
01:30And the list type is mutable.
01:32I can, in fact, add something to the end of it.
01:35I can say x.append and call it the number 5,
01:40and save that and run it,
01:42and now we have the number 5 at the end. Or I can say x.insert,
01:49and insert it at the beginning, which I use the index 0 for the beginning, and put a 7 there,
01:56and save that and run it,
01:58and now I have a 7 at the beginning.
02:00I could, of course, insert that at any point.
02:03If I say 2, use the number 2 there.
02:08So this is item 0 and this is item 1 and this would be item 2.
02:12And we can expect the 7 to show up in there.
02:14So I'll save it and I'll run it.
02:16And there we have the 7 in there.
02:19So you can actually modify the list that is mutable, but if I were to change
02:25this back to the tuple type, which is immutable, and save it and run it, then I get an error.
02:31That tuple object has no attribute append, and in fact it has no attribute insert
02:37either, because it's immutable.
02:39And it cannot be changed.
02:42So we'll go ahead and we'll take these out.
02:44And I'm going to show you one other sequence type that you've seen before, but
02:48you might not have thought it in this way.
02:51And that is the string.
02:52If I save this and run it,
02:58we'll see that we have a string.
03:00Just like with any sequential type, I can actually look at particular elements
03:04of the string by subscripting it to say 2.
03:07So that will be 0, 1, 2.
03:09I'll just get the r. Save that and run it.
03:13And there's the r. Or I can do what's called a slice.
03:18And we'll learn more about slices later on. I can say 2:4.
03:24And I'll get a slice of just the r and the i. And in slices, it's worth noting
03:29that even though I'm using the 2 index for the beginning, which would be 0, 1, 2,
03:34that's the r, that I'm using the 4 index for the end which would be 2, 3, 4, it would be the n.
03:40The way slices work in Python, they don't actually return that last element.
03:45And there are explanations in the documentation just to why that is.
03:48And we will get more into slices in more detail in a later chapter.
03:52It's also notable that all of these sequence types can be used as iterators.
03:57So if I go back to (1, 2, 3, 4, 5), I have an immutable tuple.
04:08And I'm going to for I in x: print(i).
04:17And so that will print each one on a separate line, each of the
04:21different elements.
04:22And in fact, the string also works like that.
04:26If I put a string in here and save and run, I get each of those individual
04:32letters from the string.
04:34So this is how you use sequences in Python.
04:39There are a number of them.
04:40These are the most common.
04:42The tuple is immutable.
04:44the list is mutable and is designated with the square brackets instead of the
04:48parenthesis for the tuple,
04:51and a string is also a sequence, an immutable sequence.
Collapse this transcript
Creating associative lists with dictionaries
00:00Python has one more very powerful aggregate type.
00:04It's called Dictionary, and it's much like what we would call an associative array
00:09or a hash in another language.
00:12So let's go ahead and make a working copy of variables.py. We'll call this
00:16variables-dictionary.py.
00:24Go ahead and open up that working copy, and we will start by defining a
00:28dictionary, and I will call it d, and when you use the curly brace notation for
00:36defining it, and we will use names for keys and numbers for values.
00:49Just going to put five of them in here, and space that out just a little bit and
01:02then we will - say, we will print it first here, d, and we'll go ahead and
01:07we'll save and run, and you'll see there is our dictionary.
01:11Now, this can be useful for a number of things.
01:15For example, we can step through the keys and print values, for k in d,
01:22and print.
01:26print the key, and we will print the value, which would be d k like this, and if
01:32we save that and run it, you will see that we get each of the keys and each of
01:36the values from our print statement, so we've iterated through the dictionary,
01:41and it's given us the key in the k variable, and we've used that to subscript
01:48and to print out the value.
01:50Now this is nice, but notice that it's in no particular order,
01:55that it's not alphabetical.
01:57It's not numerical.
01:58It's in no particular order whatsoever, and this is common for hashed variables
02:03in virtually all environments that supports such.
02:06So in Python, if you want to get this in assorted order, use the Sorted built-in
02:12function and you subscript the dictionary object and use its keys method.
02:20So sorted(d.keys()) like that, save it and run it,
02:25and now they are in alphabetical order by the keys.
02:28Five, four, one, three, and two.
02:32those are alphabetical by the keys.
02:35Now this particular syntax for defining the dictionary is a little bit
02:40awkward, don't you think?
02:42Wouldn't it be nice if there is a better one? Well there is.
02:46Python has something called keyword arguments, and we will learn about those
02:51more in our chapter on functions.
02:54But the keyword arguments are used to a great advantage in defining dictionary
02:59objects because we can do it like this, say dict using the constructor for the
03:06dictionary class, and I am just going to go ahead and put that closing
03:10parenthesis on a separate line and go ahead and show you how this works.
03:15So I can say one = 1, two = 2.
03:18Notice I don't have to type any of those nasty quotes.
03:22Three = 3, four = 4.
03:26Now if I had string objects that I was using at the values, of course, I would
03:30need quote, so I could say five = and put the number five in quotes, like that.
03:38And if I save this and run it, you will notice that this works exactly the same
03:44way, except we have this spelled out, word five there.
03:47So that's a much easier, more convenient, and a more common way to define a dictionary.
03:53Dictionaries are mutable objects, so I can add a new value to a dictionary, like
03:58this, d 'seven' = 7, and save that, and run it, and now we have the seven value
04:10in the middle there in our sorted list.
04:14So that's dictionaries in a nutshell. They are very powerful and very useful,
04:18and you will see, when we get to our example code, they get used a lot in Python.
Collapse this transcript
Finding the type and identity of a variable
00:00In Python, and especially in Python 3, everything is an object, and an object has identity.
00:08The identity of an object is a unique ID, a unique number, which is specific to
00:15that particular object and no other object.
00:18This can be an important consideration when we are considering things
00:22like immutable objects.
00:24And so Python has an ID function, a built-in function, for finding the
00:28identity of an object.
00:30This is the Python Shell.
00:32It's Idle, which is the graphical interface to the Python Shell in
00:36graphical environments, like Windows and Mac, and some forms of Linux,
00:41they have a graphical shell.
00:42You will have this graphical shell for a Python included with your
00:46Python distribution.
00:48In other environments that don't have a graphical shell,
00:51you will have something the Python command-line interpreter, which if you just
00:55type Python by itself, you will get this same interface.
00:58So we are going to start here by creating an object. I am going to call it 'x',
01:03and I am going to give it a value, 42.
01:07Now when I type x by itself, I'll get the value 42, and if I type ID of x, I
01:14get that object's ID.
01:15So this is the ID of the immutable object, which is the integer 42.
01:22If I type, type of x, I see that its class is int., and so the x itself is
01:30simply a reference to the object, which is of type int
01:35and has the value 42, it has the ID
01:39that is this 505409528.
01:43In fact, if I just type ID of 42, I get exactly that same ID.
01:50And if I type, type of 42, I get class int.
01:54So the number 42 is an object, and that object has ID.
02:00It has type.
02:02It has value, just like any other object.
02:04So if I create another variable and call it 'y', and assign it the value 42, the
02:11ID of y is going to be exactly the same.
02:15Of course, when I test for quality x==y, I'll get true, but I can also test them
02:21for being exactly the same object.
02:24And that's what that 'is' operator, I can say x is y and they are exactly the
02:30same object, because they have the same ID.
02:32The 'is' operator simply compares the IDs, rather than comparing the values.
02:37The double equal sign, which is this one here, compares the values to see if the
02:41values are the same.
02:42The 'is' operator compares the IDs to see if they refer to exactly the same object.
02:49So let's say that I have a mutable dictionary, and I say x = dict, and I'll just
02:57give it (x = 42) and, so I now have a dictionary object, and I say it type of x
03:05and it's a dictionary object, I type x, and I get that which is the dictionary
03:10object and I type ID of x, and it is this.
03:14Now, if I create another dictionary object, and I say y = dict, and I say (x =
03:2142), I give it exactly the same contents, and I say ID of y, I have a different
03:31ID, and this is because a dictionary object is a mutable object, and so there is
03:36no reason - in fact it would make life more difficult if by simply assigning the
03:42same content to a dictionary Python were to give me exactly the same object.
03:47X and Y are still references that point to objects, but these two objects, even
03:53though they have exactly the same value, if I say x, I get that, if I say y get
03:57that. Those are exactly the same value. These are different objects.
04:01So I can test for x == y and I get True. If test for x is y, I get False, because
04:09it's pointing to two different objects.
04:11So these can become important distinctions, and we will see some examples as we
04:15go into our examples of working code in Python.
04:18We will see some examples of where you can use something like this.
04:21But at this point, what's important for you to understand is what ID is.
04:26That ID is a unique ID that refers to a specific object, and how to test for the
04:32quality of ID with 'is' operator to see if two different variables - and remember
04:39variables are referenced objects - to see if two different variables refer to
04:42exactly the same object.
Collapse this transcript
Specifying logical values with True and False
00:00So we are going to talk about the logical values of true and false here, and for
00:04this purpose I have started up the Python Shell, which on the graphical
00:08interfaces will be called Idle, or if you're in a command-line interface, it's
00:13simply the Python interpreter. It gets you exactly the same interface.
00:16So, I'm going to start by creating couple of variables. We'll call them a and b,
00:20and we'll assign them values of zero and 1 a, b - 0, 1.
00:23And I'm going to say a==b, and so the double equal sign is the equality operator.
00:31It tests for equality between two values, and it returns either True or False.
00:35In this case it returns False, and false is actually a keyword in Python, which is a
00:42Boolean value for False.
00:45So, if I say a < b, I will get the Boolean value True, or a > b, I'll get the
00:52Boolean value False.
00:54In fact, you can assign True and False to variables. I can say a = True, and if
01:00I type a by itself, I get True. If I type, type of a, you'll see it is class 'bool'.
01:07So, True and False are objects of class 'bool,' and they are mutable objects of course.
01:13So, if I type id of a, I get an id, and if I assign b = True and type id of b, I
01:21get exactly the same id.
01:23In fact, if I simply type id of True id, I will get that id.
01:29So, true and false are Boolean objects, and they are very simple, and they're
01:34simply used for representing the Boolean values of true and false.
Collapse this transcript
6. Conditionals
Selecting code with if and else conditional statements
00:00Conditional execution in Python is handled with the If statement.
00:06So, let's go ahead and make a working copy of conditionals.py, call it
00:13conditionals-working.py, and we'll Open that up and start by just defining a
00:20couple of variables.
00:22a and b equals 0 and 1.
00:24If we want to just execute some code, if a is less than b, all we do is we type if a < b:
00:33print ('this is true').
00:35Now, when I save that and run it, you see that 'this is true' got printed.
00:42So, this print statement executed, and the way this works is the if keyword
00:46introduces the conditional, and the expression here, a is less than b, and that
00:50could be any expression that evaluates to True or False and a colon introduces
00:56the suite of code and so this could be a suite of code.
00:59It could be a number of things, and that gets executed if this
01:04expression evaluates to true.
01:05If the expression does not evaluate to true - I'll just change this 0 to 1, and a
01:10is no longer less than b, save that and run it - then nothing happens at all.
01:15So, if we want something different to happen, if the expression is false, then I
01:21can simply say else and a colon and another suite of code, it is not True.
01:29So, if I save that and run it, then we get that here it is not true, and if I
01:35make this 1 a 0 again, save and run, then we get 'this is true.'
01:40So, this expression can actually be any expression that evaluates to true or
01:44false, and so I could just actually put the word True there, and it'll be true,
01:51save and run, this is true, or I can put the word False there, and save and run,
01:59and we get, 'it is not true.'
02:01So, that is the if and else in Python.
02:06If is a keyword, and then it's followed by any expression that evaluates true or
02:10false and a colon and then a suite of code, and the optional else will execute
02:16its suite of code, if the condition is false and not true.
Collapse this transcript
Setting multiple choices with elif
00:00If statements in Python can be extended to test multiple conditions using elif.
00:06Let's go ahead and make a working copy of conditionals.py, call it
00:11conditionals-working.py, and we'll go ahead and open our working copy and
00:20define a variable here.
00:22We'll say if v is == to one, print v is one elif v == two, print v is two, and we could do as many of
00:42these as we wanted to.
00:47So, when we save this and run it, you'll notice we get v is one. And if we change this
00:53one to, say, a three, save that and run it, then we get v is three, but if we make
01:00this a seven, then save that and run it, nothing at all happens.
01:07Now, if you want to have a default case, you can simply say, else:
01:12and this still gets executed if none of the conditions turn out to be true.
01:17Say, print v is some other thing,
01:21and save that and run it, and we get V is some
01:24other thing, because v is seven.
01:26So, the thing to understand about this is that only one of these suites is ever
01:32going to be executed.
01:34So, you have if, and an expression that evaluates to true or false, and a colon,
01:40and a suite, and then with each of the elifs, you also have an expression that
01:44evaluates to true or false, and a colon, and a suite.
01:48Only one of these suites is ever going to get executed, and that's the purpose of elif.
01:54It allows you to have several different conditions that get evaluated, and only
01:59one of them will ever get executed.
02:02And then finally, the else clause is executed in the event that none of the
02:07conditions is true, but again, only one of these suites will ever be executed.
02:14
Collapse this transcript
Understanding other strategies for multiple choices
00:00Some languages have a special control structure, called switch, or case, or
00:04something like that, that allows you to select from multiple choices of a single variable.
00:09Python doesn't have one.
00:11So, we're going to take a look at one particular strategy where you can do this
00:16very easily within Python, and you'll see that it's not necessarily a weakness in the language;
00:22it's just different way of looking at things.
00:24So, we'll go ahead and make a working copy of switch.py, call it switch-working.
00:33We'll open our working copy, and we'll start by declaring a dictionary. We'll call it
00:40choices, and we'll just put in a few choices here, one first, two second, three,
00:57and we'll declare a variable and then we'll select based on that variable.
01:08So, when I save this and run it, you'll see that we have selected one and we
01:17printed out first. And if I change this to say three, save that and run it, it'll save third.
01:24So, here we've been able to very easily select based on a number of choices, and
01:29we could make this a very long list if we wanted to, and we can add things,
01:33delete things from the list, and change things in the list, and this will all
01:36work exactly as expected.
01:38The one thing this does not do well is if I select something that's not in the
01:42list, you'll see that we get an error, save that and run it.
01:48Of course, we can trap this error with try and accept, or there is an even
01:53easier way to do this. We can use the get method of the dictionary object,
01:58so you get V comma, and then I can put in a default result, and I can say other.
02:06And so what that does is it looks for V in the dictionary, and if it doesn't find
02:11it, it gives you back this value.
02:12So, if I save that and run it, you can see we get other, because we have seven.
02:17If I put in five, then I'll get fifth. Save and run and there is fifth.
02:24So, this is a very simple way to do what most people use switch statements for
02:29and you'll see some other examples, including an example of executing code based
02:34on multiple choices, later on in the course.
Collapse this transcript
Using the conditional expression
00:00One other type of conditional structure in Python is the
00:03conditional expression.
00:05Let's make a working copy of conditionals.py, conditionals-working.py and we'll
00:12open up that working copy, and we'll go ahead and assign a couple of variables.
00:19Now, a lot of times, all you're doing with a conditional is something like this.
00:26if a is less than b, then V equals this is true, else, V equals this is not true and print v.
00:43You'll see this kind of a thing a lot in a lot of different languages.
00:46We save that and run it, say this is true, and if the condition is
00:53otherwise, save and run.
00:55It says this is not true.
00:58So, in Python, there's a much, much easier way to do this.
01:01You can simply say v equals this is true if a is less than b, else, this is not
01:10true, And so that takes all
01:13of this, and it basically puts it in an expression.
01:17So delete that, and I save and run, and we get exactly the same results.
01:24Make that a 0 and it'll say this is true, and this is true.
01:30So, all we've done here is we've taken that whole if-else structure and we put
01:35it in an expression.
01:36And Python has several of these, and we'll cover these throughout the course,
01:40but it's a convenient shorthand, and you'll notice that it even reads well.
01:44v equals this is true if a is less than b, else, this is not true
01:48And so this part here is what makes it a conditional expression.
01:54You have if, and you have the expression that evaluates true or false, and else,
02:00and then a second value.
02:01So, without all of this, you would simply have v equals this is true,
02:07and with all of this, you have a conditional expression, this is true or this is not true,
02:12depending on the evaluation of this conditional expression.
02:17So, that's a conditional expression in Python, and it's a very convenient
02:21shorthand for a lot of cases where you would otherwise use four lines of if
02:25and else.
Collapse this transcript
7. Loops
Creating loops with while
00:00The simplest form of a loop in Python is the while loop.
00:04So, let's make a working copy of while.py, while-working.py, and we'll go ahead
00:12and open our working copy there.
00:14The while loop is controlled with the while keyword, which we can see here, and
00:18then there is an expression.
00:21So, the expression gets evaluated, and if the expression is true, then the code
00:25inside the loop, the suite, is executed.
00:29After that code is executed, the expression is evaluated again, and if it's still
00:34true, the code gets executed again.
00:37This continues until the expression is evaluated as false, and then the execution
00:43begins after the while loop.
00:45So, let's go ahead and run this, and there is our Fibonacci series.
00:50So, this expression is b<50, so as long as the result there is <50, the while
00:58loop will continue.
00:59So, if I were to increase this to say 150, save that, and run it, then we get a few
01:05more numbers out there in the Fibonacci series.
01:09So, while is the simplest form of loop in Python, and you can see all it does is
01:14it evaluates this expression.
01:16As long as the expression is true, it executes the code in the while loop, and as
01:21soon as the expression is not true, the loop ends.
01:24So, that's the while loop in Python.
Collapse this transcript
Iterating with for
00:00One of the most common reasons for using a loop in programming is what's
00:04called an iterator.
00:06This is where you need to step through some data structure, taking one object
00:10at a time, and doing something with each of those objects before going back for the next one.
00:15Let's take a look at how this works in Python with the 'for' loop.
00:18We'll make a working copy of for.py, and call it for-working.py, and we'll go ahead
00:26and open that working copy.
00:28Here, we are opening a file with lines of text and reading that file line-by-
00:34line and printing out each line on the screen.
00:37So, let's go ahead and run it and see what it does, and we see that it prints
00:41these lines of text, and there they are.
00:44If we open the file here, lines.txt, we see that it has these five lines of text.
00:48You'll notice that in the file the lines are right next to each other, and in our
00:53result, it's printing a blank line between them.
00:56The reason for that is that the print function prints a blank line after each
01:00object that it prints, and the line itself has a line ending at the end of it.
01:05So, we can make print not to do that by typing end = " " just a empty string. If we
01:11save that and run it, then we get the lines of text, just like we expect them.
01:15So, the readlines method, inside the file object, is what's called an iterator.
01:21What this does is it takes one object at a time from a sequence of objects, and
01:28it returns those, one at a time, in this case into the line variable.
01:32The for loop is designed to work with iterators, so the for keyword introduces
01:37the for loop, and then a variable name, which is used to contain each object in
01:42the iteration, and in keyword introduces the iterator.
01:46So, it reads like for line in iteration or for line in file object readlines, and
01:53then it prints each line, one at a time.
01:56So, this here, this file object, .readlines, is the iterator.
02:01In Python, all the container types are iterators.
02:05So, if I have a list, let's say 1, 2, 3, 4, 5, then it will work exactly the same.
02:13It will just print 1, 2, 3, 4, 5 all in one line because we are not ending our
02:16lines with a new line here in the print function.
02:19So, if I save that and run it, we just get 12345.
02:22In fact, a string is a container object, and this will work exactly the same way.
02:29It will just take each letter from the string, and of course that will just look
02:33like the word string.
02:34But instead of we take this out and print them one line at a time, we can
02:38see that we are getting each letter as separate object.
02:42So, the string is a container that contains individual characters.
02:47In this case, we are printing the lines of the file, and the readlines method,
02:55from the file object, is the iterator that gives us one line at a time.
03:00So, if I save this and run it, there we get the lines of the file.
03:04So, that's the for loop.
03:05The for loop is used for stepping through iterators, and virtually all container
03:11types in Python are iterators.
03:14So, you'll see the for loop use a lot.
03:17In fact, in my informal survey of Python code, as I was preparing for this course,
03:23I saw probably 20 or 30 for loops for every while loop that I saw.
03:27The for loop is by far the most common type of a loop in Python because
03:32iteration is such a common thing to need to do, and so many objects in Python are iterators.
03:38So, that's the for loop, and that's how it works for line in readlines, so it's
03:44for variable in container.
03:47Then that variable becomes available to the suite of the loop, and that's how a for
03:52loop works in Python.
Collapse this transcript
Enumerating iterators
00:00For loops in Python are very useful for iterating over container types, and yet
00:05they are significantly different from for loops in other languages.
00:09In particular, for loops in other languages tend to have some sort of an index
00:14variable associated with them, and this can some times be useful. And we don't
00:18have that in the standard for loop in Python.
00:21So, let's take a look at how we can get that very easily using the
00:26enumerate function.
00:27Go ahead and make a working copy of for.py. I'll call it for-working.py and open
00:34that working file, and this is our little readlines example. And if we run this,
00:42You'll notice that we get the lines of text from the lines.txt file, which looks like this.
00:47They have that extra new line in them. We'll go ahead and get rid of that with end=" ".
00:54I am going to add something to this here. I am going to add the enumerate
00:57function, enumerate, and it goes like that.
01:03Enumerate actually returns two values. The first value is an index, and the
01:08second the value is the value from the iterator.
01:11I am going to print the index before the line, and we'll save this and run it, and
01:17you'll see what we get.
01:18So, the index is this extra number over here, and you'll notice that it starts at
01:220, and that's actually a useful place for it because that's how you index
01:26containers in Python.
01:28So, let's take a look at an entirely different example here, and we'll take a
01:32string, and we'll iterate over that string.
01:38We'll use the enumerate function, and we will print the index and the character,
01:48just so you can get an idea of that looks like, save it and run it.
01:52So, here we have - I am going to scroll back up - each position in the string, with
01:56its index number and its character.
01:59Now, let's say that I am just interested in the letter S. So, I want to know
02:05which of these characters are the letter S. I can say if c='s' like that:
02:11print ('index'), number is an S, and I'll do a format I, like this.
02:21That will place the value of the index into this placeholder here.
02:27So, I'll save that, and run it, and now we know index 3 is an s, index 6 is an s
02:33and index 10 is an s. So, counting from 0, 1, 2, 3 there is an S, 4, 5, 6 is
02:41an S, 7, 8, 9 and 10.
02:45So 3, 6 and 10 are the Ss. So, sometime it's necessary to be able to find at what
02:51index, in an array type, a particular value is.
02:55This is a very useful pattern for doing that, and there is actually a lot of uses
02:59for having this index, and enumerate is how you can get that.
03:03So, this is how you get indexes and an iterator with for loop.
03:07Use this pattern here for, index and value and enumerate, which returns those two
03:13values, and the argument to enumerate is the iterator.
03:17Then you have the index and the value available inside your for loop.
Collapse this transcript
Controlling loop flow with break, continue, and else
00:00Sometimes when you are writing a loop you need a way to shortcut the loop, or to
00:04break out of the loop, and Python has controls for this.
00:08Let's go ahead and make a working copy of loopcontrol.py. I'll call this
00:15loopcontrol-working.py and go ahead and open that working copy.
00:19Here, we have a simple loop that prints out each character of a string.
00:23It looks like it's just printing the string, but it's actually doing it one
00:26character at a time in the loop.
00:28I'll go ahead and run this, and you'll see that's what it looks like.
00:31Let's say that we wanted to skip all of the letter Ss. We could simply say if c =='s':
00:38and continue.
00:40What continue does is it shortcuts the loop.
00:43It just goes back to the beginning and gets to the next iteration without doing
00:47whatever comes after it.
00:49If we save this and run, we see that we skip all the Ss.
00:53On the other hand, maybe we want to end at the first s. Maybe we were
00:56just looking for the first s. So, we can use break, and break jumps out of loop entirely.
01:02Let me save this and run it.
01:03That terminates the loop.
01:05It just brings the first 3 characters, and when it gets that first s, it stops entirely.
01:10So, that's break and continue.
01:12Finally, there is one more control in Python.
01:16It's called else, and it works just like else does in an if statement.
01:21If I say else here, and print ('else') and get rid of this break,
01:28what this does is this gets run whenever this condition becomes completely false.
01:33In other words, when the iterator is out of stuff to iterate, then else gets used.
01:38So, if I save this and run it, you see that it prints the entire string and
01:43then it prints else.
01:44And else also works in a while loop - actually all of these controls also work in while loop.
01:50I am just going to show you this one. I am going to do this as a while loop
01:53here, we'll say i= 0 and while (i<len(s)).
02:00We don't have this c here any more. We can say s so i, and then we'll need to increment.
02:06All right, here we go.
02:09So, let's save this and run it, and we see that does exactly the same thing.
02:14So, when this condition becomes false, in other words when we've
02:17incremented past the end of the string, then else gets used, and it prints
02:22the else down there.
02:23So, that's break and continue and else, and these are controls that will break
02:30entirely out of loop.
02:31will shortcut a loop with continue, or else is used when the condition becomes
02:36completely false, or if it's never true in the first place.
02:40So, that's break, continue and else.
Collapse this transcript
8. Operators
Performing simple arithmetic
00:00In this chapter, as we look at operators in Python, we are going to be using the
00:03Python Shell which is called Idle in a graphical environment, or in a text
00:08environment, it's simply the Python Interpreter, run from the command line.
00:12Python has all of the standard arithmetic operators. For example, if you say 5 + 5, you get 10.
00:19If say 5 * 5, you get 25.
00:22If you say 5 - 3, you get 2, and if you say 5 / 3, you get this 1.666.
00:33Python also has some thing that they call floor division, which is simply integer division.
00:37If I say 5 with two slashes divide by three then I get 1, which, of course, has
00:44a remainder as well.
00:46So if I say 5 with a percent sign from modulo and a 3, then I get the remainder.
00:53Python also has a built-in function called divmod that gives the two results together.
00:58So if we say Divmod(5, 3), then you get both of those results together as a tuple.
01:07Finally, Python has increment and decrement operators, and they are not quite the
01:12same as you see in some other scripting languages.
01:14If I say num = 5 and I say num += 1, then look at the value of num; we get 6.
01:25If I Say, num -= 1 and we look at the value of num, then we get 5.
01:32There is also a multiplication and division form of these.
01:36So If I say num *= 5, I get 25.
01:41If I say num floor division equals 5, then I get the integer 5.
01:49Of course if I say num *= 5 again and then num with one slash /=5, then we get the
02:01floating point version 5.0.
02:03So those were the basic arithmetic operators that are available in Python.
02:07It has all the standard ones, and a couple that it's implemented in its
02:12own interesting way.
Collapse this transcript
Operating on bitwise values
00:00Python also has a full set of bitwise operators for operating on binary values,
00:05and occasionally this comes in handy.
00:08It's a little bit difficult to show, because when you print a value, for
00:14example if I just say 5 here, it will print it in decimal.
00:19Even if I specify it in binary,
00:22if I say it 0b0101, which is a five, it still prints it in decimal.
00:29So I am going to write a little one-line function, and I'll call it b for
00:35printing binary values.
00:37I am going to use a format string here, and we'll learn more about those in a later chapter.
00:47The format method of the string, like that, and now when I say b5 like that, it
00:58prints the binary value to 8 places.
01:02That's basically what that format string does inside the curly braces,
01:06the :08b, that prints out a binary value to 8 places.
01:12So now we can look at the binary operators, and we can see what they do on a bitwise level.
01:17So, we are going to define a couple of values, and we will call them x and y. And
01:24x, we'll give it a couple of fives, so that it's 010101 et cetera.
01:30We will do that like this.
01:34And y, we'll do the same thing, but with the opposite bits and that happens to
01:40be xaa in hexadecimal.
01:43So if we look at these values, x looks like that and y looks like that.
01:50So the or of these two values should be x|y, and the vertical bar there is the
01:58or operator.
02:01We will have all the bits set, like that, and the and of the two values, which is
02:07with the ampersand, will have all the bits cleared.
02:13The exclusive or will look just like the or.
02:20So instead, let's take the exclusive or of, say, x and, say, 0 and that will look like that.
02:32Or if we take the exclusive or of x and all the bits on, it will look like
02:39that, because all of the bits get flipped.
02:41We also have shift operators. We can say x shifted left by four bits, and
02:48there we have four clear bits on the right, or we can say x shifted to the right
02:54by four bits, and it clears all the bits to the left.
02:59We have the one's compliment operator which is the unary operator and it just
03:04looks like that, a little tilde.
03:07Since it operates on the word size of the implementation, which is more than
03:12the 8 bits that I am printing, it gets a sign extension, and it ends up looking like that.
03:17So those are the bitwise or binary operators.
03:21The word binary could mean having to do with two values.
03:24So we call them bitwise operators.
03:26Those are the bitwise operators available in Python.
Collapse this transcript
Comparing values
00:00Python also has a complete set of comparison operators.
00:04For example, if I say 5 < 6, I'll get True.
00:11If I say 6 < 5, I'll get False.
00:15Likewise, if I say 5 <= 6, I'll get True, or 5 <= 5, I'll also get True.
00:27It also has greater than or equal to, 6 >= 5 or 6 >= 6.
00:366 is not of course >= 7.
00:40And equality is tested with the double equal signs. So 5 == 5 is True.
00:47And 5 == 6 is not True.
00:51Then it has a not equal operator. So 6 != 7 is True.
00:59And 6 != 6 is False.
01:03It also has is and is not, and these are for testing id.
01:09So for example, if I have two variables x and y, and we'll assign them values
01:16of 5 and 6.
01:19So the id(x) is that, and the id(y) is that.
01:26So they're not the same.
01:28So if I say x is y, I get False.
01:31If I say x is not y, I get True.
01:37Likewise, if I assign 5 to y, now their ids will be the same.
01:44Id(y) is the same as id(x).
01:49Now x is y. For immutables like integers, the ids are always going to be the
01:56same if the value is the same.
01:57So testing equality and testing id is almost the same thing, but for immutables,
02:03like for example, if I have a list, I say x, y = a list with 5 and another
02:11list with 5,
02:17now they have different ids, id(x) is that and id(y),
02:25you can see that they have two different ids now, even know their values are the same.
02:29So if I test x = y, it's True,
02:32but if I test x is y, it is now not True, because they have different ids.
02:37They're actually different objects.
02:40So those are the comparison operators in Python.
02:43You can compare values, and you can also compare ids with is and is not.
02:48So when would I want to compare ids?
02:51Because Python is fundamental an object-oriented language, everything in
02:55Python is an object.
02:58And because Python, of course, supports polymorphism there's going to be times
03:02when you're going to be using objects.
03:05You may need to know is this exactly the same object as this other object over there?
03:10Which object is it that I'm dealing with? And you can't know which is by testing value.
03:15So this is a time when you might want to use is and is not to test for the
03:20identity of the object rather than just testing the value of the object.
03:24So those are Python's comparison operators.
03:27Of course, you can compare value, as well as comparing identity.
Collapse this transcript
Operating on Boolean values
00:00Boolean values in Python are the special True and False objects.
00:06So if I say 5 == 5, I get the True value back.
00:13And if I say 7 < 5, I get the False value back.
00:18So True and False are special values. They're actually of a Boolean class.
00:24If I say, type(True) <class 'bool'>.
00:28And we have a couple of operators for dealing especially with Boolean values.
00:33So if I say True and False, like that, I get False.
00:38If I say True and True, I get True.
00:42If I say True or False, that's True.
00:46If I say False or False, that's False.
00:51So the and, and the or operators, the ones that are spelled out as words, are
00:57especially Boolean operators.
01:00These are different then the bitwise, and, or.
01:04So if I say True & True, like this, I get True.
01:11The difference is that's a bitwise operator.
01:14I'm doing bitwise arithmetic, as opposed to simply Boolean arithmetic.
01:21I'm doing bitwise arithmetic, which is different then the Boolean operators.
01:25So the Boolean operators are and and or spelled out.
01:30And they're useful for things like this. If I have,
01:32say, two values a, b and they're 0, 1, and if I have another two values x, y and
01:42they're spelled out say 'zero', 'one',
01:45and I say x < y, which of course is False,
01:52and a < b, which of course is True,
01:55so I could say, if I wanted to, if a < b and x < y, of course, that won't be
02:05True print('yes') else:
02:10print('no') and it prints no.
02:17And so here I'm combining these two Boolean values. a < b, will result in a
02:23Boolean value of True. x < y results in a Boolean value of False.
02:29And so if they're both True, which they're not, we would print('yes').
02:33And if they're not both True then we'll print('no').
02:36So this is where you use the Boolean operators.
02:39You use them when you're operating on two Boolean values.
02:42And you're get these Boolean values typically in a comparison operation, like
02:47less than, or greater than, or one of the comparison operators that we covered in
02:52our movie on comparison operators.
02:54So that's the use of the Boolean operators, as opposed to the bitwise operators.
Collapse this transcript
Operating on parts of a container with the slice operator
00:00Slices are Python terminology for parts of a container.
00:05So as an example, let's go ahead and set up a container here, call it list,
00:12and we'll use the mutable list type, and we'll go ahead and assign it a bunch of values here.
00:25Now the interesting thing to note about this is that the first element of
00:29the list is at index 0.
00:32So if I say list sub 0, and you get the number 1.
00:35Of I say sub 1, we are going to get the number 2.
00:40So it's important to note that the subscripts of container objects in
00:45Python are 0-based.
00:48That means that the first item is number 0, the second item is number 1, the
00:51third item is number 2, and on like that.
00:54So we have 10 items here, and they are numbered 0 through 9.
00:57So if I look at list sub 9, we have a number 10.
01:02Also it's interesting to note that if I say, if I want to get items 0 through
01:085 and I use this syntax here, which is called a slice, that is the slice of the first 5 items.
01:16And you'll notice that it gives me 0 through 4, because item number 4 is the
01:22one with a 5 in it.
01:23So when I said list 0 through 5, that actually means list 0 through 5.
01:29But it always gives me everything up to, and not including, the last item.
01:34Now many people find this confusing. I find this confusing.
01:38The reasons for it are well explained in the Python documentation, and it's still
01:43hard to warp your head around.
01:45The thing to remember is that ranges in Python are non-inclusive.
01:51It's like if I use the range object, and I say I want the range of 0 through 10,
02:00and of course it gives it me in that form because it's an iterable.
02:04I have to say 4 i in range of 0 through 10, print i. And it's going to give me
02:120 through 9.
02:16So ranges in Python are non inclusive.
02:20They never include the last item.
02:23And that second argument in the slice is a range.
02:28So if I say list 0 through 10, it's going to give me 0 through 9, which in our
02:35case ends with the number 10. Confusing?
02:38Yes. Understandable?
02:40Yes, it 'sunderstandable.
02:42So let's go ahead and make our list a whole lot bigger.
02:44I am going to use a shorthand here.
02:50That's going to give us 100 items in our list.
02:52And there they are, 0 through 99.
02:56And so if I want to look at item 27, it's going to give me item 27, which in this
03:03case because we used a range for the entire thing actually has a 27 in it.
03:07And that makes it easy for us to deal with our nice, long list.
03:11Okay there is a third argument to this slice operator, which is also optional.
03:16The first one, of course, is the index.
03:19So if I say list sub 27, that's the first one, and that will give me a slice of
03:24just one element at index number 27.
03:28If I say list sub 27:42, this will give me a slice that begins at index 27
03:37and ends at index 42 and is non inclusive, so it actually won't give me that last one.
03:43So I get 27 through 41.
03:45The last one, if I say list sub 27: 42:3, that's going to give me every
03:53third element.
03:56So it starts at 27, and then it gives me 30 and 33 and 36 and 39.
04:02And it does not give me 42, because our range is non-inclusive, so it didn't include 42.
04:09If I had said list sub 27:43:3, then it would have given me that 42 element.
04:18So the slice operator actually has three possible arguments.
04:23The first one is the index, where the slice begins.
04:27And the second one, which is optional, is the index where the slice ends.
04:32If it's omitted, then it simply gives me one element at the index that I
04:37specified in the first argument.
04:39The third argument is the step.
04:41And that indicates how many elements to step over for each iteration, and what
04:46this returns, of course, is an iterator.
04:49So if I were to say 4 i in list sub 27 :43:3 : print i. We get the elements from our results.
05:06Finally, it's important to note that we can actually assign - and that's the reason
05:11that I used a mutable object here for our example -
05:14we can actually assign to the slice.
05:17I can say list sub 27:43:3 =, and I can put something in there.
05:26Let's say 99, 99, 99, 99, 99, 99.
05:32And I can put all 99s in there.
05:36And now when I look at my list, where I used to have a 27, I now have a 99, and I
05:43have a 99 there, and I have a 99 there, and so all of these elements got
05:49replaced with 99s, because you can actually assign to a slice as well as just reading from it.
05:57So slices are incredibly useful.
06:00More often than not, you are going to use just the first two forms of it.
06:05But occasionally, with that third form, you can do some very powerful things,
06:10especially for matrix calculations and any thing that has more than one or tow dimensions.
06:16So that's the slice operator.
06:18It has the three arguments: the start and the stop and the step.
06:23And keep in mind that the stop is non- inclusive, just like ranges in Python are non-inclusive.
06:30So when you specify 43 there as the stop,
06:33you have to realize that you are not going to get a value from that stop compartment.
06:37You are going to get a value from everything up to it but not including it,
06:41because ranges are not inclusive in Python.
06:44And the step argument tells it how often to step, or how many to step over.
06:50So that's the slice operator.
Collapse this transcript
Understanding operator precedence
00:00As you are writing code in Python, there are a lot of opportunities for you to
00:03use various expressions.
00:05And some of these expressions might have a number of operators and a number of factors.
00:09For example, let's say that you have an expression that looks something like
00:13this: 5 * 25 + 14 / 2.
00:19And you might look at an expression like that, maybe you didn't code it
00:22yourself, maybe somebody else did,
00:24and you are looking at some code and you see that and you say, hmm, is that 5
00:29times the sum of 25 + 14, with the result of that divided by 2, or is it 5 times
00:3625 plus the result of 14 divided by 2, or some other combination?
00:43The answer to this question lies in the subject of operator precedence.
00:48When there are a number of different operators in one expression, which
00:52operations get evaluated first?
00:55And the results of that operation would then be used in operating on the other operators.
01:01So in this case, I happened to know, because I looked it up, that multiplication
01:07and division have a higher precedence than addition and subtraction.
01:12And so I know that the first thing that's going to happen is 5 * 25 will be
01:17evaluated, and then 14 / 2 will be evaluated, and those two results will be added
01:24together, giving us the answer of 132, because 5 * 25 is 125, and 14 / 2 is 7.
01:31125 + 7 is 132.
01:36If we want a different result, obviously we could use parenthesis.
01:40We could say 5 * and put in parenthesis here 25 + 14 / 2, and we can get
01:48that different result.
01:50I strongly suggest when you are writing your own code that you use the
01:55parentheses to explicitly say what it is that you mean to say,
01:59that you don't write bare expressions with a lot of different operators like
02:04the first one here in this example, that you just don't do that.
02:08If you are reading other people's code and you see that and you want to know
02:11what it is that they meant or at least what the result is that they got, then
02:15you can refer to the Operator Precedence chart, and I've provided one handy in
02:19your exercise files.
02:21Let's take a look at what operator precedence looks like in Python.
02:24There is no need for you to memorize this, but it's good for you to become
02:27at least familiar with its existence and know where to find it when you need to look it up.
02:32In this chart, you'll see there's three columns: Associativity, Operators, and Description.
02:38Associativity means which way is it evaluated, if you have several of these
02:43things from this column?
02:45So for example, if you have several Boolean or operators, they'll be
02:49evaluated left to right.
02:51If you have several Comparison operators, they'll be evaluated right to left.
02:56More often than not, they are left to right in Python.
02:59The designers of Python have done a really good job of trying to make this stuff
03:03consistent as they possibly can.
03:04And where it's not consistent, it's because it makes better sense that way.
03:08Starting at the top of the list, we have lambda, and then we have or, and, not.
03:13These are the Boolean, or, and, and not.
03:15Then we have all of the Comparison operators lumped together in one priority, and
03:20those are evaluated right to left.
03:22And then continuing, there is the Bitwise operators or, exclusive or, and and.
03:29Then there is the Bitwise shift operators, and then we have addition and
03:33subtraction, multiplication, division, and remainder, the Unary operators,
03:38the Exponent operator,
03:40and then bundled together and right to left again slices, function calls, and
03:45attribute references, and then finally, left to right the Binding operator,
03:50which is the parentheses when it's not meant to be a tuple and then tuple,
03:55lists and dictionaries.
03:57So this is operator precedence in Python.
03:59Again, it's much better for you to not rely on this, to use parentheses to
04:05say exactly what it is that you mean to say when you are writing complex expressions.
04:09When you are reading other people's code that have not been that kind to you,
04:13it's good to know that this table exists and where to find it, so that you can
04:17read that code and know exactly how it gets evaluated.
Collapse this transcript
9. Regular Expressions
Using the re module
00:00Regular expressions are a very powerful method for matching patterns in text.
00:05Regular expressions are used for a variety of purposes, from simple search and
00:09replace operations to complex text and data file manipulation.
00:15Regular expressions are actually a small language in itself.
00:17Regular expressions can be very simple or they can be very complex.
00:22Entire books have been written on the subject of regular expressions.
00:26If you are moderately familiar with how they work and what they look like,
00:29you can get a lot of power out of them using Python's regular expression module.
00:33Regular expressions are implemented in Python with the re module.
00:38This is Python's regular expression module and it's distributed with Python.
00:42So if you have Python, you have the re module.
00:45How it works looks like this.
00:48You import re and you compile a pattern and then you use the pattern to search
00:54and replace or to perform whatever manipulations you are going to perform using
00:57the regular expressions.
00:59So let's go ahead and look at how we use regular expressions in Python.
Collapse this transcript
Searching with regular expressions
00:00So let's take a look at how we use regular expressions in Python.
00:04We'll start by making a working copy of regex.py and we'll call
00:08this regex-working.py.
00:13Regex is a common short name for regular expressions, because who wants to say
00:18all those syllables when you can just say regex?
00:21Here we have a very simple program that opens a file called raven.txt, which has
00:27the complete text of Edgar Allan Poe's poem, The Raven.
00:30So we open that file and then we read the file line-by-line and we do a regex
00:38search for anything that matches this pattern here, and this pattern here
00:44basically matches the word Lenore or the word Nevermore, which occur with some
00:49regularity in this poem.
00:50And then it prints them out and you will notice we have end= the blank string,
00:54because we don't want to put a new line at the end of a line that already has a
00:58new line at the end of it.
01:00And so we'll go ahead and run this and there we have the lines that have
01:06Nevermore or Lenore in them.
01:09So searching with regular expressions is done using the re.search method of the
01:16re module and here is our regular expression pattern.
01:21This is a very simple regular expression pattern.
01:23It's beyond the scope of this course to teach you regular expressions, but in a
01:28nutshell what this one does is it's an alternation and so it has the regular
01:34expression alternation operator which you can just call OR.
01:38So anything that has Len or Neverm immediately followed by the letters ore.
01:49So this will match Lenore and it will also match Nevermore and we see in our
01:54results down here that we have lines that have Nevermore, quoth the raven, and
02:00we have lines that have Lenore.
02:03So that's how you do a search using regular expressions in Python.
02:09If you want to, you can just print out the part of this that was matched.
02:13If we take this line here and instead of putting it in the if, we take its
02:19result and call it match, then we get a match object which we can use and this
02:27is some of the beauty of how Python's "everything is an object" helps us out.
02:33We can test match, if we have a match then what we can print here is
02:40match.group(), like that.
02:44So if I save this and run it, now we get all of the words that we actually matched.
02:50Now this can be really useful for simply looking for specific patterns in a set
02:56of text and it can also be used when we look later on for replacing patterns in
03:02text, when we talk about replacing later on in this chapter.
03:06So those are some simple examples of how you use Python's regular expression engine.
Collapse this transcript
Replacing with regular expressions
00:00Let's take a look at how we can do search and replace using regular
00:03expressions in Python.
00:05Start by making a working copy of regex.py. Call it regex-working.py.
00:14We'll open our working copy and here we have our little script that searches for
00:19a particular pattern in a file.
00:21If we run this, you see it finds all the places where either Lenore or Nevermore
00:27is found in Edgar Allan Poe's "The Raven."
00:31So let's do a search and replace instead of just a plain search.
00:35Search and replace in Python is done with re.sub, so we'll change this re.search
00:41to re.sub and we'll use the same pattern there.
00:46And we put in our replacement pattern here. We'll just replace it with some hash
00:51marks and we are going to turn this if into just a print and we'll at the end of that,
00:59we'll put the end= blank like that and we don't need this anymore.
01:05So now, we have re.sub and sub is the search and replace in the regular
01:12expression package in Python and the first argument is the regular
01:15expression pattern itself.
01:17The second argument is what to replace it with when it's found, and then the
01:21string to replace it from.
01:24Now in this case, this will go ahead and print the string even if it doesn't
01:28find any replacement.
01:29So it will print the string either way.
01:31So we'll get the entire file with just those lines replaced.
01:35So I'll save this and run it and we'll go ahead and maximize this and we can see
01:39these places where the hash marks are found. These are places where it found
01:44either Lenore or Nevermore.
01:50So that's the simplest form of a search and replace in Python.
01:54Let's say though that we just want to print the lines where we actually found it
01:57and print those lines with that string replaced.
02:01So one easy way to do that is instead of putting the print here we can do a
02:05search here and get this results of the search with match, hence we use this
02:10search function, just how we learned to do it before.
02:15So search in line like that and then if match, because we only want those lines
02:24whether it's been a match, then we can do a simple string substitution, and
02:29print line and say end= blank like that and we can use the replace method in the
02:41line object itself.
02:44And we have our result in match and it's in the group method and what we replace
02:50it with is the hash marks.
02:52So this is actually doing the search and replace in two separate steps.
02:57The search is being done using the regular expressions and the result is in the match object.
03:02We can test the match object to see if it's true, then it will have a match and
03:07then we can use that match in the string replace method to do the replacement.
03:14So if we save this and run it, so now we get only those lines where the string
03:19was found and we have the replacement in those lines.
03:23So those are a couple of simple ways to use Python's regular expressions module
03:26to do search and replace.
Collapse this transcript
Reusing regular expressions with re.compile
00:00Python's regular expression module has a way that you can pre-compile a regular
00:04expression when you're going to be using it over and over again.
00:07This is an efficiency and it also allows you access to some of its more
00:11advanced functionalities.
00:13So let's go ahead and make a working copy of regex.py, call it regex-working.py.
00:21I will open that working copy up and you'll see here that we have a tight little
00:25loop that's using the same pattern over and over again and it's using it to
00:31search for this pattern, in line after line of text.
00:35So we can get some more efficiency out of this loop by pre-compiling the
00:39regular expression.
00:40So up here we open the file.
00:42We can say pattern = re.compile and then we will come down here and we will
00:51cut and paste our pattern and then when we do the search down here, you can say
00:58pattern like that.
01:00And regular expression module will recognize that that's a pattern object.
01:05That's a precompiled regular expression object.
01:09And we will use that, so when we save this and run it.
01:11You see we get the same result, but it's more efficient because we are simply
01:16compiling that regular expression once rather than otherwise the regular
01:21expression module needs to compile the regular expression each time it uses it
01:25and this is in a tight little loop and we want that loop to be fast.
01:29This also gives us the ability to use some of the regular expression module's
01:33other features like for example, you'll notice in the raven text, the very last
01:40use of the word nevermore, it's not capitalized at the beginning.
01:44And so we don't have this line, "Shall be lifted - nevermore!"
01:48at the end of our results.
01:50So we can tell the regular expression model to ignore case, just by putting in re.IGNORECASE.
01:59And in fact you can use just an I, like that. I like to use the whole thing
02:04because it's more explicit and when I come back to look at it years from now,
02:08after maybe I have not used Python for some reason for a while or not used this
02:14particular feature, I will remember what it means.
02:17So it's something you just need to type out once and so it's worth the extra effort.
02:22So if I save this and run it, now we get that last line as well, because we are
02:26telling the regular expression module to ignore case.
02:30So a number of efficiencies are available if we are using pre-complied
02:34regular expressions.
02:35For example, if I want to do a substitution down here, I can say pattern.sub
02:46comma line, like that and now I have the efficiency of having a
02:51pre-compiled pattern.
02:52I can go ahead and use the regular expression module to do the substitution and
02:56I don't necessarily have to get the result out separately and then use the
03:01string module substitution.
03:03So this allows me to use the regular expression engine for more things
03:08without the inefficiencies of having to compile the pattern over and over and over again.
03:12So if I save this and run it, now we have that same result and it's easier to
03:17read and it flows in with our whole pattern if you're using the regular
03:22expression module and we even have that last line with the lowercase nevermore.
03:28It's still working because the pattern was compiled with the IGNORECASE.
03:32So that's just some of the efficiencies that you can get from using pre-compiled
03:36regular expressions in Python.
03:38It's not hard to do.
03:39I recommend that you do it that way if you're going to be using your regular
03:43expressions in a loop or for any purpose that's more than just once or twice.
Collapse this transcript
10. Exceptions
Learning how exceptions work
00:00Exceptions are Python's key method for handling errors.
00:05Whenever you see one of Python's little error messages, like you've written some
00:09script and you run it for the first time and it dumps you out with stack trace
00:14and an error message, those error messages are simply uncaught exceptions.
00:20You can catch exceptions in Python using try and except.
00:24For example, if you're opening a file and the file name is wrong or you don't
00:29have permissions to open the file or something like that, Python will raise
00:33an IO Error exception.
00:35You can catch the exception like this, using try and except.
00:39Then you can even capture Python's error message, print it, and either continue
00:43with your execution or give a user some intelligible error message or whatever
00:48exactly it is that you want to do with the error.
00:51And then you can use else for conditions where you don't get the error at all,
00:55and it just works the way that you expect it to.
00:57Of course, you can also raise your own exceptions with the raise statement.
01:00You have access to this entire exception handling process. It's built into
01:06Python for your own error conditions in the modules, objects, and functions
01:11that you write yourself.
01:12So let's go ahead and take a look at how Python uses exceptions for its error reporting.
Collapse this transcript
Handling exceptions
00:00Exceptions are a primary method of handling errors in Python.
00:05So let's take a look at how we handle exceptions.
00:07We will make a working copy of exceptions.py, call it exceptions-working.py.
00:15We will open our working copy and here we have a very simple little script
00:19that reads lines of text from a file and there is the text file there and it
00:24prints them on the screen.
00:25Go ahead and we will run this and there is our lines of text.
00:29You'll notice, we did this in different way this time.
00:31Instead of using end = a blank string, ctually using the strip method in
00:36the string itself and that just strips any trailing new lines from the end of the string.
00:41It's another way to do it, using the string method rather than using the print
00:45function to resolve that discrepancy.
00:47Now if I had typed the name wrong or if I am referring to a file that doesn't
00:52exist and I save this and I run it,
00:55you'll notice that we get one of Python's lovely little error messages and it
00:59has the Traceback (most recent call last).
01:02It's doing what it can to help you to find the error in your code and then down
01:06at the bottom here, it says IOError and it has a message.
01:10This IOError before the colon is actually the name of the exception.
01:15That's the exception that's being raised by the Python interpreter and then
01:19after the colon is its error message.
01:22Now I can trap that exception.
01:24And then I could do something different with it in my code.
01:27So here is how I do that.
01:29I use try and I am just going to put that line there in the try and then I use
01:36except like this, and I can print a message.
01:39I can say, "could not open the file."
01:47And then I don't want this to run, so I can put that in the else.
01:52Put the else there and so now what I have, I save this and run it.
01:58I will just get this little message, "could not open the file, come back tomorrow"
02:02and it doesn't try to read the lines in it.
02:05And if the typo is not there, I save that and run it, now I get the actual lines of text.
02:13Now this will actually catch any error at all, because I just said except like that.
02:18If I want to just kept that particular error, I say except IOError, and if I
02:24save that, well let's go ahead and just type this again.
02:28Save that, run it, then I get that error.
02:31So it's sometimes useful to go ahead and let Python give you that error message,
02:36because that's the easy way to find out which error is going to raise.
02:39I can also get the error message itself. I can say as e:
02:44like this and then instead of come back tomorrow, I can give it that error
02:49message like this and then save and run and it says, "Could not open the file:
02:54Error 2 No such file or directory:".
02:56And there we have something it's actually useful for the user.
03:00Now we can actually if we want to, we can put all of this code up here in
03:04the try and it doesn't hurt anything to do it that way and then we don't
03:08need an else clause.
03:09Save that and run it.
03:11We are still getting our error message.
03:12Let's go ahead and cut that out and we see that it works the same way.
03:16So in the event that you have more than one line of code in your try clause,
03:23execution will stop after the error is raised.
03:27So the error gets raised here and then it will go right to handling the error
03:32in the except clause.
03:33So this line won't get run when the exception happens.
03:37So if we have this misspelling in here, you save it and run it, we get the error
03:41message and it doesn't try to use the file handle that it never got, because as
03:46soon as that exception is raised, which happens in this open function, then the
03:51exception clause is run right away.
03:53So you'll see this pattern commonly where a number of lines of code will be put
03:57in a try block and then in fact sometimes there will be several different except
04:02clauses as well, listing out a number of different errors that could be raised.
04:07So this is how exceptions work in Python and this is how you handle exceptions
04:12in your code using try and except.
Collapse this transcript
Raising exceptions
00:00Python uses exceptions as its primary method of handling errors.
00:04We can raise our own exceptions in the functions and modules that we write.
00:08Let's take a look at how we do that.
00:10Make a working copy of exceptions.py, call it exceptions-working.py, and we'll go
00:17ahead and open our working copy, and here we have our simple print the lines of
00:21text from this file. Go ahead and run that.
00:24Now, let's say that we want it to write a function that will open a file and
00:29return its lines of text.
00:31It's pretty easy little function, call it readfile, and we'll pass it a filename
00:39and open(filename), like that, and we'll return the readlines method from the
00:52filehandle and that's actually an Iterator and it allow us to do this. We can
00:59now get rid off that and here we can say readfile lines.text. Save that and run it
01:11and there it works exactly like we expect.
01:14Now, let's say that we misspell lines.text here. We'll get our same error
01:21message that we got before, IOError, and of course we can handle that in a try block like this.
01:40And there we have our error handling, our exception catching,
01:46and there we get our error message like that, but let's say that we have another
01:49condition that we want to raise a different kind of an error for.
01:53We could check the filename for example, using the endswith method of the string
02:00object to see if it ends with .TXT. And in that case, we'll just go ahead and do
02:07what we normally do, an else. We're going to raise an exception.
02:11We're going to use the raise statement, we're going to raise a ValueError and we're going to
02:16give it a little message, "Filename must end with .TXT," all right and then give
02:25it a different kind of a name here.
02:27We save this and run it.
02:30Now, we have an unhandled exception.
02:32We get exactly the same kind of error reporting that Python does when it raises
02:37its own exceptions and we see it gives us the trace back.
02:41It's just an unhandled exception.
02:43That's what Python does with an unhandled exception.
02:46And so, we can handle that exception with a separate except, except ValueError
02:52as e and we can print bad filename and the message.
03:00So now when we save it and run it, we get this nice little error message here.
03:05So that's how we raise an exception in Python.
03:07You'll notice it's very simple. We use the raise keyword and we give it the exception.
03:13Python has predefined a number of exceptions in its library, pretty much
03:19anything you are going to need, and on your screen is the URL where you can find
03:24that list with a lot of descriptions of them.
03:26In this way you don't need to define your own and your programs will work more
03:30consistently with the rest of the Python universe, by using the exception names
03:35that are already defined.
Collapse this transcript
11. Functions
Defining functions
00:00Functions in Python are the primary unit of reusable code, even in objects.
00:07Object methods are simply functions that are properties of the objects.
00:12So let's look at how we define a function.
00:15We'll make a working copy of functions .py, call it functions-working.py and
00:23we'll go ahead and open that up and here we have a very simple function.
00:28It's called testfunc and it has one line of code in it.
00:34So if we run this, we see that that function gets run because it's
00:39getting called from main.
00:41Now, a few things to notice in this file.
00:44First of all, main is getting called down here.
00:48So main is a function just like any other function and it's simply getting
00:53called from the end of the file.
00:55The reason it's getting called from the end of the file is so that it can use
00:58things that are defined after it, like for instance, testfunc.
01:02If instead of calling main from the end of the file, if there is simply a call
01:11to testfunc from the top.
01:13that would not work.
01:14We'll save that and run it and you see we get NameError because name testfunc is
01:18not defined at the point where it was called.
01:23So in order for that to be defined first, we put it in a function and we call
01:29that function from the end. And so that's one of the reasons that we have this
01:33pattern at the end of the file that calls main and then main is defined at the top.
01:42It's also worth noting that we have to have some content in the suite after the colon.
01:49So if this were like this, def testfunc():
01:53like that and save it and run it, we're going to get an error, IndentationError.
01:59So it thinks that I have intended to put this inside the function, which would
02:03not work, because there is no body of the function.
02:06So there has to be something there.
02:09So if you're looking for a way to simply have a stub, if you're outlining some code
02:14and you just want to have a function definition without any body, there is
02:18the pass statement, which is essentially a NOOP.
02:23Save this and run it and now it works just fine, there's nothing happens, but
02:27pass is legal content that doesn't actually do anything.
02:32So you'll see that sometimes when people are working with things or explaining
02:36things or creating a code in Python. It's a placeholder. It's a stub.
02:42It's just there to make it syntactically correct but it doesn't actually do anything.
02:51If I want to pass an argument to my function, I can do that by putting an
02:57argument name here, call it number, and then I can print that out over here.
03:06So if I save this and run it, you see we have This is a test function 42.
03:10So the number is getting passed in during the function call and the number is
03:16getting picked up in this variable, which is defined in the function definition,
03:21and then I can use that in the body of the function itself.
03:25I could have another number and I could even have one more and I could pass
03:31those and I could use them down here.
03:41I save this and run it.
03:43Then we get all of those numbers.
03:45Because these are defined, they must be passed.
03:49If I don't pass all of them and I try to run that, you see I get a TypeError,
03:58testfunc() takes exactly 3 positional arguments (1 given).
04:02You might want to have some optional arguments and you can accomplish this by
04:07giving them default values.
04:12You give them default values by assigning values in the function definition.
04:17So now these arguments are optional and yet they'll still work inside the function.
04:23So if I save that and I run it, you see I've got the 43 and the 75 from in here
04:28and the 42 from there, but if I put a different number up here for the second one
04:33and I save that and I run it, then we get that value.
04:38Then the default value is not used and instead the value passed is used.
04:44The reason for this is that all the function arguments must have values
04:48assigned, so that when that function is called, what happens is predictable, not
04:53just to you the programmer but also to the compiler.
04:57And so they all must be initialized in one way or another.
05:00If you don't want it to have a default value but you still want the parameter to
05:04be optional, then you'll assign it explicitly the value None.
05:08And now when I save this and I run it, I'll have the value 16 there because I
05:13passed it, but now I cannot have that there and I can save it and I run it and
05:19I get the value None.
05:22None is a special value that you can actually test for.
05:26I can say, if another None, it's a singleton object and so identity is a good way
05:35to test for it. print. Or I can assign something to it. I can say another = 112
05:42and now when I save and I run, I get 112 here because I tested for None and
05:49that test was successful. But if I put something in here, 61, let's save that
05:56and run it, then we have the 61.
05:58So function arguments must be initialized in one way or another.
06:03Either they are going to be required or, if you want them to be optional, you
06:07have to assign them default values.
06:09The default value can be none and you can test for none, but it must be
06:14explicitly assigned.
06:16So that's fundamentally how you define a function and how you pass the
06:21arguments in Python.
Collapse this transcript
Using lists of arguments
00:00Sometimes when you're defining a function, you might need an arbitrary number of arguments.
00:06Arguments that aren't necessarily going to be used every time and aren't
00:10necessarily going to even be named, perhaps a list of things.
00:15Python has a facility for this and let's see how that works.
00:19We'll go ahead and make a working copy of functions.py, call it
00:22functions-working.py and we'll open that working copy up and here we have our
00:30little test function.
00:32And let's say that we just want to give it an arbitrary list of arguments and so
00:38that's done simply like that.
00:41The asterisk is special in this place as it means that this is just a list
00:47of optional arguments.
00:49You can have before it-- you can have a named argument or several of them.
00:53you could have this, that and the other, and then after all of that you can have
01:01your optional arguments, and so when you call it you might need to give it some
01:06actual values there and then you could have your arbitrary number of optional
01:13arguments like that.
01:15So if we want to list those, we can just get rid of this text here and say
01:21this, that, and other, and if we save that and run it, you'll notice that we get
01:28the 1, 2 and the 3.
01:30What about these other ones?
01:32If I say args, what I'll get is I'll get a tuple with those values.
01:37Save that and run it and there is our tuple.
01:40So you can see that it's just a normal tuple, as in Python, and so I can use it
01:47as an Iterator if I want to. I can say for n in args like that, print n, end,
01:57equals blank or let's give it a space like that. And I can save it and run it
02:05and now we have our arbitrary arguments after our named arguments.
02:11So, it's good to keep in mind that this is a tuple.
02:14That means that it is immutable, can't add to it or change anything in it, but
02:20it is an excellent way to get an arbitrary list of arguments into a function.
Collapse this transcript
Using named function arguments
00:00Sometimes it's convenient to be able to pass named parameters into a function,
00:06and there is facility for that in Python.
00:08Go head and make a working copy of functions.py and we'll call it functions-working.py
00:18and open that working copy and here we have our little test function.
00:22Sometimes you might want to pass parameters to it and have them look like this.
00:28one=1, two=2, four=42, and so here you are actually passing named
00:37arguments and the caller is naming them rather than the receiver.
00:42So these arguments are not named on the receiving end.
00:45So these are specified with the two asterisks and very commonly called kwargs
00:53for keyword args, keyword arguments, and these are accessed like this.
00:59kwargs is actually a dictionary and so I can say kwargs sub 'one', like that, and
01:09kwargs sub 'two', kwargs sub 'four' and when I save these and run it, you see that we are
01:22getting those values here, 1, 2, and 42.
01:26These keyword arguments can be combined with normal positional arguments, so you
01:32can pass it 5, 6, 7, 8, 9, and 10 and these can be named arguments.
01:43this, that and other and they can even be tuple arguments.
01:50And so what this will do is this will pass the named arguments, these first
01:55three will be this, that, and other, and then these here will be in this tuple
02:01and then you have your named arguments.
02:03The only restriction is that they must actually be specified in this order.
02:08Your named arguments first, your arbitrary tuple arguments after that, and your
02:13keyword argument after that.
02:15Other than that, there is no restriction on the number or even the type of
02:20all these arguments.
02:22So go ahead and take a look at all of those.
02:28We have this, that, and other and we will go ahead and look at the tuple all at
02:34once like that and we will save this and run it.
02:39You see we have them orders 5, 6, 7, there is our tuple, and there is
02:44our keyword arguments.
02:46Now, the keywords arguments, of course, are optional and the names of the
02:51keywords are not necessarily known by the receiver, just like with the tuple.
02:57Let's go head and get rid of all of this and we will look at the
03:03keyword arguments first. For k in kwargs:
03:10print k and kwargsk sub k.
03:15So this will print one per line each of the keyword arguments.
03:18I save this and run it.
03:204, 2, 1 just like with any dictionary.
03:25So if I change these up here, 3 and I have 17 and in fact you see we still have them.
03:37Of course, because it is a dictionary, it's going to come out in no particular order.
03:41But more often than not, you are going to use these keyword arguments
03:45for settings and flags and things like that and you'll test for them in your
03:49function, and you are not going to really be counting on the order in which
03:52they are presented.
03:53On the other hand, the tuple arguments will be presented in the order that they
03:58are passed because they are being passed as a tuple.
04:02So if I say, for n in args:
04:06print(n), and we'll save that and run it, then we get those actually in the order
04:14that they were passed.
04:16So that's how you can pass named arguments to a function.
04:19This is very commonly used for settings and flags and things like that and also,
04:25this is how you can combine them with the arbitrary tuple arguments and with
04:29your normal positional arguments.
Collapse this transcript
Returning values from functions
00:00Functions can be used for a number of purposes and some times those purposes
00:04require the values be returned from the function.
00:07Let's take a look at how we return values from functions in Python.
00:11We start by making a working copy of functions.py.
00:14We will name it functions-working.py and we'll open that up and there we have
00:21our little test function.
00:23How about instead of printing this if we simply return it and then print it from
00:30up here and say print(testfunc())?
00:33So we'll save this and run it and there is our string.
00:40So all this function is doing is it's returning this string.
00:44The return keyword is the way that the values are written.
00:49The value itself comes after Return and it can be any type. We can return a number.
00:58Save that and run it and there is our number.
01:01We can return an object, say range(25), and that will return a range object.
01:10We'll save this and run it. And there is the range object.
01:13In fact, that range object is now usable as an iterator.
01:18So if I say for n in testfunc(): print(n, end=' ').
01:30Save that and run it.
01:32We've got that whole range.
01:34And you'll notice that just like a range is supposed to, it's non-inclusive and
01:38it does not include that last 25th object.
01:44So you can really return any object from a function using the return statement
01:50and that's done simply with return and then the object.
Collapse this transcript
Creating a sequence with a generator function
00:00A generator function is a function that returns an iterator object.
00:05So this is how you create functionality that can be used in a for loop or any
00:11place an iterator is allowable in Python.
00:14So let's go ahead and create a generator object.
00:16We will make a working copy of generator.py, and we'll go ahead and open that up.
00:27And here we have an example of using the range object.
00:31And if we run this, you'll notice that we get our range of numbers up to and
00:35not including the 25, because the range object is naturally noninclusive.
00:43So a lot of times you might want an inclusive range object.
00:47So let's go ahead and create one.
00:49We'll call this inclusive_range, and we'll define a function.
00:56Call it inclusive_range.
01:00And the range object takes three arguments:
01:03start, stop, and step.
01:08And we'll go ahead and say i=start, while i<=stop, and that will make
01:18it inclusive. i+=step.
01:23And then just before we increment, we're going to return, although we're not
01:31going to use return. We're going to yield i.
01:36What that does is it returns I, but because we're using yield instead of
01:41return, the next time the function is called execution will continue right
01:46after the yield statement.
01:48So the next thing that will happen is i will get incremented by step and then
01:54the loop will be tested again.
01:56And then assuming that the loop condition is still true, yield will be called
02:01again and it will yield another iteration in the sequence.
02:06So again, what makes the yield different than return is that as the function
02:11gets called over and over again, each time execution begins right after the
02:16yield and continues as if the function were running continually.
02:21And yield returns each time the next item in the sequence.
02:26So let's go ahead and run this.
02:29In order to run it, we are going to need to give it a start and a step.
02:32So we'll start at 0, and we'll step by 1, and we should get the same sequence,
02:40but including a 25 at the end.
02:42Save it and run it, and there we are, got the same sequence, and there is our 25 at the end.
02:49So that is how yield works and that is how you create a generator.
02:55Let's go ahead and exercise all the techniques we've been learning in this
02:59function chapter and make this function work exactly like range does.
03:05Range can be called with one, two, or three arguments.
03:09If it's called with just one argument, stop is the value that's used and start
03:14is given a default value of 0 and step is given a default value of 1.
03:19But Python doesn't really have a way to do that.
03:22If I give this one here a default value of 0, I say start=0, and I give step a
03:28default value of 1, and I call this with just the 25 by itself.
03:35Save that and run it.
03:37We get this SyntaxError.
03:38Non-default argument follows default argument.
03:43So this is not allowable in Python.
03:46The only way we can really do this is with a tuple.
03:50So let's go ahead and process our arguments.
03:53Let's start by taking a number of arguments, because we are going to different
03:57things with different numbers of arguments.
03:58numargs = the length of tuple, and if numargs<1, we're going to raise an error.
04:17Requires at least one argument.
04:21And then elif numargs == 1, and we'll just set these up, elif numargs == 2,
04:34elif numargs == 3, or else, and we'll raise another error. TypeError, inclusive_range
04:52expected at most 3 arguments, got some number, format (numargs)).
05:06Now I've got this little x here because it's expecting something to be in that suite.
05:12So if there's just one argument, then start is going to be 0 and step is going
05:18to be 1, and we'll go up to the top of the list, and we'll use our argument.
05:23We'll say stop=args0. All right.
05:30And if we have two arguments, then our arguments are start and stop, and we can
05:35assign those like this and give step the default value.
05:41If we have three arguments, and we can assign them all like this.
05:45start, stop, and step=args. All right.
05:51Now, this should work.
05:53Let's save it and see how we are calling it up here? With just the 25 by itself.
06:00So we'll run it, and there we have all 25 numbers, just like we expected.
06:05It works just like range, except it's inclusive and it gives us that last number.
06:10If we have a 5 at the beginning of it, it should give us 5 through 25, there we go.
06:17And if we step by three, let's say, save that and run it.
06:23That's exactly what we expect.
06:26Let's say we have too many arguments. Let's give it some other number.
06:30Now we're going to expect to get this one here.
06:35It's not less than 1. It's not 1.
06:37It's not 2. It's not 3.
06:38It's this something else.
06:40So save that and run it.
06:42And we get inclusive_range expected at most 3 arguments, and got 4.
06:48And let's trigger this error here and give it no arguments at all. Save that and run it.
06:56And requires at least one argument is our error message.
07:01So there we have it. We've duplicated the functionality of the range object.
07:04We've got a function that returns an iterator object and it does exactly what
07:09range does, except that it's inclusive.
07:12And we've accomplished this using the yield statement, which turns our
07:19function into a generator, and the way the yield works is each time yield is run,
07:25it returns the value.
07:27And the next time the function is called, execution picks up from right after the yield.
07:33And this turns the function into a generator and what it generates is an
07:38iterator object, which can be used exactly like any iterator object in Python.
Collapse this transcript
12. Classes
Understanding classes and objects
00:00Classes in Python are how you make objects.
00:04The classes themselves are the blueprint for how an object is created.
00:10For example, here is a class called Duck.
00:12And it implements a couple of methods called quack and walk, so that when you
00:17create a duck object, that duck will quack like a duck and walk like a duck and
00:22that of course will make it a duck.
00:24An object is an instance of a class.
00:27That means that when you create an object, it's a separate thing.
00:31It's separately encapsulated.
00:33It has all of its own attributes.
00:35So if you make several different objects from a given class, each of those
00:40different instance of the class, but they're all separately encapsulated and
00:44have their own data space, their own code space and are essentially their own objects.
00:49An object is an instance of a class.
00:51That means when you create an object, that object is built from the blueprint of
00:56the class, but it's its own object.
00:58Its own encapsulation.
01:00And so if you create several different objects from the same class,
01:03they're separately encapsulated.
01:04They have their own data space and they have their own attributes, and they
01:08operate independently of one another.
01:10So in this case, we've created an object called donald from the Duck class.
01:14And we can say donald.quack and donald.walk.
01:17And donald will quack like a duck and will walk like a duck and therefore is a duck.
01:23Let's take a look at how this works in practice.
01:25So we'll start by making a working copy of classes.py, and we'll call
01:29it classes-working.py.
01:34Go ahead and open that working copy.
01:37And we see we have our Duck class and we have donald.
01:41So if we go ahead and run this, you'll see that donald quacks like a duck and
01:46donald walks like a duck.
01:48So let's take a look at how this works.
01:51Class is the keyword that introduces the definition of a class.
01:55Duck here is the name of the class and then there is a colon, and so because
01:59there is a colon, you have things that are indented under this level.
02:03And those are the suite of the class definition.
02:07And in this case we have two things inside the class.
02:10We have a function called quack and that function, because it has self as its
02:17first argument, is actually a method of the class.
02:22And we'll talk in a moment about how this works.
02:24Then we have walk, which is defined in the same way, and so that's another method.
02:29And then down here, when we create the object donald, we create the object
02:34donald by assigning it from Duck.
02:37And Duck is the class definition.
02:40And so now donald is an object.
02:43And donald is an object of the class Duck.
02:47So if I were to just go here and I were to say print(donald), like that, save
02:53that and run it, then it says <__main__.Duck object at.
02:58And so donald is an object of the class Duck.
03:04So when I call the quack method, I use this dot operator and that dot operator
03:09is the attribute dereference operator.
03:11That means that it's going to look inside the object donald for an
03:15attribute called quack.
03:16And because it has these parentheses on it, it's going to go ahead and call it
03:20as an object method.
03:23And so that will call this code, and it prints this quack, and donald.walk calls
03:28this code, and it prints that "Walks like a duck."
03:32So Duck is the class and that's all this stuff here, and donald is the object.
03:39He's an instance of Duck.
03:42And you can call the methods inside donald.
03:46And so you can call the methods inside the donald object of class Duck
03:50using this dot notation.
03:52So that's how you define a class and create objects based on it in Python.
03:57Python is fundamentally an object-oriented language.
04:00And that means you're going to do this a lot.
04:02There are times when you just have a single thing that you want to do and you
04:05want to do it in a very simple way.
04:09And for that, you'll just create a function and you'll use a function.
04:13Often you're going to want to do things that are more complicated and these
04:16more complicated things are going to have their own local data and they're
04:19going to have multiple methods that are tightly related to each other and
04:25interact with each other.
04:26And these are the times when we're going to go ahead and create a class and use objects.
04:31As you go through the process of writing programs in Python, especially if
04:35you've not worked with an object- oriented language before, you're going to see
04:39more and more cases where objects make sense.
04:44If you're used to using functions a lot, you'll be creating a lot of functions
04:47for things, but over time as you get more familiar with the power and the
04:50flexibility and the encapsulation and inheritance of the different properties of
04:54objects that we're going to go through in this chapter, you're going to use
04:57objects more and more.
04:58And you'll end up using objects for a lot of the things that you used to use
05:02multiple functions for.
05:03So objects are very powerful.
05:05Python is a fundamentally object- oriented language, so you're going to use these
05:09techniques often as you write code in Python.
Collapse this transcript
Using methods
00:00When you're creating objects and classes in Python, you're going to want to get
00:04them some functionality.
00:06That functionality is usually created with methods.
00:09So let's go ahead and make a working copy of classes.py.
00:13We'll call this classes-working.py.
00:18We'll open up that working copy.
00:20You can see that we have a class called Duck and it already has couple of
00:24methods in it, quack and walk.
00:26Those get called down here.
00:28So donald gets created as class Duck.
00:30So this is an object with that class and the object donald.
00:34We're calling the quack method on the object donald and we're calling the walk
00:38method on the object donald.
00:40The calls are done using this dot operator, which is used to reference an
00:46attribute of the object.
00:49In this case, the attribute is a method.
00:51So it's called with the parenthesis and that calls it as you would call a function.
00:57These are actually functions.
00:58It's just that these are functions that are attributes of an object.
01:02That's what makes the methods.
01:04So we'll go ahead and we'll run this, and you'll see that the object gets
01:08created and the methods get called.
01:10It prints out Quaaack!
01:11and it prints out Walks like a duck.
01:13Everything is working like we expected it to.
01:15So methods are actually functions.
01:18You'll see that they're defined just like you define functions in Python.
01:21The difference is these are indented under the class Duck.
01:26So that makes them methods of the class Duck.
01:29You'll also notice that the first argument to these functions is this word self.
01:34That is a reference to the object. Not the class, but the object.
01:39In other words, when quack gets called on the donald object, then the donald
01:44object gets passed to the quack method.
01:48So the quack has a way of referring to object attributes.
01:51You'll also notice that nothing is getting passed inside of these parentheses.
01:56It's as if donald was passed inside those parentheses, but you don't
02:01actually put that there.
02:02That happens automatically by virtue of the dot operator.
02:06When quack gets called as a method of donald, then donald gets passed magically
02:13inside those parentheses, so that it's the first argument to the method.
02:19There's a special type of a method that I want to talk about which is called a constructor.
02:23This gets called every time you create an object based on this class.
02:28The constructor in Python is created by naming a method with two underscores and
02:33the word init and two more underscores at the end.
02:36This creates a constructor method.
02:38So I'm just going to print('constructor') here.
02:42And we'll go ahead and we'll save this and we'll run it.
02:47You'll see that constructor gets printed at the beginning.
02:50So when we run this, the first thing we do is we create the donald object and
02:55that's where the constructor gets called.
02:58In fact, one of the most common purposes for a constructor is to initialize some data.
03:05So if I put in the number 47 here and then I pass in that value in the
03:10constructor, I'll say value here, instead of printing constructor here, I can
03:16save this value, saying self._v = value.
03:22What this does is this creates a local variable that is an attribute of the object.
03:28In this case, the donald object, but if I had different objects with different names,
03:32it would be attributes of those objects.
03:35We'll see how valuable this is in a moment.
03:38Then I can use that value in the methods.
03:42For example, I can print it out here.
03:45I can print it out here.
03:49So now I'm initializing this variable to the number 47.
03:54Each time I use it, I'm going to go ahead and print it out.
03:58So we'll save this and run it.
04:00Now we see that we have a 47 here and a 47 there.
04:04If I were to change this to something else, save it and run it.
04:08We have 52 here and 52 there.
04:10If I create a different object with a different number in it and go ahead and
04:21call it, now when I save that and run it, then we have the donald ducks and we
04:30have the frank ducks.
04:31So the value here is that this self._v is actually attached to the object, not to the class.
04:39This is what's called encapsulation in object oriented programming, because that
04:45value is a part of the object.
04:48So I can have different objects with different values.
04:52I could actually have all kinds of different data associated with those objects.
04:55They could be opening different databases, they could be accessing different
04:59files, they could be keeping their place in these databases and in these files.
05:03This is the power of encapsulation in object oriented programming.
05:07We'll see a lot of examples of that as we move forward, but for now what's
05:10important to know is that all this happens to this self variable right there and right there.
05:16When the object calls a method that self variable gets passed, and that's a
05:21reference to the object.
05:23All the things that are attached to the object, its other methods, its
05:26attributes, its data, is all carried there.
05:29So here we've defined methods in our object.
05:32These methods are defined in exactly the same way that we define a function in
05:37Python except that its first argument is always self and that argument doesn't
05:41get passed explicitly.
05:43It's passed implicitly through the dot operator.
05:46Then we have a special method called init which is used as a constructor.
05:50We can use that to set up data.
05:52We can use it to open databases.
05:54We can use it for all kinds of purposes.
05:57The point of it is to initialize whatever needs to get initialized when you
06:01create the object based on this class.
06:04So that's how you can create a constructor and that's how you create methods in
06:07classes that will be used in objects in Python.
Collapse this transcript
Using object data
00:00Object data is data that gets carried around with the object.
00:04And so when you have several objects, even several objects that are based on the
00:08same class, they can have their own set of data.
00:11Let's take a look at how this is done.
00:13And we'll make a working copy of classes.py.
00:17We'll call this, casses-working.py.
00:21I'll go ahead and open our working copy.
00:24We see that we have our Duck object and the donald instance of the object.
00:28And all of the attributes in this object are code. They are methods.
00:36So let's add some data to the mix.
00:38We'll do this by first creating a constructor by naming a method with two
00:43underscores and the word init and two more underscores.
00:47And we'll pass it a value, call it color and we'll give it a default value of white.
00:53It's always a good idea to give your variables default value, unless they are
00:58absolutely going to be required.
01:00And we'll save that in an object variable.
01:04Object Variable is carried with the object itself.
01:07Remember that self is a reference to the object.
01:10So I say self._color = color.
01:13Now, I named it with an underscore for a couple of reasons.
01:19One reason is that I want to tell myself this is an attribute that I'm using
01:24locally, that I'm not going to be using directly.
01:27In other words, I'm not going to be accessing this variable from outside of the object.
01:32All of the access is going to be done from methods within the object.
01:35And for the most part, unless there's a really overriding reason to access
01:40data outside of the object without a method, then it's a really good idea to
01:45only do it with a method.
01:46Let me show you what I mean.
01:47It I wanted to, I could assign a value to color here. I can say donald._color = 'blue'.
02:00And down here, we'll just get rid of these and we'll print donald._color.
02:08And so, I'll save this and we'll run it and we'll see that it says blue.
02:15And if I print this out twice, we'll see that the first is says white, and then it says blue.
02:23And that's because I've gone and I've changed it here.
02:27And so this is what you call a side effect, and these can be very, very hard to keep track of.
02:33If instead, I just say I'm not going to do it that way at all.
02:38I'm going to do this all through Accessor Methods.
02:40I've a separate method for getting the color and I call this get_color and this
02:46will return self._color.
02:50And then I have another method for setting the color and I'll call this one,
02:55set_color, and I'll say self._color = color.
03:06Now, it's all controlled and I can keep track of it much easier.
03:10And so if I want to print donald's color, I can say print donald.get_color().
03:20Save that and we'll run it.
03:22And if I want to change his color, then I have a method that.
03:26donald.set_color(), and we'll say that their color is blue.
03:35And then we'll go ahead and print it again.
03:39Let's go ahead and save this and run it and see what it does.
03:41You might be saying to yourself, okay so what's the difference? We just made that harder.
03:45But did we actually make it better, and the answer is, yeah we made it better.
03:49The reason that it's better is that now we have code itself has control over
03:54what happens when that gets set.
03:56Let's say when I set their color that I need to save it in a database, or that
04:01I need to do some other things. Maybe it's not just a color, maybe it's some
04:06other controlling configuration thing. Maybe ducks that have blue feathers have
04:11to also have blue feet.
04:12So, when the color gets set, then I know that I've got a method that's going to
04:17also set the color of the feet.
04:19That's what going to also save it in the database or set some attribute some
04:24place else, based on what this change is.
04:26If I'm allowing it to get set just arbitrarily from outside of the object then I
04:32don't have that control.
04:33Then we might end up with the duck that's got blue feathers and green feet and
04:39that would never work.
04:40Bu enforcing this rule, and you'll notice when you read about object oriented
04:45code and when you learn about object oriented techniques, using these accessor
04:50methods is a standard and the reason for that is that it avoids side effects
04:55and avoids the kinds of problems that can happen when you lose control over how
05:00the data is being used.
05:02Remember one of the major advantages of object oriented programming is the encapsulation.
05:07And once you have that encapsulation, then that gives you control, that allows
05:11you to know exactly how your data is being used.
05:13Now the other thing that we'll notice about this is that this does not scale well.
05:20If I want it to be able to set say some other flags, some other values, some
05:24other attributes, that can quickly get out of hand.
05:27If they are more than two or three of these, it would become a real problem to keep track of.
05:32So what we tend to do in Python is to use a dictionary and to use what's
05:38called keyword arguments.
05:40If instead of just setting the color like this, I allow keyword arguments,
05:44kwargs like that and then based on those keyword arguments, I can set the color like this.
05:59That one even allows me to have a default value of white and then when I want to
06:04set it at the beginning, and let's just take these out here and I can say color
06:13equals blue, like that.
06:16Save that and run it and we get blue.
06:18And if I don't pass the argument at all, save that and run it, then we get white.
06:26So this scales. If I wanted to say set feet = 2, I can do that.
06:36Save it and run it.
06:37Of course, I'm not setting the color, but I'm setting another attribute.
06:42And if I wanted, I can have a getter for feet.
06:45The other side of this that doesn't scale well though is that I'm saving the
06:48color in a variable like this.
06:50Again, that could get on unwieldy and it could become difficult to keep track of.
06:54So, I can use a dictionary for that as well.
06:58In fact, I could use a dictionary for all of them and just call these variables
07:05and assign it to kwargs, like that.
07:10And for my set_color and get_color, if I wanted to have separate accessors for
07:15those, I could still do that. I could say variable sub color and assign that to the color.
07:25And I could say variables.get('color') and give it a default value and I like to
07:37use None in a circumstance like this and I can save that.
07:43And when I run it, you'll see that we get None down here.
07:48That just tells me that donald's color has not been set.
07:52But instead of this, we can make one of these that scales as well.
07:55Now, we're really getting into some power here.
07:58We can say set_variable and allow it the name. I'll call that k and then v for
08:07value, self.variables(), so k equals v, and get_variable(self, k).
08:22Return self.variables.get(k, None).
08:30Now instead of get_color, I can say get_variable("color").
08:38Save that and run it. But I've set feet. I haven't set color.
08:42So I can just put feet in here and then I get the number of feet.
08:49So, this allows us scalability.
08:51This allows us, if we wanted to, even after donald has been created, we could
08:56set his color, set_variable("color") to blue, and then down here, I can get his color as well.
09:10And now, we have this flexibility.
09:13We have a very small amount of code that can do a lot of different things.
09:18So, this is a technique that you'll see commonly used in Python where you are
09:23storing your object data in dictionary objects.
09:27It allows you a lot of flexibility.
09:29It allows you to use a lot of different data, a lot of flags, a lot of
09:34attributes, and to do different things with them, to save them to the databases,
09:39to use them as configuration options, and to vary easily be able to set them and
09:45get them and control them.
09:47So, this is one method.
09:49Obviously, it's not the only method and we'll see a lot of examples through out
09:52the rest of this course and different ways to handle object data, but this is in
09:57a nut shell how you use object data with objects and classes in Python.
Collapse this transcript
Understanding inheritance
00:00In object-oriented programming, inheritance is when one class inherits the
00:04properties of another class.
00:06The class that is being inherited from is often called a base class or a parent class.
00:12Let's take a look at how this is done in Python.
00:14We'll start by making a working copy of classes.py, classes-working.py, and
00:22we'll open our working copy.
00:23You notice that we have this Duck class here.
00:27We're going to create another class.
00:29We'll call this one Animal.
00:33So the Animal class will have methods in it that will be inherited by the Duck
00:38class and perhaps other animals as well.
00:41We'll start by saying that an animal makes a sound, so we'll call talk and that
00:47will print 'I have something to say!', and say that the animal moves around.
00:58We'll call that walk, print. 'Hey!
01:01I' 'm walkin'' here!' And then an animal is covered with something, usually fur or
01:14feathers or something. We'll call that clothes.
01:18'I have nice clothes'. [00:01:22.02
01:25All right. So there is our animal.
01:27Now, Duck can inherit all of these methods from Animal, in fact all of its
01:33attributes, by simply saying Animal here.
01:36Putting in a parenthesis in the definition of Duck.
01:41Now, Duck is said to be, is an animal. Duck is a animal.
01:46Object-oriented speak for saying that the Duck inherits the properties of Animal.
01:52So Duck will continue to work the same way that it did before.
01:56If we save this and we run it, we don't really see any difference in how it works.
02:01Except that now it has access to these other properties.
02:04I can say donald.clothes and save that and run it.
02:09And we see donald says he has nice clothes.
02:13You'll notice that walk printed "Walks like a duck."
02:16It did not print "Hey! I'm walkin' here!"
02:19That's because walk in Duck overrides walk in Animal.
02:25The way that works is that Duck inherits Animal and then Duck defines a
02:30method called walk, so it uses this one instead of the one in its parent.
02:36If we wanted to say incorporate the one from its parent, we can do that with the
02:41super function. This is a built-in function which accesses the parent class and
02:48just say, super().walk() like that, and now donald will do both.
02:54Save that and run it, and he says, "Hey! Im walkin here!"
02:57And he says, "Walks like a duck."
02:59So this is how you can access the class in the parent, even though you're
03:04overriding it in the class that inherits from the parent.
03:07So what makes this useful is that now we've defined an animal base class and now
03:13if we want to have another animal, it's very easy for us to do that.
03:16We can say class Dog and it inherits from Animal, and that's really all that we need to define.
03:24We can just say pass here and we can say fido = Dog(), and fido.walk(), and
03:40we have a working dog.
03:42Save that and run it.
03:44And there we have, "Hey! I'm walkin' here!"
03:46And that's from fido.
03:48So obviously a dog, instead of having clothes, he is got fur. So we can say, def
03:57clothes, print, 'I have brown and white fur'.
04:05And then down here if we say fido.clothes(), save that and run it, and it says,
04:12"I have brown and white fur."
04:14But what we've done is we've created a base class that perhaps has all the
04:18properties that are going to be common to the classes that we're creating and
04:23then we simply inherit that and that makes our code very reusable.
04:28You'll see this technique used a lot.
04:30In fact, in an object-oriented language like Python, virtually all of the
04:35classes at some level are inheriting form other classes.
04:39You have two classes like the tuple and the list and they do a lot of
04:44common similar things.
04:46In fact, strings do as well.
04:48And so those are all inheriting from some common classes and simply building
04:53upon that and overwriting some methods and implementing some and not
04:57implementing others.
04:58And that allows them to reuse a lot of code and it also allows them to operate
05:03in a lot of the same contexts as each other.
05:06So this is inheritance and this is how you do inheritance in Python.
Collapse this transcript
Applying polymorphism to classes
00:00Polymorphism is the practice of using one object of one particular class as if
00:06it were another object of another class.
00:09Let's take a look at how this is done in Python.
00:11This is actually something that Python is very good at.
00:14We'll make a working copy of classes.py and we'll call it classes-working.py.
00:21We'll open that and we see we have our Duck class that has quack and walk in it.
00:28And we'll go ahead and create a Dog class and Dog will have bark.
00:43And fur.
00:53The dog has brown and white fur.
01:02Now, we'll go ahead and create a dog object called fido = Dog and fido.bark and fido.fur.
01:18So now we have a Dog object and a Duck object.
01:24And if we go and run this, we see that the Duck quacks and walks like a duck.
01:30And the Dog barks and has brown and white fur.
01:33So these are two separate and distinct objects and they have two separate and
01:38distinct interfaces.
01:40If we want to be able to use them polymorphically, we need to make sure that
01:45they have a common interface.
01:47And so the Duck class, we can give it a bark and a fur and say bark.
01:55print('The duck cannot bark').
02:00And fur, and this one will say "The duck has feathers."
02:11And we can give the Dog, a walk.
02:19print('Walks like a dog').
02:23And quack. The dog cannot quack.
02:34Now, we can use them in the same way.
02:38For example, let's just get rid of all of this, and we have a Dog and we have a Duck.
02:46And if I say for object in and give it a list, donald and fido.
02:56I can say, o.quack(), o.walk(), o.bark(), o.fur().
03:12So what we have here is we're calling all four of these functions for both of these objects.
03:17We're using them in exactly the same way.
03:19We're using them in a way that really does not know or care exactly what type
03:24of an object it is.
03:25It's simply calling these methods without concern for which type of an object,
03:30just assuming that these methods actually exist in there.
03:33So we'll save that and we'll run it and we see our result.
03:37We have the Duck first. Quaaack!
03:39Walks like a duck.
03:40The duck cannot bark.
03:41The duck has feathers.
03:42And then we have the Dog.
03:44And there is all those same methods on the Dog.
03:48So if I had say a function, say in_the_ forest, and it expects a dog and it says,
03:59dog.bark() and dog.fur().
04:10And let's say I had another one that says in_the_pond and it expects a duck.
04:17And it says duck.quack() and it calls duck.walk().
04:25Now, I can call either of these methods with either of these objects.
04:29I can say in_the_forest, and you see the in_the_forest is expecting a dog and
04:34I can pass it donald.
04:35And as long as donald implements the interface that is being used in this
04:42function, it will still work.
04:44Save this and run it.
04:46It says the duck cannot bark and The duck has feathers.
04:50And likewise, if I call in_the_pond and I pass it fido, save that and run it.
05:01The dog cannot quack and it walks like a dog.
05:05So this is what polymorphism is.
05:07And Python is particularly good at this because the objects in Python don't
05:14actually care what the name of the class is.
05:19When you use an object, Python is what's called loosely typed or actually they
05:24call it duck typing, because the types in Python, everything is an object.
05:29And if it walks like a duck, then you can use it like a duck.
05:33That's why they call it duck typing.
05:34It's loosely typed.
05:36When I declare that this in_the_forest function expects a dog, I'm just naming
05:42it dog, but it's an object.
05:44I could name it cat and it would still work exactly the same, because that's
05:51really just a variable name.
05:52That's not a type name at all.
05:53That's no kind of a restriction.
05:55It's just what I'm calling it here.
05:57So I save that and run it.
05:59It still works exactly the same.
06:01So a strong advantage of this loosely typed or what they call duck typing is
06:07that polymorphism is natural.
06:10So I can create a super class that implements all of the things that an animal
06:16normally does, and then I can create subclasses from that with just the specific
06:21attributes of the type of an animal that I'm interfacing, and then anything that
06:26expects any of those interfaces can use it.
06:29Because all of those interfaces are guaranteed to be there.
06:32So I know that that's a big concept to wrap your head around, but think of it
06:36this way. Any object of any class that implements the interface that's expected
06:43by any function can be used by that function.
06:47So when I create a function here called in_the_forest and it expects an object
06:54that can bark and an object that has fur, or a function that expects an object
06:59that can quack and the object that can walk,
07:01any object that implements those methods will work in that function regardless
07:07of what its type is.
07:08And that is polymorphism and that's how it works in Python.
Collapse this transcript
Using generators
00:00A generator object is an object that can be used in the context of an iterable,
00:06like for instance in a for loop.
00:08Let's take a look at how this is done in Python.
00:11We'll make a working copy of generator .py. I'll call it generator-working.py.
00:18We'll open that up and we see that here we have a range object being used in the
00:25context of an iterator.
00:28So o is getting assigned to this range object that's a range of 25 and it's
00:34being used in the context of this for loop which is an iterable context and if
00:39I run this, you see that we get series of numbers from 0 through 24 and this
00:46is how range works.
00:47Range is non-inclusive, which means that we ask for a range of 0 through 25.
00:54What we get 0 through 24, because it's up to but not including the range we specify.
01:01Range takes three possible arguments. It only requires 1 and so those three
01:06possible arguments are the start and the stop and the step.
01:13So we start at 0 and stop at 25 and step by 1, this is the result that we get.
01:21And so start and step default to 0 and 1 and all you have to specify is the stop.
01:28If I were to start it say at 5 and step by say 2, save that and run it,
01:36you will get 5 through 23.
01:38Again, we don't get 25 because it's not inclusive, and you see they are stepping by 2.
01:42So what I would like to do here is create our own range object as an exercise to
01:49learn how to create a generator object in Python.
01:52It will work exactly like this one, except that it will be inclusive.
01:56We'll always get that last number there.
01:58So go ahead and reset this to 25 and we will start creating our class.
02:05So we'll call this class inclusive_ range and it will have a constructor.
02:19And it will have an iterator.
02:27These are both special method names in Python.
02:30Init with the two underscores before and after it are for constructors and iter
02:36like this, with two underscores before it and two underscores after it, makes the
02:40object an iterable object.
02:43So this is where we'll put our generator function in here.
02:46The constructor will need to be able to do this weird thing with the argument.
02:52The first argument and the third argument are optional but the second
02:55argument is required.
02:57That's going to take a little bit of manipulation on our end and we'll do
03:00that in the constructor.
03:01We need this arbitrary list of positional arguments.
03:03So we'll use the list argument syntax here and then asterisk and args and
03:10we'll get the number of arguments by using the length built in.
03:14len(args) like that and if we have less than one argument we are going to
03:21raise an error.
03:26We'll use TypeError requires at least one argument. Let's say if numargs is
03:36less than 1 and we'll use elif numargs == 1, elif numargs == 2.
03:48I like to outline my code like this sometimes and then go back and fill it in.
03:52Numargs = 3 or else we'll raise a TypeError.
04:06Expected at most three arguments and
04:11got this other number.
04:16Now we can go ahead and fill in each of these conditions.
04:20If we get just one argument then we know that's the stop.
04:23So we can say self.stop = args sub 0. Otherwise we have got self.start = 0 and
04:39self.step = 1, because those are those default values.
04:46If we have two arguments and we know that that's the start and the stop.
04:50self.start, self.stop, and we assign that to args and we use our default for step.
05:03Finally, if we have three arguments, then we know that's all of them,
05:07start, stop and step.
05:15So now we have our constructor and our iterator is very easy.
05:20We start by setting the starting point and we have a simple while loop, while i
05:29is less than or equal to a stop, then we yield the result-- and we'll get back to that one--
05:38and we increment the iterator by this step.
05:45So this is what makes it a generator is the yield statement.
05:51Yield works just like return but with the significant difference.
05:54If I were to use return here, it would return the value and the next time the
05:58iterator was called it would start at the beginning of the function.
06:01By using yield instead it returns the value and the next time the function is
06:06called execution picks up right after the yield statement.
06:10So the way this will run is it will set the starting point and it will test
06:15the while loop and assuming that the starting point is less than or equal to
06:20the stop point, it will yield the value. Do that's the starting point and then
06:25the next time the iterator is called, it will increment that value and test
06:30the while loop again, and then it will yield the next value and then it will
06:35increment and we'll yield the next value and this allows it to operate as an iterator.
06:40So by having the yield statement inside the function, that makes the function a
06:46generator and what a generator generates is an iterable object.
06:50We need to change this to our inclusive_range. I have a little typo here.
06:58self.step. Save that and run it and there we have a range all the way up to and
07:06including our stop, and so let's go ahead and test out our constructor.
07:14I'll change the start point to 5 and now it start to 5 and go up to 25.
07:20Save that and run it, and there it, starts at 5 and goes all the way up to 5.
07:26Let's have it step by 2 instead of stepping by 1. Save that and run it.
07:33Now we see it steps by 2. We can change that to 7 and it will still do what we expect.
07:41That's great and now let's call it with no arguments and we'll test our error conditions.
07:47No arguments, we would expect it to get that TypeError and there it is,
07:51TypeError requires at least one argument and if we give it four arguments, let's say
07:551, 25, and 3 and 14, we expect to get this other type error here and there it is,
08:06expected at most three arguments and got four.
08:09So we have successfully duplicated the range generator function, save that and
08:15run it, except that ours is inclusive.
08:18That was really easy to do.
08:19So this is how you make a generator object is by using the iter method in your
08:26class and now your object becomes iterable.
08:30It becomes a generator and when the object is used in the context of an
08:36iterable, like for instance, in this for loop, then that iter methods gets called
08:42automatically and you do not have to do something like .iter.
08:48You can simply use the object in that context.
08:51In fact I don't even have to create an intermediate variable.
08:57So I can take this line out all together and put it in this place here and you
09:02will see that range is used like this very often.
09:06So I can save that and run it and there we have a drop in replacement for
09:12range except that this one is inclusive and that's how you make the generator object in Python.
09:18It's a very convenient and very powerful technique.
09:22You will find yourself using it in some places that you won't anticipate.
09:26I have used it in database applications where I have a very specific database
09:30application with a specific class that simply steps through a particular type of a query.
09:36I have used it in parsing files, where I want to get a certain pattern out of a file.
09:42There is all kinds of applications for this and you will find that you actually
09:45use it more often than you might think.
Collapse this transcript
Using decorators
00:00Decorators are special functions that return other functions and they are used
00:04to modify the way that a function works.
00:07There's a special syntax for using decorators in Python.
00:10Let's take a look at how that works.
00:13Let's make a working copy of decorators.py and we will call it
00:18decorators-working.py and we will open that up, and we will see we have
00:23our Duck example here.
00:26This one has a properties variable that's getting set by the keyword arguments,
00:30and it has a way of setting properties and getting properties.
00:34Down here we have set a property in our constructor and we were getting that
00:38property in this print function.
00:41So if we run this, we see that we are printing out that color.
00:44Now, one of the most common uses for decorators in Python is to create accessor
00:49methods for variables.
00:51For examples, if I wanted special accessors for color, I can define a function
00:57called color and configure it like a getter.
01:02So I'll return self.properties.get ('color') and with a default value of None.
01:11What turns this into an accessor is this decorator function that looks like that.
01:18With an @ sign and the word property, and that turns this into an accessor for
01:24the variable called color.
01:26Then I can create a setter by saying @color.setter and def and I name it exactly
01:37the same thing, color.
01:39This is all special syntax that's designed just for this purpose. I set an argument.
01:45We will call it c and we will set self.properties sub 'color' = c, and now we have our setter.
01:55Finally, color.deLeter, sub 'color' again, and delete self.properties sub 'color' and what
02:12this allows us to do is this.
02:16I can see donald.clolor = 'blue'.
02:21I don't need to initialize it here any more.
02:26So if I save that and run it, we will see that it still works the way that we want it to.
02:31Here I can just say donald.color.
02:34Now, this might look like I went to a lot of trouble to just be able to use a
02:39property that I could have just used without all of this trouble and it would
02:43have set the property in the object, and read the property from the object.
02:48But the beauty here is that now it's under the control of the object. And so if
02:55I wanted to do some thing else in here when I set this.
02:58If I wanted to save it to a database or if I wanted to create a database based
03:04on a filename, which is an example of how I have used this recently.
03:09Then in the deLeter, if I wanted to close the database based on that filename.
03:13So now I can do all of those things, but I still have this convenient syntax.
03:18So this is the most common use of decorators and this is a little bit of the
03:22power of decorators as well, is it they can fundamentally change the behavior of
03:28a function, because here I have got function methods which are operating a
03:33setters and getters, but I am not calling them as functions. I am calling them
03:38in this simple normal properties syntax.
03:41So that's the power of decorators and that's a simple example of how you can use
03:46decorators in your objects.
Collapse this transcript
13. String Methods
Understanding strings as objects
00:00In Python, strings are objects, just like everything is an object.
00:04We are going to take a little bit of time and look at what this means, because
00:08this is not what people are used to who have been programming in other
00:11programming languages.
00:12But in Python, the "everything is an object" paradigm has particular impact on how
00:20we operate on strings.
00:22And also, it's a little bit different than it was in Python 2.
00:25Even though strings were objects in Python 2, they weren't fully first class
00:29objects in the sense that they are in Python 3, and the interface is a lot more
00:33consistent in Python 3, but it also means that it's significantly different
00:37than it was in Python 2.
00:38So if you're familiar with Python 2, this is worth paying attention to just a little bit.
00:42So here we have a string, 'this is a string,' and the value of that of course is a string.
00:50Now, if we assign it to a variable, now we have a variable, and if we just get
00:57the value of that variable, it says, "This is a string."
00:59Now, of course in Python a variable is just a reference to an object.
01:04So I can operate on that string by saying s.upper() and and we get the
01:09uppercase of the string.
01:10And here is the thing that surprises people sometimes is I can do the same
01:14thing just on the string, I can say 'This is a string'.upper(), and that
01:21will give me the uppercase of THIS IS A STRING., because the string itself is an object.
01:26The significant impact here is the use of the format method.
01:30The format method is very often called on an bare string, so to speak.
01:35So it's very common to do something like this in Python.
01:38This is a string and put in a format, and close the quotes, and say .format(42)
01:46like that, and the result will be 'This is a string 42', because what we have
01:51done is we actually operated on the string using the format method, and
01:56replaced the token in the string with the formatted number 42, and this is very common to do.
02:03Older versions of Python, it was common to do something like, 'This is a string
02:08%d' and then use the % operator and say 42 like that, and that worked exactly
02:17the same way, because you weren't using the dot notation to access a method.
02:23Instead it overloading this % operator to do exactly the same thing.
02:28Now, it's worth noting that in Python 3 that % notation is considered
02:33obsolescent, which means that in future versions of Python that will no
02:37longer be supported.
02:38So this is a good time to get used to using the .format method, and in
02:42fact, the format method is a lot more powerful and a lot more consistent in its syntax.
02:48The syntax used in the old percent style string replacement was borrowed from C,
02:53and it's 40 years old, and while it certainly works and it's certainly familiar
02:57to anybody with the background in the C programming language,
02:59it's not as consistent or as powerful as the new format operator in the format language.
03:04So we will be talking more about that in detail later on in this chapter.
03:08For now, what's important to note is that a string is an object and a
03:13variable containing a string is really just a variable that contains a
03:17reference to a string object.
03:18So everything that you can do on that string object, you can do on the string
03:22itself, because the string itself is the string object.
Collapse this transcript
Working with common string methods
00:00The string object in Python supports a lot of standard methods.
00:05We're going to take a look at just some of them here.
00:07We'll start with a string. I'm going to go ahead and put it in a variable and
00:10say s = 'this is a string'.
00:13And notice that's all lowercase, and we just look at the string by itself.
00:17It looks like that.
00:18If I say capitalize(), then we get it with just the first letter capitalized.
00:24I want all the letters capitalized I can say .upper() and there is certainly a
00:28lot of use for that.
00:30Likewise, I can say .lower(). Of course it was all lowercase before, so I had
00:36'THIS IS A STRING' in all uppercase I can say .lower().
00:42And we'll see that we get the lowercase version of that.
00:44We can also say swapcase().
00:47So if I had 'This Is A String,' sort of title case-ish, I say .swapcase().
00:55Then I get it in the opposite case.
00:58If I take our string, which says, 'this is a string' and I want to find a
01:03particular word in it, I can look for it say the word "is."
01:08And we will find it at position 2.
01:10And you might look here and you might say, well, "is" is at position 0, 1, 2, 3,
01:164, 5, but in fact, it found this.
01:21So it's looking for exactly that string.
01:23In the first occurrence of it is the one that get will return.
01:26And so the first letter is 0, the second letter is 1, and then "is" starts at position 2.
01:32We can also do string replace.
01:34I can say s.replace, this for that.
01:40And it'll say 'that is a string'.
01:42Now, it's important to note that the string itself is immutable.
01:45So the string has not changed with these functions do as they return a different string.
01:49And it's an entirely different string object that gets returned.
01:53For example, if I look at the id of (s) I'll see that its id is that number there.
02:00And if I say newstring = s.upper(), I now have a new string which is
02:09the uppercase string.
02:11It's that different string that was returned by the upper() method.
02:15If I look at the id of (newstring), you'll see that it's entirely different than the
02:19id of 'this is a string'.
02:21So there's few more useful ones, there is a strip. I say s.strip().
02:26What strip does is that strips a particular sequence of characters from both
02:30the end of the string and the beginning of the string.
02:33By default what it strips is whitespace.
02:35So if I have a string that says ' this is a string ' like that, with a bunch of
02:40whitespace at the beginning and the end of it,
02:41and I say .strip(),
02:43I'll get back the string without that whitespace at the beginning and the ending of that.
02:47And so where this very commonly used for is removing new lines, but you need to
02:52be aware when you use it for that, that it will also remove any leading space.
02:58If you want to just remove whitespace from the end of string, you can use rstrip().
03:10And that will remove the whitespace from the end of a string and not change
03:14anything at the beginning of the string.
03:15And if you just want to remove a new line, let's say we have a string, I'm going
03:19to put this in a variable because we need it a couple of times, and say s1 =
03:24'This is a string\n' with the newline at the end of it.
03:28I said sting instead of string. That will work.
03:31And there we see we have the string with a newline at the end of it.
03:35If I say s1.strip(), of course, it'll remove the new line.
03:40And that's very useful, but it will also remove any whitespace from the
03:42beginning or the end.
03:43If I just want to remove the new line from the end, I can actually say
03:47s1.rstrip and specify the newline.
03:52So whatever string you specify, parenthesis is what will be stripped.
03:56And there we have it with just a newline taken from just the end of the string.
04:01There's also a set of methods for testing the content of a string really quickly.
04:06We'll look at these. We can say s.isalnum().
04:10And what that is, is that it checks if the string has only
04:13alphanumeric characters in it.
04:14And of course, this is False because it also had spaces in it.
04:17If I have a string that looks like 'thisisastring' and has no spaces in it and I
04:23say .alnum() and it'll come up True.
04:27I must have spelled something wrong. I did. 'thisisastring'.isalnum() and
04:36that comes up True.
04:37So these methods that start with "is," there is a bunch of them. I'm just going to
04:41show you a few. There's isalpha(), 'thisisastring'.isalpha().
04:47And that checks just for alpha characters.
04:50So that would be the letters a-z or other alpha characters in other text
04:56encodings beside just ASCII.
04:58And there is also one for checking if it is digit.
05:01And so if I have a string that's just digits and say isdigit(), that one will
05:06come up True, but if I check s.isdigit() it will of course come up False.
05:12And finally there's isprintable(), which checks to see if all the characters in
05:18the string are printable.
05:20So those are some of most common and most popular methods that are available
05:23for the string class.
Collapse this transcript
Formatting strings with str.format
00:00The string format method is very powerful and useful tool.
00:03You'll see it used a lot and you will use it a lot.
00:06It looks like this.
00:08Let's start by assigning a couple of variables a and b = 5 and 42.
00:12And then we'll print them out.
00:15If I were to just say print a, b like that then we get the numbers.
00:20But that's not terribly useful or descriptive.
00:23And you might want to look at it more like this.
00:26You might want to say this is and put in a placeholder and that is and put in
00:32another placeholder.
00:33And then use the format method and say a and b. And now you get a string,
00:39'this is 5 and that is 42.'
00:42So this is what the format method does.
00:44It allows you to put placeholders in a string and then replace those
00:47placeholders with values and return a new string.
00:51It's important to note that the string that's returned is a new string.
00:56Strings are immutable in Python.
00:57So this string is an entirely different string than that string.
01:02So if I had a string that just had this in it, do a copy and paste here, and say
01:07s = and put that in it.
01:10Now I have that string.
01:11If I just look at s, that's what's in it.
01:13If I say s.format(a, b), I get a new string.
01:19So the id of s is this.
01:22And if I say new = s.format(a, b) and look at the id of that, I have a different id.
01:33Those are two entirely different strings.
01:36So format returns a new string.
01:39It's also important to note that format is new as of Python 3.
01:44Format was not available in Python 2.
01:47In Python 2 things were done differently.
01:49In Python 2 you might have done some thing like this.
01:52this is %d, that %d. And then use a % operator and have a and b.
02:01So this was overloading the % operator and it was using C style format strings.
02:07And we just felt that this is obsolescent, and it needed to be replaced with
02:10something more powerful.
02:11And that's what happened in Python 3.
02:14The format method is more powerful.
02:16It's a more consistent syntax and it's actually a lot easier to use.
02:20One thing in particular that you can note here is that using this old way you
02:25needed to know a type.
02:26This %d represents a decimal type.
02:29And using this new way it uses the repr method, repr, to look at the value and
02:37decide what type it is and print it out based on its type.
02:40So you don't need to know what type the variables are in order to use format.
02:45Another thing worth noting is that this method that we are using here, and this
02:49gets used a lot in this course and you will see it a lot in new code with the
02:53bare curly braces, is actually new in Python 3.1.
02:57In Python 3.0, you needed some sort of a indicator inside of the curly braces,
03:03a positional indicator or a name indicator.
03:06And we'll look at how those work in a moment.
03:08But in Python 3.1 and later, you don't need anything inside of those curly
03:12braces, and it simply takes the positional arguments based on their order.
03:16So if I wanted to print a and b in the opposite order, I would actually have to
03:21put them in the opposite order in the format.
03:23I'd have to change them here, and say b, a and then I will get 42 and 5.
03:32On the other hand if I wanted to, I could say 1 here and 0 here, and not change
03:40their order and it will print them in the opposite order.
03:43So you can specify positional arguments inside the curly braces that will allow you, [00:03:49.1] for example if you wanted to print the same value several times, you could
03:53say, this is 1 and that is {0} and this too is {1}.format(a, b).
04:04And now I am actually getting this 1 value twice and the 0 value once.
04:08So these numbers represent the positional order in which the arguments
04:12are provided to format.
04:14You can also use names.
04:16You can say this is {bob} and that is {fred}.
04:23And then name your arguments in format. bob = a, fred = b and that can be useful.
04:33In fact you could put them in a dictionary d= dictionary, bob = a and fred = b
04:42and then use that dictionary.
04:44'this is {bob} and that is {fred}'.format and you use this double asterisk to
04:51refer to the dictionary.
04:53So format is very powerful in this way.
04:55And in fact, it's an extremely rich language all on its own.
04:59The full documentation for format is available on the Python
05:03documentation website.
05:04And it has all kinds of ways that data can be formatted and ways that you can specify type.
05:10It's an extremely rich language in its own.
05:12And it's actually more powerful and more flexible than the old way of
05:15doing things in Python 2. So that's format.
05:18These are the things about it that are essential to know in order to be able use it.
05:23You can get a lot of power out of it just knowing what I have shown you here.
05:26And in fact, nine times out of ten, this is all you are going to need in order
05:29to use format effectively.
Collapse this transcript
Splitting and joining strings
00:00Splitting and joining strings is a very common operation, especially in text
00:05based environments like the World Wide Web or when you are operating on a lot of text files.
00:09So Python provides some string methods for splitting and joining strings.
00:14Let's take a look at how that works.
00:15We'll take a string. We'll put it in a variable because we are going to be using
00:18it here quite a bit.
00:20And we'll say s = 'This is a string of words.'
00:26And if we want to split that string apart we can just say s.split.
00:31And it'll split the string apart on the white space.
00:34And in fact if there was a lot of white space in between the words, if 'tThis
00:38string was something like this is a string of words' like that .split.
00:47We see that it folds all the white space together first before splitting on the white space.
00:54So that's a very nice and handy thing to do.
00:57If we wanted to split on some other token besides the white space we can specify
01:02it in the split method but it won't do this folding thing.
01:06That folding thing is a special thing that it does just with the white space.
01:09And it only does that if you don't specify an argument to split it all.
01:12For example if I say s.split and I want to split it on say the i characters like that,
01:21then I'll get back a list of the string with all of the i's removed and the
01:25words separated on the i characters and you see the space is still in there.
01:29So let's go ahead and split it on the white space and assign it to a variable.
01:34We'll call the variable words = s.split like that.
01:39And now we have a list words is a list with a bunch of separate words in it.
01:43And it's utterable. I can say for w in words:
01:47print(w) and it'll print those words out separately.
01:51But I can also join them back together if I want to.
01:54I can say new string =, doing it with a colon in it, .join and so the join
02:00method operates on the token that's going to be used to join things back
02:04together not on the list of words.
02:06And so I say join and I say words like this.
02:10And now I have a new string, which is all of those words joined back
02:13together with colons.
02:14Or if I wanted to I could say put a string with a comma and a space in it
02:20and say .join(words).
02:22And I would get back a list of words with a comma and a space.
02:26So I can really put whatever I want to there in the string that I am going to
02:29use to join the words back together.
02:30So in a nutshell that's how we split and join strings in Python.
02:35Again this is a very common operation.
02:37This is something that you'll use quite a bit if you are working with any text files.
02:41If you are working on a World Wide Web, if you are working with mail, if you are
02:43doing any manipulation of text whatsoever.
02:45You are going to find a lot of uses for split and join.
Collapse this transcript
Finding and using standard string methods
00:00Python has an extremely rich set of string methods, over 40 of them last I counted.
00:06What we've covered here are the essential ones.
00:09And I'd like show you how to find the rest of them and how to use them.
00:12It's really quite straightforward.
00:13Here we have the Python documentation page or the Python Standard Library.
00:19And we'll notice this is section 5, Built-in Types.
00:22And down here we see this link of 5.6.1 String Methods.
00:27And here's a complete list of all the string methods.
00:29Like for example, here is this center one.
00:32And we see that center it takes with and an optional fill character and it
00:36returns a centered string of length width.
00:39And padding is done using this specified fill character. Default is a space.
00:43So if I had a string, 'this is a string', and I wanted to center it on say 80
00:50character string, I would simply say new = s.center(80) like that.
00:56And now I have a new string.
00:58And we see that this new string is 80 characters wide.
01:01I can check if I want to. length of new is 80.
01:05And we see that the string from my original string is centered there.
01:09Like I said, there are over 40 of these different methods.
01:12And here's the entire list and they are all very well documented.
01:15It's really simple.
01:16It's not in a terribly technical language.
01:19And so I encourage you to take the time and at least read through this one and
01:23get an idea for what is available.
01:25And then refer to it when you need one.
01:28That makes it really easy for you to have these tools at your disposal without
01:31having to memorize everything, without having to go through a lot of detail on
01:35the ones that you are not going to use very often.
01:37So use the documentation in this case.
01:39There is a great wealth of string methods available.
01:42And I encourage you to become familiar with them and use them.
Collapse this transcript
14. Containers
Creating sequences with tuples and lists
00:00Tuples and lists are the basic array types in Python.
00:04tuples are immutable and lists are mutable.
00:07tuples are created with the comma operator.
00:12Say t = 1, 2, 3, 4, 5 like that, and I get a tuple with those five elements in it.
00:18So, element number 0 is the beginning of the list and element 4 is the end of the list.
00:28Of course, you can always get the end of the list with -1, like that.
00:33I can take the length of the list, I can get the smallest element, I can get the
00:41largest element and so I have a tuple.
00:46There is some confusion about how you create a tuple in Python.
00:49Sometimes it looks like you use the parenthesis to create a tuple, because more
00:53often than not you'll see it done like this to create the tuple, but in fact,
01:01it's the comma operator.
01:03This is the important distinction because if you want to create a tuple with one
01:06element, that won't do it.
01:10That creates an integer.
01:14The comma is required. The parentheses are for binding, and when you have a lot
01:18of elements separated by commas, the parenthesis are convenient for that and
01:21that's why you'll often see it that way.
01:23But in fact, if you want a tuple with one element, you create it like this.
01:31And now, we have a tuple. type(t) is <class 'tuple'>.
01:37Lists are created with square brackets.
01:45Now I have a list. type of x is <class 'list'>.
01:52Lists work very much like tuples in that I can subscript it in the same way or
01:58I can look at the last one and I can check its length and I can get the largest
02:06element and the smallest element.
02:11The difference is, is that I can change things.
02:14If I take my tuple and let's put something bigger in the tuple.
02:24Now I have a tuple with 25 elements in it and that is a tuple.
02:30Let's say that I try to change one of those elements.
02:39I get this error, 'tuple' object does not support item assignment.
02:43Tuples are immutable, so I can't change things in them.
02:47On the other hand if I create a list, I am using the list constructor here to
02:55convert this range into a list and there is my list and type(x) is <class l'ist'>
03:02and I can say x10 = 42.
03:08Now, we see that 42 right there in the list.
03:14So, a list is mutable and a tuple is not mutable.
03:19So, why would you want to use a tuple when you can use a list and the list is
03:22more powerful and has more functionality?
03:25Tuples are there because more often than not, when you them you don't need
03:28to be changing them.
03:29It's a smaller class.
03:31It's simpler to implement, they are faster for some things, but most importantly
03:37they don't allow you to change stuff.
03:39So, if you have a circumstance, and most circumstances are like this, where you
03:44need an object that's always going to stay the same size, it's always going to
03:47have the same data in it,
03:49you want to use a tuple so that you can't accidentally it, and if you do, you'll
03:53get an exception and you'll be able to find your problem.
03:56So, use your tuples where you can, and where you absolutely need to be able to
04:02change your array, that's where you use a list.
Collapse this transcript
Operating on sequences with built-in methods
00:00Tuples and lists are very powerful in Python and there are a lot of operations
00:05that you can perform on them.
00:07Let's go ahead and set up a couple of tuples and lists.
00:11We'll have a tuple we'll call t and we'll initialize it with a range.
00:20So, there is our tuple and we can see type(t) is class tuple.
00:25So, I can check and I can say is there 10 in there. I can say 10 in t and I'll get it True.
00:31If I say 50 in t I get a false.
00:34Of course, you can also use not in. I can say 50 not in t and that will be True.
00:41I can look at a particular entry. I can say well what is that index 10.
00:45I can say t10 like that.
00:49I see because a range was 0 base that at position 10 is the number 10.
00:53Of course, I can look at the length of it and a tuple is iterable.
01:00I can say for i in t and I can print(i).
01:07Likewise, you can do all of these things with lists. x= list(range(20).
01:16I am missing a parenthesis there.
01:18So x is now that list and I can 10 in x and I can get true.
01:24I can 20 in x and will get false because that range was not inclusive and I can
01:31iterate it. I can say for i in x:
01:34print(i) and that's iterable as well.
01:38Of course, one of the major differences is that I can assign things to my list and
01:43cannot assign things to my tuple.
01:45My tuple is immutable.
01:47So I can't say t sub 10 = 25.
01:54tuple object does not support item assignment.
01:56A tuple is immutable.
01:58But I can say x sub 10 = 25 and when I look at x now I've got that 25 in the middle of it.
02:06Likewise, I can do any operation on a tuple that does not involve modifying it.
02:12I can use the count method to count how many 5s there are in the tuple and there
02:18is of course one of them.
02:20I can find the index of the 5.
02:21That will find that index of the first occurrence of that value and it's index number 5.
02:29If we look at t here we see 0, 1, 2, 4, 5. So that one there is indeed a 5.
02:37But I cannot append. If I say t.append(100), 'tuple' object has no
02:45attribute 'append'.
02:47On the other hand, if I look at my x object, which is a list, and I say
02:51x.append(100), it will put 100 at the end of it.
02:57The length of my x object is 21 instead of 20.
03:01I've actually extended it because I've added something to the end of it.
03:05If I want to add a number of things, I can't do that with append but I can do it with extend.
03:16This will allow me to extend it with any iterable object, so if I say
03:20(range(20)) now I'll get another 20 objects at the end of it.
03:27So, that range has been appended to the end using the extend method.
03:33If I want to insert something, I can say x.insert and I can insert at the
03:39beginning if I want to and I can put a 25 there and now we look at x.
03:46We've again extended the length of the array and there is a 25 at the beginning.
03:51But I can insert any place I want to.
03:53I can say x.insert(12, 100) and we'll see that I've got 100 there in the
04:02middle of the list.
04:05Likewise, I can remove it.
04:07x.remove(12) and that will remove the element with the value 12.
04:13It actually looks for the first value of 12 and removes that.
04:18If I want to delete the item at index 12 I use the delete operator and say x12 and
04:28that will delete that element at index 12.
04:32So, we see that 100 that we added in and we inserted at 12 is now gone.
04:39Finally, just like I can insert things at the beginning or at the end I can
04:44pop to remove things.
04:46If I just say x.pop, it will give me the value from the very end of the list and it removes it.
04:54So, you see that 19 is now gone. I got it returned from the pop method and now it's gone.
05:01If I want to, I can pop from the beginning I can say x.pop(0) and that will
05:08pop from the beginning.
05:09Now, I got that 25 from the beginning and the list is shorter by 1 and that's
05:14been removed from the list.
05:16Basically, we can do anything we want to with these lists, as long as we are
05:21using the mutable list object.
05:23So, all the power is there. You've got the equivalents of push and pop and insert and remove.
05:29You can remove things based on their value or based on their index, you can
05:34search for things, you can count the occurrence of things.
05:38All of this power is here for both the tuple and the list, as long as you are not
05:42using the things on the tuple that would modify it. Because you have to remember
05:46the tuple is immutable and the list is mutable.
Collapse this transcript
Organizing data with dictionaries
00:00Dictionaries are Python's version of associative arrays or hashed arrays.
00:05Dictionaries are created in a couple of different ways.
00:08We can create a dictionary with the curly braces and we can say key value like this.
00:24So now, we have a dictionary with those values in it.
00:27Actually, an easier way to create dictionaries is with its constructor because
00:31this allows you to use the named parameters feature of Python and it's just a
00:36whole lot easier to type.
00:37So you will see it done this way more often.
00:46We get exactly the same result and see that that type is a class dictionary.
00:54Finally, if you want to, you can even initialize one dictionary from another.
00:59If I have another dictionary?
01:11And so there I have that dictionary. I can say d =
01:14dictionary and I can take these definitions from up here, copy those and paste
01:21those in, and then I can actually specify that other dictionary with the two
01:26asterisk notation and I get a dictionary that has all of that in it.
01:31You can test if a value is in a dictionary by saying 'four' in x and I see that
01:39that's True and if I say 'three' in x that will not be true, because x here has
01:46just four, five and six in it.
01:48Likewise, you can iterate over a dictionary.
01:51You can say four k in d:
01:54print (k) and that will print out all of the keys.
01:59If you want to, you can say for k key and value in d.items print k and value.
02:12And that will give you both the keys and the values all in one fell swoop.
02:16If you want to find a particular item in a dictionary, one way to do it is to
02:21simply subscript it.
02:25The problem with that is that if your dictionary does not have that key, you
02:29will get an exception.
02:30If I try x sub 'three', I will get an exception.
02:35The way around that is to use the get method.
02:39If I say x.get('three'), it will simply silently give me the none value.
02:46If I say d.get('three') then I get the value.
02:52Another benefit of this is using the get method I can give it a default
02:57value. I can say give me that value of three or give me some default value.
03:07And I get the default value.
03:08Here I typed in the text 'not found'.
03:11If I simply want to delete an item from a dictionary, I can just look at the x here.
03:16I've got those items there.
03:18I can say del x' sub four' and now that's gone or I can say x.pop('five') and it will
03:30give me the value and delete it at the same time.
03:34So those are the major functions of dictionaries.
03:35Dictionaries are tremendously useful.
03:38Whenever you need to organize your data in such a way that it's easy to find,
03:44you can certainly store any kind of data in a list or in a tuple.
03:48But the indexes are always going to be numeric.
03:51The advantage of the dictionaries is that the indexes are data.
03:54So you can index it on any kind of data.
03:58Usually, you will use text, usually you will use words, but this allows you to
04:03basically create your own named spaces and organize them.
04:07They can be hierarchical.
04:08You can store dictionaries within dictionaries, you can store lists and tuples
04:12within dictionaries, and you will find as you will look through the examples
04:17of the code that I have written, I will often times carry one dictionary in a
04:21global namespace and put all of my data inside of that and then it becomes manageable.
04:27It's like a halfway point between flat data and an object with methods.
04:32Obviously, there is going to be times you are going to want to create an
04:35object with methods to handle your data in very specific ways, but for just
04:39organizing a whole lot of global variables or flags, you will find that
04:43dictionaries are very useful and for organizing object data within an object,
04:49you will find that dictionaries are very, very useful and very, very commonly
04:52used in these kinds of situations.
Collapse this transcript
Operating on character data with bytes and byte arrays
00:00Bytes and bytearrays are like tuples and lists except instead of containing
00:05arbitrary objects, bytes and bytearrays contain bytes.
00:108-bit words of data.
00:13An 8-bit word of data can hold up to 256 different values and this is sometimes
00:19a very convenient thing.
00:21In particular, it's convenient for converting strings and this is where you
00:26will see it used often.
00:27You will see it used for other binary things as well but it's often times used
00:31for converting strings. And we have a great example of this right here.
00:37This is a text file that I created for this purpose and when I created it on
00:41my Mac, it had this lovely little pattern of international characters that
00:46makes a little picture.
00:47It's a little viral thing that had been floating around on Facebook that I got
00:51and I thought it would be great for illustrating this problem, because there are
00:55some circumstances where you cannot display it and it doesn't look right,
00:59or if you try to read it as ASCII data in Python, you will get an exception error.
01:05So I loaded it up on the PC that I am using here and I saw this and I went oh, drat.
01:11It's not pretty.
01:12It doesn't look like it, but in fact this is a great illustration of the problem
01:16because this particular system is not handling the UTF-8 International
01:21Characters properly, whereas my other system was.
01:24They are both running the same software.
01:25They are both running Eclipse.
01:27They are both running the same version of Python and yet here we are trying to
01:30display this file here and it looks like this, whereas on my Mac, it looked
01:35different. And you will see it in a moment, we'll show you here, because we
01:38are going to convert it in a way that it will display here and we're going to
01:42use Python to do this.
01:43So this is what the file looks like here on this PC and if you are using a
01:47different operating system and you actually see the pretty fancy characters,
01:51just shh, don't tell anybody and the example will still work just fine.
01:55I'll start by making a working copy of containers.py and we'll call this
02:02containers-working.py and I'll just close this one and we'll open the working
02:09copy and we are going to start by opening the file. I am going to call this file.
02:14fin open and it's called utf8.txt, open it for read, and we are going to set its
02:24encoding as utf_8 and this is the exact character string that you need to use.
02:34This is meaningful inside of Python and that tells Python that when it's
02:39reading this file, that it needs to read it as UTF-8 and ignore whatever the
02:44default encoding is on your system, which is almost certainly something
02:48different than UTF-8.
02:49UTF-8 is really, really useful encoding.
02:53When the Unicode people came up with Unicode, it's this double wide character set
02:59that doesn't work right in normal ASCII systems where normal 8-bit wide text
03:03context and they tried to get the whole world to adopt it and the whole world didn't adopt it.
03:09So they came up with UTF-8, which is a version of Unicode that works in
03:14an 8-bit encoding scenario.
03:15So the first 127 characters of it works exactly like ASCII does.
03:21So you can set your encodings to UTF-8 safely and it will work just fine with
03:27normal ASCII code and then it has this clever system of setting high bits in
03:31order to tell the system that it needs a couple more bytes to represent a
03:35particular character.
03:36And it all happens kind of transparently behind the scenes if your system is
03:40properly implementing UTF-8. And these days most web browsers do handle UTF-8, just fine.
03:47But a lot of desktop systems don't and this one here that I am working at
03:51obviously doesn't. So we are opening this file as UTF-8 and we are telling that
03:56the encoding is UTF-8 and for it to ignore its default encoding.
04:00I am going to go ahead and open an output file.
04:03I am going to call this utf8.html because we are opening the browser, even
04:11though we are not going to put any actual HTML in it.
04:15And we'll open that for write.
04:16We are going to setup a bytearray, we call it outbytes, initialize the
04:22bytearray, with the bytearray constructor.
04:27And a bytearray is a mutable list of bytes.
04:31So it doesn't hold any other kind of object but bytes and we'll start iterating
04:36through the file for line in file in and then we are going to immediately
04:43iterate through the line for character in line because a string is an iterable
04:50object and we are going to use the ord built in.
04:55if ord of c, and that gives us the integral equivalent of that character.
05:01Is greater than 127.
05:05So there is 128 values in UTF-8 that are just normal ASCII and they are 0 through 127.
05:12So if this one is higher than 127, we are going to do something special with it.
05:17And otherwise, we are just going to append it to outbytes.
05:21We are going to say outbytes.append ord of c, like that. And then if it is greater
05:31than 127, we are going to do this fancy thing here. outbytes +=.
05:36When you use the addition operator on a mutable container type. It has the
05:43same effect as appending, but you can append more than one element at a time this way.
05:48So what I am going to do here is I am going to create a bytes object and bytes
05:54are immutable arrays of bytes and I am going to encode a string.
06:01The constructor of bytes will expect a string within an encoding and so a string
06:07is going to be this XML entity with the ampersand and the pound. If you are
06:12familiar with XML entities, they look kind of like that, where inside of here
06:17you can put a decimal value
06:19that will be interpreted as UTF- 16, which is the normal Unicode.
06:24So in there I am going to have a format and I am going to use this format here,
06:2904decimal. I know this is all looking very complicated.
06:33I told you this line is where all the magic happens. And I am going to use format
06:38ord(c) and then the bytes constructor is going to have an encoding, that
06:45encoding is UTF-8, because we use UTF-8 for everything wherever we can.
06:51So now what we have done is, if the character is outside of the normal ASCII range,
06:56we are going to encode it with this XML entity which can be used in an
07:02HTML context and that will allow us to display our fancy little picture.
07:06Otherwise, if it's not greater than 127, if it's in the normal ASCII range, we
07:12just append it to our outbyte.
07:13So now we have an outbytes bytearray which has all of the characters for our
07:20string and now what we need to do is to turn it in to a string.
07:23We'll call it outstring and we'll use this string constructor and we'll
07:28construct it out of outbytes and guess what? We are going to use encoding = 'utf_8'.
07:37Now all we need to do is to print it to our outfile, print (outstr,file =
07:43fout), and we'll print it also to the screen here so we can see it, and we'll
07:51print the word Done.
07:54So this will read our UTF-8 text from our file that we are not able to read on
08:00this system, go ahead and save this so no catastrophe happens.
08:04This will read our UTF-8 text file and it'll read it with the UTF-8 encoding and
08:09it will write it out to our UTF-8 HTML file, and for the characters that are
08:16outside of the normal ASCII range, it's going to replace them with an XML entity
08:21and that's really all that we are doing here.
08:23So we saved it, we are going to run it, and it looks like I have got a typo some
08:29place here. Yes, right there.
08:34I needed an S. That's all right. Save that and we'll run it and there we
08:39have our fancy string.
08:41So this stuff here got converted to UTF- 16 and these are the Unicode values for
08:51each of those fancy characters and now if we refresh our file system because
08:56Eclipse doesn't like to do that for us and we open this up in the little browser
09:01inside of Eclipse, there is our fancy little picture. And so this is what it
09:06looked like in the text file.
09:07This UTF-8 file has some interesting characters in it and so we weren't able to
09:12see that on this system and by encoding them with the Unicode XML entities,
09:19we are able to see it and there we have it.
09:23So the way that we did this is by using a bytearray.
09:28The beauty of a bytearray is that you can operate on character data because
09:33characters are bytes and a bytearray is mutable, so you can insert things,
09:38you can change it up and all we did here we basically used it as an accumulator.
09:43As we went through the string with the bad data in it, if we found an element
09:48that we needed to operate on, we pushed all of these characters onto the
09:52bytearray, using the bytes constructor and appending them to our outbytes which
09:58is a bytearray. Otherwise we just appended the regular character. If it was
10:02within the range we just appended the regular character.
10:05So these characters here just got appended in the normal way, but these
10:09characters, we ended up using these XML entities which represent the Unicode
10:16characters and we got our little fancy guy to display just the way that we
10:20needed him to display.
10:22So that is a very common use of bytearrays.
10:25Bytearrays are a very effective way to do things like this.
10:28You will see an example very much like this one in our example code later on
10:33in the course.
Collapse this transcript
15. File I/O
Opening files
00:00Python has some very simple built- in functions for dealing with files.
00:04Let's make a working copy of files.py.
00:07I'll call it files-working.py and we will open that working file and we see here
00:14a simple loop that reads lines from a file and prints them out.
00:19So run that and see what it does.
00:21It prints out the lines of this file. This is the file here, lines.txt, and we
00:25are just printing out all five lines with that file in this little loop.
00:29What we are going to look at in this movie is this open function.
00:32It's very simple and it has a few options.
00:36By default, all it does is it opens the files in the read mode and you give it a
00:41file name here and it returns the file handle object, which can then be used to
00:46operate on the file.
00:48If you don't specify it, read mode is the default and that looks like this.
00:53There is the second argument, which is the mode, and that defaults to the
00:57r character for read.
00:59Options there are r for read, w for write, or a for append.
01:06Append is a special write mode.
01:07It sets the current position of the file to the end of the file so that
01:11everything that you write will get appended to the file.
01:15In read mode, you can optionally give it a plus sign, which will open it for both
01:19read and write in the same file handle object.
01:23You can also give it a t for text file mode or a b for binary mode, and we will
01:29look at these options a little later in our movie on the subject.
01:33The open function returns this file handle object, which we see used here.
01:39It is an iterable object and in iteration mode it simply gives you one line
01:44of the file at a time.
01:45In fact, there is a method called read lines, which does exactly the same thing.
01:51You save that and run it, and there is our lines of text.
01:55So that is the open function in all of its simplicity.
01:59In the rest of this chapter we will look at how to read and write files and how
02:02to set its file mode.
Collapse this transcript
Reading and writing text files
00:00Reading and writing text files in Python is really very simple.
00:04Let's make a working copy of files.py. files-working.py.
00:10Open that working copy and we see that we have the simple loop here that reads
00:15lines of a file and prints them to the screen.
00:17So if we run that, we see there is our lines of file, print it to the screen, and
00:22here is our input file.
00:24So, we can see that that's exactly the same.
00:26Now, if we wanted to, instead of bringing that to the screen, if we wanted to
00:30write it to a file, we could do that.
00:32Simply change this to infile, so we can have a separate one for outfile, outfile
00:39equals open and we'll call this new.txt.
00:42We will open that for write.
00:45And we will open this one here for read.
00:47It defaults to read but if I am going to specify write, then I am going to want
00:50to also specify read.
00:53This is called infile, and all we have to do here is to say file equals outfile,
01:00And now that print is going to print the outfile instead of to the screen.
01:05And as we don't have anything coming to the screen, I am just going to print done here.
01:09So we know that we have gotten to this point.
01:12We get some feedback on the screen.
01:14I will save that and I will run it and it says done.
01:18If I refresh the file system here, which Eclipse does not do by itself, you can
01:23see there is a new.txt and it's got our five lines of text in it.
01:27So that is just a very simple way to write to a text file.
01:32Obviously, it doesn't have to be something you are reading from another text file.
01:36You can generate your own whatever and write it out to a text file very easily,
01:40using print and the File parameter for print.
01:44Let's say that what we are doing is not necessarily line oriented.
01:47Let's say that maybe we have a very large file with thousands of lines of text,
01:51And we don't really need to read them and write them line by line.
01:53We want to do it in some bigger chunks.
01:56So I have a file here called bigfile.txt and you will notice it is a really big file of text.
02:01It has 10,000 lines of text in it.
02:06If we look at the properties, we can see that it's 320,000 bytes. It's 300k.
02:12So, let's go ahead and open that one instead, and call it bigfile.txt and we
02:21are going to read this in what's called buffered mode, instead of doing it line by line.
02:24We will set a buffer size and I will say that's going to be 50,000 bytes.
02:31It's 300,000 bytes, so it will give us a few chunks and then we are going to
02:36start by filling our buffer, infile.read and buffersize and then instead of this
02:46here, I am going to use a While loop, because the Read method on the file handle
02:51object is not an iterable.
02:53So we can't use a For loop, so we are going to use a While loop.
02:55We are going to say while the length of buffer.
02:59And so as long as our buffer is not empty then we will outfile.write buffer.
03:06That's really all there is to it.
03:08We read it again in the loop, so that we are not just writing the same buffer forever.
03:12So I am going to write buffer = infile.read buffersize and after we do the
03:20write, let's just print a dot to the screen, so we have some feedback that we
03:23are doing something, dot, end, equals nothing.
03:29So this will just print dots on the screen right next to each other, and we are all done.
03:33Before the Done, we are going to want to print a blank line.
03:37So we will go ahead and save that and run it and we see we have got a handful of dots there.
03:43It means that we have written something and we refresh our file system and take
03:49a look at the properties of new.txt and it's exactly 320,000 bytes.
03:54We will open that up and there is all of our lines of text in there.
03:58So what we have done here is we simply read it in a few big chunks and
04:02obviously 50,000 bytes is very small by today's standard.
04:06Your buffers can be bigger than that or if you are on a mobile device or
04:09something small, maybe you do want them that small.
04:12We just did that this way for illustration, but this shows you how you can read
04:17and write in buffered I/O mode.
04:19So it allows you to deal with bigger chunks of files than just line by line.
04:25So that's how simple it is to read and write text files in Python and we will
04:29discuss reading and writing binary files in a separate lesson.
Collapse this transcript
Reading and writing binary files
00:00Python makes a distinction between text files and binary files.
00:04Even on operating systems with file systems that don't make that
00:07distinction, Python still does.
00:10So how you read and write binary files, even though it's still very simple, is
00:15different in significant ways from how you read and write text files.
00:19So let's make a working copy of files.py. files-working.py.
00:27Open that working file and we see we have our little loop here that reads
00:31lines of text and prints them to the screen, and let's just go ahead and take
00:35this out and put in olives.jpg and we will save that and run it, and we will
00:45see that we get this UnicodeDecodeError because Python is trying to decode the
00:51text in that JPEG file.
00:54That's a JPEG file.
00:55If we open that up, we will see there is an image of some grapes on a vine
00:59there, and that it not a text file at all.
01:02So what we need to do is we need to open this in binary mode.
01:05So we are going to open it in Read Binary, like that.
01:09And now if we save this and run it, we are going to get this output, which is
01:15still not really what we want.
01:18What's happening is that the Print function is trying to print that in a way
01:22that's text readable, and we are not going to want to write that to a file if we
01:25are making a copy of this.
01:27So what we need to do is we need to open an output file in binary mode and we
01:31need to use our buffered I/O. So we will call this infile, and we will open an
01:36outfile, and call that new.jpg.
01:42Open that in write binary mode, and we are going to do a buffered I/O here.
01:48So we will start by giving ourselves a buffersize.
01:52Let's see, how big is this file?
01:57Properties, it's 142K.
02:01So we will just go ahead and make our buffersize 50000, and that will work fine.
02:05And the rest of it is very similar to how we would do this with the text file,
02:13infile.read(buffersize) and infile.read is not an iterable, so we have to use a
02:22while loop, length of buffer, and we will outfile.write from our buffer.
02:32And we would go ahead and print a dot.
02:36So we see that something is happening on the screen and we will read the next buffer.
02:44When we are all done, we will print a blank line and we will print the word Done.
02:53You can see that we are done.
02:56So what's different here is that by opening the file in binary mode, we are no
03:01longer dealing with text.
03:03The rest of it looks pretty much the same as how we do the buffered reading and
03:07writing with a text file, but the difference here is that we are not working
03:10with text at all. This buffer is now a binary object.
03:14It's not a text object at all.
03:16We will go ahead and we will save this and we will run it and we have got a
03:21few little dots there.
03:22And if we refresh our file system, which Eclipse does not do for us, we have this new.jpg.
03:28I open that up.
03:29There is our JPEG intact.
03:31So we know that copy worked.
03:33I will look at the size of it.
03:35It's the right number of bytes, 142309.
03:39Is that the same as our olives?
03:42It is exactly the same.
03:44So we have an exact duplicate of that file.
03:47So reading and writing binary files, the methodology is very similar, except
03:52you have to use the buffered I/O. You are not going to want to use line
03:55oriented I/O for a binary file.
03:58And most of the time for text files, you are going to use line oriented I/O,
04:02although you can use buffered I/O for text files as well.
04:04As a matter of fact, you can use binary mode for text files if you want to, and
04:08deal with them as bytes, and that will certainly work.
04:11But the distinction here is that with binary files, you have to use the
04:15buffered I/O and you have to use binary data types.
04:19So when you read that file, it's going to read it as an array of bytes and it's
04:24not going to read it as text.
04:26So this is how you do buffered I/O with binary files in Python.
04:30And it's really very simple and it's something that you are going to use now and
04:33then as you are dealing with binary files.
04:36One final note. You will notice that the buffered read method is not an
04:41utterable. If I was going to be doing this a lot, I would go ahead and I would
04:45write a method for an object that is iterable.
04:48That would make this easier for me to do.
04:51It's certainly a matter of style.
04:52It's something that you might think about doing if you are going to be doing
04:55this a lot, and there is an example of how to make a generator function that
04:59generates an iterable in both the Functions chapter and the Classes chapter in this course.
05:05So that's how you do buffered I/O on binary files in Python.
Collapse this transcript
16. Databases
Creating a database with SQLite 3
00:00There are many database choices available for Python.
00:02For our purposes, we're going to be using SQLite3 for a number of reasons.
00:07First of all, SQLite3 comes with Python.
00:10If you have Python installed and you're watching this course, then you have
00:13SQLite3 and that makes it easy for us for the purposes of teaching.
00:17SQLite3 is a perfect choice for a lot of applications.
00:21For most of the web site work that I do these days, I'm using SQLite3 instead of
00:26MySQL which I might have used a few years ago.
00:28It's reliable, it's simple, it doesn't require a separate database engine,
00:32it's self-contained, server less, zero configuration and fully transactional.
00:37It's a fully capable database engine in a driver and that makes it just
00:41incredibly easy to use.
00:43For our purposes, having something that's simple like this allows me to show
00:47you how databases work with Python without having to mess with the database a
00:52whole lot and spend our time in the Python.
00:54So, I'm going to go ahead and start by making a working copy of databases.py.
00:59Call it databases-working.py. Go ahead and load that up.
01:03You see our first line here says import sqlite3 and that simply imports the
01:08Python Library that supports SQLite3.
01:11And then here all we do is we say db = SQLite3.connect and the name of the file, test.db.
01:21And we save this and run it and we have created a database.
01:26We'll go ahead and refresh this file system here because Eclipse doesn't do that
01:30for us and you see that we now have empty file and we've created our database.
01:34So, we'll go ahead and populate the database and that's also very simple.
01:38We simply say db.execute and I'm going to give it some SQL here and say drop
01:45table if exists so that we can create a new table each time and call the table test.
01:51And then db.execute, create table tees, and give it a couple of fields.
01:59t1, it's a text field and i1 is an int and I've created a table inside my database.
02:06Now I'll just insert a little bit of data. db.execute insert into test (t1, i1,
02:16values (?, ?) and these are placeholders and that allows us to give it a
02:22tuple with the values one and 1.
02:27And I'll just make a few of these. Two and give that a 2.
02:34And a 3 and a 4.
02:36And 4 and a three and we have now inserted some data into our database.
02:44So this is all done with SQL and we'll say db.commit() because SQLite is a
02:50transactional database.
02:51It will buffer these values, in case you're going to be using it in
02:55a transactional mode.
02:56And then I say cursor = db.execute and select star from test order by t1.
03:05Again, standard SQL for row in cursor: print(row).
03:12So, now, I've inserted some data into the database and I'm going to print that
03:16data out from the database.
03:17Save it and run it and there we have it.
03:21There's our four records and they're sorted by the t1 field ,which is our text
03:26field, and that's getting read from the database.
03:28So, that's all there is to it.
03:30Using SQLite in Python is incredibly simple.
03:34Our first line here connects to the database and that actually creates the file
03:38if the file didn't already exist.
03:40And then, from there on, we're using db.execute because db is the database
03:45object that we got back from the connect statement and we simply interact with
03:49the database using SQL.
03:51Be sure to do a commit after you change any data in the database and then we can
03:57do a select and use the cursor object that's returned by db.execute and simply
04:03step through the cursor object as an iterator and print the data.
04:07The data comes back, you'll notice, in tuples and they're in the order that you
04:12specify things in your SQL.
04:14So, if I want it in the i1 first followed by t1, I simply change my SQL so that
04:20specifies an order, because the order that was in was the order that we define
04:24them in the create table text and then int.
04:26So, if I want int and then text, I simply change in my SQL and it'll come back
04:31in that order and obviously if I want to order it by the integer instead of
04:34by the text, I simply change my SQL and it comes ordered by the integer
04:39instead of by the text.
04:40There's one more thing I'd like to show you in this context and that is the row
04:45factory that comes with SQLite.
04:46The SQLite interface is actually incredibly rich and very full featured in
04:52Python and there is a lot of options and a lot of methods that you can override
04:59and a tremendous amount of power there for working with databases.
05:03We are going to keep it simple for our purposes here but there is one thing that
05:06I want to show you and that's what's called a row factory.
05:08We'll say db.row_factory = sqlite3.Row.
05:16So, what the row factory does is it allows you to specify how rows will be
05:23returned from the cursor and the built-in row factory that's provided,
05:27sqlite3.Row, is very powerful and very suitable for most purposes.
05:33So, when I save this and run it, you'll notice the only change I made was to add
05:37that row factory there after the connect.
05:40You'll notice now we get row objects instead of those tuples and the row objects
05:46can be looked at as tuples if we'd like or it can be looked at as dictionaries,
05:52which I find particularly useful.
05:55So, if I say dictionary like that, I'm creating a dictionary object based on a
06:01iterable because row is an iterable.
06:04So, if I save this and run it, now I get dictionary objects and so they
06:09are completely indexed.
06:11If I want to, I can say, rows up t1 and I'll get my t1 objects.
06:18I can say row.t1, row.i1 and get all the data. Save that and run it.
06:26The built-in row factory from SQLite is very flexible.
06:30I tend to use it in the dictionary mode because I find that very convenient, but
06:33it has a lot of other options and they're all documented on the SQLite3 page in
06:38the Python documentation.
06:40So, as you can see, accessing a database from Python is very simple.
06:45Most databases have an interface very similar to this one.
06:48For most simple database applications, SQLite3 is going to be a great choice and
06:53you can see that it's very simple to use in Python.
Collapse this transcript
Creating, retrieving, updating, and deleting records
00:00The basic four functions of a database are considered create, retrieve, update
00:06and delete, which conveniently spells the word CRUD.
00:09In the Exercise Files, you'll notice file called sqlite3-crud.py.
00:15We're going to use that as a starting point here.
00:16So we'll just make a working copy of it and we'll call it
00:19sqlite3-crud-working.py. If you like, you can name it something simpler and
00:27we'll open that up and you'll notice that this is a rather complete file.
00:33Rather than type all this stuff, I just give it to you and we'll take a tour
00:38of it and we'll see how it works.
00:39You'll notice that at the top of the file here in imports sqlite3 and down here
00:45we have the main function.
00:46Normally I would put this at the top, but really the object of our exercise here
00:51is those functions at the top.
00:53So, we'll get to those in a moment and you'll notice a few little print
00:56statements here as comments.
00:57So, we create the table and it's called test and this is the same as in the
01:02creating a database lesson.
01:04You'll notice that we also have our row factory in here and that's also
01:08described in the creating a database lesson, and then we create the rows and
01:12we're using this insert function that's defined above.
01:14I don't call it create because I think of create as being creating the table or
01:17creating the database.
01:18I call it insert. CRUD doesn't work as well if there is an I instead of the C,
01:23but this works for me to call it insert and actually it matches the
01:27corresponding SQL also, which is insert. And then we retrieve a row based on a key.
01:32There's the key and there is the key, we update rows and changing their values
01:37and we delete rows and if we run this, go ahead and run it, it creates a table,
01:44it creates rows and then it shows them to you and it retrieves rows and it
01:48retrieves them based on those keys and there is the dictionary objects and it
01:52updates rows, and there it changed these two, and it deletes rows and this is all
01:58that's left after it's deleted them.
01:59So, this just shows us that it's working and now we can look at exactly how
02:03all this stuff works.
02:05When you're building a specific application and your specific application has
02:09specific database tables and specific schemas, a lot of times it's convenient
02:14to create specific functionality in your program that deals with those objects
02:20and normally you're going to do it in an object-oriented method and we'll look
02:23at that in another lesson in this chapter, but for now, here's how you can do
02:28it in a simple way.
02:29I would not write production code this way.
02:32There's no error checking. Using functions I'm passing the database handle around.
02:37The way I would create actual applications is going to be in more
02:41object-oriented manner. We'll look at that in another lesson.
02:43For now, our purpose here is just to look at how can we do these individual
02:47tasks in very simple way. And so, for the insert function, I simply pass it a
02:53dictionary and the dictionary has the data that's going to be inserted and then
02:57up here we can use this little outline feature in the Eclipse workflow and I
03:03look at the insert function. And you'll see it takes that row which is a
03:07dictionary object and it passes the individual elements into the placeholders in
03:14the SQLite3 execute method.
03:17So, the execute method takes as its first argument a string of SQL and in
03:22that argument you can put in placeholders and there's actually a couple of ways to do that.
03:25I'm showing you the simple way here with the question mark and these are
03:28positional and then it takes a list as the second argument and so this has to
03:33be a list or a tuple. In this case a tuple, and so it need to be as one argument
03:38which is why we're passing it a tuple with parentheses around it so that it's
03:41grouped as one argument and then that has positional ordered parameters.
03:46The first one is going to correspond with the first question mark and the second one
03:50is going to correspond with the second question mark and each of these is simply
03:54dereferencing the dictionary object that's passed into the function.
03:57So, this very simple.
03:59in the main, all we need to do is we call it like this, insert and the first
04:03parameter here is DB, which is the database object, so that the insert function
04:07can access the database and the second parameter is this dictionary object and
04:12obviously, in your code, you could create that separately.
04:15It could be derived from all sorts of sources and for our purposes, we're simply
04:19creating the dictionary object on the fly here.
04:21And so we call that four times and that inserts the data and we'll see that
04:25right here at the top of our results, Create rows.
04:28Notice that I have this little display rows function and that looks like this.
04:33It basically executes a select and it prints out the results from the dictionary
04:38object, because we're using the row factory.
04:40So, that's our insert function.
04:42Our retrieve function is like this.
04:44It simply passes a key and it gets a row object in return and so it prints that
04:50out as a dictionary and so that looks like this here in our results.
04:54These are the dictionary objects that are returned by those two calls to retrieve.
04:58So, retrieve is really just this part here and when we look at it up in our code,
05:03it takes a key and I'm calling that key t1, I could just name it key if I
05:07want and it calls execute with this SQL, which is basically select an entire row
05:13from the test table where t1 equals question mark, and then it passes this one
05:18positional argument out.
05:19Now this has to be a list or a tuple, and so I create a tuple here and remember
05:24it's the comma that creates a tuple.
05:26It is not the parentheses.
05:28The parentheses are just for grouping.
05:30So, if you want a tuple with one element, it needs to be like this parentheses
05:35and then the object and then a comma and then the closed parentheses and this is
05:39a case where I need a tuple with just one object.
05:42It calls db.execute with this SQL and that returns a cursor and then I use the
05:47cursor with the fetchone method in the cursor object from SQLite3, and that'll
05:53simply fetch one result because that's what I'm asking for with this
05:57particular retrieve.
05:58Obviously, if you want a method that retrieves more than one object, you can
06:01do that and we'll look at an example of that in the database object lesson in this chapter.
06:06Now, returning to our main function, we update rows and it's really very
06:09similar. We're passing a dictionary to an update function and the update
06:13function simply has an execute statement with the SQL here, update test, set
06:19this value, set that value and it passes it a tuple with those elements from the
06:24dictionary that we're passing here.
06:26You see the pattern here?
06:27Delete works the same way.
06:29It gets a key and it has the SQL.
06:32It says delete from test where t1 equals question mark and then it's this one
06:37element tuple and it calls commit.
06:39We have to call commit every time we do anything that can change the database.
06:44So, for update, we call commit, for delete, we call commit and also for insert
06:49we're calling commit and so there is our retrieve. There is our update and
06:55after update, we display the rows and after delete, we display the rows and
06:58there is our result, update, change those two, and there they are changing the
07:03two up here and Delete rows, we're deleting two rows, we delete one and we
07:09delete three with these keys and all we have left is two and four.
07:13So, those are the major four functions of a database.
07:17Insert, retrieve, update and delete and you can see with SQLite and Python,
07:23it's incredibly simple.
07:24It's really just passing the SQL and getting the right parameters into the
07:29SQL and it just works.
Collapse this transcript
Creating a database object
00:00When you are writing an application that uses a database, sometimes it's a good
00:03idea to create a class that handles that particular schema.
00:07Let's take a look at an example of how you can do that in Python.
00:11We'll start by making a working copy of sqlite3-class.py, and we will call it
00:16sqlite3-class-working.py, and we'll go ahead and open up that working copy.
00:23And here we have a complete working example of a class. It's very simple.
00:28It's just a few lines of code, and how we access that class through this interface.
00:33We'll go ahead and run it and you can see what it does.
00:38This is just an example of testing this particular class, so it creates a table
00:43test and it creates some rows and retrieves the rows.
00:46It tests these four functions of the database.
00:49So if we look at our interface, we create our object by passing in a file name
00:54and a table name, and that will actually initialize the database.
00:58And then we create the table using some sql.
01:02Then we insert some rows using dictionary objects.
01:06Then we retrieve rows, just using keys, and it will retrieve dictionary objects.
01:11And retrieve test, there is our dictionary objects.
01:15We update a couple of rows, again, using dictionary objects, and there they are.
01:20These dictionary objects could instead be specific classes that you've created
01:24for your database application.
01:26And we delete rows with keys. And you'll notice that every time we do one of
01:30these operations, we're printing out all the rows in a database using the
01:35database handle itself as an iterator.
01:37So this is a nice little convenient interface.
01:40First of all, the constructor takes these two arguments as named arguments
01:44using the kwargs pattern.
01:47And the first one is the filename and it assigns it to a filename property.
01:53And the second one is the table and it assigns it to a table property.
01:56And you'll notice that these do not have underscores, because these are meant to
01:59be accessible to the outside world.
02:02Down here, I use the property decorator to allow the filename to be assigned
02:07like that, and when it gets assigned it actually connects to the database and it
02:12sets up the row_factory.
02:14And when you delete the file name, it actually closes the database.
02:19And so this allows you to use this kind of a pattern for assigning the filename,
02:24and you can even do this on the object level, using the object, and it will go
02:28ahead and initialize the database like that.
02:31Likewise, with the table, it sets the table name and that one is just really
02:38simply setting this _table variable, and if you delete it, it defaults
02:43to test, so that there is always a table name. Because it will kind of break the
02:48code here if there isn't a table name, if the table name is blank, and you'll
02:52see that as we go through.
02:54So the insert function is very simple, and you'll notice it goes off the end
02:58of the screen here.
02:59So I'll just go ahead and reformat that.
03:02So the sql, insert into it, and you'll notice that we have to use a
03:07replacement in the string using format, because the question mark pattern
03:12doesn't work for the table name.
03:15That's true across the board in every database entry that I have ever used.
03:19If you want to use the positional parameters, you cannot do that for the table name,
03:23and so I allow the table name to be set using the format here and it uses
03:28the underscore table.
03:30And then, the row is passed in as a dictionary object and here we make a tuple
03:35out of the two parameters that we are inserting, the values t1 and i1, and they
03:40are positional like that in order.
03:42So insert looks like that. Retrieve looks like this.
03:45It returns a dictionary object using the fetch 1 method of the database cursor
03:51and the sql is just a simple select * from the table name.
03:57We are replacing the table name using format and we are using positional
04:00arguments over here for the key, and again, this is single element tuple and
04:04so it has to have that comma. Because the comma is what creates the tuple, not the parenthesis.
04:09Update, it takes a row as a dictionary object and it passes the menu using that
04:15tuple, and the same pattern here.
04:18We're replacing the table name using the string format method, and delete uses a key
04:24and there is the single element tuple there, and all of these methods that
04:30change the database, they all have this db.commit.
04:33There is a display rows method that we are not actually using, which does
04:37what we were doing in our other examples. It simply prints them out using a print function.
04:42But here is how we are looking at the data in this example. We are using this iter method.
04:47That's a special method in Python.
04:49If you put this in your class, it allows your object to be used as an iterator.
04:54So it has two underscores __iter__ for its name, and other than that, it works
05:01just like any method.
05:02And it's a generator because it uses yield, and this allows it to operate as an iterator.
05:09So it simply yields a dictionary of the row, and that allows us to call it like
05:13this, for row in db:print(row), and we get these results.
05:18So we'll go ahead and we'll save this and we'll run it again, and we see there
05:23we have our results.
05:26Finally, it's worth noting that because of this pattern down here at the bottom,
05:30if __name__="__main__": main(),
05:33this entire file will work just fine as a module in Python.
05:39You could simply say import sqlite3-class-working and you would have access to
05:45this class and be able to use this in another file.
05:50And this main function down here will be completely ignored, because when you
05:55import it that way, this is no longer true and so main will not be called.
06:01So it's a useful pattern to be able to write a module like this and to have a
06:06class that you are going to use throughout a project or even to distribute it to the world.
06:10And to test it using a main function that is really just there for testing purposes.
06:17So this is a useful pattern and it's one that you'll probably use.
06:21Here we have a custom class for working with a specific database, and a lot
06:28of different techniques that you can use in building a class like that for yourself.
06:32It does the major four functions and it does a couple of other things.
06:36The object itself is useable as an iterator, because we included an iterator method.
06:42It uses properties for setting the filename that make it easy to change files if you want to.
06:49So here we have an example of how you can create a custom class for your own
06:53database schema, for your own project, using Python's object-oriented features
06:57to make your programming task a lot easier.
Collapse this transcript
17. Modules
Using standard library modules
00:00The Python standard library has a number of modules that you can import into
00:04your programs and use for your own purposes.
00:07This page has a list of them starting here in section 7, under String Services.
00:13And you'll see that there are quite a few of them.
00:16So we're going to just go through a few of these, a few of the more common
00:20ones and show you as an example how you can use them.
00:23And I suggest that you go through this list at least once and just look out what they are.
00:30And just look at their descriptions.
00:31Just read through the list, so you have an idea of the kinds of things that
00:34are available to you.
00:36So here in Eclipse, we're going to make a working copy of modules.py.
00:41Call this modules-working.py, and we'll open that up.
00:47You'll notice that here we're importing sys, and here on the web page you'll see
00:53sys is for system-specific parameters and functions.
00:58If we open that page, you'll see that there's full documentation on all of the
01:04things that you can do with sys.
01:06So, one of these is to get the Python version.
01:09This is with sys version info.
01:11And so if we run this, you'll see that we say, this is Python version 3.1.2.
01:20You can also get the system platform.
01:23You can say print(sys.platform) and if we save that and run it, you'll see
01:31that this is win32.
01:33On my Mac at home it says Darwin and whatever operating system you're running Python on,
01:39it will give you an idea.
01:41And this is a category of operating system.
01:43It's not actually the operating system.
01:45You can get the operating system from the OS module, but this gives you an
01:49indicator of what types of services are going to be available on this platform.
01:54Like, for instance, if I'm on a win32 platform, I'm not going to do things that
01:58are UNIX specific and vise-versa.
02:01So, that can be a useful token to see.
02:04If we import OS, this is another module that you'll find in that list,
02:10you'll notice that I can import inside of the function.
02:14I don't need to do my import at the top.
02:16This allows me to actually selectively import things, say I read that
02:20sys.platform variable and say I'm going to do certain things one way or
02:25certain things another way depending on which platform I get.
02:28So I can import modules selectively, and the system won't try to import them if
02:34they're not on the right platform or whatever.
02:37So, here we can get the os.name for example, and if I save that and run it,
02:45you'll see this says nt.
02:48So, that's the name that it's giving this particular type of Windows.
02:51And it distinguishes it like from, for example the older Windows 3 or
02:56something like that.
02:59I can get variables from the environment.
03:00I can print os.getenv and say I want the PATH variable.
03:06Save and run.
03:11And there is the PATH variable from the operating system.
03:16So, I can get current working directory, and we'll save and run that.
03:25And there is the current working directory.
03:27Of course, this module has a lot of functions in it.
03:32Just one more I want to show is the urandom function.
03:35This is sometimes useful.
03:39Save and run that.
03:42This is a function that'll give a string of random bytes.
03:45And of course you see that this is the byte type, and I set 25 so it's 25 bytes long.
03:55Another useful module is the urllib module, and we'll go ahead and import from
04:02that urllib.request, and we'll grab a web page from the internet.
04:11urllib.request.urlopen, and we'll give it a URL here.
04:20We'll go ahead and get my homepage, print(page). There we go.
04:26Save that and run it.
04:29We get this object.
04:31And that's an iterable object.
04:33So, we can iterate on it and say for line in page:
04:39print, and convert each line to a string because they come out binary, and
04:47we provide an encoding.
04:50And they have no lines at the end of them.
04:52So we'll give it this line ending there.
04:56And we save and run and there is an entire web page.
05:07So, that's a really useful one.
05:09There are a lot of very useful modules in here. I'm just going to take a quick look
05:13at a couple of more.
05:14One is the random module.
05:17It's a very rich random number library.
05:19For example, you can print a random number from in a range. randint,
05:33A range between 1 and 1000. Save and run.
05:37And then we have the number 726.
05:38If we run it again, we get a different number and a different number and
05:42a different number.
05:43And that's very useful.
05:45Another very useful method in this library is the shuffle method. It takes a list.
05:52I'm going to just give it a list with a range in it, and if we print that list,
05:57you'll see that we have a range of 25 numbers.
06:03We can shuffle the list, random.shuffle, and print it again.
06:16And there we have the list shuffled randomly.
06:20If we do that a few times, save and run, you can see we get different
06:26shuffles each time.
06:29Finally, in our little partial tour of the standard library, look at
06:34the datetime module.
06:47So we'll save that and run it, and there we have the time as of right now
06:54when I'm recording this.
06:55In fact, we can do this. now.year, now.month, now.day, now.hour, now.minute,
07:13now.second and now.microsecond, and save that and run it.
07:21And there we have all of those components, separately usable with these
07:25properties of the datetime object.
07:27So, these are just a few of the standard modules that are available with Python.
07:31Again I strongly recommend that you look through the documentation for these
07:35standard modules. At least read their descriptions so that you get an idea of
07:39what's available there, so that as you're going through writing your own code,
07:43you're not tempted to reinvent the wheel.
07:45The modules that are included with Python and the Python distribution tend to
07:49be very well written.
07:50They tend to be very feature rich and they tend to be quite well optimized and reliable.
07:56So, I suggest that you use them when you have an opportunity.
Collapse this transcript
Finding third-party modules
00:00In addition to the modules that distribute with Python in the Python
00:04standard library there is also a repository of modules that have been
00:09written by other people.
00:10This is called PyPI, the Python Package Index, and it's available at this web page.
00:16We're going to click on the link here, Python 3 packages, so we can see what
00:21packages are available that support Python 3.
00:23Of course by the time you look at this, this list will probably be much longer
00:28because more-and-more modules are being imported to Python 3 all the time.
00:32Just as an example of how to install a module that you find here, I've selected
00:39one called bitstring, and what this does is it allows you an easy way of working
00:45with strings of bits, and we'll go ahead and we'll download this and install it.
00:51And so this is the page and most of the pages look something like this.
00:54They've got some documentation.
00:56They have a link to the web site where it's been developed and a way to download a module.
01:03And so I've already downloaded this and unpacked it on the computer here and there it is.
01:11Go ahead and change into that directory.
01:14And we can see that it's this Python file and a setup.py and some other related files.
01:24All of the modules that are available on PyPI have a setup.py and it's a
01:29standard, and so they all install pretty much the same way.
01:33Now I am installing this on Windows.
01:35And the way that you install it on other operating systems is pretty
01:39much exactly the same.
01:41You run the setup.py script with the argument install.
01:47And on Windows, unless you've put Python in your path you'll have to type in
01:51the path to Python.
01:53On most other systems you won't need to do that.
01:55So I am just going to type in the path here.
01:58And I say python31, which is the standard place where it installs on a Windows system.
02:04And let's say python, and then I am going to give the name of the setup script,
02:09which is setup.py and the word install, like that.
02:13And so if you are on a UNIX-based system like a Mac or Linux you probably just
02:17type something like Python 3 setup.py install.
02:23You do want to make sure that if you have both Python 3 and an earlier version
02:27of Python installed on your system that you are running the correct Python when
02:34you run the setup.py.
02:36If for example you were to run Python 2 and the setup and install,
02:41your module would be installed in the path for the Python 2 and not in the
02:44path for the Python 3.
02:45So you want to make sure you are running the right Python when you do this.
02:48And so in this case that's by using this directory and then Python and
02:54setup.py and install.
02:56So I am going to go ahead and run that, and there it is it's built it and it's
03:02copied it into the site-packages directory, which is where all of your user
03:07installable packages are installed.
03:10And again if you are on a UNIX system or on any different operating system that
03:13will be in a different place, but it'll be called site-packages just like that.
03:18Let me go ahead and change to that directory so we can see what happens here.
03:26So this is the site-packages directory on this system, and you see it just has
03:30this one module installed.
03:33And it installs this egg-info, which is just a lot of information about the
03:37module, and that's useful.
03:39It installs the .py file and then it also installs this .pyc file.
03:45What that is is a complied version of the module.
03:48So that when it's run it's actually a little bit more efficient, and this
03:52happens at install time.
03:53So we'll go ahead and switch to Eclipse now and we'll take a look at how we use this.
04:00Make a working copy of modules.py. Call that modules-working.py.
04:08We'll open that up and instead of import sys here we are going to import
04:17bitstring, and we'll go ahead and use it. Set a variable.
04:25Now I have already read the documentation from the module.
04:28That might be the first thing that you'll want to do. a = bitstring.BitString(bin =
04:3301010101, and I want to put that in quotes because that's a string.
04:42So what this does is it allows you to find binary patterns using strings
04:46and then use those.
04:49We'll go ahead and print it in some different forms. a.hex, a.bin, a.unsigned
04:58integer, and we'll save that and run it.
05:03And there we have successfully installed and used a module that we've found on the PyPI index.
05:10So the PyPI index is a very useful thing and you want to be careful of course
05:15because a lot of people submit modules and they are varying quality, so you
05:20want to do a little bit of vetting.
05:21Or you may just want to download some modules and look at their source code and
05:25learn how other people do things.
05:26It's a very valuable resource.
05:29And again it gives you the opportunity to leverage other people's work and to
05:33not be reinventing the wheel.
05:35So do take a look at the Python index at PyPI and become familiar with what it
05:41is and how it works and add it to your quiver of tools.
Collapse this transcript
Creating a module
00:00Oftentimes as you are writing code you'll find pieces of code that you want to
00:04reuse in different projects. For this you'll want to write here own modules.
00:08So let's take a look at how we do this.
00:11For example, if this is my homepage and if you look down at the bottom of the
00:15page you'll see that it tells the time and it says it in words.
00:18It says it's twenty past three.
00:21Now, I did this with a Python module, and we're going to take a look at that
00:25module, and here it is.
00:27Now, the point of this is to show you how to put the code into the module.
00:31We'll look at the details of the module in another lesson.
00:34But for now let's see that it has this class numwords.
00:39But for now let's just look at from the perspective of how we put the code into a module.
00:44So you'll notice that it has this class numwords, and this formats a number into words.
00:51And it has this other class saytime_t that inherits numwords and that
00:57class is for formatting the time as words.
01:02And then it has a special version of saytime as a wrapper for using a time object.
01:11And it has a main function, so that it can be run from the command line.
01:15And it has a test function for testing.
01:19And so all of this is put in a normal file and really there is nothing
01:23special about the file.
01:25In fact, if I run it-- we'll go ahead and do that.
01:30You see that it gives the time right now, twenty-eight til five.
01:34It can also be run with an argument that hasn't run these tests.
01:39And in Eclipse, so a little bit of a production to get it to do that, to come
01:46over here and give it an argument, say test, and Apply and Run, and then it runs
01:56it in test mode.
01:57And you'll see if I do that from the command line, I just give the word test on
02:01the command line, and it runs all of these tests.
02:04It tests all the numbers and it tests the time.
02:07I'd like to do things this way.
02:09You can also use the unit testing module that comes with Python.
02:13And so I have a lot of results that I could look at.
02:16So the module itself you just write it like you write a normal script.
02:20You write your script and in the process you write whatever classes you're going to write.
02:27And you think about how it will be accessible from the outside world.
02:30And then when it's time to use it as a module you'll notice down here at the
02:34bottom it has this if _name_ pattern, we've seen this before.
02:38And that prevents the main code from being run when it's imported as a module.
02:42So I don't have any code that's outside of a function.
02:45And that's generally true when I write a script any way.
02:49And here is the script on my web site.
02:51It's a very short script.
02:52That's the entire thing.
02:54And all it does is it imports time, because it grabs the time as a localtime
02:59variable, and it also wants to be able to format that time so that it can format
03:04the date and time as well.
03:06And it imports the saytime module and it calls that here.
03:10It says "In Phoenix Arizona, it is now," and it has the saytime words.
03:16And it has the formatted date, on day of the week, and the day, month, and year.
03:22And so when we run that you'll see it has the CGI header because this is
03:27included in a page as a server side include.
03:31And it says, "In Phoenix, Arizona, it is now," and it gives the time, twenty-six
03:34til five, on this date.
03:38And so when you have code that you want to reuse you're going to want to put
03:43it in a module and when you put it in a module it's really just like writing a normal script.
03:49You just need to be careful that you don't have any code that's outside of a
03:52class or a function, and you want to have this pattern down here at the
03:56bottom for running main.
03:57So that you have some way to test it or as I do with this one, to actually
04:02just use it as a script.
04:04Let's go ahead and take that out. It's still got the argument in there.
04:09So that when it's not run with the test argument it just runs it as a script and
04:13it gives the time so you can include it in a shell script or you can use it in a
04:17lot of different ways.
04:18So I'm looking for flexibility when I do this.
04:21But that's essentially all there is to it.
04:23You just put your classes in there, set it up with the pattern at the bottom so
04:27that it only runs main when it's not imported, and so it doesn't do that when
04:30it's imported and then your class becomes available to other scripts.
04:35And you'll see a lot of examples of this as we go through the projects later
04:38on in the course.
Collapse this transcript
18. Debugging
Dealing with syntax errors
00:00As you are building code in Python, you may occasionally make a typo, or
00:05misplace a punctuation mark or forget a comma or something like that.
00:09The Python interpreter will do its best to try to guide you to where the errors
00:14are and sometimes it's helpful and sometimes it's not.
00:18Let's take a look at some examples here.
00:20There is a file in your debugging folder called saytime-errors.py. We will
00:26go ahead and make a working copy of this and we will call this
00:30saytime-errors-working.py.
00:35I will go ahead and open that working copy and this is the saytime module and it
00:41has some errors in it.
00:43So we will go ahead and we will run it and see what happens, and it's flagged
00:48a syntax error here.
00:50It says Syntaxerror:
00:51invalid syntax and you see that little caret is pointing at the second
00:56quote mark on line 26.
00:58So, we will scroll down here to line 26 and you see a little red x there and if
01:08I hold my cursor over the red x, we are getting a different error message and
01:13this is because Eclipse is doing its best to help too.
01:17So Eclipse is looking at it from the perspective of syntax highlighting and
01:23Python is actually trying to run the code.
01:26So, looking at it from two different perspectives they are going to give you two
01:28different perspectives.
01:30You know they both might be helpful and they might not.
01:32We are going to focus on the Python error messages here, because you are not
01:36always going to be coding inside of Eclipse, and the syntax highlighting
01:40parser is not always going to be as helpful as the parser that's trying to run the code.
01:45So, in this case, it's pointing at this character here.
01:50So, let's see if we can get the entire statement here on the screen and it
01:54starts here with _words = and it's got the opening curly brace and that ends
02:01down here with this closing curly brace.
02:03So the curly braces mean that this is a dictionary definition and you see
02:08there is our first key and a colon and there is a tuple object as the value and a comma.
02:17So, what we have here is a dictionary definition and we looked down here at this
02:22line with the error on it and we see there is colon there and there is the quote
02:28and there is the opening quote.
02:29It's not really obvious that there is anything wrong with it.
02:32That quote does not look like a problem.
02:34Even though the syntax error is pointing at that quote, that quote does not
02:39look like a problem.
02:40So let's look at it in order. Let's go through the process of looking at this
02:46whole definition and see if we can figure out what's wrong.
02:49So this is the first key and then there is colon. The value is that whole tuple
02:54object and then there is a comma and then there is another key and a colon and
03:00then the value, which is another tuple object, and a comma.
03:03So, we are seeing a pattern here.
03:05Key, value, comma, key, value, comma, we are getting closer, and here is a key
03:14and here is a value and there ought to be a comma there, because this looks like another key.
03:21So, we will put that comma in and we will save the file.
03:25We notice that the red x goes away.
03:26That's a good sign and we run it, and we get another error message.
03:31But this one is on line 70.
03:33So it looks like we have fixed this syntax error.
03:37You see the little red mark over here that's probably line 70, sure is, and we
03:44have a different error message.
03:46This one says, IndentationError:
03:49unindent does not match any outer indentation level.
03:53So it says it's an indentation error and we see we have another dictionary
03:59definition and all of that looks okay.
04:03You see a little red squiggly mark from the syntax highlighter.
04:07It's trying to help us there, but it's actually covering up the problem.
04:12You will notice that under those little red squiggly marks, there is an
04:15underscore and that underscore is indented farther out than the code above it,
04:20and so if we push that in one character and then save the file, see the red x goes away.
04:28Now we can see that underscore and we can see that indentation level.
04:31So that was an indentation error.
04:33You will notice that it's pointing at the wrong character here.
04:38If it was pointing back here, it might have been more obvious.
04:41That's typical of parsers everywhere.
04:43They will do their best to show you where the error is and more often than not,
04:48they are off by a few characters and sometimes even a few lines of code.
04:52So go ahead and run in it again and now we have another error, and this one says
04:58it's on line 118 or line 129.
05:02We have two errors being printed out here and what this is doing actually, we fill
05:09the screen with this, this is what's called a traceback in Python.
05:15It's telling where it encountered the error and it's tracing back its execution.
05:19So this is actually a runtime error.
05:21This is not syntax error.
05:23It says AttributeError, 'built_in_ function_or_method', object has no
05:28attribute 'tm_hour'.
05:30Here it is trying to assign this t.tm_ hour to a variable, self.hour, and that's at line 118.
05:41So, let's take a look at 118 and there is the line of code, and so what's
05:49happening is t here is an object that's getting passed into this constructor and saytime_t.
05:56So what's the line above this?
05:59Scroll back down here and a line above this is print saytime_t and this is at line 129.
06:06So let's go down to 129 and there it is. And so it's passing this time.local time
06:15and I happen to know that local time there is a function.
06:20It is not an attribute.
06:23So it's correct here, object has no attribute, ?_hour, and that's because we
06:29didn't call it with the function. The function has the attribute.
06:33So if we save this and run it again, now we get something else. This is not
06:38printed in red which means it's not being sent to standard error, which means
06:42it's not really a runtime error.
06:44This looks more like another kind of an error.
06:47It says bound method saytime.
06:49This is actually the output of this print statement here.
06:52It's printing a bound method, rather than running the bound method.
07:00So you see here .words.
07:02.words is supposed to be a method.
07:06It's actually a method in one of our classes here, there it is.
07:12See it's a method here, def words, and so what we need to do, see just like the one up here.
07:22It needs to have parenthesis.
07:22So we will save that and we will run it and our script works as we expected.
07:30So that's pretty much the process that you have to go through.
07:33If you type a whole bunch of code and it's not working the way that you expect
07:37it to work, you need to have some patience. You need to look at carefully and
07:41objectively and sometimes from myself, if I am not seeing and I will go and do
07:47something else, clear my head and come back and look at it.
07:51Usually at some point after I have cleared my head enough and I look at it
07:55enough, the errors will jump out and at me.
07:57These are the common type of syntax errors that you will run into in Python,
08:01things like forgetting parenthesis, indentation errors, forgetting commas, things like that.
08:06So you can start with looking for those sorts of things.
08:10Just have the patience, try and follow the code in your head, and eventually you
08:16ought to be able to find the errors and correct them.
Collapse this transcript
Dealing with runtime errors
00:00Sometimes when running error into your code, they won't be syntax errors.
00:04instead they will be errors that don't show up until you try to run the code.
00:08We call these runtime errors.
00:10And we got some examples here.
00:11Let's make a working copy of this mvc errors.py, and we'll call
00:18this mvc-working.py.
00:24Open up that working copy and here we have demonstration file of a mvc model.
00:32mvc stands for Model View Controller, and if we run this and look at the output,
00:42you'll see that things aren't quite okay in the first forest here.
00:47So couple of places we have this bound method being printed out
00:54and that is not necessarily what we are looking for.
01:00So let's see we can hunt this bound.
01:02It says bound method Duck.feathers, bound method Person.feathers,
01:08bound method Dog.feathers.
01:10And so here is the feathers method. This gets inherited. We have Duck, Person
01:16and Dog and these are all inherit animal actions and the animal actions has
01:23the method feathers.
01:25So like it's inherited into these different classes, and that's getting
01:29printed out some place.
01:30So when we see this string in Python that says bound method blah, blah, blah,
01:35that means that you are trying to print a method, rather than calling it in.
01:40It usually means missed parenthesis.
01:43That's the most common thing here.
01:45And so Ecllipse is actually helping me here. Because I put my cursor on
01:50feathers up here, it's highlighting all the places where it sees the word
01:53feathers, and so this is jumping out at me here, and you'll notice that it's
01:58missing the parenthesis.
01:59So if I go ahead and put those parenthesis in, see I was printing the method
02:04instead of calling the method and printing what it returns.
02:06So if I save that and run it, now we don't get that error any more.
02:12And we have quack, the duck has no feathers, the person imitates a duck, and I am
02:18going to just say, "wait a minute, the duck has no feathers?" Ducks have feathers.
02:23And I know that I typed in feathers for the duck.
02:27See, the duck has gray and white feathers, and so why is it printing it this way?
02:33Well, you'll notice that the feathers method cause doAction for feathers and what
02:39doAction does is it looks for the strings with the action, and so the strings is
02:45defined in each of these animals.
02:49So I have strings here, strings there.
02:51So this is where strings are defined and it's looking for feathers, which is spelled wrong.
02:58And if I correct that spelling and save that and run it
03:06and we will look at our result here,
03:07we now see that the duck has gray and white feathers
03:11So often times it's a typo like that and these kind of things can be hard to find.
03:16The trick is to go through the code, to follow the execution path of the code,
03:22and to say if this gets called by that, that gets called by this, this is the
03:25way that's supposed to work and just take your time and be patient and try not
03:30get flummoxed by the error.
03:32I like to say the computers have infinite patience.
03:35It will sit there and stare at you with the error for as long as it takes.
03:39The trick is for you to try and gain as much as patience as the computer has in
03:43order to be able to find the errors.
03:45So often times these things just take patience, but the methodology is to go
03:51through the execution of the code and to look at all of the pieces that are
03:55supposed to fit together and try and find out piece that's not fitting together
03:58the way that it is supposed to.
Collapse this transcript
Dealing with logical errors
00:00Sometimes when you run into errors in our code.
00:02It's not a syntax error.
00:04It's not a runtime error.
00:06It's just that the code doesn't quite do what it was that we had intended for it do.
00:11These things are often also caused by typos.
00:15So let's make a working copy of, incrange-errors.py and we will call that
00:21incrange-errors-working.py.
00:26This is our inclusive range method from another example in this course.
00:34There is the code, and you will see that it calls it down here, and we will just
00:41run it and see what happens.
00:42Well, nothing happens.
00:44That's not a good sign.
00:46So why would nothing happen?
00:47Well, what's supposed to happen?
00:49The object gets initialized and it gets constructed with these parameters,
00:54a start, a stop and a step of 4, 25 and 3, and then it gets printed out by
01:02using the object as an iterator, and we can see right here, here is the iterator function.
01:09It's go a yield here, which makes it a generator, so that looks like it should work.
01:14We have the start, stop and step, and so here is the start and the stop and the
01:20step, and let's just run through the code here and see what happens.
01:24I am starting here because this is where the print is, and this is also just the
01:29shortest and easiest to look at piece of code. I happen to know, because I wrote this,
01:33that this is a little bit more of a hornets nest, and so I am just going
01:38to start here because it looks like a simple place to start.
01:42This is where the action is actually happening here.
01:44So i equals start, while i is greater than or equal to and that doesn't look right,
01:52because the start is at 4, and the stop is at 25, so I would want to run
01:58this loop while i <= stop.
02:03So that looks like a typo, and so I will change that, and I will save it and run it,
02:09and now we are getting some output here.
02:12So let's look at the output and see if it is correct.
02:15So we have this range.
02:17It starts at 4 and over here we are starting at 3. That's not right.
02:21And it stops at 25. Okay, well, that's plausible, and the step is 3, so 3+3
02:29would be 6, 7+3 would be 10.
02:33This is actually stepping by 4.
02:35It's starting at 3 and stepping by 4.
02:38So it would appear that I got those 2 swapped some place.
02:43So let's look at the code and see how this works.
02:46So we have numargs, which is the length of args.
02:50So that's the number of arguments that I am passing in and if numargs is
02:54less than one, we have a TypeError. If numargs equals to one, so I have three arguments.
02:59So let's just step down here to numargs equals three and so I
03:03assign them like this.
03:05Step, stop and start equals args.
03:07Well, that's not right.
03:08Its start, stop and step is what it should be.
03:11So I will switch those. Those got swapped just like I thought. start, stop and step.
03:21And that looks like it should fix it. I will save that and run it, and here we
03:30have a different result.
03:31Let's see if this looks right.
03:33It should start at 4.
03:34It is starting at 4.
03:36Stop at 25, that looks right, and the step is 3. So we have 4,
03:417, 10, 13, 16, that looks right.
03:45So now it's working as we expected.
03:49At this point I would test the other ways of passing parameters, test some
03:54other corner cases.
03:56I happen to know because I made these errors that that's the extent of
03:59the errors in the file.
04:00So the trick is like so much of debugging to be patient, to follow the execution
04:05of the code, to look at what's supposed to happen that's not happening, to look
04:09at what's happening that's not supposed to happen, and through patience and
04:13perseverance to find those little typos, and really the key here is the
04:18patience and perseverance.
04:19Sometimes this can just take a while.
Collapse this transcript
Using unit tests
00:00The Python standard library includes a unit test module that's very powerful and
00:04very flexible and is also very easy to use.
00:09Unit tests are valuable for a few reasons.
00:12Unit tests are automated tests that you can run on your code and you can write
00:16these tests once and save them and run them over and over.
00:18So if you have a set of code that's got a lifetime to it, that over the course
00:22of its lifetime it gets updated, it gets changed, having these unit tests
00:26already written and being able to run these unit tests on your code is going to
00:31have some real value for you.
00:33So let's look at how this is done in Python.
00:36I've got the saytime module here, which has been used for a number of different
00:40purposes in this course.
00:42And you'll notice at the end of it it's got a little test function.
00:48And when I wrote this, this just seemed like the easiest way to do it.
00:51And it's also, I like to be able to look at the results and say yeah, that looks right.
00:55That looks right. That looks right.
00:57If this were anymore complicated or if it was going to have much of a
01:02development lifecycle to it, I would use unit tests instead.
01:05And so we're going to go ahead and do that.
01:11This is a unittest script that I wrote for saytime.
01:15And I basically took those textual tests and I made them into unit tests.
01:21And this is very, very easy to do.
01:24All I do is I import saytime and I import the unittest.
01:27So this is the module that I'm working on and this is the unittest framework
01:31from the Python standard library.
01:33And then I create this class.
01:36And then at the end of the module here, if __name == "__main__", instead of just
01:40calling my own main, I call a special main that's in the unittest package.
01:45And in the unittest package, the special main will actually open up this file
01:50and parse it and find the classes that import unittest, and it will go ahead and
01:56run the test in that class.
01:59And so here is the class.
02:00So I can name it whatever I want.
02:02And it has a special method called setUp.
02:05In this special method setUp, I can do any initializations that I want to.
02:08And so here I've created this list of numbers.
02:10I could have just as easily put that in the test for the numbers, but I wanted
02:13to demonstrate the setUp here.
02:16And so I take a range of 11 numbers, from 0-10, and I make a list out of them,
02:22and I assign them to this variable here.
02:25And so that gets used in test_numbers.
02:27So here is the first method.
02:29These methods will get run as the tests.
02:32So the first method here is test_numbers.
02:34And I've got some words that I'm going to compare those numbers again.
02:37And these are the words that will be the results of my saywords numwords.
02:42So 'oh', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
02:43'ten', those are the results that I'm expecting.
02:48And so I enumerate through the self.nums.
02:51I get both an index and the number itself.
02:54And then I run this assertEqual method, which is from the unittest package, and
02:59it's going to compare two values.
03:02And if these two values are equal, then fine. It will leave it alone.
03:06And if they're not, then it will throw an AssertionError.
03:08And so here the two values are the result from my saytime.numwords and the word
03:16from this tuple here.
03:18If they equal, then fine.
03:20And if they're not equal, then it'll throw an AssertionError.
03:23And so the same thing here, test_time. I have time_tuples.
03:27And so this is a tuple with a bunch of tuples in it.
03:30And these are the times that I'm testing against.
03:32And these are hours and minutes.
03:34And then here's the list of the results that I want, "midnight", "one past
03:37midnight", "eleven o'clock", etcetera.
03:40And if they compare equal, it's the same thing.
03:42I enumerate through the time_tuples.
03:44I run them through the module that I'm testing and I compare them to this tuple
03:51up here of these words.
03:53If they're equal, fine.
03:54If they're not equal, it throws an AssertionError.
03:56So this is how this works.
03:59And obviously you can write your own tests.
04:02There are a number of different assertion tests.
04:04You can find those in the documentation for the unittest module.
04:07I strongly recommend that you read the documentation for the unittest package.
04:12It's got a lot of options.
04:14It has a lot of methods that you can use for your testing.
04:17There are a lot of different assertions that you can test for.
04:20And it even has some ways to do some more complicated tests.
04:24This kind of test that I've written here is the simplest case.
04:27And for most purposes, this is actually just fine, and it does the job and
04:32it does the job well.
04:34So let's go ahead and run it.
04:36When we run this, you'll notice that we get our little test.
04:39And we've been just selecting Python Run for all of these.
04:42There's a special one here in the PyDev module for Eclipse.
04:45It's called Python unit-test.
04:47And we're going to run that one. Say OK.
04:50And here it ran our unittest.
04:52We'll maximize this so we can see what it does.
04:55First of all, it finds files.
04:57And it finds the test-saytime.
05:00And that's our unittest module that we just wrote.
05:04And it imports the test module.
05:05So it's importing the saywords.
05:08And here it runs the two tests, test_numbers and test_time.
05:11It ran the two tests.
05:13It didn't throw any assertion errors.
05:15And there's the result that we're expecting.
05:17If it had not gotten the result that it wanted, let's just go ahead and misspell
05:21one of these words here.
05:22I'll just throw an extra o in there.
05:24We'll save that and we'll run it.
05:26And now we got one failure.
05:28You see it got an AssertionError that oh did not equal to ooh.
05:34So it gives us enough information here that we can actually go through the code
05:38and we can say, oh, well, I've got a typo in my assertion test or there's an
05:41actual problem in my module that I need to go and fix.
05:45So the beauty of this is, is that as your code goes through its development
05:49lifecycle, you make one release.
05:51You make another release.
05:52You make another release. You add features.
05:54You take features away.
05:55You change features.
05:57Your unit-tests are already written.
05:59And so you can accumulate more.
06:01You can change them.
06:02And this is going to help you to keep the quality of your code high throughout
06:07its development lifecycle.
06:09So unit-tests are very useful.
06:11The unit-test package that comes in the standard Python library is very complete
06:16and very well written and very reliable.
06:18If you're going to be releasing your code using Python, you must
06:21submit unit-tests with it.
06:23And of course the unit-tests are going to be of value to you in any code that
06:27has a lengthy product lifecycle.
Collapse this transcript
19. Building a Database Application
Normalizing a database interface
00:00As you build applications in Python, you are probably going to find that you use
00:04databases quite a bit and so you will probably find some value in having a
00:09normalized interface for working with your databases.
00:13I have built such a normalized interface and you are welcome to use mine but I
00:16would suggest that you simply use this as a model and build your own.
00:20Build one that works for you, that works for the way that you like to work with databases.
00:24So I will show you mine as an example.
00:27It's called bwDB.py and it's in the lib folder, in the 19 Projects folder in
00:33your Exercise Files. So go ahead and open that up and we will maximize this so
00:39that we can take a look.
00:40Of course it imports SQLite3. This is a library for using SQLite3, like I said.
00:48For most of my web applications these days I am using SQLite3, because it's
00:54small, it's fast, it's self-contained, it's easy and it's very robust and
00:59reliable. I've never had any problems with it.
01:03So there is a class here called bwDB and the first thing in it is the
01:08constructor, and the constructor simply takes this keyword arguments and it
01:13looks for the file name and the table name.
01:15You will notice that in each of these methods I have what's called a docstring.
01:19If the first line in a function or a method is just a string by itself this is
01:25picked up by Python's documentation protocol and it's called a docstring.
01:29I use it to describe how the function works.
01:33So this is the constructor method, the table is for the CRUD methods and you don't
01:37have to use that. I will get to that in a moment.
01:40And the file name is for connecting to the database file.
01:45Here is one of my workhorse methods.
01:47It's called sql_do. This is for non-selective type queries.
01:52You just pass it in some SQL, you pass it in some parameters, and it does its job.
01:57This next one, sql_query, is the same thing except that it also works as a
02:02generator and it will iterate through set of results, and of course each
02:08result is a row factory.
02:10You will notice that the constructor assigns file name here and file name is
02:16actually a property, which is defined down below, and we have seen this technique
02:21already. And so in the setter when a file name gets assigned it sets the
02:27attribute in the object.
02:29It also connects to the database and it sets up the row query.
02:33So this is actually a constructor of sorts but it allows you to change files if
02:39you want to. If you are using the object and you decide that you need to assign
02:43this object to a different database file, first of course, it will call the
02:48Destructor which closes the old database, and then it'll call this constructor
02:52for the file name and it will connect to the new database.
02:55This works really, really well.
03:02We have and sql_query method for returning a single row, and we have an
03:06sql_query method for returning a single value.
03:10I find these very useful and I use them a lot.
03:12Again depending on how your pattern of dealing with database is, you might
03:16find different things useful and I would suggest that you use those.
03:20Now we get into the CRUD methods. CRUD stands for create, retrieve, update and delete.
03:25These are the basic four functions of a database.
03:29So this is the getrec that just would be the retrieve part of CRUD, and for my
03:34CRUD methods I depend on their being a column in the table that's called id.
03:42So all of my tables and all of my applications that are going to use these
03:46methods must have a column called id.
03:49I typically create this column in SQLite using the integer primary key feature
03:54which makes that column an equivalent for SQLite's internal row id.
04:00This all just works very nicely together and you will see examples of this in
04:04the projects that we are going to look at in this chapter.
04:11Getrecs is a method that returns all of the rows in the table and it returns it
04:15as a generator with row factories.
04:19Insert inserts a record and this uses a dictionary for the record.
04:24This is actually very interesting.
04:26This method constructs the SQL based on the names of the keys in the dictionary
04:31object that gets passed.
04:33So it takes a little bit of care to work with it but when you use it with care
04:37it works very, very well.
04:42This next method works the same way. Again it constructs the sql_query based on
04:47the keys in the dictionary object that gets passed and this will update a
04:53particular record based on an id that's passed.
04:59Finally we have the delete method where it deletes based on the id, deletes the
05:05row from the table based on the id and a countrecs method that simply gives us a
05:12count of all the records in the table.
05:14This is a very fast operation to do in SQL.
05:18Most database engines including SQLite are very highly optimized for count operations.
05:26So this method offloads that work to the database engine and allows it to
05:30happen very quickly.
05:32Finally we have the property accessors for the filename property and a close
05:37method for closing the database.
05:40Then we have a test method for testing and we will go ahead and run that.
05:50And that creates a database in memory.
05:53Sqlite has a feature where if you give the filename as this with colons
06:00on either side of it, that whole thing is the filename then it will
06:03create a database in memory.
06:05Creates a table, inserts into the table, reads from the table, updates a table.
06:08Exercises all of the CRUD methods.
06:13So that is my example of a normalized database interface. I find this very
06:19useful and you'll see an example of it here in this chapter of how I use this.
06:24It makes it that much easier for me to work with databases in my applications,
06:29and these days in the little web applications that I might be working on it
06:33saves me a lot of time in work and allows me to focus on the logic of the code.
Collapse this transcript
Deconstructing a database application
00:00The four basic functions of a database are create, retrieve, update and delete,
00:05often pronounced as CRUD.
00:07This is an example of an application that does those basic four functions.
00:12Of course there is a lot of functions that people perform with database, there is a
00:14lot of things that they are used for, and as you are writing code over the years
00:18you will be writing databases for a lot different purposes.
00:21But they all basically break down to those four functions.
00:24So those are the things that if you pay attention to those things, then building the
00:28more complex applications becomes a little bit easier.
00:31So this is an application that just does that.
00:34It manages as a very simple database and it simply allows you to add records,
00:38edit records, and delete records, and view records.
00:42So those are the basic four functions create, retrieve, update and delete.
00:46What this application does as it manages a Testimonials database that I use in
00:51my web site and you will see if you look at my web site, you will see little boxes
00:54like this one over here that have testimonials.
00:57For our purposes I have replaced the testimonials with some witty little quotes
01:01that I have collected over the years and here is the database itself.
01:06This has got 14 records in the database and if you wanted to add something and
01:15print a byline and click Add, you will see that it adds it to the database right
01:24here, and then I can edit it, if I want to.
01:30Update it and there it is updated in the database.
01:34And if I want to delete it, I can delete it.
01:38It's all very simple to operate and very clear, and this comes from it being a very
01:45simple application and also from it being designed clearly.
01:50So, here in the Example files, under Projects and under testimonials, you will
01:56find db.py and that is that script right there.
02:01See down here,it says db.py version 1.13.
02:05So that is this script right here.
02:07So we are going to take a little tour through this script and see how it works.
02:12At the top here you see that I imported a few libraries that start with bw.
02:17These libraries are available in the lib folder under Projects and these are
02:23libraries that I have built over the years, and there is this global namespace container.
02:32I tend to do this in all of my web scripts because it helps to keep state in
02:37otherwise stateless environment, and it helps me to keep my global name space cleaned up.
02:43So I use a dictionary for that in Python, and I have here a call to init, which
02:50initializes these variables, again helping to keep state and to set up my various
02:55objects and to read my configuration file and things like that, and then I look
03:00for a variable a in the CGI variables.
03:03If I find it, I run something called dispatch. Otherwise I load the first main page.
03:09So what dispatch does is it simply looks for what is the action, a stands
03:14for action, what is the action that's been taken and it will dispatch the
03:17proper function for that.
03:20If these get any bigger I actually have a library that runs a jump table that
03:24will do something like this.
03:25So I tend to do a lot of work on the web.
03:28I tend to use CGI a lot.
03:30CGI being stateless the way that it is, the web and HTTP being stateless, that
03:35helps to have things like this to manage a little bit of a state machine.
03:42The main part of the application lists these records.
03:45So this is the retrieve part of the four functions of the database.
03:50So the first thing this does is it grabs a count of the records in the
03:54database using the countrecs method in the database library and that very
03:59quickly and efficiently returns a count all of the records and that allows
04:02us to do some math here and figure out how many we are going to display on the page
04:06and how many pages there is going to be and then we set up this little
04:10menu here which is this part here that tells us, we can jump to a specific
04:14page or we can go back and forward.
04:17So that's very useful.
04:21Then we have our little bit of SQL and this actually does the retrieval.
04:25SELECT From ORDER BY byline and LIMIT and OFFSET.
04:31And in SQLite, limit and offset allow us to only get the first so many records
04:39and if it's not on the first page, then to skip forward to an offset first and
04:45then get that many records, and it will do this on any query.
04:48Most modern database engines have some way of doing this.
04:51It's not a part of the SQL standard so they all tend to be a little bit different.
04:56This one, SQLite actually, uses a very similar syntax, I don't think it's exact,
05:01but a very similar syntax to how it's done in MySQL and those are the two really
05:06popular ones for web applications these days.
05:09So that's how we do the paging and we make that list at the bottom of the page.
05:14The pagebar itself with the various links is there and displaying pages is here
05:23and then we get down to the actual actions.
05:27Adding a record to the database, it simply builds this dictionary object and
05:32passes it off to the insert CRUD function in my database library, which I explain
05:37in another movie in this chapter.
05:40Likewise, the delete function calls the delete method in the database library
05:50and the update function calls the update method in the database library.
05:57Using these CRUD methods in my normalized database library allows me to keep
06:02this code very small.
06:05Each of these function uses exactly the same data structure.
06:09It uses this dictionary.
06:11It uses an id field that's called id, and this allows the methods in the
06:16database library to do there job.
06:20So, let's take a quick look at those methods and this is the database library, bwDB.
06:31So the insert method here, it takes the dictionary object and it actually goes
06:36through the dictionary object.
06:40It grabs all of its keys and then uses this generator expression to create a
06:46list of all the values.
06:48And so it has got a list of the keys and it's got a list of the values.
06:53And then it uses those two lists to build the SQL using the strings format
07:01method and then it passes that SQL query off to the database.
07:06So this allows us to use a dictionary object and to build our query based on
07:12the names of the keys in that dictionary object and to use that so that we
07:17can use the same code for different applications that have different database schemas.
07:23So, the same technique is also used for update.
07:29Where again, we build a query based on a list of keys and values.
07:36Keys and values.
07:41The other methods like delete(), they only need the id.
07:44So that makes that a lot easier.
07:47So this is a very useful technique where you can use normalized code for a
07:51number of different applications with different database schemas.
07:54And by using that normalized code and some simple coding conventions, you can
07:59keep an application like this, down to about 250 lines and still have it look
08:04and operated like something a lot bigger and a lot more complex.
Collapse this transcript
Displaying random entries from a database
00:00Here we have a simple database application that displays a list of random
00:04testimonials or quotes on a web page.
00:07If you look at my web page, I actually used this for testimonials.
00:10And every time the page gets reloaded, it pulls up three different quotes from
00:15the database at random.
00:17The database itself is managed with this application that allows you to go
00:22through and add, edit and delete entries in the database.
00:26We'll look at that in a separate movie in this chapter.
00:29In this chapter, we're going to look at how this application works ,which
00:34retrieves the quotes from the database and displays them at random.
00:38So in the Projects folder, in your Exercise Files, in the testimonials folder
00:43and you'll find testimonials.py.
00:46And this is actually exactly the same script that is on my web site.
00:49This is the script that reads the quotes from the database and displays a
00:54number of them at random.
00:54It's a very short script.
00:57It's just 73 lines long, including the white space and comments and everything,
01:02and here's how it works.
01:03The first thing it does is it initializes some variables.
01:09It reads the configuration file to find out where the database is and
01:12everything, and opens up the database.
01:15And all that happens here in this init function.
01:19Here it reads the configuration file there and it opens up the database here.
01:24And this uses libraries that I've also included in the Lib folder.
01:30bwDB for my normalized CRUD oriented database functions, and bwConfig for
01:38reading the configuration file.
01:39bwConfig is a very simple library.
01:43It reads these configuration files in a format that I had already been using for
01:47a long time with my Perl work from before I was working on Python.
01:51And so I just wanted something that would read the same configuration file, so I
01:54could start replacing a lot of my Perl scripts with Python scripts, and it was
01:58just very easy for me to write that.
02:01And the application itself mostly takes place in this one function, in main.
02:06The first thing it does is it goes out to the database and it grabs a list of
02:10all the IDs, and it does this with this sql_query method which returns a
02:17generator which iterates through the results.
02:21And iterating through results, I simply take all of these IDs and add them to this list here.
02:30I'm using a list because I need to be able to delete things from it later.
02:34So a tuple would have been immutable.
02:36Then I want to know how many records I'm going to be displaying and so I
02:40look for the query string and if there isn't a query string, that just default to five.
02:46And we'll notice, if we look at the HTML for the page that has those quotes on it,
02:54 you'll notice this is called with this little bit of server side include and
02:59so it's called testimonials.py with a query string set to 3.
03:05And so, that's why we have three of them displaying on that page.
03:09And then, I check and see if we have enough in the database to be able to
03:13display a decent number randomly.
03:15I like further to be at least four times as many records in the database as
03:19those that I am displaying. Otherwise I really don't want to bother doing
03:22something random because it's not going to look random.
03:27Now we simply take the list of IDs and using the random library, which gets
03:36imported up at the top here.
03:38This is in the standard Python library.
03:42It creates a random integer based on the size of the list minus one, and it
03:49grabs a random item from the list of IDs, and then it deletes that from the list
03:55and adds it to the list of result IDs, which is initialized here.
04:01Then once it has that list of result IDs,
04:04it simply iterates through that list and prints the record with that ID.
04:08And printing a record with that ID, it uses the CRUD function getrec and then
04:13it simply grabs the data out of the resulting row factory, indexing on it as if
04:18it were a dictionary.
04:19We'll go ahead and run this here.
04:21Well for our purposes, we're going to need to reduce this little default down to a three.
04:28So I'll save that and run it, and here we have our result.
04:34We have three quotes, and if we run it again, we get three different quotes and
04:40different quotes and you'll notice that it's all coming out in HTML.
04:46So, that's how this application works.
04:49Once we have done the back end work of creating the CRUD, once we have done the
04:53back end work of creating a decent library with easy to use database interface,
04:59writing something like this becomes relatively trivial.
05:03And so, here we have it on the webpage with our random quotes.
Collapse this transcript
Conclusion
Goodbye
00:00In this course my goal was to give you a good foundation in Python, so you
00:03can use it to build powerful and compelling applications for yourself and for your clients.
00:08I've covered the basic syntax of Python, its data types, features, modules and
00:13its object model, and I've walked you through some real applications, so you
00:17can see how to apply your programming knowledge to building your own projects in Python.
00:22I've really enjoyed creating this course for you and I sincerely hope that it's
00:25as useful for you as it has been fun for me.
Collapse this transcript


Suggested courses to watch next:

CGI Essential Training (1h 33m)
Bill Weinman

Perl 5 Essential Training (6h 54m)
Bill Weinman


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,024 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked