Level up your Python: Best Practices for Clean and Consistent Code
45 min video / 30 minute readSpeakers
César Román
Global IS Manufacturing Manager
Pyrotek
Gain valuable insights into writing clean and maintainable Python code, whether you're a Python beginner or a seasoned developer. In this session, you’ll get practical knowledge of PEP 8, explore best practices for code formatting and style, and discover tools to streamline your workflow.
Transcript:
00:50
Chris Andersen: Ready. All right, everyone, we're gonna go ahead and get started. My name is Chris Andersen. I am a technical sales rep here at Inductive Automation. And welcome to today's session. It's called "Level Up Your Python Best Practices For Clean And Consistent Code," and I'll be your moderator today. To start things off, I'm gonna introduce César over here. I've had the pleasure of working with him for the last year. But a little bit of background on him leveraging his strong foundation of computer science and proficiency in C++, Java, and C#. César joined PyroTech in 2012 as a senior software engineer. A year later, he did a five-day course with RO and Bobby McKinsey, and that kind of sparked his passion for Ignition. Ignition's ease of use the flexibility perfectly aligned with César's interests and also led him into Python, which became his preferred programming language. This ignited, pun intended, his journey to become PyroTech's first skated developer, and he's a Vision veteran today. Today César leads PyroTech's information systems manufacturing team, overseeing all of Ignition's deployments globally. So please help me welcome César to the stage.
01:19
César: Thank you. Thank you, sir. All right. Hello. Hey, hi, everybody. Well, I wasn't expecting this large of a crowd with an appetite for Python, but yeah, welcome everybody. So as first Chris introduced me, yes, I've been with PyroTech, and as a software engineer, I started my career with C#. I jumped into Python as soon as I started working on Ignition. So the experience that I've had with Python so far led me into publishing these packages. I don't know; I'm just gonna have to do this. Show of hands, who's installed Ignition API? All right, none. All right, there. So the point of Ignition API in this case is to allow you to get code completion. If you're working on your scripting projects from an IDE like Visual Studio Code or PyCharm, you get the system library code completion there. Another one of the projects that I used to have on the Ignition Exchange is Incendium, which is a library that sits on top of Ignition API as well and enhances or makes some things easier, like working with stored procedures, databases, and also with Vision components like alerting and messages.
02:53
César: Another thing that eventually happened: I'm also interested in CI and CD, and recently... Well, not recently, a couple of years ago, GitHub, which is also the backend that Azure DevOps uses for running CI/CD on their images or runners, dropped support for Python 2.7. So that's when I created this Docker image called Six. Well, naming is always interesting. So I took some inspiration from another package called Six from the Python library that gives support for both 2 and 3. So this is what I've done. And these projects have given me the opportunity and experience to use all these coding standards and things that I'm gonna be touching upon. Where you can find me? These are the links. So yeah, let's get started. This is the agenda for this session. We have coding standards, style guides, and the tool set. Well, I don't know if you were expecting that. This is not gonna be specifically a hands-on presentation. I will give you the theory behind it, the tools that you might be able to apply eventually. But yeah, of course, if you have any questions, not just here in this session, please feel free to reach out.
04:27
César: So yeah, let's get started with coding standards. In this case, what are coding standards? As it says right here, coding standards, also known as coding guidelines or style guides, are a set of rules or of conventions that developers use when writing code. These coding standards are important because they provide consistency. In this case, they ensure consistency by improving reliability, maintainability, and improving collaboration within a code base. So when you set these guidelines, Me I started as a sole developer. So setting standards for myself was extremely easy. But as soon as my team started growing, I felt the need to create those guides internally so we can follow them. So these guidelines, for consistency purposes, do you establish or they establish a uniform standard for writing code and ensure that your projects adhere to a consistent format and style? They improve readability because they promote code that is easy to read and understand. By following the specific conventions for formatting, developers can improve the overall readability of their code.
06:00
César: They also improve on maintainability because your code is consistent, not just in only one single application, but across all of your applications or all of your portfolio. You can achieve that maintainability because your code is following a standard style. They also improve us as well, collaboration, because onboarding a new member, just giving or sharing with them the guidelines that you use, the style that you have chosen, makes it fairly easy for them to understand and follow the guide. So in this case, it will reduce misunderstandings, potentially, and ensure that code is written in a consistent manner. And by that as well, a secondary effect to that is efficiency. So if you follow the same style for every application that you create, all the code that you write, it improves the consistency because it might reduce errors and improve development speed. Finally, quality. One of the things as well, well-structured code, often will lead to higher-quality software, which will also be a testament to your customers in this case. If they get to see that your code is well-structured, it not only works good but it also looks good. It also improves on that.
07:29
César: So one of the key components, among others, but these are some that I'm gonna be touching upon on this session, is naming conventions, indentation, sorry, and spacing. And lastly, commenting and documentation. So in this case, naming conventions it means that you should use a consistent naming for variables, functions, classes, and it goes in this case for Ignition into components on your UI, whether Perspective or Vision. In indentation, you have a consistent pattern. The eternal battle, I would say, that between tabs versus spaces, so we will touch upon that as well. And commenting, well-documented or code that is commented in a good way it is easier to understand. Instead of just the code sitting there, having a docstring there will let other developers, not only you to fully understand what's the function's purpose. In this case, while naming conventions, some of the guidelines that you may run into, or you may see online, touch upon these styles. So just to go through a few of them, you will see words thrown out as Camel Case, Pascal Case, Snake Case, uppercase, and Hungarian notation.
09:05 César: So in this Camel Case, as you can see, it's just, oh yeah, you see that this is like the hump of the camel; you start with the lowercase and then the next word is with uppercase. Pascal Case starts with an uppercase, Snake Case all lowercase, and each word is separated by an underscore. This is the same thing, or this is also Snake Uppercase. And lastly, Hungarian notation. So we will touch upon this in a moment. And this would be an example, for example, well, an example for Camel Case and Pascal Case. So you would see this in Java code, or this is some code that is from using the Java standard, so you will see like classes using Pascal Case, variables in here, and methods also using Camel Case, and it is fairly easy to read if you were to have or if you were to follow something else or lowercase and no spaces between them, it would be a little bit harder to understand. Some cases, for example, this might be something that you would run into if you look at Python code online, is following the Snake Case standard. So you would see this method or function following that convention, also variables in here, the ones that they receive and internal.
10:38
César: And also, it's fairly easy to understand. Some other naming convention, as you can see here, Hungarian notation. Back in the past, it was used for saying that if it starts with an I, because it's an integer. So it was being used like that. In my case, in particular, I used it for GUI components. So for example, all my buttons start with BTN, all my checkboxes with CHK. Not just, so it is also easy to see on the tree view on the side in case, well, referring to the Ignition designer, it's just very easy to know what component we're looking at. So up next, style guides. Also some key guidelines of style, well, sorry, style guides they enhance reliability. So you're gonna see that some of these concepts we have already touched upon in coding standards. In this case, style guides are the ones that provide a better description of the coding standards. It not just only touches on code, because, as you could see, coding standards was just naming, for example, and indentation.
12:02
César: In this case, these style guides touch on other things like importing, but yeah, we'll touch upon that in a couple of slides. So again, they enhance readability. That's their purpose, making code easier to read and understand. Also, facilitate maintenance, as we already have covered, because code that is easy to understand and easy to read it should be very easy to maintain. So, yes, again, we touch on collaboration. Teams or large teams, or all of the members, if they adhere to the style guide, the coding standards, and the conventions that have been set, will make collaboration a little bit easier. People have their own thoughts; people have their ideas on how code should be written. They have their own styles. But if we all adhere to one single style, that makes it easier.
13:08
César: They also promote best practices because they encourage, well, they lead to more efficient, reliable, and secure code. And finally, they streamline code reviews. You'll see this if, for example, you have your code on a repository, whether Git, not specifically just GitHub or Azure DevOps, any other. If you go through a process, like a pull request, going through the code will make it very easy if everything is following the same style. Some of the most well, popular, not all of them, of course, but for Python, for example, we have PEP 8. We have also the Google Python Style Guide for Java. For those who are also Java developers, Google also offers a Java style guide.
14:05
César: And for C#, well, of course, Microsoft has its own coding conventions. So these style guides establish, again as we touched, is, they establish a set of rules and conventions for writing code and as well promoting consistency, readability, and maintainability, and all the topics that we have already touched upon. So these style guides, I'm not gonna ask you to read through all of this. This is just one of the, let's say, Easter eggs of Python is the, just a poem of some sorts that sets some of the main philosophies or the main philosophy of behind Python. One of the things, beauty, data, it touches upon beauty and elegance. So that means that there's a value in quite beautiful and elegant code with an emphasis on doing things the right way.
15:08
César: It also touches on explicitness. So being explicit is better than implicit, and clear code is preferable even if it's longer. Another one of the key topics here from the Zen of Python is simplicity and clarity. So simple is better than complex, and readability counts. Code should be easy to understand. Practicality beats purity. And while ideals are important, practicality takes precedence. Another thing, errors as learning. So errors should never pass silently unless explicitly silence. This emphasizes on learning from mistakes and also one way to do things. So there should be one, and preferably only one, obvious way to do something. So this will encourage consistency in coding practices.
16:15
César: So this guide PEP 8, well, just a little bit of background here. A PEP it's a Python Enhancement Proposal. So these are proposals that are submitted to the Python Council and are voted and approved or rejected. And PEP 8 is the style guide for Python code. It was written in 2001 by Guido van Rossum, the creator of the Python language. And the primary focus of PEP 8 is to improve the readability and consistency of Python code. One of the things that you should keep in mind is that PEP 8 is a guideline, not a strict rule set. So it's flexible. Some things can be broken. You can also just ignore all of them or most of them. But yeah, it is a guideline, not a strict rule set. Well, I'm just gonna go back. So yeah, we have some key guidelines. In this case, it's spaces over tabs, keeping your code to a maximum of 79 characters or 80. It also gives you some thoughts or suggestions on how to name your variables, how to group your imports, and touches upon docstrings, which we'll cover in a couple of slides. The other one is the Google Style Guide. I touch upon this one because one of the things that it's being used for in Ignition is for the docstrings. So one of the main the way that they, well, yeah, they suggest you to write your docstrings. It's one that is supported in Ignition.
18:10
César: So in the designer, if you add the docstring to your functions using the Google style, you will get code completion. That was introduced in, but I don't remember the version exactly, but I do have it here. Well, it adheres mostly to PEP 8, but it has its own exceptions. But yeah, again, it emphasizes on code clarity and maintainability. Another one that it's also one of the guides or guidelines that was created here by Inductive Automation. They do have their own guideline. If you haven't seen it, I do have a link to that that will take you to the PDF document. So it was, yeah, created here by Inductive Automation. Again, its purpose is to improve readability, consistency, compatibility. So, the same topics or same key guidelines that we have discussed.
19:11
César: Also, it has some differences between the things that they suggest with PEP 8. And, yeah, again, we see indentation, in this case, tabs over spaces. So, naming conventions also differ from PEP 8. Instead of Snake Case, they suggest the use of Camel Case. Pascal Case is the same also for Python. And Docstrings, as I had mentioned, they conform or they adopt the Google style. So, in this case, you will just see some of the key features and where's the difference between all of them. Alright, well, just a few, another addition here. Yeah, you will see also this mention of PEP 8s, or sorry, PEPs, or Python Enhancement Proposals. We have touched upon docstrings. Python also has its own style. But, yeah, there are also many others that are supported by, for example, PyCharm. PyCharm suggests the use of NumPy. NumPy has its own docstring standard. There's another one, yeah, but the PEP 8 and Google style. Might be missing another one, but, yeah, the one that matters the most is Google in this case because it is supported by Ignition.
20:39
César: So, in this case, I'm using the same code example from a couple of slides ago. This is the same Python code, but using the Ignition Exchange Style Guide. So, you will see that this code, instead of using a Snake Case, it's using their convention, so Camel Case. Still, it remains readable and easy to understand. In this case, for docstrings, this is the Google style. So, this is something, again, that is supported by Ignition. So, not only do you get code completion on system libraries, and, yeah, this feature was introduced starting with version 8.1.32. So, when you see some code like this, you will get on your designer, or even in the scripting console, you will get code completion on your function, even though it's not part of the system library.
0:21:46.2
César: Now, bringing all of these together, it's the toolset. Which tools you will be using, or which tools I recommend for enforcing or for implementing the style that you have chosen? The ones that I recommend using an IDE, Ignition Designer, I consider it as an IDE because it's your graphical interface for developing your applications. If you're only working on code, PyCharm and Visual Studio Code are also great tools. Using Python, and lastly, but not less important, Git. As we have seen the shift in Ignition, moving some of the scripting or the components of the projects into the file system has made it easier for us to store that information into a Git-Repo. And we have version control, we have the history, we have other tools that can look into those changes and verify them. But, yeah, I don't know if all of you are extremely or very familiar with Python, but just to set the stage, what is Python? We have Python, CPython, Jython; you would see these terms being mentioned on the internet or on the forums as well. So in this case, Python, as we can see here, is the language specification.
23:27
César: So if you learn the Python programming language and you write some Python code, you then need something to run your Python code. In this case, it's this. CPython, let's say, is the correct or actual name of Python that you download from Python.org. And when you run Python on your command line, this is what you're running most of the time, almost every time. It's based on the C language. That's why it is prefixed with the C. But, yeah, the term is interchangeable. You will see Python being called, or CPython being just called Python. And Jython, it is Python, but for the Java platform. And Ignition uses Jython. Back in the day, when I was working on 7.7 projects, it was using Jython 2.5 as its coding or back end. Nowadays, the latest version comes bundled with Jython 2.7.13. And in this case, Jython 2.7, it's almost a one-to-one to the CPython standard library. And it supports most of the language standards for language settings. It conforms to Python up to 2.7.13, according to their documentation. And for this, which versions do I use?
25:08
César: For Python, well, we see Python 2.7. I don't know if you've heard of it. It's been discussed in other ICCs. 2.7 has reached end-of-life. It's been dropped, as I mentioned, from the runner images on GitHub, which are also used by Azure DevOps. It is no longer maintained. It is no longer, you don't have any versions starting from April. Well, the last version was released on April 2020. But we see Jython in this case. Jython is still being actively developed. The last version, I think, they have already moved to 2.7.14. And I think it's 15 on the worst by now. Yeah, it's using the, it's all, well, it sits between two worlds. So you can use Python code, although not most of the libraries or some of the libraries that are purely CPython. But you have, and you can tap into the power of Java or Java libraries. And you can also import JAR files from third parties that, well, are compatible with Java 8.11 and up to Java 17. And for Python 3, which can be used for installing some of the tools that I'll be describing next, the last version right now it's 3.12. Well, a couple of weeks ago, it was 3.12.6. 3.13 is in the works is in the release candidate version, so it will be released. But why do I touch on Python 3? Python 3, it's the version that I use for installing all of these tools that check into my code, which will be discussed here.
27:06
César: So also part of the toolset, you would have some things like code formatters. In this case, they're also known as autoformatters. These are programs that refactor your code, and most of the time some of these adhere or conform with PEP 8. And for example, black, it autoformats your code using its own style. It says that you can choose any color as long as it's black. I think that's their motto. But yeah, as I was mentioning, PEP 8 is a style guide. It's a guideline, not something to be enforced. So in this case, also black just drifts a little bit from the length of the code. But yeah, we won't get into too much detail on that. But yeah, you have also tools like Autopep8, YAPF, which is a tool developed by Google. And most recently, you see some things like Ruff. This is an application in this case, because you can run on a CLI, that is written in Rust. It's very fast, and it bundles some of these other libraries that we see here on the bottom. That's why you see it pop up here, here, and here, and here. So Ruff, it's, let's say, a combined tool from all of these. Import sorters, as we saw for PEP 8, it has its own standard. It has its recommendation for sorting your imports. Like the standard library should be at this level. The imports from your local library and from third party should be next or on the bottom line. And we also have, again, as I mentioned, Ruff, which can also sort your imports.
29:04
César: For static analysis, we have tools like Flake8. This is also a combination of other tools, like McCabe, PyFlakes. But these tools, what they do is they analyze your code for flag errors. So they will check your code and see that it conforms to a certain style. So in this case, Flake8 will look at if you're missing an import or if you imported something and you're not using it, and so on. Another set of tools are linters. In this case, there might be many more, but in this case, I'm highlighting Pylint and Ruff. In this case, linters are programs that analyze your code, as I mentioned, for flag errors. So they provide suggestions on how to fix each error. So they will give you a code for each error, and that will give you an idea of where the problem lies. So these are particularly useful when you install them as extensions to your text editor or as part of your toolset. And in this case, these popular linters, in this case, they will show you that exactly. They will flag these errors and will tell you even the line where it lies.
30:36
César: Also, finally, I'm not gonna touch upon, because this is a more advanced topic, but type checkers. You have all of these below, Mypy, Pytype, Pyright. In this case, type checkers, so these are tools that help you ensure that your code adheres to a specified type annotations. So, for example, in one of your functions, you say that this first argument must be an integer. And if you, on your call to that method, you're passing a string, that would get caught and marked as a probable error. So, yeah, as I mentioned, Ruff, you see it on many of these categories. Again, this is a tool that has been recently published and released to the community, well, to the Python community, and it's gaining some traction.
31:36
César: So, another tool, it's called pre-commit. In this case, it relies on git hooks. It suggests that you should have your code stored as a Git. Repo. And Git has its own hooks. This is also an advanced topic, but pre-commit is a tool that has been created. As soon as you're committing your changes to the repo, it runs a set of tools. Those are configurable in a file. I will have an example here on a few slides. Yeah, one of the recommendations is that order matters. So, that's why we're touching upon linters, style checkers, and all of that. So, you should have, at least on this order, you should first run your code formatter. Like black, Ruff, YAPF, then sort your imports, run your checks, and any other tool that you might want to add on its configuration.
32:40
César: So, you might be wondering now how to get started. Because starting might be daunting, especially on a code base that has been sitting there and might not be conforming to these styles. So, the recommendation is to start small. You can start on a single file. You can start on a whole project if you wish. But yeah, start small. You should pick your own tools. In this case, select from all of the list of all of the available tools that are out there, choose the ones that will talk to you or the ones that you want to implement. And finally, set your own standards. As we have seen, these style guides, like PEP 8, the Ignition Exchange Style Guide, and the Google Style, they share some similarities. They do have, all of them, the same goal, but they do have their own differences. And so can you. You can set your own standards and follow them, and apply them to your projects. And how can you start?
33:51
César: Well, all of these tools can be configured. They're highly configurable. For example, Ruff has its ruff.toml file. I've just added some of one of the key things that I want to highlight. For example, these would adhere to the Ignition Exchange Style Guide. So, we would be using tabs instead of spaces. And also, these tools are very well documented. So, if you want to learn more about them, and most of them are just sitting on GitHub and have the links for their documentation. PyLink, for example, has also its own file that you can use for configuring it. It could be either sitting at the project level, it could be sitting at the computer level for all of your projects, and also highlighting some of the things that you can configure in this. So, you can say that your arguments should be Camel Case. The default, as well, again, for PEP 8 is Snake Case.
34:56
César: But you can configure all of these and also indent instead of spaces. We see that you can configure it to accept tabs. Flake8, same thing. You have your own file to configure it. Most of these tools, you can also write exceptions inline. This means that you can add to your code something like this. Again, each tool has its own specific error codes and has its own way of us adding these exceptions. In this case, this is for Flake8 in particular. You can also have your file that this would be applied globally. But, yeah, if you want to exclude some things in some files and not just a blanket on top of your whole project, you can do it like that. Pydocstyle, I mentioned this tool as well, because I use it internally. And, again, you can check if your code is conforming to a certain style. More are supported, of course, but in this case, this is how you would configure the Google style. And it will check that your docstring is conforming to this style. And how to put all of these together? You would have, well, preferably all of these files sitting at the root of your project.
36:29
César: And using pre-commit on a Git. Repo, every time you run commit, it will run these tools in the order... Oh, sorry, in the order they're presented. So, for example, for Ruff, they have their own hook, which is Ruff pre-commit. You have a version that you're running and what you're doing. Ruff, in this case, what I'm using it for is for formatting, because the rules that they run, they're using the latest Flake8, which is another thing that I can spend many hours talking about this. But, for example, the last version of Flake8 that supports Python 2 style code or Python 2 code is 5.0.4. I think now it's on version 7. But you will see this as a recurring theme because Python 2 has reached end-of-life. And some of these libraries are just moving forward and just dropping support for Python 2. But I'm keeping it alive. One of the things that I created, as I mentioned in the first slide, is six, the Docker image, that I run on my CI/CD pipelines on Azure DevOps and on GitHub that comes with Python 2. So that's the workaround that I found.
37:51
César: And running pre-commit, here's just a simple example of running pre-commit on your command line that will run all of these checks on your code, and it will flag any potential error. If everything goes well, you'll see all green, and that's what we're expecting. So, yeah, these are some links where you can check my sources. And I think we're doing fine. All right, so that's my presentation now. We can go into Q&A.
38:33
Chris Andersen: Thank you. Just kind of opening up for the Q&A session. Going right here in the middle.
38:48
Audience Member 1: What would be a reason for using four spaces over a tab?
38:53
César: I'm sorry?
38:54
Audience Member 1: What would be the reasoning for using four spaces instead of tab for your indentation?
39:00 César: Okay. Well, yeah, as I was mentioning, PEP 8, for example, the guide created by Guido van Rossum et al., or other people, they desired or they chose spaces over tabs. Why exactly? That's up to them. But if you open Python code on any IDE, for example, Visual Studio Code or PyCharm, by default, they're gonna be using that standard. If you press Tab on your keyboard, it will add four spaces immediately. Why settle on that? Because most of the tools that I have mentioned, like Black and Flake8, and all of them, are using PEP 8 as their base. So that's why you would have to tweak them or to configure them into using tabs instead of spaces. But the PEP 8 standard says that you should be using spaces. Ignition Exchange Style Guide says tabs. Again, if you go into the Ignition Designer and you start writing your code, if you click tab, you get a tab character, not four spaces. So it's either whatever you choose is good, but as long as you adhere to that. Because if you have code, for example, that is mixing tabs and spaces, you will get errors. And you will see that on the Ignition Designer. You will see that on your IDE. So yeah, choose one and stay with that as long as you like. As long as it makes sense to you, you can choose any. But not both.
40:34
Audience Member 2: In cases where you're trying to or you need to call Python 3 code, do you have a preferred way to use, call it a Python 3 service from Ignition, like Flask or Bottle, one of those?
40:49
César: We do have some instances for that where we use the Web Dev Module to run some Python code and be in running some REST API services. But, well, that goes beyond this conversation. In this case, what I use Python 3 for specifically to this topic is just installing all of these tools and running code checks. But yeah, it's definitely something that I believe Kevin McClusky has a very well opposed, probably in the forums or on the knowledge base on Ignition, on the Inductive Automation side. Yeah, he touches upon also the differences between Jython, Python and how you can run Python 3 for some cases like that.
41:38
Chris Andersen: Or waiting for other people to formulate questions. Maybe you wanna elaborate a little bit on your GitHub library you were talking about earlier.
41:44
César: Sure. Okay. Well, as I was mentioning, my experience with Python started when I started working with Ignition. And I was coming from a Java and C# background. Python, I liked it. It's very easy, very simple. You don't have to mess with colon, semicolons. If I missed one here, if you have a C, C++, or other background, you would relate to that. But in this case, it's that Python relies on just white space and indentation for four loops or for just structuring your code. So yeah, I started creating; I created the Ignition API library back in, I don't know, like 2018, 2017, internally for the company that I worked for. Then I decided to just publish it on GitHub. It has switched organizations, but I think it's found its final resting place. It's still being active. So as soon as Ignition comes up with a new version, I also make the changes on the code base so you can have that code completion. One of the, well, a few members here from the community, like Keith Gamble from the Design Group, has contributed to a poll request to that repository.
43:12
César: So also if you click on one of the links, it's sitting now under the Ignition-Devs GitHub Work, where I also have other projects where you can use that, or there's a dev container base. Well, also dev containers is another topic, but copier Ignition templates. So I have a readme for that, where you can just easily install with Python 3 the copier tool, and you can choose which type of project you're gonna be working on, and it will be using the tools and standards that I use. The Ignition API library, well, I think it's quite popular. I thought I was gonna be seeing a little bit more hands raised. But yeah, it's something that I use, and I found it very useful for me and my team that I just posted there. And yeah, anytime you have questions, feel free to reach out through any of the channels that I have.
44:19
Chris Andersen: I have just one question. So there's a lot of pre-built tools with Ignition. So how do you decide when you're doing pre-built versus gonna scripting using both? What's kind of your approach to that? It just depends on the project, I guess?
44:33
César: Yeah, well, most of the things that we do, well, I'm mainly focused on the scripting side of things because we have our own structure. We have our own internal modules that we use. But yeah, usually our everyday tool is either PyCharm or Visual Studio Code, because we can use and import other libraries to make it easier on ourselves to work on other projects.
45:04
Chris Andersen: All right. Well, we'll end the session a little bit early. If you do have any questions, feel free to reach out. That concludes the session for today. So thank you very much. Let's give it up for César.
45:14
César: Thank you.
Want to stay up-to-date with us?
Sign up for our weekly News Feed.