 basically I'm going on to the packages and plotting notebook, so that is notebook number five. So you can follow along from there. And of course, yeah, it is good to basically type everything I type as well. Okay, but yeah, so Julia has a huge ecosystem of different useful packages. This number, over 4,000 registered packages is probably very old and it's probably more than double of that. By now. But even beyond that, it has packages called PyCall, for example, to call import and call any Python function, any Python package, an R call to call any R package, or any R function. So if something is missing that you want to use in Julia, you can always use Python or R functions. It has, it can essentially natively call C functions. So if something is in a C library or well, I mean, it C libraries object file. So if it's compiled from Fortran C++ C, you can call it directly. Now that I think about it actually C++ you would need to know the mangle name of the function. So that's a lot more complicated. But in principle, you can do it. Right. So let's actually show this. So you can check out the Julia registries, which is a GitHub page to see the available packages. So this is a huge list. This is kind of the official registry of Julia packages. It also has instructions for how to register your own package. Then there's the Julia observer. It also has a list of packages and you can search from the website. Example is a an existing package. Okay, I guess the search will take a little while. Also have a note in here. Julia hub. Yes, since I'm going into it at this point. Okay. Well, it's not that hard to find Julia hub. So Julia hub is probably the an easier or a better more efficient way of searching for packages. It has some some other uses as well. So they offer some services for running Julia in the cloud, for example. So yeah, Julia long example is the package I was looking for. You can find the link to the documentation, the repository tells you what the license is and who's working on it. So yeah, the documentation for the example package is quite short. It has two functions. Hello and do math and do math adds five to a number. Hello is essentially the hello world. Well, it takes in a name and says hello to that name, which we already wrote. We already wrote that function basically. So let's install the example package. I'm just to recap. So to install package, you run using package using PKG. And then PKG contains the packet at the function add so package dot add example. This will install the example package. It's no output yet. All right, there we go. So no changes. So I guess it was already installed. So it will probably print a little bit more stuff for you. Okay, then to use a package, the standard thing is to use the using keyword, which will pull some functions from the package into the main namespace. And now, so you saw that the example package contained a function called hello. So the hello is in fact now in the main namespace. And we need to give it a name to say hello to. And it prints Hello Julia. Okay. Another way of using a package, this is more familiar to Python users is to use the import keyword. Now, the import keyword doesn't introduce any functions or any new names to the main namespace. So if we didn't run using example, but just run import example, then the hello function wouldn't be available. Actually, maybe it's just best to demonstrate that. But since we already did using example, we need to get rid of it by restarting. So now if you run import example, okay, now starting, please wait. There we go. Hello is not defined. There is no function called hello. But there is a function called example dot hello. So this is very familiar if you're using Python. And the first option is maybe more familiar if you're using R. And it's up to you really which one you use. If you use the Python type, like I am, you might expect that there's a lot of name collisions when a lot of packages import something, I mean export something with the same name. So two packages have the function hello. And then, well, which one is, how do you make, how does it decide which function to run? Well, that's what multiple dispatch is for. So as long as they don't have the same input types, Julia will always know which function to run. Now, import can still be very useful for many things. One is you can do a limited import. So you can do import example dot hello. And you can do aliasing. So this will, if you run this, it will import, it will just take example dot hello. And now that will be available. And it will be available with the name example dot hello. We already had that. So that's not much of a demonstration. But you can give it a new name. So you can import something as hello to if you're afraid of or if there is namespace collision, this will get rid of that namespace problem like this. So now there's a function called hello to you can also import the entire example package as let's say e to give it a quick shortcut. And now we have e dot hello like this. Okay, so yeah, that's the import keyword. It's also useful even if you're mostly just using the using keyword. Okay. Oh, I actually found the link to Julia Hub. Well, fine. I already showed it to you. But there is also a notebook called zero nine ecosystems ecosystem. And this notebook has a list of a bunch of packages, some generally useful. And then for different fields. So this may be what you are looking for, or maybe what is useful in your field. Here is also here in link to the Julia Hub. But they are writing just Julia Hub into Google or writing, or any search engine or writing Julia registry into any search engine will give you the right answer generally. Okay, so they've already been installing packages, but it is good to have some do some yourself. Actually, yeah, I will show a quick example of another thing. And then we will do exercise number one, two, and three at the same time in one go. So, because this is also a question that has been asked a couple of times. So Julia provides a very, very good interoperability interoperability with other languages. So even though it is trying to solve the two language problem, it doesn't it is newer than some other languages, of course. So the other languages may have some packages that you just want to call directly from them. Now, the first, first I will demonstrate how to do this with Python. If you don't have Python installed, then this will not work or it may not work. But if you if you are using Python, then you will have it installed and this will work. So I mean, if you don't use Python, then you don't need to care. And then you can also skip the Python exercise. So there is a package.py call. So what I'm writing here is to add the package.py call. Let's run that. Whoops, that is the wrong name. So I'll have to wait for it to finish. This is actually not trusted right now. It's probably good to trust it. Okay, that will also restart this and I can run. So install the package called PyCall with a capital C. Okay, no changes. Using PyCall. So PyCall is for calling Python packages. So once you have written using PyCall, you can run but you can import Python libraries using the PyImport macro. So it starts with an at. Let's do scipy.optimize and we'll call it so. So for scipy.optimize scipy.optimize contains the Newton's over. We'll need to give it a function. So we'll use an anonymous function. Let's just take cosine of x minus x. So that one has a clear minimum. Sorry, a clear maximum. Is that true? It doesn't really have either. How does it? No. Okay, we'll see what it does. You can ask Julia. You can plot the function and see what it looks like. Yeah. Well, we didn't use the plot library. That's coming very quickly. Okay, well, it did find what it thinks is a minimum. I guess it's between some range. One is, I guess, the starting point for the Newton iteration. Of course, this is a Newton's over. So it will just converge at some, probably a minimum. Okay. Next, let's call a C library. So for that, we don't need to install anything. This is native. It's a function called C call. I keep saying C, but Fortran libraries are exactly the same. So any object files, any libraries you can call in this way. This is in the standard libraries. I'm calling the clock function and you do need to call in here. So I'm calling the clock function here. It returns an integer. So we'll convert it to a Julia in 32 type integer and it doesn't have any parameters. So we'll just have an empty tuple here, which means no parameters. Okay. And it returns the time. Now this syntax is maybe not the most clear. So let's call a function that takes some parameters. Print F and it also in fact returns an in 32 because it's a C function. It returns one or zero depending on whether it was successful. But it takes an input parameter and the parameter is a string. So there is a type C string in Julia or, I mean, well, I guess it's a type C string. It goes, I mean, it turns a string from Julia into a string that is the C function can accept. And we'll print hello. I guess we need a comma here. So this string is now the input parameter for the print F function. Okay. So it prints hello, as we expect. It returns six. I'm not sure what the print F return values mean. But oh, that's what it returns. Now one more quick demonstration of this, because mostly you would want, you don't want to call the standard C library functions. They are already there in Julia. What you want to do is call functions you have written yourself that are in some library in your system. So I'm going to call print F again. But I'm going to specify what library to call it from. And that is libc.so.6. And again, it returns in 32. It takes a string. And that string is hello. So it will now look for this library in the LB library path to the link library path. And it will run, find this symbol from it and run it if it's a function or try to run it as a function. Okay, and that works. Now this is just on my system. I'm, as you know, these names can be different on different systems. So, so yeah, you will need, you will basically need to compile your code, your C code into a library and know the name of the library. If you're on a boon to this will probably work as I've written it. Okay. So there are some others are called, which I already mentioned, the CXXWrap. That's nice because yeah, like I said, there's the mangled names problem in C++. So yeah, you can call C++ functions. And then there's, well, you can also call Matlab, Java, Mathematica, even Objective C, anything basically. So if you're interested in one of those languages, follow the links to see how it works. Yeah, I wanted to add a smaller thing about this whole interoperability in Julia. That in Julia, there's also, well, it's more advanced, but there's this box called binary builder, which you can actually use to compile a third party like libraries into executables that Julia understands. So that if you have like a software open source, which is written, for example, in C or in C++, then you can use this binary builder to compile it into a binary executable that Julia can understand and reads and so can add this binary dependency to your Julia software. So if someone has been developing a C++ software since the 50s, you don't have to catch up with the 70 years of work, you can just compile that, well, not just it's sometimes a little tricky, but you can compile that C++ or C library into a binary that Julia understands at that binary dependency and then just write a wrapper for that and build on top of that. Yeah, okay. So it's a nice addition for the topic. I can add the link to the repository of this package with the HackMD. Yeah, that's good. Yeah, if you add it to the HackMD, I mean, of course, it's also good to add it to the repository. Yeah, so that's good to know. Okay, so now we have exercise one, it's all the way up here, install the package called primes and then try to figure out how do you list the first 100 primes? No, list all the primes that are smaller than 100 actually. Okay. And yeah, it is giving you a hint that there is something called primes you need to search the help for. And then if you're interested, try calling a C function or a Python function. And once you are done with the one exercise you most want to do, put up a green checkmark and continue to the others. But I did yesterday many times, which is to track a window and stop sharing by mistake. Okay, there we are. Yeah, so that's solved. So, okay, so searching primes returns collection of prime numbers from low if specified to high. Okay, I guess that is enough to figure out that. So if you know that syntax, it means that you don't have to specify it. You can though, so we can specify anything from zero to 100. And that will give us all the primes between zero and 100. But yeah, just using primes 100 will work. Okay, so for calling, have I left the solutions into these exercises? I am really sorry if I have. Yeah, either this is on my notebook only or it's for you as well. Great. Well, fine. I mean, the solutions are available anyway. But it's not great if you can see them before you even start the exercise. So I'm looking here to figure out what to do. So to call cosine, you specify that you want the cosine function with this colon that sort of did say name in C, not a name in Julia. It will return a float. I think a float 32 or 64. Let's say 64. It takes in as a parameter a float 64, and we will have use pi as the input. Okay, and it returns minus one, which is exactly what it should. Okay. And to run math, let's call cosine. So in Python, we would need to import math. So we'll do that using pi import. So add pi import and import math. Now, if you just run this, oh, pi import not defined. Okay. So at some point, I have restarted this, the shell. I don't have pi call anymore. So let's say using pi call. Okay. Oh, because this is the different notebook, right? Pi import math works. So yeah, we could just do that. Math dot cosine pi. Okay. So this is basically the standard syntax for Python, but it just happens to coincide with Julia syntax. So once you've done pi import a package, it's now it's now a name in Julia. It's basically like if you had done import package in Julia. So now we can run math dot cosine in Python. Okay. Now I should make sure that these get removed.