 Welcome to this lecture on digital communication using GNU radio. This lecture will be a slide detour from our regular material and this is an optional lecture because in this lecture we are going to look a little bit at the python programming language. As we have been mentioning GNU radio is significantly you know GNU radio significant make significant use of the python programming language and you can use python effectively to extend the functionalities of GNU radio or achieve some functionality that may not be possible easily using the inbuilt blocks. For example, there may be some aspects of processing that can be much easily written in code than use the inbuilt blocks. So in this lecture we are going to give a very brief introduction to the python programming language only for the perspective of writing a little bit of extensions for GNU radio. While this is not mandatory I strongly recommend you to follow along and see the contents that we are presenting and look at the references that are presented at the end so that you can expand on your knowledge of the python programming language. If you wish to follow along with today's lecture but you do not have access to a python installation or you do not want to install it for some reason you can use the google colab oratory which you can just access by searching for google colab and here you actually have what is called a jupiter notebook where you can start entering code and getting them evaluated. This also has most of the features that you will need to get a python for scientific computing experience. If you want to install a separate python installation that is fully featured and can be used for various purposes you can just download the anaconda distribution. Anaconda distribution has lots of packages which allow you to do a lot of useful python related development. In fact radio conda itself is made using the anaconda python distribution. If you have used the radio conda GNU radio installer to install GNU radio on Windows there is an inbuilt python that you can use to access all the features that we are going to discuss today. To access it you need to open the command prompt by clicking on the windows menu and just type in command prompt and once you open the command prompt just make it a little bigger you have to go to the directory in which radio conda is installed. So once you go to the radio conda directory you will see that there is a python.exe. If you just type python enter it gives you access to the python prompt where you can type out all the code that we are doing today and follow along. It includes numpy and all the other libraries that we will discuss as part of our brief python introduction. Over here just to confirm we are creating a numpy array as float and we will just perform some operations and you can clearly see that numpy features are available. The only minor disadvantage is that you may not have autocomplete so it's good to import numpy as np so that you don't have to type numpy each time and you are set to follow along with this lecture. To exit you can type ctrl z followed by enter and that allows you to leave the python prompt. For those who are using either mac or a linux distribution such as ubuntu or debian or the like you can use the inbuilt python by typing python 3 in general for using python 3 and you have access to all the requisite features but for more convenient use just like features with autocomplete and other such benefits it's useful to use ipython 3 if you have it installed since it can make life a lot easier this allows you to use autocomplete and also has good ways to browse your history of course if you don't want to use it that's fine but you can use the python prompt or the ipython prompt in this lecture I will use the ipython prompt all the code that we will type is identical the only difference is that ipython 3 has bit more syntax highlighting and autocompletion. Let us now delve into some of the features of the python programming language that will be useful for us in conjunction with GNU radio. So before we begin this particular prompt where we have this interface to type in commands is also called a REPL that stands for read evaluate print loop that is it reads a command evaluates it prints the result onto the screen and again loop meaning it goes back to reading a command REPLs or REPLs are very convenient because you can do some very quick few lines of code and check that it works before you actually put it together in this particular lecture we are only going to do a REPL based evaluation of python to just talk about some of the basic features of the language at the beginning whenever you have a hash either at the beginning of the line or anywhere in between the hash causes the rest of the line to be ignored and it is syntax for python comments. So let us begin by using python as a calculator. So for example if I do something like 2 times 3 I get 6 if I do 3 times 8 I get 24 this is very easy it is multiplication 4 plus 3 is 7 now all of these are integers. So let us now do something like 2.2 plus 5 and as you can see you get a decimal. Now there is one important point decimals in python which is actually decimals in GNU radio as well because GNU radio is built using python use the float data type that leads to strange effects like this if you do 0.1 plus 0.2 very famous expression it evaluates to 0.3 followed by several zeros and four this leads to a popular issue which you will face when use floating points that is 0.1 plus 0.2 double equal to is a comparison operator in python that compares to values this leads to the popular issue or Conan rum 0.1 plus 0.2 is it equal to 0.3 the answer is false. The reason for this is because floating point arithmetic especially when you use addition does not capture the full accuracy required and therefore you will have several effects like this sometimes it may work for example if I do 0.4 plus 0.1 equal to 0.5 it may work but it does not work all the time so beware. So you are now familiar with two basic data types one is the integer another is the float then there is one more basic there are several of course but let us do one more basic data type that is the string if you say hello python essentially outputs hello in single quote in python you can write strings in both single quote or double quote. So whenever you see this in and out that I python prints those are using regular python it does not print this output prints the expression below this expression is evaluated and the evaluated value is printed here. Let us go to the next step which is variables so if you say x is equal to 30 y is equal to 40 and say x times y you get x is equal to 30 this is an assignment operation it does not return anything x equal to 30 actually evaluates to nothing it just puts the value 30 in the variable x y is equal to 40 puts the value 40 in the variable y and x star y is an expression that is evaluated x is 30 y is put as 40 and the evaluated value is 1200 which is printed onto the screen. Now this is integer multiplication if you want to do something like times 1.0 python automatically converts this to floating point. So this matters a lot when you look at division. So for example if you do something like 4 by 3 you get 1.3333 which makes complete sense because 4 upon 3 is actually 113rd which is 1.33 but 4 upon 2 also is not the number 2 but it is 2.0 so this is something you have to be aware of if you really want to do integer division into 4 double slash 2 which gives you the integer 2. This is something which we have already seen because whenever we do things like SAM, PRATE divided by 2 we always use this double slash so that the result is an integer. So these are some very basic data types and operations in python of course if you want to do more of functions and use functions and modules and things like that you can always just look at other documents but right now we are just interested in these basic aspects that will be useful for us for GNU radio. The next data type that I am going to talk about is the list. So I am going to say L is equal to 1, 2 and hello. So this creates a python list if I say L square bracket 0 I get 1, if I say L square bracket 1 I get 2, L square bracket 2 is hello and if I L square bracket 3 we will give you the index error list index out of range. So you can think of lists as being like arrays except that in python lists can hold any data type in fact lists can also hold other lists and there are several useful features that lists offer for example you can keep adding to a list you can remove elements you can insert elements and so on these are things that you can look at. There are also other data types such as sets and dictionaries but we will skip over them for this discussion. Now there is an important issue with lists which we will face when we perform numerical computation. Let us take an example if you say A1 is 1, 2, 1, 2 or let us say 1, 3, 2 and A2 is 3, 5, 7 a common operation that we want to do is to add these lists as arrays so if you do A1 plus A2 then you actually get the concatenation of these lists while what you would have wanted was 1 plus 3, 3 plus 5, 2 plus 7 and you would have wanted a list which is 4, 8, 9. Unfortunately python lists are generic containers that operate with multiple objects that is you can put numbers, you can put strings and so on so the behavior of the plus is to always just concatenate. The other thing is doing arithmetic using vectors is not really possible or recommended using lists because it is often slow. If you really want to do the addition there is a way in python to do it using what is called list comprehensions so you can do something like i plus j for i in A1 for j in A2 that will give you something like a Cartesian product that is it gives you the 1 plus 3, 1 plus 5, 1 plus 7, 3 plus 3, 3 plus 5, 2 plus 7 and 1 plus 7 plus 5, 3 plus 7 and 2 plus 7. So you get all those in a different order of course but this is also not what we want. We want to combine A1 and A2 together so if you want to do that there is a function called zip so you can do i0 plus i1 in zip A1, A2. What this does is it puts elements from A1 and A2 you know index wise together sorry for i in. This puts elements index wise together and you get what you want so 1 plus 3, 3 plus 5, 2 plus 7 but this is definitely not a convenient way to do arithmetic and we as scientists engineers who are using GNU radio want to be able to perform this kind of arithmetic operations very very effectively. So to handle this we will use a special module which is called numpy, numpy is not included with the default python distribution but it is included along with GNU radio and very very useful for numerical computing. So let us look at numpy very quickly say if we say import numpy import is a special command in python that allows you to expose the features of a library or module that is not available by default. So numpy is a special library to access its features you have to type message import numpy and this expression makes numpy features available to you. Now python is very careful about namespaces that is if you want to like use any of the numpy features for example numpy has a function called sign a sign just type sign it is not defined to access it you have to say numpy dot sign. Now why it does why is this done? The reason is because there may be other modules with the sign functionality for example python has this layer is this module called math which is inbuilt and math has a sign. So this sign is different from the numpy sign the key difference is that numpy sign works on arrays while the math sign works only on numbers so in order to avoid the confusion what python has done is to say okay I am going to let you use the numpy features but every time you have to type the word numpy dot and the function the word numpy dot and the function. So if you want to say create an array you say numpy dot array 123 this creates a numpy array you can't just say array if you really want to say this then there is a way to import it I am not talking about that method because it is not recommended using namespaces is good but because it is very very tedious to keep typing import numpy using numpy dot numpy dot at you know every time there is a convenience feature we can give the module and alias while importing it you can say import numpy as np. So this is something which is very common because many people use many numpy functions but they don't want to import all the functions but they don't want to have to type the word numpy every time so they say import numpy as np. So now let us quickly create some numpy arrays so let's say a1 is np.array let's say a1 3 1 3 2 a2 is np.array minus 3 2 minus 2.2. Now if we type a1 and if we type a2 you can see that there is a subtle difference in the first case it is 1 3 2 without dots indicating that this is an umpy array with integers the second one is an umpy array with floating points now the other thing is unlike lists there is the word array printed around this list like creature so what is the key difference between numpy arrays and lists so one key difference is that numpy arrays would like to hold the same data type that is unlike lists where you can have every element to be a different data type numpy arrays you need to ensure have the same data type the second thing if you look at a1.d type it's int 64 a2.d type is float 64 so the data types also start to matter but when you perform arithmetic numpy still allows you to multiply its integers and floats and it will convert or promote the a1 to float as well when you perform the multiplication let us now begin by performing a simple addition operation say a1 plus a2 you get exactly what is expected 1 adds with minus 3 3 adds with 2 and 2 adds with minus 2.2 this yields 1 minus 3 2 3 plus 2 5 to minus 2.2 minus plus 2 is minus 0.2 this is what we expect similarly if you do a1 times a2 you get element by element multiplication that is 1 times minus 3 3 times 2 2 times minus 2.2 so in this manner numpy arrays are much more convenient to deal with from our perspective of numerical computing and you know using them as ingredients for GNU radio now there are some convenience functions that numpy provides which we will just look at for example let us say you want to generate some random numbers np dot random is a sub module within numpy it is a sub module because it is a module within numpy you can say something np dot random dot random 10 comma 1 which will give you 10 Gaussian random variables you can just say random 10 that will give you a single array 10 1 will give you a 2 dimensional array this will give you 10 random Gaussian values or you can say something like random 0 10 that gives you a random number between 0 and 10 and you can say something like size equal to 10 that gives you 10 random numbers between 0 to 10 of course it's 0 to 9 10 is not included so this way you can generate random numbers but what if you want to define something which is much more common let's say you want to define a particular sequence or waveform or something like that so to generate a set of numbers in numpy you can use two approaches one is linspace and a range so let's say we want to generate something like a sine wave or something like that so you can say t is equal to np dot linspace and we'll say 0 and we'll say let's say 10 and we'll say let's say about 10 numbers in between so what does t have it gives you numbers between 0 and 10 with 10 included equally spaced to give you 10 numbers 1 2 3 4 5 6 7 8 9 10 what are these 0 1 by 9 2 by 9 3 by 9 4 by 9 5 by 9 6 by 9 7 by 9 8 by 9 9 by 9 that gives you all the 10 numbers if you want them to be if you want them to have like spacing which is you know you want them to have integer spacing you have chosen 0 to 10 so instead if you do 0 to 9 you will get these numbers but it's more common to use you know more of numbers because you want to basically divide it into a small part and things like that so for example you get t is linspace you get these numbers similarly you can also use a range so t is equal to np dot a range a range gives you various options so if you say a range 10 then t gives you the numbers from 0 through 9 if you do something like t is equal to np a range 2 through 10 it gives you numbers from 2 through 9 always remember that the last number is not included okay finally let's actually give it a little more useful let's make it a little more useful by adding a step size let's say 0.1 so now this gives you numbers from 2 to just before 10 by adding 0.1 at each step so you get 2 2.1 2.2 2.3 and so on so for those who have used matlab or octave this is closer to that 0 colon so it's a 2 colon 0.1 colon 10 but with the difference that this 9.9 is the number just before 10 and 10 is not included okay okay now let us do something useful let us actually generate a simple waveform let's say t is i'll use np dot a range and let's go from 0 to np dot pi and step 0.01 okay so 0 to pi we have numbers and this the step size between those numbers is 0.01 let's actually perform a trapezoidal integration of something let's say let's integrate sine t from 0 through pi numerically so the function called np dot trapezoid and we're going to type np dot sine t with respect to t now before i press enter those who are interested if you perform the integral of sine from 0 to pi i don't know if you remember or you want to evaluate it i think it works out to the number 2 so as you can see it's 1.999982 which is close to 2 if you want if you want to make it more accurate you can increase the step size or it'll take more time to integrate but it becomes closer and closer to 2 similarly if you now want to integrate cos if you remember cos between 0 and pi goes from the top to the bottom and it integrates to 0 you get 0.0005 so which makes complete sense now there are some more convenience functions in num pi for example there's a very useful function called np dot sync so the sync actually if you just press question mark over here gives you a quick documentation the sync actually does sine pi x by pi x so if you just do np dot sync of t it actually gives you a sequence of numbers in this case goes from 0 and gives you a sequence of numbers that represents sync deliberately i am not showing the plotting over here plotting can be done using a library called matplotlib and that feature is something which you can learn about yourself for us we will can now use these within gnu radio and use the plotting and other such features the final thing i want to mention is that you can get a lot of information about num pi by looking at the num pi website if you go to the num pi website and click documentation then you get a lot of user guides as well where you can go through the process and you can look at an api reference that tells you detailed aspects about all the things that we have seen okay for example how about looking at discrete Fourier transform fft or you can look at some other such features and you can be proficient in num pi knowing num pi is not mandatory but it allows you to use gnu radio more effectively especially in situations where expressing some aspects in python is more effective if you want to learn more about pythons in general you can use the python tutorial the python tutorial is available on the python website so you can just go click on documentation and click tutorial going through this tutorial slowly will be very very useful and instructive while again it is not mandatory it will just make life a lot easier if you have to implement some part of your gnu radio functionality in python now how do we put things together and use python within gnu radio so there are a couple of ways so one way is to just use the python blocks that are available so if you say control f for command f and say python there are three things python block python module and python snippet now python snippet is something which we will not cover because it allows you to modify existing blocks we will use the python block and python module in general the python module is something that we will see but before that there is one more which we want to look at which we have seen already just import so control f for command f and type import so if we now use this import you can double click this import and we always used to say import numpy we can also import numpy as np because it is more convenient then we can actually visualize whatever we were discussing over there so let us actually create a vector source so control f for command f and type vector and we take this vector source and we will take a throttle control f for command f we will grab a throttle we will make this float for convenience throttle also we will make it float and let us now do control f for command f and grab a time sink now we will make this also as float we will add a grid we will also make it auto scale and we will connect our devices over here now let us actually create a vector source consisting of a sink signal so let's double click it and then we will say np dot sink and what goes inside here let's say something called t now if we say okay it's going to give an error if you double click you will find out what the error is it says t is not defined now you must remember that canoe radio companion actually just puts out a python code and this particular python code has np dot sink t but the t is missing now we can actually just write the t over here as np dot arrange and do those things instead it's more convenient for us to take it as a variable and we say control f for command f and type variable keep our variable over here we'll double click this and select this variable and call it t and let's say this is np dot arrange minus 10 to 10 step 0.01 okay so now let us execute this flow graph we will save it as execute this flow graph you can see that you have this varying sink okay it's moving because the width of the time sink and the width of the sink are different we can always adjust it by just making sure that the time sink shows the sink fully just double click this there is a function in python called len that gives you the length of any variable now the length of the sink is equal to the length of t so I am just going to change the number of points to length t and if I do that you can see that the sink essentially stands because the length of the sink is equal to the length of the time sink the length of the sinc signal is equal to the length of the sink time sink so as you can see this is makes it very very convenient now I will just discuss the python block or say python module rather if you want to write a special function that changes some particular aspect of your flow graph then the python module is very very useful so now let us add the module block and now if you double click the python module block the id is the name of the module you can change it to something convenient let's say my module and if you say open an editor you can actually open it in any editor that you desire and start editing the code using something like visual studio code or spider or some such python editor will allow you to get some syntax highlighting and writing assistance so let's actually put our t here so let's say import numpy as np and say t is equal to np.a range say minus 10 10 0.01 of course you can write any other function variable anything over here it is then accessible to your flow graph this is very useful when you want to write multiple lines of code compute something and you know not have that affect your flow graph you know because maybe making it in the flow graph is more complicated so let us now save and exit and say okay now we don't need this t we don't need this np because we have everything in my module so you can just delete this and delete this so now we are just going to say oh we need the import for the sync so let's replace the import so we will just put the import back say import numpy as np and this instead of t we can say my module dot t and over here instead of t we will say my module dot t in fact if it's if you find it inconvenient to keep typing this my module dot t what we could do is we could edit this and say you can say tlen is len of t over here save and exit say okay and we can replace this with tlen my module dot tlen and you have access to all these variables over here if we now execute this it works as expected if you now change this over here and let's say you make this go from let's say minus 5 to 5 you can shorter sync with fewer cycles as you can see fewer cycles and thus you can use these modules features to write more code that you can then start using in your flow graph so this was a quick tour of python for glue radio but I strongly urge you to learn python as and when you need it whenever you get the chance it's very useful and you can also do many more advanced glue radio related work if you have this knowledge in this lecture you saw a very brief but very quick tour of some of the aspects of the python programming language by no means was this a complete picture because python is a general purpose programming language that has vast capabilities and learning python may end up helping you even beyond the scope of this course nevertheless for the purposes of this course I gave you a very brief picture learning this while not mandatory to use glue radio will allow you to achieve some of the functionalities in a much much easier fashion so while it's not compulsory I strongly encourage you to learn python and learn it to the best possible extent so that you can be proficient in both new radio extensions as well as other aspects thank you