 In this video, we're going to learn how to import further functionalities that exist in Python from the standard library into JupyterLab. So first of all, let's go ahead and create a new file and rename it into standard library stdlib for short. So first of all, let's have a brief discussion of what the standard library is. Let's go to the Python documentation for that. So as we see on the start page of the Python documentation, there are many things and one of them is called the library reference. So let's click on that. And then we'll see the title is going to be the Python standard library. So what is a standard library? Well, in basically a standard library exists in basically any language. So usually it goes like this, a language can see like the very basic building blocks of building a computer program. And then after a while, many different programmers independent of each other start to develop the same thing over and over again, because there's just a certain functionality that you need to get things done to build applications and so on. So in other words, one could say, if programmers were not to share their code with each other, then all the programmers independent of each other would always reinvent the wheel all the time. And that is of course not practical. Therefore, things that are not part of the very core Python language are outsourced, so to say, into what we call the standard library. And from there, you can import them into your program and you can basically use the functionality just as if it were already there. OK, so the only difference from code in the standard library is that you have to import it first. That's the only thing. But other than that, the standard library is always included in any Python installation. So no matter if you installed Python for this course using the official Python.org website or if you went to anaconda.com and installed from there, it doesn't matter. The standard library is always installed with core Python. That is different from so-called third party packages, which we will look into in the next video. But in this video, we are only focusing on the standard library. So let's scroll down here. So first of all, here in the documentation, wherever it says built in something, so built in function, built in constants and so on. That is all the functionality in Python that I refer to as core Python. So this is stuff that we can use without importing. But then if you go further below, these are all the so-called modules and subpackages that we can import. And you can think of that as just a library full of books, right? So if you need to know something, you only have to figure out in which book can you read up the information that you need. Then you just import this package or, so to say, open the correct book. You look up what you need, and then you can reuse it. You don't have to have everything memorized, so to say. And let's see what we find here, generically speaking. So at first, we will find all the different functionalities. They are grouped by a similar functionality. So for example, we have a couple of modules that regard the text processing. Then we have a couple of stuff regarding data types, more advanced data types. So we have seen the list data type so far in this course, but there are, of course, more advanced data types. Then very important, we have here a couple of modules like the math module and the random module that regard working with numbers. So that is something that we will look into in this video. And of course, a lot more like functionality for working with files. So if you want to open and write to different file formats, you can do that. And compression, for example, so using these compression libraries, you can use data or you can put data into a zip file, for example, without installing zip or without using your operating systems, a sipping tool, cryptography here. So if you want to encrypt data or encrypt some secrets, then you should not go ahead and implement that on your own. Most likely you are missing something. And then whatever your secret is, it's not protected quite well. You should always use battle proven libraries such as here, Haslip and so on. And many, many more. So I don't want to go over all of that. You see that it's a lot of data talking. So here's an important one, internet protocols. So if you want to retrieve data from the internet, like for example, for building a scraper, which for data scientist may be a very important topic to look into and many, many more things. Okay, so let's go to the part where we talk about mathematical modules. In particular, for example, here, the math module. And the math module groups together a lot of functionality that we need for doing math that is not part of core Python. So we need to import it first. So let's look at an example. So first of all, how can we get the math module into our JupyterLab notebook here? Well, quite simple. We use the import statement. And we can simply use the name of the module. So I simply say import math and let's execute this code cell. And we see that there is no output below the cell. That means there must be a so-called side effect. And there is. So in memory, what happened is we get back an object. And basically, this object here is like a dictionary. Like dictionary is maybe a wrong word because there is also the dictionary data type. And this is not a dictionary, but this is like a lookup table that knows about all the different things that we just imported. And this is of type module. So a module is basically a file that contains Python code. And we create a variable called math that points to it. And that is so far what we have done in this notebook. So let's see what we can do with it. So whenever you import something and you don't know what functionality comes with it, there are a couple of ways of how to figure that out. First of all, you can use Python's build in help function and call it with math as the argument. And then you get a standardized help message. So standardized meaning here it gives you a list of all the functions that are inside the module and many, many other things. I think when we scroll further down, we should also find the constants. So here the numerical constants e and pi and so on. So there are a couple of, this is one way of getting an overview. And also another function would be to use the build in dir function for directory. So if you pass the dir function, the math as the argument, we get a list. So we see the brackets here, a list of textual objects, so strings. And this is basically all the so-called attributes that the module has. And so this is how you could get an overview. Of course, you should also get used to just simply skimming over and reading the official documentation, right? So that is, of course, also one way. So let's remove this here and now let's see what the math module does. So for example, the math module gives us a couple of constants as we saw. For example, Euler's number, so e, then also, for example, the number pi. And you see that, of course, after a certain number of decimals, the number stopped. And that is due to the fact that both e and pi, which are irrational numbers, which means they have an infinite number of digits after the period dot. Even though they are infinite in theory, of course, a computer only has a finite number of bits in memory, so to say, or finite memory. And both the e and the pi are what, let's use Python's type function. So both of them are floating point numbers. And we have not looked into numeric data types in detail. We will do so in a future video. However, let me tell you that all the floating point objects have the same size in memory. Therefore, the number of digits is pretty much the same for all floating point numbers. And roughly speaking, it is about 13 to 14 digits after the period dot. That's the maximum procession we get using the floating point data type. There are other data types if you need more procession. But that is what we get here. And then, of course, besides these constants, we have a couple of other functions. And probably most notably would be the square root function. So let's have square root here. And if I call the function, let's say, for example, with 2 as the argument, I get back the result 1.4142 and so on. So you may wonder, what is the dot here? The dot is an operator. It's the so-called attribute access operator. We have seen that briefly in a previous video where we talked about what object orientation is. And there we introduced the idea of that every data type has or brings its specific behavior with it that different objects of different data types behave differently. And one regard of behavior was always, what are the methods certain objects come with? So methods were functions that we called on an object. And just like that, we see here, e and pi. They are what we call constants. So they are defined on the math object. And we can access them by saying math dot e, math dot pi, and so on. And here, math dot square root, this looks like a method call. So it looks like an object with a method on it. However, square root is like a real function. So it does not belong to an object. It can live without an object. But it looks like a method call here. But that is due to the fact that using the attribute access operator, this is just a way of how to retrieve objects that are, in this case, sitting, so to say, behind the math module. So let's briefly look into a memory diagram, what we really have here. So let's say here, let's say I have the number pi. And pi is a floating point number. And so pi can be accessed via the math module, by an attribute, and the attribute is called pi. Similarly, I have an attribute e in the math module. And that is basically giving us a way to access the Euler's number e, which is, of course, also a float. And one more example, we saw that square root. So square root will probably be a bigger object. And this is an object of type function, as I said before. And what the attribute access operator, the dot, does, it simply allows us to follow the references here. So whenever we say math dot, that basically means we are following the math variable to the module. And then on the module live various different attributes. Some of them are functions, some of them are constants. And then depending on what we choose, we are following another reference. And then we are getting back a reference to some nested object here. Okay, so this is really what's going on inside the computer's memory. Okay, so that is the math module. And let's see what else we can do with regarding importing things from the standard library. So besides just importing the entire module as a whole, we could also simply go ahead and import an individual function, for example. So in other words, I could say instead of import math, I will say from math import square root. And if I execute this cell, what this basically does is, it creates a new variable called sqrt square root, and that references the square root object within the math module. So in other words, what this line does in memory is the following. It simply goes ahead and in our global namespace, it creates a new variable called sqrt. And this basically references the function object here right away. It's like a shortcut really. But at the end of the day, it's the same function, right? There's no copy pasting going on. Okay, so that is an alternative syntax. And sometimes what you see is the following we could also do from math import e. And then we can extend this statement by saying s, let's say Euler's number. And what that will do is it will work just like the statement above. However, the variable in the global namespace here is not E. So E does not exist. E will give me a name error, but it is Euler's number here, or numbers. I should have done singular here, okay? So let's correct that. That is different ways of how we can import things from the standard library using the math module as the example, okay? So for the remainder of this video, let's continue with a different example, also from the standard library. Let's import the so-called random module. So let's simply say import random. And the random module provides us all kinds of functionality regarding random numbers. And that is very important for data scientists and also for people in the business world because oftentimes we want to build, let's say, an optimization problem or we want to solve an optimization problem. And we have to do so given random data because the future, if we model something regarding the future, it's random. We don't know the future yet. So we are going to build, for example, a Monte Carlo simulation. And for that, we need random numbers. And that is what the random module provides us with. So let's look at a couple of examples. And I'm giving you the most prominent ones. So on the random module, there is a function called random as well. And let's call the random function. And the random function will give us a floating point number randomly drawn between 0 and 1. And it's uniformly distributed. So that is basically what we get here. And we see the numbers look quite random, of course. Inside the computer, note that nothing is really random. A computer is always deterministic. But these numbers are generated with algorithms that basically, such that even statistical tests would think that these numbers are really random. So there is a lot of theory behind that. We are not going into detail here. But that is what we still want a way to use these functions. So now one thing that you often do when you work with the random module is you're going ahead and you will set the so-called random seed. And I think of that as the start value of the sequence of random numbers. It's not really that, but you could think of that. So let's say I set the random seed to 42. And let's execute the random dot random function one more time. And we get back some randomly looking number. And now let's go ahead and copy paste the random seed down here. And let's also go ahead and run the random random function one more time. And we get back exactly the same random number. OK, so this is how you can reseed the random number generator. Why is that important? Well, whenever you build an algorithm that works with random data and Monte Carlo simulation being a very good example of that, then you want the analysis to be totally 100% reproducible. So in other words, you want that if someone else runs the notebook on their laptop, you want to get the exact same outcome. OK, so even when we do a Monte Carlo simulation where we basically get back an average result and a variance among the average results for the variables we are tracking, even then we are interested in being able to perfectly replicate this random sequence. Right, and that is something in science we have to do that. Otherwise, the science is not reproducible. But also in industry, that's probably what you want to do. OK, so that is what you often see. And you can have different random seeds for different functions in the same code base. OK, so this is just a very early example of how to use it, but oftentimes you use the random seed in several places in a big program. So what are other functionalities the random module gives us? So what I personally find quite helpful is the so-called choice function, so random choice. And the choice function takes one argument, which is let's go to the documentation. So that we also read up some documentation. Let's look for the choice function. So here it is. And the choice function, as we see, takes one argument, which is called SQ. SQ stands for sequence. And the sequence is more like it's not a data type, it's more like a concept of a data type. And basically what it is, it's a data type that has elements that come in a certain order. And it must be finite. OK, so we cannot give the choice function an object with modeling infinite data. Maybe you may be wondering right now, how could we have infinite data? But we can model infinite data. We will see that in a future video. But for now, let's just keep things simple. And let's go ahead and give it a list object. We know what lists are already. And let's basically make, let's model the tossing of dice or throwing a dice. OK, so throwing dice is the example. So we have six different sides. And what the random choice function does, it draws one element randomly out of the list. OK, and let's say if I wanted to make the die unfair, if they want to make the number six more likely than other numbers, then all I have to do is, let's say I want to make six three times as likely as five. Well, then I just put in three sixes. And then the number six should come up a whole lot more often here. OK, so that's the random choice function. That's quite nice. And sometimes when we are working with like a full sequence of data, when a full sequence of integers where no integers missing, just like, for example, random choice without several sixes, then what we could do is we could instead use the so-called rent int function. And rent int takes two arguments. The first one being the lower bound, the second one being the upper bound, both including, so let's give it the one and the six. And the second cell here, the lower cell, will do exactly what the upper cell now does with just less writing. OK, so these are a couple of nice functions. And we will see them in a future video when we write our own little simulations and games in this course. And they are really helpful. And oftentimes they are more than enough to build a very complicated Monte Carlo simulation. So you can get very, very far with the random module already. OK, so but that is it here. And the main goal of this video was not to introduce the random module but to give you an example of how we can extend functionality of our programs using the standard library. OK, that is the important idea here. So I see you in the next video where we'll talk about extending our notebook even further by not only using the standard library but by even installing software that does not come with Python, by software that other people have written, that we can still obtain and install, but that does not come with Python, by default. OK, see you in the next video.