1. IntroductionWelcome| 00:04 | Hi! I'm Bill Weinman, and I'd like to
welcome you to Python 3 Essential Training.
| | 00:08 | Python is a modern object-oriented
programming language that's well-suited for a
| | 00:12 | variety of uses, from simple
scripts to complex web applications.
| | 00:17 | In this course, I'll show you how to use
Python and how to take advantage of its
| | 00:21 | unique and powerful features.
| | 00:23 | I'll start by giving you an
overview of Python, so that you can get
| | 00:26 | started right away.
| | 00:27 | This quick start is designed for the
experienced programmer who wants to
| | 00:31 | leverage their existing knowledge to
start using Python quickly and with as
| | 00:35 | little detail as necessary.
| | 00:36 | Then we'll get right into the details of
the language, its syntax and structure,
| | 00:40 | exception handling, functions,
classes and Python's powerful object model.
| | 00:45 | I'll show you how to do common tasks in
Python, including file layout, databases
| | 00:49 | and web development, and I'll show you
how to use modules to leverage your work
| | 00:53 | and the work of others to get your
projects done faster and with less effort.
| | 00:57 | Finally, I'll walk you through some
real-world examples of working Python
| | 01:01 | code, so you can see how the pieces
fit together and to help you get started
| | 01:05 | on your own projects.
| | 01:07 | This course is designed for programmers.
| | 01:09 | If you already have some programming
experience in at least one other modern
| | 01:13 | language, this course is for you.
| | 01:15 | I've been a programmer since the `70s,
and I've used many different languages
| | 01:18 | over the years, and I'm
really excited about Python.
| | 01:21 | I'm glad to be able to share this
knowledge and experience with you, so that you
| | 01:26 | can write better applications today.
| | 01:28 | Now, let's get started with
Python 3 Essential Training.
| | Collapse this transcript |
| Understanding prerequisites for Python| 00:00 | In order to get the most out of this course,
there are a few things you're going to need.
| | 00:04 | First of all, you need a basic
understanding of programming.
| | 00:08 | This means that you need
experience writing working code in a modern
| | 00:12 | programming language,
| | 00:13 | for example, Perl, PHP, Java,
JavaScript, C++, or any modern programming
| | 00:21 | language, and you need some
understanding of object-oriented programming.
| | 00:25 | You don't necessarily need to be an
expert, but you need to at least have an
| | 00:29 | understanding of what it is, and why it is.
| | 00:32 | You will need to have a text editor.
| | 00:35 | A text editor is not a word processor.
| | 00:37 | When you edit text using a word
processor, the word processor adds other
| | 00:41 | information to the file, information about
formatting, layout, fonts, things like these.
| | 00:47 | These things will make the program not work.
| | 00:49 | You cannot edit program
code in a word processor.
| | 00:53 | You need a plain text text editor and there
are lots of them available on every platform.
| | 00:57 | For the purposes of this course,
we're going to be using an integrated
| | 01:00 | development environment
called Eclipse for our text editor.
| | 01:04 | You do not need to use Eclipse.
| | 01:07 | Use whatever text editor
you're comfortable with.
| | 01:09 | Use whatever coding
environment you're comfortable with.
| | 01:12 | The reason that I'm using Eclipse in this
course is for the purposes of instruction.
| | 01:16 | It runs on every platform and it
allows me to demonstrate running the code in
| | 01:21 | the same environment.
| | 01:22 | You don't need to use an
integrated environment like that.
| | 01:25 | You can use a plain text editor.
| | 01:27 | Finally, you'll need a system with
Python 3 installed, and I strongly recommend
| | 01:32 | Python 3.1 or later.
| | 01:34 | The examples in this
course are using Python 3.1.
| | 01:38 | Python 3 is a significant upgrade from Python 2.
| | 01:41 | Code written in Python 2 will not
necessarily work in Python 3, and vice versa.
| | 01:48 | It's essentially the same language, but
there are some significant differences,
| | 01:51 | and this course is about Python 3.
| | 01:54 | Python 3 is easy to get and to
install. Installers are available for most
| | 01:58 | operating systems, and you can find
an installer for your operating system
| | 02:02 | at this URL.
| | Collapse this transcript |
| Using the exercise files| 00:00 | If you're a premium member of the
lynda.com Online Training Library, or if you're
| | 00:04 | watching this tutorial on a DVD-ROM,
you have access to the exercise files used
| | 00:09 | throughout this title.
| | 00:10 | The exercise files are organized by
chapter, and I suggest that you copy them to
| | 00:15 | your desktop and work with them from there.
| | 00:17 | Each chapter has number of files in it.
| | 00:20 | For example, here in the Chapter 6,
there are three files, and by and large these
| | 00:24 | files are Python scripts code.
| | 00:26 | We'll be using these
files from inside of Eclipse.
| | 00:29 | Eclipse is an integrated development
environment, and I'll show you how to
| | 00:33 | import the files into Eclipse in
the movie on installing Eclipse.
| | 00:36 | You do not have to use Eclipse
to follow along with this title.
| | 00:40 | You can use whatever editor or
whatever development environment you choose.
| | 00:44 | I use Eclipse because it's platform-
independent, and it's portable, and it's
| | 00:49 | easy to use for teaching, but you do not have
to use Eclipse to follow along in this title.
| | 00:54 | Whenever I open a file in this title, I
start by making a copy of the file and
| | 00:59 | then work with the working copy.
| | 01:01 | I do this by dragging the file while
holding down the Control key on a PC or the
| | 01:06 | Command key on a Mac and then let it go,
and this will give me an opportunity to
| | 01:12 | choose a name for the copy, and I
typically use the same name with a dash and the
| | 01:17 | name working, and end it with .PY.
| | 01:21 | By doing this and working with the
working copy, the original files are left
| | 01:25 | unchanged, and this way you can go
through the exercises again at a later time if
| | 01:30 | you choose to do that.
| | 01:31 | If you don't have access to the
exercise files, you can follow along from
| | 01:34 | scratch, or with your own assets.
| | 01:37 | So, let's get started.
| | Collapse this transcript |
|
|
2. Python Quick StartGetting started with "Hello World"| 00:00 | As we start the Python Quick Start,
we're going to use the traditional
| | 00:05 | "Hello, World!" program.
| | 00:07 | And purpose of "Hello, World!" is not
an exercise to find the simplest form of
| | 00:13 | code in a particular
language, or anything like that.
| | 00:16 | It's actually to learn about the
development environment, to learn about what we
| | 00:19 | call the development cycle:
| | 00:21 | what it takes to edit, and to test,
and to change, and to test and to run code
| | 00:28 | in a particular environment.
| | 00:30 | And so for this purpose we use the
simplest form of a program itself, so that
| | 00:35 | that can get out of the way and
then we can focus on the environment.
| | 00:38 | In this case, I've this up
here on the screen in Eclipse.
| | 00:42 | And this is Eclipse using Pydev, which
is a Python development environment that
| | 00:45 | runs inside of Eclipse.
| | 00:47 | Eclipse is an integrated
development environment originally written for
| | 00:51 | developing in Java, but it has plug-
ins for a lot of different languages.
| | 00:54 | And Pydev is actually a pretty
good plug-in for the Python language.
| | 01:00 | And so, we'll be using
this throughout this course.
| | 01:02 | You do not have to use Eclipse, and
if you have some other development
| | 01:07 | environment that you prefer, or you just
want to use an editor and a command line,
| | 01:12 | that's perfectly fine.
| | 01:13 | You can do all of the exercises;
you do not need to use Eclipse.
| | 01:17 | The reason that I'm using Eclipse is because
it's convenient for the purpose of teaching.
| | 01:22 | I've got everything that I
need right up here on the screen.
| | 01:24 | I can run code, I get the results of
code, and it works well for the purpose of
| | 01:29 | teaching, but you don't need to
use it for your development work.
| | 01:33 | And you do not need to use it
to follow along in the exercises.
| | 01:37 | In Eclipse, if I want to run this Hello, World!,
| | 01:40 | I simply click on this Run button up here,
and it'll ask me, How I want to run it?
| | 01:45 | and I'm going to select Python Run.
| | 01:47 | I only need to do this the
first time I run a script.
| | 01:49 | So I'm going to say OK.
| | 01:52 | And here we have the
result down here: "Hello, World!"
| | 01:56 | If I were running this in another
environment and I actually have this script
| | 02:00 | loaded up here on a Unix Server -
| | 02:02 | this is my Unix Server -
| | 02:04 | there is the script, you
see it's exactly the same.
| | 02:09 | And if run it I say ./hello.py, and it runs it.
| | 02:15 | An important part of this is this shebang line.
| | 02:19 | If we look here in Eclipse,
we see this shebang line here.
| | 02:23 | In many environments, mostly Unix-
based environments, but this includes
| | 02:28 | Macintosh and it includes many, many
web servers that are running Unix-based
| | 02:32 | operating systems, like Linux or PSD,
| | 02:35 | this shebang line is actually very important.
| | 02:38 | It's called a shebang line because
it's starts with a hash and then has an
| | 02:42 | exclamation mark, which is
sometimes called a bang.
| | 02:45 | And then after that it has the path to the
interpreter that will be used to run the script.
| | 02:53 | When the script is executed and the
shell sees it, it will look here for the
| | 02:58 | interpreter and then use that to run the script.
| | 03:01 | So sometimes you'll see a bash up
here, or Perl, or something like that.
| | 03:05 | And all that's doing is it's telling
the shell to use that interpreter to run
| | 03:10 | whatever script is there.
| | 03:11 | For Python, it's going to be something like this.
| | 03:14 | It might be #!/usr/bin/python3.
| | 03:16 | It might be #!/usr/local/bin/python3.
| | 03:21 | It might be #!/usr/bin/env python3, something like that.
| | 03:31 | In this case, I'm using #!/usr/bin/python3
because I know that, that works in the
| | 03:35 | environments that I'm using.
| | 03:37 | And if it doesn't, then I'll make a
symbolic link or something and make it work.
| | 03:40 | So if you're running this on
a Unix-based operating system,
| | 03:42 | you'll want to do ls -l and look at the
file permissions, and make sure that it has
| | 03:49 | executable permissions.
| | 03:51 | If it doesn't, you can make it
executable by typing chmod, or as we pronounce it
| | 03:57 | chmod 755, which makes it editable and
executable for your user ID, and then
| | 04:06 | the name of the file.
| | 04:08 | And that will make it executable.
| | 04:10 | And then you can execute it with ./ or
however it is that you do that on your system.
| | 04:16 | So that is the development
environment that we will be using.
| | 04:20 | For the most part, we're going to using Eclipse.
| | 04:23 | And so we'll be running scripts like this.
| | 04:26 | Save it and Run it.
| | 04:27 | It'll run here in the Console.
| | 04:30 | So you're going to want to take the
opportunity, using this "Hello, World!"
| | 04:33 | script, to learn about the development
cycle and whatever environment you're
| | 04:37 | using, especially if it's not Eclipse,
to follow along with the exercises
| | 04:42 | in this course.
| | Collapse this transcript |
| Selecting code with conditionals| 00:00 | So, continuing with our Python
Quick Start, let's take a look at how
| | 00:04 | conditionals work in Python.
| | 00:06 | I am going ahead and make a copy of
this conditionals.py, and it's a good idea
| | 00:11 | to work with copies.
| | 00:13 | I am just going to name this conditionals
-working. We'll go ahead and open that.
| | 00:24 | There we have an example of a conditional, a
very simple conditional. It's if and else.
| | 00:31 | And you'll notice that the
assignment - it's really cool.
| | 00:33 | In Python, you can assign multiple
values at a time, so this assigns a 0 to a and
| | 00:38 | assigns 1 to b. So that makes a nice
little test for the conditional. If a is
| | 00:42 | less than b, which it is,
then it will print this.
| | 00:46 | You'll also notice, in Python, you do
the replacement, and this is Python 3;
| | 00:51 | Python 2 works differently.
| | 00:53 | In Python 3, these curly braces will be
replaced by the values in the format, and
| | 00:58 | we'll get more into how this works
exactly, and some of the details of it, later
| | 01:03 | on when we talk about strings.
| | 01:06 | But in fact this format is a
method of the string object.
| | 01:12 | Any place where you have a string,
it allows you to do these kinds of
| | 01:15 | replacements; it's very useful.
| | 01:18 | So, when we run this - and we'll get this
one because a is less than b, and unless
| | 01:24 | we were to change these values and
then maybe we could get this one.
| | 01:26 | So let's go ahead and run it, and I'll
run it here in Eclipse, and I'll select
| | 01:31 | Python Run, and there we go.
| | 01:34 | a is less than b, and see
there is the value 0 and 1.
| | 01:38 | If I change this, if I make this say a
5, and I save that and run it, a is not
| | 01:44 | less than b anymore.
| | 01:46 | So the syntax of the conditional is, if, and
then you have the condition, and you have a colon.
| | 01:53 | This is how blocks work in Python.
You'll see this same type of syntax and
| | 01:58 | loops and functions and classes, where you have
the colon and then you have code that's indented.
| | 02:06 | There aren't any braces
signifying a block of code.
| | 02:10 | Blocks are actually called suites
in the Python documentation, and they
| | 02:15 | simply consist of code that is
indented under the level of whatever it is
| | 02:20 | that's controlling it.
| | 02:21 | So here we are controlling it with a
conditional, and we have the colon, and then
| | 02:24 | we have this code indented.
| | 02:26 | Now four spaces of indenting is
considered standard in Python.
| | 02:31 | It's actually not required.
| | 02:32 | I can make this one space and do the
same down here and it would still work,
| | 02:38 | save and run, but four is traditional.
| | 02:43 | So we are just going to go ahead and
go with the tradition here and save that
| | 02:48 | and run it, and there we have it.
| | 02:51 | Python also has conditional expressions.
If you are familiar with any C-based
| | 02:55 | languages, you'll be familiar with
something that might look like this, where you
| | 02:58 | would say print, and you would have a condition
a < b and a question mark, and then one value, and a colon,
| | 03:08 | and then another value.
| | 03:10 | If the condition were true, you would
get the first one; if the condition were
| | 03:13 | false, you would get the second one.
| | 03:15 | Python has something like this,
but it works very differently.
| | 03:18 | Here, you would say "foo" if a < b else "bar".
| | 03:26 | If I save that and run it, then we get
bar because a is not less than b. If I put
| | 03:33 | this back to a 0, like we had
it originally, and save and run,
| | 03:38 | now we get foo because a is less
than b. So this is how conditional
| | 03:42 | expressions work in Python.
| | 03:45 | A lot of the syntax that you will see
here is a little bit different than in
| | 03:50 | other C-based languages.
| | 03:52 | And that's because the designers of
Python, they didn't consider themselves be
| | 03:56 | beholden to tradition, and instead
they wanted to do things that seem to flow
| | 04:01 | better or make sense in some way.
| | 04:04 | And actually, this does have its own set
of reason in that you have print "foo"
| | 04:09 | just like you would have if
you didn't have a condition.
| | 04:12 | You only really care about having the
condition if you have another value.
| | 04:16 | So you have this whole if-else all in
one place, and it's spelled out; it's not
| | 04:22 | punctuation marks that might just
be hard to remember or hard to read.
| | 04:28 | It's very clear: "foo" if a < b
else "bar"; it's kind of readable.
| | 04:33 | So that is how conditions work in Python 3.
| | 04:37 | You have the traditional if-else, and
you have the conditional expressions.
| | Collapse this transcript |
| Repeating code with a loop| 00:00 | There are two fundamentals types of
loops in Python. There is while loops and for
| | 00:05 | loops, and let's start by
looking at the while loop.
| | 00:09 | So we'll take our whileloop.py and
make a little copy of it, and call
| | 00:16 | it whileloop-working.
| | 00:21 | Go ahead and open that, and you'll
see this is a simple Fibonacci series.
| | 00:26 | It's a common exercise for while loops.
| | 00:29 | So here we are assigning two values to a
and b: 0 and 1. The 0 will get assigned
| | 00:34 | to a, and the 1 will get assigned to b.
We say while b < 50 and we go ahead and
| | 00:41 | do things we'll make b grow in a
Fibonacci series and we print it each time
| | 00:48 | using the print function.
| | 00:50 | So if I go ahead and run this and
select the Python Run, you'll see here we get
| | 00:57 | the Fibonacci series.
| | 00:59 | So while loops just work like that.
They say while, and then there is a condition.
| | 01:04 | And as long as this condition is true,
the while loop will continue to execute.
| | 01:10 | And as soon as this condition becomes
not true, then the while loop will end
| | 01:14 | and execution will continue after it
if there is any code after it, which in
| | 01:18 | this case we don't have.
| | 01:19 | Down here I could say print ("Done") and if I
save that and run it, you'll see we get Done
| | 01:27 | at the end.
| | 01:29 | You'll notice that the print ("Done")
is not indented. If I were to indent it
| | 01:34 | here, then it would become part of the loop.
| | 01:36 | But by having it back here, at the same
indention level as the while statement
| | 01:42 | itself, then it is no longer part of this suite
of code that is controlled by the while loop.
| | 01:50 | So that's how while loops work.
| | 01:54 | Let's take a look at for loops.
| | 01:58 | Go ahead and make a copy of
forloop.py, and I'll name it forloop-working
| | 02:10 | and we'll open that.
| | 02:11 | What a for loop does is it works
with what's called an iterator.
| | 02:15 | An iterator is an object
that each time you call it,
| | 02:18 | it gives you the next value.
| | 02:21 | So in this case, we open a file and
it's this lines.txt, which we can see right
| | 02:27 | here; it just has five lines of text.
| | 02:29 | Then for line in fh, that's the file
handle, which is actually an object and it
| | 02:37 | has this method readlines, which is an iterator.
| | 02:41 | So for each time this fh.readlines is
called, it will put the next value in the
| | 02:48 | line variable, which will be the next
line of text, and then we'll print it.
| | 02:52 | So when I run it, we get these lines of text.
| | 02:58 | Now, you'll notice that there is an
extra line ending, an extra new line, in
| | 03:03 | each one of these, and that's because
the print function puts a new line at the
| | 03:07 | end, and each of these lines actually has a new
line at the end of it, so we get two for each one.
| | 03:14 | If you hover the mouse in Eclipse, you
hover the mouse over the print function,
| | 03:18 | you get a little bit of documentation for it.
| | 03:19 | You'll notice that there is an end option,
and it defaults to having this new line.
| | 03:24 | So if I just say end= ' ', empty
string like that and I save it and run it,
| | 03:32 | now, we don't have that effect anymore.
| | 03:35 | So, the for loop works likes this.
| | 03:39 | It calls an iterator, and its
values get put in this variable here.
| | 03:45 | It has a colon, like all the control
structures in Python, and the block of code
| | 03:50 | underneath it is indented.
| | 03:53 | So for each line of readlines, it will
take the line, put it in the line variable,
| | 03:57 | and then print it, just like we see here.
| | 04:00 | So that's how for loops work in Python,
and those are the two types of loops that
| | 04:05 | we'll see in Python.
| | 04:06 | We have while loops, which are
traditional, conditional loops, and for loops,
| | 04:11 | which work with iterators.
| | Collapse this transcript |
| Reusing code with a function| 00:00 | One very common way to reuse code in
Python is the use of a function, so let's
| | 00:05 | take a look at how functions are used in Python.
| | 00:08 | We'll go ahead and make a
working copy of function.py.
| | 00:12 | I'm going to call this function-working.py.
| | 00:15 | Save that and open it up.
| | 00:19 | Then I'll go ahead and maximize
this, so we can look at this code.
| | 00:24 | Here, we have a function definition.
| | 00:26 | def is the keyword. It says
this is going to define a function.
| | 00:31 | isprime is the name of the function,
and n, in this case, is a parameter.
| | 00:36 | We can have multiple
parameters, separated by commas.
| | 00:40 | We'll get into more of the
details of how this works.
| | 00:42 | This is the Quick Start.
| | 00:43 | It's going to show you in a nutshell,
if you're an experienced programmer, how
| | 00:47 | to create functions.
| | 00:48 | We'll get into the
details later on in the course.
| | 00:51 | In this case, this is a simple
function for testing if a number is a
| | 00:54 | prime number or not.
| | 00:55 | It checks if it's 1.
| | 00:57 | It checks if it's divisible evenly by
other factors, and otherwise it says,
| | 01:02 | this is a prime number.
| | 01:05 | So all of this code that is the body
of the function is indented, as is how
| | 01:11 | blocks of code are done in Python.
| | 01:13 | And it's introduced with this colon.
| | 01:15 | So you have the def, the name of the
function, parenthesis, any parameters
| | 01:20 | inside the parenthesis, and a colon, and
then indented code for the body of the function.
| | 01:27 | Down here, we call it.
| | 01:28 | Here, we're calling it inside a for loop.
| | 01:30 | And we simply call it by referencing the
name and putting any parameters inside.
| | 01:35 | Now in this case, the parameter is a
variable called n, which happens to be the
| | 01:40 | same as what I call it up here.
| | 01:42 | We could have used an x, or any other
legal variable name down here, but just so
| | 01:47 | you know that this n is different than this n.
| | 01:51 | All right, so let's go ahead and run it.
| | 01:56 | We'll select Run up here and Python Run.
| | 02:00 | And there we have a list of
all of these prime numbers.
| | 02:06 | So 1 is special.
| | 02:07 | 2 is a prime number.
| | 02:08 | 3 is a prime number.
| | 02:10 | 4 is not a prime number, because it's
divisible evenly by 2, and et cetera,
| | 02:16 | et cetera, prime numbers and not prime numbers.
| | 02:21 | So this function is getting called
over and over inside of this loop.
| | 02:26 | And we only have to have the code there once.
| | 02:28 | And that, of course, is the value
of a function or a subroutine.
| | 02:32 | So that's how functions are
defined and used in Python.
| | 02:36 | And of course, they're used quite a bit,
and we'll see a lot more examples of
| | 02:40 | this as we go through the course.
| | Collapse this transcript |
| Creating sequences with generator functions| 00:00 | Generator functions are an
incredibly useful pattern in Python.
| | 00:05 | What a generator function does is
it actually creates an iterator.
| | 00:09 | Let's take a look at how this works.
| | 00:12 | We can make a working copy of generator.py.
| | 00:15 | I'm going to call it generator-working.py.
| | 00:21 | Go ahead and open that up and take a look.
| | 00:25 | This is the generator here.
| | 00:26 | Now it calls this isprime, which is
very similar to the one that we used in
| | 00:30 | our functions example, except
instead of the Print statements, it returns
| | 00:34 | False if it's not prime, and it
returns True if it is prime. So that's a
| | 00:38 | little utility function.
| | 00:40 | This one here, it looks, at first glance,
like a normal function, and in fact, it
| | 00:45 | is, except it has this yield statement.
| | 00:50 | Yield is like return.
| | 00:51 | It returns a value.
| | 00:53 | You see here we have return False, return
True. Those return those Boolean values.
| | 00:59 | This one here returns a number,
| | 01:01 | and it returns this number only if
isprime returns true, so it returns the next
| | 01:07 | prime number, but it uses
yield instead of return.
| | 01:12 | And what yield does is it returns a
value, but then the next time the function
| | 01:16 | is called, it continues
execution after the yield.
| | 01:20 | So in this case, we have this while loop.
| | 01:23 | And it checks to see if the number is prime.
| | 01:28 | If it's not, it
increments and checks the next one.
| | 01:31 | And if it is, it yields.
| | 01:34 | And that will return a value.
| | 01:36 | And then the next time this function
is called, it'll just continue here,
| | 01:39 | incrementing and looking for the next one.
| | 01:42 | And so this actually, because of these
of yield, it returns an iterator object,
| | 01:47 | that is suitable for use in a for loop.
| | 01:50 | And here we have a for loop, and for n in primes,
| | 01:54 | and so it calls this primes function.
| | 01:56 | There is the primes function.
| | 01:58 | And for each iteration, it'll put the
value in n. And it'll print it out, and it
| | 02:04 | tests to see if it's greater than
100. Then it breaks out of the loop.
| | 02:08 | And so this uses this
generator function as an iterator.
| | 02:13 | And it will print a list of prime numbers.
| | 02:15 | Let's go ahead and take a look at
this as it works. We'll run it.
| | 02:21 | And here we have a complete list
of all the prime numbers up to 97.
| | 02:29 | So you can see that this is incredibly useful.
| | 02:32 | And we'll some more examples of
it as we go through the course.
| | 02:36 | So this is a generator function, and
what it generates is an iterator that's
| | 02:40 | suitable 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:00 | Object-oriented programming is a
very powerful model for reusing code.
| | 00:06 | Let's take a look at how objects and
classes are defined and used in Python.
| | 00:12 | We'll start with this simpleoop.
| | 00:14 | oop stands for Object-oriented programming.
| | 00:17 | We'll make a working copy of this, and
we'll go ahead and open the working copy.
| | 00:27 | And let's just take a look
at what's in here right now.
| | 00:32 | This is a class, and a class, in Python,
as in many object-oriented paradigms, a
| | 00:39 | class is the definition that
is used to create an object.
| | 00:43 | It's sometimes called a blueprint.
| | 00:45 | So objects are instances of classes.
| | 00:50 | So when you take a class, here's the
class that we've defined up here, class
| | 00:55 | Fibonacci, and you assign it to a
variable, that's called instantiating, or
| | 01:01 | creating an instance, of that class,
| | 01:03 | and the instance itself, in this case,
| | 01:05 | it's just called f, that
instance is called an object.
| | 01:10 | An object is an instance of a class.
| | 01:13 | So the class is the definition, and here
we have class, and it's named Fibonacci,
| | 01:18 | and it has these parentheses, and
we'll talk later about what goes in the
| | 01:21 | parentheses if anything.
Right now nothing needs to go into them.
| | 01:24 | The colon introduces the blocks or
suites of code that are indented, and
| | 01:30 | therefore part of the class definition.
| | 01:33 | And here, we have two functions
defined as part of this class.
| | 01:38 | And each of these functions, you'll
notice that its first argument is self.
| | 01:43 | And here we have one that's just got
self, and here we have one that's got self
| | 01:47 | and some other variables.
| | 01:50 | self is the common name for that first argument.
| | 01:53 | It doesn't have to be self.
| | 01:54 | It's traditionally self.
| | 01:56 | And what it is is a
reference to the instantiated object.
| | 02:01 | So when we use the object f, and here
we're calling a method or a function
| | 02:07 | inside of the object f, that's what
this dot notation does, f.series().
| | 02:12 | It calls the series function or method,
but it calls the copy of it that's part
| | 02:18 | of the object, the instantiated object.
| | 02:21 | And its first argument is actually a
reference to the object f. And so, we can
| | 02:28 | assign and use variables that are
encapsulated within that object and that are
| | 02:34 | actually carried around.
| | 02:36 | So if we had different instances of
the same class, they would have separate
| | 02:41 | variables, separate values in self.a
and self.b. This init function, or method, is
| | 02:49 | actually special. This is called a Constructor.
| | 02:52 | And this gets called when f gets assigned.
| | 02:57 | So f gets assigned Fibonacci, and that
creates an object called f, which is an
| | 03:05 | instance of Fibonacci.
| | 03:07 | As that object is created, init is
called, and init is called with a reference to
| | 03:14 | self and with these variables,
and here we have 0 and 1.
| | 03:19 | You can define these however you
want to because you're writing this
| | 03:22 | constructor. The constructor is optional.
| | 03:25 | If you don't need it, you
don't need to create it.
| | 03:28 | But in this case, we used a constructor so
that we could demonstrate how this works.
| | 03:33 | And what this is doing here is it
simply creating some default initial values
| | 03:37 | for a and b, which are going to
used as part of the Fibonacci series.
| | 03:42 | And then we have this second method,
or function, and this one is actually a
| | 03:49 | generator. You see it uses the yield statement.
| | 03:53 | And so that generates an iterator,
which is used here in this for loop, and so
| | 03:58 | for r in f.series() is going to give
us a series of all the Fibonacci numbers
| | 04:02 | that are less then 100.
| | 04:05 | So let's go ahead and run it, and there
we have our Fibonacci series up to 89,
| | 04:14 | which is the last Fibonacci
number that is less than 100.
| | 04:18 | So here we have defined a class
called Fibonacci, we have instantiated it,
| | 04:24 | creating an object, called f, and in that
object, we called this generator function
| | 04:31 | and we got a series of Fibonacci numbers.
| | 04:34 | So that is a simple example of
a class and an object in Python.
| | Collapse this transcript |
| Greater reusability with inheritance and polymorphism| 00:00 | The object model in Python is
really very powerful and well-designed.
| | 00:04 | And Python does support
inheritance and polymorphism.
| | 00:08 | So let's take a look at an example of how
we do inheritance and polymorphism in Python.
| | 00:14 | First, we'll make a working copy of
oop2.py, and we'll open our working copy, and
| | 00:29 | here we have a number of classes,
and you'll see we have these animals:
| | 00:34 | Dog, Person and Duck. And each
of these inherits AnimalActions.
| | 00:42 | So AnimalActions has the code in it.
| | 00:47 | It has these four methods:
| | 00:49 | quack, feathers, bark and fur. And you
will notice that each of these methods is
| | 00:53 | defined on one line.
| | 00:54 | So because each of these methods has just one
line of code, you can do it all on one line.
| | 00:59 | You have the def keyword, and then you have
the name of the method and then the code.
| | 01:05 | In this case, it's return self.strings 'quack'.
| | 01:09 | This notation here is because strings
is a dictionary, and we'll get into that
| | 01:15 | later on in the course when we talk
about data types. But these strings,
| | 01:20 | self.strings, are actually defined in
the classes that inherit AnimalActions,
| | 01:27 | and so this is an example of inheritance.
| | 01:31 | This is also an example of data
abstraction, because each of these classes
| | 01:36 | has different data.
| | 01:38 | So here we have the duck, and
it has these four strings in it:
| | 01:42 | quack, feathers, bark and fur.
And the duck says quack. The duck has gray
| | 01:47 | and white feathers. The duck cannot
bark. The duck has no fur. And then we
| | 01:51 | have a Person, which also inherits
AnimalActions, and the Person has quack,
| | 01:56 | feathers, bark and fur.
| | 01:58 | But for quack, instead of saying
quack, the person imitates a duck.
| | 02:02 | The person takes a feather from
the ground and shows it for feathers.
| | 02:05 | For bark, the persons says woof.
| | 02:08 | For fur, the person puts on a fur
coat, and then we have dog, which also has
| | 02:12 | quack, feathers, bark and fur,
and does dog-like things with these.
| | 02:17 | So this allows us to abstract all of
this data, and to use it in exactly the same
| | 02:23 | way in each of these classes.
| | 02:25 | Because each of these classes
inherits AnimalActions, these methods become
| | 02:30 | available in each of these other classes.
| | 02:33 | So when I create a duck object,
here we have donald = Duck,
| | 02:40 | that duck object will have
these dictionary strings, Quaaaaak!
| | 02:46 | The duck has gray and white feathers, and
it will also have these action methods:
| | 02:51 | quack, feathers, bark and fur.
| | 02:53 | And so I can call duck.quack
and I can call duck.feathers.
| | 02:59 | The beauty of this is that I can also
define a Person, john, and I can call
| | 03:07 | in_the_forest, where it's
expecting a duck, I can call it with john.
| | 03:12 | And so here we have an iterator. We are
calling for o in ( donald, john, fido),
| | 03:16 | so o will be sequentially don and john and fido.
| | 03:20 | john is a person; john is not a duck.
| | 03:22 | But in_the_forest(o) calls in the
forest with john and in_the_forest expects a
| | 03:30 | duck object, so it calls
duck.quack and duck.feathers.
| | 03:34 | Well, john implements - because john is
a person, a person inherits AnimalActions,
| | 03:40 | and it implements quack and feathers.
| | 03:43 | So this is called polymorphism.
| | 03:45 | And let's see how this works.
| | 03:48 | Remember, we are going to be calling in
the doghouse and in the forest for each
| | 03:54 | of these three objects:
| | 03:55 | donald, john and fido.
| | 03:57 | A Duck, a Person and a Dog.
| | 03:58 | First, we'll call in the forest for
each of them, and then we'll call in the
| | 04:02 | doghouse for each of them.
| | 04:04 | So I am going to run this.
| | 04:09 | And we'll take a look at the results.
| | 04:10 | In the forest, we have Quaaaak!
| | 04:13 | And the duck has gray and white feathers.
| | 04:15 | So we are calling Quaaaak!
| | 04:17 | and feathers for each of these.
| | 04:20 | We are calling Quaaaak!
| | 04:21 | and feathers also for the person, and
it says the person imitates a duck, and
| | 04:24 | the person takes the feather from the
ground and shows it, and also for the dog,
| | 04:29 | and then in the doghouse, the duck cannot bark,
the duck has not fur, the person says woof!
| | 04:33 | the person puts on a fur
coat and then for the dog Arf!
| | 04:36 | and the dog has white fur with black spots.
| | 04:40 | So this is an example of
polymorphism and inheritance in Python.
| | 04:48 | Now real quick, I want to also show you this
example that's been rewritten as a Model-View-Controller.
| | 04:54 | Model-View-Controller is a very common
pattern in object-oriented programming,
| | 05:00 | and I just want to show you that we can
do exactly the same thing and actually
| | 05:04 | separate it out a little bit further.
| | 05:07 | In this case, we are not bothering to
define the data for that which doesn't
| | 05:12 | apply for each of these.
| | 05:14 | So the dog doesn't quack,
| | 05:16 | so I am not having a string for dog.
| | 05:19 | So this is the modeling, and we have
the model for the duck and the person and
| | 05:25 | the dog, and each of these inherits
AnimalAction. And in this context, we don't
| | 05:29 | really care about the implementation of
AnimalActions, because all that matters
| | 05:33 | is that we are modeling
each of these types of objects.
| | 05:40 | The view is the implementation of
how do we view each of these things?
| | 05:47 | So we have these four methods:
| | 05:48 | bark, fur, quack and feathers.
And they each call doAction with the word bark,
| | 05:54 | fur, quack and feathers.
| | 05:55 | And then doAction is a local method, and
you will notice it has this underscore.
| | 06:01 | That doesn't make it special in
Python, but it does tell the person who is
| | 06:05 | reading it that this is something
that's just going to be called internally.
| | 06:09 | You are not going to want
to call this on the object.
| | 06:11 | You are just going to want to call it from
inside of the object, or inside of the class.
| | 06:16 | So this gets called from each of these
methods. And if the action is not found in
| | 06:22 | the strings, then it has a default that
it does, where it says, this animal name
| | 06:26 | has no action. And so that allows us to
model these, and to actually expand them,
| | 06:35 | and define more actions, and to not
have to worry about doing a whole lot of
| | 06:41 | extra modifications to the parent
class. And then the controller is, of course,
| | 06:48 | how we call all of this stuff,
which is pretty much the same.
| | 06:51 | So this does exactly the same thing.
If I go ahead and run this, we'll see that
| | 06:57 | our result is exactly the same, but what
we have here is a refined version of the
| | 07:05 | same thing using a model,
view and controller pattern.
| | 07:09 | It's a contrived example, but this is
commonly how we can do object-oriented
| | 07:14 | programming in Python 3.
| | Collapse this transcript |
| Handling errors with exceptions| 00:00 | Error reporting in Python is done
with something called exceptions.
| | 00:04 | Exceptions are an object-
oriented way of handling errors.
| | 00:09 | So let's take a look how this works in Python.
| | 00:12 | Go ahead and make a working
copy of exceptions.py. We'll call it
| | 00:17 | exceptions-working.py.
| | 00:19 | So let's go ahead and open our working
copy, and we will notice that we have a
| | 00:26 | script here that opens a file and
reads the lines and prints the lines.
| | 00:30 | The problem is is that it's spelled the
filename wrong, and so when we run this,
| | 00:35 | we will get an error, and
we see there is the error.
| | 00:38 | And you will notice that error is in red.
That's because Python sends its default
| | 00:42 | error messages out to standard error,
which is printed in red in Eclipse, but
| | 00:47 | what we want to do is want to be able
to catch that error and do something
| | 00:51 | intelligent within our scripts.
| | 00:53 | We are going to do this with 'try,' and we
will go ahead and indent this code
| | 00:59 | under 'try' and accept.
| | 01:02 | Now we will just print, 'something bad
happened,' and then we can go ahead and
| | 01:10 | continue to execute and say print
'after badness.' And so when we run this, go
| | 01:19 | ahead and save it and run it,
something bad happened and after badness.
| | 01:24 | We can see that we caught the error, we
did something, and we continued after that.
| | 01:30 | Now we actually print the error
message that Python gives us. We can say
| | 01:34 | except IOError as e and I can say
something bad happened and put the error
| | 01:41 | message in parentheses here.
| | 01:44 | .format (e)), and when I save that and
run it, something bad happened (Error 2 No
| | 01:52 | such file or directory,
| | 01:53 | and now we know exactly what the problem
was. We could set a flag. We could mere
| | 02:00 | some different code. We can do anything
different that we want to. We have the
| | 02:04 | full reporting of Python's
errors as this variable e
| | 02:10 | So this is how Python handles errors.
| | 02:12 | It throws these exceptions, and this
is how we catch them and how can do
| | 02:17 | something intelligent with them.
| | 02:18 | We will see a lot more examples of this
as we go through the rest of the course.
| | Collapse this transcript |
|
|
3. Setting Up PythonInstalling Python 3 and Eclipse for Windows| 00:00 | Let's take a look at how you can install
Python and the Eclipse environment on a Windows PC.
| | 00:06 | I am using a Windows 7 PC here. This same
procedure should work for any kind of modern Windows.
| | 00:13 | This is the download page for
Python 3.1.2. Use the downloader or installer for
| | 00:19 | whatever version of Python is the latest.
| | 00:22 | If I scroll down here, you will see
that there is downloads available for a
| | 00:26 | number of operating systems. I am
going to pick the one for this Microsoft
| | 00:30 | Windows box, and I have already
actually downloaded this, so I have got that
| | 00:35 | already in my Download folder.
| | 00:37 | Let's also go ahead and download Eclipse.
| | 00:39 | Now in order to install Eclipse, you
must have Java installed, and you should
| | 00:43 | probably have the latest Java installed.
| | 00:46 | So I strongly recommend that you make
sure that your computer has Java, and it's
| | 00:51 | the latest version of Java.
| | 00:53 | Windows machines do not
necessarily come with Java already installed.
| | 00:56 | So you need to make sure that you have
Java installed before you install Eclipse.
| | 01:00 | Eclipse is designed to be a
development environment for the Java language.
| | 01:05 | We are using it here to develop in
Python because it has a lovely plug-in
| | 01:09 | available for Python
development, and that works really well.
| | 01:12 | Here, on the download page for Eclipse,
you will notice that there are a lot of
| | 01:15 | choices, and any one of these will
actually work. We are going to install the
| | 01:20 | basic Eclipse Classic.
| | 01:23 | Most of the time, when you hover over
this link here whatever operating system
| | 01:27 | you are working with, it will get the
proper download for your operating system.
| | 01:31 | If you are not sure, you can select the
one that you want from this list over here.
| | 01:35 | So let's go ahead and get
started with the installation.
| | 01:38 | First, we are going to install Python,
and that involves double-clicking on this
| | 01:42 | installer, and I will say Run.
| | 01:45 | I'm going to go ahead and Install for all
users, and I am going to install it in the
| | 01:49 | default location, and I want
to make a note where that is.
| | 01:53 | That's Python31 folder, right off of the C disk.
| | 01:58 | Again, I am going to accept the defaults.
It's installing everything, and we want
| | 02:02 | that, and then it just goes
ahead and does its thing.
| | 02:07 | Now let's go ahead and run
IDLE and make sure that it works.
| | 02:11 | There it is, so now we know that we have
Python 3.1.2 installed, and it's working.
| | 02:18 | Now we are going to install Eclipse.
| | 02:20 | Eclipse comes to us in a zip file, so
I am going to Extract All just to this
| | 02:26 | default location in my Downloads folder.
| | 02:31 | Now we have the eclipse folder, so I
am just pressing Ctrl+N to open another
| | 02:37 | Explorer window, and we'll come down here
and find Program Files, and I am going to
| | 02:43 | install it on Program Files (x86)
because I don't loaded the 32 bit version.
| | 02:47 | You can put it in the other one if you want
to, and I am just going to drag this over
| | 02:52 | here and move it to Program Files.
| | 02:54 | So I don't want it to go in one of
these other folders, so I am going to
| | 02:58 | actually drag it into this part of the
window here where it says move to Program
| | 03:01 | Files, and I will Continue
and authorize, and there it is.
| | 03:06 | I will open this up, and there is
eclipse.exe. I am going to pin it to the Start menu.
| | 03:14 | Now, there it is in my Start menu.
| | 03:18 | So I can close this window, I can
close this window, and I no longer need this
| | 03:25 | empty folder here. I will
just go ahead and delete that.
| | 03:29 | Now it's time to start Eclipse. There is
still quite a bit left to do here. I am
| | 03:35 | accepting that and running it.
| | 03:36 | I am going to accept the default
location for my workspace. I am going to say
| | 03:42 | use this as a default so you don't ask
me again. And you can put your workspace
| | 03:46 | wherever it makes sense for you.
And now we are running Eclipse but it's not
| | 03:50 | ready to use at all yet.
| | 03:52 | First thing we need to do is we need
to install Pydev. That's the development
| | 03:57 | environment for Python. And under
the Help menu, you will see there is a
| | 04:01 | selection for Install New Software,
and before we can even type something in
| | 04:06 | here, we need to click on this Available
Software Sites preferences and Add a new software site.
| | 04:14 | The URL for this is pydev.org/updates.
| | 04:20 | We are going to call this
Pydev, and say OK, and OK.
| | 04:27 | Then up here, we can just start typing
Pydev, and we will see that it comes up, so
| | 04:31 | we select that, and it says Pending, and
then we check on the one that says Pydev.
| | 04:38 | You probably don't need this Mylyn
Integration unless you know that you do, and
| | 04:43 | if you are using Mylyn, by all
means, go ahead and add that.
| | 04:46 | So now I am going to say Next, and it
found it, and so I am going to select that
| | 04:50 | and press Finish. And now it's
installing the Pydev development environment for
| | 04:55 | Python within Eclipse.
| | 04:58 | Say OK to the unsigned content
warning, and it is strongly recommended -
| | 05:02 | it says so right there - that you restart
Eclipse, and there is no reason not to,
| | 05:08 | so we will just say OK.
| | 05:08 | All right, we are getting closer.
So now we have some configuring to do.
| | 05:14 | We are going to open the Preferences,
which is under the Window menu, and we are
| | 05:18 | going to come down here to Pydev and
click on the little arrow, and then you
| | 05:22 | are going to click on Interpreter -
Python, and we are going to need to add our
| | 05:28 | Python interpreter.
| | 05:29 | So we will click New, and we will click
Browse and remember where Python is.
| | 05:35 | It's under the C drive and in Python 3.1,
and there is our Python interpreter.
| | 05:40 | Click Open, and we will just
name this Python 3.1 and say OK.
| | 05:46 | Now you will get this Selection Needed
window. You just take the defaults and
| | 05:51 | select OK Once you have all of this, you
select OK, and this will take a few minutes.
| | 05:57 | Now that you have configured the Python
interpreter, you can create your first project.
| | 06:02 | So under the File menu, you hover over New
and you come down here and you select Project.
| | 06:09 | Under the Selection Wizard, you click
on the little arrow next to Pydev and you
| | 06:13 | select a Pydev project and click Next,
and you want to give it a Project name.
| | 06:18 | I am going to call this Python 3
Essential Training, and you want your Grammar Version
| | 06:26 | should be 3.0, and your
Interpreter will be 3.1 Interpreter.
| | 06:31 | Project type should be Python and click
Finish, and it says it's the Pydev
| | 06:36 | perspective. You can say Yes for that,
and over here in the Perspectives, slide
| | 06:41 | this over and right-click on the Java
and click Close and slide it back over,
| | 06:46 | unless you are actually going to be
working in Java, in which case, you might
| | 06:49 | want to leave that.
| | 06:50 | So now we are going to add a folder to
our project. I'm going to right-click on
| | 06:55 | Python 3 Essential Training, and I am
going to say New > Folder. I am going to
| | 06:59 | click on Advanced and Link to folder in
the file system, and then I am going to
| | 07:03 | browse, and I am going to find my exercise
files for this course and I put that in my desktop,
| | 07:09 | and there is Exercise Files, and I will
select OK, and so Link to folder in the
| | 07:14 | file system is checked, and the parent
is this Python 3 Essential Training. I am
| | 07:19 | going to say Finish and
there is my Exercise Files.
| | 07:22 | So this did not copy the
Exercise Files into my Project folder;
| | 07:26 | It simply linked to it. And so, almost
there. We are going to go back into the
| | 07:30 | Preferences, and under Pydev and
under Editor, we are going to find this
| | 07:36 | thing called Hover.
| | 07:38 | If Show docstrings is checked, you might
want to uncheck it; you can try it both ways,
| | 07:43 | but for my purposes in
demonstrating, I have unchecked it.
| | 07:47 | Feel free to try it both ways
and see how that works for you.
| | 07:50 | So what this does is when you hover
over an object in Python, it shows the
| | 07:55 | entire documentation.
| | 07:56 | It pops up on the screen, and
personally I find that this gets in the way.
| | 07:59 | You may find it helpful.
| | 08:01 | So feel free to try it both ways.
I have got it unchecked on mine.
| | 08:05 | Finally, under General > Editors >
Text Editors, you want to make sure that
| | 08:11 | Show line numbers is checked,
because that's going to be useful.
| | 08:14 | So we will select OK, and feel free
to look through the Preferences and
| | 08:19 | experiment with some of the other
options. And now we are going to go ahead and
| | 08:22 | just load up our Hello World program
and run it. And so I will select Python Run
| | 08:29 | and OK, and there we have it.
| | 08:31 | So we have installed Python, we have
installed Eclipse, and we have installed the
| | 08:36 | Pydev development environment, and we
have configured it so we can use it for
| | 08:40 | Python development, and you can use
this environment to follow along with the
| | 08:43 | exercises in this course.
| | Collapse this transcript |
| Installing Python 3 and Eclipse for Mac| 00:00 | So now we are going to
install Python and Eclipse on a Mac.
| | 00:04 | So this is the Python download page,
and you will see I have already downloaded
| | 00:08 | Python 3.1.2 Mac OS X Installer Disk Image.
| | 00:13 | So if you are on a Mac, that's
the one that you want to download.
| | 00:17 | If the version number is a little bit
higher, if it's a later version, go ahead
| | 00:20 | and install the later version.
That should work just fine.
| | 00:24 | Then you want to download from the
Eclipse download page, and Eclipse is written
| | 00:29 | in Java, and it's actually a Java
development environment, and so you will see
| | 00:33 | that there are a lot of different choices.
| | 00:35 | If you are a Java developer and you
want to install one of these other ones,
| | 00:38 | that's fine. Go ahead and do that.
| | 00:40 | For my purposes, I am just getting the
Eclipse Classic, because I am really just
| | 00:43 | using it for Python development today.
And you'll notice that when I run the
| | 00:47 | mouse over this, it highlights the one
for Mac OS X Cocoa, and that's really the
| | 00:51 | one that you want to install.
| | 00:53 | So I have already downloaded that as
well, and here is my Downloads folder, and I
| | 00:57 | have got the Eclipse downloaded,
and I have the Python downloaded.
| | 01:01 | So go ahead and close the browser, and we
are going to start by installing Python.
| | 01:07 | So I will double-click on the
installer, and I will double-click on the
| | 01:10 | Python.mpkg, and I will say Continue,
and Continue, and Continue,
| | 01:16 | and Agree, and Install.
| | 01:19 | I am going to install this in
default location. Type in my Password.
| | 01:22 | Mac OS X already comes with Python
installed, but it's Python 2, and so you
| | 01:28 | really need to install Python 3 for this
course, because this course is about Python 3.
| | 01:33 | That installation is done, and I can
unmount this, and I just want to go ahead
| | 01:40 | and go out to my Applications folder, and
then I will find Python 3.1 folder, and
| | 01:48 | in there, you'll find IDLE. And I am
going to drag that to my Doc because we are
| | 01:53 | going to be using that.
| | 01:55 | I will go ahead and we'll open it, so it's
Python 3.1.2, and that's what we are looking for.
| | 02:00 | So Python is installed and working on this Mac.
| | 02:03 | I will Quit IDLE, and we are going
to go ahead now and install Eclipse.
| | 02:08 | So I am going to double-click on the
Eclipse installer, and this is going to
| | 02:12 | unarchive it. And it will unarchive the
tar file, which is inside of the gz file.
| | 02:17 | And I have got this folder, and all I
need to do with at this point is drag this
| | 02:20 | whole folder to my applications folder
and I come in here, and I am going to find
| | 02:24 | the folder called Eclipse, and inside
of that folder there is the Eclipse
| | 02:28 | application. I am going to
drag that to my dock and run it.
| | 02:33 | So you go ahead and open that.
| | 02:35 | Now there are a few things we need to
do to configure Eclipse. First thing, we
| | 02:39 | are going to select a workspace.
I am going to allow the default; you are
| | 02:42 | welcome to use whatever folder works for you.
| | 02:44 | I am going to select the check box to use
it as a default, so it doesn't ask me again.
| | 02:48 | Now before I do anything else, when
Eclipse starts up, under the Help menu, I am
| | 02:53 | going to go to Install New Software, and
I am going to select this link. This is
| | 02:58 | Available Software Sites, and I am
going to add one, and this is for Pydev, and
| | 03:04 | the URL is pydev.org/updates, with an s at the end.
| | 03:10 | Say OK, and we see that gets added
there, and I say OK, and then all I need
| | 03:16 | to do is select that is go up here and
type Pydev, and just the first couple of
| | 03:21 | letters, and I will get this here, and I can
double-click on that, Pending, and it finds Pydev.
| | 03:27 | So you want to check Pydev. You don't
need to check the Mylyn integration, unless
| | 03:32 | you know what that is, and you are going
to be using that. And I will select Next,
| | 03:37 | PyDev for Eclipse, and Next. And I want
to accept the terms of the license and
| | 03:43 | Finish, and here we go.
| | 03:45 | This should take just a moment. At the
security warning, you want to say OK, and
| | 03:50 | it is strongly recommended that you
restart Eclipse. There is no reason not to.
| | 03:54 | So I am just going to select
Yes, and Eclipse will restart.
| | 03:58 | So now I am going to go ahead, and I am
going to go to the Workbench. That's this
| | 04:01 | icon over here at the right, and I am
going to maximize this on my workspace.
| | 04:05 | You will see over here we have Java selected.
| | 04:08 | I am going to select Other and Pydev
and OK, and because I am not going to
| | 04:13 | be doing any Java development, I am just
going to right-click on Java and select Close.
| | 04:18 | Then I can move this over, and
there is my Pydev Workspace.
| | 04:22 | Now before we get started, we need to
go into Preferences, and under Pydev and
| | 04:29 | Interpreter Python, we need to add our
Python Interpreter, and this is so Pydev
| | 04:35 | knows where to look for Libraries, what
sort of Grammar to use, things like that.
| | 04:40 | So I am going to go ahead and add it.
I am going. It's under browse user > local > bin >
| | 04:48 | python 3.1, and that's an alias, and it's
supposed to be. And so when I say OK, it
| | 04:54 | actually goes and it finds
what the alias was pointing at.
| | 04:57 | Under interpreter name, I am
just going to type Python 3.1.
| | 05:00 | I am going to say OK, and it will say OK.
| | 05:04 | Now if you are also going to be doing
Python 2 development, you might want to
| | 05:08 | add that interpreter as well.
| | 05:10 | I know I am not going to be, so
I am going to leave it like this.
| | 05:13 | So now I say OK, and it goes and it
finds all of the frameworks, and it finds all
| | 05:17 | the libraries, and it does all of
this stuff, and now that's installed.
| | 05:21 | So we are getting closer. At this
point, we want to go back into the
| | 05:24 | Preferences, and under Pydev and under
Editor, see this thing that says Hover,
| | 05:31 | and see it's a Show docstrings?
| | 05:33 | I uncheck that. I find that very distracting.
| | 05:36 | It's up to you if you
want to uncheck that or not.
| | 05:39 | What it does is whenever you hover over
an object in Python, it will show you the
| | 05:44 | entire documentation, and it
will pop up for that object.
| | 05:47 | I am sure some people find that very helpful.
I find that it gets in the way, so I uncheck that.
| | 05:52 | Also, up here in General and under
Editors and Text Editors, I want to
| | 05:59 | check, Show line numbers.
| | 06:00 | I find that very useful, and I
think you will too. So now we say OK.
| | 06:05 | Over here in the Pydev Package Explorer,
right-click and say New > Project, and
| | 06:11 | select Pydev and select Pydev Project and Next.
| | 06:16 | And under Interpreter, you want to
select the Python 3.1 Interpreter, and under
| | 06:21 | Grammar Version, you want to select 3.0,
and make sure it says Python for the
| | 06:26 | project type, and type in the name of project.
| | 06:29 | I am going to call this Python 3
Essential Training, and select Finish.
| | 06:35 | Now I have this project here, and I want
to right-click on the project and say,
| | 06:41 | New > Folder, and the parent folder
will already be selected as Python 3
| | 06:45 | Essential Training, and then select the Advanced
button and select Link to folder in the system.
| | 06:51 | Now I am going to select Browse, and on my
desktop, I have my Exercise Files folder.
| | 06:58 | So you want to select that wherever it
is you put yours. I find the desktop to
| | 07:01 | be very convenient for this.
| | 07:02 | I am going to press Open.
| | 07:04 | And so what this will do is this will
add my Exercise folders to this Project
| | 07:09 | folder without actually copying the
folder. And so it will be just linked to the
| | 07:14 | folder, and it will use it in place
without making another copy of it.
| | 07:18 | So I am going to say Finish, and there it is.
| | 07:21 | Now just open up Chapter 02 and double-
click on hello.py. And the first time you
| | 07:28 | open something up after just
installing Eclipse and Pydev and everything, it
| | 07:32 | might take in a moment, and then
there it is. We have our Hello, World!
| | 07:37 | It's a very simple Python program.
| | 07:39 | The whole purpose of this program is
just as an exercise in getting your
| | 07:43 | development environment running, so
it's exactly what it is designed for.
| | 07:46 | So when I select Run, it will ask me
to Run As, and I will select Python Run,
| | 07:52 | and say OK, and there we have it.
There is our result: Hello, World!
| | 07:56 | So this tells us that Python is installed,
that Eclipse is installed, that Pydev
| | 08:01 | is installed, Python Interpreter is
configured within Eclipse and Pydev, and the
| | 08:07 | entire environment is running.
| | 08:08 | So now you have a working Eclipse
environment where you can follow along with
| | 08:12 | the exercises and do
your own Python development.
| | Collapse this transcript |
|
|
4. General SyntaxCreating a main script| 00:00 | As we go through the examples in this
course, and as you look at scripts that you
| | 00:04 | find from different sources, and as you
write your own scripts, you are going to
| | 00:08 | notice a few things that are constant
in how these scripts are constructed.
| | 00:14 | If we look at the syntax.py file here in
our 04 Syntax folder in Exercise Files,
| | 00:21 | you will notice a few things.
| | 00:23 | First of all, at the very top, there is
this line with a Pound sign, which is
| | 00:27 | the Comment Indicator in Python and
an exclamation point and then a path to
| | 00:33 | the Python Interpreter.
| | 00:35 | This is used in environments that
run the script from a shell, UNIX-based
| | 00:40 | environments like a Mac or Linux
environment, and one of the beauties of a
| | 00:45 | scripting language like Python is
that your script can run in a number of
| | 00:49 | different environments without change.
| | 00:52 | So it's important that you leave
this as the first line of the file.
| | 00:56 | Now this path here that starts with
the first slash must be the path to
| | 01:01 | the Python Interpreter.
| | 01:02 | Now this is a very common path: /user/bin/
python3, that will work in a lot of environments.
| | 01:07 | If you try to run this in UNIX-
based environments and you find that it
| | 01:10 | doesn't work, one thing that you'll
want to look at is this path to see if the
| | 01:15 | path needs to change.
| | 01:16 | Another thing that you will notice
is this line down here at the end.
| | 01:20 | What this does is it allows us to run
the script with the functions in any
| | 01:25 | order that we want.
| | 01:27 | Without this line and without the main
execution of the script being inside a
| | 01:33 | function called main, then you
wouldn't be able to run functions that are
| | 01:37 | defined after the function is called.
| | 01:40 | In other words, if I put a
function in here, and I say def egg():
| | 01:47 | and print("egg") now I'll need to
call the egg here, egg() and save and run,
| | 01:57 | you will notice that that runs.
| | 02:00 | Now if I were to take out this def main
| | 02:04 | and just make this like that without it
being in any function at all, and we will
| | 02:10 | get rid of this, so you might want to
just call egg from here and then define
| | 02:17 | egg down there, that will not work.
| | 02:19 | That will give us a syntax error because egg
is not defined at the point where we call it.
| | 02:24 | So what this allows us to do is to
define functions after they are called, and
| | 02:31 | this is actually very useful and very
common, so you will see this construct in a
| | 02:36 | lot of the scripts that you encounter.
| | 02:40 | If we just have it this way, it
would serve the same purpose.
| | 02:44 | The reason for this part of it here is
it allows this to only be run when this
| | 02:49 | file is called as the main module.
| | 02:52 | Later on in the course, we will get
into writing modules, and modules typically
| | 02:57 | contain classes and functions.
| | 02:59 | A lot of times when you write a
module you are going to want to have a test
| | 03:03 | suite at the end of the module, and
this allows you to put that in a main
| | 03:09 | function, and it will only run if the
module is called as the main module.
| | 03:13 | It won't run when the module
is included in other modules.
| | 03:18 | So you will see this pattern a lot, and
that's basically what it does and what
| | 03:23 | it's for, and it's just a good idea
to always stick it in your scripts.
| | Collapse this transcript |
| Understanding whitespace in Python| 00:00 | Whitespace is significant in Python in
ways that you may not be accustomed to,
| | 00:04 | if you are familiar with
other scripting languages.
| | 00:08 | Let's go ahead and make a working
copy of syntax.py, and we can look at
| | 00:12 | whitespace in Python.
Call it syntax-whitespace.py.
| | 00:20 | Go ahead and open that up, and you will
notice that this main function consists
| | 00:26 | of one statement, a print statement,
and that print statement is indented four
| | 00:30 | spaces, ands that actually tells Python
that this print statement is associated
| | 00:37 | with this main function.
| | 00:40 | It's actually the body of the main function.
| | 00:43 | Four spaces are traditional in Python.
| | 00:45 | You can use two. You can use
one. It will work just as well.
| | 00:49 | It does have to be consistent. In other
words, if I have more than one line here,
| | 00:54 | and if that other line is indented, say
three spaces instead of four, if I save
| | 01:06 | that and run it, you will see that I
get a syntax error, and it says unindent
| | 01:11 | does not match any outer indentation level.
| | 01:14 | So Python got confused. We indented
this one four spaces, we indented this one
| | 01:19 | three spaces and it just got confused.
| | 01:22 | It didn't know what to do with that.
So the indention has to be the same amount.
| | 01:27 | Save that and run it, and
we will see that that works.
| | 01:30 | Now if I take this second line and I
indent it back at the same level as the
| | 01:35 | function definition, then it is no
longer part of the body of that function.
| | 01:40 | So what will happen when I run this is
it will actually see this line, this is
| | 01:44 | another line, before the syntax file and
the reason for that is because that will
| | 01:50 | get executed on the first pass
through here before we call main.
| | 01:53 | main gets called at the end of the file.
| | 01:56 | So this line will be
printed first and then this line.
| | 02:00 | So we will save that, and we will run
it, and you see this is another line, and
| | 02:05 | then this is the syntax file.
| | 02:07 | So, by bringing the indentation out to
the same level as the definition, it is
| | 02:13 | now no longer part of the body of that function.
| | 02:15 | We will go ahead and indent that again
and save it and run it, and we see that it
| | 02:21 | works as we expect with this
second line after the first line.
| | 02:25 | So indentation as whitespace is
significant in Python because Python doesn't use
| | 02:31 | curly braces, or any other characters, to
indicate the body of a function, or what
| | 02:38 | they a call suite - what we might call a
block of code that's - associated with a
| | 02:42 | particular control structure.
| | 02:43 | These indents are used for
conditionals. They are used for classes.
| | 02:48 | They are used for any place where you
might need to associate a block of text
| | 02:52 | with a particular control structure.
| | 02:54 | Now there is one circumstance where
the indentation and the whitespace is not
| | 02:59 | actually significant.
| | 03:00 | If you have just one line of code in a
particular structure - and that's all there
| | 03:06 | is, there is not more than one line of code - that
one line of code can be on the same line
| | 03:11 | as the control structure itself.
| | 03:13 | So if I put this print here - and I can
put a space, or not put a space, or put several
| | 03:17 | spaces - it will work exactly the same.
| | 03:19 | I save this and run it, you see
that it still works. Just like this 'if'
| | 03:25 | statement down here has one line of
code, which is the function call for main,
| | 03:30 | now this function definition for main
has just one line of code, the print, and
| | 03:35 | in this case the whitespace is not significant.
| | 03:37 | I can have five spaces, I can have one
space, and it still runs just the same.
| | 03:42 | That's a special case for
whether its just one line of code in a
| | 03:46 | particular structure.
| | 03:49 | Under most circumstances, where you have
a function, or a class, or something like
| | 03:53 | that, and you have more than one line of
code, you will see the indentation used,
| | 03:58 | and four spaces is traditional, and the
indentation has to be consistent all the
| | 04:04 | way through the block or the suite of code.
| | Collapse this transcript |
| Commenting code| 00:00 | Comments in Python are
quite simple. Let's take a look.
| | 00:05 | We'll start by making a
working copy of comments.py,
| | 00:09 | and we'll call it comments-working.py.
| | 00:14 | We'll go ahead and open the working copy.
| | 00:16 | And here we have a little program
that generates a list of prime numbers.
| | 00:21 | Now, you'll notice that at the top of
the file, we have a number of lines that
| | 00:26 | are introduced by a Pound sign.
| | 00:28 | I call it a Pound sign some people
called the Hash Mark, or that tick-tack-toe-
| | 00:32 | looking thingie, whatever we call it.
| | 00:35 | That is the symbol that
indicates a comment in Python.
| | 00:39 | So everything starting with the Pound
sign, and all the way to the end of the
| | 00:43 | line, is ignored by the Python interpreter.
| | 00:46 | So all these are comments.
| | 00:48 | You'll notice that we don't have
any comments in the rest of the code.
| | 00:51 | And this is a piece of code that may
very well benefit from some comments.
| | 00:56 | So for example, this line here, I might
have a comment that says # generate a
| | 01:07 | list of prime numbers.
| | 01:10 | And now when somebody comes back and
looks at the code later on he'll, see this:
| | 01:15 | for n in primes generate
a list of prime numbers.
| | 01:17 | Oh, well I guess that's what that does.
| | 01:20 | Now, when you're reading comments you
want to be careful that you don't just
| | 01:24 | trust the comment, that you actually
look at the code and make sure that the
| | 01:27 | code actually does what you think it does.
| | 01:29 | Use the comment as a guideline, but
oftentimes as people are writing code they
| | 01:35 | might put in a comment and then maybe
change the code later, forget to change
| | 01:39 | the comment, or perhaps their terminology is a
little bit different than what you're expecting.
| | 01:45 | So comments are very useful.
| | 01:46 | The purpose of comments is to make
the code more readable by human beings,
| | 01:51 | because something like this here, I
wrote it, so I know what it does, but you're
| | 01:57 | looking at it and you might say, hmm,
what algorithm is he using to generate
| | 02:01 | these prime numbers?
| | 02:03 | And so a couple of little comments might
make it a lot more readable. For example,
| | 02:07 | I can say # one is never prime by definition.
| | 02:14 | And over here I might say
# found a divisor, not prime.
| | 02:25 | And over here, because we have a
generator function and a lot of people who
| | 02:31 | aren't familiar with Python might
not know what a generator function is,
| | 02:36 | I can say, # yield makes this a generator.
| | 02:42 | And it'll at least give somebody a
clue. They can look that up if they don't
| | 02:46 | know what that means.
| | 02:48 | So the principle here is to use comments
to make the code a little bit more clear.
| | 02:54 | There is a danger, of course, if you use
too many comments, if you comment every
| | 03:00 | line, or if you comment way too many things.
| | 03:02 | The comments might become a distraction.
| | 03:04 | But just keep in mind that the purpose
of the comment is to make the code more
| | 03:08 | clear to somebody who is reading it for
the first time and may not be familiar
| | 03:12 | with the algorithm that you are using.
| | 03:14 | So comments in Python are
introduced by a Pound sign or Hash Mark.
| | 03:19 | And everything from that Pound sign to
the end of the line is ignored by the
| | 03:25 | interpreter, and therefore considered a comment.
| | Collapse this transcript |
| Assigning values| 00:00 | Assignments in Python are handled with the
assignment operator, which is the Equal sign.
| | 00:06 | Let's go ahead and make a
working copy of syntax.py.
| | 00:11 | I'll call it syntax-working.py.
| | 00:14 | And we'll open that working copy, and
we'll go ahead and create an assignment.
| | 00:19 | So I'll have a variable called a,
and I will assign it the value 1.
| | 00:24 | Now what this does in Python is it
actually defines the variable a, and it
| | 00:31 | creates an integer type
variable, and it puts the value 1 in it.
| | 00:37 | And so in the print statement, I can print a.
| | 00:41 | And if I go ahead and save this and run it,
we'll see that we get the value 1 printed.
| | 00:49 | If instead I were to put a string there,
say "one" spelled out, run that then
| | 00:58 | we get a one here.
| | 00:59 | We can look at the type of the variable
that was created by using the type function.
| | 01:06 | And so this will print the type and the value.
| | 01:09 | Save that and run it.
| | 01:10 | See that that's a Class String, it's the type.
| | 01:14 | In fact everything in Python is an
object, and objects have classes, and so the
| | 01:19 | type of a thing is
typically the name of the class.
| | 01:24 | And so if I make this a number again
and save that and run it, we'll see that we
| | 01:30 | get a variable of the <class 'int'>.
| | 01:33 | So if a variable has not been
assigned before, then the assignment operator
| | 01:39 | actually creates the object.
| | 01:42 | And it creates it of the
appropriate type, or the appropriate class.
| | 01:46 | You can assign multiple objects at the
same time. You can say a, b = 0, 1, and
| | 01:55 | then if I print(a, b), then I'll get
both of those values, the 0 and the 1.
| | 02:03 | Interestingly, you can even do
something like this, where you're actually
| | 02:13 | swapping these values.
| | 02:14 | You can use the same variables on the
right and the left-hand side of the Equal
| | 02:19 | sign, and you can pretty much do
this safely under most circumstances.
| | 02:23 | So here we'll get a 1 and
0 when we run this, 1, 0.
| | 02:30 | There are some types of objects in
Python that are sets of values, or sequences
| | 02:35 | of values, called lists, and
tuples, and things like that.
| | 02:39 | For example, if we say a = (1, 2, 3, 4,
5), by putting them in the parentheses,
| | 02:51 | this makes this into a tuple.
| | 02:54 | And if we save this and run it, you
see that we get all of those values.
| | 02:58 | Now, when you use print on an aggregate
type, on a set, or a tuple, or something
| | 03:02 | like that, it actually tries to print
it in a form that would be acceptable
| | 03:07 | syntax in Python for creating that object.
| | 03:11 | And so for example, another aggregate
type is the list, which has square brackets.
| | 03:16 | And if I define it like that, then the
print statement will print it like that.
| | 03:23 | So the assignment operator is
used for assigning a value in Python,
| | 03:30 | and it will also create an object if
that object has not already been created.
| | Collapse this transcript |
| Selecting code and values with conditionals| 00:00 | There are two different
types of conditionals in Python.
| | 00:03 | There is conditional execution,
and there is conditional values.
| | 00:07 | Let's take a look at what these look like.
| | 00:09 | We'll make a working copy of
syntax.py, call it syntax-conditionals.py.
| | 00:19 | Go ahead and open our working copy,
and we'll start in here by defining a
| | 00:25 | couple of variables. We'll just call them a
and b, and give them values of 0 and 1.
| | 00:31 | And 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:48 | So what we have here - I'm going to save that -
is an assignment for assigning two values,
| | 00:54 | 0 and 1, two variables, a and b.
And then we're testing if a is less than b, and
| | 00:59 | so this is a conditional statement.
| | 01:01 | And it has colon here, and that colon
means there is going to be a suite, or a
| | 01:06 | block of code, that is indented under that level.
| | 01:09 | And so here we have just a print
statement, so that's the only statement in that
| | 01:14 | suite, and it will only print if a is
actually less than b. So if I save this
| | 01:21 | and run it, we get a is
less than b in our result.
| | 01:26 | If I change this 0 here to a 1,
then we will get nothing in our result.
| | 01:32 | It won't print anything, you
see. There's nothing there.
| | 01:35 | Now, I can handle that
exceptional case, and I can say else:
| | 01:41 | print(a is not less than b), and save
that and run it, and now we see a is not
| | 01:50 | less than b because, in fact a is equal
to b. So this is the common if and else
| | 01:57 | in Python. You also have an else if,
which in Python is spelled like this, elif.
| | 02:07 | And you need another condition, else if
a > b, and we'll print a is greater than
| | 02:18 | b, and then our else. For else, we know
that if it's not less than and if it's
| | 02:23 | not greater than then it is equal, a = b.
| | 02:29 | So, if we save this and run it, of
course we get a = b, and if we make the a a
| | 02:36 | larger number than the b, and save
that and run it, then we get a > b.
| | 02:41 | So, this is the conditional
execution form of conditionals in Python.
| | 02:46 | We have the if clause, we have the
else if, and you can have a string of else
| | 02:50 | ifs, if you want to.
| | 02:51 | And we have the else, for if the
case where none of the ifs and else ifs
| | 02:56 | are evaluated to true.
| | 02:59 | There is another form of conditional
in Python, which is the conditional
| | 03:03 | expression, or the conditional value.
| | 03:06 | So we'll start with our
same assignment (a, b = 0, 1).
| | 03:10 | We'll say (s = "less than" if a < b
else "not less than) and then we'll go
| | 03:23 | ahead and print(s).
| | 03:27 | So what this does is this
is a conditional expression.
| | 03:32 | We have a value that's getting
assigned only if this condition is true;
| | 03:37 | otherwise, this other value would be assigned.
| | 03:41 | You may have seen this in other
languages done with question marks and colons,
| | 03:45 | and the designers of Python felt that
that was too obscure and too difficult to
| | 03:50 | read and decided instead to use
syntax that's much easier to read, and in
| | 03:54 | fact, this is much easier to read.
| | 03:57 | It'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:06 | Let's go ahead and save it and run it,
and we see that we get the word less
| | 04:10 | than, and if I make this a 1, now it's
now less that anymore, and I'll run that,
| | 04:17 | and it says "not less than".
| | 04:19 | So that is the conditional value, or
the conditional expression in Python.
| | 04:24 | So Python has two
different types of conditionals.
| | 04:26 | It's got conditional Execution, which is
with the traditional if, elif, and else,
| | 04:32 | and it has conditional expressions,
which don't use the question mark and colon
| | 04:38 | syntax of some other C-based languages,
which instead use the same keywords if
| | 04:43 | and else. It is actually a
whole lot easier to read.
| | Collapse this transcript |
| Creating and using functions| 00:00 | Functions, or subroutines, are a very
common form of reusable code, so let's look
| | 00:06 | at how functions are done in Python.
| | 00:09 | We'll make a working copy of syntax.py.
| | 00:12 | We'll call this syntax-functions.py.
| | 00:18 | Go ahead and open our working copy.
| | 00:19 | We'll notice, of course,
that main here is a function.
| | 00:24 | And the purpose of that is not so
much reusability as it is modularity in
| | 00:28 | allowing us to create more functions,
and be able to run them from main.
| | 00:33 | So let's go ahead and create a function here.
| | 00:39 | And I'll just call it func.
| | 00:42 | And we'll print out a range of numbers.
| | 00:47 |
| | 00:52 | And in my print statement
I am going to say end= ' '.
| | 00:57 | And that way instead of putting each
number on a separate line, we'll put them
| | 01:01 | all in the same line, separated by spaces.
| | 01:03 | And I'll put another print after it,
an empty one to print a new line.
| | 01:09 | And so I'll save that, and I'll
call the function from in main.
| | 01:14 | And we'll just call it instead of this
print function here, we'll just say func.
| | 01:19 | And that's all we need to
do to call our function.
| | 01:21 | So we'll save it and run.
| | 01:24 | And we see we are printing
out this sequence of 10 numbers.
| | 01:28 | And this is, in fact, how
the range function works.
| | 01:31 | It prints out everything not
including the number of the range.
| | 01:35 | So it's 10 numbers staring at 0.
| | 01:39 | Now if I wanted to call the function
again, I would just say func again, and I can
| | 01:43 | do that several times.
| | 01:45 | And each time it will run
this same block of code.
| | 01:48 | So I save it and I run it, and
that's how a function works.
| | 01:53 | So let's look at how we define the function.
| | 01:55 | The def keyword is for defining the function.
| | 01:58 | That means that what comes next is
going to be the name of the function, so
| | 02:01 | there is the name, and then there is a
set of parentheses where we would put
| | 02:05 | arguments, or parameters.
| | 02:07 | And the colon says that this is going
to be followed by a block of code, or a
| | 02:11 | suite of codes, as it's called in Python.
| | 02:14 | And then we have the suite of code itself.
| | 02:18 | The suite of code is indented under the
definition of the function, and in this
| | 02:22 | case of course, we're using the
traditional four spaces of indenting, like that.
| | 02:29 | Inside the parentheses we could put arguments.
| | 02:33 | So for example, if I put an argument
called a there, then I could say a, 10.
| | 02:40 | So it would start at the number a in
its range here, and so here I could use a 1,
| | 02:47 | and here I could use a 3,
and here I could use a 5.
| | 02:50 | And it would use that as an
argument to the range function.
| | 02:54 | What that does is it defines a
starting point for the range.
| | 02:58 | And so if I save that and run it, then we
see we have one that starts with 1, one
| | 03:02 | that starts with 3, and one that starts with 5.
| | 03:05 | And so this argument in the parentheses
is used inside the function in this way.
| | 03:12 | We can give the argument a
default value by saying a=0.
| | 03:17 | Well, let's give it something
different so we can see. Let's say a=7.
| | 03:22 | And if in this middle one I don't put
an argument, then that will be the default
| | 03:27 | argument that's used.
| | 03:28 | It'll default to 7.
| | 03:30 | So if I save this and run it, you
see that the middle one starts at 7.
| | 03:35 | So there are a lot of other things we
can do with functions and with function
| | 03:39 | arguments, and we'll cover those
later in our chapter on functions.
| | 03:42 | But this is, in a nutshell, how you
define a function in Python, and how you
| | 03:47 | call and use that function, and how
you can use arguments when you call and
| | 03:52 | use that function.
| | Collapse this transcript |
| Creating and using objects| 00:00 | Python is fundamentally an
object-oriented language.
| | 00:03 | In fact, in Python 3 everything is an object.
| | 00:08 | So let's look at how we
can create our own objects.
| | 00:11 | We'll start by making a working copy of
syntax.py. I'll call this syntax-objects.py.
| | 00:20 | And we'll open our working copy.
| | 00:22 | Now we'll go into a lot more
detail on objects later on.
| | 00:25 | The point here is just to get a
handle on the syntax of creating objects.
| | 00:30 | So we'll go ahead and start by defining a class.
| | 00:34 | Now a class is the definition that's
used when creating an object in Python.
| | 00:39 | So we'll use the class keyword,
and we'll call this class Egg.
| | 00:45 | And the first thing we'll define
inside of the class is a constructor.
| | 00:50 | And a constructor in Python is a method,
or a function inside the class, and has a
| | 00:54 | special name which is __init__, like that.
| | 01:00 | And all methods within classes
have self as the first argument.
| | 01:05 | This is a reference to the object itself.
| | 01:08 | And it's traditionally called self.
| | 01:10 | It's not required, but it's a really,
really good idea to always call it self.
| | 01:14 | And following self can be arguments that
can be used in constructing the object.
| | 01:19 | And in this case we are going
to say how do you want your eggs?
| | 01:22 | And so it'll be a kind of eggs, and
we'll call it kind, and we'll give it a
| | 01:26 | default value of fried.
| | 01:31 | And then we will assign this
value to an object variable.
| | 01:35 | And 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:48 | encapsulated in the object.
| | 01:50 | And so each instance of this class, each
object, can have a different value for kind.
| | 01:57 | Now let's define a method
for finding out what kind.
| | 02:02 | And we'll call this whatKind, and
it has self as the only argument.
| | 02:10 | And we'll simply return self.kind.
| | 02:14 | Now we have a class.
| | 02:16 | It's a very simple class, and it
doesn't do anything terribly useful, but it's
| | 02:19 | good as an example of the
syntax of how you create a class.
| | 02:24 | And now we'll go ahead and create an object.
| | 02:26 | Now an object is an instance of a class.
| | 02:28 | You can think of the
class as like the blueprint.
| | 02:31 | This defines how the object is created,
and the object itself is an instance.
| | 02:37 | The object is an encapsulation of all
of the methods and the variables that are
| | 02:42 | inside of the class.
| | 02:44 | And so we'll say fried = Egg, like that.
| | 02:51 | And that will create a object
called fried, based on the class, Egg.
| | 02:57 | And you notice we don't have anything
in the parentheses, so it will use this
| | 03:00 | default value when it
creates or constructs the object.
| | 03:05 | The constructor is called
every time you create an object.
| | 03:09 | So here we've created an
object with the assignment operator.
| | 03:12 | And so the first thing it'll do is
it'll call this Constructor, and it'll
| | 03:16 | assign this default value.
| | 03:17 | We can also create a scrambled egg, like this.
| | 03:23 |
| | 03:29 | And so when we print these out, later
on we can say print(fried.whatKind()).
| | 03:40 | And if we save this and run it,
it says that it's a fried egg.
| | 03:46 | Instead of the fried kind, I used the
scrambled kind, and this is just this different
| | 03:52 | object, but it's using
exactly the same interface.
| | 03:56 | If I save it and run it,
| | 03:58 | now we have a scrambled egg.
| | 04:00 | So this is just a very simple and a very
simplistic example of how an object is created.
| | 04:07 | We have a definition, which is called a
class, and this defines the blueprint of
| | 04:13 | how these objects are made.
| | 04:14 | And then we have a couple of
objects that are created using that class.
| | 04:21 | And so these are considered
instances of that class, or objects.
| | 04:26 | And these objects are completely
functional, and they contain data, and they
| | 04:31 | contain code in the form of these
methods, and that is how you define and
| | 04:36 | create objects in Python.
| | Collapse this transcript |
|
|
5. Variables, Objects, and ValuesUnderstanding variables and objects in Python| 00:00 | Everything in Python 3 is an object:
variables, functions, even code;
| | 00:07 | all of these things are actually objects.
| | 00:11 | In Python every object has
an ID, a type, and a value.
| | 00:17 | The id is a unique identifier that
identifies a particular instance of an object.
| | 00:22 | This cannot change for the life of the object.
| | 00:26 | The type identifies the class of an
object, and again this cannot change for
| | 00:31 | the life of the object.
| | 00:33 | The value is the contents of the object,
including whatever variables, or methods,
| | 00:39 | or properties the object may have.
| | 00:41 | Mutable objects can change their
value; immutable objects cannot.
| | 00:47 | Let's take a look in an
example of an object. This is idle.
| | 00:51 | It's the graphical interface of the Python shell.
| | 00:54 | Python comes with this in graphical
environments like Windows and Mac.
| | 01:00 | And if you are in a non-graphical
environment, an environment with just a
| | 01:03 | command line, you can just run the
Python by interpreter with the command line
| | 01:07 | and you'll get exactly the same interface.
| | 01:10 | So let's go ahead and create a variable.
| | 01:12 | For example, let's create an object.
| | 01:14 | We'll call it x, and we'll
assign it the number 42.
| | 01:18 | So we type x by itself.
| | 01:21 | The Python shell here will give us
the value of x. So that's its value.
| | 01:27 | Its id is this number, and the size of
the number, what the number looks like is
| | 01:33 | going to be different depending
on what your implementation is.
| | 01:36 | Generally, it's like an address.
| | 01:38 | It is a unique identifier that
identifies this particular object.
| | 01:43 | And the type of x is class int.
| | 01:47 | And you remember everything in Python
is an object, and so objects have class.
| | 01:52 | Their type is a class.
| | 01:55 | And so in this case it's an integer.
| | 01:58 | All variables in Python are first-
class objects, and what that means is that
| | 02:04 | what might look like a simple variable
may actually be something more complex.
| | 02:09 | It could be an object
that's been defined in a library,
| | 02:12 | it could be a built-in object, it
can be any sort of a thing, and it will
| | 02:17 | oftentimes have attributes and
methods, and we'll get into the details of
| | 02:21 | that later on in the course.
| | 02:23 | But for now what's important to
understand is that everything in Python is an
| | 02:26 | object, including variables, and as we
look at variables and we look at the types
| | 02:31 | of variables and how we use them, you
need to realize that they are objects, and
| | 02:36 | we'll oftentimes be using syntax like
this v.attribute or v.method to access the
| | 02:42 | attributes and the methods within those objects.
| | Collapse this transcript |
| Distinguishing mutable and immutable objects| 00:00 | Objects in Python may be mutable or immutable.
| | 00:04 | Mutable objects may change
value; immutable objects may not.
| | 00:09 | Some immutable objects at times may
look like they are changing their values.
| | 00:13 | They are not actually changing their
values though. The distinction is visible
| | 00:16 | using the id function.
| | 00:19 | Integers, container objects, strings,
things like these may appear to be
| | 00:24 | changing values when they are not.
| | 00:26 | For example, here in the Python shell, we
can create an object, and we'll call it x,
| | 00:32 | and we'll assign a number to it, 42.
| | 00:35 | Integers are immutable objects in Python, and
if we look at the value, we see that it's 42.
| | 00:39 | If we look at its type, we
see that its type is int.
| | 00:44 | If we look at the id, we see
that it has this unique identifier.
| | 00:51 | Now if I change the value of x, and
remember it's an immutable object so I cannot
| | 00:56 | change the value of an
integer, but I assign x = 43,
| | 01:00 | what I've actually done is I've changed this
variable x to refer to a different integer.
| | 01:07 | Variables in Python are references to objects.
| | 01:10 | So this reference is now
referring to a different object.
| | 01:14 | If I type id of x, you'll see
I get a different identifier.
| | 01:19 | If I type x, I see that it's 43.
| | 01:21 | If I assign x back to 42 and take its
id, you'll see that this id is now exactly
| | 01:30 | the same as the one up there.
| | 01:33 | So I did not actually change the
immutable value. I simply changed the variable
| | 01:39 | to refer to a different object.
| | 01:41 | This is an important distinction, and
it's one that may take a while for you
| | 01:45 | to get your head around, but we'll cover some
of those as we get into this in more detail.
| | 01:49 | There will be times when something that
you want to do, like change the value of
| | 01:54 | a string or to insert objects in a
tuple, you may find that you need to use a
| | 02:00 | different type, a mutable type instead
of an immutable type, in order to be able
| | 02:05 | to accomplish where it is
you are trying to accomplish.
| | 02:08 | In fact, most fundamental types in
Python are immutable. Numbers, strings, and
| | 02:13 | tuples are the fundamental
types that are immutable.
| | 02:17 | Mutable objects include lists,
dictionaries and some other objects, depending
| | 02:21 | upon their implementation.
| | 02:23 | So as you create your code in Python,
simply be aware that there are some
| | 02:27 | types that are immutable -
| | 02:29 | and these are typically the more
fundamental types - and other types that are mutable.
| | 02:33 | And as we get into the details of
these types, we'll talk about the things you
| | 02:36 | can and cannot do with
mutable and immutable objects.
| | Collapse this transcript |
| Using numbers| 00:00 | There're basically two
different kinds of numbers in Python.
| | 00:04 | Let's go ahead and make a
working copy of variables.py,
| | 00:07 | and we'll look at them, variables-numbers.py.
| | 00:15 | We'll open our working copy.
| | 00:18 | And we'll go ahead and define a variable.
| | 00:23 | And we'll give it a value.
| | 00:26 | And then we'll print that
variable and save and run.
| | 00:32 | And you see we get that value.
| | 00:35 | So what we have here is an integer type.
| | 00:39 | So if I type num and I'll also have num,
so we'll get both the type and the value,
| | 00:48 | we'll go ahead and run that,
| | 00:49 | and we see that its class
is int, and its value is 42.
| | 00:53 | If I say 42.0, now its type is
going to be <class 'float' > 42.0.
| | 01:00 | So those are the two
different kinds of numbers in Python.
| | 01:04 | You have integers, and you
have floating point numbers.
| | 01:08 | If I take an integer like this, and I say 42/
9, I'm no longer going to have an integer.
| | 01:15 | If I save this and run it, we'll see that
I have class 'float' and that it is this
| | 01:21 | real number with a whole lot of
digits after the decimal point.
| | 01:25 | If I want to get an integer division,
I can use two slashes instead of one.
| | 01:31 | And now what I'll get, instead
of 4.66666, I will get just 4.
| | 01:37 | You'll notice that it is not rounded up.
| | 01:41 | So if I want it to be rounded, I can
type round and get back the floating point
| | 01:48 | division and save that and run it,
| | 01:53 | and now we have it rounded up. It's a 5.
| | 01:55 | I can give another argument to round it
to how many digits I want it to round to.
| | 01:59 | I can save that and run it.
| | 02:01 | And now we have 4.67.
| | 02:04 | In addition to the integer division with
the two slashes, remember it was like this -
| | 02:11 | if I save that and run it, we get the 4 -
| | 02:14 | I might also want the remainder, which is
also called modulo, and that's with the % sign.
| | 02:22 | So if I save that and run it, I have 6.
That's the remainder after you do that 42/9.
| | 02:29 | It's 4 with a remainder of 6.
| | 02:34 | If I have a floating point number, say
42.9, but I want to make sure that
| | 02:41 | it's actually going to be read as an
integer, I can say int of, like this, and
| | 02:47 | save that and run it,
| | 02:49 | and I get just the 42 part.
| | 02:52 | Likewise, if I have an integer
number and I want the floating point
| | 02:58 | representation of it, I can say
float like that and save that and run it.
| | 03:04 | And I actually get a floating
point representation of the integer 42.
| | 03:09 | Float and int are actually object constructors.
| | 03:13 | These are constructors for those classes.
| | 03:16 | So when I say float 42, what I'm
actually doing is I'm creating an object of
| | 03:20 | type float, and I'm giving
it an initial value of 42.
| | 03:25 | That's getting passed to the constructor.
| | 03:27 | So those are the basic ways that you
can use and create integers and floating
| | 03:31 | point numbers in Python 3.
| | Collapse this transcript |
| Using strings| 00:00 | Python has some very powerful
facilities for working with strings.
| | 00:04 | And in fact, in Python 3, they become
refined, and in some cases even more powerful.
| | 00:10 | Let's get right into strings, and we'll
start by making a working copy of variables.py.
| | 00:16 | And we can call this variables-strings.py,
| | 00:21 | go ahead and open that working copy,
| | 00:24 | and we'll start by defining a String.
| | 00:27 | I'll just call it s, and I'll say
'This is a string!' and we'll go ahead, and
| | 00:34 | we'll print(s) and save that and run it.
| | 00:41 | And there we have the string.
| | 00:42 | Strings in Python are immutable objects,
| | 00:47 | and they're created with either
single quotes or double quotes.
| | 00:52 | And so if we change those single
quotes to double quotes, we'll see - if we
| | 00:55 | save and run, we'll see that
we get exactly the same result.
| | 01:01 | You can use Escape characters in a
string, as you can in many languages.
| | 01:06 | So if I put in here a \n, that'll
introduce a new line in the middle of the string.
| | 01:12 | And if I save that and run it, we see that
there is a new line now between the a
| | 01:17 | and the s of string.
| | 01:19 | On the other hand, if I want this \n to
actually be a part of the string, rather
| | 01:24 | than getting replaced with a new line,
I can put the letter r before the
| | 01:29 | definition of the string like that,
| | 01:32 | and if I save that and run it, I
get the \n as part of the string.
| | 01:37 | This is called a raw string, and the
place where this gets used the most is when
| | 01:42 | creating regular expressions.
| | 01:44 | And we'll get into regular
expressions in some detail in another chapter.
| | 01:49 | In addition to these sorts of Escapes
with the backslashes, you can also do some
| | 01:55 | formatting and replacing
of variables in the string.
| | 01:59 | For example, if I create a number and
call this, say n, and give it a value of
| | 02:06 | 42, I could put that 42 right
in the middle of the string here.
| | 02:12 | And I'm going to show you
the Python 3 way to do this.
| | 02:16 | And we'll look briefly at the Python 2 way to
do it as well, because you'll see that a lot.
| | 02:21 | For all your new code, you want to
use the Python 3 way, which is with the
| | 02:25 | format method of the string object,
because the Python 2 way is going to go away.
| | 02:32 | It's considered obsolescent, and it will
be dropped in the next version of Python.
| | 02:37 | So I'm going to save this and run.
| | 02:39 | And you'll see what this does.
| | 02:40 | This actually inserts the value
of n in the middle of the string.
| | 02:46 | We have these curly braces here, and
those get replaced with the format.
| | 02:54 | So format is a method of the string object.
| | 02:59 | And so this literal
string is actually an object.
| | 03:02 | Remember, everything in Python is an object.
| | 03:05 | We can use this objecty-referencing
operator, this period, to access a method
| | 03:10 | of that object, and do
this variable replacement.
| | 03:15 | So this is very powerful,
and this is very common.
| | 03:18 | And you'll see it done
this way in new Python 3 code.
| | 03:22 | In Python 2 code, you'll
see it's done this other way.
| | 03:24 | I'm going to put %s here, and over here
a % sign and the letter n. And so we'll
| | 03:36 | save that and we'll run it.
| | 03:39 | And you see we get the same result.
| | 03:41 | This is the way that it was done in Python 2.
| | 03:44 | And this is a bit of a hack.
| | 03:46 | It's perfectly valid,
and you'll see it a lot.
| | 03:49 | You'll even see it some in Python 3
code that's written by people who are used
| | 03:53 | to Python 2, and that's fine.
| | 03:56 | The reason you don't want to use this
construct is because it is considered
| | 04:00 | obsolescent, and it will be
dropped in the next version of Python.
| | 04:05 | So you'll see this, you want to know
what it does, but the right way to do it in
| | 04:10 | Python 3 is to use the new
format method of the string object.
| | 04:20 | And that will look like this.
| | 04:21 | I'll save that and run it.
| | 04:23 | And that's how that works.
| | 04:25 | There's one more way I want to show
you for defining a string, and this is
| | 04:29 | using the triple quotes.
| | 04:31 | And you can triple either the
single quotes or the double quotes.
| | 04:34 | So I can either do it this way, or
instead of these triple quotes, I can do it
| | 04:42 | this way with the double quotes, like this.
| | 04:45 | And you'll see it's done both ways.
| | 04:47 | I tend to use the singles
tripled instead of the doubles tripled.
| | 04:51 | Now what this does is it allows you to
have a string that spans several lines.
| | 04:58 | And so, what I'll often do is I'll start
with a backslash and a new line and go
| | 05:06 | all the way back to the
end of the line like that,
| | 05:09 | and this will allow me to just have
line after line of text and more text,
| | 05:20 | and to have it actually
started at the beginning of it.
| | 05:21 | I'll explain what this does in a moment.
| | 05:23 | Let's save this and run.
| | 05:24 | And then you can see what this does.
| | 05:26 | This is useful if you have
lines and lines and lines of text.
| | 05:30 | And so the way you do this is with
three quotes, either single quotes or double
| | 05:36 | quotes, at the beginning and the end.
| | 05:37 | And the result will be a string that
has the new lines, and it's all formatted
| | 05:41 | exactly like you type it in.
| | 05:43 | What this here does, this backslash and
a new line, is that it escapes the new
| | 05:49 | line, so that it doesn't
actually show up in the string.
| | 05:53 | If I didn't have this, and I save this and
run it - that's scrolled out of the way -
| | 06:01 | there you see that we get a black line
at the beginning, because this blank line
| | 06:04 | here is actually inserted in the string.
| | 06:07 | The way to get that not to happen is
to use the backslash before it.
| | 06:11 | The backslash has to be the very last
character on the line, so that it's escaping
| | 06:15 | the new line and not a space or something.
| | 06:18 | So I save that and I run it,
| | 06:20 | and you can see that we don't
have a scrollbar over here.
| | 06:22 | This is actually at the top,
| | 06:25 | and there is no new line at
the beginning of the string.
| | 06:27 | So that's the triple
quote way of defining strings.
| | 06:31 | And that's often used in docstrings in
function, which we'll get to later on in
| | 06:36 | the chapter on functions.
| | Collapse this transcript |
| Aggregating values with lists and tuples| 00:00 | Python has several sequential
types that look like lists of things,
| | 00:05 | and we're going to look
at a few of them right now.
| | 00:07 | Let's make a working copy of variables.py
and we'll call this variables-lists.py.
| | 00:17 | And we'll open that working copy.
| | 00:19 | So let's create a variable.
| | 00:21 | And we'll just call it x. And
we'll assign it a list of values in
| | 00:26 | parentheses (1, 2, 3).
| | 00:29 | And we'll go ahead and we'll print(x).
| | 00:31 | What print will do with this is it
will try to print it in a way that Python
| | 00:35 | could actually create one if it needed to.
| | 00:39 | And so it has it in the
parentheses just like that.
| | 00:42 | So let's print the type of it, also.
| | 00:45 | Save that and run it.
| | 00:47 | So the class is tuple.
| | 00:49 | So this is a tuple.
| | 00:52 | And a tuple is created with parentheses.
| | 00:54 | And a tuple is an immutable object.
| | 00:57 | So I can't insert things.
| | 00:59 | I can't append things.
I can't delete things.
| | 01:01 | Once I've created it, I've created it.
| | 01:03 | And I can't change it.
| | 01:05 | So this is useful for a lot of stuff.
| | 01:07 | Perhaps you just to
operate on a fixed list of things.
| | 01:11 | In fact, most of time, when you need a
list of something, you're probably not
| | 01:16 | going to need an immutable list.
| | 01:17 | And to use a tuple is going to be
faster than to use immutable list.
| | 01:22 | On the other hand, if we create this with
the square brackets, then we get the list type.
| | 01:27 | I'll save this and run it.
| | 01:30 | And the list type is mutable.
| | 01:32 | I can, in fact, add something to the end of it.
| | 01:35 | I can say x.append and call it the number 5,
| | 01:40 | and save that and run it,
| | 01:42 | and now we have the number 5 at
the end. Or I can say x.insert,
| | 01:49 | and insert it at the beginning, which I use
the index 0 for the beginning, and put a 7 there,
| | 01:56 | and save that and run it,
| | 01:58 | and now I have a 7 at the beginning.
| | 02:00 | I could, of course, insert that at any point.
| | 02:03 | If I say 2, use the number 2 there.
| | 02:08 | So this is item 0 and this is
item 1 and this would be item 2.
| | 02:12 | And we can expect the 7 to show up in there.
| | 02:14 | So I'll save it and I'll run it.
| | 02:16 | And there we have the 7 in there.
| | 02:19 | So you can actually modify the list
that is mutable, but if I were to change
| | 02:25 | this back to the tuple type, which is
immutable, and save it and run it, then I get an error.
| | 02:31 | That tuple object has no attribute
append, and in fact it has no attribute insert
| | 02:37 | either, because it's immutable.
| | 02:39 | And it cannot be changed.
| | 02:42 | So we'll go ahead and we'll take these out.
| | 02:44 | And I'm going to show you one other
sequence type that you've seen before, but
| | 02:48 | you might not have thought it in this way.
| | 02:51 | And that is the string.
| | 02:52 | If I save this and run it,
| | 02:58 | we'll see that we have a string.
| | 03:00 | Just like with any sequential type, I
can actually look at particular elements
| | 03:04 | of the string by subscripting it to say 2.
| | 03:07 | So that will be 0, 1, 2.
| | 03:09 | I'll just get the r. Save that and run it.
| | 03:13 | And there's the r. Or I can
do what's called a slice.
| | 03:18 | And we'll learn more about
slices later on. I can say 2:4.
| | 03:24 | And I'll get a slice of just the r and
the i. And in slices, it's worth noting
| | 03:29 | that even though I'm using the 2 index
for the beginning, which would be 0, 1, 2,
| | 03:34 | that'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:40 | The way slices work in Python, they
don't actually return that last element.
| | 03:45 | And there are explanations in the
documentation just to why that is.
| | 03:48 | And we will get more into slices
in more detail in a later chapter.
| | 03:52 | It's also notable that all of these
sequence types can be used as iterators.
| | 03:57 | So if I go back to (1, 2, 3, 4,
5), I have an immutable tuple.
| | 04:08 | And I'm going to for I in x: print(i).
| | 04:17 | And so that will print each one
on a separate line, each of the
| | 04:21 | different elements.
| | 04:22 | And in fact, the string also works like that.
| | 04:26 | If I put a string in here and save
and run, I get each of those individual
| | 04:32 | letters from the string.
| | 04:34 | So this is how you use sequences in Python.
| | 04:39 | There are a number of them.
| | 04:40 | These are the most common.
| | 04:42 | The tuple is immutable.
| | 04:44 | the list is mutable and is designated
with the square brackets instead of the
| | 04:48 | parenthesis for the tuple,
| | 04:51 | and a string is also a
sequence, an immutable sequence.
| | Collapse this transcript |
| Creating associative lists with dictionaries| 00:00 | Python has one more very
powerful aggregate type.
| | 00:04 | It's called Dictionary, and it's much
like what we would call an associative array
| | 00:09 | or a hash in another language.
| | 00:12 | So let's go ahead and make a working
copy of variables.py. We'll call this
| | 00:16 | variables-dictionary.py.
| | 00:24 | Go ahead and open up that working
copy, and we will start by defining a
| | 00:28 | dictionary, and I will call it d, and
when you use the curly brace notation for
| | 00:36 | defining it, and we will use
names for keys and numbers for values.
| | 00:49 | Just going to put five of them in here,
and space that out just a little bit and
| | 01:02 | then we will - say, we will print it
first here, d, and we'll go ahead and
| | 01:07 | we'll save and run, and
you'll see there is our dictionary.
| | 01:11 | Now, this can be useful for a number of things.
| | 01:15 | For example, we can step through
the keys and print values, for k in d,
| | 01:22 | and print.
| | 01:26 | print the key, and we will print the
value, which would be d k like this, and if
| | 01:32 | we save that and run it, you will see
that we get each of the keys and each of
| | 01:36 | the values from our print statement, so
we've iterated through the dictionary,
| | 01:41 | and it's given us the key in the k
variable, and we've used that to subscript
| | 01:48 | and to print out the value.
| | 01:50 | Now this is nice, but notice
that it's in no particular order,
| | 01:55 | that it's not alphabetical.
| | 01:57 | It's not numerical.
| | 01:58 | It's in no particular order whatsoever,
and this is common for hashed variables
| | 02:03 | in virtually all
environments that supports such.
| | 02:06 | So in Python, if you want to get this in
assorted order, use the Sorted built-in
| | 02:12 | function and you subscript the
dictionary object and use its keys method.
| | 02:20 | So sorted(d.keys()) like
that, save it and run it,
| | 02:25 | and now they are in
alphabetical order by the keys.
| | 02:28 | Five, four, one, three, and two.
| | 02:32 | those are alphabetical by the keys.
| | 02:35 | Now this particular syntax for
defining the dictionary is a little bit
| | 02:40 | awkward, don't you think?
| | 02:42 | Wouldn't it be nice if there
is a better one? Well there is.
| | 02:46 | Python has something called keyword
arguments, and we will learn about those
| | 02:51 | more in our chapter on functions.
| | 02:54 | But the keyword arguments are used to a
great advantage in defining dictionary
| | 02:59 | objects because we can do it like this,
say dict using the constructor for the
| | 03:06 | dictionary class, and I am just
going to go ahead and put that closing
| | 03:10 | parenthesis on a separate line and
go ahead and show you how this works.
| | 03:15 | So I can say one = 1, two = 2.
| | 03:18 | Notice I don't have to type
any of those nasty quotes.
| | 03:22 | Three = 3, four = 4.
| | 03:26 | Now if I had string objects that I was
using at the values, of course, I would
| | 03:30 | need quote, so I could say five = and
put the number five in quotes, like that.
| | 03:38 | And if I save this and run it, you will
notice that this works exactly the same
| | 03:44 | way, except we have this spelled out, word five there.
| | 03:47 | So that's a much easier, more convenient,
and a more common way to define a dictionary.
| | 03:53 | Dictionaries are mutable objects, so I
can add a new value to a dictionary, like
| | 03:58 | this, d 'seven' = 7, and save that, and
run it, and now we have the seven value
| | 04:10 | in the middle there in our sorted list.
| | 04:14 | So that's dictionaries in a nutshell.
They are very powerful and very useful,
| | 04:18 | and 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:00 | In Python, and especially in Python 3,
everything is an object, and an object has identity.
| | 00:08 | The identity of an object is a unique ID,
a unique number, which is specific to
| | 00:15 | that particular object and no other object.
| | 00:18 | This can be an important
consideration when we are considering things
| | 00:22 | like immutable objects.
| | 00:24 | And so Python has an ID function,
a built-in function, for finding the
| | 00:28 | identity of an object.
| | 00:30 | This is the Python Shell.
| | 00:32 | It's Idle, which is the graphical
interface to the Python Shell in
| | 00:36 | graphical environments, like
Windows and Mac, and some forms of Linux,
| | 00:41 | they have a graphical shell.
| | 00:42 | You will have this graphical
shell for a Python included with your
| | 00:46 | Python distribution.
| | 00:48 | In other environments that
don't have a graphical shell,
| | 00:51 | you will have something the Python
command-line interpreter, which if you just
| | 00:55 | type Python by itself, you
will get this same interface.
| | 00:58 | So we are going to start here by
creating an object. I am going to call it 'x',
| | 01:03 | and I am going to give it a value, 42.
| | 01:07 | Now when I type x by itself, I'll get
the value 42, and if I type ID of x, I
| | 01:14 | get that object's ID.
| | 01:15 | So this is the ID of the
immutable object, which is the integer 42.
| | 01:22 | If I type, type of x, I see that its
class is int., and so the x itself is
| | 01:30 | simply a reference to the
object, which is of type int
| | 01:35 | and has the value 42, it has the ID
| | 01:39 | that is this 505409528.
| | 01:43 | In fact, if I just type ID of 42,
I get exactly that same ID.
| | 01:50 | And if I type, type of 42, I get class int.
| | 01:54 | So the number 42 is an
object, and that object has ID.
| | 02:00 | It has type.
| | 02:02 | It has value, just like any other object.
| | 02:04 | So if I create another variable and call
it 'y', and assign it the value 42, the
| | 02:11 | ID of y is going to be exactly the same.
| | 02:15 | Of course, when I test for quality x==y,
I'll get true, but I can also test them
| | 02:21 | for being exactly the same object.
| | 02:24 | And that's what that 'is' operator, I
can say x is y and they are exactly the
| | 02:30 | same object, because they have the same ID.
| | 02:32 | The 'is' operator simply compares the
IDs, rather than comparing the values.
| | 02:37 | The double equal sign, which is this one
here, compares the values to see if the
| | 02:41 | values are the same.
| | 02:42 | The 'is' operator compares the IDs to see
if they refer to exactly the same object.
| | 02:49 | So let's say that I have a mutable
dictionary, and I say x = dict, and I'll just
| | 02:57 | give it (x = 42) and, so I now have a
dictionary object, and I say it type of x
| | 03:05 | and it's a dictionary object, I type x,
and I get that which is the dictionary
| | 03:10 | object and I type ID of x, and it is this.
| | 03:14 | Now, if I create another dictionary
object, and I say y = dict, and I say (x =
| | 03:21 | 42), I give it exactly the same contents,
and I say ID of y, I have a different
| | 03:31 | ID, and this is because a dictionary
object is a mutable object, and so there is
| | 03:36 | no reason - in fact it would make life
more difficult if by simply assigning the
| | 03:42 | same content to a dictionary Python
were to give me exactly the same object.
| | 03:47 | X and Y are still references that point
to objects, but these two objects, even
| | 03:53 | though they have exactly the same value,
if I say x, I get that, if I say y get
| | 03:57 | that. Those are exactly the same
value. These are different objects.
| | 04:01 | So I can test for x == y and I get True.
If test for x is y, I get False, because
| | 04:09 | it's pointing to two different objects.
| | 04:11 | So these can become important
distinctions, and we will see some examples as we
| | 04:15 | go into our examples of working code in Python.
| | 04:18 | We will see some examples of
where you can use something like this.
| | 04:21 | But at this point, what's important
for you to understand is what ID is.
| | 04:26 | That ID is a unique ID that refers to a
specific object, and how to test for the
| | 04:32 | quality of ID with 'is' operator to see
if two different variables - and remember
| | 04:39 | variables are referenced objects - to
see if two different variables refer to
| | 04:42 | exactly the same object.
| | Collapse this transcript |
| Specifying logical values with True and False| 00:00 | So we are going to talk about the
logical values of true and false here, and for
| | 00:04 | this purpose I have started up the
Python Shell, which on the graphical
| | 00:08 | interfaces will be called Idle, or if
you're in a command-line interface, it's
| | 00:13 | simply the Python interpreter.
It gets you exactly the same interface.
| | 00:16 | So, I'm going to start by creating
couple of variables. We'll call them a and b,
| | 00:20 | and we'll assign them
values of zero and 1 a, b - 0, 1.
| | 00:23 | And I'm going to say a==b, and so the
double equal sign is the equality operator.
| | 00:31 | It tests for equality between two values,
and it returns either True or False.
| | 00:35 | In this case it returns False, and false is
actually a keyword in Python, which is a
| | 00:42 | Boolean value for False.
| | 00:45 | So, if I say a < b, I will get the
Boolean value True, or a > b, I'll get the
| | 00:52 | Boolean value False.
| | 00:54 | In fact, you can assign True and False
to variables. I can say a = True, and if
| | 01:00 | I type a by itself, I get True. If I type,
type of a, you'll see it is class 'bool'.
| | 01:07 | So, True and False are objects of class
'bool,' and they are mutable objects of course.
| | 01:13 | So, if I type id of a, I get an id, and
if I assign b = True and type id of b, I
| | 01:21 | get exactly the same id.
| | 01:23 | In fact, if I simply type id
of True id, I will get that id.
| | 01:29 | So, true and false are Boolean
objects, and they are very simple, and they're
| | 01:34 | simply used for representing the
Boolean values of true and false.
| | Collapse this transcript |
|
|
6. ConditionalsSelecting code with if and else conditional statements | 00:00 | Conditional execution in Python
is handled with the If statement.
| | 00:06 | So, let's go ahead and make a
working copy of conditionals.py, call it
| | 00:13 | conditionals-working.py, and we'll
Open that up and start by just defining a
| | 00:20 | couple of variables.
| | 00:22 | a and b equals 0 and 1.
| | 00:24 | If we want to just execute some code, if a
is less than b, all we do is we type if a < b:
| | 00:33 | print ('this is true').
| | 00:35 | Now, when I save that and run it, you
see that 'this is true' got printed.
| | 00:42 | So, this print statement executed, and
the way this works is the if keyword
| | 00:46 | introduces the conditional, and the
expression here, a is less than b, and that
| | 00:50 | could be any expression that evaluates
to True or False and a colon introduces
| | 00:56 | the suite of code and so
this could be a suite of code.
| | 00:59 | It could be a number of things,
and that gets executed if this
| | 01:04 | expression evaluates to true.
| | 01:05 | If the expression does not evaluate to
true - I'll just change this 0 to 1, and a
| | 01:10 | is no longer less than b, save that
and run it - then nothing happens at all.
| | 01:15 | So, if we want something different to
happen, if the expression is false, then I
| | 01:21 | can simply say else and a colon and
another suite of code, it is not True.
| | 01:29 | So, if I save that and run it, then we
get that here it is not true, and if I
| | 01:35 | make this 1 a 0 again, save and
run, then we get 'this is true.'
| | 01:40 | So, this expression can actually be
any expression that evaluates to true or
| | 01:44 | false, and so I could just actually put
the word True there, and it'll be true,
| | 01:51 | save and run, this is true, or I can put
the word False there, and save and run,
| | 01:59 | and we get, 'it is not true.'
| | 02:01 | So, that is the if and else in Python.
| | 02:06 | If is a keyword, and then it's followed
by any expression that evaluates true or
| | 02:10 | false and a colon and then a suite of
code, and the optional else will execute
| | 02:16 | its suite of code, if the
condition is false and not true.
| | Collapse this transcript |
| Setting multiple choices with elif| 00:00 | If statements in Python can be extended
to test multiple conditions using elif.
| | 00:06 | Let's go ahead and make a working
copy of conditionals.py, call it
| | 00:11 | conditionals-working.py, and we'll go
ahead and open our working copy and
| | 00:20 | define a variable here.
| | 00:22 | We'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:42 | these as we wanted to.
| | 00:47 | So, when we save this and run it, you'll
notice we get v is one. And if we change this
| | 00:53 | one to, say, a three, save that and run it,
then we get v is three, but if we make
| | 01:00 | this a seven, then save that and
run it, nothing at all happens.
| | 01:07 | Now, if you want to have a
default case, you can simply say, else:
| | 01:12 | and this still gets executed if none
of the conditions turn out to be true.
| | 01:17 | Say, print v is some other thing,
| | 01:21 | and save that and run it, and we get V is some
| | 01:24 | other thing, because v is seven.
| | 01:26 | So, the thing to understand about this
is that only one of these suites is ever
| | 01:32 | going to be executed.
| | 01:34 | So, you have if, and an expression that
evaluates to true or false, and a colon,
| | 01:40 | and a suite, and then with each of the
elifs, you also have an expression that
| | 01:44 | evaluates to true or
false, and a colon, and a suite.
| | 01:48 | Only one of these suites is ever going to
get executed, and that's the purpose of elif.
| | 01:54 | It allows you to have several different
conditions that get evaluated, and only
| | 01:59 | one of them will ever get executed.
| | 02:02 | And then finally, the else clause is
executed in the event that none of the
| | 02:07 | conditions 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:00 | Some languages have a special
control structure, called switch, or case, or
| | 00:04 | something like that, that allows you to
select from multiple choices of a single variable.
| | 00:09 | Python doesn't have one.
| | 00:11 | So, we're going to take a look at one
particular strategy where you can do this
| | 00:16 | very easily within Python, and you'll see that
it's not necessarily a weakness in the language;
| | 00:22 | it's just different way of looking at things.
| | 00:24 | So, we'll go ahead and make a working
copy of switch.py, call it switch-working.
| | 00:33 | We'll open our working copy, and we'll start
by declaring a dictionary. We'll call it
| | 00:40 | choices, and we'll just put in a few
choices here, one first, two second, three,
| | 00:57 | and we'll declare a variable and then
we'll select based on that variable.
| | 01:08 | So, when I save this and run it,
you'll see that we have selected one and we
| | 01:17 | printed out first. And if I change this to say
three, save that and run it, it'll save third.
| | 01:24 | So, here we've been able to very easily
select based on a number of choices, and
| | 01:29 | we could make this a very long list
if we wanted to, and we can add things,
| | 01:33 | delete things from the list, and
change things in the list, and this will all
| | 01:36 | work exactly as expected.
| | 01:38 | The one thing this does not do well is
if I select something that's not in the
| | 01:42 | list, you'll see that we get
an error, save that and run it.
| | 01:48 | Of course, we can trap this error
with try and accept, or there is an even
| | 01:53 | easier way to do this. We can use the
get method of the dictionary object,
| | 01:58 | so you get V comma, and then I can put in a
default result, and I can say other.
| | 02:06 | And so what that does is it looks for V
in the dictionary, and if it doesn't find
| | 02:11 | it, it gives you back this value.
| | 02:12 | So, if I save that and run it, you can
see we get other, because we have seven.
| | 02:17 | If I put in five, then I'll get
fifth. Save and run and there is fifth.
| | 02:24 | So, this is a very simple way to do
what most people use switch statements for
| | 02:29 | and you'll see some other examples,
including an example of executing code based
| | 02:34 | on multiple choices, later on in the course.
| | Collapse this transcript |
| Using the conditional expression| 00:00 | One other type of
conditional structure in Python is the
| | 00:03 | conditional expression.
| | 00:05 | Let's make a working copy of
conditionals.py, conditionals-working.py and we'll
| | 00:12 | open up that working copy, and we'll go
ahead and assign a couple of variables.
| | 00:19 | Now, a lot of times, all you're doing
with a conditional is something like this.
| | 00:26 | if a is less than b, then V equals this
is true, else, V equals this is not true and print v.
| | 00:43 | You'll see this kind of a thing a
lot in a lot of different languages.
| | 00:46 | We save that and run it, say
this is true, and if the condition is
| | 00:53 | otherwise, save and run.
| | 00:55 | It says this is not true.
| | 00:58 | So, in Python, there's a much,
much easier way to do this.
| | 01:01 | You can simply say v equals this is
true if a is less than b, else, this is not
| | 01:10 | true, And so that takes all
| | 01:13 | of this, and it basically
puts it in an expression.
| | 01:17 | So delete that, and I save and run,
and we get exactly the same results.
| | 01:24 | Make that a 0 and it'll say
this is true, and this is true.
| | 01:30 | So, all we've done here is we've taken
that whole if-else structure and we put
| | 01:35 | it in an expression.
| | 01:36 | And Python has several of these, and
we'll cover these throughout the course,
| | 01:40 | but it's a convenient shorthand, and
you'll notice that it even reads well.
| | 01:44 | v equals this is true if a is
less than b, else, this is not true
| | 01:48 | And so this part here is what
makes it a conditional expression.
| | 01:54 | You have if, and you have the expression
that evaluates true or false, and else,
| | 02:00 | and then a second value.
| | 02:01 | So, without all of this, you would
simply have v equals this is true,
| | 02:07 | and with all of this, you have a conditional
expression, this is true or this is not true,
| | 02:12 | depending on the evaluation
of this conditional expression.
| | 02:17 | So, that's a conditional expression
in Python, and it's a very convenient
| | 02:21 | shorthand for a lot of cases where
you would otherwise use four lines of if
| | 02:25 | and else.
| | Collapse this transcript |
|
|
7. LoopsCreating loops with while| 00:00 | The simplest form of a loop
in Python is the while loop.
| | 00:04 | So, let's make a working copy of
while.py, while-working.py, and we'll go ahead
| | 00:12 | and open our working copy there.
| | 00:14 | The while loop is controlled with the
while keyword, which we can see here, and
| | 00:18 | then there is an expression.
| | 00:21 | So, the expression gets evaluated, and
if the expression is true, then the code
| | 00:25 | inside the loop, the suite, is executed.
| | 00:29 | After that code is executed, the
expression is evaluated again, and if it's still
| | 00:34 | true, the code gets executed again.
| | 00:37 | This continues until the expression is
evaluated as false, and then the execution
| | 00:43 | begins after the while loop.
| | 00:45 | So, let's go ahead and run this,
and there is our Fibonacci series.
| | 00:50 | So, this expression is b<50, so as
long as the result there is <50, the while
| | 00:58 | loop will continue.
| | 00:59 | So, if I were to increase this to say
150, save that, and run it, then we get a few
| | 01:05 | more numbers out there in the Fibonacci series.
| | 01:09 | So, while is the simplest form of loop
in Python, and you can see all it does is
| | 01:14 | it evaluates this expression.
| | 01:16 | As long as the expression is true, it
executes the code in the while loop, and as
| | 01:21 | soon as the expression
is not true, the loop ends.
| | 01:24 | So, that's the while loop in Python.
| | Collapse this transcript |
| Iterating with for| 00:00 | One of the most common reasons for
using a loop in programming is what's
| | 00:04 | called an iterator.
| | 00:06 | This is where you need to step through
some data structure, taking one object
| | 00:10 | at a time, and doing something with each of
those objects before going back for the next one.
| | 00:15 | Let's take a look at how this
works in Python with the 'for' loop.
| | 00:18 | We'll make a working copy of for.py, and
call it for-working.py, and we'll go ahead
| | 00:26 | and open that working copy.
| | 00:28 | Here, we are opening a file with lines
of text and reading that file line-by-
| | 00:34 | line and printing out each line on the screen.
| | 00:37 | So, let's go ahead and run it and see
what it does, and we see that it prints
| | 00:41 | these lines of text, and there they are.
| | 00:44 | If we open the file here, lines.txt, we
see that it has these five lines of text.
| | 00:48 | You'll notice that in the file the lines
are right next to each other, and in our
| | 00:53 | result, it's printing a blank line between them.
| | 00:56 | The reason for that is that the print
function prints a blank line after each
| | 01:00 | object that it prints, and the line
itself has a line ending at the end of it.
| | 01:05 | So, we can make print not to do that by
typing end = " " just a empty string. If we
| | 01:11 | save that and run it, then we get the
lines of text, just like we expect them.
| | 01:15 | So, the readlines method, inside the
file object, is what's called an iterator.
| | 01:21 | What this does is it takes one object
at a time from a sequence of objects, and
| | 01:28 | it returns those, one at a time, in
this case into the line variable.
| | 01:32 | The for loop is designed to work with
iterators, so the for keyword introduces
| | 01:37 | the for loop, and then a variable name,
which is used to contain each object in
| | 01:42 | the iteration, and in
keyword introduces the iterator.
| | 01:46 | So, it reads like for line in iteration
or for line in file object readlines, and
| | 01:53 | then it prints each line, one at a time.
| | 01:56 | So, this here, this file
object, .readlines, is the iterator.
| | 02:01 | In Python, all the
container types are iterators.
| | 02:05 | So, if I have a list, let's say 1, 2, 3, 4,
5, then it will work exactly the same.
| | 02:13 | It will just print 1, 2, 3, 4, 5 all in
one line because we are not ending our
| | 02:16 | lines with a new line
here in the print function.
| | 02:19 | So, if I save that and run it, we just get 12345.
| | 02:22 | In fact, a string is a container object,
and this will work exactly the same way.
| | 02:29 | It will just take each letter from the
string, and of course that will just look
| | 02:33 | like the word string.
| | 02:34 | But instead of we take this out and
print them one line at a time, we can
| | 02:38 | see that we are getting
each letter as separate object.
| | 02:42 | So, the string is a container
that contains individual characters.
| | 02:47 | In this case, we are printing the
lines of the file, and the readlines method,
| | 02:55 | from the file object, is the
iterator that gives us one line at a time.
| | 03:00 | So, if I save this and run it,
there we get the lines of the file.
| | 03:04 | So, that's the for loop.
| | 03:05 | The for loop is used for stepping
through iterators, and virtually all container
| | 03:11 | types in Python are iterators.
| | 03:14 | So, you'll see the for loop use a lot.
| | 03:17 | In fact, in my informal survey of Python
code, as I was preparing for this course,
| | 03:23 | I saw probably 20 or 30 for loops
for every while loop that I saw.
| | 03:27 | The for loop is by far the most
common type of a loop in Python because
| | 03:32 | iteration is such a common thing to need to
do, and so many objects in Python are iterators.
| | 03:38 | So, that's the for loop, and that's how
it works for line in readlines, so it's
| | 03:44 | for variable in container.
| | 03:47 | Then that variable becomes available to
the suite of the loop, and that's how a for
| | 03:52 | loop works in Python.
| | Collapse this transcript |
| Enumerating iterators| 00:00 | For loops in Python are very useful for
iterating over container types, and yet
| | 00:05 | they are significantly different
from for loops in other languages.
| | 00:09 | In particular, for loops in other
languages tend to have some sort of an index
| | 00:14 | variable associated with them, and this
can some times be useful. And we don't
| | 00:18 | have that in the standard for loop in Python.
| | 00:21 | So, let's take a look at how we
can get that very easily using the
| | 00:26 | enumerate function.
| | 00:27 | Go ahead and make a working copy of
for.py. I'll call it for-working.py and open
| | 00:34 | that working file, and this is our
little readlines example. And if we run this,
| | 00:42 | You'll notice that we get the lines of text
from the lines.txt file, which looks like this.
| | 00:47 | They have that extra new line in them. We'll go
ahead and get rid of that with end=" ".
| | 00:54 | I am going to add something to this
here. I am going to add the enumerate
| | 00:57 | function, enumerate, and it goes like that.
| | 01:03 | Enumerate actually returns two values.
The first value is an index, and the
| | 01:08 | second the value is the value from the iterator.
| | 01:11 | I am going to print the index before the
line, and we'll save this and run it, and
| | 01:17 | you'll see what we get.
| | 01:18 | So, the index is this extra number over
here, and you'll notice that it starts at
| | 01:22 | 0, and that's actually a useful place
for it because that's how you index
| | 01:26 | containers in Python.
| | 01:28 | So, let's take a look at an entirely
different example here, and we'll take a
| | 01:32 | string, and we'll iterate over that string.
| | 01:38 | We'll use the enumerate function, and we
will print the index and the character,
| | 01:48 | just so you can get an idea of
that looks like, save it and run it.
| | 01:52 | So, here we have - I am going to scroll
back up - each position in the string, with
| | 01:56 | its index number and its character.
| | 01:59 | Now, let's say that I am just
interested in the letter S. So, I want to know
| | 02:05 | which of these characters are the
letter S. I can say if c='s' like that:
| | 02:11 | print ('index'), number is an S,
and I'll do a format I, like this.
| | 02:21 | That will place the value of the
index into this placeholder here.
| | 02:27 | So, I'll save that, and run it, and now
we know index 3 is an s, index 6 is an s
| | 02:33 | and index 10 is an s. So, counting
from 0, 1, 2, 3 there is an S, 4, 5, 6 is
| | 02:41 | an S, 7, 8, 9 and 10.
| | 02:45 | So 3, 6 and 10 are the Ss. So, sometime
it's necessary to be able to find at what
| | 02:51 | index, in an array type, a particular value is.
| | 02:55 | This is a very useful pattern for doing
that, and there is actually a lot of uses
| | 02:59 | for having this index, and
enumerate is how you can get that.
| | 03:03 | So, this is how you get indexes
and an iterator with for loop.
| | 03:07 | Use this pattern here for, index and
value and enumerate, which returns those two
| | 03:13 | values, and the argument to
enumerate is the iterator.
| | 03:17 | Then you have the index and the
value available inside your for loop.
| | Collapse this transcript |
| Controlling loop flow with break, continue, and else| 00:00 | Sometimes when you are writing a loop
you need a way to shortcut the loop, or to
| | 00:04 | break out of the loop, and
Python has controls for this.
| | 00:08 | Let's go ahead and make a working
copy of loopcontrol.py. I'll call this
| | 00:15 | loopcontrol-working.py and go
ahead and open that working copy.
| | 00:19 | Here, we have a simple loop that
prints out each character of a string.
| | 00:23 | It looks like it's just printing the
string, but it's actually doing it one
| | 00:26 | character at a time in the loop.
| | 00:28 | I'll go ahead and run this, and
you'll see that's what it looks like.
| | 00:31 | Let's say that we wanted to skip all of
the letter Ss. We could simply say if c =='s':
| | 00:38 | and continue.
| | 00:40 | What continue does is it shortcuts the loop.
| | 00:43 | It just goes back to the beginning and
gets to the next iteration without doing
| | 00:47 | whatever comes after it.
| | 00:49 | If we save this and run, we
see that we skip all the Ss.
| | 00:53 | On the other hand, maybe we want
to end at the first s. Maybe we were
| | 00:56 | just looking for the first s. So, we can use
break, and break jumps out of loop entirely.
| | 01:02 | Let me save this and run it.
| | 01:03 | That terminates the loop.
| | 01:05 | It just brings the first 3 characters, and
when it gets that first s, it stops entirely.
| | 01:10 | So, that's break and continue.
| | 01:12 | Finally, there is one more control in Python.
| | 01:16 | It's called else, and it works just
like else does in an if statement.
| | 01:21 | If I say else here, and print
('else') and get rid of this break,
| | 01:28 | what this does is this gets run whenever
this condition becomes completely false.
| | 01:33 | In other words, when the iterator is out
of stuff to iterate, then else gets used.
| | 01:38 | So, if I save this and run it, you see
that it prints the entire string and
| | 01:43 | then it prints else.
| | 01:44 | And else also works in a while loop - actually
all of these controls also work in while loop.
| | 01:50 | I am just going to show you this one.
I am going to do this as a while loop
| | 01:53 | here, we'll say i= 0 and while (i<len(s)).
| | 02:00 | We don't have this c here any more. We can
say s so i, and then we'll need to increment.
| | 02:06 | All right, here we go.
| | 02:09 | So, let's save this and run it, and we
see that does exactly the same thing.
| | 02:14 | So, when this condition becomes
false, in other words when we've
| | 02:17 | incremented past the end of the
string, then else gets used, and it prints
| | 02:22 | the else down there.
| | 02:23 | So, that's break and continue and
else, and these are controls that will break
| | 02:30 | entirely out of loop.
| | 02:31 | will shortcut a loop with continue, or
else is used when the condition becomes
| | 02:36 | completely false, or if it's
never true in the first place.
| | 02:40 | So, that's break, continue and else.
| | Collapse this transcript |
|
|
8. OperatorsPerforming simple arithmetic| 00:00 | In this chapter, as we look at operators
in Python, we are going to be using the
| | 00:03 | Python Shell which is called Idle in
a graphical environment, or in a text
| | 00:08 | environment, it's simply the Python
Interpreter, run from the command line.
| | 00:12 | Python has all of the standard arithmetic
operators. For example, if you say 5 + 5, you get 10.
| | 00:19 | If say 5 * 5, you get 25.
| | 00:22 | If you say 5 - 3, you get 2, and
if you say 5 / 3, you get this 1.666.
| | 00:33 | Python also has some thing that they call
floor division, which is simply integer division.
| | 00:37 | If I say 5 with two slashes divide by
three then I get 1, which, of course, has
| | 00:44 | a remainder as well.
| | 00:46 | So if I say 5 with a percent sign from
modulo and a 3, then I get the remainder.
| | 00:53 | Python also has a built-in function called
divmod that gives the two results together.
| | 00:58 | So if we say Divmod(5, 3), then you
get both of those results together as a tuple.
| | 01:07 | Finally, Python has increment and
decrement operators, and they are not quite the
| | 01:12 | same as you see in some
other scripting languages.
| | 01:14 | If I say num = 5 and I say num += 1,
then look at the value of num; we get 6.
| | 01:25 | If I Say, num -= 1 and we look at
the value of num, then we get 5.
| | 01:32 | There is also a
multiplication and division form of these.
| | 01:36 | So If I say num *= 5, I get 25.
| | 01:41 | If I say num floor division
equals 5, then I get the integer 5.
| | 01:49 | Of course if I say num *= 5 again and
then num with one slash /=5, then we get the
| | 02:01 | floating point version 5.0.
| | 02:03 | So those were the basic arithmetic
operators that are available in Python.
| | 02:07 | It has all the standard ones, and a
couple that it's implemented in its
| | 02:12 | own interesting way.
| | Collapse this transcript |
| Operating on bitwise values| 00:00 | Python also has a full set of bitwise
operators for operating on binary values,
| | 00:05 | and occasionally this comes in handy.
| | 00:08 | It's a little bit difficult to show,
because when you print a value, for
| | 00:14 | example if I just say 5 here,
it will print it in decimal.
| | 00:19 | Even if I specify it in binary,
| | 00:22 | if I say it 0b0101, which is a five,
it still prints it in decimal.
| | 00:29 | So I am going to write a little
one-line function, and I'll call it b for
| | 00:35 | printing binary values.
| | 00:37 | I am going to use a format string here, and
we'll learn more about those in a later chapter.
| | 00:47 | The format method of the string, like
that, and now when I say b5 like that, it
| | 00:58 | prints the binary value to 8 places.
| | 01:02 | That's basically what that format
string does inside the curly braces,
| | 01:06 | the :08b, that prints out a binary value to 8 places.
| | 01:12 | So now we can look at the binary operators,
and we can see what they do on a bitwise level.
| | 01:17 | So, we are going to define a couple of
values, and we will call them x and y. And
| | 01:24 | x, we'll give it a couple of fives,
so that it's 010101 et cetera.
| | 01:30 | We will do that like this.
| | 01:34 | And y, we'll do the same thing, but with
the opposite bits and that happens to
| | 01:40 | be xaa in hexadecimal.
| | 01:43 | So if we look at these values,
x looks like that and y looks like that.
| | 01:50 | So the or of these two values should
be x|y, and the vertical bar there is the
| | 01:58 | or operator.
| | 02:01 | We will have all the bits set, like that,
and the and of the two values, which is
| | 02:07 | with the ampersand, will
have all the bits cleared.
| | 02:13 | The exclusive or will look just like the or.
| | 02:20 | So instead, let's take the exclusive
or of, say, x and, say, 0 and that will look like that.
| | 02:32 | Or if we take the exclusive or of x
and all the bits on, it will look like
| | 02:39 | that, because all of the bits get flipped.
| | 02:41 | We also have shift operators.
We can say x shifted left by four bits, and
| | 02:48 | there we have four clear bits on the
right, or we can say x shifted to the right
| | 02:54 | by four bits, and it
clears all the bits to the left.
| | 02:59 | We have the one's compliment operator
which is the unary operator and it just
| | 03:04 | looks like that, a little tilde.
| | 03:07 | Since it operates on the word size of
the implementation, which is more than
| | 03:12 | the 8 bits that I am printing, it gets a
sign extension, and it ends up looking like that.
| | 03:17 | So those are the bitwise or binary operators.
| | 03:21 | The word binary could mean
having to do with two values.
| | 03:24 | So we call them bitwise operators.
| | 03:26 | Those are the bitwise
operators available in Python.
| | Collapse this transcript |
| Comparing values| 00:00 | Python also has a complete
set of comparison operators.
| | 00:04 | For example, if I say 5 < 6, I'll get True.
| | 00:11 | If I say 6 < 5, I'll get False.
| | 00:15 | Likewise, if I say 5 <= 6, I'll get
True, or 5 <= 5, I'll also get True.
| | 00:27 | It also has greater than or
equal to, 6 >= 5 or 6 >= 6.
| | 00:36 | 6 is not of course >= 7.
| | 00:40 | And equality is tested with the
double equal signs. So 5 == 5 is True.
| | 00:47 | And 5 == 6 is not True.
| | 00:51 | Then it has a not equal
operator. So 6 != 7 is True.
| | 00:59 | And 6 != 6 is False.
| | 01:03 | It also has is and is not,
and these are for testing id.
| | 01:09 | So for example, if I have two
variables x and y, and we'll assign them values
| | 01:16 | of 5 and 6.
| | 01:19 | So the id(x) is that, and the id(y) is that.
| | 01:26 | So they're not the same.
| | 01:28 | So if I say x is y, I get False.
| | 01:31 | If I say x is not y, I get True.
| | 01:37 | Likewise, if I assign 5 to y,
now their ids will be the same.
| | 01:44 | Id(y) is the same as id(x).
| | 01:49 | Now x is y. For immutables like
integers, the ids are always going to be the
| | 01:56 | same if the value is the same.
| | 01:57 | So testing equality and testing id is
almost the same thing, but for immutables,
| | 02:03 | like for example, if I have a list, I
say x, y = a list with 5 and another
| | 02:11 | list with 5,
| | 02:17 | now they have different ids,
id(x) is that and id(y),
| | 02:25 | you can see that they have two different
ids now, even know their values are the same.
| | 02:29 | So if I test x = y, it's True,
| | 02:32 | but if I test x is y, it is now not
True, because they have different ids.
| | 02:37 | They're actually different objects.
| | 02:40 | So those are the comparison operators in Python.
| | 02:43 | You can compare values, and you can
also compare ids with is and is not.
| | 02:48 | So when would I want to compare ids?
| | 02:51 | Because Python is fundamental an
object-oriented language, everything in
| | 02:55 | Python is an object.
| | 02:58 | And because Python, of course, supports
polymorphism there's going to be times
| | 03:02 | when you're going to be using objects.
| | 03:05 | You may need to know is this exactly the
same object as this other object over there?
| | 03:10 | Which object is it that I'm dealing with?
And you can't know which is by testing value.
| | 03:15 | So this is a time when you might want
to use is and is not to test for the
| | 03:20 | identity of the object rather than
just testing the value of the object.
| | 03:24 | So those are Python's comparison operators.
| | 03:27 | Of course, you can compare
value, as well as comparing identity.
| | Collapse this transcript |
| Operating on Boolean values| 00:00 | Boolean values in Python are the
special True and False objects.
| | 00:06 | So if I say 5 == 5, I get the True value back.
| | 00:13 | And if I say 7 < 5, I get the False value back.
| | 00:18 | So True and False are special values.
They're actually of a Boolean class.
| | 00:24 | If I say, type(True) <class 'bool'>.
| | 00:28 | And we have a couple of operators for
dealing especially with Boolean values.
| | 00:33 | So if I say True and
False, like that, I get False.
| | 00:38 | If I say True and True, I get True.
| | 00:42 | If I say True or False, that's True.
| | 00:46 | If I say False or False, that's False.
| | 00:51 | So the and, and the or operators, the
ones that are spelled out as words, are
| | 00:57 | especially Boolean operators.
| | 01:00 | These are different then the bitwise, and, or.
| | 01:04 | So if I say True & True, like this, I get True.
| | 01:11 | The difference is that's a bitwise operator.
| | 01:14 | I'm doing bitwise arithmetic, as
opposed to simply Boolean arithmetic.
| | 01:21 | I'm doing bitwise arithmetic, which is
different then the Boolean operators.
| | 01:25 | So the Boolean operators
are and and or spelled out.
| | 01:30 | And they're useful for
things like this. If I have,
| | 01:32 | say, two values a, b and they're 0, 1,
and if I have another two values x, y and
| | 01:42 | they're spelled out say 'zero', 'one',
| | 01:45 | and I say x < y, which of course is False,
| | 01:52 | and a < b, which of course is True,
| | 01:55 | so I could say, if I wanted to, if a <
b and x < y, of course, that won't be
| | 02:05 | True print('yes') else:
| | 02:10 | print('no') and it prints no.
| | 02:17 | And so here I'm combining these two
Boolean values. a < b, will result in a
| | 02:23 | Boolean value of True. x < y
results in a Boolean value of False.
| | 02:29 | And so if they're both True, which
they're not, we would print('yes').
| | 02:33 | And if they're not both
True then we'll print('no').
| | 02:36 | So this is where you use the Boolean operators.
| | 02:39 | You use them when you're
operating on two Boolean values.
| | 02:42 | And you're get these Boolean values
typically in a comparison operation, like
| | 02:47 | less than, or greater than, or one of the
comparison operators that we covered in
| | 02:52 | our movie on comparison operators.
| | 02:54 | So 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:00 | Slices are Python
terminology for parts of a container.
| | 00:05 | So as an example, let's go ahead and
set up a container here, call it list,
| | 00:12 | and we'll use the mutable list type, and we'll
go ahead and assign it a bunch of values here.
| | 00:25 | Now the interesting thing to note
about this is that the first element of
| | 00:29 | the list is at index 0.
| | 00:32 | So if I say list sub 0, and you get the number 1.
| | 00:35 | Of I say sub 1, we are going to get the number 2.
| | 00:40 | So it's important to note that the
subscripts of container objects in
| | 00:45 | Python are 0-based.
| | 00:48 | That means that the first item is
number 0, the second item is number 1, the
| | 00:51 | third item is number 2, and on like that.
| | 00:54 | So we have 10 items here, and
they are numbered 0 through 9.
| | 00:57 | So if I look at list sub 9, we have a number 10.
| | 01:02 | Also it's interesting to note that if
I say, if I want to get items 0 through
| | 01:08 | 5 and I use this syntax here, which is called a
slice, that is the slice of the first 5 items.
| | 01:16 | And you'll notice that it gives me 0
through 4, because item number 4 is the
| | 01:22 | one with a 5 in it.
| | 01:23 | So when I said list 0 through 5,
that actually means list 0 through 5.
| | 01:29 | But it always gives me everything
up to, and not including, the last item.
| | 01:34 | Now many people find this
confusing. I find this confusing.
| | 01:38 | The reasons for it are well explained in
the Python documentation, and it's still
| | 01:43 | hard to warp your head around.
| | 01:45 | The thing to remember is that
ranges in Python are non-inclusive.
| | 01:51 | It's like if I use the range object, and
I say I want the range of 0 through 10,
| | 02:00 | and of course it gives it me in
that form because it's an iterable.
| | 02:04 | I have to say 4 i in range of 0
through 10, print i. And it's going to give me
| | 02:12 | 0 through 9.
| | 02:16 | So ranges in Python are non inclusive.
| | 02:20 | They never include the last item.
| | 02:23 | And that second argument
in the slice is a range.
| | 02:28 | So if I say list 0 through 10, it's
going to give me 0 through 9, which in our
| | 02:35 | case ends with the number 10. Confusing?
| | 02:38 | Yes. Understandable?
| | 02:40 | Yes, it 'sunderstandable.
| | 02:42 | So let's go ahead and make
our list a whole lot bigger.
| | 02:44 | I am going to use a shorthand here.
| | 02:50 | That's going to give us 100 items in our list.
| | 02:52 | And there they are, 0 through 99.
| | 02:56 | And so if I want to look at item 27,
it's going to give me item 27, which in this
| | 03:03 | case because we used a range for the
entire thing actually has a 27 in it.
| | 03:07 | And that makes it easy for us
to deal with our nice, long list.
| | 03:11 | Okay there is a third argument to this
slice operator, which is also optional.
| | 03:16 | The first one, of course, is the index.
| | 03:19 | So if I say list sub 27, that's the
first one, and that will give me a slice of
| | 03:24 | just one element at index number 27.
| | 03:28 | If I say list sub 27:42, this will
give me a slice that begins at index 27
| | 03:37 | and ends at index 42 and is non inclusive,
so it actually won't give me that last one.
| | 03:43 | So I get 27 through 41.
| | 03:45 | The last one, if I say list sub 27:
42:3, that's going to give me every
| | 03:53 | third element.
| | 03:56 | So it starts at 27, and then it
gives me 30 and 33 and 36 and 39.
| | 04:02 | And it does not give me 42, because our
range is non-inclusive, so it didn't include 42.
| | 04:09 | If I had said list sub 27:43:3, then
it would have given me that 42 element.
| | 04:18 | So the slice operator actually
has three possible arguments.
| | 04:23 | The first one is the
index, where the slice begins.
| | 04:27 | And the second one, which is
optional, is the index where the slice ends.
| | 04:32 | If it's omitted, then it simply
gives me one element at the index that I
| | 04:37 | specified in the first argument.
| | 04:39 | The third argument is the step.
| | 04:41 | And that indicates how many elements
to step over for each iteration, and what
| | 04:46 | this returns, of course, is an iterator.
| | 04:49 | So if I were to say 4 i in list sub 27
:43:3 : print i. We get the elements from our results.
| | 05:06 | Finally, it's important to note that we
can actually assign - and that's the reason
| | 05:11 | that I used a mutable
object here for our example -
| | 05:14 | we can actually assign to the slice.
| | 05:17 | I can say list sub 27:43:3 =,
and I can put something in there.
| | 05:26 | Let's say 99, 99, 99, 99, 99, 99.
| | 05:32 | And I can put all 99s in there.
| | 05:36 | And now when I look at my list, where I
used to have a 27, I now have a 99, and I
| | 05:43 | have a 99 there, and I have a 99
there, and so all of these elements got
| | 05:49 | replaced with 99s, because you can actually
assign to a slice as well as just reading from it.
| | 05:57 | So slices are incredibly useful.
| | 06:00 | More often than not, you are going to
use just the first two forms of it.
| | 06:05 | But occasionally, with that third form,
you can do some very powerful things,
| | 06:10 | especially for matrix calculations and any
thing that has more than one or tow dimensions.
| | 06:16 | So that's the slice operator.
| | 06:18 | It has the three arguments: the
start and the stop and the step.
| | 06:23 | And keep in mind that the stop is non-
inclusive, just like ranges in Python are non-inclusive.
| | 06:30 | So when you specify 43 there as the stop,
| | 06:33 | you have to realize that you are not going
to get a value from that stop compartment.
| | 06:37 | You are going to get a value from
everything up to it but not including it,
| | 06:41 | because ranges are not inclusive in Python.
| | 06:44 | And the step argument tells it how
often to step, or how many to step over.
| | 06:50 | So that's the slice operator.
| | Collapse this transcript |
| Understanding operator precedence| 00:00 | As you are writing code in Python,
there are a lot of opportunities for you to
| | 00:03 | use various expressions.
| | 00:05 | And some of these expressions might have a
number of operators and a number of factors.
| | 00:09 | For example, let's say that you have
an expression that looks something like
| | 00:13 | this: 5 * 25 + 14 / 2.
| | 00:19 | And you might look at an expression
like that, maybe you didn't code it
| | 00:22 | yourself, maybe somebody else did,
| | 00:24 | and you are looking at some code and
you see that and you say, hmm, is that 5
| | 00:29 | times the sum of 25 + 14, with the
result of that divided by 2, or is it 5 times
| | 00:36 | 25 plus the result of 14 divided
by 2, or some other combination?
| | 00:43 | The answer to this question lies in
the subject of operator precedence.
| | 00:48 | When there are a number of
different operators in one expression, which
| | 00:52 | operations get evaluated first?
| | 00:55 | And the results of that operation would then
be used in operating on the other operators.
| | 01:01 | So in this case, I happened to know,
because I looked it up, that multiplication
| | 01:07 | and division have a higher
precedence than addition and subtraction.
| | 01:12 | And so I know that the first thing
that's going to happen is 5 * 25 will be
| | 01:17 | evaluated, and then 14 / 2 will be
evaluated, and those two results will be added
| | 01:24 | together, giving us the answer of 132,
because 5 * 25 is 125, and 14 / 2 is 7.
| | 01:31 | 125 + 7 is 132.
| | 01:36 | If we want a different result,
obviously we could use parenthesis.
| | 01:40 | We could say 5 * and put in
parenthesis here 25 + 14 / 2, and we can get
| | 01:48 | that different result.
| | 01:50 | I strongly suggest when you are
writing your own code that you use the
| | 01:55 | parentheses to explicitly say
what it is that you mean to say,
| | 01:59 | that you don't write bare expressions
with a lot of different operators like
| | 02:04 | the first one here in this
example, that you just don't do that.
| | 02:08 | If you are reading other people's code
and you see that and you want to know
| | 02:11 | what it is that they meant or at least
what the result is that they got, then
| | 02:15 | you can refer to the Operator
Precedence chart, and I've provided one handy in
| | 02:19 | your exercise files.
| | 02:21 | Let's take a look at what
operator precedence looks like in Python.
| | 02:24 | There is no need for you to memorize
this, but it's good for you to become
| | 02:27 | at least familiar with its existence and know
where to find it when you need to look it up.
| | 02:32 | In this chart, you'll see there's three
columns: Associativity, Operators, and Description.
| | 02:38 | Associativity means which way is it
evaluated, if you have several of these
| | 02:43 | things from this column?
| | 02:45 | So for example, if you have
several Boolean or operators, they'll be
| | 02:49 | evaluated left to right.
| | 02:51 | If you have several Comparison
operators, they'll be evaluated right to left.
| | 02:56 | More often than not, they
are left to right in Python.
| | 02:59 | The designers of Python have done a
really good job of trying to make this stuff
| | 03:03 | consistent as they possibly can.
| | 03:04 | And where it's not consistent, it's
because it makes better sense that way.
| | 03:08 | Starting at the top of the list, we
have lambda, and then we have or, and, not.
| | 03:13 | These are the Boolean, or, and, and not.
| | 03:15 | Then we have all of the Comparison
operators lumped together in one priority, and
| | 03:20 | those are evaluated right to left.
| | 03:22 | And then continuing, there is the
Bitwise operators or, exclusive or, and and.
| | 03:29 | Then there is the Bitwise shift
operators, and then we have addition and
| | 03:33 | subtraction, multiplication, division,
and remainder, the Unary operators,
| | 03:38 | the Exponent operator,
| | 03:40 | and then bundled together and right to
left again slices, function calls, and
| | 03:45 | attribute references, and then
finally, left to right the Binding operator,
| | 03:50 | which is the parentheses when it's
not meant to be a tuple and then tuple,
| | 03:55 | lists and dictionaries.
| | 03:57 | So this is operator precedence in Python.
| | 03:59 | Again, it's much better for you to
not rely on this, to use parentheses to
| | 04:05 | say exactly what it is that you mean to
say when you are writing complex expressions.
| | 04:09 | When you are reading other people's
code that have not been that kind to you,
| | 04:13 | it's good to know that this table
exists and where to find it, so that you can
| | 04:17 | read that code and know
exactly how it gets evaluated.
| | Collapse this transcript |
|
|
9. Regular ExpressionsUsing the re module| 00:00 | Regular expressions are a very
powerful method for matching patterns in text.
| | 00:05 | Regular expressions are used for a
variety of purposes, from simple search and
| | 00:09 | replace operations to complex
text and data file manipulation.
| | 00:15 | Regular expressions are
actually a small language in itself.
| | 00:17 | Regular expressions can be very
simple or they can be very complex.
| | 00:22 | Entire books have been written on
the subject of regular expressions.
| | 00:26 | If you are moderately familiar with
how they work and what they look like,
| | 00:29 | you can get a lot of power out of them
using Python's regular expression module.
| | 00:33 | Regular expressions are
implemented in Python with the re module.
| | 00:38 | This is Python's regular expression
module and it's distributed with Python.
| | 00:42 | So if you have Python, you have the re module.
| | 00:45 | How it works looks like this.
| | 00:48 | You import re and you compile a pattern
and then you use the pattern to search
| | 00:54 | and replace or to perform whatever
manipulations you are going to perform using
| | 00:57 | the regular expressions.
| | 00:59 | So let's go ahead and look at how
we use regular expressions in Python.
| | Collapse this transcript |
| Searching with regular expressions| 00:00 | So let's take a look at how we
use regular expressions in Python.
| | 00:04 | We'll start by making a working
copy of regex.py and we'll call
| | 00:08 | this regex-working.py.
| | 00:13 | Regex is a common short name for
regular expressions, because who wants to say
| | 00:18 | all those syllables when you can just say regex?
| | 00:21 | Here we have a very simple program that
opens a file called raven.txt, which has
| | 00:27 | the complete text of Edgar
Allan Poe's poem, The Raven.
| | 00:30 | So we open that file and then we read
the file line-by-line and we do a regex
| | 00:38 | search for anything that matches
this pattern here, and this pattern here
| | 00:44 | basically matches the word Lenore or
the word Nevermore, which occur with some
| | 00:49 | regularity in this poem.
| | 00:50 | And then it prints them out and you
will notice we have end= the blank string,
| | 00:54 | because we don't want to put a new line
at the end of a line that already has a
| | 00:58 | new line at the end of it.
| | 01:00 | And so we'll go ahead and run this
and there we have the lines that have
| | 01:06 | Nevermore or Lenore in them.
| | 01:09 | So searching with regular expressions
is done using the re.search method of the
| | 01:16 | re module and here is our
regular expression pattern.
| | 01:21 | This is a very simple
regular expression pattern.
| | 01:23 | It's beyond the scope of this course to
teach you regular expressions, but in a
| | 01:28 | nutshell what this one does is it's an
alternation and so it has the regular
| | 01:34 | expression alternation
operator which you can just call OR.
| | 01:38 | So anything that has Len or Neverm
immediately followed by the letters ore.
| | 01:49 | So this will match Lenore and it will
also match Nevermore and we see in our
| | 01:54 | results down here that we have lines
that have Nevermore, quoth the raven, and
| | 02:00 | we have lines that have Lenore.
| | 02:03 | So that's how you do a search
using regular expressions in Python.
| | 02:09 | If you want to, you can just print
out the part of this that was matched.
| | 02:13 | If we take this line here and instead
of putting it in the if, we take its
| | 02:19 | result and call it match, then we get a
match object which we can use and this
| | 02:27 | is some of the beauty of how Python's
"everything is an object" helps us out.
| | 02:33 | We can test match, if we have a
match then what we can print here is
| | 02:40 | match.group(), like that.
| | 02:44 | So if I save this and run it, now we get
all of the words that we actually matched.
| | 02:50 | Now this can be really useful for
simply looking for specific patterns in a set
| | 02:56 | of text and it can also be used when we
look later on for replacing patterns in
| | 03:02 | text, when we talk about
replacing later on in this chapter.
| | 03:06 | So those are some simple examples of how
you use Python's regular expression engine.
| | Collapse this transcript |
| Replacing with regular expressions| 00:00 | Let's take a look at how we can
do search and replace using regular
| | 00:03 | expressions in Python.
| | 00:05 | Start by making a working copy of
regex.py. Call it regex-working.py.
| | 00:14 | We'll open our working copy and here we
have our little script that searches for
| | 00:19 | a particular pattern in a file.
| | 00:21 | If we run this, you see it finds all the
places where either Lenore or Nevermore
| | 00:27 | is found in Edgar Allan Poe's "The Raven."
| | 00:31 | So let's do a search and replace
instead of just a plain search.
| | 00:35 | Search and replace in Python is done
with re.sub, so we'll change this re.search
| | 00:41 | to re.sub and we'll use the same pattern there.
| | 00:46 | And we put in our replacement pattern
here. We'll just replace it with some hash
| | 00:51 | marks and we are going to turn this if
into just a print and we'll at the end of that,
| | 00:59 | we'll put the end= blank like
that and we don't need this anymore.
| | 01:05 | So now, we have re.sub and sub is
the search and replace in the regular
| | 01:12 | expression package in Python and
the first argument is the regular
| | 01:15 | expression pattern itself.
| | 01:17 | The second argument is what to replace
it with when it's found, and then the
| | 01:21 | string to replace it from.
| | 01:24 | Now in this case, this will go ahead
and print the string even if it doesn't
| | 01:28 | find any replacement.
| | 01:29 | So it will print the string either way.
| | 01:31 | So we'll get the entire file
with just those lines replaced.
| | 01:35 | So I'll save this and run it and we'll
go ahead and maximize this and we can see
| | 01:39 | these places where the hash marks are
found. These are places where it found
| | 01:44 | either Lenore or Nevermore.
| | 01:50 | So that's the simplest form of
a search and replace in Python.
| | 01:54 | Let's say though that we just want to
print the lines where we actually found it
| | 01:57 | and print those lines
with that string replaced.
| | 02:01 | So one easy way to do that is instead
of putting the print here we can do a
| | 02:05 | search here and get this results of
the search with match, hence we use this
| | 02:10 | search function, just how
we learned to do it before.
| | 02:15 | So search in line like that and then if
match, because we only want those lines
| | 02:24 | whether it's been a match, then we can
do a simple string substitution, and
| | 02:29 | print line and say end= blank like that
and we can use the replace method in the
| | 02:41 | line object itself.
| | 02:44 | And we have our result in match and it's
in the group method and what we replace
| | 02:50 | it with is the hash marks.
| | 02:52 | So this is actually doing the
search and replace in two separate steps.
| | 02:57 | The search is being done using the regular
expressions and the result is in the match object.
| | 03:02 | We can test the match object to see if
it's true, then it will have a match and
| | 03:07 | then we can use that match in the
string replace method to do the replacement.
| | 03:14 | So if we save this and run it, so now
we get only those lines where the string
| | 03:19 | was found and we have the
replacement in those lines.
| | 03:23 | So those are a couple of simple ways to
use Python's regular expressions module
| | 03:26 | to do search and replace.
| | Collapse this transcript |
| Reusing regular expressions with re.compile| 00:00 | Python's regular expression module has
a way that you can pre-compile a regular
| | 00:04 | expression when you're going to
be using it over and over again.
| | 00:07 | This is an efficiency and it also
allows you access to some of its more
| | 00:11 | advanced functionalities.
| | 00:13 | So let's go ahead and make a working
copy of regex.py, call it regex-working.py.
| | 00:21 | I will open that working copy up and
you'll see here that we have a tight little
| | 00:25 | loop that's using the same pattern
over and over again and it's using it to
| | 00:31 | search for this pattern,
in line after line of text.
| | 00:35 | So we can get some more efficiency
out of this loop by pre-compiling the
| | 00:39 | regular expression.
| | 00:40 | So up here we open the file.
| | 00:42 | We can say pattern = re.compile and
then we will come down here and we will
| | 00:51 | cut and paste our pattern and then when
we do the search down here, you can say
| | 00:58 | pattern like that.
| | 01:00 | And regular expression module will
recognize that that's a pattern object.
| | 01:05 | That's a precompiled regular expression object.
| | 01:09 | And we will use that, so
when we save this and run it.
| | 01:11 | You see we get the same result, but
it's more efficient because we are simply
| | 01:16 | compiling that regular expression
once rather than otherwise the regular
| | 01:21 | expression module needs to compile the
regular expression each time it uses it
| | 01:25 | and this is in a tight little loop
and we want that loop to be fast.
| | 01:29 | This also gives us the ability to use
some of the regular expression module's
| | 01:33 | other features like for example, you'll
notice in the raven text, the very last
| | 01:40 | use of the word nevermore, it's
not capitalized at the beginning.
| | 01:44 | And so we don't have this line,
"Shall be lifted - nevermore!"
| | 01:48 | at the end of our results.
| | 01:50 | So we can tell the regular expression model to
ignore case, just by putting in re.IGNORECASE.
| | 01:59 | And in fact you can use just an I,
like that. I like to use the whole thing
| | 02:04 | because it's more explicit and when I
come back to look at it years from now,
| | 02:08 | after maybe I have not used Python for
some reason for a while or not used this
| | 02:14 | particular feature,
I will remember what it means.
| | 02:17 | So it's something you just need to type
out once and so it's worth the extra effort.
| | 02:22 | So if I save this and run it, now we
get that last line as well, because we are
| | 02:26 | telling the regular
expression module to ignore case.
| | 02:30 | So a number of efficiencies are
available if we are using pre-complied
| | 02:34 | regular expressions.
| | 02:35 | For example, if I want to do a
substitution down here, I can say pattern.sub
| | 02:46 | comma line, like that and now
I have the efficiency of having a
| | 02:51 | pre-compiled pattern.
| | 02:52 | I can go ahead and use the regular
expression module to do the substitution and
| | 02:56 | I don't necessarily have to get the
result out separately and then use the
| | 03:01 | string module substitution.
| | 03:03 | So this allows me to use the
regular expression engine for more things
| | 03:08 | without the inefficiencies of having to
compile the pattern over and over and over again.
| | 03:12 | So if I save this and run it, now we
have that same result and it's easier to
| | 03:17 | read and it flows in with our whole
pattern if you're using the regular
| | 03:22 | expression module and we even have that
last line with the lowercase nevermore.
| | 03:28 | It's still working because the
pattern was compiled with the IGNORECASE.
| | 03:32 | So that's just some of the efficiencies
that you can get from using pre-compiled
| | 03:36 | regular expressions in Python.
| | 03:38 | It's not hard to do.
| | 03:39 | I recommend that you do it that way if
you're going to be using your regular
| | 03:43 | expressions in a loop or for any
purpose that's more than just once or twice.
| | Collapse this transcript |
|
|
10. ExceptionsLearning how exceptions work| 00:00 | Exceptions are Python's key
method for handling errors.
| | 00:05 | Whenever you see one of Python's little
error messages, like you've written some
| | 00:09 | script and you run it for the first
time and it dumps you out with stack trace
| | 00:14 | and an error message, those error
messages are simply uncaught exceptions.
| | 00:20 | You can catch exceptions in
Python using try and except.
| | 00:24 | For example, if you're opening a file
and the file name is wrong or you don't
| | 00:29 | have permissions to open the file or
something like that, Python will raise
| | 00:33 | an IO Error exception.
| | 00:35 | You can catch the exception
like this, using try and except.
| | 00:39 | Then you can even capture Python's
error message, print it, and either continue
| | 00:43 | with your execution or give a user some
intelligible error message or whatever
| | 00:48 | exactly it is that you
want to do with the error.
| | 00:51 | And then you can use else for
conditions where you don't get the error at all,
| | 00:55 | and it just works the way that you expect it to.
| | 00:57 | Of course, you can also raise your
own exceptions with the raise statement.
| | 01:00 | You have access to this entire
exception handling process. It's built into
| | 01:06 | Python for your own error conditions
in the modules, objects, and functions
| | 01:11 | that you write yourself.
| | 01:12 | So let's go ahead and take a look
at how Python uses exceptions for its error reporting.
| | Collapse this transcript |
| Handling exceptions| 00:00 | Exceptions are a primary
method of handling errors in Python.
| | 00:05 | So let's take a look at
how we handle exceptions.
| | 00:07 | We will make a working copy of
exceptions.py, call it exceptions-working.py.
| | 00:15 | We will open our working copy and
here we have a very simple little script
| | 00:19 | that reads lines of text from a file
and there is the text file there and it
| | 00:24 | prints them on the screen.
| | 00:25 | Go ahead and we will run this
and there is our lines of text.
| | 00:29 | You'll notice, we did this
in different way this time.
| | 00:31 | Instead of using end = a blank string,
ctually using the strip method in
| | 00:36 | the string itself and that just strips any
trailing new lines from the end of the string.
| | 00:41 | It's another way to do it, using the
string method rather than using the print
| | 00:45 | function to resolve that discrepancy.
| | 00:47 | Now if I had typed the name wrong or
if I am referring to a file that doesn't
| | 00:52 | exist and I save this and I run it,
| | 00:55 | you'll notice that we get one of
Python's lovely little error messages and it
| | 00:59 | has the Traceback (most recent call last).
| | 01:02 | It's doing what it can to help you to
find the error in your code and then down
| | 01:06 | at the bottom here, it says
IOError and it has a message.
| | 01:10 | This IOError before the colon is
actually the name of the exception.
| | 01:15 | That's the exception that's being
raised by the Python interpreter and then
| | 01:19 | after the colon is its error message.
| | 01:22 | Now I can trap that exception.
| | 01:24 | And then I could do something
different with it in my code.
| | 01:27 | So here is how I do that.
| | 01:29 | I use try and I am just going to put
that line there in the try and then I use
| | 01:36 | except like this, and I can print a message.
| | 01:39 | I can say, "could not open the file."
| | 01:47 | And then I don't want this to run,
so I can put that in the else.
| | 01:52 | Put the else there and so now
what I have, I save this and run it.
| | 01:58 | I will just get this little message,
"could not open the file, come back tomorrow"
| | 02:02 | and it doesn't try to read the lines in it.
| | 02:05 | And if the typo is not there, I save that
and run it, now I get the actual lines of text.
| | 02:13 | Now this will actually catch any error at
all, because I just said except like that.
| | 02:18 | If I want to just kept that particular
error, I say except IOError, and if I
| | 02:24 | save that, well let's go
ahead and just type this again.
| | 02:28 | Save that, run it, then I get that error.
| | 02:31 | So it's sometimes useful to go ahead and
let Python give you that error message,
| | 02:36 | because that's the easy way to find
out which error is going to raise.
| | 02:39 | I can also get the error
message itself. I can say as e:
| | 02:44 | like this and then instead of come
back tomorrow, I can give it that error
| | 02:49 | message like this and then save and
run and it says, "Could not open the file:
| | 02:54 | Error 2 No such file or directory:".
| | 02:56 | And there we have something
it's actually useful for the user.
| | 03:00 | Now we can actually if we want to,
we can put all of this code up here in
| | 03:04 | the try and it doesn't hurt anything
to do it that way and then we don't
| | 03:08 | need an else clause.
| | 03:09 | Save that and run it.
| | 03:11 | We are still getting our error message.
| | 03:12 | Let's go ahead and cut that out and
we see that it works the same way.
| | 03:16 | So in the event that you have more
than one line of code in your try clause,
| | 03:23 | execution will stop after the error is raised.
| | 03:27 | So the error gets raised here and then
it will go right to handling the error
| | 03:32 | in the except clause.
| | 03:33 | So this line won't get run
when the exception happens.
| | 03:37 | So if we have this misspelling in here,
you save it and run it, we get the error
| | 03:41 | message and it doesn't try to use the
file handle that it never got, because as
| | 03:46 | soon as that exception is raised, which
happens in this open function, then the
| | 03:51 | exception clause is run right away.
| | 03:53 | So you'll see this pattern commonly
where a number of lines of code will be put
| | 03:57 | in a try block and then in fact
sometimes there will be several different except
| | 04:02 | clauses as well, listing out a number
of different errors that could be raised.
| | 04:07 | So this is how exceptions work in
Python and this is how you handle exceptions
| | 04:12 | in your code using try and except.
| | Collapse this transcript |
| Raising exceptions| 00:00 | Python uses exceptions as its
primary method of handling errors.
| | 00:04 | We can raise our own exceptions in
the functions and modules that we write.
| | 00:08 | Let's take a look at how we do that.
| | 00:10 | Make a working copy of exceptions.py,
call it exceptions-working.py, and we'll go
| | 00:17 | ahead and open our working copy, and
here we have our simple print the lines of
| | 00:21 | text from this file.
Go ahead and run that.
| | 00:24 | Now, let's say that we want it to
write a function that will open a file and
| | 00:29 | return its lines of text.
| | 00:31 | It's pretty easy little function, call
it readfile, and we'll pass it a filename
| | 00:39 | and open(filename), like that, and
we'll return the readlines method from the
| | 00:52 | filehandle and that's actually an
Iterator and it allow us to do this. We can
| | 00:59 | now get rid off that and here we can say
readfile lines.text. Save that and run it
| | 01:11 | and there it works exactly like we expect.
| | 01:14 | Now, let's say that we misspell
lines.text here. We'll get our same error
| | 01:21 | message that we got before, IOError,
and of course we can handle that in a try block like this.
| | 01:40 | And there we have our error
handling, our exception catching,
| | 01:46 | and there we get our error message like
that, but let's say that we have another
| | 01:49 | condition that we want to raise
a different kind of an error for.
| | 01:53 | We could check the filename for example,
using the endswith method of the string
| | 02:00 | object to see if it ends with .TXT.
And in that case, we'll just go ahead and do
| | 02:07 | what we normally do, an else.
We're going to raise an exception.
| | 02:11 | We're going to use the raise statement, we're
going to raise a ValueError and we're going to
| | 02:16 | give it a little message, "Filename must
end with .TXT," all right and then give
| | 02:25 | it a different kind of a name here.
| | 02:27 | We save this and run it.
| | 02:30 | Now, we have an unhandled exception.
| | 02:32 | We get exactly the same kind of error
reporting that Python does when it raises
| | 02:37 | its own exceptions and we see
it gives us the trace back.
| | 02:41 | It's just an unhandled exception.
| | 02:43 | That's what Python does
with an unhandled exception.
| | 02:46 | And so, we can handle that exception
with a separate except, except ValueError
| | 02:52 | as e and we can print bad
filename and the message.
| | 03:00 | So now when we save it and run it,
we get this nice little error message here.
| | 03:05 | So that's how we raise an exception in Python.
| | 03:07 | You'll notice it's very simple. We use the
raise keyword and we give it the exception.
| | 03:13 | Python has predefined a number of
exceptions in its library, pretty much
| | 03:19 | anything you are going to need, and on
your screen is the URL where you can find
| | 03:24 | that list with a lot of descriptions of them.
| | 03:26 | In this way you don't need to define
your own and your programs will work more
| | 03:30 | consistently with the rest of the
Python universe, by using the exception names
| | 03:35 | that are already defined.
| | Collapse this transcript |
|
|
11. FunctionsDefining functions| 00:00 | Functions in Python are the primary
unit of reusable code, even in objects.
| | 00:07 | Object methods are simply functions
that are properties of the objects.
| | 00:12 | So let's look at how we define a function.
| | 00:15 | We'll make a working copy of functions
.py, call it functions-working.py and
| | 00:23 | we'll go ahead and open that up and
here we have a very simple function.
| | 00:28 | It's called testfunc and it
has one line of code in it.
| | 00:34 | So if we run this, we see that
that function gets run because it's
| | 00:39 | getting called from main.
| | 00:41 | Now, a few things to notice in this file.
| | 00:44 | First of all, main is getting called down here.
| | 00:48 | So main is a function just like any
other function and it's simply getting
| | 00:53 | called from the end of the file.
| | 00:55 | The reason it's getting called from
the end of the file is so that it can use
| | 00:58 | things that are defined after it,
like for instance, testfunc.
| | 01:02 | If instead of calling main from the end
of the file, if there is simply a call
| | 01:11 | to testfunc from the top.
| | 01:13 | that would not work.
| | 01:14 | We'll save that and run it and you see
we get NameError because name testfunc is
| | 01:18 | not defined at the point where it was called.
| | 01:23 | So in order for that to be defined
first, we put it in a function and we call
| | 01:29 | that function from the end. And so
that's one of the reasons that we have this
| | 01:33 | pattern at the end of the file that calls
main and then main is defined at the top.
| | 01:42 | It's also worth noting that we have to have
some content in the suite after the colon.
| | 01:49 | So if this were like this, def testfunc():
| | 01:53 | like that and save it and run it,
we're going to get an error, IndentationError.
| | 01:59 | So it thinks that I have intended to
put this inside the function, which would
| | 02:03 | not work, because there
is no body of the function.
| | 02:06 | So there has to be something there.
| | 02:09 | So if you're looking for a way to
simply have a stub, if you're outlining some code
| | 02:14 | and you just want to have a
function definition without any body, there is
| | 02:18 | the pass statement, which is essentially a NOOP.
| | 02:23 | Save this and run it and now it works
just fine, there's nothing happens, but
| | 02:27 | pass is legal content that
doesn't actually do anything.
| | 02:32 | So you'll see that sometimes when
people are working with things or explaining
| | 02:36 | things or creating a code in Python.
It's a placeholder. It's a stub.
| | 02:42 | It's just there to make it syntactically
correct but it doesn't actually do anything.
| | 02:51 | If I want to pass an argument to my
function, I can do that by putting an
| | 02:57 | argument name here, call it number,
and then I can print that out over here.
| | 03:06 | So if I save this and run it, you
see we have This is a test function 42.
| | 03:10 | So the number is getting passed in
during the function call and the number is
| | 03:16 | getting picked up in this variable,
which is defined in the function definition,
| | 03:21 | and then I can use that in
the body of the function itself.
| | 03:25 | I could have another number and I
could even have one more and I could pass
| | 03:31 | those and I could use them down here.
| | 03:41 | I save this and run it.
| | 03:43 | Then we get all of those numbers.
| | 03:45 | Because these are defined, they must be passed.
| | 03:49 | If I don't pass all of them and I try
to run that, you see I get a TypeError,
| | 03:58 | testfunc() takes exactly 3
positional arguments (1 given).
| | 04:02 | You might want to have some optional
arguments and you can accomplish this by
| | 04:07 | giving them default values.
| | 04:12 | You give them default values by
assigning values in the function definition.
| | 04:17 | So now these arguments are optional and
yet they'll still work inside the function.
| | 04:23 | So if I save that and I run it, you see
I've got the 43 and the 75 from in here
| | 04:28 | and the 42 from there, but if I put a
different number up here for the second one
| | 04:33 | and I save that and I
run it, then we get that value.
| | 04:38 | Then the default value is not used
and instead the value passed is used.
| | 04:44 | The reason for this is that all the
function arguments must have values
| | 04:48 | assigned, so that when that function is
called, what happens is predictable, not
| | 04:53 | just to you the programmer
but also to the compiler.
| | 04:57 | And so they all must be
initialized in one way or another.
| | 05:00 | If you don't want it to have a default
value but you still want the parameter to
| | 05:04 | be optional, then you'll
assign it explicitly the value None.
| | 05:08 | And now when I save this and I run it,
I'll have the value 16 there because I
| | 05:13 | passed it, but now I cannot have that
there and I can save it and I run it and
| | 05:19 | I get the value None.
| | 05:22 | None is a special value
that you can actually test for.
| | 05:26 | I can say, if another None, it's a
singleton object and so identity is a good way
| | 05:35 | to test for it. print. Or I can assign
something to it. I can say another = 112
| | 05:42 | and now when I save and I run, I get
112 here because I tested for None and
| | 05:49 | that test was successful. But if I put
something in here, 61, let's save that
| | 05:56 | and run it, then we have the 61.
| | 05:58 | So function arguments must be
initialized in one way or another.
| | 06:03 | Either they are going to be required or,
if you want them to be optional, you
| | 06:07 | have to assign them default values.
| | 06:09 | The default value can be none and
you can test for none, but it must be
| | 06:14 | explicitly assigned.
| | 06:16 | So that's fundamentally how you
define a function and how you pass the
| | 06:21 | arguments in Python.
| | Collapse this transcript |
| Using lists of arguments| 00:00 | Sometimes when you're defining a function,
you might need an arbitrary number of arguments.
| | 00:06 | Arguments that aren't necessarily
going to be used every time and aren't
| | 00:10 | necessarily going to even be
named, perhaps a list of things.
| | 00:15 | Python has a facility for this
and let's see how that works.
| | 00:19 | We'll go ahead and make a
working copy of functions.py, call it
| | 00:22 | functions-working.py and we'll open
that working copy up and here we have our
| | 00:30 | little test function.
| | 00:32 | And let's say that we just want to give
it an arbitrary list of arguments and so
| | 00:38 | that's done simply like that.
| | 00:41 | The asterisk is special in this place
as it means that this is just a list
| | 00:47 | of optional arguments.
| | 00:49 | You can have before it-- you can have
a named argument or several of them.
| | 00:53 | you could have this, that and the other,
and then after all of that you can have
| | 01:01 | your optional arguments, and so when you
call it you might need to give it some
| | 01:06 | actual values there and then you could
have your arbitrary number of optional
| | 01:13 | arguments like that.
| | 01:15 | So if we want to list those, we can
just get rid of this text here and say
| | 01:21 | this, that, and other, and if we save
that and run it, you'll notice that we get
| | 01:28 | the 1, 2 and the 3.
| | 01:30 | What about these other ones?
| | 01:32 | If I say args, what I'll get is
I'll get a tuple with those values.
| | 01:37 | Save that and run it and there is our tuple.
| | 01:40 | So you can see that it's just a normal
tuple, as in Python, and so I can use it
| | 01:47 | as an Iterator if I want to. I can say
for n in args like that, print n, end,
| | 01:57 | equals blank or let's give it a space
like that. And I can save it and run it
| | 02:05 | and now we have our arbitrary
arguments after our named arguments.
| | 02:11 | So, it's good to keep in
mind that this is a tuple.
| | 02:14 | That means that it is immutable, can't
add to it or change anything in it, but
| | 02:20 | it is an excellent way to get an
arbitrary list of arguments into a function.
| | Collapse this transcript |
| Using named function arguments| 00:00 | Sometimes it's convenient to be able to
pass named parameters into a function,
| | 00:06 | and there is facility for that in Python.
| | 00:08 | Go head and make a working copy of
functions.py and we'll call it functions-working.py
| | 00:18 | and open that working copy and
here we have our little test function.
| | 00:22 | Sometimes you might want to pass
parameters to it and have them look like this.
| | 00:28 | one=1, two=2, four=42, and
so here you are actually passing named
| | 00:37 | arguments and the caller is
naming them rather than the receiver.
| | 00:42 | So these arguments are not
named on the receiving end.
| | 00:45 | So these are specified with the two
asterisks and very commonly called kwargs
| | 00:53 | for keyword args, keyword
arguments, and these are accessed like this.
| | 00:59 | kwargs is actually a dictionary and so
I can say kwargs sub 'one', like that, and
| | 01:09 | kwargs sub 'two', kwargs sub 'four' and when
I save these and run it, you see that we are
| | 01:22 | getting those values here, 1, 2, and 42.
| | 01:26 | These keyword arguments can be combined
with normal positional arguments, so you
| | 01:32 | can pass it 5, 6, 7, 8, 9, and
10 and these can be named arguments.
| | 01:43 | this, that and other and they
can even be tuple arguments.
| | 01:50 | And so what this will do is this will
pass the named arguments, these first
| | 01:55 | three will be this, that, and other,
and then these here will be in this tuple
| | 02:01 | and then you have your named arguments.
| | 02:03 | The only restriction is that they
must actually be specified in this order.
| | 02:08 | Your named arguments first, your
arbitrary tuple arguments after that, and your
| | 02:13 | keyword argument after that.
| | 02:15 | Other than that, there is no
restriction on the number or even the type of
| | 02:20 | all these arguments.
| | 02:22 | So go ahead and take a look at all of those.
| | 02:28 | We have this, that, and other and we
will go ahead and look at the tuple all at
| | 02:34 | once like that and we will save this and run it.
| | 02:39 | You see we have them orders 5, 6, 7,
there is our tuple, and there is
| | 02:44 | our keyword arguments.
| | 02:46 | Now, the keywords arguments, of
course, are optional and the names of the
| | 02:51 | keywords are not necessarily known by
the receiver, just like with the tuple.
| | 02:57 | Let's go head and get rid of all
of this and we will look at the
| | 03:03 | keyword arguments first. For k in kwargs:
| | 03:10 | print k and kwargsk sub k.
| | 03:15 | So this will print one per line
each of the keyword arguments.
| | 03:18 | I save this and run it.
| | 03:20 | 4, 2, 1 just like with any dictionary.
| | 03:25 | So if I change these up here, 3 and
I have 17 and in fact you see we still have them.
| | 03:37 | Of course, because it is a dictionary,
it's going to come out in no particular order.
| | 03:41 | But more often than not, you
are going to use these keyword arguments
| | 03:45 | for settings and flags and things like
that and you'll test for them in your
| | 03:49 | function, and you are not going to
really be counting on the order in which
| | 03:52 | they are presented.
| | 03:53 | On the other hand, the tuple arguments
will be presented in the order that they
| | 03:58 | are passed because they
are being passed as a tuple.
| | 04:02 | So if I say, for n in args:
| | 04:06 | print(n), and we'll save that and run it,
then we get those actually in the order
| | 04:14 | that they were passed.
| | 04:16 | So that's how you can pass
named arguments to a function.
| | 04:19 | This is very commonly used for settings
and flags and things like that and also,
| | 04:25 | this is how you can combine them with
the arbitrary tuple arguments and with
| | 04:29 | your normal positional arguments.
| | Collapse this transcript |
| Returning values from functions| 00:00 | Functions can be used for a number of
purposes and some times those purposes
| | 00:04 | require the values be
returned from the function.
| | 00:07 | Let's take a look at how we
return values from functions in Python.
| | 00:11 | We start by making a
working copy of functions.py.
| | 00:14 | We will name it functions-working.py
and we'll open that up and there we have
| | 00:21 | our little test function.
| | 00:23 | How about instead of printing this if we
simply return it and then print it from
| | 00:30 | up here and say print(testfunc())?
| | 00:33 | So we'll save this and run
it and there is our string.
| | 00:40 | So all this function is doing
is it's returning this string.
| | 00:44 | The return keyword is the way
that the values are written.
| | 00:49 | The value itself comes after Return
and it can be any type. We can return a number.
| | 00:58 | Save that and run it and there is our number.
| | 01:01 | We can return an object, say
range(25), and that will return a range object.
| | 01:10 | We'll save this and run it.
And there is the range object.
| | 01:13 | In fact, that range object
is now usable as an iterator.
| | 01:18 | So if I say
for n in testfunc(): print(n, end=' ').
| | 01:30 | Save that and run it.
| | 01:32 | We've got that whole range.
| | 01:34 | And you'll notice that just like a range
is supposed to, it's non-inclusive and
| | 01:38 | it does not include that last 25th object.
| | 01:44 | So you can really return any object
from a function using the return statement
| | 01:50 | and that's done simply with
return and then the object.
| | Collapse this transcript |
| Creating a sequence with a generator function| 00:00 | A generator function is a
function that returns an iterator object.
| | 00:05 | So this is how you create
functionality that can be used in a for loop or any
| | 00:11 | place an iterator is allowable in Python.
| | 00:14 | So let's go ahead and create a generator object.
| | 00:16 | We will make a working copy of
generator.py, and we'll go ahead and open that up.
| | 00:27 | And here we have an example
of using the range object.
| | 00:31 | And if we run this, you'll notice that
we get our range of numbers up to and
| | 00:35 | not including the 25, because the
range object is naturally noninclusive.
| | 00:43 | So a lot of times you might
want an inclusive range object.
| | 00:47 | So let's go ahead and create one.
| | 00:49 | We'll call this inclusive_range,
and we'll define a function.
| | 00:56 | Call it inclusive_range.
| | 01:00 | And the range object takes three arguments:
| | 01:03 | start, stop, and step.
| | 01:08 | And we'll go ahead and say i=start,
while i<=stop, and that will make
| | 01:18 | it inclusive. i+=step.
| | 01:23 | And then just before we increment,
we're going to return, although we're not
| | 01:31 | going to use return. We're going to yield i.
| | 01:36 | What that does is it returns I, but
because we're using yield instead of
| | 01:41 | return, the next time the function is
called execution will continue right
| | 01:46 | after the yield statement.
| | 01:48 | So the next thing that will happen is
i will get incremented by step and then
| | 01:54 | the loop will be tested again.
| | 01:56 | And then assuming that the loop
condition is still true, yield will be called
| | 02:01 | again and it will yield
another iteration in the sequence.
| | 02:06 | So again, what makes the yield
different than return is that as the function
| | 02:11 | gets called over and over again, each
time execution begins right after the
| | 02:16 | yield and continues as if the
function were running continually.
| | 02:21 | And yield returns each time
the next item in the sequence.
| | 02:26 | So let's go ahead and run this.
| | 02:29 | In order to run it, we are going to
need to give it a start and a step.
| | 02:32 | So we'll start at 0, and we'll step by 1,
and we should get the same sequence,
| | 02:40 | but including a 25 at the end.
| | 02:42 | Save it and run it, and there we are, got the
same sequence, and there is our 25 at the end.
| | 02:49 | So that is how yield works and
that is how you create a generator.
| | 02:55 | Let's go ahead and exercise all the
techniques we've been learning in this
| | 02:59 | function chapter and make this
function work exactly like range does.
| | 03:05 | Range can be called with one,
two, or three arguments.
| | 03:09 | If it's called with just one argument,
stop is the value that's used and start
| | 03:14 | is given a default value of 0 and
step is given a default value of 1.
| | 03:19 | But Python doesn't really have a way to do that.
| | 03:22 | If I give this one here a default value
of 0, I say start=0, and I give step a
| | 03:28 | default value of 1, and I call
this with just the 25 by itself.
| | 03:35 | Save that and run it.
| | 03:37 | We get this SyntaxError.
| | 03:38 | Non-default argument follows default argument.
| | 03:43 | So this is not allowable in Python.
| | 03:46 | The only way we can
really do this is with a tuple.
| | 03:50 | So let's go ahead and process our arguments.
| | 03:53 | Let's start by taking a number of
arguments, because we are going to different
| | 03:57 | things with different numbers of arguments.
| | 03:58 | numargs = the length of tuple, and if numargs<1,
we're going to raise an error.
| | 04:17 | Requires at least one argument.
| | 04:21 | And then elif numargs == 1, and we'll
just set these up, elif numargs == 2,
| | 04:34 | elif numargs == 3, or else, and we'll raise
another error. TypeError, inclusive_range
| | 04:52 | expected at most 3 arguments,
got some number, format (numargs)).
| | 05:06 | Now I've got this little x here because
it's expecting something to be in that suite.
| | 05:12 | So if there's just one argument, then
start is going to be 0 and step is going
| | 05:18 | to be 1, and we'll go up to the top of
the list, and we'll use our argument.
| | 05:23 | We'll say stop=args0. All right.
| | 05:30 | And if we have two arguments, then our
arguments are start and stop, and we can
| | 05:35 | assign those like this and
give step the default value.
| | 05:41 | If we have three arguments, and
we can assign them all like this.
| | 05:45 | start, stop, and step=args. All right.
| | 05:51 | Now, this should work.
| | 05:53 | Let's save it and see how we are calling
it up here? With just the 25 by itself.
| | 06:00 | So we'll run it, and there we have
all 25 numbers, just like we expected.
| | 06:05 | It works just like range, except it's
inclusive and it gives us that last number.
| | 06:10 | If we have a 5 at the beginning of it,
it should give us 5 through 25, there we go.
| | 06:17 | And if we step by three,
let's say, save that and run it.
| | 06:23 | That's exactly what we expect.
| | 06:26 | Let's say we have too many arguments.
Let's give it some other number.
| | 06:30 | Now we're going to expect to get this one here.
| | 06:35 | It's not less than 1. It's not 1.
| | 06:37 | It's not 2. It's not 3.
| | 06:38 | It's this something else.
| | 06:40 | So save that and run it.
| | 06:42 | And we get inclusive_range
expected at most 3 arguments, and got 4.
| | 06:48 | And let's trigger this error here and give
it no arguments at all. Save that and run it.
| | 06:56 | And requires at least one
argument is our error message.
| | 07:01 | So there we have it. We've duplicated
the functionality of the range object.
| | 07:04 | We've got a function that returns an
iterator object and it does exactly what
| | 07:09 | range does, except that it's inclusive.
| | 07:12 | And we've accomplished this using
the yield statement, which turns our
| | 07:19 | function into a generator, and the way
the yield works is each time yield is run,
| | 07:25 | it returns the value.
| | 07:27 | And the next time the function is called,
execution picks up from right after the yield.
| | 07:33 | And this turns the function into a
generator and what it generates is an
| | 07:38 | iterator object, which can be used
exactly like any iterator object in Python.
| | Collapse this transcript |
|
|
12. ClassesUnderstanding classes and objects| 00:00 | Classes in Python are how you make objects.
| | 00:04 | The classes themselves are the
blueprint for how an object is created.
| | 00:10 | For example, here is a class called Duck.
| | 00:12 | And it implements a couple of methods
called quack and walk, so that when you
| | 00:17 | create a duck object, that duck will
quack like a duck and walk like a duck and
| | 00:22 | that of course will make it a duck.
| | 00:24 | An object is an instance of a class.
| | 00:27 | That means that when you create
an object, it's a separate thing.
| | 00:31 | It's separately encapsulated.
| | 00:33 | It has all of its own attributes.
| | 00:35 | So if you make several different
objects from a given class, each of those
| | 00:40 | different instance of the class, but
they're all separately encapsulated and
| | 00:44 | have their own data space, their own code
space and are essentially their own objects.
| | 00:49 | An object is an instance of a class.
| | 00:51 | That means when you create an object,
that object is built from the blueprint of
| | 00:56 | the class, but it's its own object.
| | 00:58 | Its own encapsulation.
| | 01:00 | And so if you create several
different objects from the same class,
| | 01:03 | they're separately encapsulated.
| | 01:04 | They have their own data space and
they have their own attributes, and they
| | 01:08 | operate independently of one another.
| | 01:10 | So in this case, we've created an
object called donald from the Duck class.
| | 01:14 | And we can say donald.quack and donald.walk.
| | 01:17 | And donald will quack like a duck and will
walk like a duck and therefore is a duck.
| | 01:23 | Let's take a look at how this works in practice.
| | 01:25 | So we'll start by making a working
copy of classes.py, and we'll call
| | 01:29 | it classes-working.py.
| | 01:34 | Go ahead and open that working copy.
| | 01:37 | And we see we have our
Duck class and we have donald.
| | 01:41 | So if we go ahead and run this, you'll
see that donald quacks like a duck and
| | 01:46 | donald walks like a duck.
| | 01:48 | So let's take a look at how this works.
| | 01:51 | Class is the keyword that
introduces the definition of a class.
| | 01:55 | Duck here is the name of the class and
then there is a colon, and so because
| | 01:59 | there is a colon, you have things
that are indented under this level.
| | 02:03 | And those are the suite of the class definition.
| | 02:07 | And in this case we have
two things inside the class.
| | 02:10 | We have a function called quack and
that function, because it has self as its
| | 02:17 | first argument, is
actually a method of the class.
| | 02:22 | And we'll talk in a moment about how this works.
| | 02:24 | Then we have walk, which is defined in
the same way, and so that's another method.
| | 02:29 | And then down here, when we create
the object donald, we create the object
| | 02:34 | donald by assigning it from Duck.
| | 02:37 | And Duck is the class definition.
| | 02:40 | And so now donald is an object.
| | 02:43 | And donald is an object of the class Duck.
| | 02:47 | So if I were to just go here and I
were to say print(donald), like that, save
| | 02:53 | that and run it, then it
says <__main__.Duck object at.
| | 02:58 | And so donald is an object of the class Duck.
| | 03:04 | So when I call the quack method, I use
this dot operator and that dot operator
| | 03:09 | is the attribute dereference operator.
| | 03:11 | That means that it's going to
look inside the object donald for an
| | 03:15 | attribute called quack.
| | 03:16 | And because it has these parentheses on it,
it's going to go ahead and call it
| | 03:20 | as an object method.
| | 03:23 | And so that will call this code, and it
prints this quack, and donald.walk calls
| | 03:28 | this code, and it prints
that "Walks like a duck."
| | 03:32 | So Duck is the class and that's all
this stuff here, and donald is the object.
| | 03:39 | He's an instance of Duck.
| | 03:42 | And you can call the methods inside donald.
| | 03:46 | And so you can call the methods
inside the donald object of class Duck
| | 03:50 | using this dot notation.
| | 03:52 | So that's how you define a class and
create objects based on it in Python.
| | 03:57 | Python is fundamentally an
object-oriented language.
| | 04:00 | And that means you're going to do this a lot.
| | 04:02 | There are times when you just have a
single thing that you want to do and you
| | 04:05 | want to do it in a very simple way.
| | 04:09 | And for that, you'll just create a
function and you'll use a function.
| | 04:13 | Often you're going to want to do
things that are more complicated and these
| | 04:16 | more complicated things are going to
have their own local data and they're
| | 04:19 | going to have multiple methods that
are tightly related to each other and
| | 04:25 | interact with each other.
| | 04:26 | And these are the times when we're going to
go ahead and create a class and use objects.
| | 04:31 | As you go through the process of
writing programs in Python, especially if
| | 04:35 | you've not worked with an object-
oriented language before, you're going to see
| | 04:39 | more and more cases where objects make sense.
| | 04:44 | If you're used to using functions a lot,
you'll be creating a lot of functions
| | 04:47 | for things, but over time as you get
more familiar with the power and the
| | 04:50 | flexibility and the encapsulation and
inheritance of the different properties of
| | 04:54 | objects that we're going to go
through in this chapter, you're going to use
| | 04:57 | objects more and more.
| | 04:58 | And you'll end up using objects for a
lot of the things that you used to use
| | 05:02 | multiple functions for.
| | 05:03 | So objects are very powerful.
| | 05:05 | Python is a fundamentally object-
oriented language, so you're going to use these
| | 05:09 | techniques often as you write code in Python.
| | Collapse this transcript |
| Using methods| 00:00 | When you're creating objects and
classes in Python, you're going to want to get
| | 00:04 | them some functionality.
| | 00:06 | That functionality is
usually created with methods.
| | 00:09 | So let's go ahead and make a
working copy of classes.py.
| | 00:13 | We'll call this classes-working.py.
| | 00:18 | We'll open up that working copy.
| | 00:20 | You can see that we have a class
called Duck and it already has couple of
| | 00:24 | methods in it, quack and walk.
| | 00:26 | Those get called down here.
| | 00:28 | So donald gets created as class Duck.
| | 00:30 | So this is an object with
that class and the object donald.
| | 00:34 | We're calling the quack method on the
object donald and we're calling the walk
| | 00:38 | method on the object donald.
| | 00:40 | The calls are done using this dot
operator, which is used to reference an
| | 00:46 | attribute of the object.
| | 00:49 | In this case, the attribute is a method.
| | 00:51 | So it's called with the parenthesis and
that calls it as you would call a function.
| | 00:57 | These are actually functions.
| | 00:58 | It's just that these are functions
that are attributes of an object.
| | 01:02 | That's what makes the methods.
| | 01:04 | So we'll go ahead and we'll run this,
and you'll see that the object gets
| | 01:08 | created and the methods get called.
| | 01:10 | It prints out Quaaack!
| | 01:11 | and it prints out Walks like a duck.
| | 01:13 | Everything is working like we expected it to.
| | 01:15 | So methods are actually functions.
| | 01:18 | You'll see that they're defined just
like you define functions in Python.
| | 01:21 | The difference is these are
indented under the class Duck.
| | 01:26 | So that makes them methods of the class Duck.
| | 01:29 | You'll also notice that the first
argument to these functions is this word self.
| | 01:34 | That is a reference to the object.
Not the class, but the object.
| | 01:39 | In other words, when quack gets called
on the donald object, then the donald
| | 01:44 | object gets passed to the quack method.
| | 01:48 | So the quack has a way of
referring to object attributes.
| | 01:51 | You'll also notice that nothing is
getting passed inside of these parentheses.
| | 01:56 | It's as if donald was passed
inside those parentheses, but you don't
| | 02:01 | actually put that there.
| | 02:02 | That happens automatically
by virtue of the dot operator.
| | 02:06 | When quack gets called as a method of
donald, then donald gets passed magically
| | 02:13 | inside those parentheses, so that
it's the first argument to the method.
| | 02:19 | There's a special type of a method that I
want to talk about which is called a constructor.
| | 02:23 | This gets called every time you
create an object based on this class.
| | 02:28 | The constructor in Python is created by
naming a method with two underscores and
| | 02:33 | the word init and two
more underscores at the end.
| | 02:36 | This creates a constructor method.
| | 02:38 | So I'm just going to print('constructor') here.
| | 02:42 | And we'll go ahead and we'll
save this and we'll run it.
| | 02:47 | You'll see that constructor
gets printed at the beginning.
| | 02:50 | So when we run this, the first thing
we do is we create the donald object and
| | 02:55 | that's where the constructor gets called.
| | 02:58 | In fact, one of the most common purposes
for a constructor is to initialize some data.
| | 03:05 | So if I put in the number 47 here
and then I pass in that value in the
| | 03:10 | constructor, I'll say value here,
instead of printing constructor here, I can
| | 03:16 | save this value, saying self._v = value.
| | 03:22 | What this does is this creates a local
variable that is an attribute of the object.
| | 03:28 | In this case, the donald object, but if
I had different objects with different names,
| | 03:32 | it would be attributes of those objects.
| | 03:35 | We'll see how valuable this is in a moment.
| | 03:38 | Then I can use that value in the methods.
| | 03:42 | For example, I can print it out here.
| | 03:45 | I can print it out here.
| | 03:49 | So now I'm initializing
this variable to the number 47.
| | 03:54 | Each time I use it, I'm going
to go ahead and print it out.
| | 03:58 | So we'll save this and run it.
| | 04:00 | Now we see that we have
a 47 here and a 47 there.
| | 04:04 | If I were to change this to
something else, save it and run it.
| | 04:08 | We have 52 here and 52 there.
| | 04:10 | If I create a different object with a
different number in it and go ahead and
| | 04:21 | call it, now when I save that and run it,
then we have the donald ducks and we
| | 04:30 | have the frank ducks.
| | 04:31 | So the value here is that this self._v is
actually attached to the object, not to the class.
| | 04:39 | This is what's called encapsulation in
object oriented programming, because that
| | 04:45 | value is a part of the object.
| | 04:48 | So I can have different
objects with different values.
| | 04:52 | I could actually have all kinds of
different data associated with those objects.
| | 04:55 | They could be opening different
databases, they could be accessing different
| | 04:59 | files, they could be keeping their
place in these databases and in these files.
| | 05:03 | This is the power of
encapsulation in object oriented programming.
| | 05:07 | We'll see a lot of examples of that
as we move forward, but for now what's
| | 05:10 | important to know is that all this happens to
this self variable right there and right there.
| | 05:16 | When the object calls a method that
self variable gets passed, and that's a
| | 05:21 | reference to the object.
| | 05:23 | All the things that are attached to
the object, its other methods, its
| | 05:26 | attributes, its data, is all carried there.
| | 05:29 | So here we've defined methods in our object.
| | 05:32 | These methods are defined in exactly
the same way that we define a function in
| | 05:37 | Python except that its first argument
is always self and that argument doesn't
| | 05:41 | get passed explicitly.
| | 05:43 | It's passed implicitly through the dot operator.
| | 05:46 | Then we have a special method called
init which is used as a constructor.
| | 05:50 | We can use that to set up data.
| | 05:52 | We can use it to open databases.
| | 05:54 | We can use it for all kinds of purposes.
| | 05:57 | The point of it is to initialize
whatever needs to get initialized when you
| | 06:01 | create the object based on this class.
| | 06:04 | So that's how you can create a
constructor and that's how you create methods in
| | 06:07 | classes that will be used in objects in Python.
| | Collapse this transcript |
| Using object data| 00:00 | Object data is data that gets
carried around with the object.
| | 00:04 | And so when you have several objects,
even several objects that are based on the
| | 00:08 | same class, they can have their own set of data.
| | 00:11 | Let's take a look at how this is done.
| | 00:13 | And we'll make a working copy of classes.py.
| | 00:17 | We'll call this, casses-working.py.
| | 00:21 | I'll go ahead and open our working copy.
| | 00:24 | We see that we have our Duck object
and the donald instance of the object.
| | 00:28 | And all of the attributes in this
object are code. They are methods.
| | 00:36 | So let's add some data to the mix.
| | 00:38 | We'll do this by first creating a
constructor by naming a method with two
| | 00:43 | underscores and the word
init and two more underscores.
| | 00:47 | And we'll pass it a value, call it color
and we'll give it a default value of white.
| | 00:53 | It's always a good idea to give your
variables default value, unless they are
| | 00:58 | absolutely going to be required.
| | 01:00 | And we'll save that in an object variable.
| | 01:04 | Object Variable is
carried with the object itself.
| | 01:07 | Remember that self is a reference to the object.
| | 01:10 | So I say self._color = color.
| | 01:13 | Now, I named it with an
underscore for a couple of reasons.
| | 01:19 | One reason is that I want to tell
myself this is an attribute that I'm using
| | 01:24 | locally, that I'm not
going to be using directly.
| | 01:27 | In other words, I'm not going to be
accessing this variable from outside of the object.
| | 01:32 | All of the access is going to be
done from methods within the object.
| | 01:35 | And for the most part, unless there's
a really overriding reason to access
| | 01:40 | data outside of the object without a
method, then it's a really good idea to
| | 01:45 | only do it with a method.
| | 01:46 | Let me show you what I mean.
| | 01:47 | It I wanted to, I could assign a value
to color here. I can say donald._color = 'blue'.
| | 02:00 | And down here, we'll just get rid of
these and we'll print donald._color.
| | 02:08 | And so, I'll save this and we'll run
it and we'll see that it says blue.
| | 02:15 | And if I print this out twice, we'll see that
the first is says white, and then it says blue.
| | 02:23 | And that's because I've
gone and I've changed it here.
| | 02:27 | And so this is what you call a side effect, and
these can be very, very hard to keep track of.
| | 02:33 | If instead, I just say I'm not
going to do it that way at all.
| | 02:38 | I'm going to do this all
through Accessor Methods.
| | 02:40 | I've a separate method for getting the
color and I call this get_color and this
| | 02:46 | will return self._color.
| | 02:50 | And then I have another method for
setting the color and I'll call this one,
| | 02:55 | set_color, and I'll say self._color = color.
| | 03:06 | Now, it's all controlled and I
can keep track of it much easier.
| | 03:10 | And so if I want to print donald's
color, I can say print donald.get_color().
| | 03:20 | Save that and we'll run it.
| | 03:22 | And if I want to change his
color, then I have a method that.
| | 03:26 | donald.set_color(), and we'll
say that their color is blue.
| | 03:35 | And then we'll go ahead and print it again.
| | 03:39 | Let's go ahead and save this
and run it and see what it does.
| | 03:41 | You might be saying to yourself, okay so
what's the difference? We just made that harder.
| | 03:45 | But did we actually make it better, and
the answer is, yeah we made it better.
| | 03:49 | The reason that it's better is that now
we have code itself has control over
| | 03:54 | what happens when that gets set.
| | 03:56 | Let's say when I set their color that
I need to save it in a database, or that
| | 04:01 | I need to do some other things. Maybe
it's not just a color, maybe it's some
| | 04:06 | other controlling configuration thing.
Maybe ducks that have blue feathers have
| | 04:11 | to also have blue feet.
| | 04:12 | So, when the color gets set, then I
know that I've got a method that's going to
| | 04:17 | also set the color of the feet.
| | 04:19 | That's what going to also save it in
the database or set some attribute some
| | 04:24 | place else, based on what this change is.
| | 04:26 | If I'm allowing it to get set just
arbitrarily from outside of the object then I
| | 04:32 | don't have that control.
| | 04:33 | Then we might end up with the duck
that's got blue feathers and green feet and
| | 04:39 | that would never work.
| | 04:40 | Bu enforcing this rule, and you'll
notice when you read about object oriented
| | 04:45 | code and when you learn about object
oriented techniques, using these accessor
| | 04:50 | methods is a standard and the reason
for that is that it avoids side effects
| | 04:55 | and avoids the kinds of problems that
can happen when you lose control over how
| | 05:00 | the data is being used.
| | 05:02 | Remember one of the major advantages of
object oriented programming is the encapsulation.
| | 05:07 | And once you have that encapsulation,
then that gives you control, that allows
| | 05:11 | you to know exactly how your data is being used.
| | 05:13 | Now the other thing that we'll notice
about this is that this does not scale well.
| | 05:20 | If I want it to be able to set say
some other flags, some other values, some
| | 05:24 | other attributes, that
can quickly get out of hand.
| | 05:27 | If they are more than two or three of these,
it would become a real problem to keep track of.
| | 05:32 | So what we tend to do in Python is
to use a dictionary and to use what's
| | 05:38 | called keyword arguments.
| | 05:40 | If instead of just setting the color
like this, I allow keyword arguments,
| | 05:44 | kwargs like that and then based on those
keyword arguments, I can set the color like this.
| | 05:59 | That one even allows me to have a
default value of white and then when I want to
| | 06:04 | set it at the beginning, and let's just
take these out here and I can say color
| | 06:13 | equals blue, like that.
| | 06:16 | Save that and run it and we get blue.
| | 06:18 | And if I don't pass the argument at all,
save that and run it, then we get white.
| | 06:26 | So this scales. If I wanted to
say set feet = 2, I can do that.
| | 06:36 | Save it and run it.
| | 06:37 | Of course, I'm not setting the color,
but I'm setting another attribute.
| | 06:42 | And if I wanted, I can have a getter for feet.
| | 06:45 | The other side of this that doesn't
scale well though is that I'm saving the
| | 06:48 | color in a variable like this.
| | 06:50 | Again, that could get on unwieldy and
it could become difficult to keep track of.
| | 06:54 | So, I can use a dictionary for that as well.
| | 06:58 | In fact, I could use a dictionary for
all of them and just call these variables
| | 07:05 | and assign it to kwargs, like that.
| | 07:10 | And for my set_color and get_color, if
I wanted to have separate accessors for
| | 07:15 | those, I could still do that. I could
say variable sub color and assign that to the color.
| | 07:25 | And I could say variables.get('color')
and give it a default value and I like to
| | 07:37 | use None in a circumstance
like this and I can save that.
| | 07:43 | And when I run it, you'll
see that we get None down here.
| | 07:48 | That just tells me that
donald's color has not been set.
| | 07:52 | But instead of this, we can make
one of these that scales as well.
| | 07:55 | Now, we're really getting into some power here.
| | 07:58 | We can say set_variable and allow it
the name. I'll call that k and then v for
| | 08:07 | value, self.variables(), so k
equals v, and get_variable(self, k).
| | 08:22 | Return self.variables.get(k, None).
| | 08:30 | Now instead of get_color,
I can say get_variable("color").
| | 08:38 | Save that and run it. But I've
set feet. I haven't set color.
| | 08:42 | So I can just put feet in here
and then I get the number of feet.
| | 08:49 | So, this allows us scalability.
| | 08:51 | This allows us, if we wanted to, even
after donald has been created, we could
| | 08:56 | set his color, set_variable("color")
to blue, and then down here, I can get his color as well.
| | 09:10 | And now, we have this flexibility.
| | 09:13 | We have a very small amount of code
that can do a lot of different things.
| | 09:18 | So, this is a technique that you'll see
commonly used in Python where you are
| | 09:23 | storing your object data in dictionary objects.
| | 09:27 | It allows you a lot of flexibility.
| | 09:29 | It allows you to use a lot of
different data, a lot of flags, a lot of
| | 09:34 | attributes, and to do different things
with them, to save them to the databases,
| | 09:39 | to use them as configuration options,
and to vary easily be able to set them and
| | 09:45 | get them and control them.
| | 09:47 | So, this is one method.
| | 09:49 | Obviously, it's not the only method and
we'll see a lot of examples through out
| | 09:52 | the rest of this course and different
ways to handle object data, but this is in
| | 09:57 | a nut shell how you use object data
with objects and classes in Python.
| | Collapse this transcript |
| Understanding inheritance| 00:00 | In object-oriented programming,
inheritance is when one class inherits the
| | 00:04 | properties of another class.
| | 00:06 | The class that is being inherited from is
often called a base class or a parent class.
| | 00:12 | Let's take a look at how this is done in Python.
| | 00:14 | We'll start by making a working copy
of classes.py, classes-working.py, and
| | 00:22 | we'll open our working copy.
| | 00:23 | You notice that we have this Duck class here.
| | 00:27 | We're going to create another class.
| | 00:29 | We'll call this one Animal.
| | 00:33 | So the Animal class will have methods
in it that will be inherited by the Duck
| | 00:38 | class and perhaps other animals as well.
| | 00:41 | We'll start by saying that an animal
makes a sound, so we'll call talk and that
| | 00:47 | will print 'I have something to say!',
and say that the animal moves around.
| | 00:58 | We'll call that walk, print. 'Hey!
| | 01:01 | I' 'm walkin'' here!' And then an animal
is covered with something, usually fur or
| | 01:14 | feathers or something. We'll call that clothes.
| | 01:18 | 'I have nice clothes'.
[00:01:22.02
| | 01:25 | All right. So there is our animal.
| | 01:27 | Now, Duck can inherit all of these
methods from Animal, in fact all of its
| | 01:33 | attributes, by simply saying Animal here.
| | 01:36 | Putting in a parenthesis
in the definition of Duck.
| | 01:41 | Now, Duck is said to be, is
an animal. Duck is a animal.
| | 01:46 | Object-oriented speak for saying that
the Duck inherits the properties of Animal.
| | 01:52 | So Duck will continue to work
the same way that it did before.
| | 01:56 | If we save this and we run it, we don't
really see any difference in how it works.
| | 02:01 | Except that now it has
access to these other properties.
| | 02:04 | I can say donald.clothes
and save that and run it.
| | 02:09 | And we see donald says he has nice clothes.
| | 02:13 | You'll notice that walk
printed "Walks like a duck."
| | 02:16 | It did not print "Hey! I'm walkin' here!"
| | 02:19 | That's because walk in
Duck overrides walk in Animal.
| | 02:25 | The way that works is that Duck
inherits Animal and then Duck defines a
| | 02:30 | method called walk, so it uses this
one instead of the one in its parent.
| | 02:36 | If we wanted to say incorporate the one
from its parent, we can do that with the
| | 02:41 | super function. This is a built-in
function which accesses the parent class and
| | 02:48 | just say, super().walk() like
that, and now donald will do both.
| | 02:54 | Save that and run it, and he
says, "Hey! Im walkin here!"
| | 02:57 | And he says, "Walks like a duck."
| | 02:59 | So this is how you can access the
class in the parent, even though you're
| | 03:04 | overriding it in the class
that inherits from the parent.
| | 03:07 | So what makes this useful is that now
we've defined an animal base class and now
| | 03:13 | if we want to have another animal,
it's very easy for us to do that.
| | 03:16 | We can say class Dog and it inherits from Animal,
and that's really all that we need to define.
| | 03:24 | We can just say pass here and we can
say fido = Dog(), and fido.walk(), and
| | 03:40 | we have a working dog.
| | 03:42 | Save that and run it.
| | 03:44 | And there we have, "Hey! I'm walkin' here!"
| | 03:46 | And that's from fido.
| | 03:48 | So obviously a dog, instead of having
clothes, he is got fur. So we can say, def
| | 03:57 | clothes, print, 'I have brown and white fur'.
| | 04:05 | And 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:14 | But what we've done is we've created
a base class that perhaps has all the
| | 04:18 | properties that are going to be common
to the classes that we're creating and
| | 04:23 | then we simply inherit that and
that makes our code very reusable.
| | 04:28 | You'll see this technique used a lot.
| | 04:30 | In fact, in an object-oriented
language like Python, virtually all of the
| | 04:35 | classes at some level are
inheriting form other classes.
| | 04:39 | You have two classes like the
tuple and the list and they do a lot of
| | 04:44 | common similar things.
| | 04:46 | In fact, strings do as well.
| | 04:48 | And so those are all inheriting from
some common classes and simply building
| | 04:53 | upon that and overwriting some
methods and implementing some and not
| | 04:57 | implementing others.
| | 04:58 | And that allows them to reuse a lot of
code and it also allows them to operate
| | 05:03 | in a lot of the same contexts as each other.
| | 05:06 | So this is inheritance and this is
how you do inheritance in Python.
| | Collapse this transcript |
| Applying polymorphism to classes| 00:00 | Polymorphism is the practice of using
one object of one particular class as if
| | 00:06 | it were another object of another class.
| | 00:09 | Let's take a look at how this is done in Python.
| | 00:11 | This is actually something
that Python is very good at.
| | 00:14 | We'll make a working copy of
classes.py and we'll call it classes-working.py.
| | 00:21 | We'll open that and we see we have our
Duck class that has quack and walk in it.
| | 00:28 | And we'll go ahead and create a Dog
class and Dog will have bark.
| | 00:43 | And fur.
| | 00:53 | The dog has brown and white fur.
| | 01:02 | Now, we'll go ahead and create a dog
object called fido = Dog and fido.bark and fido.fur.
| | 01:18 | So now we have a Dog object and a Duck object.
| | 01:24 | And if we go and run this, we see that
the Duck quacks and walks like a duck.
| | 01:30 | And the Dog barks and has brown and white fur.
| | 01:33 | So these are two separate and distinct
objects and they have two separate and
| | 01:38 | distinct interfaces.
| | 01:40 | If we want to be able to use them
polymorphically, we need to make sure that
| | 01:45 | they have a common interface.
| | 01:47 | And so the Duck class, we can give
it a bark and a fur and say bark.
| | 01:55 | print('The duck cannot bark').
| | 02:00 | And fur, and this one will
say "The duck has feathers."
| | 02:11 | And we can give the Dog, a walk.
| | 02:19 | print('Walks like a dog').
| | 02:23 | And quack. The dog cannot quack.
| | 02:34 | Now, we can use them in the same way.
| | 02:38 | For example, let's just get rid of all of
this, and we have a Dog and we have a Duck.
| | 02:46 | And if I say for object in and
give it a list, donald and fido.
| | 02:56 | I can say, o.quack(),
o.walk(), o.bark(), o.fur().
| | 03:12 | So what we have here is we're calling all four
of these functions for both of these objects.
| | 03:17 | We're using them in exactly the same way.
| | 03:19 | We're using them in a way that really
does not know or care exactly what type
| | 03:24 | of an object it is.
| | 03:25 | It's simply calling these methods
without concern for which type of an object,
| | 03:30 | just assuming that these
methods actually exist in there.
| | 03:33 | So we'll save that and we'll
run it and we see our result.
| | 03:37 | We have the Duck first. Quaaack!
| | 03:39 | Walks like a duck.
| | 03:40 | The duck cannot bark.
| | 03:41 | The duck has feathers.
| | 03:42 | And then we have the Dog.
| | 03:44 | And there is all those same methods on the Dog.
| | 03:48 | So if I had say a function, say in_the_
forest, and it expects a dog and it says,
| | 03:59 | dog.bark() and dog.fur().
| | 04:10 | And let's say I had another one that
says in_the_pond and it expects a duck.
| | 04:17 | And it says duck.quack()
and it calls duck.walk().
| | 04:25 | Now, I can call either of these
methods with either of these objects.
| | 04:29 | I can say in_the_forest, and you see
the in_the_forest is expecting a dog and
| | 04:34 | I can pass it donald.
| | 04:35 | And as long as donald implements the
interface that is being used in this
| | 04:42 | function, it will still work.
| | 04:44 | Save this and run it.
| | 04:46 | It says the duck cannot
bark and The duck has feathers.
| | 04:50 | And likewise, if I call in_the_pond
and I pass it fido, save that and run it.
| | 05:01 | The dog cannot quack and it walks like a dog.
| | 05:05 | So this is what polymorphism is.
| | 05:07 | And Python is particularly good at this
because the objects in Python don't
| | 05:14 | actually care what the name of the class is.
| | 05:19 | When you use an object, Python is
what's called loosely typed or actually they
| | 05:24 | call it duck typing, because the
types in Python, everything is an object.
| | 05:29 | And if it walks like a duck,
then you can use it like a duck.
| | 05:33 | That's why they call it duck typing.
| | 05:34 | It's loosely typed.
| | 05:36 | When I declare that this in_the_forest
function expects a dog, I'm just naming
| | 05:42 | it dog, but it's an object.
| | 05:44 | I could name it cat and it would still
work exactly the same, because that's
| | 05:51 | really just a variable name.
| | 05:52 | That's not a type name at all.
| | 05:53 | That's no kind of a restriction.
| | 05:55 | It's just what I'm calling it here.
| | 05:57 | So I save that and run it.
| | 05:59 | It still works exactly the same.
| | 06:01 | So a strong advantage of this loosely
typed or what they call duck typing is
| | 06:07 | that polymorphism is natural.
| | 06:10 | So I can create a super class that
implements all of the things that an animal
| | 06:16 | normally does, and then I can create
subclasses from that with just the specific
| | 06:21 | attributes of the type of an animal that
I'm interfacing, and then anything that
| | 06:26 | expects any of those interfaces can use it.
| | 06:29 | Because all of those
interfaces are guaranteed to be there.
| | 06:32 | So I know that that's a big concept to
wrap your head around, but think of it
| | 06:36 | this way. Any object of any class that
implements the interface that's expected
| | 06:43 | by any function can be used by that function.
| | 06:47 | So when I create a function here called
in_the_forest and it expects an object
| | 06:54 | that can bark and an object that has fur,
or a function that expects an object
| | 06:59 | that can quack and the object that can walk,
| | 07:01 | any object that implements those
methods will work in that function regardless
| | 07:07 | of what its type is.
| | 07:08 | And that is polymorphism and
that's how it works in Python.
| | Collapse this transcript |
| Using generators| 00:00 | A generator object is an object that
can be used in the context of an iterable,
| | 00:06 | like for instance in a for loop.
| | 00:08 | Let's take a look at how this is done in Python.
| | 00:11 | We'll make a working copy of generator
.py. I'll call it generator-working.py.
| | 00:18 | We'll open that up and we see that here
we have a range object being used in the
| | 00:25 | context of an iterator.
| | 00:28 | So o is getting assigned to this range
object that's a range of 25 and it's
| | 00:34 | being used in the context of this for
loop which is an iterable context and if
| | 00:39 | I run this, you see that we get series
of numbers from 0 through 24 and this
| | 00:46 | is how range works.
| | 00:47 | Range is non-inclusive, which means that
we ask for a range of 0 through 25.
| | 00:54 | What we get 0 through 24, because it's up to
but not including the range we specify.
| | 01:01 | Range takes three possible arguments.
It only requires 1 and so those three
| | 01:06 | possible arguments are the
start and the stop and the step.
| | 01:13 | So we start at 0 and stop at 25 and
step by 1, this is the result that we get.
| | 01:21 | And so start and step default to 0
and 1 and all you have to specify is the stop.
| | 01:28 | If I were to start it say at 5
and step by say 2, save that and run it,
| | 01:36 | you will get 5 through 23.
| | 01:38 | Again, we don't get 25 because it's not
inclusive, and you see they are stepping by 2.
| | 01:42 | So what I would like to do here is
create our own range object as an exercise to
| | 01:49 | learn how to create a
generator object in Python.
| | 01:52 | It will work exactly like this one,
except that it will be inclusive.
| | 01:56 | We'll always get that last number there.
| | 01:58 | So go ahead and reset this to 25
and we will start creating our class.
| | 02:05 | So we'll call this class inclusive_
range and it will have a constructor.
| | 02:19 | And it will have an iterator.
| | 02:27 | These are both special method names in Python.
| | 02:30 | Init with the two underscores before
and after it are for constructors and iter
| | 02:36 | like this, with two underscores before
it and two underscores after it, makes the
| | 02:40 | object an iterable object.
| | 02:43 | So this is where we'll put
our generator function in here.
| | 02:46 | The constructor will need to be able to
do this weird thing with the argument.
| | 02:52 | The first argument and the third
argument are optional but the second
| | 02:55 | argument is required.
| | 02:57 | That's going to take a little bit of
manipulation on our end and we'll do
| | 03:00 | that in the constructor.
| | 03:01 | We need this arbitrary
list of positional arguments.
| | 03:03 | So we'll use the list argument syntax
here and then asterisk and args and
| | 03:10 | we'll get the number of
arguments by using the length built in.
| | 03:14 | len(args) like that and if we have
less than one argument we are going to
| | 03:21 | raise an error.
| | 03:26 | We'll use TypeError requires at least
one argument. Let's say if numargs is
| | 03:36 | less than 1 and we'll use elif
numargs == 1, elif numargs == 2.
| | 03:48 | I like to outline my code like this
sometimes and then go back and fill it in.
| | 03:52 | Numargs = 3 or else we'll raise a TypeError.
| | 04:06 | Expected at most three arguments and
| | 04:11 | got this other number.
| | 04:16 | Now we can go ahead and fill
in each of these conditions.
| | 04:20 | If we get just one argument
then we know that's the stop.
| | 04:23 | So we can say self.stop = args sub 0.
Otherwise we have got self.start = 0 and
| | 04:39 | self.step = 1, because
those are those default values.
| | 04:46 | If we have two arguments and we know
that that's the start and the stop.
| | 04:50 | self.start, self.stop, and we assign
that to args and we use our default for step.
| | 05:03 | Finally, if we have three arguments,
then we know that's all of them,
| | 05:07 | start, stop and step.
| | 05:15 | So now we have our constructor
and our iterator is very easy.
| | 05:20 | We start by setting the starting point
and we have a simple while loop, while i
| | 05:29 | is less than or equal to a stop, then
we yield the result-- and we'll get back to that one--
| | 05:38 | and we increment the iterator by this step.
| | 05:45 | So this is what makes it a
generator is the yield statement.
| | 05:51 | Yield works just like return but
with the significant difference.
| | 05:54 | If I were to use return here, it would
return the value and the next time the
| | 05:58 | iterator was called it would start
at the beginning of the function.
| | 06:01 | By using yield instead it returns the
value and the next time the function is
| | 06:06 | called execution picks up
right after the yield statement.
| | 06:10 | So the way this will run is it will
set the starting point and it will test
| | 06:15 | the while loop and assuming that the
starting point is less than or equal to
| | 06:20 | the stop point, it will yield the value.
Do that's the starting point and then
| | 06:25 | the next time the iterator is called,
it will increment that value and test
| | 06:30 | the while loop again, and then it will
yield the next value and then it will
| | 06:35 | increment and we'll yield the next value
and this allows it to operate as an iterator.
| | 06:40 | So by having the yield statement inside
the function, that makes the function a
| | 06:46 | generator and what a generator
generates is an iterable object.
| | 06:50 | We need to change this to our
inclusive_range. I have a little typo here.
| | 06:58 | self.step. Save that and run it and
there we have a range all the way up to and
| | 07:06 | including our stop, and so let's go
ahead and test out our constructor.
| | 07:14 | I'll change the start point to 5 and
now it start to 5 and go up to 25.
| | 07:20 | Save that and run it, and there it,
starts at 5 and goes all the way up to 5.
| | 07:26 | Let's have it step by 2 instead of
stepping by 1. Save that and run it.
| | 07:33 | Now we see it steps by 2. We can change
that to 7 and it will still do what we expect.
| | 07:41 | That's great and now let's call it with no
arguments and we'll test our error conditions.
| | 07:47 | No arguments, we would expect it to
get that TypeError and there it is,
| | 07:51 | TypeError requires at least one argument and
if we give it four arguments, let's say
| | 07:55 | 1, 25, and 3 and 14, we expect to get
this other type error here and there it is,
| | 08:06 | expected at most three arguments and got four.
| | 08:09 | So we have successfully duplicated the
range generator function, save that and
| | 08:15 | run it, except that ours is inclusive.
| | 08:18 | That was really easy to do.
| | 08:19 | So this is how you make a generator
object is by using the iter method in your
| | 08:26 | class and now your object becomes iterable.
| | 08:30 | It becomes a generator and when the
object is used in the context of an
| | 08:36 | iterable, like for instance, in this for
loop, then that iter methods gets called
| | 08:42 | automatically and you do not
have to do something like .iter.
| | 08:48 | You can simply use the object in that context.
| | 08:51 | In fact I don't even have to
create an intermediate variable.
| | 08:57 | So I can take this line out all
together and put it in this place here and you
| | 09:02 | will see that range is
used like this very often.
| | 09:06 | So I can save that and run it and
there we have a drop in replacement for
| | 09:12 | range except that this one is inclusive and
that's how you make the generator object in Python.
| | 09:18 | It's a very convenient
and very powerful technique.
| | 09:22 | You will find yourself using it in
some places that you won't anticipate.
| | 09:26 | I have used it in database
applications where I have a very specific database
| | 09:30 | application with a specific class that
simply steps through a particular type of a query.
| | 09:36 | I have used it in parsing files, where I
want to get a certain pattern out of a file.
| | 09:42 | There is all kinds of applications for
this and you will find that you actually
| | 09:45 | use it more often than you might think.
| | Collapse this transcript |
| Using decorators| 00:00 | Decorators are special functions that
return other functions and they are used
| | 00:04 | to modify the way that a function works.
| | 00:07 | There's a special syntax for
using decorators in Python.
| | 00:10 | Let's take a look at how that works.
| | 00:13 | Let's make a working copy of
decorators.py and we will call it
| | 00:18 | decorators-working.py and we will
open that up, and we will see we have
| | 00:23 | our Duck example here.
| | 00:26 | This one has a properties variable
that's getting set by the keyword arguments,
| | 00:30 | and it has a way of setting
properties and getting properties.
| | 00:34 | Down here we have set a property in
our constructor and we were getting that
| | 00:38 | property in this print function.
| | 00:41 | So if we run this, we see that
we are printing out that color.
| | 00:44 | Now, one of the most common uses for
decorators in Python is to create accessor
| | 00:49 | methods for variables.
| | 00:51 | For examples, if I wanted special
accessors for color, I can define a function
| | 00:57 | called color and configure it like a getter.
| | 01:02 | So I'll return self.properties.get
('color') and with a default value of None.
| | 01:11 | What turns this into an accessor is
this decorator function that looks like that.
| | 01:18 | With an @ sign and the word property,
and that turns this into an accessor for
| | 01:24 | the variable called color.
| | 01:26 | Then I can create a setter by saying
@color.setter and def and I name it exactly
| | 01:37 | the same thing, color.
| | 01:39 | This is all special syntax that's designed
just for this purpose. I set an argument.
| | 01:45 | We will call it c and we will set
self.properties sub 'color' = c, and now we have our setter.
| | 01:55 | Finally, color.deLeter, sub 'color' again,
and delete self.properties sub 'color' and what
| | 02:12 | this allows us to do is this.
| | 02:16 | I can see donald.clolor = 'blue'.
| | 02:21 | I don't need to initialize it here any more.
| | 02:26 | So if I save that and run it, we will see
that it still works the way that we want it to.
| | 02:31 | Here I can just say donald.color.
| | 02:34 | Now, this might look like I went to a
lot of trouble to just be able to use a
| | 02:39 | property that I could have just used
without all of this trouble and it would
| | 02:43 | have set the property in the object,
and read the property from the object.
| | 02:48 | But the beauty here is that now it's
under the control of the object. And so if
| | 02:55 | I wanted to do some thing
else in here when I set this.
| | 02:58 | If I wanted to save it to a database or
if I wanted to create a database based
| | 03:04 | on a filename, which is an example
of how I have used this recently.
| | 03:09 | Then in the deLeter, if I wanted to
close the database based on that filename.
| | 03:13 | So now I can do all of those things,
but I still have this convenient syntax.
| | 03:18 | So this is the most common use of
decorators and this is a little bit of the
| | 03:22 | power of decorators as well, is it they
can fundamentally change the behavior of
| | 03:28 | a function, because here I have got
function methods which are operating a
| | 03:33 | setters and getters, but I am not
calling them as functions. I am calling them
| | 03:38 | in this simple normal properties syntax.
| | 03:41 | So that's the power of decorators and
that's a simple example of how you can use
| | 03:46 | decorators in your objects.
| | Collapse this transcript |
|
|
13. String MethodsUnderstanding strings as objects| 00:00 | In Python, strings are objects,
just like everything is an object.
| | 00:04 | We are going to take a little bit of
time and look at what this means, because
| | 00:08 | this is not what people are used to
who have been programming in other
| | 00:11 | programming languages.
| | 00:12 | But in Python, the "everything is an
object" paradigm has particular impact on how
| | 00:20 | we operate on strings.
| | 00:22 | And also, it's a little bit
different than it was in Python 2.
| | 00:25 | Even though strings were objects in
Python 2, they weren't fully first class
| | 00:29 | objects in the sense that they are in
Python 3, and the interface is a lot more
| | 00:33 | consistent in Python 3, but it also
means that it's significantly different
| | 00:37 | than it was in Python 2.
| | 00:38 | So if you're familiar with Python 2, this is
worth paying attention to just a little bit.
| | 00:42 | So here we have a string, 'this is a
string,' and the value of that of course is a string.
| | 00:50 | Now, if we assign it to a variable, now
we have a variable, and if we just get
| | 00:57 | the value of that variable,
it says, "This is a string."
| | 00:59 | Now, of course in Python a
variable is just a reference to an object.
| | 01:04 | So I can operate on that string by
saying s.upper() and and we get the
| | 01:09 | uppercase of the string.
| | 01:10 | And here is the thing that surprises
people sometimes is I can do the same
| | 01:14 | thing just on the string, I can say
'This is a string'.upper(), and that
| | 01:21 | will give me the uppercase of THIS IS A
STRING., because the string itself is an object.
| | 01:26 | The significant impact here is
the use of the format method.
| | 01:30 | The format method is very often
called on an bare string, so to speak.
| | 01:35 | So it's very common to do
something like this in Python.
| | 01:38 | This is a string and put in a format,
and close the quotes, and say .format(42)
| | 01:46 | like that, and the result will be
'This is a string 42', because what we have
| | 01:51 | done is we actually operated on the
string using the format method, and
| | 01:56 | replaced the token in the string with the
formatted number 42, and this is very common to do.
| | 02:03 | Older 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:17 | the same way, because you weren't
using the dot notation to access a method.
| | 02:23 | Instead it overloading this %
operator to do exactly the same thing.
| | 02:28 | Now, it's worth noting that in
Python 3 that % notation is considered
| | 02:33 | obsolescent, which means that in
future versions of Python that will no
| | 02:37 | longer be supported.
| | 02:38 | So this is a good time to get used
to using the .format method, and in
| | 02:42 | fact, the format method is a lot more
powerful and a lot more consistent in its syntax.
| | 02:48 | The syntax used in the old percent style
string replacement was borrowed from C,
| | 02:53 | and it's 40 years old, and while it
certainly works and it's certainly familiar
| | 02:57 | to anybody with the background
in the C programming language,
| | 02:59 | it's not as consistent or as powerful as the
new format operator in the format language.
| | 03:04 | So we will be talking more about
that in detail later on in this chapter.
| | 03:08 | For now, what's important to note
is that a string is an object and a
| | 03:13 | variable containing a string is
really just a variable that contains a
| | 03:17 | reference to a string object.
| | 03:18 | So everything that you can do on that
string object, you can do on the string
| | 03:22 | itself, because the string
itself is the string object.
| | Collapse this transcript |
| Working with common string methods| 00:00 | The string object in Python
supports a lot of standard methods.
| | 00:05 | We're going to take a look
at just some of them here.
| | 00:07 | We'll start with a string. I'm going to
go ahead and put it in a variable and
| | 00:10 | say s = 'this is a string'.
| | 00:13 | And notice that's all lowercase, and
we just look at the string by itself.
| | 00:17 | It looks like that.
| | 00:18 | If I say capitalize(), then we get it
with just the first letter capitalized.
| | 00:24 | I want all the letters capitalized I
can say .upper() and there is certainly a
| | 00:28 | lot of use for that.
| | 00:30 | Likewise, 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:42 | And we'll see that we get
the lowercase version of that.
| | 00:44 | We can also say swapcase().
| | 00:47 | So if I had 'This Is A String,' sort
of title case-ish, I say .swapcase().
| | 00:55 | Then I get it in the opposite case.
| | 00:58 | If I take our string, which says,
'this is a string' and I want to find a
| | 01:03 | particular word in it, I can
look for it say the word "is."
| | 01:08 | And we will find it at position 2.
| | 01:10 | And you might look here and you might
say, well, "is" is at position 0, 1, 2, 3,
| | 01:16 | 4, 5, but in fact, it found this.
| | 01:21 | So it's looking for exactly that string.
| | 01:23 | In the first occurrence of it
is the one that get will return.
| | 01:26 | And so the first letter is 0, the second
letter is 1, and then "is" starts at position 2.
| | 01:32 | We can also do string replace.
| | 01:34 | I can say s.replace, this for that.
| | 01:40 | And it'll say 'that is a string'.
| | 01:42 | Now, it's important to note that
the string itself is immutable.
| | 01:45 | So the string has not changed with these
functions do as they return a different string.
| | 01:49 | And it's an entirely different
string object that gets returned.
| | 01:53 | For example, if I look at the id of (s)
I'll see that its id is that number there.
| | 02:00 | And if I say newstring =
s.upper(), I now have a new string which is
| | 02:09 | the uppercase string.
| | 02:11 | It's that different string that
was returned by the upper() method.
| | 02:15 | If I look at the id of (newstring), you'll
see that it's entirely different than the
| | 02:19 | id of 'this is a string'.
| | 02:21 | So there's few more useful ones,
there is a strip. I say s.strip().
| | 02:26 | What strip does is that strips a
particular sequence of characters from both
| | 02:30 | the end of the string and
the beginning of the string.
| | 02:33 | By default what it strips is whitespace.
| | 02:35 | So if I have a string that says ' this
is a string ' like that, with a bunch of
| | 02:40 | whitespace at the beginning and the end of it,
| | 02:41 | and I say .strip(),
| | 02:43 | I'll get back the string without that
whitespace at the beginning and the ending of that.
| | 02:47 | And so where this very commonly used
for is removing new lines, but you need to
| | 02:52 | be aware when you use it for that, that
it will also remove any leading space.
| | 02:58 | If you want to just remove whitespace
from the end of string, you can use rstrip().
| | 03:10 | And that will remove the whitespace
from the end of a string and not change
| | 03:14 | anything at the beginning of the string.
| | 03:15 | And if you just want to remove a new line,
let's say we have a string, I'm going
| | 03:19 | to 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:28 | I said sting instead of string. That will work.
| | 03:31 | And there we see we have the
string with a newline at the end of it.
| | 03:35 | If I say s1.strip(), of
course, it'll remove the new line.
| | 03:40 | And that's very useful, but it will
also remove any whitespace from the
| | 03:42 | beginning or the end.
| | 03:43 | If I just want to remove the
new line from the end, I can actually say
| | 03:47 | s1.rstrip and specify the newline.
| | 03:52 | So whatever string you specify,
parenthesis is what will be stripped.
| | 03:56 | And there we have it with just a
newline taken from just the end of the string.
| | 04:01 | There's also a set of methods for
testing the content of a string really quickly.
| | 04:06 | We'll look at these. We can say s.isalnum().
| | 04:10 | And what that is, is that it
checks if the string has only
| | 04:13 | alphanumeric characters in it.
| | 04:14 | And of course, this is False
because it also had spaces in it.
| | 04:17 | If I have a string that looks like
'thisisastring' and has no spaces in it and I
| | 04:23 | say .alnum() and it'll come up True.
| | 04:27 | I must have spelled something wrong.
I did. 'thisisastring'.isalnum() and
| | 04:36 | that comes up True.
| | 04:37 | So these methods that start with "is,"
there is a bunch of them. I'm just going to
| | 04:41 | show you a few. There's
isalpha(), 'thisisastring'.isalpha().
| | 04:47 | And that checks just for alpha characters.
| | 04:50 | So that would be the letters a-z or
other alpha characters in other text
| | 04:56 | encodings beside just ASCII.
| | 04:58 | And there is also one for
checking if it is digit.
| | 05:01 | And so if I have a string that's just
digits and say isdigit(), that one will
| | 05:06 | come up True, but if I check
s.isdigit() it will of course come up False.
| | 05:12 | And finally there's isprintable(), which
checks to see if all the characters in
| | 05:18 | the string are printable.
| | 05:20 | So those are some of most common and
most popular methods that are available
| | 05:23 | for the string class.
| | Collapse this transcript |
| Formatting strings with str.format| 00:00 | The string format method is
very powerful and useful tool.
| | 00:03 | You'll see it used a lot
and you will use it a lot.
| | 00:06 | It looks like this.
| | 00:08 | Let's start by assigning a
couple of variables a and b = 5 and 42.
| | 00:12 | And then we'll print them out.
| | 00:15 | If I were to just say print a, b
like that then we get the numbers.
| | 00:20 | But that's not terribly useful or descriptive.
| | 00:23 | And you might want to look at it more like this.
| | 00:26 | You might want to say this is and put
in a placeholder and that is and put in
| | 00:32 | another placeholder.
| | 00:33 | And 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:42 | So this is what the format method does.
| | 00:44 | It allows you to put placeholders
in a string and then replace those
| | 00:47 | placeholders with values
and return a new string.
| | 00:51 | It's important to note that the
string that's returned is a new string.
| | 00:56 | Strings are immutable in Python.
| | 00:57 | So this string is an entirely
different string than that string.
| | 01:02 | So if I had a string that just had this
in it, do a copy and paste here, and say
| | 01:07 | s = and put that in it.
| | 01:10 | Now I have that string.
| | 01:11 | If I just look at s, that's what's in it.
| | 01:13 | If I say s.format(a, b), I get a new string.
| | 01:19 | So the id of s is this.
| | 01:22 | And if I say new = s.format(a, b)
and look at the id of that, I have a different id.
| | 01:33 | Those are two entirely different strings.
| | 01:36 | So format returns a new string.
| | 01:39 | It's also important to note
that format is new as of Python 3.
| | 01:44 | Format was not available in Python 2.
| | 01:47 | In Python 2 things were done differently.
| | 01:49 | In Python 2 you might have
done some thing like this.
| | 01:52 | this is %d, that %d. And then
use a % operator and have a and b.
| | 02:01 | So this was overloading the % operator
and it was using C style format strings.
| | 02:07 | And we just felt that this is
obsolescent, and it needed to be replaced with
| | 02:10 | something more powerful.
| | 02:11 | And that's what happened in Python 3.
| | 02:14 | The format method is more powerful.
| | 02:16 | It's a more consistent syntax and
it's actually a lot easier to use.
| | 02:20 | One thing in particular that you can
note here is that using this old way you
| | 02:25 | needed to know a type.
| | 02:26 | This %d represents a decimal type.
| | 02:29 | And using this new way it uses the repr
method, repr, to look at the value and
| | 02:37 | decide what type it is and
print it out based on its type.
| | 02:40 | So you don't need to know what type
the variables are in order to use format.
| | 02:45 | Another thing worth noting is that this
method that we are using here, and this
| | 02:49 | gets used a lot in this course and you
will see it a lot in new code with the
| | 02:53 | bare curly braces, is
actually new in Python 3.1.
| | 02:57 | In Python 3.0, you needed some sort of a
indicator inside of the curly braces,
| | 03:03 | a positional indicator or a name indicator.
| | 03:06 | And we'll look at how those work in a moment.
| | 03:08 | But in Python 3.1 and later, you
don't need anything inside of those curly
| | 03:12 | braces, and it simply takes the
positional arguments based on their order.
| | 03:16 | So if I wanted to print a and b in the
opposite order, I would actually have to
| | 03:21 | put them in the opposite order in the format.
| | 03:23 | I'd have to change them here, and
say b, a and then I will get 42 and 5.
| | 03:32 | On the other hand if I wanted to, I
could say 1 here and 0 here, and not change
| | 03:40 | their order and it will
print them in the opposite order.
| | 03:43 | So 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:53 | say, this is 1 and that is {0}
and this too is {1}.format(a, b).
| | 04:04 | And now I am actually getting this
1 value twice and the 0 value once.
| | 04:08 | So these numbers represent the
positional order in which the arguments
| | 04:12 | are provided to format.
| | 04:14 | You can also use names.
| | 04:16 | You can say this is {bob} and that is {fred}.
| | 04:23 | And then name your arguments in
format. bob = a, fred = b and that can be useful.
| | 04:33 | In fact you could put them in a
dictionary d= dictionary, bob = a and fred = b
| | 04:42 | and then use that dictionary.
| | 04:44 | 'this is {bob} and that is {fred}'.format
and you use this double asterisk to
| | 04:51 | refer to the dictionary.
| | 04:53 | So format is very powerful in this way.
| | 04:55 | And in fact, it's an extremely
rich language all on its own.
| | 04:59 | The full documentation for
format is available on the Python
| | 05:03 | documentation website.
| | 05:04 | And it has all kinds of ways that data can be
formatted and ways that you can specify type.
| | 05:10 | It's an extremely rich language in its own.
| | 05:12 | And it's actually more powerful
and more flexible than the old way of
| | 05:15 | doing things in Python 2. So that's format.
| | 05:18 | These are the things about it that are
essential to know in order to be able use it.
| | 05:23 | You can get a lot of power out of it
just knowing what I have shown you here.
| | 05:26 | And in fact, nine times out of ten,
this is all you are going to need in order
| | 05:29 | to use format effectively.
| | Collapse this transcript |
| Splitting and joining strings| 00:00 | Splitting and joining strings is a
very common operation, especially in text
| | 00:05 | based environments like the World Wide Web
or when you are operating on a lot of text files.
| | 00:09 | So Python provides some string
methods for splitting and joining strings.
| | 00:14 | Let's take a look at how that works.
| | 00:15 | We'll take a string. We'll put it in a
variable because we are going to be using
| | 00:18 | it here quite a bit.
| | 00:20 | And we'll say s = 'This is a string of words.'
| | 00:26 | And if we want to split that
string apart we can just say s.split.
| | 00:31 | And it'll split the string
apart on the white space.
| | 00:34 | And in fact if there was a lot of
white space in between the words, if 'tThis
| | 00:38 | string was something like this is
a string of words' like that .split.
| | 00:47 | We see that it folds all the white space
together first before splitting on the white space.
| | 00:54 | So that's a very nice and handy thing to do.
| | 00:57 | If we wanted to split on some other
token besides the white space we can specify
| | 01:02 | it in the split method but
it won't do this folding thing.
| | 01:06 | That folding thing is a special thing
that it does just with the white space.
| | 01:09 | And it only does that if you don't
specify an argument to split it all.
| | 01:12 | For example if I say s.split and I want to
split it on say the i characters like that,
| | 01:21 | then I'll get back a list of the
string with all of the i's removed and the
| | 01:25 | words separated on the i characters
and you see the space is still in there.
| | 01:29 | So let's go ahead and split it on the
white space and assign it to a variable.
| | 01:34 | We'll call the variable
words = s.split like that.
| | 01:39 | And now we have a list words is a list
with a bunch of separate words in it.
| | 01:43 | And it's utterable. I can say for w in words:
| | 01:47 | print(w) and it'll print
those words out separately.
| | 01:51 | But I can also join them
back together if I want to.
| | 01:54 | I can say new string =, doing it
with a colon in it, .join and so the join
| | 02:00 | method operates on the token that's
going to be used to join things back
| | 02:04 | together not on the list of words.
| | 02:06 | And so I say join and I say words like this.
| | 02:10 | And now I have a new string, which
is all of those words joined back
| | 02:13 | together with colons.
| | 02:14 | Or if I wanted to I could say put a
string with a comma and a space in it
| | 02:20 | and say .join(words).
| | 02:22 | And I would get back a list of
words with a comma and a space.
| | 02:26 | So I can really put whatever I want to
there in the string that I am going to
| | 02:29 | use to join the words back together.
| | 02:30 | So in a nutshell that's how we
split and join strings in Python.
| | 02:35 | Again this is a very common operation.
| | 02:37 | This is something that you'll use quite a
bit if you are working with any text files.
| | 02:41 | If you are working on a World Wide Web,
if you are working with mail, if you are
| | 02:43 | doing any manipulation of text whatsoever.
| | 02:45 | You are going to find a lot
of uses for split and join.
| | Collapse this transcript |
| Finding and using standard string methods| 00:00 | Python has an extremely rich set of
string methods, over 40 of them last I counted.
| | 00:06 | What we've covered here are the essential ones.
| | 00:09 | And I'd like show you how to find
the rest of them and how to use them.
| | 00:12 | It's really quite straightforward.
| | 00:13 | Here we have the Python documentation
page or the Python Standard Library.
| | 00:19 | And we'll notice this is
section 5, Built-in Types.
| | 00:22 | And down here we see this
link of 5.6.1 String Methods.
| | 00:27 | And here's a complete list
of all the string methods.
| | 00:29 | Like for example, here is this center one.
| | 00:32 | And we see that center it takes with
and an optional fill character and it
| | 00:36 | returns a centered string of length width.
| | 00:39 | And padding is done using this
specified fill character. Default is a space.
| | 00:43 | So if I had a string, 'this is a string',
and I wanted to center it on say 80
| | 00:50 | character string, I would simply
say new = s.center(80) like that.
| | 00:56 | And now I have a new string.
| | 00:58 | And we see that this new
string is 80 characters wide.
| | 01:01 | I can check if I want to. length of new is 80.
| | 01:05 | And we see that the string from my
original string is centered there.
| | 01:09 | Like I said, there are over
40 of these different methods.
| | 01:12 | And here's the entire list and
they are all very well documented.
| | 01:15 | It's really simple.
| | 01:16 | It's not in a terribly technical language.
| | 01:19 | And so I encourage you to take the
time and at least read through this one and
| | 01:23 | get an idea for what is available.
| | 01:25 | And then refer to it when you need one.
| | 01:28 | That makes it really easy for you to
have these tools at your disposal without
| | 01:31 | having to memorize everything, without
having to go through a lot of detail on
| | 01:35 | the ones that you are not
going to use very often.
| | 01:37 | So use the documentation in this case.
| | 01:39 | There is a great wealth of
string methods available.
| | 01:42 | And I encourage you to become
familiar with them and use them.
| | Collapse this transcript |
|
|
14. ContainersCreating sequences with tuples and lists| 00:00 | Tuples and lists are the
basic array types in Python.
| | 00:04 | tuples are immutable and lists are mutable.
| | 00:07 | tuples are created with the comma operator.
| | 00:12 | Say t = 1, 2, 3, 4, 5 like that, and I get
a tuple with those five elements in it.
| | 00:18 | So, element number 0 is the beginning
of the list and element 4 is the end of the list.
| | 00:28 | Of course, you can always get the
end of the list with -1, like that.
| | 00:33 | I can take the length of the list, I can
get the smallest element, I can get the
| | 00:41 | largest element and so I have a tuple.
| | 00:46 | There is some confusion about
how you create a tuple in Python.
| | 00:49 | Sometimes it looks like you use the
parenthesis to create a tuple, because more
| | 00:53 | often than not you'll see it done like
this to create the tuple, but in fact,
| | 01:01 | it's the comma operator.
| | 01:03 | This is the important distinction
because if you want to create a tuple with one
| | 01:06 | element, that won't do it.
| | 01:10 | That creates an integer.
| | 01:14 | The comma is required. The parentheses
are for binding, and when you have a lot
| | 01:18 | of elements separated by commas, the
parenthesis are convenient for that and
| | 01:21 | that's why you'll often see it that way.
| | 01:23 | But in fact, if you want a tuple with
one element, you create it like this.
| | 01:31 | And now, we have a tuple.
type(t) is <class 'tuple'>.
| | 01:37 | Lists are created with square brackets.
| | 01:45 | Now I have a list.
type of x is <class 'list'>.
| | 01:52 | Lists work very much like tuples in
that I can subscript it in the same way or
| | 01:58 | I can look at the last one and I can
check its length and I can get the largest
| | 02:06 | element and the smallest element.
| | 02:11 | The difference is, is that I can change things.
| | 02:14 | If I take my tuple and let's put
something bigger in the tuple.
| | 02:24 | Now I have a tuple with 25
elements in it and that is a tuple.
| | 02:30 | Let's say that I try to change one of
those elements.
| | 02:39 | I get this error, 'tuple' object
does not support item assignment.
| | 02:43 | Tuples are immutable, so I
can't change things in them.
| | 02:47 | On the other hand if I create a list,
I am using the list constructor here to
| | 02:55 | convert this range into a list and
there is my list and type(x) is <class l'ist'>
| | 03:02 | and I can say x10 = 42.
| | 03:08 | Now, we see that 42 right there in the list.
| | 03:14 | So, a list is mutable
and a tuple is not mutable.
| | 03:19 | So, why would you want to use a tuple
when you can use a list and the list is
| | 03:22 | more powerful and has more functionality?
| | 03:25 | Tuples are there because more often
than not, when you them you don't need
| | 03:28 | to be changing them.
| | 03:29 | It's a smaller class.
| | 03:31 | It's simpler to implement, they are
faster for some things, but most importantly
| | 03:37 | they don't allow you to change stuff.
| | 03:39 | So, if you have a circumstance, and
most circumstances are like this, where you
| | 03:44 | need an object that's always going to
stay the same size, it's always going to
| | 03:47 | have the same data in it,
| | 03:49 | you want to use a tuple so that you
can't accidentally it, and if you do, you'll
| | 03:53 | get an exception and you'll
be able to find your problem.
| | 03:56 | So, use your tuples where you can, and
where you absolutely need to be able to
| | 04:02 | change your array, that's where you use a list.
| | Collapse this transcript |
| Operating on sequences with built-in methods| 00:00 | Tuples and lists are very powerful in
Python and there are a lot of operations
| | 00:05 | that you can perform on them.
| | 00:07 | Let's go ahead and set up a
couple of tuples and lists.
| | 00:11 | We'll have a tuple we'll call t
and we'll initialize it with a range.
| | 00:20 | So, there is our tuple and we
can see type(t) is class tuple.
| | 00:25 | So, 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:31 | If I say 50 in t I get a false.
| | 00:34 | Of course, you can also use not in.
I can say 50 not in t and that will be True.
| | 00:41 | I can look at a particular entry.
I can say well what is that index 10.
| | 00:45 | I can say t10 like that.
| | 00:49 | I see because a range was 0 base
that at position 10 is the number 10.
| | 00:53 | Of course, I can look at the
length of it and a tuple is iterable.
| | 01:00 | I can say for i in t and I can print(i).
| | 01:07 | Likewise, you can do all of these
things with lists. x= list(range(20).
| | 01:16 | I am missing a parenthesis there.
| | 01:18 | So x is now that list and I
can 10 in x and I can get true.
| | 01:24 | I can 20 in x and will get false
because that range was not inclusive and I can
| | 01:31 | iterate it. I can say for i in x:
| | 01:34 | print(i) and that's iterable as well.
| | 01:38 | Of course, one of the major differences is
that I can assign things to my list and
| | 01:43 | cannot assign things to my tuple.
| | 01:45 | My tuple is immutable.
| | 01:47 | So I can't say t sub 10 = 25.
| | 01:54 | tuple object does not support item assignment.
| | 01:56 | A tuple is immutable.
| | 01:58 | But 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:06 | Likewise, I can do any operation on a
tuple that does not involve modifying it.
| | 02:12 | I can use the count method to count how
many 5s there are in the tuple and there
| | 02:18 | is of course one of them.
| | 02:20 | I can find the index of the 5.
| | 02:21 | That will find that index of the first
occurrence of that value and it's index number 5.
| | 02:29 | If we look at t here we see 0, 1, 2,
4, 5. So that one there is indeed a 5.
| | 02:37 | But I cannot append. If I say
t.append(100), 'tuple' object has no
| | 02:45 | attribute 'append'.
| | 02:47 | On the other hand, if I look at
my x object, which is a list, and I say
| | 02:51 | x.append(100), it will put 100 at the end of it.
| | 02:57 | The length of my x object is 21 instead of 20.
| | 03:01 | I've actually extended it because
I've added something to the end of it.
| | 03:05 | If I want to add a number of things, I can't do
that with append but I can do it with extend.
| | 03:16 | This 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:27 | So, that range has been appended
to the end using the extend method.
| | 03:33 | If I want to insert something, I can
say x.insert and I can insert at the
| | 03:39 | beginning if I want to and I can put
a 25 there and now we look at x.
| | 03:46 | We've again extended the length of the
array and there is a 25 at the beginning.
| | 03:51 | But I can insert any place I want to.
| | 03:53 | I can say x.insert(12, 100) and
we'll see that I've got 100 there in the
| | 04:02 | middle of the list.
| | 04:05 | Likewise, I can remove it.
| | 04:07 | x.remove(12) and that will
remove the element with the value 12.
| | 04:13 | It actually looks for the
first value of 12 and removes that.
| | 04:18 | If I want to delete the item at index
12 I use the delete operator and say x12 and
| | 04:28 | that will delete that element at index 12.
| | 04:32 | So, we see that 100 that we added
in and we inserted at 12 is now gone.
| | 04:39 | Finally, just like I can insert
things at the beginning or at the end I can
| | 04:44 | pop to remove things.
| | 04:46 | If I just say x.pop, it will give me the value
from the very end of the list and it removes it.
| | 04:54 | So, you see that 19 is now gone. I got it
returned from the pop method and now it's gone.
| | 05:01 | If I want to, I can pop from the
beginning I can say x.pop(0) and that will
| | 05:08 | pop from the beginning.
| | 05:09 | Now, I got that 25 from the beginning
and the list is shorter by 1 and that's
| | 05:14 | been removed from the list.
| | 05:16 | Basically, we can do anything we want
to with these lists, as long as we are
| | 05:21 | using the mutable list object.
| | 05:23 | So, all the power is there. You've got the
equivalents of push and pop and insert and remove.
| | 05:29 | You can remove things based on their
value or based on their index, you can
| | 05:34 | search for things, you can
count the occurrence of things.
| | 05:38 | All of this power is here for both the
tuple and the list, as long as you are not
| | 05:42 | using the things on the tuple that
would modify it. Because you have to remember
| | 05:46 | the tuple is immutable and the list is mutable.
| | Collapse this transcript |
| Organizing data with dictionaries| 00:00 | Dictionaries are Python's version of
associative arrays or hashed arrays.
| | 00:05 | Dictionaries are created in
a couple of different ways.
| | 00:08 | We can create a dictionary with the curly
braces and we can say key value like this.
| | 00:24 | So now, we have a
dictionary with those values in it.
| | 00:27 | Actually, an easier way to create
dictionaries is with its constructor because
| | 00:31 | this allows you to use the named
parameters feature of Python and it's just a
| | 00:36 | whole lot easier to type.
| | 00:37 | So you will see it done this way more often.
| | 00:46 | We get exactly the same result and see
that that type is a class dictionary.
| | 00:54 | Finally, if you want to, you can even
initialize one dictionary from another.
| | 00:59 | If I have another dictionary?
| | 01:11 | And so there I have
that dictionary. I can say d =
| | 01:14 | dictionary and I can take these
definitions from up here, copy those and paste
| | 01:21 | those in, and then I can actually
specify that other dictionary with the two
| | 01:26 | asterisk notation and I get a
dictionary that has all of that in it.
| | 01:31 | You can test if a value is in a
dictionary by saying 'four' in x and I see that
| | 01:39 | that's True and if I say 'three' in x
that will not be true, because x here has
| | 01:46 | just four, five and six in it.
| | 01:48 | Likewise, you can iterate over a dictionary.
| | 01:51 | You can say four k in d:
| | 01:54 | print (k) and that will
print out all of the keys.
| | 01:59 | If you want to, you can say for k key
and value in d.items print k and value.
| | 02:12 | And that will give you both the keys
and the values all in one fell swoop.
| | 02:16 | If you want to find a particular item
in a dictionary, one way to do it is to
| | 02:21 | simply subscript it.
| | 02:25 | The problem with that is that if your
dictionary does not have that key, you
| | 02:29 | will get an exception.
| | 02:30 | If I try x sub 'three', I will get an exception.
| | 02:35 | The way around that is to use the get method.
| | 02:39 | If I say x.get('three'), it will
simply silently give me the none value.
| | 02:46 | If I say d.get('three') then I get the value.
| | 02:52 | Another benefit of this is using the
get method I can give it a default
| | 02:57 | value. I can say give me that value of
three or give me some default value.
| | 03:07 | And I get the default value.
| | 03:08 | Here I typed in the text 'not found'.
| | 03:11 | If I simply want to delete an item from a
dictionary, I can just look at the x here.
| | 03:16 | I've got those items there.
| | 03:18 | I can say del x' sub four' and now that's
gone or I can say x.pop('five') and it will
| | 03:30 | give me the value and
delete it at the same time.
| | 03:34 | So those are the major
functions of dictionaries.
| | 03:35 | Dictionaries are tremendously useful.
| | 03:38 | Whenever you need to organize your
data in such a way that it's easy to find,
| | 03:44 | you can certainly store any kind
of data in a list or in a tuple.
| | 03:48 | But the indexes are always going to be numeric.
| | 03:51 | The advantage of the
dictionaries is that the indexes are data.
| | 03:54 | So you can index it on any kind of data.
| | 03:58 | Usually, you will use text, usually you
will use words, but this allows you to
| | 04:03 | basically create your own
named spaces and organize them.
| | 04:07 | They can be hierarchical.
| | 04:08 | You can store dictionaries within
dictionaries, you can store lists and tuples
| | 04:12 | within dictionaries, and you will find
as you will look through the examples
| | 04:17 | of the code that I have written,
I will often times carry one dictionary in a
| | 04:21 | global namespace and put all of my data
inside of that and then it becomes manageable.
| | 04:27 | It's like a halfway point between
flat data and an object with methods.
| | 04:32 | Obviously, there is going to be
times you are going to want to create an
| | 04:35 | object with methods to handle your
data in very specific ways, but for just
| | 04:39 | organizing a whole lot of global
variables or flags, you will find that
| | 04:43 | dictionaries are very useful and for
organizing object data within an object,
| | 04:49 | you will find that dictionaries are
very, very useful and very, very commonly
| | 04:52 | used in these kinds of situations.
| | Collapse this transcript |
| Operating on character data with bytes and byte arrays| 00:00 | Bytes and bytearrays are like tuples and
lists except instead of containing
| | 00:05 | arbitrary objects, bytes
and bytearrays contain bytes.
| | 00:10 | 8-bit words of data.
| | 00:13 | An 8-bit word of data can hold up to
256 different values and this is sometimes
| | 00:19 | a very convenient thing.
| | 00:21 | In particular, it's convenient for
converting strings and this is where you
| | 00:26 | will see it used often.
| | 00:27 | You will see it used for other binary
things as well but it's often times used
| | 00:31 | for converting strings. And we have
a great example of this right here.
| | 00:37 | This is a text file that I created for
this purpose and when I created it on
| | 00:41 | my Mac, it had this lovely little
pattern of international characters that
| | 00:46 | makes a little picture.
| | 00:47 | It's a little viral thing that had been
floating around on Facebook that I got
| | 00:51 | and I thought it would be great for
illustrating this problem, because there are
| | 00:55 | some circumstances where you cannot
display it and it doesn't look right,
| | 00:59 | or if you try to read it as ASCII data in
Python, you will get an exception error.
| | 01:05 | So I loaded it up on the PC that I am
using here and I saw this and I went oh, drat.
| | 01:11 | It's not pretty.
| | 01:12 | It doesn't look like it, but in fact this
is a great illustration of the problem
| | 01:16 | because this particular system is
not handling the UTF-8 International
| | 01:21 | Characters properly,
whereas my other system was.
| | 01:24 | They are both running the same software.
| | 01:25 | They are both running Eclipse.
| | 01:27 | They are both running the same version
of Python and yet here we are trying to
| | 01:30 | display this file here and it looks
like this, whereas on my Mac, it looked
| | 01:35 | different. And you will see it in a
moment, we'll show you here, because we
| | 01:38 | are going to convert it in a way that
it will display here and we're going to
| | 01:42 | use Python to do this.
| | 01:43 | So this is what the file looks like
here on this PC and if you are using a
| | 01:47 | different operating system and you
actually see the pretty fancy characters,
| | 01:51 | just shh, don't tell anybody and
the example will still work just fine.
| | 01:55 | I'll start by making a working copy
of containers.py and we'll call this
| | 02:02 | containers-working.py and I'll just
close this one and we'll open the working
| | 02:09 | copy and we are going to start by
opening the file. I am going to call this file.
| | 02:14 | fin open and it's called utf8.txt, open
it for read, and we are going to set its
| | 02:24 | encoding as utf_8 and this is the exact
character string that you need to use.
| | 02:34 | This is meaningful inside of Python
and that tells Python that when it's
| | 02:39 | reading this file, that it needs to
read it as UTF-8 and ignore whatever the
| | 02:44 | default encoding is on your system,
which is almost certainly something
| | 02:48 | different than UTF-8.
| | 02:49 | UTF-8 is really, really useful encoding.
| | 02:53 | When the Unicode people came up with
Unicode, it's this double wide character set
| | 02:59 | that doesn't work right in normal
ASCII systems where normal 8-bit wide text
| | 03:03 | context and they tried to get the whole world
to adopt it and the whole world didn't adopt it.
| | 03:09 | So they came up with UTF-8, which
is a version of Unicode that works in
| | 03:14 | an 8-bit encoding scenario.
| | 03:15 | So the first 127 characters of it
works exactly like ASCII does.
| | 03:21 | So you can set your encodings to UTF-8
safely and it will work just fine with
| | 03:27 | normal ASCII code and then it has this
clever system of setting high bits in
| | 03:31 | order to tell the system that it
needs a couple more bytes to represent a
| | 03:35 | particular character.
| | 03:36 | And it all happens kind of
transparently behind the scenes if your system is
| | 03:40 | properly implementing UTF-8. And these days
most web browsers do handle UTF-8, just fine.
| | 03:47 | But a lot of desktop systems don't
and this one here that I am working at
| | 03:51 | obviously doesn't. So we are opening
this file as UTF-8 and we are telling that
| | 03:56 | the encoding is UTF-8 and for it
to ignore its default encoding.
| | 04:00 | I am going to go ahead and open an output file.
| | 04:03 | I am going to call this utf8.html
because we are opening the browser, even
| | 04:11 | though we are not going to
put any actual HTML in it.
| | 04:15 | And we'll open that for write.
| | 04:16 | We are going to setup a bytearray,
we call it outbytes, initialize the
| | 04:22 | bytearray, with the bytearray constructor.
| | 04:27 | And a bytearray is a mutable list of bytes.
| | 04:31 | So it doesn't hold any other kind of
object but bytes and we'll start iterating
| | 04:36 | through the file for line in file in
and then we are going to immediately
| | 04:43 | iterate through the line for character
in line because a string is an iterable
| | 04:50 | object and we are going to use the ord built in.
| | 04:55 | if ord of c, and that gives us the
integral equivalent of that character.
| | 05:01 | Is greater than 127.
| | 05:05 | So there is 128 values in UTF-8 that are
just normal ASCII and they are 0 through 127.
| | 05:12 | So if this one is higher than 127,
we are going to do something special with it.
| | 05:17 | And otherwise, we are just
going to append it to outbytes.
| | 05:21 | We are going to say outbytes.append ord
of c, like that. And then if it is greater
| | 05:31 | than 127, we are going to do
this fancy thing here. outbytes +=.
| | 05:36 | When you use the addition operator
on a mutable container type. It has the
| | 05:43 | same effect as appending, but you can
append more than one element at a time this way.
| | 05:48 | So what I am going to do here is I am
going to create a bytes object and bytes
| | 05:54 | are immutable arrays of bytes
and I am going to encode a string.
| | 06:01 | The constructor of bytes will expect a
string within an encoding and so a string
| | 06:07 | is going to be this XML entity with
the ampersand and the pound. If you are
| | 06:12 | familiar with XML entities, they look
kind of like that, where inside of here
| | 06:17 | you can put a decimal value
| | 06:19 | that will be interpreted as UTF-
16, which is the normal Unicode.
| | 06:24 | So in there I am going to have a format
and I am going to use this format here,
| | 06:29 | 04decimal. I know this is
all looking very complicated.
| | 06:33 | I told you this line is where all the
magic happens. And I am going to use format
| | 06:38 | ord(c) and then the bytes
constructor is going to have an encoding, that
| | 06:45 | encoding is UTF-8, because we use
UTF-8 for everything wherever we can.
| | 06:51 | So now what we have done is, if the
character is outside of the normal ASCII range,
| | 06:56 | we are going to encode it with
this XML entity which can be used in an
| | 07:02 | HTML context and that will allow us
to display our fancy little picture.
| | 07:06 | Otherwise, if it's not greater than 127,
if it's in the normal ASCII range, we
| | 07:12 | just append it to our outbyte.
| | 07:13 | So now we have an outbytes bytearray
which has all of the characters for our
| | 07:20 | string and now what we need to
do is to turn it in to a string.
| | 07:23 | We'll call it outstring and we'll
use this string constructor and we'll
| | 07:28 | construct it out of outbytes and guess what?
We are going to use encoding = 'utf_8'.
| | 07:37 | Now all we need to do is to print it
to our outfile, print (outstr,file =
| | 07:43 | fout), and we'll print it also to the
screen here so we can see it, and we'll
| | 07:51 | print the word Done.
| | 07:54 | So this will read our UTF-8 text from
our file that we are not able to read on
| | 08:00 | this system, go ahead and
save this so no catastrophe happens.
| | 08:04 | This will read our UTF-8 text file and
it'll read it with the UTF-8 encoding and
| | 08:09 | it will write it out to our UTF-8
HTML file, and for the characters that are
| | 08:16 | outside of the normal ASCII range,
it's going to replace them with an XML entity
| | 08:21 | and that's really all that we are doing here.
| | 08:23 | So we saved it, we are going to run it,
and it looks like I have got a typo some
| | 08:29 | place here. Yes, right there.
| | 08:34 | I needed an S. That's all right.
Save that and we'll run it and there we
| | 08:39 | have our fancy string.
| | 08:41 | So this stuff here got converted to UTF-
16 and these are the Unicode values for
| | 08:51 | each of those fancy characters and now
if we refresh our file system because
| | 08:56 | Eclipse doesn't like to do that for us
and we open this up in the little browser
| | 09:01 | inside of Eclipse, there is our fancy
little picture. And so this is what it
| | 09:06 | looked like in the text file.
| | 09:07 | This UTF-8 file has some interesting
characters in it and so we weren't able to
| | 09:12 | see that on this system and by encoding
them with the Unicode XML entities,
| | 09:19 | we are able to see it and there we have it.
| | 09:23 | So the way that we did
this is by using a bytearray.
| | 09:28 | The beauty of a bytearray is that you
can operate on character data because
| | 09:33 | characters are bytes and a bytearray is
mutable, so you can insert things,
| | 09:38 | you can change it up and all we did here
we basically used it as an accumulator.
| | 09:43 | As we went through the string with the
bad data in it, if we found an element
| | 09:48 | that we needed to operate on,
we pushed all of these characters onto the
| | 09:52 | bytearray, using the bytes constructor
and appending them to our outbytes which
| | 09:58 | is a bytearray. Otherwise we just
appended the regular character. If it was
| | 10:02 | within the range we just
appended the regular character.
| | 10:05 | So these characters here just got
appended in the normal way, but these
| | 10:09 | characters, we ended up using these
XML entities which represent the Unicode
| | 10:16 | characters and we got our little
fancy guy to display just the way that we
| | 10:20 | needed him to display.
| | 10:22 | So that is a very common use of bytearrays.
| | 10:25 | Bytearrays are a very
effective way to do things like this.
| | 10:28 | You will see an example very much like
this one in our example code later on
| | 10:33 | in the course.
| | Collapse this transcript |
|
|
15. File I/OOpening files| 00:00 | Python has some very simple built-
in functions for dealing with files.
| | 00:04 | Let's make a working copy of files.py.
| | 00:07 | I'll call it files-working.py and we
will open that working file and we see here
| | 00:14 | a simple loop that reads lines
from a file and prints them out.
| | 00:19 | So run that and see what it does.
| | 00:21 | It prints out the lines of this file.
This is the file here, lines.txt, and we
| | 00:25 | are just printing out all five lines
with that file in this little loop.
| | 00:29 | What we are going to look at in
this movie is this open function.
| | 00:32 | It's very simple and it has a few options.
| | 00:36 | By default, all it does is it opens the
files in the read mode and you give it a
| | 00:41 | file name here and it returns the file
handle object, which can then be used to
| | 00:46 | operate on the file.
| | 00:48 | If you don't specify it, read mode is
the default and that looks like this.
| | 00:53 | There is the second argument, which
is the mode, and that defaults to the
| | 00:57 | r character for read.
| | 00:59 | Options there are r for read,
w for write, or a for append.
| | 01:06 | Append is a special write mode.
| | 01:07 | It sets the current position of the
file to the end of the file so that
| | 01:11 | everything that you write
will get appended to the file.
| | 01:15 | In read mode, you can optionally give
it a plus sign, which will open it for both
| | 01:19 | read and write in the same file handle object.
| | 01:23 | You can also give it a t for text file
mode or a b for binary mode, and we will
| | 01:29 | look at these options a little
later in our movie on the subject.
| | 01:33 | The open function returns this file
handle object, which we see used here.
| | 01:39 | It is an iterable object and in
iteration mode it simply gives you one line
| | 01:44 | of the file at a time.
| | 01:45 | In fact, there is a method called read
lines, which does exactly the same thing.
| | 01:51 | You save that and run it,
and there is our lines of text.
| | 01:55 | So that is the open
function in all of its simplicity.
| | 01:59 | In the rest of this chapter we will
look at how to read and write files and how
| | 02:02 | to set its file mode.
| | Collapse this transcript |
| Reading and writing text files| 00:00 | Reading and writing text files
in Python is really very simple.
| | 00:04 | Let's make a working copy of
files.py. files-working.py.
| | 00:10 | Open that working copy and we see that
we have the simple loop here that reads
| | 00:15 | lines of a file and prints them to the screen.
| | 00:17 | So if we run that, we see there is our
lines of file, print it to the screen, and
| | 00:22 | here is our input file.
| | 00:24 | So, we can see that that's exactly the same.
| | 00:26 | Now, if we wanted to, instead of
bringing that to the screen, if we wanted to
| | 00:30 | write it to a file, we could do that.
| | 00:32 | Simply change this to infile, so we can
have a separate one for outfile, outfile
| | 00:39 | equals open and we'll call this new.txt.
| | 00:42 | We will open that for write.
| | 00:45 | And we will open this one here for read.
| | 00:47 | It defaults to read but if I am going
to specify write, then I am going to want
| | 00:50 | to also specify read.
| | 00:53 | This is called infile, and all we have
to do here is to say file equals outfile,
| | 01:00 | And now that print is going to print
the outfile instead of to the screen.
| | 01:05 | And as we don't have anything coming to the
screen, I am just going to print done here.
| | 01:09 | So we know that we have gotten to this point.
| | 01:12 | We get some feedback on the screen.
| | 01:14 | I will save that and I
will run it and it says done.
| | 01:18 | If I refresh the file system here,
which Eclipse does not do by itself, you can
| | 01:23 | see there is a new.txt and it's
got our five lines of text in it.
| | 01:27 | So that is just a very simple
way to write to a text file.
| | 01:32 | Obviously, it doesn't have to be
something you are reading from another text file.
| | 01:36 | You can generate your own whatever and
write it out to a text file very easily,
| | 01:40 | using print and the File parameter for print.
| | 01:44 | Let's say that what we are doing
is not necessarily line oriented.
| | 01:47 | Let's say that maybe we have a very
large file with thousands of lines of text,
| | 01:51 | And we don't really need to read
them and write them line by line.
| | 01:53 | We want to do it in some bigger chunks.
| | 01:56 | So I have a file here called bigfile.txt and
you will notice it is a really big file of text.
| | 02:01 | It has 10,000 lines of text in it.
| | 02:06 | If we look at the properties, we can
see that it's 320,000 bytes. It's 300k.
| | 02:12 | So, let's go ahead and open that one
instead, and call it bigfile.txt and we
| | 02:21 | are going to read this in what's called
buffered mode, instead of doing it line by line.
| | 02:24 | We will set a buffer size and I will
say that's going to be 50,000 bytes.
| | 02:31 | It's 300,000 bytes, so it will give us
a few chunks and then we are going to
| | 02:36 | start by filling our buffer, infile.read
and buffersize and then instead of this
| | 02:46 | here, I am going to use a While loop,
because the Read method on the file handle
| | 02:51 | object is not an iterable.
| | 02:53 | So we can't use a For loop, so
we are going to use a While loop.
| | 02:55 | We are going to say while the length of buffer.
| | 02:59 | And so as long as our buffer is not
empty then we will outfile.write buffer.
| | 03:06 | That's really all there is to it.
| | 03:08 | We read it again in the loop, so that we
are not just writing the same buffer forever.
| | 03:12 | So I am going to write buffer =
infile.read buffersize and after we do the
| | 03:20 | write, let's just print a dot to the
screen, so we have some feedback that we
| | 03:23 | are doing something, dot, end, equals nothing.
| | 03:29 | So this will just print dots on the screen
right next to each other, and we are all done.
| | 03:33 | Before the Done, we are going
to want to print a blank line.
| | 03:37 | So we will go ahead and save that and run it
and we see we have got a handful of dots there.
| | 03:43 | It means that we have written something
and we refresh our file system and take
| | 03:49 | a look at the properties of
new.txt and it's exactly 320,000 bytes.
| | 03:54 | We will open that up and there is
all of our lines of text in there.
| | 03:58 | So what we have done here is we
simply read it in a few big chunks and
| | 04:02 | obviously 50,000 bytes is
very small by today's standard.
| | 04:06 | Your buffers can be bigger than that
or if you are on a mobile device or
| | 04:09 | something small, maybe
you do want them that small.
| | 04:12 | We just did that this way for
illustration, but this shows you how you can read
| | 04:17 | and write in buffered I/O mode.
| | 04:19 | So it allows you to deal with bigger
chunks of files than just line by line.
| | 04:25 | So that's how simple it is to read and
write text files in Python and we will
| | 04:29 | discuss reading and writing
binary files in a separate lesson.
| | Collapse this transcript |
| Reading and writing binary files| 00:00 | Python makes a distinction
between text files and binary files.
| | 00:04 | Even on operating systems with
file systems that don't make that
| | 00:07 | distinction, Python still does.
| | 00:10 | So how you read and write binary files,
even though it's still very simple, is
| | 00:15 | different in significant ways from
how you read and write text files.
| | 00:19 | So let's make a working copy
of files.py. files-working.py.
| | 00:27 | Open that working file and we see we
have our little loop here that reads
| | 00:31 | lines of text and prints them to the
screen, and let's just go ahead and take
| | 00:35 | this out and put in olives.jpg and we
will save that and run it, and we will
| | 00:45 | see that we get this UnicodeDecodeError
because Python is trying to decode the
| | 00:51 | text in that JPEG file.
| | 00:54 | That's a JPEG file.
| | 00:55 | If we open that up, we will see there
is an image of some grapes on a vine
| | 00:59 | there, and that it not a text file at all.
| | 01:02 | So what we need to do is we
need to open this in binary mode.
| | 01:05 | So we are going to open it
in Read Binary, like that.
| | 01:09 | And now if we save this and run it,
we are going to get this output, which is
| | 01:15 | still not really what we want.
| | 01:18 | What's happening is that the Print
function is trying to print that in a way
| | 01:22 | that's text readable, and we are not
going to want to write that to a file if we
| | 01:25 | are making a copy of this.
| | 01:27 | So what we need to do is we need to
open an output file in binary mode and we
| | 01:31 | need to use our buffered I/O. So we
will call this infile, and we will open an
| | 01:36 | outfile, and call that new.jpg.
| | 01:42 | Open that in write binary mode, and
we are going to do a buffered I/O here.
| | 01:48 | So we will start by
giving ourselves a buffersize.
| | 01:52 | Let's see, how big is this file?
| | 01:57 | Properties, it's 142K.
| | 02:01 | So we will just go ahead and make our
buffersize 50000, and that will work fine.
| | 02:05 | And the rest of it is very similar to
how we would do this with the text file,
| | 02:13 | infile.read(buffersize) and infile.read
is not an iterable, so we have to use a
| | 02:22 | while loop, length of buffer, and
we will outfile.write from our buffer.
| | 02:32 | And we would go ahead and print a dot.
| | 02:36 | So we see that something is happening
on the screen and we will read the next buffer.
| | 02:44 | When we are all done, we will print
a blank line and we will print the word Done.
| | 02:53 | You can see that we are done.
| | 02:56 | So what's different here is that by
opening the file in binary mode, we are no
| | 03:01 | longer dealing with text.
| | 03:03 | The rest of it looks pretty much the
same as how we do the buffered reading and
| | 03:07 | writing with a text file, but the
difference here is that we are not working
| | 03:10 | with text at all. This
buffer is now a binary object.
| | 03:14 | It's not a text object at all.
| | 03:16 | We will go ahead and we will save this
and we will run it and we have got a
| | 03:21 | few little dots there.
| | 03:22 | And if we refresh our file system, which
Eclipse does not do for us, we have this new.jpg.
| | 03:28 | I open that up.
| | 03:29 | There is our JPEG intact.
| | 03:31 | So we know that copy worked.
| | 03:33 | I will look at the size of it.
| | 03:35 | It's the right number of bytes, 142309.
| | 03:39 | Is that the same as our olives?
| | 03:42 | It is exactly the same.
| | 03:44 | So we have an exact duplicate of that file.
| | 03:47 | So reading and writing binary files,
the methodology is very similar, except
| | 03:52 | you have to use the buffered I/O.
You are not going to want to use line
| | 03:55 | oriented I/O for a binary file.
| | 03:58 | And most of the time for text files,
you are going to use line oriented I/O,
| | 04:02 | although you can use
buffered I/O for text files as well.
| | 04:04 | As a matter of fact, you can use binary
mode for text files if you want to, and
| | 04:08 | deal with them as bytes,
and that will certainly work.
| | 04:11 | But the distinction here is that
with binary files, you have to use the
| | 04:15 | buffered I/O and you have
to use binary data types.
| | 04:19 | So when you read that file, it's going
to read it as an array of bytes and it's
| | 04:24 | not going to read it as text.
| | 04:26 | So this is how you do buffered
I/O with binary files in Python.
| | 04:30 | And it's really very simple and it's
something that you are going to use now and
| | 04:33 | then as you are dealing with binary files.
| | 04:36 | One final note. You will notice
that the buffered read method is not an
| | 04:41 | utterable. If I was going to be doing
this a lot, I would go ahead and I would
| | 04:45 | write a method for an object that is iterable.
| | 04:48 | That would make this easier for me to do.
| | 04:51 | It's certainly a matter of style.
| | 04:52 | It's something that you might think
about doing if you are going to be doing
| | 04:55 | this a lot, and there is an example of
how to make a generator function that
| | 04:59 | generates an iterable in both the Functions
chapter and the Classes chapter in this course.
| | 05:05 | So that's how you do buffered
I/O on binary files in Python.
| | Collapse this transcript |
|
|
16. DatabasesCreating a database with SQLite 3| 00:00 | There are many database
choices available for Python.
| | 00:02 | For our purposes, we're going to be
using SQLite3 for a number of reasons.
| | 00:07 | First of all, SQLite3 comes with Python.
| | 00:10 | If you have Python installed and
you're watching this course, then you have
| | 00:13 | SQLite3 and that makes it easy
for us for the purposes of teaching.
| | 00:17 | SQLite3 is a perfect choice
for a lot of applications.
| | 00:21 | For most of the web site work that I do
these days, I'm using SQLite3 instead of
| | 00:26 | MySQL which I might have used a few years ago.
| | 00:28 | It's reliable, it's simple, it doesn't
require a separate database engine,
| | 00:32 | it's self-contained, server less, zero
configuration and fully transactional.
| | 00:37 | It's a fully capable database
engine in a driver and that makes it just
| | 00:41 | incredibly easy to use.
| | 00:43 | For our purposes, having something
that's simple like this allows me to show
| | 00:47 | you how databases work with Python
without having to mess with the database a
| | 00:52 | whole lot and spend our time in the Python.
| | 00:54 | So, I'm going to go ahead and start by
making a working copy of databases.py.
| | 00:59 | Call it databases-working.py.
Go ahead and load that up.
| | 01:03 | You see our first line here says
import sqlite3 and that simply imports the
| | 01:08 | Python Library that supports SQLite3.
| | 01:11 | And then here all we do is we say db
= SQLite3.connect and the name of the file, test.db.
| | 01:21 | And we save this and run it
and we have created a database.
| | 01:26 | We'll go ahead and refresh this file
system here because Eclipse doesn't do that
| | 01:30 | for us and you see that we now have
empty file and we've created our database.
| | 01:34 | So, we'll go ahead and populate the
database and that's also very simple.
| | 01:38 | We simply say db.execute and I'm
going to give it some SQL here and say drop
| | 01:45 | table if exists so that we can create a
new table each time and call the table test.
| | 01:51 | And then db.execute, create table
tees, and give it a couple of fields.
| | 01:59 | t1, it's a text field and i1 is an int
and I've created a table inside my database.
| | 02:06 | Now I'll just insert a little bit of
data. db.execute insert into test (t1, i1,
| | 02:16 | values (?, ?) and these are
placeholders and that allows us to give it a
| | 02:22 | tuple with the values one and 1.
| | 02:27 | And I'll just make a few of
these. Two and give that a 2.
| | 02:34 | And a 3 and a 4.
| | 02:36 | And 4 and a three and
we have now inserted some data into our database.
| | 02:44 | So this is all done with SQL and
we'll say db.commit() because SQLite is a
| | 02:50 | transactional database.
| | 02:51 | It will buffer these values, in
case you're going to be using it in
| | 02:55 | a transactional mode.
| | 02:56 | And then I say cursor = db.execute
and select star from test order by t1.
| | 03:05 | Again, standard SQL
for row in cursor: print(row).
| | 03:12 | So, now, I've inserted some data into
the database and I'm going to print that
| | 03:16 | data out from the database.
| | 03:17 | Save it and run it and there we have it.
| | 03:21 | There's our four records and they're
sorted by the t1 field ,which is our text
| | 03:26 | field, and that's getting read from the database.
| | 03:28 | So, that's all there is to it.
| | 03:30 | Using SQLite in Python is incredibly simple.
| | 03:34 | Our first line here connects to the
database and that actually creates the file
| | 03:38 | if the file didn't already exist.
| | 03:40 | And then, from there on, we're using
db.execute because db is the database
| | 03:45 | object that we got back from the
connect statement and we simply interact with
| | 03:49 | the database using SQL.
| | 03:51 | Be sure to do a commit after you change
any data in the database and then we can
| | 03:57 | do a select and use the cursor object
that's returned by db.execute and simply
| | 04:03 | step through the cursor object
as an iterator and print the data.
| | 04:07 | The data comes back, you'll notice, in
tuples and they're in the order that you
| | 04:12 | specify things in your SQL.
| | 04:14 | So, if I want it in the i1 first
followed by t1, I simply change my SQL so that
| | 04:20 | specifies an order, because the order
that was in was the order that we define
| | 04:24 | them in the create table text and then int.
| | 04:26 | So, if I want int and then text,
I simply change in my SQL and it'll come back
| | 04:31 | in that order and obviously if I want
to order it by the integer instead of
| | 04:34 | by the text, I simply change my SQL
and it comes ordered by the integer
| | 04:39 | instead of by the text.
| | 04:40 | There's one more thing I'd like to show
you in this context and that is the row
| | 04:45 | factory that comes with SQLite.
| | 04:46 | The SQLite interface is actually
incredibly rich and very full featured in
| | 04:52 | Python and there is a lot of options
and a lot of methods that you can override
| | 04:59 | and a tremendous amount of power
there for working with databases.
| | 05:03 | We are going to keep it simple for our
purposes here but there is one thing that
| | 05:06 | I want to show you and that's
what's called a row factory.
| | 05:08 | We'll say db.row_factory = sqlite3.Row.
| | 05:16 | So, what the row factory does is it
allows you to specify how rows will be
| | 05:23 | returned from the cursor and the
built-in row factory that's provided,
| | 05:27 | sqlite3.Row, is very powerful and
very suitable for most purposes.
| | 05:33 | So, when I save this and run it, you'll
notice the only change I made was to add
| | 05:37 | that row factory there after the connect.
| | 05:40 | You'll notice now we get row objects
instead of those tuples and the row objects
| | 05:46 | can be looked at as tuples if we'd like
or it can be looked at as dictionaries,
| | 05:52 | which I find particularly useful.
| | 05:55 | So, if I say dictionary like that, I'm
creating a dictionary object based on a
| | 06:01 | iterable because row is an iterable.
| | 06:04 | So, if I save this and run it, now I
get dictionary objects and so they
| | 06:09 | are completely indexed.
| | 06:11 | If I want to, I can say, rows
up t1 and I'll get my t1 objects.
| | 06:18 | I can say row.t1, row.i1 and get
all the data. Save that and run it.
| | 06:26 | The built-in row factory
from SQLite is very flexible.
| | 06:30 | I tend to use it in the dictionary mode
because I find that very convenient, but
| | 06:33 | it has a lot of other options and
they're all documented on the SQLite3 page in
| | 06:38 | the Python documentation.
| | 06:40 | So, as you can see, accessing a
database from Python is very simple.
| | 06:45 | Most databases have an
interface very similar to this one.
| | 06:48 | For most simple database applications,
SQLite3 is going to be a great choice and
| | 06:53 | you can see that it's
very simple to use in Python.
| | Collapse this transcript |
| Creating, retrieving, updating, and deleting records| 00:00 | The basic four functions of a database
are considered create, retrieve, update
| | 00:06 | and delete, which
conveniently spells the word CRUD.
| | 00:09 | In the Exercise Files, you'll
notice file called sqlite3-crud.py.
| | 00:15 | We're going to use that
as a starting point here.
| | 00:16 | So we'll just make a working
copy of it and we'll call it
| | 00:19 | sqlite3-crud-working.py. If you like,
you can name it something simpler and
| | 00:27 | we'll open that up and you'll notice
that this is a rather complete file.
| | 00:33 | Rather than type all this stuff,
I just give it to you and we'll take a tour
| | 00:38 | of it and we'll see how it works.
| | 00:39 | You'll notice that at the top of the
file here in imports sqlite3 and down here
| | 00:45 | we have the main function.
| | 00:46 | Normally I would put this at the top,
but really the object of our exercise here
| | 00:51 | is those functions at the top.
| | 00:53 | So, we'll get to those in a moment
and you'll notice a few little print
| | 00:56 | statements here as comments.
| | 00:57 | So, we create the table and it's
called test and this is the same as in the
| | 01:02 | creating a database lesson.
| | 01:04 | You'll notice that we also have our
row factory in here and that's also
| | 01:08 | described in the creating a database
lesson, and then we create the rows and
| | 01:12 | we're using this insert
function that's defined above.
| | 01:14 | I don't call it create because I think
of create as being creating the table or
| | 01:17 | creating the database.
| | 01:18 | I call it insert. CRUD doesn't work
as well if there is an I instead of the C,
| | 01:23 | but this works for me to call it
insert and actually it matches the
| | 01:27 | corresponding SQL also, which is insert.
And then we retrieve a row based on a key.
| | 01:32 | There's the key and there is the key,
we update rows and changing their values
| | 01:37 | and we delete rows and if we run this,
go ahead and run it, it creates a table,
| | 01:44 | it creates rows and then it shows them
to you and it retrieves rows and it
| | 01:48 | retrieves them based on those keys and
there is the dictionary objects and it
| | 01:52 | updates rows, and there it changed these
two, and it deletes rows and this is all
| | 01:58 | that's left after it's deleted them.
| | 01:59 | So, this just shows us that it's
working and now we can look at exactly how
| | 02:03 | all this stuff works.
| | 02:05 | When you're building a specific
application and your specific application has
| | 02:09 | specific database tables and specific
schemas, a lot of times it's convenient
| | 02:14 | to create specific functionality in
your program that deals with those objects
| | 02:20 | and normally you're going to do it in
an object-oriented method and we'll look
| | 02:23 | at that in another lesson in this
chapter, but for now, here's how you can do
| | 02:28 | it in a simple way.
| | 02:29 | I would not write production code this way.
| | 02:32 | There's no error checking. Using
functions I'm passing the database handle around.
| | 02:37 | The way I would create
actual applications is going to be in more
| | 02:41 | object-oriented manner.
We'll look at that in another lesson.
| | 02:43 | For now, our purpose here is just to
look at how can we do these individual
| | 02:47 | tasks in very simple way. And so, for
the insert function, I simply pass it a
| | 02:53 | dictionary and the dictionary has the
data that's going to be inserted and then
| | 02:57 | up here we can use this little outline
feature in the Eclipse workflow and I
| | 03:03 | look at the insert function.
And you'll see it takes that row which is a
| | 03:07 | dictionary object and it passes the
individual elements into the placeholders in
| | 03:14 | the SQLite3 execute method.
| | 03:17 | So, the execute method takes as its
first argument a string of SQL and in
| | 03:22 | that argument you can put in placeholders and
there's actually a couple of ways to do that.
| | 03:25 | I'm showing you the simple way here
with the question mark and these are
| | 03:28 | positional and then it takes a list as
the second argument and so this has to
| | 03:33 | be a list or a tuple. In this case a
tuple, and so it need to be as one argument
| | 03:38 | which is why we're passing it a tuple
with parentheses around it so that it's
| | 03:41 | grouped as one argument and then that
has positional ordered parameters.
| | 03:46 | The first one is going to correspond with
the first question mark and the second one
| | 03:50 | is going to correspond with the second
question mark and each of these is simply
| | 03:54 | dereferencing the dictionary
object that's passed into the function.
| | 03:57 | So, this very simple.
| | 03:59 | in the main, all we need to do is we
call it like this, insert and the first
| | 04:03 | parameter here is DB, which is the
database object, so that the insert function
| | 04:07 | can access the database and the second
parameter is this dictionary object and
| | 04:12 | obviously, in your code, you
could create that separately.
| | 04:15 | It could be derived from all sorts of
sources and for our purposes, we're simply
| | 04:19 | creating the dictionary object on the fly here.
| | 04:21 | And so we call that four times and
that inserts the data and we'll see that
| | 04:25 | right here at the top of
our results, Create rows.
| | 04:28 | Notice that I have this little display
rows function and that looks like this.
| | 04:33 | It basically executes a select and it
prints out the results from the dictionary
| | 04:38 | object, because we're using the row factory.
| | 04:40 | So, that's our insert function.
| | 04:42 | Our retrieve function is like this.
| | 04:44 | It simply passes a key and it gets a
row object in return and so it prints that
| | 04:50 | out as a dictionary and so that
looks like this here in our results.
| | 04:54 | These are the dictionary objects that are
returned by those two calls to retrieve.
| | 04:58 | So, retrieve is really just this part
here and when we look at it up in our code,
| | 05:03 | it takes a key and I'm calling
that key t1, I could just name it key if I
| | 05:07 | want and it calls execute with this SQL,
which is basically select an entire row
| | 05:13 | from the test table where t1 equals
question mark, and then it passes this one
| | 05:18 | positional argument out.
| | 05:19 | Now this has to be a list or a tuple,
and so I create a tuple here and remember
| | 05:24 | it's the comma that creates a tuple.
| | 05:26 | It is not the parentheses.
| | 05:28 | The parentheses are just for grouping.
| | 05:30 | So, if you want a tuple with one element,
it needs to be like this parentheses
| | 05:35 | and then the object and then a comma and
then the closed parentheses and this is
| | 05:39 | a case where I need a tuple with just one object.
| | 05:42 | It calls db.execute with this SQL and
that returns a cursor and then I use the
| | 05:47 | cursor with the fetchone method in the
cursor object from SQLite3, and that'll
| | 05:53 | simply fetch one result because
that's what I'm asking for with this
| | 05:57 | particular retrieve.
| | 05:58 | Obviously, if you want a method that
retrieves more than one object, you can
| | 06:01 | do that and we'll look at an example of that
in the database object lesson in this chapter.
| | 06:06 | Now, returning to our main function,
we update rows and it's really very
| | 06:09 | similar. We're passing a dictionary
to an update function and the update
| | 06:13 | function simply has an execute
statement with the SQL here, update test, set
| | 06:19 | this value, set that value and it passes
it a tuple with those elements from the
| | 06:24 | dictionary that we're passing here.
| | 06:26 | You see the pattern here?
| | 06:27 | Delete works the same way.
| | 06:29 | It gets a key and it has the SQL.
| | 06:32 | It says delete from test where t1
equals question mark and then it's this one
| | 06:37 | element tuple and it calls commit.
| | 06:39 | We have to call commit every time we do
anything that can change the database.
| | 06:44 | So, for update, we call commit, for
delete, we call commit and also for insert
| | 06:49 | we're calling commit and so there is
our retrieve. There is our update and
| | 06:55 | after update, we display the rows and
after delete, we display the rows and
| | 06:58 | there is our result, update, change
those two, and there they are changing the
| | 07:03 | two up here and Delete rows, we're
deleting two rows, we delete one and we
| | 07:09 | delete three with these keys and
all we have left is two and four.
| | 07:13 | So, those are the major
four functions of a database.
| | 07:17 | Insert, retrieve, update and delete
and you can see with SQLite and Python,
| | 07:23 | it's incredibly simple.
| | 07:24 | It's really just passing the SQL and
getting the right parameters into the
| | 07:29 | SQL and it just works.
| | Collapse this transcript |
| Creating a database object| 00:00 | When you are writing an application
that uses a database, sometimes it's a good
| | 00:03 | idea to create a class that
handles that particular schema.
| | 00:07 | Let's take a look at an example
of how you can do that in Python.
| | 00:11 | We'll start by making a working copy
of sqlite3-class.py, and we will call it
| | 00:16 | sqlite3-class-working.py, and we'll
go ahead and open up that working copy.
| | 00:23 | And here we have a complete working
example of a class. It's very simple.
| | 00:28 | It's just a few lines of code, and
how we access that class through this interface.
| | 00:33 | We'll go ahead and run it and you can see what it does.
| | 00:38 | This is just an example of testing
this particular class, so it creates a table
| | 00:43 | test and it creates some
rows and retrieves the rows.
| | 00:46 | It tests these four
functions of the database.
| | 00:49 | So if we look at our interface,
we create our object by passing in a file name
| | 00:54 | and a table name, and that
will actually initialize the database.
| | 00:58 | And then we create the table using some sql.
| | 01:02 | Then we insert some rows
using dictionary objects.
| | 01:06 | Then we retrieve rows, just using
keys, and it will retrieve dictionary objects.
| | 01:11 | And retrieve test,
there is our dictionary objects.
| | 01:15 | We update a couple of rows, again,
using dictionary objects, and there they are.
| | 01:20 | These dictionary objects could instead
be specific classes that you've created
| | 01:24 | for your database application.
| | 01:26 | And we delete rows with keys.
And you'll notice that every time we do one of
| | 01:30 | these operations, we're printing
out all the rows in a database using the
| | 01:35 | database handle itself as an iterator.
| | 01:37 | So this is a nice little convenient interface.
| | 01:40 | First of all, the constructor
takes these two arguments as named arguments
| | 01:44 | using the kwargs pattern.
| | 01:47 | And the first one is the filename
and it assigns it to a filename property.
| | 01:53 | And the second one is the table
and it assigns it to a table property.
| | 01:56 | And you'll notice that these do
not have underscores, because these are meant to
| | 01:59 | be accessible to the outside world.
| | 02:02 | Down here, I use the property
decorator to allow the filename to be assigned
| | 02:07 | like that, and when it gets assigned
it actually connects to the database and it
| | 02:12 | sets up the row_factory.
| | 02:14 | And when you delete the file name,
it actually closes the database.
| | 02:19 | And so this allows you to use this
kind of a pattern for assigning the filename,
| | 02:24 | and you can even do this on the
object level, using the object, and it will go
| | 02:28 | ahead and initialize the database like that.
| | 02:31 | Likewise, with the table, it sets
the table name and that one is just really
| | 02:38 | simply setting this _table
variable, and if you delete it, it defaults
| | 02:43 | to test, so that there is always a
table name. Because it will kind of break the
| | 02:48 | code here if there isn't a table name,
if the table name is blank, and you'll
| | 02:52 | see that as we go through.
| | 02:54 | So the insert function is very simple,
and you'll notice it goes off the end
| | 02:58 | of the screen here.
| | 02:59 | So I'll just go ahead and reformat that.
| | 03:02 | So the sql, insert into it,
and you'll notice that we have to use a
| | 03:07 | replacement in the string using format,
because the question mark pattern
| | 03:12 | doesn't work for the table name.
| | 03:15 | That's true across the board in
every database entry that I have ever used.
| | 03:19 | If you want to use the positional
parameters, you cannot do that for the table name,
| | 03:23 | and so I allow the table name
to be set using the format here and it uses
| | 03:28 | the underscore table.
| | 03:30 | And then, the row is passed in as a
dictionary object and here we make a tuple
| | 03:35 | out of the two parameters that we
are inserting, the values t1 and i1, and they
| | 03:40 | are positional like that in order.
| | 03:42 | So insert looks like that.
Retrieve looks like this.
| | 03:45 | It returns a dictionary object
using the fetch 1 method of the database cursor
| | 03:51 | and the sql is just a simple
select * from the table name.
| | 03:57 | We are replacing the table name
using format and we are using positional
| | 04:00 | arguments over here for the key,
and again, this is single element tuple and
| | 04:04 | so it has to have that comma. Because
the comma is what creates the tuple, not the parenthesis.
| | 04:09 | Update, it takes a row as a dictionary
object and it passes the menu using that
| | 04:15 | tuple, and the same pattern here.
| | 04:18 | We're replacing the table name using
the string format method, and delete uses a key
| | 04:24 | and there is the single element
tuple there, and all of these methods that
| | 04:30 | change the database, they all have this db.commit.
| | 04:33 | There is a display rows method
that we are not actually using, which does
| | 04:37 | what we were doing in our other examples.
It simply prints them out using a print function.
| | 04:42 | But here is how we are looking at the data
in this example. We are using this iter method.
| | 04:47 | That's a special method in Python.
| | 04:49 | If you put this in your class,
it allows your object to be used as an iterator.
| | 04:54 | So it has two underscores __iter__
for its name, and other than that, it works
| | 05:01 | just like any method.
| | 05:02 | And it's a generator because it uses
yield, and this allows it to operate as an iterator.
| | 05:09 | So it simply yields a dictionary of
the row, and that allows us to call it like
| | 05:13 | this, for row in db:print(row),
and we get these results.
| | 05:18 | So we'll go ahead and we'll save this
and we'll run it again, and we see there
| | 05:23 | we have our results.
| | 05:26 | Finally, it's worth noting that because
of this pattern down here at the bottom,
| | 05:30 | if __name__="__main__": main(),
| | 05:33 | this entire file will
work just fine as a module in Python.
| | 05:39 | You could simply say import
sqlite3-class-working and you would have access to
| | 05:45 | this class and be able
to use this in another file.
| | 05:50 | And this main function down here will
be completely ignored, because when you
| | 05:55 | import it that way, this is no longer
true and so main will not be called.
| | 06:01 | So it's a useful pattern to be able
to write a module like this and to have a
| | 06:06 | class that you are going to use throughout
a project or even to distribute it to the world.
| | 06:10 | And to test it using a main function
that is really just there for testing purposes.
| | 06:17 | So this is a useful pattern and
it's one that you'll probably use.
| | 06:21 | Here we have a custom class for working
with a specific database, and a lot
| | 06:28 | of different techniques that you can
use in building a class like that for yourself.
| | 06:32 | It does the major four functions
and it does a couple of other things.
| | 06:36 | The object itself is useable as an
iterator, because we included an iterator method.
| | 06:42 | It uses properties for setting the filename
that make it easy to change files if you want to.
| | 06:49 | So here we have an example of how you
can create a custom class for your own
| | 06:53 | database schema, for your own project,
using Python's object-oriented features
| | 06:57 | to make your programming task a lot easier.
| | Collapse this transcript |
|
|
17. ModulesUsing standard library modules| 00:00 | The Python standard library has a
number of modules that you can import into
| | 00:04 | your programs and use for your own purposes.
| | 00:07 | This page has a list of them starting
here in section 7, under String Services.
| | 00:13 | And you'll see that there
are quite a few of them.
| | 00:16 | So we're going to just go through a
few of these, a few of the more common
| | 00:20 | ones and show you as an
example how you can use them.
| | 00:23 | And I suggest that you go through this list
at least once and just look out what they are.
| | 00:30 | And just look at their descriptions.
| | 00:31 | Just read through the list, so you
have an idea of the kinds of things that
| | 00:34 | are available to you.
| | 00:36 | So here in Eclipse, we're going to
make a working copy of modules.py.
| | 00:41 | Call this modules-working.py,
and we'll open that up.
| | 00:47 | You'll notice that here we're importing
sys, and here on the web page you'll see
| | 00:53 | sys is for system-specific
parameters and functions.
| | 00:58 | If we open that page, you'll see that
there's full documentation on all of the
| | 01:04 | things that you can do with sys.
| | 01:06 | So, one of these is to get the Python version.
| | 01:09 | This is with sys version info.
| | 01:11 | And so if we run this, you'll see that
we say, this is Python version 3.1.2.
| | 01:20 | You can also get the system platform.
| | 01:23 | You can say print(sys.platform) and
if we save that and run it, you'll see
| | 01:31 | that this is win32.
| | 01:33 | On my Mac at home it says Darwin and
whatever operating system you're running Python on,
| | 01:39 | it will give you an idea.
| | 01:41 | And this is a category of operating system.
| | 01:43 | It's not actually the operating system.
| | 01:45 | You can get the operating system from
the OS module, but this gives you an
| | 01:49 | indicator of what types of services are
going to be available on this platform.
| | 01:54 | Like, for instance, if I'm on a win32
platform, I'm not going to do things that
| | 01:58 | are UNIX specific and vise-versa.
| | 02:01 | So, that can be a useful token to see.
| | 02:04 | If we import OS, this is another
module that you'll find in that list,
| | 02:10 | you'll notice that I can
import inside of the function.
| | 02:14 | I don't need to do my import at the top.
| | 02:16 | This allows me to actually
selectively import things, say I read that
| | 02:20 | sys.platform variable and say I'm
going to do certain things one way or
| | 02:25 | certain things another way
depending on which platform I get.
| | 02:28 | So I can import modules selectively,
and the system won't try to import them if
| | 02:34 | they're not on the right platform or whatever.
| | 02:37 | So, here we can get the os.name for
example, and if I save that and run it,
| | 02:45 | you'll see this says nt.
| | 02:48 | So, that's the name that it's
giving this particular type of Windows.
| | 02:51 | And it distinguishes it like from,
for example the older Windows 3 or
| | 02:56 | something like that.
| | 02:59 | I can get variables from the environment.
| | 03:00 | I can print os.getenv
and say I want the PATH variable.
| | 03:06 | Save and run.
| | 03:11 | And there is the PATH
variable from the operating system.
| | 03:16 | So, I can get current working
directory, and we'll save and run that.
| | 03:25 | And there is the current working directory.
| | 03:27 | Of course, this module has
a lot of functions in it.
| | 03:32 | Just one more I want to
show is the urandom function.
| | 03:35 | This is sometimes useful.
| | 03:39 | Save and run that.
| | 03:42 | This is a function that'll
give a string of random bytes.
| | 03:45 | And of course you see that this is the
byte type, and I set 25 so it's 25 bytes long.
| | 03:55 | Another useful module is the urllib
module, and we'll go ahead and import from
| | 04:02 | that urllib.request, and we'll
grab a web page from the internet.
| | 04:11 | urllib.request.urlopen,
and we'll give it a URL here.
| | 04:20 | We'll go ahead and get my
homepage, print(page). There we go.
| | 04:26 | Save that and run it.
| | 04:29 | We get this object.
| | 04:31 | And that's an iterable object.
| | 04:33 | So, we can iterate on it
and say for line in page:
| | 04:39 | print, and convert each line to a
string because they come out binary, and
| | 04:47 | we provide an encoding.
| | 04:50 | And they have no lines at the end of them.
| | 04:52 | So we'll give it this line ending there.
| | 04:56 | And we save and run and
there is an entire web page.
| | 05:07 | So, that's a really useful one.
| | 05:09 | There are a lot of very useful modules
in here. I'm just going to take a quick look
| | 05:13 | at a couple of more.
| | 05:14 | One is the random module.
| | 05:17 | It's a very rich random number library.
| | 05:19 | For example, you can print a
random number from in a range. randint,
| | 05:33 | A range between 1 and 1000. Save and run.
| | 05:37 | And then we have the number 726.
| | 05:38 | If we run it again, we get a
different number and a different number and
| | 05:42 | a different number.
| | 05:43 | And that's very useful.
| | 05:45 | Another very useful method in this
library is the shuffle method. It takes a list.
| | 05:52 | I'm going to just give it a list with a
range in it, and if we print that list,
| | 05:57 | you'll see that we have a range of 25 numbers.
| | 06:03 | We can shuffle the list,
random.shuffle, and print it again.
| | 06:16 | And there we have the list shuffled randomly.
| | 06:20 | If we do that a few times, save
and run, you can see we get different
| | 06:26 | shuffles each time.
| | 06:29 | Finally, in our little partial
tour of the standard library, look at
| | 06:34 | the datetime module.
| | 06:47 | So we'll save that and run it, and
there we have the time as of right now
| | 06:54 | when I'm recording this.
| | 06:55 | In fact, we can do this. now.year,
now.month, now.day, now.hour, now.minute,
| | 07:13 | now.second and now.microsecond,
and save that and run it.
| | 07:21 | And there we have all of those
components, separately usable with these
| | 07:25 | properties of the datetime object.
| | 07:27 | So, these are just a few of the standard
modules that are available with Python.
| | 07:31 | Again I strongly recommend that you
look through the documentation for these
| | 07:35 | standard modules. At least read their
descriptions so that you get an idea of
| | 07:39 | what's available there, so that as
you're going through writing your own code,
| | 07:43 | you're not tempted to reinvent the wheel.
| | 07:45 | The modules that are included with
Python and the Python distribution tend to
| | 07:49 | be very well written.
| | 07:50 | They tend to be very feature rich and they
tend to be quite well optimized and reliable.
| | 07:56 | So, I suggest that you use
them when you have an opportunity.
| | Collapse this transcript |
| Finding third-party modules| 00:00 | In addition to the modules that
distribute with Python in the Python
| | 00:04 | standard library there is also a
repository of modules that have been
| | 00:09 | written by other people.
| | 00:10 | This is called PyPI, the Python Package
Index, and it's available at this web page.
| | 00:16 | We're going to click on the link here,
Python 3 packages, so we can see what
| | 00:21 | packages are available that support Python 3.
| | 00:23 | Of course by the time you look at this,
this list will probably be much longer
| | 00:28 | because more-and-more modules are
being imported to Python 3 all the time.
| | 00:32 | Just as an example of how to install a
module that you find here, I've selected
| | 00:39 | one called bitstring, and what this does
is it allows you an easy way of working
| | 00:45 | with strings of bits, and we'll go ahead
and we'll download this and install it.
| | 00:51 | And so this is the page and most of
the pages look something like this.
| | 00:54 | They've got some documentation.
| | 00:56 | They have a link to the web site where it's
been developed and a way to download a module.
| | 01:03 | And so I've already downloaded this and
unpacked it on the computer here and there it is.
| | 01:11 | Go ahead and change into that directory.
| | 01:14 | And we can see that it's this Python file
and a setup.py and some other related files.
| | 01:24 | All of the modules that are
available on PyPI have a setup.py and it's a
| | 01:29 | standard, and so they all
install pretty much the same way.
| | 01:33 | Now I am installing this on Windows.
| | 01:35 | And the way that you install it on
other operating systems is pretty
| | 01:39 | much exactly the same.
| | 01:41 | You run the setup.py script
with the argument install.
| | 01:47 | And on Windows, unless you've put
Python in your path you'll have to type in
| | 01:51 | the path to Python.
| | 01:53 | On most other systems you won't need to do that.
| | 01:55 | So I am just going to type in the path here.
| | 01:58 | And I say python31, which is the standard
place where it installs on a Windows system.
| | 02:04 | And let's say python, and then I am
going to give the name of the setup script,
| | 02:09 | which is setup.py and the
word install, like that.
| | 02:13 | And so if you are on a UNIX-based
system like a Mac or Linux you probably just
| | 02:17 | type something like
Python 3 setup.py install.
| | 02:23 | You do want to make sure that if you
have both Python 3 and an earlier version
| | 02:27 | of Python installed on your system that
you are running the correct Python when
| | 02:34 | you run the setup.py.
| | 02:36 | If for example you were to run
Python 2 and the setup and install,
| | 02:41 | your module would be installed in the
path for the Python 2 and not in the
| | 02:44 | path for the Python 3.
| | 02:45 | So you want to make sure you are
running the right Python when you do this.
| | 02:48 | And so in this case that's by using
this directory and then Python and
| | 02:54 | setup.py and install.
| | 02:56 | So I am going to go ahead and run that,
and there it is it's built it and it's
| | 03:02 | copied it into the site-packages
directory, which is where all of your user
| | 03:07 | installable packages are installed.
| | 03:10 | And again if you are on a UNIX system
or on any different operating system that
| | 03:13 | will be in a different place, but it'll
be called site-packages just like that.
| | 03:18 | Let me go ahead and change to that
directory so we can see what happens here.
| | 03:26 | So this is the site-packages directory
on this system, and you see it just has
| | 03:30 | this one module installed.
| | 03:33 | And it installs this egg-info, which
is just a lot of information about the
| | 03:37 | module, and that's useful.
| | 03:39 | It installs the .py file and then
it also installs this .pyc file.
| | 03:45 | What that is is a
complied version of the module.
| | 03:48 | So that when it's run it's actually
a little bit more efficient, and this
| | 03:52 | happens at install time.
| | 03:53 | So we'll go ahead and switch to Eclipse
now and we'll take a look at how we use this.
| | 04:00 | Make a working copy of modules.py.
Call that modules-working.py.
| | 04:08 | We'll open that up and instead of
import sys here we are going to import
| | 04:17 | bitstring, and we'll go
ahead and use it. Set a variable.
| | 04:25 | Now I have already read the
documentation from the module.
| | 04:28 | That might be the first thing that you'll
want to do. a = bitstring.BitString(bin =
| | 04:33 | 01010101, and I want to put that
in quotes because that's a string.
| | 04:42 | So what this does is it allows you
to find binary patterns using strings
| | 04:46 | and then use those.
| | 04:49 | We'll go ahead and print it in some
different forms. a.hex, a.bin, a.unsigned
| | 04:58 | integer, and we'll save that and run it.
| | 05:03 | And there we have successfully installed and
used a module that we've found on the PyPI index.
| | 05:10 | So the PyPI index is a very useful thing
and you want to be careful of course
| | 05:15 | because a lot of people submit modules
and they are varying quality, so you
| | 05:20 | want to do a little bit of vetting.
| | 05:21 | Or you may just want to download some
modules and look at their source code and
| | 05:25 | learn how other people do things.
| | 05:26 | It's a very valuable resource.
| | 05:29 | And again it gives you the opportunity
to leverage other people's work and to
| | 05:33 | not be reinventing the wheel.
| | 05:35 | So do take a look at the Python index
at PyPI and become familiar with what it
| | 05:41 | is and how it works and add
it to your quiver of tools.
| | Collapse this transcript |
| Creating a module| 00:00 | Oftentimes as you are writing code
you'll find pieces of code that you want to
| | 00:04 | reuse in different projects. For this
you'll want to write here own modules.
| | 00:08 | So let's take a look at how we do this.
| | 00:11 | For example, if this is my homepage
and if you look down at the bottom of the
| | 00:15 | page you'll see that it tells
the time and it says it in words.
| | 00:18 | It says it's twenty past three.
| | 00:21 | Now, I did this with a Python module,
and we're going to take a look at that
| | 00:25 | module, and here it is.
| | 00:27 | Now, the point of this is to show you
how to put the code into the module.
| | 00:31 | We'll look at the details of
the module in another lesson.
| | 00:34 | But for now let's see that
it has this class numwords.
| | 00:39 | But for now let's just look at from the
perspective of how we put the code into a module.
| | 00:44 | So you'll notice that it has this class
numwords, and this formats a number into words.
| | 00:51 | And it has this other class saytime_t
that inherits numwords and that
| | 00:57 | class is for formatting the time as words.
| | 01:02 | And then it has a special version of
saytime as a wrapper for using a time object.
| | 01:11 | And it has a main function, so that
it can be run from the command line.
| | 01:15 | And it has a test function for testing.
| | 01:19 | And so all of this is put in a
normal file and really there is nothing
| | 01:23 | special about the file.
| | 01:25 | In fact, if I run it-- we'll go ahead and do that.
| | 01:30 | You see that it gives the time
right now, twenty-eight til five.
| | 01:34 | It can also be run with an
argument that hasn't run these tests.
| | 01:39 | And in Eclipse, so a little bit of a
production to get it to do that, to come
| | 01:46 | over here and give it an argument, say
test, and Apply and Run, and then it runs
| | 01:56 | it in test mode.
| | 01:57 | And you'll see if I do that from the
command line, I just give the word test on
| | 02:01 | the command line, and
it runs all of these tests.
| | 02:04 | It tests all the numbers and it tests the time.
| | 02:07 | I'd like to do things this way.
| | 02:09 | You can also use the unit
testing module that comes with Python.
| | 02:13 | And so I have a lot of
results that I could look at.
| | 02:16 | So the module itself you just write
it like you write a normal script.
| | 02:20 | You write your script and in the process you
write whatever classes you're going to write.
| | 02:27 | And you think about how it will be
accessible from the outside world.
| | 02:30 | And then when it's time to use it as a
module you'll notice down here at the
| | 02:34 | bottom it has this if _name_
pattern, we've seen this before.
| | 02:38 | And that prevents the main code from
being run when it's imported as a module.
| | 02:42 | So I don't have any code
that's outside of a function.
| | 02:45 | And that's generally true
when I write a script any way.
| | 02:49 | And here is the script on my web site.
| | 02:51 | It's a very short script.
| | 02:52 | That's the entire thing.
| | 02:54 | And all it does is it imports time,
because it grabs the time as a localtime
| | 02:59 | variable, and it also wants to be able
to format that time so that it can format
| | 03:04 | the date and time as well.
| | 03:06 | And it imports the saytime
module and it calls that here.
| | 03:10 | It says "In Phoenix Arizona, it is
now," and it has the saytime words.
| | 03:16 | And it has the formatted date, on day of
the week, and the day, month, and year.
| | 03:22 | And so when we run that you'll see
it has the CGI header because this is
| | 03:27 | included in a page as a server side include.
| | 03:31 | And it says, "In Phoenix, Arizona, it is
now," and it gives the time, twenty-six
| | 03:34 | til five, on this date.
| | 03:38 | And so when you have code that you
want to reuse you're going to want to put
| | 03:43 | it in a module and when you put it in a module
it's really just like writing a normal script.
| | 03:49 | You just need to be careful that you
don't have any code that's outside of a
| | 03:52 | class or a function, and you want
to have this pattern down here at the
| | 03:56 | bottom for running main.
| | 03:57 | So that you have some way to test it
or as I do with this one, to actually
| | 04:02 | just use it as a script.
| | 04:04 | Let's go ahead and take that out.
It's still got the argument in there.
| | 04:09 | So that when it's not run with the test
argument it just runs it as a script and
| | 04:13 | it gives the time so you can include it
in a shell script or you can use it in a
| | 04:17 | lot of different ways.
| | 04:18 | So I'm looking for flexibility when I do this.
| | 04:21 | But that's essentially all there is to it.
| | 04:23 | You just put your classes in there, set
it up with the pattern at the bottom so
| | 04:27 | that it only runs main when it's not
imported, and so it doesn't do that when
| | 04:30 | it's imported and then your class
becomes available to other scripts.
| | 04:35 | And you'll see a lot of examples of
this as we go through the projects later
| | 04:38 | on in the course.
| | Collapse this transcript |
|
|
18. DebuggingDealing with syntax errors| 00:00 | As you are building code in Python,
you may occasionally make a typo, or
| | 00:05 | misplace a punctuation mark or
forget a comma or something like that.
| | 00:09 | The Python interpreter will do its best
to try to guide you to where the errors
| | 00:14 | are and sometimes it's
helpful and sometimes it's not.
| | 00:18 | Let's take a look at some examples here.
| | 00:20 | There is a file in your debugging
folder called saytime-errors.py. We will
| | 00:26 | go ahead and make a working
copy of this and we will call this
| | 00:30 | saytime-errors-working.py.
| | 00:35 | I will go ahead and open that working
copy and this is the saytime module and it
| | 00:41 | has some errors in it.
| | 00:43 | So we will go ahead and we will run it
and see what happens, and it's flagged
| | 00:48 | a syntax error here.
| | 00:50 | It says Syntaxerror:
| | 00:51 | invalid syntax and you see that
little caret is pointing at the second
| | 00:56 | quote mark on line 26.
| | 00:58 | So, we will scroll down here to line 26
and you see a little red x there and if
| | 01:08 | I hold my cursor over the red x,
we are getting a different error message and
| | 01:13 | this is because Eclipse is
doing its best to help too.
| | 01:17 | So Eclipse is looking at it from the
perspective of syntax highlighting and
| | 01:23 | Python is actually trying to run the code.
| | 01:26 | So, looking at it from two different
perspectives they are going to give you two
| | 01:28 | different perspectives.
| | 01:30 | You know they both might be
helpful and they might not.
| | 01:32 | We are going to focus on the Python
error messages here, because you are not
| | 01:36 | always going to be coding inside of
Eclipse, and the syntax highlighting
| | 01:40 | parser is not always going to be as helpful
as the parser that's trying to run the code.
| | 01:45 | So, in this case, it's
pointing at this character here.
| | 01:50 | So, let's see if we can get the
entire statement here on the screen and it
| | 01:54 | starts here with _words = and it's got
the opening curly brace and that ends
| | 02:01 | down here with this closing curly brace.
| | 02:03 | So the curly braces mean that this
is a dictionary definition and you see
| | 02:08 | there is our first key and a colon
and there is a tuple object as the value and a comma.
| | 02:17 | So, what we have here is a dictionary
definition and we looked down here at this
| | 02:22 | line with the error on it and we see
there is colon there and there is the quote
| | 02:28 | and there is the opening quote.
| | 02:29 | It's not really obvious that
there is anything wrong with it.
| | 02:32 | That quote does not look like a problem.
| | 02:34 | Even though the syntax error is
pointing at that quote, that quote does not
| | 02:39 | look like a problem.
| | 02:40 | So let's look at it in order. Let's go
through the process of looking at this
| | 02:46 | whole definition and see if
we can figure out what's wrong.
| | 02:49 | So this is the first key and then there
is colon. The value is that whole tuple
| | 02:54 | object and then there is a comma and
then there is another key and a colon and
| | 03:00 | then the value, which is
another tuple object, and a comma.
| | 03:03 | So, we are seeing a pattern here.
| | 03:05 | Key, value, comma, key, value, comma,
we are getting closer, and here is a key
| | 03:14 | and here is a value and there ought to be a
comma there, because this looks like another key.
| | 03:21 | So, we will put that comma
in and we will save the file.
| | 03:25 | We notice that the red x goes away.
| | 03:26 | That's a good sign and we run it,
and we get another error message.
| | 03:31 | But this one is on line 70.
| | 03:33 | So it looks like we have
fixed this syntax error.
| | 03:37 | You see the little red mark over here
that's probably line 70, sure is, and we
| | 03:44 | have a different error message.
| | 03:46 | This one says, IndentationError:
| | 03:49 | unindent does not match
any outer indentation level.
| | 03:53 | So it says it's an indentation error
and we see we have another dictionary
| | 03:59 | definition and all of that looks okay.
| | 04:03 | You see a little red squiggly
mark from the syntax highlighter.
| | 04:07 | It's trying to help us there, but
it's actually covering up the problem.
| | 04:12 | You will notice that under those
little red squiggly marks, there is an
| | 04:15 | underscore and that underscore is
indented farther out than the code above it,
| | 04:20 | and so if we push that in one character
and then save the file, see the red x goes away.
| | 04:28 | Now we can see that underscore and
we can see that indentation level.
| | 04:31 | So that was an indentation error.
| | 04:33 | You will notice that it's
pointing at the wrong character here.
| | 04:38 | If it was pointing back here,
it might have been more obvious.
| | 04:41 | That's typical of parsers everywhere.
| | 04:43 | They will do their best to show you
where the error is and more often than not,
| | 04:48 | they are off by a few characters and
sometimes even a few lines of code.
| | 04:52 | So go ahead and run in it again and now
we have another error, and this one says
| | 04:58 | it's on line 118 or line 129.
| | 05:02 | We have two errors being printed out
here and what this is doing actually, we fill
| | 05:09 | the screen with this, this is
what's called a traceback in Python.
| | 05:15 | It's telling where it encountered the
error and it's tracing back its execution.
| | 05:19 | So this is actually a runtime error.
| | 05:21 | This is not syntax error.
| | 05:23 | It says AttributeError, 'built_in_
function_or_method', object has no
| | 05:28 | attribute 'tm_hour'.
| | 05:30 | Here it is trying to assign this t.tm_
hour to a variable, self.hour, and that's at line 118.
| | 05:41 | So, let's take a look at 118 and
there is the line of code, and so what's
| | 05:49 | happening is t here is an object that's
getting passed into this constructor and saytime_t.
| | 05:56 | So what's the line above this?
| | 05:59 | Scroll back down here and a line above this
is print saytime_t and this is at line 129.
| | 06:06 | So let's go down to 129 and there it is.
And so it's passing this time.local time
| | 06:15 | and I happen to know that
local time there is a function.
| | 06:20 | It is not an attribute.
| | 06:23 | So it's correct here, object has no
attribute, ?_hour, and that's because we
| | 06:29 | didn't call it with the function.
The function has the attribute.
| | 06:33 | So if we save this and run it again,
now we get something else. This is not
| | 06:38 | printed in red which means it's not
being sent to standard error, which means
| | 06:42 | it's not really a runtime error.
| | 06:44 | This looks more like another kind of an error.
| | 06:47 | It says bound method saytime.
| | 06:49 | This is actually the output
of this print statement here.
| | 06:52 | It's printing a bound method,
rather than running the bound method.
| | 07:00 | So you see here .words.
| | 07:02 | .words is supposed to be a method.
| | 07:06 | It's actually a method in one
of our classes here, there it is.
| | 07:12 | See it's a method here, def words, and
so what we need to do, see just like the one up here.
| | 07:22 | It needs to have parenthesis.
| | 07:22 | So we will save that and we will run
it and our script works as we expected.
| | 07:30 | So that's pretty much the
process that you have to go through.
| | 07:33 | If you type a whole bunch of code and
it's not working the way that you expect
| | 07:37 | it to work, you need to have some
patience. You need to look at carefully and
| | 07:41 | objectively and sometimes from myself,
if I am not seeing and I will go and do
| | 07:47 | something else, clear my head
and come back and look at it.
| | 07:51 | Usually at some point after I have
cleared my head enough and I look at it
| | 07:55 | enough, the errors will jump out and at me.
| | 07:57 | These are the common type of syntax
errors that you will run into in Python,
| | 08:01 | things like forgetting parenthesis,
indentation errors, forgetting commas, things like that.
| | 08:06 | So you can start with
looking for those sorts of things.
| | 08:10 | Just have the patience, try and follow
the code in your head, and eventually you
| | 08:16 | ought to be able to find
the errors and correct them.
| | Collapse this transcript |
| Dealing with runtime errors| 00:00 | Sometimes when running error into
your code, they won't be syntax errors.
| | 00:04 | instead they will be errors that don't
show up until you try to run the code.
| | 00:08 | We call these runtime errors.
| | 00:10 | And we got some examples here.
| | 00:11 | Let's make a working copy of
this mvc errors.py, and we'll call
| | 00:18 | this mvc-working.py.
| | 00:24 | Open up that working copy and here we
have demonstration file of a mvc model.
| | 00:32 | mvc stands for Model View Controller,
and if we run this and look at the output,
| | 00:42 | you'll see that things aren't
quite okay in the first forest here.
| | 00:47 | So couple of places we have
this bound method being printed out
| | 00:54 | and that is not
necessarily what we are looking for.
| | 01:00 | So let's see we can hunt this bound.
| | 01:02 | It says bound method Duck.feathers,
bound method Person.feathers,
| | 01:08 | bound method Dog.feathers.
| | 01:10 | And so here is the feathers method.
This gets inherited. We have Duck, Person
| | 01:16 | and Dog and these are all inherit
animal actions and the animal actions has
| | 01:23 | the method feathers.
| | 01:25 | So like it's inherited into these
different classes, and that's getting
| | 01:29 | printed out some place.
| | 01:30 | So when we see this string in Python
that says bound method blah, blah, blah,
| | 01:35 | that means that you are trying to
print a method, rather than calling it in.
| | 01:40 | It usually means missed parenthesis.
| | 01:43 | That's the most common thing here.
| | 01:45 | And so Ecllipse is actually helping
me here. Because I put my cursor on
| | 01:50 | feathers up here, it's highlighting
all the places where it sees the word
| | 01:53 | feathers, and so this is jumping out
at me here, and you'll notice that it's
| | 01:58 | missing the parenthesis.
| | 01:59 | So if I go ahead and put those
parenthesis in, see I was printing the method
| | 02:04 | instead of calling the method
and printing what it returns.
| | 02:06 | So if I save that and run it,
now we don't get that error any more.
| | 02:12 | And we have quack, the duck has no
feathers, the person imitates a duck, and I am
| | 02:18 | going to just say, "wait a minute, the
duck has no feathers?" Ducks have feathers.
| | 02:23 | And I know that I typed
in feathers for the duck.
| | 02:27 | See, the duck has gray and white feathers,
and so why is it printing it this way?
| | 02:33 | Well, you'll notice that the feathers
method cause doAction for feathers and what
| | 02:39 | doAction does is it looks for the
strings with the action, and so the strings is
| | 02:45 | defined in each of these animals.
| | 02:49 | So I have strings here, strings there.
| | 02:51 | So this is where strings are defined and
it's looking for feathers, which is spelled wrong.
| | 02:58 | And if I correct that
spelling and save that and run it
| | 03:06 | and we will look at our result here,
| | 03:07 | we now see that the duck
has gray and white feathers
| | 03:11 | So often times it's a typo like that
and these kind of things can be hard to find.
| | 03:16 | The trick is to go through the code, to
follow the execution path of the code,
| | 03:22 | and to say if this gets called by that,
that gets called by this, this is the
| | 03:25 | way that's supposed to work and just
take your time and be patient and try not
| | 03:30 | get flummoxed by the error.
| | 03:32 | I like to say the
computers have infinite patience.
| | 03:35 | It will sit there and stare at you
with the error for as long as it takes.
| | 03:39 | The trick is for you to try and gain as
much as patience as the computer has in
| | 03:43 | order to be able to find the errors.
| | 03:45 | So often times these things just take
patience, but the methodology is to go
| | 03:51 | through the execution of the code and
to look at all of the pieces that are
| | 03:55 | supposed to fit together and try and
find out piece that's not fitting together
| | 03:58 | the way that it is supposed to.
| | Collapse this transcript |
| Dealing with logical errors| 00:00 | Sometimes when you run into errors in our code.
| | 00:02 | It's not a syntax error.
| | 00:04 | It's not a runtime error.
| | 00:06 | It's just that the code doesn't quite do
what it was that we had intended for it do.
| | 00:11 | These things are often also caused by typos.
| | 00:15 | So let's make a working copy of,
incrange-errors.py and we will call that
| | 00:21 | incrange-errors-working.py.
| | 00:26 | This is our inclusive range method
from another example in this course.
| | 00:34 | There is the code, and you will see that
it calls it down here, and we will just
| | 00:41 | run it and see what happens.
| | 00:42 | Well, nothing happens.
| | 00:44 | That's not a good sign.
| | 00:46 | So why would nothing happen?
| | 00:47 | Well, what's supposed to happen?
| | 00:49 | The object gets initialized and it
gets constructed with these parameters,
| | 00:54 | a start, a stop and a step of 4, 25
and 3, and then it gets printed out by
| | 01:02 | using the object as an iterator, and we can
see right here, here is the iterator function.
| | 01:09 | It's go a yield here, which makes it a
generator, so that looks like it should work.
| | 01:14 | We have the start, stop and step, and
so here is the start and the stop and the
| | 01:20 | step, and let's just run through
the code here and see what happens.
| | 01:24 | I am starting here because this is where
the print is, and this is also just the
| | 01:29 | shortest and easiest to look at piece
of code. I happen to know, because I wrote this,
| | 01:33 | that this is a little bit more of
a hornets nest, and so I am just going
| | 01:38 | to start here because it looks
like a simple place to start.
| | 01:42 | This is where the action
is actually happening here.
| | 01:44 | So i equals start, while i is greater
than or equal to and that doesn't look right,
| | 01:52 | because the start is at 4, and
the stop is at 25, so I would want to run
| | 01:58 | this loop while i <= stop.
| | 02:03 | So that looks like a typo, and so I will
change that, and I will save it and run it,
| | 02:09 | and now we are getting some output here.
| | 02:12 | So let's look at the
output and see if it is correct.
| | 02:15 | So we have this range.
| | 02:17 | It starts at 4 and over here we
are starting at 3. That's not right.
| | 02:21 | And it stops at 25. Okay, well,
that's plausible, and the step is 3, so 3+3
| | 02:29 | would be 6, 7+3 would be 10.
| | 02:33 | This is actually stepping by 4.
| | 02:35 | It's starting at 3 and stepping by 4.
| | 02:38 | So it would appear that I
got those 2 swapped some place.
| | 02:43 | So let's look at the
code and see how this works.
| | 02:46 | So we have numargs,
which is the length of args.
| | 02:50 | So that's the number of arguments
that I am passing in and if numargs is
| | 02:54 | less than one, we have a TypeError.
If numargs equals to one, so I have three arguments.
| | 02:59 | So let's just step down here to
numargs equals three and so I
| | 03:03 | assign them like this.
| | 03:05 | Step, stop and start equals args.
| | 03:07 | Well, that's not right.
| | 03:08 | Its start, stop and step is what it should be.
| | 03:11 | So I will switch those. Those got
swapped just like I thought. start, stop and step.
| | 03:21 | And that looks like it should fix it.
I will save that and run it, and here we
| | 03:30 | have a different result.
| | 03:31 | Let's see if this looks right.
| | 03:33 | It should start at 4.
| | 03:34 | It is starting at 4.
| | 03:36 | Stop at 25, that looks right,
and the step is 3. So we have 4,
| | 03:41 | 7, 10, 13, 16, that looks right.
| | 03:45 | So now it's working as we expected.
| | 03:49 | At this point I would test the other
ways of passing parameters, test some
| | 03:54 | other corner cases.
| | 03:56 | I happen to know because I made
these errors that that's the extent of
| | 03:59 | the errors in the file.
| | 04:00 | So the trick is like so much of
debugging to be patient, to follow the execution
| | 04:05 | of the code, to look at what's supposed
to happen that's not happening, to look
| | 04:09 | at what's happening that's not
supposed to happen, and through patience and
| | 04:13 | perseverance to find those little
typos, and really the key here is the
| | 04:18 | patience and perseverance.
| | 04:19 | Sometimes this can just take a while.
| | Collapse this transcript |
| Using unit tests| 00:00 | The Python standard library includes a
unit test module that's very powerful and
| | 00:04 | very flexible and is also very easy to use.
| | 00:09 | Unit tests are valuable for a few reasons.
| | 00:12 | Unit tests are automated tests that you
can run on your code and you can write
| | 00:16 | these tests once and save
them and run them over and over.
| | 00:18 | So if you have a set of code that's got
a lifetime to it, that over the course
| | 00:22 | of its lifetime it gets updated, it
gets changed, having these unit tests
| | 00:26 | already written and being able to run
these unit tests on your code is going to
| | 00:31 | have some real value for you.
| | 00:33 | So let's look at how this is done in Python.
| | 00:36 | I've got the saytime module here, which
has been used for a number of different
| | 00:40 | purposes in this course.
| | 00:42 | And you'll notice at the end of it
it's got a little test function.
| | 00:48 | And when I wrote this, this just
seemed like the easiest way to do it.
| | 00:51 | And it's also, I like to be able to look at
the results and say yeah, that looks right.
| | 00:55 | That looks right. That looks right.
| | 00:57 | If this were anymore complicated
or if it was going to have much of a
| | 01:02 | development lifecycle to it,
I would use unit tests instead.
| | 01:05 | And so we're going to go ahead and do that.
| | 01:11 | This is a unittest script
that I wrote for saytime.
| | 01:15 | And I basically took those textual
tests and I made them into unit tests.
| | 01:21 | And this is very, very easy to do.
| | 01:24 | All I do is I import
saytime and I import the unittest.
| | 01:27 | So this is the module that I'm working
on and this is the unittest framework
| | 01:31 | from the Python standard library.
| | 01:33 | And then I create this class.
| | 01:36 | And then at the end of the module here,
if __name == "__main__", instead of just
| | 01:40 | calling my own main, I call a special
main that's in the unittest package.
| | 01:45 | And in the unittest package, the
special main will actually open up this file
| | 01:50 | and parse it and find the classes that
import unittest, and it will go ahead and
| | 01:56 | run the test in that class.
| | 01:59 | And so here is the class.
| | 02:00 | So I can name it whatever I want.
| | 02:02 | And it has a special method called setUp.
| | 02:05 | In this special method setUp, I can
do any initializations that I want to.
| | 02:08 | And so here I've created this list of numbers.
| | 02:10 | I could have just as easily put that in
the test for the numbers, but I wanted
| | 02:13 | to demonstrate the setUp here.
| | 02:16 | And so I take a range of 11 numbers,
from 0-10, and I make a list out of them,
| | 02:22 | and I assign them to this variable here.
| | 02:25 | And so that gets used in test_numbers.
| | 02:27 | So here is the first method.
| | 02:29 | These methods will get run as the tests.
| | 02:32 | So the first method here is test_numbers.
| | 02:34 | And I've got some words that I'm
going to compare those numbers again.
| | 02:37 | And these are the words that will be
the results of my saywords numwords.
| | 02:42 | So 'oh', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine',
| | 02:43 | 'ten', those are the results that I'm expecting.
| | 02:48 | And so I enumerate through the self.nums.
| | 02:51 | I get both an index and the number itself.
| | 02:54 | And then I run this assertEqual method,
which is from the unittest package, and
| | 02:59 | it's going to compare two values.
| | 03:02 | And if these two values are equal,
then fine. It will leave it alone.
| | 03:06 | And if they're not, then it
will throw an AssertionError.
| | 03:08 | And so here the two values are the
result from my saytime.numwords and the word
| | 03:16 | from this tuple here.
| | 03:18 | If they equal, then fine.
| | 03:20 | And if they're not equal,
then it'll throw an AssertionError.
| | 03:23 | And so the same thing here,
test_time. I have time_tuples.
| | 03:27 | And so this is a tuple
with a bunch of tuples in it.
| | 03:30 | And these are the times
that I'm testing against.
| | 03:32 | And these are hours and minutes.
| | 03:34 | And then here's the list of the
results that I want, "midnight", "one past
| | 03:37 | midnight", "eleven o'clock", etcetera.
| | 03:40 | And if they compare equal, it's the same thing.
| | 03:42 | I enumerate through the time_tuples.
| | 03:44 | I run them through the module that I'm
testing and I compare them to this tuple
| | 03:51 | up here of these words.
| | 03:53 | If they're equal, fine.
| | 03:54 | If they're not equal,
it throws an AssertionError.
| | 03:56 | So this is how this works.
| | 03:59 | And obviously you can write your own tests.
| | 04:02 | There are a number of different assertion tests.
| | 04:04 | You can find those in the
documentation for the unittest module.
| | 04:07 | I strongly recommend that you read the
documentation for the unittest package.
| | 04:12 | It's got a lot of options.
| | 04:14 | It has a lot of methods that
you can use for your testing.
| | 04:17 | There are a lot of different
assertions that you can test for.
| | 04:20 | And it even has some ways to
do some more complicated tests.
| | 04:24 | This kind of test that I've
written here is the simplest case.
| | 04:27 | And for most purposes, this is
actually just fine, and it does the job and
| | 04:32 | it does the job well.
| | 04:34 | So let's go ahead and run it.
| | 04:36 | When we run this, you'll
notice that we get our little test.
| | 04:39 | And we've been just selecting
Python Run for all of these.
| | 04:42 | There's a special one here in
the PyDev module for Eclipse.
| | 04:45 | It's called Python unit-test.
| | 04:47 | And we're going to run that one. Say OK.
| | 04:50 | And here it ran our unittest.
| | 04:52 | We'll maximize this so we can see what it does.
| | 04:55 | First of all, it finds files.
| | 04:57 | And it finds the test-saytime.
| | 05:00 | And that's our unittest
module that we just wrote.
| | 05:04 | And it imports the test module.
| | 05:05 | So it's importing the saywords.
| | 05:08 | And here it runs the two tests,
test_numbers and test_time.
| | 05:11 | It ran the two tests.
| | 05:13 | It didn't throw any assertion errors.
| | 05:15 | And there's the result that we're expecting.
| | 05:17 | If it had not gotten the result that it
wanted, let's just go ahead and misspell
| | 05:21 | one of these words here.
| | 05:22 | I'll just throw an extra o in there.
| | 05:24 | We'll save that and we'll run it.
| | 05:26 | And now we got one failure.
| | 05:28 | You see it got an
AssertionError that oh did not equal to ooh.
| | 05:34 | So it gives us enough information here
that we can actually go through the code
| | 05:38 | and we can say, oh, well, I've got a
typo in my assertion test or there's an
| | 05:41 | actual problem in my module
that I need to go and fix.
| | 05:45 | So the beauty of this is, is that as
your code goes through its development
| | 05:49 | lifecycle, you make one release.
| | 05:51 | You make another release.
| | 05:52 | You make another release. You add features.
| | 05:54 | You take features away.
| | 05:55 | You change features.
| | 05:57 | Your unit-tests are already written.
| | 05:59 | And so you can accumulate more.
| | 06:01 | You can change them.
| | 06:02 | And this is going to help you to keep
the quality of your code high throughout
| | 06:07 | its development lifecycle.
| | 06:09 | So unit-tests are very useful.
| | 06:11 | The unit-test package that comes in the
standard Python library is very complete
| | 06:16 | and very well written and very reliable.
| | 06:18 | If you're going to be releasing
your code using Python, you must
| | 06:21 | submit unit-tests with it.
| | 06:23 | And of course the unit-tests are going
to be of value to you in any code that
| | 06:27 | has a lengthy product lifecycle.
| | Collapse this transcript |
|
|
19. Building a Database ApplicationNormalizing a database interface| 00:00 | As you build applications in Python, you
are probably going to find that you use
| | 00:04 | databases quite a bit and so you will
probably find some value in having a
| | 00:09 | normalized interface for
working with your databases.
| | 00:13 | I have built such a normalized interface
and you are welcome to use mine but I
| | 00:16 | would suggest that you simply use
this as a model and build your own.
| | 00:20 | Build one that works for you, that works for
the way that you like to work with databases.
| | 00:24 | So I will show you mine as an example.
| | 00:27 | It's called bwDB.py and it's in the
lib folder, in the 19 Projects folder in
| | 00:33 | your Exercise Files. So go ahead and
open that up and we will maximize this so
| | 00:39 | that we can take a look.
| | 00:40 | Of course it imports SQLite3. This is a
library for using SQLite3, like I said.
| | 00:48 | For most of my web applications these
days I am using SQLite3, because it's
| | 00:54 | small, it's fast, it's self-contained,
it's easy and it's very robust and
| | 00:59 | reliable. I've never had any problems with it.
| | 01:03 | So there is a class here called
bwDB and the first thing in it is the
| | 01:08 | constructor, and the constructor
simply takes this keyword arguments and it
| | 01:13 | looks for the file name and the table name.
| | 01:15 | You will notice that in each of these
methods I have what's called a docstring.
| | 01:19 | If the first line in a function or a
method is just a string by itself this is
| | 01:25 | picked up by Python's documentation
protocol and it's called a docstring.
| | 01:29 | I use it to describe how the function works.
| | 01:33 | So this is the constructor method,
the table is for the CRUD methods and you don't
| | 01:37 | have to use that. I will
get to that in a moment.
| | 01:40 | And the file name is for
connecting to the database file.
| | 01:45 | Here is one of my workhorse methods.
| | 01:47 | It's called sql_do. This is
for non-selective type queries.
| | 01:52 | You just pass it in some SQL, you pass
it in some parameters, and it does its job.
| | 01:57 | This next one, sql_query, is the same
thing except that it also works as a
| | 02:02 | generator and it will iterate
through set of results, and of course each
| | 02:08 | result is a row factory.
| | 02:10 | You will notice that the constructor
assigns file name here and file name is
| | 02:16 | actually a property, which is defined
down below, and we have seen this technique
| | 02:21 | already. And so in the setter when a
file name gets assigned it sets the
| | 02:27 | attribute in the object.
| | 02:29 | It also connects to the
database and it sets up the row query.
| | 02:33 | So this is actually a constructor of
sorts but it allows you to change files if
| | 02:39 | you want to. If you are using the
object and you decide that you need to assign
| | 02:43 | this object to a different database
file, first of course, it will call the
| | 02:48 | Destructor which closes the old database,
and then it'll call this constructor
| | 02:52 | for the file name and it will
connect to the new database.
| | 02:55 | This works really, really well.
| | 03:02 | We have and sql_query method for
returning a single row, and we have an
| | 03:06 | sql_query method for returning a single value.
| | 03:10 | I find these very useful and I use them a lot.
| | 03:12 | Again depending on how your pattern of
dealing with database is, you might
| | 03:16 | find different things useful and I
would suggest that you use those.
| | 03:20 | Now we get into the CRUD methods. CRUD
stands for create, retrieve, update and delete.
| | 03:25 | These are the basic four
functions of a database.
| | 03:29 | So this is the getrec that just would
be the retrieve part of CRUD, and for my
| | 03:34 | CRUD methods I depend on their being a
column in the table that's called id.
| | 03:42 | So all of my tables and all of my
applications that are going to use these
| | 03:46 | methods must have a column called id.
| | 03:49 | I typically create this column in
SQLite using the integer primary key feature
| | 03:54 | which makes that column an
equivalent for SQLite's internal row id.
| | 04:00 | This all just works very nicely
together and you will see examples of this in
| | 04:04 | the projects that we are
going to look at in this chapter.
| | 04:11 | Getrecs is a method that returns all of
the rows in the table and it returns it
| | 04:15 | as a generator with row factories.
| | 04:19 | Insert inserts a record and this
uses a dictionary for the record.
| | 04:24 | This is actually very interesting.
| | 04:26 | This method constructs the SQL based on
the names of the keys in the dictionary
| | 04:31 | object that gets passed.
| | 04:33 | So it takes a little bit of care to
work with it but when you use it with care
| | 04:37 | it works very, very well.
| | 04:42 | This next method works the same way.
Again it constructs the sql_query based on
| | 04:47 | the keys in the dictionary object
that gets passed and this will update a
| | 04:53 | particular record based on an id that's passed.
| | 04:59 | Finally we have the delete method where
it deletes based on the id, deletes the
| | 05:05 | row from the table based on the id and
a countrecs method that simply gives us a
| | 05:12 | count of all the records in the table.
| | 05:14 | This is a very fast operation to do in SQL.
| | 05:18 | Most database engines including
SQLite are very highly optimized for count operations.
| | 05:26 | So this method offloads that work to
the database engine and allows it to
| | 05:30 | happen very quickly.
| | 05:32 | Finally we have the property accessors
for the filename property and a close
| | 05:37 | method for closing the database.
| | 05:40 | Then we have a test method for testing
and we will go ahead and run that.
| | 05:50 | And that creates a database in memory.
| | 05:53 | Sqlite has a feature where if you
give the filename as this with colons
| | 06:00 | on either side of it, that whole
thing is the filename then it will
| | 06:03 | create a database in memory.
| | 06:05 | Creates a table, inserts into the table,
reads from the table, updates a table.
| | 06:08 | Exercises all of the CRUD methods.
| | 06:13 | So that is my example of a normalized
database interface. I find this very
| | 06:19 | useful and you'll see an example of it
here in this chapter of how I use this.
| | 06:24 | It makes it that much easier for me to
work with databases in my applications,
| | 06:29 | and these days in the little web
applications that I might be working on it
| | 06:33 | saves 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:00 | The four basic functions of a database
are create, retrieve, update and delete,
| | 00:05 | often pronounced as CRUD.
| | 00:07 | This is an example of an application
that does those basic four functions.
| | 00:12 | Of course there is a lot of functions that
people perform with database, there is a
| | 00:14 | lot of things that they are used for,
and as you are writing code over the years
| | 00:18 | you will be writing
databases for a lot different purposes.
| | 00:21 | But they all basically break
down to those four functions.
| | 00:24 | So those are the things that if you pay
attention to those things, then building the
| | 00:28 | more complex applications
becomes a little bit easier.
| | 00:31 | So this is an application that just does that.
| | 00:34 | It manages as a very simple database
and it simply allows you to add records,
| | 00:38 | edit records, and delete
records, and view records.
| | 00:42 | So those are the basic four functions
create, retrieve, update and delete.
| | 00:46 | What this application does as it
manages a Testimonials database that I use in
| | 00:51 | my web site and you will see if you look
at my web site, you will see little boxes
| | 00:54 | like this one over here that have testimonials.
| | 00:57 | For our purposes I have replaced the
testimonials with some witty little quotes
| | 01:01 | that I have collected over the
years and here is the database itself.
| | 01:06 | This has got 14 records in the database
and if you wanted to add something and
| | 01:15 | print a byline and click Add, you will
see that it adds it to the database right
| | 01:24 | here, and then I can edit it, if I want to.
| | 01:30 | Update it and there it
is updated in the database.
| | 01:34 | And if I want to delete it, I can delete it.
| | 01:38 | It's all very simple to operate and very
clear, and this comes from it being a very
| | 01:45 | simple application and also
from it being designed clearly.
| | 01:50 | So, here in the Example files, under
Projects and under testimonials, you will
| | 01:56 | find db.py and that is that script right there.
| | 02:01 | See down here,it says db.py version 1.13.
| | 02:05 | So that is this script right here.
| | 02:07 | So we are going to take a little tour
through this script and see how it works.
| | 02:12 | At the top here you see that I
imported a few libraries that start with bw.
| | 02:17 | These libraries are available in the
lib folder under Projects and these are
| | 02:23 | libraries that I have built over the years,
and there is this global namespace container.
| | 02:32 | I tend to do this in all of my web
scripts because it helps to keep state in
| | 02:37 | otherwise stateless environment, and it
helps me to keep my global name space cleaned up.
| | 02:43 | So I use a dictionary for that in Python,
and I have here a call to init, which
| | 02:50 | initializes these variables, again
helping to keep state and to set up my various
| | 02:55 | objects and to read my configuration
file and things like that, and then I look
| | 03:00 | for a variable a in the CGI variables.
| | 03:03 | If I find it, I run something called
dispatch. Otherwise I load the first main page.
| | 03:09 | So what dispatch does is it simply
looks for what is the action, a stands
| | 03:14 | for action, what is the action
that's been taken and it will dispatch the
| | 03:17 | proper function for that.
| | 03:20 | If these get any bigger I actually
have a library that runs a jump table that
| | 03:24 | will do something like this.
| | 03:25 | So I tend to do a lot of work on the web.
| | 03:28 | I tend to use CGI a lot.
| | 03:30 | CGI being stateless the way that it is,
the web and HTTP being stateless, that
| | 03:35 | helps to have things like this to
manage a little bit of a state machine.
| | 03:42 | The main part of the
application lists these records.
| | 03:45 | So this is the retrieve part of
the four functions of the database.
| | 03:50 | So the first thing this does is it
grabs a count of the records in the
| | 03:54 | database using the countrecs method
in the database library and that very
| | 03:59 | quickly and efficiently returns a
count all of the records and that allows
| | 04:02 | us to do some math here and figure out
how many we are going to display on the page
| | 04:06 | and how many pages there is
going to be and then we set up this little
| | 04:10 | menu here which is this part here
that tells us, we can jump to a specific
| | 04:14 | page or we can go back and forward.
| | 04:17 | So that's very useful.
| | 04:21 | Then we have our little bit of SQL
and this actually does the retrieval.
| | 04:25 | SELECT From ORDER BY
byline and LIMIT and OFFSET.
| | 04:31 | And in SQLite, limit and offset allow
us to only get the first so many records
| | 04:39 | and if it's not on the first page, then
to skip forward to an offset first and
| | 04:45 | then get that many records,
and it will do this on any query.
| | 04:48 | Most modern database engines
have some way of doing this.
| | 04:51 | It's not a part of the SQL standard so
they all tend to be a little bit different.
| | 04:56 | This one, SQLite actually, uses a very
similar syntax, I don't think it's exact,
| | 05:01 | but a very similar syntax to how it's
done in MySQL and those are the two really
| | 05:06 | popular ones for web applications these days.
| | 05:09 | So that's how we do the paging and we
make that list at the bottom of the page.
| | 05:14 | The pagebar itself with the various
links is there and displaying pages is here
| | 05:23 | and then we get down to the actual actions.
| | 05:27 | Adding a record to the database,
it simply builds this dictionary object and
| | 05:32 | passes it off to the insert CRUD
function in my database library, which I explain
| | 05:37 | in another movie in this chapter.
| | 05:40 | Likewise, the delete function calls
the delete method in the database library
| | 05:50 | and the update function calls the
update method in the database library.
| | 05:57 | Using these CRUD methods in my
normalized database library allows me to keep
| | 06:02 | this code very small.
| | 06:05 | Each of these function uses
exactly the same data structure.
| | 06:09 | It uses this dictionary.
| | 06:11 | It uses an id field that's called id,
and this allows the methods in the
| | 06:16 | database library to do there job.
| | 06:20 | So, let's take a quick look at those
methods and this is the database library, bwDB.
| | 06:31 | So the insert method here, it takes the
dictionary object and it actually goes
| | 06:36 | through the dictionary object.
| | 06:40 | It grabs all of its keys and then uses
this generator expression to create a
| | 06:46 | list of all the values.
| | 06:48 | And so it has got a list of the
keys and it's got a list of the values.
| | 06:53 | And then it uses those two lists to
build the SQL using the strings format
| | 07:01 | method and then it passes that
SQL query off to the database.
| | 07:06 | So this allows us to use a dictionary
object and to build our query based on
| | 07:12 | the names of the keys in that
dictionary object and to use that so that we
| | 07:17 | can use the same code for different
applications that have different database schemas.
| | 07:23 | So, the same technique is also used for update.
| | 07:29 | Where again, we build a query
based on a list of keys and values.
| | 07:36 | Keys and values.
| | 07:41 | The other methods like
delete(), they only need the id.
| | 07:44 | So that makes that a lot easier.
| | 07:47 | So this is a very useful technique
where you can use normalized code for a
| | 07:51 | number of different applications
with different database schemas.
| | 07:54 | And by using that normalized code and
some simple coding conventions, you can
| | 07:59 | keep an application like this, down to
about 250 lines and still have it look
| | 08:04 | and operated like something a
lot bigger and a lot more complex.
| | Collapse this transcript |
| Displaying random entries from a database| 00:00 | Here we have a simple database
application that displays a list of random
| | 00:04 | testimonials or quotes on a web page.
| | 00:07 | If you look at my web page,
I actually used this for testimonials.
| | 00:10 | And every time the page gets reloaded,
it pulls up three different quotes from
| | 00:15 | the database at random.
| | 00:17 | The database itself is managed with
this application that allows you to go
| | 00:22 | through and add, edit and
delete entries in the database.
| | 00:26 | We'll look at that in a
separate movie in this chapter.
| | 00:29 | In this chapter, we're going to look
at how this application works ,which
| | 00:34 | retrieves the quotes from the
database and displays them at random.
| | 00:38 | So in the Projects folder, in your
Exercise Files, in the testimonials folder
| | 00:43 | and you'll find testimonials.py.
| | 00:46 | And this is actually exactly
the same script that is on my web site.
| | 00:49 | This is the script that reads the
quotes from the database and displays a
| | 00:54 | number of them at random.
| | 00:54 | It's a very short script.
| | 00:57 | It's just 73 lines long, including the
white space and comments and everything,
| | 01:02 | and here's how it works.
| | 01:03 | The first thing it does is
it initializes some variables.
| | 01:09 | It reads the configuration file to
find out where the database is and
| | 01:12 | everything, and opens up the database.
| | 01:15 | And all that happens here in this init function.
| | 01:19 | Here it reads the configuration file
there and it opens up the database here.
| | 01:24 | And this uses libraries that I've
also included in the Lib folder.
| | 01:30 | bwDB for my normalized CRUD oriented
database functions, and bwConfig for
| | 01:38 | reading the configuration file.
| | 01:39 | bwConfig is a very simple library.
| | 01:43 | It reads these configuration files in a
format that I had already been using for
| | 01:47 | a long time with my Perl work
from before I was working on Python.
| | 01:51 | And so I just wanted something that
would read the same configuration file, so I
| | 01:54 | could start replacing a lot of my Perl
scripts with Python scripts, and it was
| | 01:58 | just very easy for me to write that.
| | 02:01 | And the application itself mostly
takes place in this one function, in main.
| | 02:06 | The first thing it does is it goes out
to the database and it grabs a list of
| | 02:10 | all the IDs, and it does this with
this sql_query method which returns a
| | 02:17 | generator which iterates through the results.
| | 02:21 | And iterating through results, I simply take
all of these IDs and add them to this list here.
| | 02:30 | I'm using a list because I need to be
able to delete things from it later.
| | 02:34 | So a tuple would have been immutable.
| | 02:36 | Then I want to know how many records
I'm going to be displaying and so I
| | 02:40 | look for the query string and if there
isn't a query string, that just default to five.
| | 02:46 | And 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:59 | so it's called testimonials.py
with a query string set to 3.
| | 03:05 | And so, that's why we have three
of them displaying on that page.
| | 03:09 | And then, I check and see if we have
enough in the database to be able to
| | 03:13 | display a decent number randomly.
| | 03:15 | I like further to be at least four
times as many records in the database as
| | 03:19 | those that I am displaying.
Otherwise I really don't want to bother doing
| | 03:22 | something random because
it's not going to look random.
| | 03:27 | Now we simply take the list of IDs
and using the random library, which gets
| | 03:36 | imported up at the top here.
| | 03:38 | This is in the standard Python library.
| | 03:42 | It creates a random integer based on
the size of the list minus one, and it
| | 03:49 | grabs a random item from the list of IDs,
and then it deletes that from the list
| | 03:55 | and adds it to the list of
result IDs, which is initialized here.
| | 04:01 | Then once it has that list of result IDs,
| | 04:04 | it simply iterates through that list
and prints the record with that ID.
| | 04:08 | And printing a record with that ID, it
uses the CRUD function getrec and then
| | 04:13 | it simply grabs the data out of the
resulting row factory, indexing on it as if
| | 04:18 | it were a dictionary.
| | 04:19 | We'll go ahead and run this here.
| | 04:21 | Well for our purposes, we're going to need
to reduce this little default down to a three.
| | 04:28 | So I'll save that and run it,
and here we have our result.
| | 04:34 | We have three quotes, and if we run it
again, we get three different quotes and
| | 04:40 | different quotes and you'll notice
that it's all coming out in HTML.
| | 04:46 | So, that's how this application works.
| | 04:49 | Once we have done the back end work of
creating the CRUD, once we have done the
| | 04:53 | back end work of creating a decent
library with easy to use database interface,
| | 04:59 | writing something like this
becomes relatively trivial.
| | 05:03 | And so, here we have it on the
webpage with our random quotes.
| | Collapse this transcript |
|
|
ConclusionGoodbye| 00:00 | In this course my goal was to give
you a good foundation in Python, so you
| | 00:03 | can use it to build powerful and compelling
applications for yourself and for your clients.
| | 00:08 | I've covered the basic syntax of Python,
its data types, features, modules and
| | 00:13 | its object model, and I've walked you
through some real applications, so you
| | 00:17 | can see how to apply your programming
knowledge to building your own projects in Python.
| | 00:22 | I've really enjoyed creating this course
for you and I sincerely hope that it's
| | 00:25 | as useful for you as it has been fun for me.
| | Collapse this transcript |
|
|