Let's talk a little bit about modules.
Python modules are libraries of code and you
can import Python modules using the import statements.
Let's start with a simple case.
We're going to import the math module by saying "import math".
The module comes with several functions.
We're just going to demonstrate a couple of them.
For example, if I wanted to use the value of pi, I would type math.pi
and Python would tell me the value of pi, 3.14, and so on.
The math module also comes with several functions, or methods.
Let's try out the square root function.
To use that, I type math.sqrt and the input argument
is the number that I want the square root to be taken of.
So in this case, I've asked Python to return the value of square root of 10.
Let's do something a little more sophisticated.
What if I wanted to find out the value of sin pi over 2?
Let's first extract the value of pi, which we know is math.pi.
We can then take this number and divide that by 2.
So this is pi over 2.
To take the sin of this number, we say math.sin and use math.pi over 2
as an input to the sin function.
And as expected, Python tells us the sin of pi over 2 is exactly 1.
Sometimes, we don't want to use the entire module.
Perhaps we just want to choose one function from that module.
Let's think about a situation where I just
need to be able to have the value of pi available to me in my program.
So I didn't need anything else from the math library, just the value of pi.
To do that, I can do the following-- I can tell Python from math, import pi.
In this case, Python has imported just the value of pi
from that module and nothing else.
Let's talk a little bit about namespaces.
What is a namespace?
Well namespace is a container of names shared
by objects that typically go together.
And its intention is to prevent naming conflicts.
Perhaps the best way to understand namespace is through an example.
So let's do the following.
Let's import the math module first.
We're then going to import the numpy module as np.
Now, the math module has a square root method, sqrt,
but numpy also has a square root method, sqrt.
What is the difference between these two functions?
Well, let's try an example.
If I type math.sqrt, I can ask Python to calculate
the value of the square root of 2.
I can do the same exact thing using the square root
function from the numpy module.
So far, it appears that these two functions are identical,
but actually these two functions are quite separate
and they exist in different namespaces.
It turns out that the numpy square root function
can do things that the math square root function doesn't know how to do.
Here's a simple example.
What if I wanted to take the square root of not just one number,
but several numbers, say, 2, 3, and 4?
I can do this simultaneously for all of them.
This is not possible using the math square root function.
Let's then talk about the import statement.
What exactly happens when you run the Python import statement?
Three things happen.
The first thing that happens is Python creates
a new namespace for all the objects which are defined in the new module.
So in abstract sense, this is our new namespace.
That's the first step.
The second step that Python does is it executes the code of the module
and it runs it within this newly created namespace.
The third thing that happens is Python creates
a name-- let's say np for numpy-- and this name references this new namespace
object.
So when you call np.sqrt function, Python
is using the sqrt function within the numpy namespace.
Math has its own namespace with its own square root function.
So when you type math.sqrt, Python is calling this sqrt function
within the math namespace.
What if somebody hands you a Python object
and you don't know the type of that object?
Let's see what you can do.
Let's define a Python string.
We're just going to define a name, and we're going to call that name Amy.
If you wanted to know what is the type of this object,
you can use the type function, and Python
will tell you the name is a string.
Now that you know that the object is a string,
we can find out what other methods that are available to you.
You can do this in two different ways.
We can use to dir, dir function, to get a directory of the methods.
So I can type dir name, and Python will give me
a long list of methods that are available to string objects.
An alternative way to do this is instead of using the actual name of the object,
I can use the object type.
In this case, I know that name was a string, so instead of typing name,
I can just type str and Python will give me the same exact list of methods.
So if I wanted to learn more about a specific method,
say, the upper method of strings, what should I do?
Well, the first option is the following.
I can just ask Python for help by typing "help"
and Python will give me a very brief description of the function.
But notice the following-- when I am asking for help,
I need to make sure that I don't actually run that method.
So what's happening here?
Name.upper is a function, or a method, that's bound to a name object.
If I add parentheses to the end, I'm actually calling that method.
I'm asking Python to do something.
In that case, Python is turning the name "Amy," in this case,
into all uppercase.
So if I'm now asking for help, if I type "help" name.upper
and I have the parentheses after upper, I'm effectively asking help on Amy.
So in this case, Python tells me it doesn't have documentation available
for Amy.
So when I'm using the help function, I need
to make sure that I don't actually run the method I'm
interested in getting help for.
The help function is very handy if all you need
is a tiny bit of clarification on how a specific method works.
But if you need more help, then your best bet
is probably to go online and just Google the method in question.