 Hello, everyone. Our next speaker for the day is Tushar Sadhwani. He's going to talk about path to Pythonic. So welcome, Tushar, to the stage. The stage is all yours. OK. Yeah. So this talk is going to be about Pythonic code and what Pythonic really means. How to identify code that's Pythonic, how to identify code that's not Pythonic, and how to fix it. So yeah, let's get into it. And yeah, first of all, I think I should start with a disclaimer that this piece of code right here, nobody should ever write code like the one that's shown on the first slide. Because if you take a look, that's 13 lines of code just get to write the hello world. And if you're writing 13 lines of code in Python, you're for writing a hello world, something has obviously gone wrong. And guess what's so wrong with that code? Well, the issue is, it's not like the code doesn't run. The only issue with the code is that the code is non-Pythonic. And it's written in a non-Pythonic way. But why exactly is that? And what does that mean? And so yeah, before we can talk about that, let's actually try to make the code Pythonic. So whatever that means. So the first thing that I would like to point out is this function right here, getMessage. Now, this is what you would call a geter method in quite a lot of languages. But this Python has its own idea of geters and setters. And yet to make those, you use something called a property decorator. And what this gives us is that once this method has been made a property, so you don't have to call the get underscore message method everywhere, you can treat the property itself like a variable that's in the class. So that cleans up the main method quite a bit. But now, the main thing is that you might notice that this class has one constructor that sets a property. And it has one method that makes use of that property. Do you know what this construct is called? It's called a function. So yeah. And converting the class into a function, that wasn't really much of work either way. So all I had to do was take the function signature from the constructor and take the body from the main method. And the whole class just collapses into one function. And so this is starting to look quite a lot more like a Python hello world. Now, the only last thing that has to be improved is these calls at the bottom called side effects. But they should always be guarded with a name call in Python. And that doesn't really change how the code functions. But just make sure that these side effects, things like printing to the console, taking some input from the user or starting an application, things like that, though it should be guarded like this, you have to make sure that when you try to import this file into another file, these things don't run at that time. So yeah. So what's the point of all this? That I'm trying to say that this piece of code is not and this piece of code is Python. The point I'm trying to make is that Python has a specific style of writing code. But why exactly is this Python? So if you try to search on the internet, why does Python feel like to write code in this way or something like that? People would point you to things like the official Python tutorial that says things like Python is supposed to be very easy to learn, very easy to write, and to be very powerful. Or you will get things like the Zen of Python that has 20 or so lines that explain what Python code should look like. But this is quite subjective, isn't it? There's no actionable thing that I can take away from this. So that's what I'm here for. So I have a simple question. How do I make my code more Pythonic? And there is some common advice that you would get is things like you have to make sure about separation of concerns, to make sure that the code is properly refactored, or even things like you have to use more of Python's built-ins. And yeah, they're not wrong. But in totality, the underlying idea is all about the readability of the code. That you want to improve the readability and you want to reduce all the boilerplate that's in your Python code. So that's it with the theory part of it. And let's jump into an example. So hopefully the text is still visible. But yeah, just on the left-hand side, we have some library code that's defining an API. And here we are doing things like we are creating a request object, we are adding an API header to it. And that has one method to get users. That takes the count of the number of users that we want to return. And it's making the final URL. It's making a request. It's loading the JSON data, then it's returning that. And on the right-hand side, we have a CLI application that's making the use of the API. Then it's also making a cache. And this also has one method, print user names, which is doing quite a lot of things, like keeping track of the time fetching data either from the cache or from the API, then printing it out, doing some funky stuff over here. And then it's printing out how long it took to make that request. And then we have some driver code over here. Now, to see what the output is, it's quite simple. You give the application a number, then it here fetches that many people from the API, and it prints that it took this long. And then given we tried to fetch it again, the data is cached, so it takes no time at all. Now, what can be made better with the code? So the first thing is going to be separation of concerns. And what that means is that with the distinct logic pieces from your code, they should be separated from each other by using the things like functions or decorators. And quite a good example would be the timing logic that was inside the print username function. That can be taken out into a decorator, time it. And that's going to be slapped on top of the function. And all it's going to do is it's going to track the time before, track the time after, calculate the duration, and print it out. So the print function doesn't have to concern itself with the timing logic. So that's the separation of concerns. And we can take it a step further, because the print function doesn't really need to know how the data was fetched. So that can be factored out into its own function. And now the print function looks quite a lot simple. It has only two pieces of logic right here. And we can take it just a little bit further. They were doing some fancy stuff here. They were doing the range of linear fuselage. And then they were also doing i plus 1. So the idea here is idea. So the idea is that if you want the index and the value at the same time, and you want the index to start at 1, so for a really common task like this, the Python here gives you quite a lot of built-ins that can be used to simplify your code. So here, we are going to use enumerate. And we are going to give the start value of 1. So that's going to give us the index and the value at the same time. So that's already quite a lot more readable. And the last improvement that we can make here is this thing, where we are opening some resource, we're doing something with the data, and then we're closing it. Now, this construct can be transformed into a context manager in Python that makes sure that the resource is properly closed every time. And so that's a slight bit more readable. And yeah, so that's the end result. Thar code has become quite a bit more smaller. See, it's more modular. But the most important thing is it's much easier to read what's going on in any part of the code. So that's what it's all about. And now we are going to take a look at a slightly more contrived example. And so before I go into this, I should probably show the output. And this is all this code is trying to do is we are taking an HTML file, and it's here converting the RGB values in the code into the corresponding text values. So now let's take a look at the code. So it's doing things like it's reading the HTML file. It's getting the lines. We are doing a for loop over them. It's using some regular expressions here to match the RGB construct. That is very kindly explained with a comment over here. And then we take out the red, green, and blue values like this, apparently. And then we are doing this on key stuff over here. That's we're taking the red, green, and blue value, converting it here to an integer. Then into a hexadecimal. And then you're doing this slicing thing to get rid of the 0x in the front. And that's joining it all together. So that's our hex value. And then we replace the RGB value with the hex value. So that's all it's doing. But there's quite a lot of scope for improvement over here. So let's improve the code. So the first thing is going to be this part of the code over here. So reading the file in Python, just to iterate over the lines. That's kind of an anti-pattern in Python. Because if the file object itself, that can be given a for loop. And Python is going to give you the lines one by one by itself. So this piece of logic you don't have to worry about. There's also the regular expression logic. So the point is if you don't have to use regex, you should avoid using regex. Then in our case, that's exactly what it is. So you can simply use a dot find here to find where the RGB line is. And if it's present in the code, we just use dot split here to find the integer values. And now, this piece of code that it does all the fancy parsing, turns out that's completely unnecessary because of this thing called Python's string formatting built-ins. And so what's going on in here is we're giving it an integer. And we're telling it that if you want to convert it into a hexadecimal value, that's two characters long. And we want to pair it with zeros if it's smaller than two values. So that whole thing can be condensed into a single line with thanks to some of the Python's built-ins. And so the last change that we're going to make is this, that since we're only reading it line by line, we don't really need to store the lines themselves in the code. And that actually makes quite a big difference because let's say that we're using a very large HTML file. So if the ran usage of a code, that's going to go from potentially multiple megabytes to basically nothing at all. So that's a big win. They buy simply, they're reading one line and then writing one line at the same time. And yeah, that's the final output. And the code has become 40% smaller. It uses a significantly less amount of RAM. But the important part is that it's much more readable. And we didn't even have to write any comments to try and explain what's going on. So that's basically what it's all about. It's about the readability and it's about reducing the volume that in the code. So that was the main part of the talk. Now I have a few tips and tricks on how to improve the readability of your code. And the first one is to get to use the obvious one is to use the proper names for your variables. And take a look at this piece of code. It's pretty much impossible to tell for sure what it's trying to do. But this is the same code, but with much better variables. And you can try to tell in five seconds what exactly is going on. So yeah. And the second tip that's going to be about using is some of the newer things in Python. Things like list comprehension, conditional expressions, the spread operator, things that are novel to Python, but are actually really powerful. Because they're very concise and they're very expressive. So you can do things like creating a list of squares from a range by doing a single line of a list comprehension. So you can do things like joining two lists by using the spread operator. So this one is interesting. You can do things like taking out the mid part of a list by a single line. So yeah, these very small improvements like this can take quite a long way in trying to make your code seem much more readable and quite a lot more Pythonic. And the last tip from my side is going to be to start using a code formator, like for example, black or auto-pipate. And that's because you should never have to worry about formatting your own code, because the computer can do it for you. And that's a good thing because the less that you have to think about formatting your own code, the more you can focus on actually writing that code. So these are my recommendations for using a code formator that are going to be black and auto-pipate. If you're starting out, you should probably look at auto-pipate because that's quite a bit more, what do you say, the lenient in terms of its formatting while black is quite a lot more strict. So definitely take a look at those. And that's about it. So I have a few resources for you to take a look at. So there were a bunch of links in the slides that I've shown. And you can access those by going to the presentation at tshr.me slash Pythonic. You can take a look at all of the source code that was in the slides. That's on my GitHub. With the official Python tutorial that I mentioned, that's available on docs.python.org. And basically everyone should try to read the entire thing because it's quite nice. And in the end, there's also a few talks by Raymond Hettinger, which they're going to quite a lot more detail on to what Pythonic really means and how to get there. So yeah, that's basically it from my side. Yeah, thanks a lot for joining. Thank you, Tushar. Thank you. That was a really interesting talk. And I could completely relate to the point which you are trying to make in this point. I have seen people who write, like if they are from a CE background or Java background, when they come to Python, they are still continuing that legacy into Python. Yeah, exactly. So powerful utilities like list comprehension, map, zip. Those are the things which people usually don't use. They do that manual stuff. Then there is no point in writing a Python code. You can continue the C itself. Yeah, exactly. And also, I love one point which you made about the code formatting black and auto-piped. So in Visual Studio, we do have options to set the formatter to black and auto-piped. So you just save your code and it will be automatically done for you. You don't have to do it manually as well. So your code would be a standard code and stuff. So yep, right. So let's see if we have any comments. Guys, please do post your questions in Q&A. And post the sessions. If you have any query, we are posting a Zulip link in the chat where a speaker would be directly available so that you can interact with the speaker. So yeah, we'll just wait for a few moments to check if we have any other queries. There's a comment from Burden saying really awesome session to share. Yeah, thanks a lot, Burden. So the slides are available. One sec. So the link is this, tshr.me slash pythonic. And that will take you straight to the presentation. And the source code is also available on my GitHub. Thank you, Harpreet. So it's a real appreciation, Tushar. You indeed deserve it. Yeah, thanks a lot, everyone. Great. So I have one question just coming up. Do you need docs or site where we can still want to put pythonic? Now there's a bunch. Like there's also my blog right here, Sardot Life that you can take a look at my Twitter. But apart from that, we also have quite a few people. Let's just try and, can I do that? Let's see. No, that's not going to work. Yeah, so the links, there's a few YouTube channels and some blogs that I can share with you probably on the Zulip chat. So they do connect with me there. Great. We have one more question. I'll just show it quickly. How to make use of variables created inside multiple if conditions? How to make use of variables created? Oh, yeah. So the Python is a function scored as it, as you know. And so that's kind of a non-issue in Python because you can create a variable inside the wave condition. They're depending on the condition. And that's going to be directly available outside the condition. So that's kind of a non-issue in Python. That's an issue in many of the languages like JavaScript. But yeah, Python is quite good with it. Yes, like it's restricted to score, right? So it doesn't make sense to access it outside where it is defined. So if you want to make it use of it, declare it globally. That's the only way. You know what? So for example, in JavaScript, if you want to define a variable's value depending on a condition, you have to give it a value first. Say for example, like null. But in Python, you don't have to do that. You can actually define it inside the condition. And it's going to be available in the entire function after that. Yeah, so that's actually really nice. True.