 So, we left at this, we stopped at this point that is we wrote the Fibonacci sequence less than n, we ran it and we found that the function works nicely for arbitrary values of input it seems to work. Does it work for the value 0? It does not, but actually it is correct because there is nothing less than 0, it is actually correct should not print anything. If it is 1, it should print 0 because remember I am asking it to print the Fibonacci sequence less than the argument provided, 2, 0, 1, 1. So, all of this works correctly as we expect. Now, your next task is to take the same Fib file that we created. Now, change this example, see the problem with the current example is that we are printing the results. So, the result is no use to us, it is printed to screen, I cannot use the results in any other, at any other point. Does it make sense? When you print the results, they are simply shown on screen. So, if somebody else wants to compute say a Fibonacci sequence and use those numbers say plot it or look at something like that, you cannot do it. So, it makes sense to return the actual values that were generated. So, I want you to now modify this code, take 5 minutes, modify this code and return a list of the numbers that are in the Fibonacci sequence less than n. So, I will change the dock string so that you are able to, this should be very easy to do, but please take the time to actually do it and test it out by knowing run Fib dot pi and calling. Right now it is still printing, you have to make the modifications to return a list, please do this. So, I hope most of you have gotten this, it is very easy again. The solution is to basically say result equals open close bracket. Over here you simply do very small number of changes, already it was added a new variable here is the result, append the current value, finally return result. So, now let us run this and see what happens, very nice. Now, I have the results in the form of a list. Now, this is very useful because I can say r is this and I can now compare this, I can check for the values, I can use this data however I want. If I want to print it, I can print it. So, I can say for i in r print i, and it will give me the output, but now the control is it me, I can decide whether I should print it or whether I want to use it for further processing or anything I want. So, this is a good strategy when you are trying to write code, it is a good idea to return quantities rather than blindly print certain quantities. So, what we look at next is we just finish off these set of slides, there are just a few more slides. We look at a new data type called sets and with that we will finish the slides, the basic slides and then we look at something called modules which will help us understand our python a little better. So, for the sake of completeness we will do the following. So, in addition so far what have we seen? We have seen tuples, strings, lists, dictionaries. Now, in addition to all of these there is another built in data type called set python. So, to create a set, you simply give the set a sequence and it will convert that sequence into a set. So, let us try this. So, our result R here, if I want to convert this result into a set, set R. Now, notice that this set has no repetition of that one. R is 0, 1, 1, 2, remember the figure 1 h sequence has a repetition. First, the third and the second values are the same. But now if I make this a set, S only contains 0, 1, 2, 3, 5 and 8. A set as we all know has unique elements. There is only one element of a kind in a particular set. So, sets are conceptually identical to the sets in mathematics. Duplicate elements are not allowed and there is no ordering of elements. An ordering is something that you impose on a set. The set itself is just a collection. There is no implicit ordering of these elements inside your set. So, do not rely on the set having any particular order. So, do you think this will work? The answer is yes. Set is also iterable. It is also behaves like a sequence. However, do you think this will work? It will not. It is not a sequence. That is, I cannot say S of 0. It has no meaning. But I can iterate over all of them. So, I can say for x in some set and that will work. In addition, you can also do the following. We can check for container shape. So, I can say 0 in S true, 25 in S false, 1 in S true. But I cannot explicitly get one element from it. Now, supposing you have two sets like this F 10 and P 10. F 10 is the set 1, 2, 3, 5, 8. P 10 is the set 2, 3, 5, 7. Let us construct this. Please remember that when you create a set, you have to give it a sequence. Do not give set and forget about these brackets. So, the union of these two sets is obtained using the operator like the R operator. That is the union. So, give me the union of the elements and it will give me a new set. I can find the intersection using the AND. That is just 2, 3, 5. I can find the set difference and I can find a symmetric difference. They are all common set operations. I can check whether, so if I say B is equal to set 1, 2, I can check if B is contained in F 10 and I can check if they are proper. They are just subsets or proper subset. Both of these can be verified. So, for example, B is less than B, no. But if B is than equal to B, yes. Similarly, B is equal to B, yes. B is equal to F 10, no. Standard kind of things. This I have already illustrated. 1 in F 10, 4 in F 10, you can check for container ship. You can iterate over the elements for I in F 10, print I, iterate. You can check for subsets. So, here is a nice example of how sets can be used when you are trying to solve some interesting problem. So, given a list of marks, say 20, 23, 22, 23, list all of the duplicate marks. How will you do that? Here is the solution. Marks is this. The list that is given. Create a set. What will the set do? Set will remove the duplicate. So, it will give me all of the unique elements. Then I look for every element in the mark set. Remove that mark once from the big marks. Whatever marks are remaining will always duplicate and make that into a set and I will get the unique result. So, if you do not follow this example, I suggest you think about it for a little while. It will be obvious. Try to solve the problem. You have these slides. Look at them and you will get a reasonable idea of what is going on. So, with this, we have basically covered our basic Python slides. I will move on to two advanced topics which I believe are of great use to you immediately. So, what we look at first is the notion of modules. So, this is an advanced section. We are just using this Python modules. So, I will quickly answer the questions. How to make an application file of Python like Xe, which we have direct click and run? It is not a trivial thing to do that. There are certain applications depending on the platform you are using. It is not 100 percent easy to do every time, but there are certain applications. There is something called Py2exe. There is something called Installer, all of which will make executables from your Python script. But most often doing this is not very, it is not too meaningful, simply because you will have to bundle Python, bundle all of the libraries, interpreter, everything and your application. So, it becomes a lot. If you want a small hello world program, it will become a lot of code. So, it is usually not a worthwhile idea. Instead, you supply the Python sources and have them install the Python package as a module and you can supply a Python script to run. That is by far the most common thing that people do. So, there are hundreds and thousands of packages in Python. For most of these, you can just, when you download them, what it will do is it will install that as a package and make certain Python scripts available for you. I do not want to get into the details of this process, but basically the idea is you distribute the source code for your Python code and you have the users install a separate your Python interpreter and you run it on top of that interpreter. It is possible to make it a standalone executable, but it is not that straight forward and I do not want to get into the details, but it is possible. It is do a search on Google and you should get plenty of, may not be plenty of information, but you will definitely get some information. The second question is, can we create a GUI application using iPython? Not with iPython, but there are plenty of GUI libraries available for Linux. There is GTK, there is QT, there is TK inter, there is Fluid, FLTK, there are a variety of, there is WX Python. Plenty of user interface toolkits are available in Python. Again, most of these are, all of these that I have mentioned are open source projects. They have plenty of documentation. There are plethora of links available online that will teach you basic programs of how to write simple GUIs using Python. There are many ways to do it. Depending on your choices, what you want to create, there are different approaches to building, but it is certainly a doable task. However, the purpose of this course is to teach you the basics of Python, so that you know enough that next time when you want to do something more advanced, you can always learn it by yourself. It is not too difficult. Once you know the basics and you have a strong foundation in writing functions and maybe later on classes and things like that, it becomes very easy to create your own applications of various types. The last question, what is the difference between difference and symmetric difference as output is same? Well, the output is not the same. There is a difference and I would suggest you find out for yourself, but let that be an exercise. I have answered all the other questions. Let that be an exercise question. So, now, let us move on to modules. So far, we have not used anything called modules in Python. However, the mechanism by which you reuse code and you provide other people with code is to create what are called modules that are installed onto a system and then people can import these modules and use the code that is provided. That is how you are able to build on functionality that other people provide for you. For example, if you want to calculate some mathematical quantities, let us say I want to take the sign of some floating point number. By default, I do not have any sign function. So, if I take sign pi by 2, firstly, pi is not defined. It says name error. Secondly, sign, even of 1.0, sign is not defined. So, it turns out that Python ships with something called standard libraries. That is, there are set of modules that Python installation typically by default will provide for you. To use one of these, you have to first know the name of that library. In this case, if you are looking at mathematical functions, you can say import math. Math happens to be a standard. It is a standard library. So, it is available on any Python. You do not have to do any installation. If you install Python, you will have math. So, math dot sign of math. So, the math now, what is math? Let us see. Math question mark says math is a module and the documentation is saying this module is always available. It provides access to the mathematical functions defined by the C standard. So, what are the methods of math? Do math dot tab. So, you have arc cos, arc cosine, hyperbolic, arc sine, arc sine, hyperbolic, arc tan, ceiling, cosine, the constant e, exponential, f abs, factorial, floor, hypotenuse, log 10, log tan, so on and so forth. So, if I want to do math of sign, I also want pi and notice that pi is also available in math. So, I can say math dot pi and it is a floating point representation to that many places, accurate only to so many places. So, if I want to say sign, notice that is not quite 0. It is 10 to the minus 16, which is effectively 0, as far as you are concerned. Math pi by 2 is 1.2. So, the point here is how did I get this math module? I did import math and to access anything inside math, so math is its own name space. Every function that is defined in math, so math dot sine, it says return the sign of x measured in radians, that is the documentation. So, it is a function. It is a built-in function or method is what it says. So, it is a function that I can call with some argument. So, any name that is available inside a module is accessible by doing math dot sine or math dot cosine or whatever. So, the point is when you do import math, the name space of math is available through the math dot operator. Now, supposing you want to only import sine, you do not care about all the symbols and you do not want to keep typing math dot sine, math dot pi, you can do the following. You can say from math import pi comma sine. Now, I can say sine of… So, in summary, there are two ways by which you can import. You can say import math or you can say from math import something. You can also do from math import star, but I would suggest you do not do it because this will make everything that is available in the math name space and put it into your current name space. This is a bad idea. So, if I have defined some local function or something called E locally that will be overwritten by anything I do in this from math import star. So, it is important that you do not do from any module import star. However, it is also useful to be able to do this on a shell. I want to try something. I want to experiment or do something. I can do it easily. I am lazy. I do not want to type too much. However, when you are writing good code, please avoid using from math import star. In fact, do not use it at all. If you use it, it is bad code. So, this basically, this slide, you will see the relevance of some of this when you do your advanced python session next week. But basically, you will see in the future also from sci pi import star, from pi lab import star. All of these are essentially the same idea. You are importing all the symbols, all the names available inside that module called pi lab and you are able to get them. Similarly, this is just summarizing what we have discussed. Star imports everything from the modules that you have specified, but it imports a lot of unnecessary stuff. Sometimes, two modules may have the same name and they will overwrite each other. You should be careful. So, one way of doing it is to say from sci pi or whatever import linspace pi and sign or from math import pi, sign, cosine or whatever or you just do import sign or math and you do math dot pi or math dot sign. So, in summary, if you look at the shell, this is the essence. You can either do import math or from math import pi or sign from math import star. There is a little more, but this is enough for now. So, the idea is you are able to import modules, use the modules. There are plenty of modules. Typically, if you install a new Python package, it will make certain modules available to you. So, if you want to create a GUI or something like that, again, you will typically end up importing some module that you need to use. Now, let us look at how we can create our own modules. Now, these slides are tailored towards some material that is already there. So, I will skip the slide and I will use the same idea. So, let us look at our own code. Firstly, let us come back to our Fibonacci example. What have we written? We have a function called fib. It takes a single argument called n and it returns a list of all the numbers in the Fibonacci sequence up to that n and less than n. Now, let us say I want to make this into a Python program that I can run from the shell and get the output. So, this is already there. There is already a Python file. Notice that it does nothing. Doing this is similar to what happens if I do percentage run Fib. It does nothing. What do I need to do to change that? I need to actually call something and now also it did not print anything. Why did not it print anything? Because Fib only returns. It returns a list. If something returns something, you are not asked it to print. It is not going to print it. Only on the interactive interpreter, it will return that expression and that will be pasted for you in that out. But if you run it as a Python script, it is not going to output it explicitly to the screen. You want to do that, you must print. Explicitly, you must print. Now it prints that list. So, if you want to print from a Python script, you must explicitly print. You cannot just dump a value and it will come on screen. It will not happen. Now, what is the issue? I have introduced you to modules. It turns out that this Fib.py that we have created is also a module. So, I can use the code from the module by saying import Fib. Now, the problem is I want to only call this function. But when I imported it, it started printing this 0, 1, 1, 2, 2. Why? Because I am printing this Fib here. Basically, when I import, it executes that Python module, gets the namespace of it and gives you that namespace. The problem is in my Python module, I am printing something. So, it is going to print this. However, I can now do. Remember, I have now said import Fib. What are the quantities available inside Fib? What are the names that are available? How do I find out? I can do Fib dot tab. Forget about all the underscore methods and these two are only filename completions. That is not actually a mod, that is not something inside the file. Fib itself contains the Fib function that we wrote. What is this function? This is exactly the documentation string that I wrote. This documentation is now available. Now, I can call this function. So, writing a module is as simple as putting your functions and your variables that are defined into that file. If that file is available on the same directory as your interpreter, you can import that file immediately. So, for example, my current working directory is home slash IITB. Now, if I want to move to slash TMP, let me move to slash TMP. What am I going to do now? I am now going to import Fib. I created the module. The module is in my home directory, but now what is my current working directory slash TMP? Now, if I do import Fib, it says no module name Fib, no problem. You will run into this problem often. So, what you do is, you need to cd to that directory which has your files. So, cd slash home slash IITB or I could do cd tilde, same thing or you could just do cd which will take you to your home directory. But if it is in desktop somewhere or some other file path, you have to make sure you give the proper path relative or absolute depending on where you are. Now, I can do import Fib. Now, I can always do Fib dot Fib and it works. So, writing a module is as simple as creating a dot py file. It has to be a text file, ASCII text file. Writing all your functions and variables inside that. There is only one little problem which we will look at in a short while. So, this example, for example, solves the gcd problem which says gcd of a comma b while b a comma b is b comma a percentage b return a. Now, he is writing some code inside this file to say if gcd of this thing is 4 and gcd of this thing is 1, print everything is ok. If not print something is wrong, some simple file. Now, he does import gcd script just like we did import Fib and it will print something. Now, I do not want it to print this Fib thing. I do not want it to by default print because I only want to call a function just because when I imported math, it did not print anything. I want it like that. I do not want it to unnecessarily be printing. I want to print when I want to print. I do not want it to be automatically printing when I do something. So, to do that what you need to do is, if you need to run anything as a program, you can do the following. I am commenting it out for now. Let us see what this gives us. What I have done is the same old file. I have added this one line below. So, there is a special variable that you can define inside that is automatically defined for you in every module called underscore underscore name underscore underscore. All of these underscore fellows are special names that are kind of hidden from you. You do not have to worry about the details, but in python generally anything with double underscores ending in double underscores is some system variable that is available for your convenience. Name is one of them. So, let us run this program. Python fib dot py. What did it print? It printed main. Now, let me import fib again. I am still in temp. So, cd move back to home directory import fib. It did not print anything. It did not even print main. Does this make sense? It printed nothing. When I ran it, it printed main, which means name is not main now. So, what is name? How do I find out? I would not put it inside this if block. Let me print it outside. It still is not printing. So, there is one thing I did not tell you about. When you import a module, once it is imported, the second time you import, it will only retain the old version of what your file is. It is not going to reread your file. To explicitly do this, you must do reload fib. So, let me quit the interpreter and try this again just to show you. When I do import fib now, what does it say? It prints fib. When I run, it says main twice. Does any of this make sense? My code is simply printing name and if name is equal to main, print name. Let us see what happens if I do fib.underscore name dunder. Notice that name is fib. So, what happens is when python imports a module, the name of that module is set to fib, the name of the module itself. If you run it as a python executable, it will be called main. That is all that is happening. So, in this code, all I am doing is I am saying if name is main, you call this or you print this. Otherwise, do not do anything. Do not call this code. This is inside this if block. So, anything inside this if block will not be executed if this condition is not true. So, if name is fib, it will not execute this block. So, now this will happen, but if I import fib here, it will not print anything. Why? So, what is happening? What is actually happening inside? So, when python imports a module, it starts reading, it reads the code, interprets that code and executes that code, creates a new name space with the name of your module and puts all the symbols that you have defined into that and that becomes your fib module. When it is importing it, name will be main. Therefore, this code block will actually never execute. It will not be run. However, if I ran it like so, name will be main and it will execute that. So, when you write your modules, if you need to run anything as python something, do not just put it here itself. Put an if name equals main to make sure that when somebody imports this code, it does not print out. It does not do that, those functions. When you do that, your module becomes a clean module that other people can use. If not, it will just be printing something, running some code that you are not interested in. So, that is what this slide is saying. When you do import GCD script, the import is successful, but the code gets run. Add the test to the following if block and now the script will run properly as I had explained. Basically, the name is local to every module and will be set to either the module name or to main depending on if it is run as an executable python file name or if it is run as a script. So, what we have learnt now is, how do you write your own modules? What is the answer? Create a .py file, make sure that the name of the file starts with a variable name. You remember I told you a way back, do not create some one .py because I cannot do one, I cannot do import one. The name that you give to import has to be a valid variable name. Therefore, it is a good idea for you to make sure that your modules have valid variable names. The second important thing I conveyed was once you change your file, if you reload it, if you change the file, you have to explicitly reload the module. If you want to get the new definitions, if not you will not get the new definitions. So, with this we will break for T.