Python Mastery: Ultimate Intermediate Course for 2025 | Arno Pretorius | Skillshare
Search

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Python Mastery: Ultimate Intermediate Course for 2025

teacher avatar Arno Pretorius, Developer | AWS Solutions Architect

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Course Introduction

      3:02

    • 2.

      Thought process

      3:55

    • 3.

      Course resources

      0:51

    • 4.

      Accessing online course resources

      1:30

    • 5.

      Python - Installation and setup - Windows

      4:26

    • 6.

      VS Code - Installation and setup - Windows

      1:56

    • 7.

      Getting started with our project - Windows

      6:27

    • 8.

      Python - Installation and setup - MacOS

      2:28

    • 9.

      VS Code - Installation and setup - MacOS

      1:19

    • 10.

      Getting started with our project - MacOS

      5:25

    • 11.

      Enhance your workflow with Code Runner - [Optional]

      4:44

    • 12.

      Regular expressions

      0:57

    • 13.

      Working with regular expressions - [Lab]

      10:17

    • 14.

      Printing multiple values

      3:37

    • 15.

      Working with different outputs - [Lab]

      3:35

    • 16.

      Match case statements

      3:08

    • 17.

      Working with match case statements - [Lab]

      8:26

    • 18.

      Modules

      1:43

    • 19.

      Browsing the Python module index

      1:22

    • 20.

      Integrate custom and built-in modules - [Lab]

      9:14

    • 21.

      Packages, Pip and PYPI

      2:03

    • 22.

      Utilising external packages - [Lab]

      10:55

    • 23.

      Helpful resources

      1:24

    • 24.

      Generate random numbers

      0:56

    • 25.

      Deep dive on the random module - [Lab]

      16:07

    • 26.

      Exploring the secrets module - [Lab]

      4:01

    • 27.

      Deep dive on the numpy module - [Lab]

      14:20

    • 28.

      Decorators

      2:10

    • 29.

      Creating our first decorator - [Lab]

      8:57

    • 30.

      Working with Decorators - [Lab]

      10:32

    • 31.

      File I/O

      6:01

    • 32.

      Performing file operations - [Lab]

      11:20

    • 33.

      Obtaining file meta data

      1:09

    • 34.

      Attributes to output file meta data - [Lab]

      4:23

    • 35.

      Parameters and arguments

      4:51

    • 36.

      Differentiating between parameters and arguments - [Lab]

      7:13

    • 37.

      Positional and keyword arguments

      5:37

    • 38.

      Map positional & keyword arguments - [Lab]

      16:35

    • 39.

      Mixing argument types - [Optional lab]

      10:28

    • 40.

      Default arguments

      4:35

    • 41.

      Working with default arguments - [Lab]

      11:53

    • 42.

      Variable length arguments

      4:09

    • 43.

      Utilising variable length arguments - [Lab]

      8:50

    • 44.

      Container unpacking

      5:21

    • 45.

      Performing container unpacking - [Lab]

      13:31

    • 46.

      Local and global arguments

      2:35

    • 47.

      Analysing the scope of arguments - [Lab]

      4:09

    • 48.

      Utilising the global keyword - [Optional lab]

      4:29

    • 49.

      Sending variables as arguments

      1:48

    • 50.

      Working with variables as arguments - [Lab]

      4:02

    • 51.

      Parameter passing by value or reference

      1:48

    • 52.

      Explore parameter values & references - [Lab]

      12:01

    • 53.

      The asterisk operator

      1:44

    • 54.

      Applying the asterisk operator - Pt. 1 - [Lab]

      16:54

    • 55.

      Applying the asterisk operator - Pt. 2 - [Lab]

      6:04

    • 56.

      Lambda functions

      1:58

    • 57.

      Perform operations with Lambda - [Lab]

      13:28

    • 58.

      Apply lambda functions to other functions

      1:38

    • 59.

      Embed lambda with other functions - [Lab]

      11:05

    • 60.

      What is object oriented programming?

      1:09

    • 61.

      Classes and objects

      3:32

    • 62.

      Creating our first class and object - [Lab]

      7:38

    • 63.

      Deep-dive on classes and objects - [Optional lab]

      6:12

    • 64.

      Custom methods

      1:45

    • 65.

      Integrating custom (Instance) methods - [Lab]

      9:33

    • 66.

      Working with static & class methods - [Lab]

      12:28

    • 67.

      What is inheritance?

      1:47

    • 68.

      Utilising Inheritance - [Lab]

      12:43

    • 69.

      Abstraction

      1:51

    • 70.

      Working with abstraction - [Lab]

      17:07

    • 71.

      Collections

      3:06

    • 72.

      Explore the collections module - [Lab]

      15:38

    • 73.

      Itertools

      1:38

    • 74.

      Working with Itertools - [Lab]

      18:42

    • 75.

      Context managers

      2:40

    • 76.

      Working with context managers - [Lab]

      7:50

    • 77.

      Built-in vs custom context managers

      1:27

    • 78.

      Create a custom context manager - [Lab]

      17:31

    • 79.

      Generators

      4:13

    • 80.

      Working with Generators - [Lab]

      7:23

    • 81.

      Generator memory efficiency

      2:47

    • 82.

      Shallow and deep copying

      0:55

    • 83.

      Utilise shallow and deep copy - [Lab]

      8:41

    • 84.

      Logging

      1:38

    • 85.

      Implement logging messages - [Lab]

      15:57

    • 86.

      JSON

      0:42

    • 87.

      Working with JSON - [Lab]

      9:19

    • 88.

      Queues

      2:43

    • 89.

      Querying queues - [Lab]

      8:13

    • 90.

      Recursion

      0:41

    • 91.

      Performing recursive calls - [Lab]

      11:19

    • 92.

      Comprehensions

      1:54

    • 93.

      Using list comprehensions - [Lab]

      13:09

    • 94.

      Using dictionary comprehensions - [Lab]

      15:33

    • 95.

      Threads and processes

      4:36

    • 96.

      Multi-processing

      0:28

    • 97.

      Multi-threading

      0:35

    • 98.

      Integrate multi-processing - [Lab]

      6:28

    • 99.

      Integrate multi threading - [Lab]

      6:31

    • 100.

      Unit tests

      0:56

    • 101.

      Perform standard unit testing - [Lab]

      12:14

    • 102.

      Virtual environments

      0:43

    • 103.

      Creating a virtual environment - [Lab]

      7:53

    • 104.

      Creating your own project

      0:46

    • 105.

      Thank you!

      0:44

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

19

Students

--

Project

About This Class

What you need:

This course is designed for those who have a basic understanding of Python and want to take their skills to the next level. You should already know how to work with variables, data types, basic conditionals, loops, and functions etc.

If you're new to Python, I recommend starting with my Python: Ultimate Beginners Course for 2025 on Skillshare. It covers the basics you'll need before diving into this intermediate course.

For this course, you’ll use Visual Studio Code (VS Code) as your coding editor. It’s free, lightweight, and widely used by developers around the world. I’ll guide you through the setup process, including how to install Python and configure VS Code. All you need is a desktop or laptop and an internet connection.

What you will learn:

In this course, you’ll build on your foundational Python knowledge to master intermediate programming concepts in this versatile and powerful language. The course balances theory with hands-on practice, teaching you to write efficient and scalable Python code while focusing on practical applications.

By the end of the course, you’ll have a solid understanding of intermediate Python concepts, confidence to develop more complex applications, and an appreciation for Python’s potential in solving real-world problems.

Here are the key topics that you’ll master in this course:

  • Regular expressions
  • Printing multiple values
  • Match case
  • Modules
  • Packages, PIP and PYPI
  • Generate random numbers
  • Decorators
  • File I/O
  • Obtaining file meta data
  • Parameters and arguments
  • Positional and keyword arguments
  • Mixing argument types
  • Default arguments
  • Variable length arguments
  • Container unpacking
  • Local and global arguments
  • Sending variables as arguments
  • Parameter passing by value or reference
  • The asterisk operator
  • Lambda functions
  • Apply lambda functions to other functions
  • Object-oriented programming
  • Classes and objects
  • Custom methods
  • Static and class methods
  • Inheritance
  • Abstraction
  • Collections
  • Itertools
  • Context managers
  • Built-in vs. custom context managers
  • Generators
  • Generators: memory efficiency
  • Shallow and deep copying
  • Logging
  • JSON
  • Queues
  • Recursion
  • Comprehensions
  • Threads and processes
  • Multi-threading and multi-processing
  • Unit tests
  • Virtual environments

What you will do:

Throughout the course, you’ll begin by learning the theoretical foundations of key concepts, followed by practical lab exercises that allow you to apply what you’ve learned. These hands-on exercises will help reinforce your understanding and ensure you’re ready to tackle more complex tasks.

As the course progresses, you’ll work on a few mini-projects that bring together all the knowledge and skills you've gained so far.

Finally, in the "Projects & Resources" section, you’ll create your very own project. This is where you’ll take the skills you’ve learned and use them to design and build something useful for yourself, putting everything together in a way that’s practical and personalised.


Course benefits:

This course includes:

  • 10+ hours of on-demand video
  • Theoretical lessons to learn fundamental concepts
  • Practical lab exercises to apply your knowledge
  • Mini-practice projects with solutions
  • Over 100+ total lessons

About your instructor:

Hi, I’m Arno Pretorius, a qualified IT teacher with experience teaching both in classrooms and online, as well as professional knowledge in AWS and software development. I’m passionate about making programming accessible and enjoyable for everyone, no matter their background.

Want to learn more?

If you enjoyed this course and want to stay tuned for possibly more courses in the future, please be sure to follow me on Skillshare!

Meet Your Teacher

Teacher Profile Image

Arno Pretorius

Developer | AWS Solutions Architect

Teacher

Arno is a software developer and a solutions architect who has a passion for web development, cloud computing and DevOps. He specialises in creating and deploying Django applications to AWS.

Holding a BSc in Information Technology, he is also an AWS Certified Solutions Architect and Developer. In his spare time, he enjoys content creation, reading and discovering new hobbies/interests.

To stay up to date with his courses, follow his Skillshare profile to receive the latest updates and announcements.

See full profile

Level: Intermediate

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Course Introduction: Hi, everyone. And welcome to the PySonUtimate Intermediate course. So just a little bit about me. Hi, I'm Ono. I'm a software developer and a solutions architect who has experience in creating and deploying PySon Jango based applications to the AWS Cloud. I also hold a BSE in information technology, and I'm an AWS certified solutions architect and developer. I also have a huge passion about the IT world and teaching, most specifically, all of the unique fields that coexist in IT itself. So with all of that being said, trust me, you're in good hands. All right, so you're probably wondering next, what will you learn in this course? So you're going to learn how to advance your PySon skills and to deepen your understanding of core programming concepts. You're also going to master intermediate PySon with data structures, functional programming and concurrency. And you're also going to learn how to solve real world problems efficiently using PySon. Right. Another thing that I'll mention is that a full description of what we will cover in this course will be listed under the about section of this course. So you can go ahead and take a look and see if there are certain concepts that you're eager or keen to learn about. Now the next thing is going to be focused on who is this course for. This course is designed for those who already have a basic understanding of PySon and for those who want to deepen their skills with intermediate concepts. Whether you're a student, a professional looking to switch careers or simply someone who is curious about coding, this course is tailored to help you to build a strong foundation in PySon. The next thing is the question on prerequisite. So are the prerequisites? Unfortunately, there is a prerequisite for this course since this is an intermediate course. So the prerequisite is that this course is designed for those who already have a basic knowledge of PySon it is ideal for those who want to add to their existing knowledge of pyson. So do keep that in mind that you need to ensure that you have a solid foundation in pyson before deciding to continue with this course. Right. So another thing I want to mention is that this course is coupled with theoretical and practical lab exercises to ensure that you understand the Bye seri and how you can apply that series in the lab exercises. Now, each lesson in this course is structured carefully in order to maximize simplicity and efficiency. And the next thing you're probably wondering is, is there any support for this course? So the question is, yes. So if you have any questions or need assistance in any regard, please feel free to make use of the discussion section of this course, and I will be very glad to assist you and answer whatever questions you may have. And it might even be the case that another fellow student helps you before I'm able to respond to your question. Alright, so that's it. Thank you for watching and I hope to see you in this course. 2. Thought process: Hi, Eon. And welcome to the next lesson, which is going to be focused on sort process. So in this lecture, I'm going to just give you some words of advice, which you can follow if you would like to on how to structure our salt process when undertaking this course. So let's go ahead and get started. So sort process. Now, before we dive into the course, we need to structure our sort process. So I just want to give you some words of advice. So let's go ahead and get to it. So the first bit of advice I would like to give you is to take it one step at a time. So take this course one step at a time. Please don't brush, right? Take your time. If a particular lesson is taking you a lot of time to master, don't lose hope. You will understand it with time. Some people understand various concepts immediately as a first time. Others take a longer time to understand certain concepts. And as myself, as a learner to certain subjects in my life, I have, of course, taken lots of time in certain areas of concepts to understand and in other particular topics I master almost instantly. For everyone, it's different. Everyone is going to have a challenge at some point of something, so please don't be discouraged and just take it slow and easy and steady. Another tip I would like to give you is to set a schedule and stick to it. Now, of course, you don't need to be extremely rigorous and detailed in your schedule. What I mean by this, you don't need to plan it by the minutes and the exact hours and the timing, et cetera. What I mean by that is have a schedule that is not going to overwhelm you, but it's going to push you just enough to stay consistent and disciplined and even motivated to complete the course. So do keep that in mind. So in my experience here, I'd recommend you choose a schedule that is more flexible to you. I myself don't like to sit rigory and exactly by how can I say the times and the minutes spent and the hours spent? I don't like to go with that approach. Or with dates, I like to keep it more flexible and say, Okay, I want to spend a certain amount per month working on this course, and I just want to finish about five to ten lessons. So that would be my approach and how I do it. So it would depend on how you prefer to go ahead. I'm just giving you an example. But anyway, it's good to have at least a base schedule to follow along with. Now, the most important advice that I want to share with you here is the last one, which is to stay positive and know it's not a race to complete the course, but rather a slow and steady journey to acquire long term knowledge for the best results here. This is what I mean here. You don't want to rush through this course, rather take your time, even if you feel that the concepts are very easy to understand, rather take your time. Take it steady and work on it on the course occasionally or regularly, depending on your schedules. That's a very important thing that I want to mention here. Again, this ties up a lot of things here on the focus of staying positive. Again, of course, if certain concepts take some time to understand, work through it, put in the effort, and you will get there. Stay positive and know it's going to take some time, but take it slow, take it easy, and relax as you go through the course. I've done my best here to make it as simple as stress free throughout this course. So do keep in mind here just to relax, take a deep breath in, and calmly go through the course and enjoy yourselves. All right, guys. So that's all I wanted to mention here in terms of thought process. 3. Course resources: Hi, everyone. And welcome to the next lesson, which is going to be focused on course resources. So let's take a look. All right, so you're probably wondering, okay, how will we code? So the first thing that we need to ensure is that we have Python installed on our device. So whether we're working on a Windows PC or if we're working on a MacOS device. Then we're going to install and set up Visual Studio code, commonly referred to as VS code, and this is a coding editor that's going to allow us to create and run our PySon programs. Now, I know this might sound a little bit stressful and worrying, but don't worry. I'm going to break it down as easily as possible for you, and I'm going to show you exactly how we're going to get started with everything. So don't worry. You are in good hands. 4. Accessing online course resources: Hi, everyone, and welcome to the next lesson, which is going to be focused on accessing our online course resources. What I mean by this is, I'm just going to show you how you can go ahead and access the required websites to download and set up PySon and also to set up visual studio code. I'm just going to show you how to access the websites. In the later lessons, I'm actually going to show you how to install and set them up. This is just a lesson on accessing them. So you can head on over to Google and you can just type in PySon Download, and then we can just say Google Search. And on this link here, you'll see it will be called Download PySon and you want to click on that. That's going to take you to the following page here, which is a Python or forward slash download forward slash. So we're not going to install PySon now. I just want to help you get to the website. Next, we're also going to be utilizing Visual Studio Code. So what you can do is go ahead in Google and type in Visual Studio Code Download. I look at Google search. And you'll see this link here that appears that says download Visual Studio Code, Mac Linux and Windows, so we can open that up. And here is the page that we are going to need to go on ahead and set up Visual Studio code as our coding editor. All right guys. That's it for this lesson, very simple. I just want to show you how you can access these websites for future reference in the upcoming lessons. 5. Python - Installation and setup - Windows: Hi, everyone. Welcome to the next lesson, which is going to be focused on installing PySon on a Windows device. Let's get started. Now, the first thing you need to do is head on over to the following web address, which is at python.org, fordslash downloads forwardlas. After entering in that web address, you'll be redirected to the following page as you can see right here. What we're going to do is download PySon for Windows now. Now in terms of the version that is given to you when you head on over to this page, it doesn't have to be the exact same version, so don't stress as long as it's not too far out. Right, what we can do is go ahead and see download Pison. There is the setup for us here, which we can go ahead and open up. It's going to take us through the setup wizard. So what we're going to want to do is we're going to want to ensure that we are using admin privileges when installing Pit Ex, and we also want to add the PySonteX to our pass. Now, this is very important just to ensure that all of our users on our system will be able to run PySon within any sort of application that allows Python to be run. Is there any restrictions? Then you want to say customized installation. Okay, ensure that everything is selected, as you can see here. Then we can see next. And then you want to say install PySon for all users here, in this case, it's 3.13. So just make sure you select the following option, and this is just going to ensure that all users on your device will be able to use PySon. After doing so, you can go ahead and say Install. A prompt will appear on your screen, and mine is currently dimmed, and you just want to say yes to that security notice. So we can see the setup is in progress. So it's just going to take a moment or so until PySon is installed on our system. So we're just going to have to be a little bit patient until it is set up and finished. So let's just give it a moment. All right. Welcome back. Congratulations on successfully setting up PySon on your Windows PC. As we can see now, that the setup was a success, well done. Now we can go ahead and close this and I'm just going to minimize this. Now, to ensure that everything has been installed correctly and that there are no issues, I would strongly recommend that you do now is to restart your PC. So please make sure you do this. This is very important. So what you can do is just head on over to your PC and you can go ahead and say restart hit it off. And then, of course, once your PC has restarted, I'll take you through the final confirmation test to make sure that PySon has indeed been installed on your system and that the pass has been system mind on your PC. So that's the main thing. So the environment variable for PySon needs to be loaded and configured. So let's go ahead and do that. So let's restart PCs and then we'll be back as soon as our computers have been restarted. Alright, so welcome back. So I trust by now that you have restarted your PC. Now, all that you're going to want to do for the final confirmation that PySon has been set correctly across our systems is to search for the command prompt. You can just type in CMD to quickly find it. So here's our command prompt. And all I'm going to do now is I'm just going to adjust this just for your viewing pleasure, and I'm just going to say PySon dash dash version. So you can go ahead and type this in as well, and then we can press Enter. And if everything was a success, it should output the PySon version that you have installed on your system. And this is just like a final confirmation check to make sure that everything has run smoothly and that we are good to go. All right. So make sure that you can see this and that you have installed PySon on your machine, and that's it. So that is how you can install PySon on your system and also check that there are no issues or conflicts or anything and that it has been installed correctly. All right, go. So for this lesson, that's how you can go ahead and install PySon on a Windows device. 6. VS Code - Installation and setup - Windows: Hi, everyone. And welcome to the next lesson, which is going to be focused on downloading and setting up Visual Studio code on a Windows device. So let's get started. Now, the first thing you need to do is head on over to the following URL, which you can add in as code visualstudio.com flash Download, it's going to take you to this page here where you can download Visual Studio code for your designated operating system. Now case, it's going to be on Windows. We can go ahead and select the option here for Windows ten and 11, so we can click on that and that's going to download the installation guide for us and the setup wizard. We can go ahead and open that up. Let's just be patient as it opens up. We want to accept the agreement. Let's go to the next stage. It's going to save it in a destination folder. Let's go to the next stage. We can see that's how we can access it at the start menu as Visual Studio code next. I'd recommend you just create a desktop icon for now. You can always remove this. We can say next and install. It's going to now install Visual Studio code in our computer. All we're going to want to do now is just be patient as that process is completed. Right, so, welcome back. As you can see, Visual Studio code has successfully been installed on our machine, and we can now launch Visual Studio Code. So if this option hasn't been checked for you in the checkbox, you can go ahead and check it, and you can see finish, and that's going to open up Visual Studio code for us. So we can say finish. And here we are. So here we are in Visual Studio code. So, well done. You successfully downloaded and set up Visual Studio code on your Windows PC. So well done. 7. Getting started with our project - Windows: Hi, everyone, and welcome to the next lesson, which is going to be focused on getting started with Visual Studio code. Alright. Now, what we're going to want to do is create our project, which will house our Python files. Okay, so as you can see, we have no folders open or anything of the sort. So what we're going to do is head on over to the desktop, and I'm going to right click and I'm going to say new going to say folder and I'm going to give this folder a name that's going to be suitable. So we're going to be working with our Python code. So I would think that a simple name here would be called My Project. There we go. Now we can navigate back to Visual Studio code, and you can either now say open folder, or you can click on the icon on the top left, go to File, then open folder. Then we can navigate to our desktop and then select my project. Here is where our PyCon code will be housed. We can then say select folder. All right. Perfect. So this is the folder that we'll be working with to store our PySon scripts. Right. Now the next thing you want to do is highlight or hover over your project folder here and you'll see a few icons. We want to click on New File, and this is going to be our PySon script file. So this is where we'll add in all of our PySon code, and then we're going to run the code based on the commands that have been defined in this file. So I'm just going to call this for now main dot pi. You can give it any name you desire, and you can press Enter. Now, as soon as you've pressed Enter, you're going to get a prompt here that says, Do you want to install the recommended PySonEtension from Microsoft for the PySon language? So I'd recommend you do so. It is going to bride you with some extra features and such. So I'd recommend go ahead and installing that. So you can say install. So it's going to take a few moments to install this extension on Visual Studio code. Now, all you need to do now is just be a bit patient, and once it's been installed, we can continue from there. Right, so welcome back as we can see that the Python extension has been installed Visin Visual Studio code, so we can close this. And what we can also do is head on over to Explorer. And here we can go ahead and toggle the following option to maximize our script here called main dot pie, for example. And if we want to see our directory, which houses our project and the associated files, we can of course just navigate back. All right. So just something I also wanted to mention on that note. Right. Now what we want to do is we want to add in our Python code to this script, and then we want to execute this script and we want to see the output result. Now, the first thing is, let's go ahead and get started and create a simple program. I'm just going to define a variable known as name, and we say equals and set that to the value of no then I'm going to print this variable and it's going to output the value associated with name which is no. Now, there are two ways in which you can go ahead and get started with this. Now, the manual way, I'm going to show you first, which is you can go ahead and click on the flowing icon on the top left. Then you want to go to terminal, and you want to open up your terminal. All right, so here we have it. We have our terminal here on the left hand side. And with this debug console, you can go ahead and just shift that over. And what I recommend you do is now to reopen your terminal. Sometimes it takes a moment to configure. So I'd always go ahead and just say, Kill terminal. Then I'm going to close it, and then we go back to terminal and then open it up again. And here we go. Alright, so now we can go ahead and get started. Now, what you're going to want to do is run your PySon script file according to the name. So this is called Min Dot Pie, and we can see the directory that we have set up here. So currently our terminal is looking at the user here, which is Ono, on the desktop in the My Project folder, which is the folder that we created here called My Project. And as you can see, it's also available here, My Project, and we have Min Dot Pi, which is within this My Project folder. We're going to want to do to execute any code that's in this main dot py file is the following. You just want to type Python. And then you can just refer to the file name, which is main dot py. But all you want to do is say PySon main dot pi, and enter, and there you can see it outputs our code for us. So that's the simplest way in which you can go ahead and execute your PySon code within Visual Studio code and using this terminal. Right. We can also type in clear and that's going to help to clear the terminal as well. So that's the first way in which you can execute code. So it's kind of a manual way you could say. Now, easier way is we can go ahead and hide this panel. You'll now see if you installed the Python extension, you'll now have the opportunity to hover over the following icon and run your Python file. This does it automatically for you, per se. We can just click on Run PySonFle by clicking on this icon, and that's going to open up the terminal for us and you're going to see it's going to execute the file. Here we have main dot pie, which was executed and output here, which is on it. That's another way in which you can do it. There are two ways. All right. That's it, guys. That's how we can go ahead and get started with Visual Studio code and set up our foundations for our PySon project. So we can go ahead now and see here. All right. So that's how we can go ahead and get that started and get everything in, like, into place. 8. Python - Installation and setup - MacOS: Hi, everyone. Welcome to the next lesson, which is going to be focused on installing PySon on a MacOS device. The first thing you want to do is you want to head on over to the following URL, which is at python.org forwardslash Downloads forwardlas. You want to make sure that you head on over to this URL. After entering that in, you'll be redirected to the following page here, which is on the Python Downloads page. Then you want to download PySon so you can click on this button here. That's going to download the setup wizard for us and we can go ahead and open that up as follows. Here is a setup wizard. We just want to continue, continue, tine and agree to the terms. Then you want to say install and enter in your password and install this software on your system. All right. There we go. We can close the following here. There we are. PySon has successfully been installed on our device. We can just say close. We can just say keep, that's fine. Now what I'd recommend you do is to head on over to your Apple icon and just restart your MacOS device. This is just to ensure that everything is set up correctly PySon in terms of environment variables and such. After doing so, what you can do is head on over to your launchpad and you want to search for your terminal. You can just type in terminal and open that up. This is the CMD equivalent in Windows to confirm that PySon has been installed and the designated version specifically that you've installed, you can just say PySon three, space, dash dash version, and Enter. There we are, we can see that the version that we wanted to install and the PySon installation has been a success as we can see the output is as follows. That's just a confirmation to show that PySon has been installed on our system. Okay, so that's it for this video, that is how you can ensure that Python is installed on your MacOS device. 9. VS Code - Installation and setup - MacOS: Hi, everyone. Welcome to the next lesson, which is going to be focused on downloading and installing Visual Studio code on our MacOS devices. First of all, you want to ensure that you're on the following page here, which is accessible if you head on over to URL and type in code visualstudio.com for slash Download your URL, on which you'll be redirected to the following page here. Next, what you want to do is you want to go on ahead and install it for a Mac, so we can go ahead and click on the following icon. That's going to download the setup wizard that we need to access Visual Studio code. We just need to give it a few moments. If for some reason the download doesn't start for you, you can go ahead and click on the direct download link instead. Just give it a moment and we can see it's done and we can go ahead and open up Visual Studio code. After clicking it, you'll see this prompt here and all you want to do now is open it. Visual Studio code is an app downloaded from the Internet and we want to open this up. There we are. Here we have it. This is Visual Studio code. That is how you can go ahead and easily set up this coding editor. 10. Getting started with our project - MacOS: Hi, everyone. Welcome to the next lesson which is going to be focused on getting started with Visual Studio code so that we can set up our PySonPject. The first thing that I want us to do is to minimize visual studio code for the time being. What we're going to do is we're going to go on a hedge and create a new folder on our desktop, which will house our PySon file in due course. Let's right click and we can then say new folder and I have this folder created and I'm going to click on this and rename it. I'm going to call it MP check. You can give it any name that you desire, there we have that folder and we want to open up this folder in Visual Studio code. It's to open up Visual Studio code, maximize it. Then we can go and click on File. Navigate to open folder. Then we want to go to the desktop because that's where we created that folder. We can then select that folder called my project and say open, and we can close this prompt and there we can see we now have access to this folder. Perfect. Well done. Now we want to create our PySonscripting file, you could say. This is where we're going to add all of our PySon code and we're also going to run our code based on the contents of S file. That's going to be within our project folder here. You can hover over it and then you'll see an icon which is going to allow you to create a new file. You want to click on that. Give your file a name here. I'm going to call it main dot py, for example. I need to be a dotpi that Visual Studio code knows that this is going to be a Python based file and we can press Enter. There we have it, the main dot Pi file. Now, since it is the first time that we're using PySon in Visual Studio code, we're going to have a prompter that's going to suggest that we install the recommended Python extension from Microsoft for the Python language. This extension just gives us a few extra features which we can utilize and just overall makes our experience with coding Python in Visual Studio code a lot more proficient and pleasant. We can say install. That's going to install the extension. There we go. It has been installed, so we can close the following page here and we can navigate to the icon here, which is Explorer. That's just going to show our directory which, of course, our files in our directory. We can also close Explorer here to maximize the file that we have here already open. It's actually something I also wanted to go ahead and mention. All right. Let's go ahead and run some code and perform some tests. Now, the first thing I want to, of course, do is just go ahead and create a simple program. I'm going to say name equals, and I'm just going to say honor. I'm creating a variable name name and assigning it to the value of honor. In the next slide, I'm going to say print and I want to output said value. Let's go ahead and do that. Within the print statement, I'm going to put in name Now, what you can do is you can go ahead and save your code here, and then we can go ahead and run it by clicking on the following icon here to run the PisonFle. There we go. We can see it has run the file accordingly here. I can also minimize this terminal here just to give you some more room. We can see the output there, which was nor and it has been run successfully. We can also see that it's automatically configured our past for us. We're running within the My project directory, and it's running the main dot pi file here specifically to output whatever code has been sent out here. And you can also clear your terminal here by typing in clear and that clears it for you. You can also go ahead and close it up. Now that's the automated way of going ahead and running your programs in Visual Studio code. What you can also do is you can go ahead and click on the terminal directory here and say new terminal, and that's going to open it here as follows. What we can do is, of course, we can just give us some space here and you can also execute the commands here as well. That's another way you can do it. If you want to go ahead and execute it in the terminal here instead of going ahead and saying run Python file, you need to manually do it according to the file name. But you're going to want to say PySon three, space, and then your file name. Here I'm going to say main dot pi, and Enter. There it's going to output accordingly as follows. Right, so that's how you can go on a hedge and utilize the terminal and Visual Studio code. And we can type in clear here and that will clear the terminal for us. Now, I would at least recommend that you rather just click on the Run PySonFle option here for it to run for you, then tomanically enter in the file name and then execute it. This will just save you some time and such. All right guys, it. That is how we can get started with PySon and how we can get started more specifically with PySon in Visual Studio code. 11. Enhance your workflow with Code Runner - [Optional]: Hi, everyone. Welcome to the next lesson, which is going to be focused on enhancing our workflow by utilizing the code runner extension. Now, this is going to be an optional lesson. You don't have to do it if you don't want to. But let's say for example, you're working with your terminal and you want to have a cleaner output. Instead of seeing those messy files each time and then the output of the code you're actually expecting, then code runner can really help to make that a lot easier and a lot more pleasant on the eye, should I say. Instead of seeing all of those file pass and names included with the output and you want to clean output, you can use code runner. So let's go ahead and get started. Okay, so we need to navigate to extension, so you'll see designated by the flowing icon. Now we can just click on this input field, and I'm just going to remove what's in it. And we want to search for code runner. I'm just going to type in, of course, the flowing, code. Runner. And we're going to see this one right here. So you'll see it will have this logo dot run, so code runner, and you want to install this particular extension. Okay. So let's just give it a moment or so to be installed, and there we go. We can see it has indeed been installed on our system. Right, so we can close that extension now, head on back, and we've got it in place. Now, there are a few settings that we do need to confirm and make sure we've got in place to have that clean output. So let's go ahead and do just that. So you want to navigate to the following icon. Then you want to go to File, then you can scroll down until you see preferences. Then you want to hover on preferences, and then you want to click on settings. So go ahead and click on that. That's going to take you to the following area here. Then here by search settings, we can just go ahead and put in code. Okay. And we can just put in Runner. All right, there we go. Okay, so we have some settings here. So first of all, we have code runner clear previous output. So we want to ensure that this has been checked. That's just going to make sure that it shows the freshest output each time we make a code execution. All right, so let's go ahead and continue. So we want to just look for the key options there. Okay? So we can leave everything as is. You just want to focus on the ones that I have mentioned. Here, we also have code run and run in terminal. Okay? You want to make sure that this has been unchecked, that it's not checked, so we can just leave it blank as is. So that's another one you want to ensure you've checked. Okay, and of course, we can see that we also have save file before run. So that's going to ensure that we want to save the current file before running. And what you want to do for this one right here is you want to ensure that it is kept to true. And then we have show execution message, okay? So we don't want to see anything like running or down or anything like that. We want it to be clear and clean and simple. So make sure that that has been unchecked. So you just want to check for those four options that I've gone into detail now just to make sure everything is cleared up and organized for code runner to work into place. Right, so let's go ahead and close this now. Have our code here, but now to actually run code runner, what you can do, it's very simple. We're also going to click Run, but you want to click on this drop down arrow here, and you'll see now that we have an option to say run code instead of run Pis and file. So you want to click on Run code, and there we go. We have that output clean, simple. You can see no more clutter. It's a lot easier to use, and it's now in place as it should be. Right, so what I'm going to do now is just change that value, and I'm just going to just say John. And now if I go ahead and manually just click on the option here, you're going to see the default will be run code now, and there'll be Ha. All right, so there we go. That is how you can go ahead and utilize code runner. So you can see it gives us a clean output, a lot easier on the eyes as well, and a lot better overall for us to utilize it in such a fashion. All right, guys. 12. Regular expressions: Hi, everyone, and welcome to the next lesson, which is going to be focused on regular expressions. So let's take a look. All right, so regular expressions, commonly referred to as rejexs. So regular expressions in Python are basically used to identify patterns in text, such as in numbers, words, or even in an email address, for example. Now, instead of searching for exact matches, rejec follow specific rules to detect specific patterns per se. Now, PySon already provides us with a built in module called RE to work with regular expressions, wrench. So that's enough for the theoretical overview. Let's go ahead and apply our knowledge into utilizing regular expressions in PySon. 13. Working with regular expressions - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on working with regular expressions commonly referred to as rejec within Python. Let's go ahead and get started. Let's remove what we have here and I'll just zoom out a tab bit. Right. Okay, so the first thing that we're going to want to do is to just go over what type of examples we're going to go over with regular expressions. So in order to have a better understanding of regular expressions, I'm going to go through a few examples and exercises with Z and they're going to be namely as follows. I'm going to show you how you can find all the digits, in other words, numbers in a given set of text, how to replace digits with certain characters, and also how to check if a string starts with the digit. This will help you to have a better understanding of how you can use the functions that come with the RE module and such. Anyway, let's go ahead and get started. So in all examples, we need to first of all, import the RE module, which comes with a lot of built in functions along with it. So we can see Import RE. Right. Now we need to add in some ext, and the first exercise is going to focus on finding all of the numbers or digits in a given set of checkt. So I'm going to say ext, equals, and here in quotes, I'm going to say I have three apples. And two pairs. That's my example. And as you can see there, I have two digits. I have three, and I have two. So, of course, we want to extract said values, technically. Then we need to specify a pattern. Now, the variable name here, you can give any name that you desire. However, I'm calling it pattern because that's essentially the pattern I'm going to set it up as. Now, you're always going to want to start with R for your expression here, the R before a given string is going to ensure that the string is a raw string, meaning that all backslashes are treated normally instead of as escape sequences. So we'll add in our quotes and then backslash D. That's going to be the important part that we need to add here. Now, this backslash D here, is, of course, going to be a regular expression that's going to match against any digit 0-9. That is what we need to first of all, specify next thing that we're going to want to do is we're going to want to specify another variable, we can call this numbers and we're going to utilize the R E module now and then we're going to invoke the find or function that comes built in with the RE module, and we're going to put in two parameters. First will be pattern and then text. So to reiterate this line here on pattern, this is to find all the digits in a given set of text, which is going to be this text here. And what we're doing is using the find or function to do just that. So the find or function is going to want to know the pattern and then the checks to apply this too. So the pattern is going to be based on the digits, this backslash D to find and match digits, and we want to find all of the digits in this text which says I have three apples and two pairs. You can s to yourself, it's of course, going to output three and two. Let's confirm this. Then you can say print numbers and run your code. Here you can see it outputs three and two. There we have it. That is how we can find digits in a given set of text. Now, let's adjust this now and I'm going to make it longer. I'm going to say I have three apples, two pairs, and four oranges. Save the code. Run. Now you can see it outputs three, two, and four. Okay. So you can see there, it will pick up and check where it can retrieve all the given numbers by utilizing the find all function. Now, let's say for argument's sake, we want to do something different. Let's say we want to replace digits with a specific character. Let's say with a hash tag. We don't want someone's number or phone number to be leaked. We just want to see it being, you could say, hidden by hashtags. So let's go ahead and do that. So we can remove this code for now. I'm going to remove that out, and I'm going to say text again. And here I'm going to say my number is, and I'll say one, two, three, four, five, as an example. Then the pattern we're going to set. So double quotes, backslash D. So we're going to look for whatever pattern that matches digits. Then we can say new underscore text because we're going to modify this text to say my number is, and then we're going to add a specific character to hide these numbers, for example. Okay. Then we're going to say RE, going to utilize the module dot. The function we'll use this time is called sub. So sub is a function, which is commonly referred to as substitute or substitution, but the actual function name is sub. So we want to essentially substitute for an alternative value to replace a digit per se. So we need to apply the pattern that we want to use to match digits. And where we see digits, we want to replace that or modify it with a hash tag on the given text. As you can expect now what's going to happen is it will say my number is, and it's going to show hashtag, hashtag, hashtag, hashtag, and hashtag. If we were to say print and then new underscored text and run that code, we can see here at outputs, my number is hashtag, hashtag, hash, hasta hashtag. Now, let's say I only put in one and two. And we run again, I only shows the first two hashtags. Okay, so this is a very good way if you want to substitute or replace digits or numbers within a given set of text. You would utilize the sub function or substitute function. Now I can also make this longer and run that, and you can see it's just going to do the following. Now, I can also change this to, let's say, $1 symbol, so I can change it to that and let's put it to the original, and it does the same thing. So that's how you can substitute accordingly. All right, so that's how we can replace digits. Now, the last thing I want to show you is how you can check if a string starts with a digit, so if it starts with a number. So let's do that. Let's remove this. Okay, text. And what I'm going to do now is I'm going to say three pairs in the basket. Okay. So we can see here already that the string is starting with a digit. All right. So the pattern. Okay, we're going to have R, and we're going to have to put in a special character here, so it's going to be an arrow going upwards or like the power two sort of symbol. And that's going to mean the start of the string. So at the start of the string, I want to look for any matching digits hence the backslash and D. So that is how you can apply these characters together in terms of the expressions. So essentially, this line now of code is going to match if the string starts with the digit and we're going to apply this now. An if statement. So I'm going to say I dot match, so we're using the match function, the pattern, and the check. So we're going to check if this particular pattern is matched in this text. So in other words, if this text here starts with a digit, according to the pattern, then we're going to output a specific response. So since this is a if statement, going to add in a kern at the end, and then I can say print, yes, it starts with a digit. If for some reason it doesn't, I can say else and print. No, it does not start with a digit. Okay, so let's go ahead and see. So in this case, we can see it starts as a digit, so it should return the statement here. Yes, it starts with a digit since it is true. So let's run this and we can see here. It says, yes, it starts with a digit. Now let me change and remove the three and just say, pairs in a basket and run. There's going to output the statement here that, of course, says no, it does not start with a digit. Okay. So that is how we can use the match function as well. Now, when we are working with regular expressions, there are a lot of functions that come with R E, but this is just a bit of a teas ae so that you can have an understanding of regular expressions and how you can apply them according to a given pattern that you decide to set in your code itself. All right, guys. So that is it for this particular practical exercise. 14. Printing multiple values: Hi, everyone, and welcome to the next lesson, which is going to be focused on printing multiple values. Let's take a look. Right. Now, when we are printing multiple values, what you can do is utilize string concatenation and string concatenation is essentially the process of combining multiple strings into one. Now, the most common way to concatenate strings is by using the plus operator and then add spaces between your strings for readability. Now, what you can also do is you can use a comma instead within your print function, and you can then display multiple values, and this is automatically going to add those spaces for you, and this can make it a lot more readable and also save you some time. So let me show you graphically what I mean by this. So let's say, for example, we have this program. Very simple. We have two variables that we've defined here, first name and last name, taking in your first and last name, of course, John and Doe. Then what you'll need to do is typically create another variable. In this case, full name would be appropriate. And then to combine first name and last name together, what you'll need to do is say first name and then plus and then add in the space with quotes and then plus again, and then the last name. That's going to combine John and do together and also leave a space between them since you added in those two quotes. As you can see you're adding the plus operator here for string concatenation. When you print full name, it's going to print out John space do in a nice format. However, this can be a bit tedious depending on the situation and the context. An easier way would simply to just go on ahead and add in your print function and then just directly add in your first name and last name together, separate them by a comma, that's also going to print the exact same result in a fewer amount of code that has been in place. So that's just something I wanted to mention here that if you are printing your values and they are being output, you can also make it a lot better and easier for yourself if you just add in a comma depending on certain circumstances. Now, there is some more I want to mention on this topic. So to ensure that you get more comfortable with using both options, I'm going to use both the plus operator for string concatenation and also comma throughout the course. Okay. Now, the reason that I'm doing this is just to help to solidify your skills with learning new things, and to apply everything so that you can learn more extensively. So I just want to kind of, you know, challenge you a little bit just to, you know, really focus on the lessons at hand and to be comfortable with not just using one sort of method, but also being comfortable with following other methods as well. So in this case, to follow string concatenation, to recognize it, to apply it. And then in other given context, to be like, Okay, in this case, I need to use a comma or I feel like using a comma, but I understand it as well. So this is just a little bit of my insight in terms of how you should go about printing your values and such. Very simple lesson, should I say? I'm also going to follow this up with a short practical exercise as well. It's very easy, but I just want us to practice and get comfortable with working on other methods and techniques. 15. Working with different outputs - [Lab]: Hi, everyone. Welcome to the next practical lab exercise, which is going to be focused on printing multiple values. We're going to just do a little bit of practice on string cocnation and also how we can utilize a comma in the appropriate context as well, just to save us a few lines of code and such and also to improve readability of our code in general. Let's get started. We'll keep it simple to start off with. I'll say first underscore name, equals, I'll say honor, and I'll say last underscore name, and I'll say Pretorius. Okay, so with string concatenation, it would be best then in this given case to define another variable, which I'll refer to as full name equals, and then I'll say first underscore name, plus. So I'm using the plus operator and then add in a space with the designated quotes plus again, and I want to then add in a last name to it, so it's going to show no space Pretoris. Then I can say print. And I'll include full name here within the paren ss and that's going to print on a Pretorius in the output. There we have it. As we can see, it is printing the following and my full name. Now, let's say I don't want to add in a string concatenation and I want this to be a lot simpler with less lines of code. I can just remove the following and just say in the print function within princes, first underscrena followed by a comma and then say last underscuN and run the code and it prints the exact same result and output in the terminal for me. You can see how easy it is that saves you a lot of time. But of course, it also depends on the situation. Let's go ahead and remove this. Let's go for another example. Let's say we have Siti and here I'm going to say Capetown. And we'll have country, and I'll say South Africa. So I have two variables defined. So I've got that in place. Now the next thing that I'm going to want to go ahead and do is specify a variable here. So I can just go ahead and say location, equals, and I can just say city plus, add in the space, plus, and I'll have country. Then I can say print location. Run the code, Cape Town South Africa. All right. Now, let's see if we can simplify this by just using a comma, so we can just remove the following and we can just say print. City followed by country. Run the code, and then we have Kick towns of Africa. So there we go. We've also saved some lines of code there as well. All right, so you can see it's a lot readable in this example when we are using a comma. Right, right, go. So that's it for this practical lab exercise. It is quite short, but I just wanted to give you a little bit of practice here. So do keep in mind here, look at the program that you're working on and the contexts and then decide what you feel will be appropriate. Alright, go. So that is it for this practical lab exercise. 16. Match case statements: Hi, everyone, and welcome to the next lesson, which is going to be focused on match case statements. So let's take a look. So you're probably wondering, Okay, what is a matchcase? So a match ka statement works like a switch statement in Java and C if you have some experience with those programming languages. So essentially, this matchK statement is going to check a value against multiple cases, and then what it's going to do, it's going to then execute the matching block that it finds in those cases that it has matched up. Now, unlike the I ELF statement that we have in PySon, it's going to offer cleaner and more readable pattern matching. So it's very similar to the I conditionals, you could say, to an extent, of course, now, it can also match lists, tuples, and objects, and not just random numbers and strings. So we can see there is a very big range when you are utilizing a match case statement. Now, let me go ahead and explain this in a visual format, so it would make more sense to understand. So here's a practical example. Let's say we want to make a very simple color checking program. So we want to check what is assigned color and such. So here in this program, we can see that the color that has been assigned is red. Then we're going to be utilizing the match statement here. So we're going to match according to the value of the color. Now, the color is red. So then we're going to have individual cases. So first, we'll have our match for color. Then we're going to have a case and this case can be anything. So in this case, the case is going to be red. And if the color matches the case of red according to its associated value, it's then going to print out the color is red. We can have another case here that is blue to check if the designated color is blue, and we also have a special sort of key phrase here where we have in case and then underscore. Underscore is very similar to an statement in if conditionals. If the case is above, do not apply, then it's going to print another option here, which is going to be unknown color. In this case, we have red, and we're putting in two separate cases to check if the color is red or blue. Now, if for example, the color is green, purple, gray, et cetera, it's then going to execute the block associated with the case underscore and it's going to print unknown color. Try and see the similarities with I Elef and L statements in Python to get a rough idea of how this match case works. All right. All right guys. That is it for this theoretical lesson on match K statements. We are going to have a practical lab exercise, we'll be going to dive deeper and learn by doing. 17. Working with match case statements - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on working with match case statements in Hyson. So let's get started. Let's keep our first program very simple. I'm going to define a variable, and I'll call this color, and I'll assign that to the color of red. Then I want to set up my match case. So I'm going to say match. And I want this to be based on color. So I'm going to be matching colors. And then I want to specify the cases. The cases are going to be the explicit values that can be associated with the variable that's being matched here, in this case, color. So we can say case, for example, red, colon. And then if the value of color matches the case of red, then we can print a statement here and say print the color is red. Now, let's say, for example, the color is blue. So I'm going to say case, and we're going to handle if it is blue. Then we'd say print, the color is blue. Now, let's say for argument's sake, the associated value is not red or blue, and we want to cater for anything else. So it's kind of like an statement. We can say case, underscore, colon, and then we can say print. The color is not red or blue. We can say that. All right, so we've got that set up. Now, if we have a look here at our code, we can see that the output here, that's correct, will be the color is red because the case here is set to red, and that matches the value of what we're matching associated value. So if I run this code, we can see here that that output in the end the color is red. Now let me change this to blue. Save my code and run it. Now, it says the color is blue. Now, let me put in a different color that is not red or blue, essentially what will happen then is the case here with this special underscore, it's then going to trigger and output the following statement, which is the color is not red or blue. Let me switch this to green, for example, and run the code, and it's going to say the color is not red or blue. Okay. So that is how we can implement a very simple match case statement and how we can integrate it. All right. So that's how we can go ahead and set that up accordingly. What I want us to do now is I want us to go a bit further and I want us to create a program that's going to take an input value. So we're going to input a specific value and then the case will output according to the value that we've input by the cases that we've set up in the match statement. Right, so let's continue and create a program that's going to check where someone is from. Where is nationality based. So I'm going to create a simple print statement, first of all, so I'll say print, and I'm going to pose a question. So I'm going to say, where are you from. Okay, very simple. Then we want to make use of an input function that's going to be assigned to a variable known as country, and we're going to match country in our match case statements. So I'm going to say country equals, and I'll say input, just like so. Then we can go on ahead and set up our match case statements. So I'm going to go ahead and say match country. And then I'm going to put a few cases in. So I'm going to say case, and I predict we'll have South Africa, for example, then the print result here will be, you are from South Africa. I'm kind of going to be cheeky here, and I don't want to keep on having different cases. I'm just going to have sort of like an se case. So I'm going to say case, underscore, colon, and I'm going to say print here. You are not from South Africa. It very simple. As you can see, we're going to have a query that's going to be in the output that says, where are you from when we run our code. Then we're going to have to input the country that we're from, and that value that we input will be assigned to the variable country. Then we're going to apply this to our match case here. We're going to say match country. Then the first case we're going to check is if the user input South Africa. If they did and it matches input, we're going to print you are from South Africa and if that user entered anything else, it's going to say you were not from South Africa. Okay, now, what we're going to want to do in this case, is we're going to want to run the PySonFle and not run code. Now, with Run code here with the code runner, okay? It's not going to work so nicely because run code only gives us output, but because we have an input that we want to enter in some data, we have no choice but to go ahead and run the PySon file, but we'll change this near the end again. Alright? So I'm going to say run PySonFle it's going to output this debug console here. And there it says, where are you from? Okay, so here, I'm just going to say, South Africa, it says, You are from South Africa. So it's printing out what we have set up here. Right, so let's go ahead and run the program again and this time, what I'm going to do is I'm going to put something that's different from South Africa. So I'm going to run the program again. And it says, of course, where are you from. So here, this time, I'm going to say USA. Enter and it says, You are not from South Africa. So it evaluates this result here where it says, you are not from South Africa in this case, because this case here of South Africa is untrue. Alright. So that is how we can essentially go on a hedge and integrate this functionality, so we can also test according to input values and utilize our cases accordingly. Alright, guys. So that is it. All I want to do now is switch this to run code, and we can just stop that for now. There we are. Okay, so now we'll have run code, and we can just perform a simple test to make sure that that's fine. I'm just going to say name sano. So let's do one final test here, and we're going to say match name case, we can say John. Could say print. Hi, John, and then I'll say the case here and that's going to be honor and I'll say print honor. Then if it's neither of them, we can just say print hi, friend. Right, so let's go ahead and ensure we are running code, and there we have it. The output here is high no, because that is what we set here as associated value. All right, guys. So that is it for this particular lab exercise on how you can use match K statements. As you can see, it's very similar to our I ELF and s statements. However, there is a bit of a difference, but it's very useful, and I'll definitely recommend utilizing it in your programs if you can. All right, so that's it for this practical lab exercise. 18. Modules: Hi, everyone, and welcome to the next lesson, which is going to be focused on modules. Now, with modules here, this is going to be kind of a refresh lesson, okay, since it is kind of beginner friendly, you could say, but I do want to delve a little bit more into the practical lab exercises when I'm going to be focusing on creating your own modules and then also using the built in modules of Pierson. So I just want to mention the upfront so that you're aware. Okay, so modules. So as a refresher, I just want to go through the basics. So a module is essentially a single PySonFle dot PYS extension that stores functions, variables and classes for reuse in other files, very similar to a toolbox, you could say, in terms of an analogy perspective. Now, instead of repeating code, you can define it in a module and access it whenever you need it. Now, what you can also do is you can create your own modules or you can input built in ones that come with PySon by default. Now, on that note, a full list of all the built in PySon modules can be found at the following URL, and this is something I will just briefly delve over in the next lesson. But I just want to make you aware here. So the main thing to really take into account, other than the definition of a module is that you can either create your own modules or you can use the built in modules that come with PySon on its own. All right, so that's all I want to mention on modules from a theoretical standpoint. 19. Browsing the Python module index: Hi, everyone. Welcome to the next lesson, which is going to be a very short lesson just to give you an oversight over the PySon module index. Now, this is something that I mentioned in the previous lesson near the end when you want to take a deeper look into all of the built in modules that come with PySon out of the box. Here is the PySon Module index. Here you can read all about the built in PySon module. I also want to give you some clarity in a previous lesson that we covered where we used a specific module. If you recall in the regular expressions lesson and more specifically in the practical lab exercise for that topic, we utilize the RE module for regular expressions. Technically here, if you were to go ahead and type in RE, you can say go, and then you can scroll down in this glossary and here you can see we have this RE PySon module here, the regular expression operation, and you can of course, click on that. You can read more about that module that we utilize, which is a built in Python module, not a custom one. Just a little bit of information that I wanted to share with you. That is how you can also read a little bit more for those that are interested to just browse a little bit through some of the concepts and modules available. 20. Integrate custom and built-in modules - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on working with custom methods and also built in methods. So let's go ahead and get started. Now, the first thing that you want to do to create your very first module in Python is you want to head on over to Explorer, and then you can see on the left hand side that you have your projects. So my project, and within that, we have our main dot py file. Now we want to store the functionality within our module in another file. Now, depending on the logic that you have in Said file, it would be best to keep it appropriate to what you're planning on putting in Said file. So I'm going to hover over my project here and say new file, and I'm going to call this greeting dot pi. Now you can see I have a greeting dot pile and a main dot py file within my project. So let's get started. All right. Now, the first thing that you're going to want to do is define some logic. I want to create a function that says hello. I'm going to say deaf and say, say underscore, hello, and then add a codon. That is how we will define a function, and then we can just say return and we can say hello, no, for example. Then let's also define a variable here in this file while we addi. Here I'm going to say favorite underscore greeting, and here I'm going to say, welcome. Very simple. So here, we've defined our greeting dot pi file, and this you could treat as your module. Since a module, of course, is going to be an existing PySonFle which is going to have, for example, functions, classes, et cetera, methods, all in S module in your PySonFle. Now we want to make use of our module here and the functionality that we've set in greetings dot pi. So you can navigate to your main dotp file, and all you need to do is say Import and then refer to that exact file name. So here it's called greeting. So I'm going to say greeting, and there we go. We've successfully imported our own custom module in pyson. Now we want to make it usable. So we can utilize our print statement and say print. Then you want to refer to the model. Dot, and then you can refer to the function that you defined, which in our case will say underscore, hello. You can say dot, say, underscore, hello. I parenths is where you are going to leave it as is because we haven't defined any parameters or anything of the sort, and that is going to return hello o. Let's say I want to get the value of welcome output. We just need to refer to the variable name here, which is favorite greeting and you can just say print and you can say greeting, dot, and then you can say favorite underscore greeting. That's going to output the value associated with said variable. Now if we run the code, we're going to see it says welcome no and welcome. It is returning whatever I defined in my function and it's also going to print out the value of the associated variable that was defined earlier on. All right, so that is a very simple way in which we can go on a hedge and set everything up. But let's say we want to go a little bit more in detail, we want this to be a bit more involved. So we can remove these lines. Go back to greeting, and let's change this up a bit. Can remove that. What I want to do is I want to keep the same function, say hello, but I want to pass through a parameter here. I'm going to say name and then with the return statement here, I'm going to use F strings. I'm going to say F and I'm going to say hello and then I'm going to add in a placeholder that will be name. We're going to pass through the argument in our main Pi file, which is going to then take hold of name here, which is going to then be passed to this placeholder for name. Okay. Then we can have another function for saying goodbye, so I can say deaf, say, underscore, good. Bye. We'll say name again. Return, and we'll have an F string that says good Bye, add in your placeholder, and we'll have Name. Just like that. So now if we go to our main dot by file, what we can do is very similar to before. We can say print. And again, we're going to refer to our custom module which is greeting dot. And of course, our function name will say underscore hello, say, underscore hello. And now we're going to pass through an argument, which is going to substitute our parameter here, and then it's going to drop down into this return statement into the placeholder for what we've defined. So we're going to define the argument now, and here I'm going to say Jack. Then I'm going to go on the next slide and say print greeting, dot, say, and the function name was say underscore, goodbye. I'm going to say say underscore, good, Bye. And here, I'm just going to say, Katie. Again, the same process is going to occur. We are going to invoke that function and pass over the argument and substitute it with the name here, the name parameter, and then pass it down into the return statement within the placeholder to say goodbye, Katie. So let's run this now, so it should say hello Jack and goodbye Katie since we've passed the arguments in here. Let's run this code. And as we can see, it says, Hello Jack and goodbye Katie. All right. So that is how we can work around and add in our own modules. Ch. That is how we can go ahead and set that up. We can just move that and let's delete this file, so we can just right click on Greeting dot pie and say delete. And D now we're working with our main dot Pi file again. Okay, so that is custom modules. Let's say you can create your own custom modules. Now, let's say we want to work with built in modules. So you've already learned before when we were utilizing the RE module when we're working with regular expressions. Now, I'm just going to show you a little bit more just to give you a bit of an idea. So built in modules is Python. We can utilize the mass module. So I'm going to say import mass. And let's say I want to get the square root of a particular value. So here I'm going to say, number equals 16. Then I can say print, refer to the mass module, and I want to utilize the square root function, and I want to get the square root of the number that I have just set up here. I want to get the square root of 16 essentially. So now if I run this, it's going to say four, 4.0. So we've got that right. Okay, so that is how we can utilize the mass module, for example. Let's say we want to output a random number 1-10. So what we can do for that, essentially, is we can go on ahead and utilize the random module. So I'm going to say import random, and then I'm going to say print. Then we're going to refer to the random module, and then random has a rand int function. So generate a random integer between, of course, the parameters that we set. So we can say rand int, the rand int function, and then we want to say between. So I want to output a random number between, let's say, one and ten. So the minimum, it can be is one and the max, it can be ten. You're not going to get 11, 12, 13, or anything like the sort. If I run this, it's going to say six. Now, let's say I run it again, it says two. That is how we can see that this is going to generate a random number 1-10. All right. This is the example of the built in modules. All right. That is it for this practical lamp exercise. Hopefully by now, you have an understanding of how you can create your own modules and utilize the built in modules in pyson. 21. Packages, Pip and PYPI: Hi, everyone, and welcome to the next lesson, which is going to be focused on packages, PIP, and PY PI. So let's take a look. Alright, so packages. Now, in PySon, a package is a folder that groups multiple PySon modules together for better organization. Now, what developers can do and what they often do is that they would install packages using PIP from PYPI otherwise commonly referred to as the PySonPackage index to add extra functionality to their projects. Now this is very permanent in web development areas where developers are utilizing PySon based web frameworks such as Jango or FLASK when they are heading over to PYPI to install a specific package to add a little tweak of functionality to their applications. You can also utilize this in normal pyson program as well, very small ones with a Python script as well. Alright, so PIP and PYPI. Now, PIP is essentially a tool for installing and managing PySon packages. This helps to make it easy to download and update all external libraries instead of coding everything from scratch with lots and lots of modules grouped together. Now, PYPI, which is the PySonPackage Index, this is essentially an online repository that stalls thousands of PySon packages, which we can download and utilize within our PySon programs. Now PIP fetches packages from PYPI so that you can use them in your projects. Okay. All right, guys, that's it on packages, PYPI and setting everything in accordance with PIP as well. In the practical lab excise, we're going to dive deeper and we're going to work with a few examples to enhance our program. 22. Utilising external packages - [Lab]: Hi, everyone. Welcome to the next practical lab exercise, which is going to be focused on working with packages. Now, this is the PI website you can head on over to pypi.org and that will take you to this website. This is where you can browse thousands of projects and how you can implement just a small application or library within your PySonPject. This is the PySonPackage Index. We can also search for projects here and then we can integrate them within our PySon applications. Right. The first one I'm going to look at is going to be simple. I want us to add in some emojis to our code. At least that's what we see in our output window. What I'm going to do is I'm going to search for image and search for it. Okay. And here we have one. So emoji, which is the emoji for PySon. And you can see we can install it by saying perp stallimogi. Right. So we're going to want to input some commands. Now, what we're going to have to do for now is we can switch up to run the PySon file just for now. Okay. And here we have everything here. Let's clear this up. Okay, there we go. And what I'm going to also do is I'm going to just close some of these terminals here and reopen There we go and clear. There we have it. Here is our terminal now. Now we can go ahead and run some commands. Let's say we want to install this emoji package. We can just go ahead and copy the following, head onto our terminal, and we can of course, right click and it will auto paste for you. We can say Pep install Emoji. Okay. And as you can see there, we have installed pricing packages into the global environment, which can cause conflicts. You can go ahead and create a virtual environment to isolate your dependency. So this is a topic we will go into detail later on in this course. So don't worry, we will get to that momentarily. So we can just say for now don't show again. Right, so as we can see now in the background and went ahead and install that Emoji package. There we go. Then we can clear this up now. All right, perfect. So we've got that installed. Now let's go ahead and integrate this. So here we have our code. Now, what I'm going to do is I'm going to import that particular libraries. I'm going to say importmoji and then we want to add an emoji to our text. So for example, I'll have a statement here that says print, and I'm going to refer to that emoji module, and I'm going to say dot. And it has a function known as emojis. So it's EMO J, I Z E. And within this function here, we're going to add what we want to add in the checks we want to output, along with emote or emoji that we want to output as well. So here, for example, I'll say your password is ready. Right. Now the next thing that you would do is add in your emerges. You can add in a space, and then Imoges in pyson are determined by adding in a colon and then the name of your emoji, I'm going to add in key and then close it with a colon. Now, there is a website that you can use here at copy dm dot kitp dot IO. I will refer to this particular resource in the next lesson, so you can have a look here at all of the individual emoges. But as you can see, they dictated by the colons either side and the name of S value right in the middle. All right. So that's exactly what I'm doing here and I'm setting it for a key. So let's go ahead and run our code. And here you can see it says your password is ready. So we can see it's nice and clean that it has that key as well. So I can also clear this up. And let me set this now to check underscore mark, save the file. And I'm going to run it manually this time. I'm going to say Python. Main dot pie. And there you can see it outputs, your password is ready. So very clean and very astute, you could say. And there we go. So that is how we can utilize images in PySon. Now, let's go ahead and add Let's add colors to our terminal here, to our text and our output text as well. So we can go on back. And we want to search for something known as colorRama. So you can enter in here, colorRama and you can then go on ahead and press Enter. Please here we have it, a cross platform color terminal text. And we want to copy the following, head on over to our terminal, right click and say Pep and store colorRama. It's just installing, there we go. It's been installed. Let's clear this up. And what we can do is go on a hedge and remove this code. All right, so we want to go on a hedge and grab the Clama module so we can say from Carlo Rama, so that's the module, and we want to import the four class. So this works as a class. And what we're going to want to do is use the print statement, and we're going to go ahead and say four, which is the class, and then we're going to specify the attribute of sorts. So let's say we want our text to be red, we're simply going to say red. Then we can say plus, and then here in our work quotes, we can say this is red text. Okay, so let's go ahead and run our code PySNmin dot pi. And you can see now everything is in red. So the checks here that we've printed out is in red, and also the terminal color is also in red. So if I were to clear this up, you can see it's now in red. Let's say I want to change this to green, for example, I can just change the attribute here to green. Save my file, and I can just say Python main dot pi. And there we go, we can go on ahead and see now that it is changed to green. I just need to change the text there to green, and there we go, it is green text. Okay, so we can see it's green. Let's set this to blue, blue, and we're going to say this is blue. Text, MSN main dot pie, and this is blue text. Okay, so we can see that's how we can change those colors. You can see how effective it is to utilize packages within your programs. Let's go back to the default, which is, of course, white. So I'm going to say this is white text. And you can press the upper arrow on your keyboard to quickly look for the commands a pysmminPi and then we go back on white text. So we can just remove that. There we go. Let's use another package which is going to allow us to generate a password. So a secure password, and we're going to determine the characters that we want ins password. So this can be useful if you want to give a list of passwords for your friend to choose if they're struggling to choose a password that's secure. So we can look for the package and then it's PWN, so password Gen like the shortened term. Here we have it, PWGen and we can copy the following, add onto your terminal, right click and paste that in and Enter. Remember the time for installation is going to vary among everyone, so don't worry if it takes some time to install and everything to get the following notice of sorts. It has been installed, and let's go ahead and set this up. We want to import the PWGen module. Then what we want to do is to define a variable, which I'm going to set as password, and I'm going to then grab the PWGen module, and then we're going to refer to the function of PWgen which is incidentally also the same name. And here we're going to define the lengths for our password. So I'm going to set this to ten characters. Then I'm going to go to the next line and say print. I'm going to say generated password, colon, and I'll add in a comma and then refer to the password that I'm seeing. PWG will generate a random password for me associated with this variable output and this text is just going to be right next to that. So now let's go ahead and say pysonmin dot pi. And here we can see the generated password. So it's a random generated password that's been set up. So it is also ten characters, so one, two, three, four, five, six, seven, eight, nine, ten. Let's set this, for example, to five. Let's run Python main dot pi. And we can see we have a password that's only five characters long. So you can see how you can adjust it and change it as you so feel. So with this package, you're going to learn how you can generate a random password. All right. So that is how we can go on ahead and set this up accordingly. Right, so what I want to do now is I want to close this up, and I want to use what we did before so we can click here on icon and run code, and we want to now just bring it back to where we were before with our code runner, since we're not inputting anything or installing anything. Right, guys. That is it. That is it for this practical lab exercise on how we can utilize packages and how we can install them and how we can utilize them to integrate their own set of custom functionalities to our projects and the lodge. 23. Helpful resources: Hi, everyone. Welcome to the next lesson, which is going to be focused on providing you with the as specified links that I mentioned from the previous lesson. Now, the first one is going to be how to access PyPI. It's very simple. You would just go on ahead and type in pypi.org in your URL and that will take you to the PySonPackage Index, which is going to show you a list of all of the third party libraries packages that are available to you, such as the ones that we used earlier, such as PW Jen and Color Rama and Emoji. Now in terms of the Imoges that I used, of course, it looked like I was memorizing them or you would say, but there is actually a site where you can look at how you would integrate them by utilizing the Pip in store Emoji command. Now you can head on over to the following URL here as you can see, copy and then DM and then 20 dockets of the IOsmogFdslash. That's how you can access that website as well. I just wanted to give you a little bit of clarity here in terms of the resources and the links. If you want to experiment more and add in some emerges and you just want to practice a little bit and look at a few of the packages that are available to you and just experiment a bit, that is how you can go ahead and do so. 24. Generate random numbers: Hi, everyone, and welcome to the next lesson, which is going to be focused on generating random numbers. So let's get started. So how do we generate random numbers? Now, PySon, as you know, comes with a lot of different modules to generate random numbers. Now, we're going to explore three modules. Now, the first module we've already gone through, and that is the random module. And with this module, we can generate pseudo random numbers. We also have a secrets module, and that creates cryptographically secure random numbers. And we also get the numpit Random module, which generates random numbers in arrays. So what we're going to do is we're going to apply our knowledge in a learn by doing manner. So let's go on ahead and get started with the practical lab exercises. 25. Deep dive on the random module - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on generating random numbers by utilizing three different kinds of modules. So we'll be utilizing the random module. The secrets module and also the Num Pi module as well, which we are going to install within our device in due course. But let's go ahead and get started with the random module, let's go ahead and exploit it as much as we can. Now, the first thing we need to do, of course, is say import random so that we can access the necessary functions. And we're going to first of all, want to output float numbers 0-1. So we can say print. Random dot random. And essentially what we're doing here is we are calling the random module, and that has a function which is going to print floats. So if I were to run the code here, it's going to print floating numbers here 0-1, so we will have decimal numbers as a result of this random function that's part of the random module itself. We can see it changes every time to a different number. Now, let's say we want to generate a random float 1-10. Instead of using this random function, we would say dot uniform and you're going to want to put the bounds, let's say 1-10. And you can run this code. Now, that's going to print floating point numbers. So floats are essentially numbers that are decimal format, and it's going to be 1-10. Now, it's going to be able to run 1.0, but it will never run ten. So essentially, it's going to be everything 1-9 in actual fact in terms of a decimal sort of order. Right. Now, let's go ahead now and print out random integers. We just experimented now with random floating point numbers or floats, as you would say, by using the dot random function and then the uniform function. Now, let's say we want to print random integers. We can use the rand int function, and let's say we want to print numbers 1-10. Okay, so this is going to include both one and ten. So with the rand in function, it will allow for the lower bound and the upper bound value. Let's run this. So we have three, six, and we can see it's an integer because it's the whole number that's being output nine, six, one, eight, three, ten. Right. Now, let's say we want to print random integers again, but we want it to be in a specific range. Now, let's say we want to print 1-9, meaning I want to also output nine. You would go ahead and change it from rand int, you would set it to rand range. Now, the difference here is it's going to exclude ten. Now, Rand It before included ten, but in this case, with Rand range is going to print from the lower bound, choose the upper bound minus one. So let's go ahead and run this code. Let's go ahead and run it. There we go. You'll notice if you execute this quite a lot of times, you're going to notice that it's never going to output ten. However, if you wanted to output ten, you would technically need to set this to 11. Then when you execute this code, it will eventually give you at least a chance of printing out ten. Just something for you to experiment with. Remember, the rand in function will include both the lower and upper bound values and Rand range only includes the lower bound number and then the upper bound number minus one. That is how that is going to work. We've looked at floating point numbers and random integers. Now, let's go ahead and look at normal distribution for statistics, for example. If you're interested in statistics or you're working in that light, we can utilize the random module and use the normal variate function and we can pass through zero and one. Now, it's going to take in a mean and the standard deviation is what's going to be taking place. In this case here, the mean will be zero and standard deviation is going to be one. If we run this, we're going to see what the normal standard variation is going to be each time we execute. Still going to be random because it's a random module. But as we can see that is how we can go ahead and utilize normal distribution with a mean and a standard deviation. Right. Now, let's go ahead and apply this when we're working with lists. So we can remove this. I'm going to create a list here and I'm going to say cars, equals, and I'm going to set up a list of cars. I'm going to say BMW, I'm going to say Tesla. I'm going to say Ford, and the last one, I can set Nissan. I have my cards in place. Now, the first thing that I want to show you is how you can pick a random item or element from this list. To do so, you can say print and we want to make use of the random module and there is a function called choice. We're going to apply choice to this list here. And essentially what's what's going to happen here, it's going to print a random item from this list. The dot choice function is going to allow you to choose a random item from the list that you've defined. So if I run the code, you're going to see Tesla, Tesla, BMW, BMW, Tesla, Nissa, it's going to be completely random each time you click it. Okay, so that is how you can utilize this particular function. Now, let's say you want to go on ahead and pick two unique elements. So you don't want to keep on just selecting one choice each time. You want to select two unique elements each time. So you can adjust this, and instead of saying dot choice, you will use the sample function. Going to plug in the list and then two. So now, you're going to pick two unique elements from this list. So if we were to run the code, we can see we have Ford Tesla. We have BMW Tesla, Ford Nissan, Tesla Nissan, and you're going to see here, it's going to just go on ahead and output two random elements or items from the given list. So that is the whole purpose of the sample function. If I wanted to select three, for example, each iteration, I can just replace that, save my code, and run it now it's going to appear in three randomly choosing which elements to output and sample. Now, something interesting that you may want to look into here is the fact that you're using the dot sample function and you're sending three or let's say, for example, two, it's never going to show duplicate items. So as we can see here, if I put two, it shows Nissan and Ford. It's not going to show, for example, Nissan Nissan, Ford Ford, Tesla, Tesla, BMW, BMW, it's not going to show that it's always going to go ahead and show something that is unique. So if I were to just rerun the code here, it's going to always show something that is unique each time that you run your code. Okay. So just something I wanted to mention on that note. Another thing that you can do is you can shuffle your list as well. Now, if I were to go on ahead and output my list, if I just say print cars and run, hose BMW, Tess a Ford, and Nissan. Okay, so if I run this again, it's going to do it in the same order, but let's say I want to shuffle this list. So what you can do is as follows. You can say print, and here within the function, you can say random dot shuffle, and you can put that list as follows. So this function is going to shuffle the order of what is included in the list. So it won't be each time when you run BMW, Tesla Ford Nissan, so if I run it, okay, you're going to see it's going to run in the non state. Now, the reason for this is you need to shuffle the list before you run your print function. So something I wanted to mention here. So you have to do this separately. As is, let it shuffle and then print. So this particular function works a little bit differently. You're going to have to leave it on its own. Now, earlier when I was showing you, you can include all of the functions and the modules together in the print statement and print the result. However, with shuffling the shuffle function, it works on its own. So here we would need to say explicitly cars afterwards. So when I run this, it's going to say BMW Nissan Forte, and you can see it shuffles the items as we can see. Although you cannot do it within a print function. So a very important point to note. And as you saw earlier, you're going to have a result of none. So this is something important that you need to keep in mind. So with most modules and functions that you want to use, you can add them in a print function, but if you're shuffling, it needs to be explicitly on its own with the shuffle function itself, and then you can print afterwards so that it shuffles the list, and then you can print that result afterwards. Okay, so just something important to remember. So it's going to modify the place. Okay. Great. Now, let's go on ahead and look at some more functions. Now, let's say, for example, I want to have random elements appear, and I also want it to be repeated, as well. So I don't want it to be in a how can I say a particular situation where we have the duplicates, but I also want to allow it to have some repetition in place. So let's go ahead and do just that. So we have our nest, and we can remove what we have here, and we can just say print random dot, and we're going to say choices this time. Remember earlier we had choice, which means single choices. We can have multiple choices, and we'll say cars, and that's going to be the list that is going to be added on, and we're going to say K equals, and we can set that to two. Alr. So that is what we want to add. And this can return duplicate values. So unlike before, when we went on a hedge and set up our sample with a sample function, you can't have duplicates, but with the choices function, you can have duplicates here. So by K equals two, we're specifying how many elements we want to output. So if I were to say run, Nissan, Tesla Tesla. So here you can see it's going to show two elements from the list, but it can be repeated, so you can see two of the same thing. So that is how you can have some sort of repetition. Right. Now, the next thing that I want to show you is how you can utilize the triangular function. Now, the triangular function is quite unique because it's going to return a float between low, high, and mode. Okay? And mode is the peak of where the output is most likely going to be closest to. So it's very similar to rounding up, you could say. So let me show you how we can do that. So we can go on a hedge and remove what we have here. And we can add our print statement. And I'm going to say random dot, triangular, that will be the function. And first, we're going to have a float that we want to return in the low point. Low point will be one. The high point can be ten, and the mode or peak can be five. So if I were to run this, going to see that the output here, of course, is a float, but you can see it's going to be closest to the mode. So one is the low point. Ten is the high point and five is the mode, in other words, the most likely point as to where the output value will be closest to. So 6.0 closest to five, 5.1, basically five, 4.7 closest to five, 5.4, closest to five, 5.2, closest to five, 5.6, close to five. So you can see there how that is working into place. Right. Now, the next thing I want to show you is quite similar to the normal function that we used before. Now, let's say we're working with simulations and we want to simulate real world measurements with natural variation. We can use the gauze function. So it's also going to take in, how can I say a mean and a sigma for the standard deviation. So what you would do is you would just replace triangulart Gauze then we can pass through zero and one as the mean and Sigma, this is going to output normally distributed value around zero, you could say, if I run this, we can see there's going to output the associated distribution by using the gauze function. A lot of this is based on statistics, the triangular gauze and the normal variate functions are mainly used in the statistics branch, should I say. But it's just something I wanted to show you so you can at least get a bit of an understanding as to the output and what to expect. Right. So there we have it. The most important things I want to remind you here when you're using your print functions, you can operate your functions and modules in the same print function. However, you cannot do it for the shuffle, so just keep that in mind. All right, right, go. So that is it for the random module. Next, we're going to go on ahead and focus on the secrets module. 26. Exploring the secrets module - [Lab]: Alright, so let's continue with the Secrets module. Okay, so what I want to do, first of all, is import the Secrets module. And the first thing that we want to do is we want to return a random integer that is below a given number. So what I can do here is I can say print, and I'm going to utilize the secrets module. I'm going to then use the range below function, and I want to print out a random number 0-9. And to do so, I would need to just put in ten. So it's going to print everything 0-9, and it's not going to include ten. So if we were to run the code here, we can see we have eight, three, one, eight, you'll notice it's not going to print out ten, it will do everything else otherwise than that. Another thing we can do is we can go on a hedge and output a specific choice also by utilizing the secrets module. Now, let's say for argument's sake that we have a list here of sensitive codes. I'm going to say codes and in a list, I'm going to put in Alpha, Beta, Gamma. I want to retrieve a secure random choice, per se. I can say print and refer to the secrets module. And then the function I would use is choice, and I'm going to put in codes. So I'm going to retrieve a secret choice. You could say or code. So if I run this, I can see I have Alpha. Each time I run is going to give me a new code, so Gamma, Alpha, Beta. All right. So that's how you can pick a random choice from a given sequence. Okay. Now the next thing I want to show you is quite unique to the secrets module, and that is how you can generate a secure hex token. And this is, of course, going to be 16 characters long. So let's go ahead and do that. Now, the value that you put in is going to, of course, be set up in bytes. So, of course, it's going to be double in our case. Okay, so let's go ahead and do that. So what we can do is we can simply say print use the secrets module, and we can utilize the token, underscore hex function, and we're going to say eight, and this is going to generate a secure hex token that will be 16 characters long. Let's run this and we can see here we have BA ED and this whole number, and that's going to be 16 characters. Now, of course, if I were to only set this 24 and run it, it's only going to print out eight characters. Because remember, we are setting the bytes in here, and essentially that's going to go ahead and double it. So if I were to put four in here, run it, it's only going to give me a four hex token output. This can be very helpful if you need tokens in some sense. That is how you can generate a secure hex token. This is how we can utilize the Secrets module, right. That is the Secrets module. The next thing that we're going to look at is the numPi module and that's something that we're going to want to go on ahead and install first within our project. We usually use the Numpi module for fast random operations, but more than that soon enough. 27. Deep dive on the numpy module - [Lab]: Alright, so let's continue. Now the next thing we're going to focus on is on the Num Pi module. And this is also very useful for working with arrays as well. But more on that soon enough. So the first thing we want to do is we want to head on over to PYPI and we want to see Pep install numPie. So we can go ahead and copy this, or you can actually type it in your terminal and Visual Studio code. And what I'm going to do now is I'm just going to switch 30 Bug to run PySonFle just for now. We can clear this output. And you just want to say Pep install num Pi, and you can press Enter. Okay. And that's just going to install it for us. Okay. Let's just be patient and give it a moment, and then we can continue with utilizing the Num Pi module. Okay, so let's just give it some time. Right, so we can see it has been installed. We can clear this up. And we don't need that anymore. Let's switch to run code, and there we go. Right. Now, now that we have the NumPi package installed, we can now access its particular modules. So I can see Import. Num Pi. Now, according to the standard, typically, Num Pi is quite lengthy for a module name. And since it is used quite often, what people usually do is they set up an alias in terms of the module name. So you can say a, and then we can define the alias as N P. So other words, wherever we define MP, that means we are basically invoking the Num Pi module itself. So just a bit of a hefty trick if you want to set up aliases with your modules. In this case, this is 99% of the time always followed when you're using NumPi. Okay. Now, the first thing that I want to show you is how you can go on ahead and set up basic arrays. Okay. So we're going to say print, and we're going to refer to NP. And we're going to utilize submodules. So NumPi has a submodule, which is called random, which has a function called Rand. So do keep that in mind. So here we're using random as a sub module. So NumPi is our module. Random is our submodule, and Rand is our function. So do keep that in mind in case you're getting a bit confused. So there is a bit of a difference in this regard. And with the rand function now, that's going to allow us to generate a one D array, and we just need to specify how many random floats we want 0-1. So I want to have. So if I run this, we may need to there we go. It's now going to print out a one dimensional array as we can see, and it's going to have three random floats because remember, rand is going to be focused on the output of floats. So anything with a decimal and it's going to be three random floats in the range of zero to one, so we can see here 0.16, 0.93, 0.7, it's all between that range. Let's say I want to generate a three by three array, not just one array, three by three. I can just say comma and then three, and now we can say run code. There we go, we have a three by three array now. It looks very similar to what you get in mathematics when you get matrix or anything of the sort, very similar in a way. In this case here, we are returning a three by three array with random floats 0-1 again as you can see. A. That is what we have in place here. That is how you can set up your arrays. Now, another thing that you can do is you can set up a array with integers as well. Here we're setting up an array with floats. Let's go ahead and change this up. I'm going to now change the function to rand int. Here we're going to just close it up and we're going to put in. We're going to put in three values here, in this case, we're going to have a low, a high, and a size. In this case, we're going to have zero, which is low, ten, which is high, and then the size, we're going to set as three. Okay. Now, in this case here, the values here are going to be 0-10, excluding ten, it's going to be zero to nine and we're going to have random integers, three random integers that are 0-9 in a one dimensional array. If I were to run this, we can see you've got the following. We've got one dimensional array. The values are 0-10, excluding ten, and we have three values. So if we were to go ahead and run that again, you can see now it's going to go ahead and output that result. That is how you can generate a one dimensional array of three random integers that are 0-9. Okay. So the low part is, of course, the base that you're starting. The high part is, of course, the upper bound, which you exclude. You just are on the upper bound minus one. So remember, whenever you are hearing about upper bound values or anything of the such, you're always going to minus one. So it's just a bit of a nifty trick that I would advise you whenever you are dealing with upper bound values that are excluding. Always minus one. That's where the true count will go up to at the most. Okay, so this is how you can work with basic arrays by utilizing the NumPi module. Okay, so what I want to do now is show you a few more useful functions that you can use. Now the next thing I want to show you is how you can generate a set of random numbers from a standard normal distribution where we will have the mean of zero and the standard deviation of one. So what we can say is print, and you can see np dot random dot Rand, and we will have N because this is going to be for normal distribution. And here we're going to put in how many random numbers we want from a normal distribution. This can be very useful if we are simulating, for example, fluctuations in a stock market or heights or anything of the like. Run that, there we go. You can see now that we've generated three random numbers from a normal distribution. Okay. So we've got that setup. The next thing I want to show you is what you can do if you want to go ahead and pick random elements or items with or without a replacement. Okay. Now, what I mean by that is the replacement is going to dictate whether you have duplicates or if you don't have duplicates. It's very similar to what I explained before with the dot sample function and the dot choices function where you add in K equals two, for example, very similar to what we had earlier with the random module, but this is how you're going to apply it with the Num Pi module itself. This is what we're going to do. We're going to first define a list. This list here is going to, let's go ahead and clean this up. We'll have a list, and we're going to say fruits equals and we can say pair Apple grape orange. We have a list of fruits, go ahead and define a list, and then we can say print and Np dot random as a submodule, and we're going to say dot choice. So this time we'll use choice, and we're going to add in three options. Now, let's say I want to go ahead and pick two unique elements from this list. We're first going to define from what list. So in this case, it's going to be fruits. Then it's going to be two, and then we want to say replace equals false. This is going to allow us essentially this code to pick two unique items and by saying replace equals false, means we're going to ensure that there are no duplicates. In other words, when we are selecting two items from this fruits list, we don't want to select apple twice like Apple and Apple or grape and grape or orange and orange or pear and pear. Let me demonstrate that for you. Replace helps to prevent the duplication. Let's go ahead and run the code. We have apple pear orange grape, Apple orange, apple grape, orange grape, orange pear. You're going to see it's not going to have any duplicates of the sort. But however, if I were to set replace to true, it's then going to allow for duplicates. So if I say replace equals true, Save this and run orange apple, orange grape. Papa. There we go. Now we have a duplicate in place. So we can now have duplicate values that are being selected. So two values can be selected that are the same. Then you will have replace equals true. Okay, so that is how we can add that into place. Okay, so very similar like I said, to what we had before with random the random module. All right. So we have that. Perfect. Okay, so let's go ahead and see where we can go further. Now, let's say, for argument's sake, you want to go on a hedge and return an array of floats with low and high. Okay? So what you can do is you can go ahead and say print. N P dot random. And you want to say the dot uniform. So remember, with the dot uniform function, you're going to be dealing with float, so the output will be in floats. And we're going to take in three values here. So we'll first have high, a low and a size. So first, the high, we're going to say one to ten. And then we want to have five random floats, so we can say five. Okay. So let's go ahead and run this. Okay. There we go. We're going to see we have one, two, three, four, five, it's going to be between, as we can see here, the low and the high, so one to ten, remember, it's not going to ever be ten. It's not going to be on ten. If we run this, we can see there it's not going to any case be ten. This is what we can do if we want to return array again of floats in high and low. All right. Okay, perfect. So we've got there you can see here the highest it can go up to as we see is 9.74 and even going as low as 2.29, but not at all going above ten. Now, let's say we want to return an array of normally distributed numbers. So we will use something known as the normal function. So what we can do is we can say mp dot random dot normal. And we can just close it up. We're going to take three values. So we'll have zero, for example, one, and we can say five. Now, the first value here is going to be for MU. Then we'll have Sigma, and then we'll have size. And we're going to return five of those normally distributed numbers in an array. And there we can see we've got that output accordingly, right? Perfect. And that is how we can go on ahead and set up the normal function as well. Alright, so there we have it. There is the way in which we can utilize all three of those modules. And I just wanted to give you a bit of an overview into how you can go on a head and utilize all of them, and some of the most popular functions. Now, I know some of them might have been a bit out there and a bit out of scope. A bit of it dives, like I mentioned, into a little bit of statistics, but it's important to at least be aware of them and to just have a little bit of context, not to say you'll ever use it, but it's just good to have some background knowledge, so you know that they exist, and you're not limited to just using one or two functions that are available. Any case, that's on Num Pi in terms of the num Pi random functions and such. And yes, that concludes this three part practical lab exercise set. 28. Decorators: Hi, everyone, and welcome to the next lesson, which is going to be focus on decorators. So what is a decorator? That's probably what's on your mind right now. So simply put a decorator in PySon is a special function or class that enhances another function or method without changing its original code. So let me give you a very simple analogy. Let's say you are getting ready for Christmas and you want to become festive and decorative. The first thing that you do is you get yourself a Christmas tree. So that is part of the decoration. However, what people do is they decorate the tree, so they go a step further and they put a lot of nice things on the tree. So try to see a decorator in this literal sense of their analogy. You could treat the Christmas tree as a function and the additional decorators you put on as a special function. That's just a way that you can go on ahead and try to how can I say, put it into perspective. Now, in PySon like I mentioned, a decorator can either be a special function or class. However, the most common decorator is, of course, the function decorator. 99.9% of the time when you're working with Pyson in any environment or ecosystem, you're going to see decorators in the sort of perspective of having a function. Now, another thing that I want to mention in terms of decorators is that it enables dynamic modifications. So what you can do is you can add or alter functionality for your functions and class methods as a whole. All right, guys. So that's it for the theoretical overview. And in the next lesson, we're going to work on a few exercises to solidify our knowledge on decorators in pyson. 29. Creating our first decorator - [Lab]: Hi, everyone. And welcome to the next practical lab exercise, which is going to be focused on working with decorators in PySon. So we're going to keep it very simple as a start and then we can build on with a few examples. So let's get started. Okay, so the first thing that we need to be aware of is how we can define a simple function in PySon and then we can build on from there. Right. So the first thing I'm going to do is define a function. I'm going to say Def and I'm going to say here say underscore Hello. And I'm going to leave the parenses empty and I'm not going to pass through anything in the curlon. And then what I'm going to do here is I'm going to say print, and it was in the print statement here, I'm going to say hello world. Perfect. Now what I want to do is I want to call this function, and I'm going to say, say, underscore, hello. There we go. What's essentially going to happen is we're going to define this function. It's then going to execute print hello world once it gets called. Here we're calling this particular function and it will execute whatever is within this function itself. Let's go ahead and run the code and we can see there it outputs hello world. That is the simple way in which you can utilize a function. Great. Perfect. So now that we have that on the wraps, let's go ahead and build upon this. So we have this function, and let's say we want to go on a hedge and modify the results that we're going to get with this function. Okay, so let's say we want to wrap this in a decorator and we want to have more of an output, not just hello world. We want to have a little bit more than that. So what I'm going to do is I'm going to go ahead and define a decorator. Now, a decorator, of course, like I mentioned, can either be a function or a class now a special functional class to be more specific. What I'm going to do is just zoom out a tad bit here and we're going to define a special function now. I'm going to say ef and this function here, I'm going to call this M underscore decorator. Okay. And then what we're going to do is we're going to pass through funk. Okay. Now, you can treat funk here as a parameter, okay, for another function which we're going to how can I say absorb? Now, this function that it absorbs is going to be absorbed when we add the decorator on top of the function. So let's say I want to go on ahead and modify this function here. What I would need to do is add in the at decorator and that at decorator is going to reference this function here called My decorator. My underscore decorator and now funk here is the parameter, and this is now going to take in this particular function that we have right here. Because we have funk here, and the reason that it knows that it's going to be this function because we attach the decorator. With this decorator, it's going to grab this function and pass it through here automatically because of this decorator that we added here was the at symbol, it's going to pass it through here. This is now essentially the decorator function and this is our original function. We can add a colon right there. Then the next thing we need to do is we need to wrap. We need to wrap this original function within our decorator. You could say in our new function. You would need to say death. Wrapper, opening and closing parentheses and close the colon. This is going to be the new function that's going to wrap around the original function now. Next thing that we're going to want to do is we're going to want to do a simple test and just run some code here. So I'll just run a simple print statement that's going to say the function is about to run. Okay? So this statement is going to execute before we run this function here, which has been passed through funk. So to call this function, we would need to go on ahead and say funk, right? And that is then going to execute this function here, which is going to say hello world. After that has been executed, we can then set up another print statement here that says the function has finished running. So this runs after the function has been called. Now the last thing we need to do is we need to return this output via the new wrapped function. So to do so, we can write here indent and say return wrapper, and that's going to execute everything accordingly for us. Okay. That is how we can simply set up a decorator. Okay? Alright, so let me go on ahead and show you what's going to happen now. So what will happen is as follows. So the first thing that's going to happen is this print statement will execute. Then the decorator is going to take this original function that we had, and as you can see, it modifies it. It doesn't alter anything that has been defined within it. It's going to pass it through here the parameter, and then we're going to call it within the wrapper, and then we're going to print an output statement to say that it has finished running aches and we'll return that wrapper to ensure that it has been adjusted. So now if I were to run my code, I can now see that my output is going to say the function is about to run, hello world, and the function has finished running. And you can see that has all been executed as it should have. Okay. So that is how we can go on ahead and set that all up to work as it should. Right, so let me give you a little bit more detail so that you understand everything perfectly. So here we have M underscore decorator funk. So again, funk is going to be the function that is being decorated. In this case, it's going to be say hello, which is being decorated by the at my underscore decorator. So this is how you decorate a function. You put in the at symbol and then followed by the decorated function, should I say? Okay. And my decorator, Frank here is going to receive the function and it's going to wrap extra code around it, which it does with this wrapper. So it's going to add in this output statement here that says the function is about to run, and this one here that says the function has finished running. So we have this wrapper here, okay? And this is a new function within our decorator. And as you can see, it adds extra behavior, namely right here and right here. So before and running the original function defined by funk. Okay. Now, the wrapper here is going to call funk inside. So the original function is still going to be running. Then we have return wrapper. So instead of returning funk itself, okay, we're going to return wrapper, okay? Now whenever we call say hello, we're actually going to be calling the return. We're actually going to be calling wrapper. That is essentially what we'll be doing. All right. There we have it. There is the simplest way in which we can integrate a decorator within Python. We are going to work on a few more practical exercises, but that is the basics to set up your very first decorator and how you can apply it to a given concept. Right, what we can do is just go ahead and take it out for now and then we'll continue momentarily. 30. Working with Decorators - [Lab]: All right. So let's continue and work on a few practical exercises. Now, the next thing that we want to do is we want to work on a program which is going to convert the function output to upper case. So let's go ahead and apply this. Okay, so the first thing is first, let's go ahead and set up a simple function. So we're going to say def, breed and then here we're going to say return, and I'm going to say there, let's say, good morning. Very simple. Then I'm going to say print. Greet. And if I run this code, it's going to say good morning. So there we have it very simple. So in this case, I removed the print statement from within the function. I moved that outside, and I'm just returning the given text, which is to say good morning, and then I'm calling the function here accordingly, it was in the print statement to execute it Wister value that's been returned ins function. Now, remember what our use case is. We want to convert the function output to uppercase. Here when we're printing and executing this function, we want this to be in uppercase. Let's go ahead and make that happen. So we would need to have uppercase decorator for that. That would be a good sort of use case say death here and we can say upper case underscore decorator. Then we're going to pass through funk. Now, in order to absorb this function, we would need to add in the decorator, which will be at, and that's going to be uppercase underscore decorator here, and then it's going to pass through this function as it has right now. Then we need to define IO wrapper we can say def wrapper. Then we want to call the original function, and we're going to assign that to a variable. I'm going to say here result equals, and that's going to be funk. I'm storing this particular function, which is going to be passed through here as funk and I'm going to store that in this variable called result. Here is where I'm calling the original function. Then the next thing I want to do is convert the output to upper case. So whatever the result is here of funk, which is essentially good morning, I want to convert that result to uppercase. So I can say return result dot upper. So I'm going to apply this particular method here, the upper method, and that's going to convert the output to upper case. And then all I need to do now to return the new function is return the wrapper. I can just say here, return wrapper. And there we have it. Now what we can do is we can go on a hedge and run the code. Let's do Zach and we can see the output now is showing good morning and that is in fact in upper case. We can see that that is now a lot cleaner and concise now that we've added in that decorator. Right. So that is how we can create a simple program that converts the function output to uproot case. So we can see where it's useful. So it automatically formats text without changing the original function itself. So you can see this function wasn't changed at all. And as we can see, this can also be very useful if we are displaying titles, messages or any sort of user input in some sort of standard way, should I say? Okay. So that is how we can go ahead and do so. Edge. That is one example that we can go on a hedge and follow. All right. Let's go ahead and look at another example. Now, let's go ahead and create another program. In this program, the use case is going to be focused on ensuring that our passwords are at least eight characters long. Now, let's define a simple function to get started. I'm going to say, D, generate underscore password as my basic function at the colon, and here I'm going to say return, ABC. Very simple. So this would be seen as a very weak password to start off with. Not only is it generic because it's ABC, but it is also on the how can I say on the low side in terms of characters. Okay. Then what we'll do is say print, and we're going to just print out that particular functions. I will say generate, underscore password, opening and closing parenses. And if we run this, it's going to output ABC, since that is what we're returning in this function. Right. So that is how we can go ahead and get that function started. Now, let's go on ahead and make this a little bit more complex. Now, in order to check if a password is too sharp and to ensure that the parsed is at least eight characters long, we're going to need to make use of a few modules. So we're going to make use of the random module and the string module. So up to this stage, it should be quite knowledgeable with modules and quite confident with it. So let's go ahead and get started with it. I would say import random, and then we can say Import string. Rich. Okay. Now what we can do is define our decorator function to begin with. So I'm going to say deaf, strong underscore password. I'm going to pass through funk. And before we can actually utilize this function, we need to add in our decorator and say at, and it's going to be strong underscore password. Just like that. Rich. Next thing that we want to do is define our wrapper. So we'll say deaf wrapper and we can just adjust it like that. Then we want to call our original function, which is right here, generate password. So to do so, we can just say password equals funk, and we're going to assign it to the variable password. So whatever is going to be returned in the result here will be ABC, that's going to be set to the password, which is currently now ABC. Then we want to set a WLloop to check if the password is too short, then we want to perform an action. So what we can do here is say while the length. So we're going to use the ng function to check the length of the password, and if it is less than eight. What I want to do is grab my password. And then I want to increment it by a random digit each time. I'm going to use the random module and say dot choice. Remember dot choice is one, and we're going to say here string dot digits. Now, string dot digits here essentially is going to go on a hedge and it's going to this value, should I say string dot digits is going to be 0-9 in strings. String dot digits is, of course, the digit zero to nine in a whole string. And this random dot choice function here is going to pick a random digit 0-9 in string format and it's going to add it onto the password. We'll have ABC, and then we can have ABC two. That's going to increment and run again. That's going to be ABC seven. That's going to increment and run again and it's going to be AB 274 like that, and it's going to add another digit. Next thing that we're going to want to do is once that has gone ahead and reach the upper bound here. While it is, how can I say greater than eight. While it's not less than eight anymore, it's then going to break the while loop and then we can say return password and then it's going to return the final password, and after doing this, we want to return this modified function that we have. To do so, we would need to say at the end, return wrapper Okay, so we've got that all defined now. So what we're going to do now is run the code. And as we can see now, we have that output, and it says ABC 66507. So if we can count this, we have four, and we have four. So this is, of course, eight characters long. So our password is now a little bit safer. It's not perfectly safe, but it's a lot better than it was before. And as you can see there, we added in the functionality to modify our function so that we can ensure that our passwords are at least eight characters long and they are working nicely as they should be. We can see we incorporated all of that in this function. So if I were to just zoom out a bit more so that you can see the overall result that we have right here and the output that we have. All right. That is it for the exercises on decorators. Hopefully you're becoming a bit more confident with it and that you are integrating it well. We've gone through a few examples. We can go ahead and remove this and there we have it decorators in Bison. 31. File I/O: Hi, everyone, and welcome to the next lesson, which is going to be focused on file IO. So let's get started. So you're probably wondering what does the IO stand for in file IO? So IO simply stands for input and output. Hence the IO part. So file IO refers to the process of reading from and writing to files. And it enables your program to work as files on your computer, and this allows us to open write to read, and then to close these files as needed. A so in simple terms, it lets you work with files like reading texts from a file or saving data to one. Okay, so I'm going to show you a few code snippets of some of the most popular actions with file management in PySon. So let's say we want to open a file. So let's say we have a file called person dot TXT. So what we can do is we can define a variable, for example, call person file, and then we're going to say equals, and we're going to open the person dot TXT file, and we're going to associate it with the variable name of person file. Then let's say we have opened that file and now we want to read from that file. So what we can do is define another variable called text, and then we want to associate that with person file, which of course is how can I say it has access to the person dot txt file since we opened it previously in the open file command. What we're going to be doing now is we're going to use the Red method to read the first hundred characters of the person dot TXT file, and we're going to output those first hundred characters in the output window by saying print text. Now, don't worry if this doesn't make sense of yet, we are going to practice it, but I just want to give you an overview so you can have a better understanding of the methods used and such. Okay, now, let's say we want to create our own file. So the process to do so would be to, of course, define an A variable, so we can say car file equals open, and then you want to specify car dot TXT, and then you want to specify another value which is W. So that is going to mean write. And this can also be interpreted as a form of creating. So write a file, create a file, and that must be car dot TXT. Now let's say we've gone ahead and created this file, and now we want to actually write to the file. So then we would make use of the write method. So we would refer to that variable that we defined earlier for creating the file, car file. Then we'll say don't write, and there we can say, for example, my favorite cars are a Ford and a hessla and that's going to be written to the file. And a very important thing to keep in mind is whenever you're writing to a file in PySon, you always need to make sure that after you've written to a file that you close it. Okay? So you need to say car file dot close at the end, at least in this example. So dot close is the method that you need. Now, there is something in PySon known as context managers where this is automatically done for you, but that is a topic that we'll cover later on in the course. But for now, we need to manually say dot close. Now, let's say we want to add to that file. We cannot say write again because that's going to override whatever was in the file. We want to add to the file, and that is going to be the next issue we need to solve and to solve it, we can solve it by appending to a file. We're going to essentially open the file, as you can see here, we define our variable. We're going to utilize the open function. Then we're going to open set file, which is going to be cart txt is the first, you could say parameter and then comma and then A. That's going to stand for append. We're going to append to that file. We're opening Set file so that we can append to it so we can add to it. Then you can go on ahead and say carfle dot right. Then as you can see, I add a space and say, I also like Honda. That's going to be added to that particular file with the code that I showed you earlier on, where we route to the file. A oids when we are writing or when we are appending or any sort of action, we need to say car file close at the end. So remember, emphasis on the dot close method. Now, let's say we have a surplus amount of files and we need to start deleting them. Now, to do so, what you can do is make use of the OS module that comes with Python. And the OS module has a function known as remove, and all you need to do is place in the file that you want to delete. So in this case, we can, for example, delete the card dot TXT file by just inserting that within quotes within the remove function. So it's as simple as that, that's how you can delete a file as well. All right guys. That is it in terms of the theoretical overview of looking at file input and output in PySon. In the next lesson, we're going to focus on the practical lab exercise, and we're going to work on practicing working with files in PySon. All right guys. That is it for the theoretical overview. 32. Performing file operations - [Lab]: Everyone, and welcome to the next practical lab exercise, which is going to be focused on file IO and PySon. Let's get started. Now, the first thing that I want you to do is to navigate to explore here. In our directory, we want to create a simple person dot TXT file. I'm going to navigate here and say new file, I'm going to call this person dot TXT. Here is my TXT file. What I can do is I can actually add in some data. I'm going to go ahead and just say, John, Smith, and I'm going to put in a date of birth, for example, say 12 oh 2-1990. Two. Just a little bit of information there. There's some data at least in person dot TXT. Let's go to main dot pie now and what we are going to want to do is we're going to want to open person dot TXT. We can say person file, that will be a variable, for example, and we're going to make use of the open function to open that file. So the name of that file is person dot TXT. So I'm going to say person dot TXT, and that will open the file for us. So now that the file is opened, theoretically speaking, we need to perform some action. Let's say we want to read from this file. We can then define a variable called text, and we want to refer to person file because according to this variable, the value here is going to be the open file. And what do we want to do with this file now that it's open? We want to read from it, so we can use the read method and then you want to specify how many characters of the file you want to read. I always like to do it a little bit high, so I'm going to say 100 and that's going to be basically everything in this file so you can see it's just about going to take everything up. And then since what has been read in characters is associated now with ext and stored in it, we can print text to see the output. So I'm going to say print text. So now if I run the code, it's going to output the first 100 characters from this file. Now, let's say I change the arc account here to only let's say five characters and I run this. I'm only going to print out John. Of course, we can see there's a space there when I highlight. If I were to say 12, for example, and run, it's going to say John Smith's dash. It only gets to this point. You can see you can limit the amount of characters that you want to read from your program itself. Okay, perfect. That is how we can go on ahead and sech that up. So that's the basic way of opening a file that already exists and how you can read from a file itself. So we've mastered opening a existing file and reading from it. Now, let's say we want to take it a step further and we want to create a file and write to it. What I'm going to do now is we can remove this code, and I want to create a file. To do so, I'm going to say car file as my variable equals, and I'm going to say open I'm going to say car dot TXT and then in the comma and I'm going to say W. Because I want to create a file, I'm going to say W. Now, before this file actually exists and gets created, we actually need to write to it, so we need to write something, but this is the first step to creating your file, theoretically speaking. Next thing we need to do is actually write to this file, and then it's going to be created and it will appear here in our directory here in our base directory. What you're going to want to do is say car file, dog right here in pareneses we can say my favorite cars are a forge and a chess. Then we want to say car file, close, and that's going to close the file for us. Now if we were to run our code, We can see nothing's going to be output, but if we go to our directory, you should now see that we have a cart TXT file that was created and we have some text in it because we wrote to the file. We can see there that we went ahead and wrote my favorite cards are a Ford and a Tesla and we can see that's been written, and of course, that file was created itself. We didn't expect any print output statement. That's why nothing was here, but we needed to run our code so we can execute the following lines of code. But we can see it's been created. Cart TXT does exist now. Right, perfect. Now, let's say that you want to go on ahead and read now from car dot TXT. You want to read a little bit from this file. So we're going to refer back to what we did earlier on. So let me go on ahead and just this. So we want to go back to read a file. So I'm going to say text equals, and I'm going to say car file dot Red. And I'm going to read a little bit from that file. So I'll say 15 characters. And I'll say print checks. So now, if I run the output, it is going to give me some code here so you can see that the IO operation was on a closed file. So remember, whenever you are closing a file, you need to reopen it again. So this is something very important to keep in mind when you're working with your files. So what you need to do now is you need to open it before you continue. So you can define your variable here again, car file. Equals open, and you want to open car dot TXT, and now you re opening it. And now if you run your code, you're going to see it says my favorite CA. Okay? Because we're only limiting it by 15 characters, but if I make it a little bit longer to 100, for example, it's going to print the whole line saying, My favorite cars are Ford and a test remember that. Very important. That's why context managers will be how can I say a lot a lot more helpful later on. So that's just something I wanted to mention so that you're aware of that entire process. So remember, once you close, you cannot perform an action until you open it again. Very important. I wanted to demonstrate that so that you can see what will happen if you don't do that. You're going to run into an error like I mentioned. Once you close, you need to open again. Right. The next thing I want to show you is how you can append to a file. Now, let's say we already have the text in car dot TXT. My favorite cars are Ford and Chess and we want to add to this file. We can use append. What you're going to want to do is just restructure your code here a bit, so we can just remove some of the old code here. And of course, we need to open the file, but we need to open it in appendamde. To do so, we need to add a comma here and say, A, because we are telling Pyson that we want to open this file and we want to append to it. Now, to append to it, of course, we need to make use of the right method again, but our focus is on appending and not writing it out. If I say car file, write, Okay. In quotes, I need to add a space and say, I also like Honda, for example. Then I can just say car file dot close. So whenever you're writing, you need to close. So that's a good measure. So now if I go ahead and run this code, of course, nothing's going to output there. But if I go to car dox, you'll see that it appended this additional texture that says, I also like Honda. So that's how you can append to a file that you have already. Okay, perfect. That is how you can go ahead and set that up accordingly. Now, you cannot go ahead and just say write to a file or else it's going to remove everything that's in your file and start from the beginning. Let me demonstrate. If I were to just replace this with W and say, I'm just going to write to the file. Say, I also like Honda, it's going to replace all of this and just show I also like Honda. Because when you're writing, it's going to be a clean break. A pen is going to add to a file. We, it's going to start from scratch. So let me show you. If I run this now and go to Cardo txty, it's just going to show I also like Honda. That's why you need to make sure you have at the A symbol, which is set when you're opening your file to specify the mode that you intend to utilize. So these are known as mode. O W is writing mode. A is appenda mode, remember that. We have two files here, but I only want to keep one. I want to keep person dot TXT, so I can remove car dot TXT. You're probably wondering, how do I do that? Very simple. You just need to say import OS and the OS module has a remove function and this applies to files. You can say Os dot remove and then all you need to do is put in the exact file name, and in our case, it's car dot TXT, which we can see here. You can say car dot TXT. And I'll recommend just closing this file for now. And if you run that code, you can go to your explorer and you can see that card dot txt has in fact been deleted. It doesn't exist anymore. Wretch. So there we have it. That is how you can go on a hedge and perform basic file IO, in other words, file input and output. So you've learned now how you can go ahead and open files, read files, create files, write to files, append to a file, and delete a file. We are going to go into a little bit more detail soon enough in terms of obtaining file metadata. So that is something that we will get to soon enough. Right. Now, in terms of this person dot TXT file, usually we clean everything up after each practical next size, but we're going to follow up in this case, for the first time. So I'd recommend just keeping everything as is. We're going to have a few theoretical overviews in the next set of lessons, and then we're going to return back to explore a little bit deeper into file handling. All right, so that's it for now. 33. Obtaining file meta data: Hi, everyone, and welcome to the next lesson, which is going to be focused on obtaining file meta data. So let's take a look. Okay. Now, when we are performing file input and output operations as we have been doing so already in this course, we may also need to know more detail about the processing and finer details of a file, otherwise known as the metadata. Now, this metadata can include the name of the file, the state of a file, whether it's open or closed, and the mode in which the file is open. If it is currently in write mode, if it's in a pen mode, so A for a pen mode, W for write mode, it is some information that we may need to know, not necessarily, but just something that might be important. So, in any case, that's just a bit of a theoretical overview. We are going to dive into some of the options that we can dive into to obtain this information. So we'll dive right into that in just a moment. 34. Attributes to output file meta data - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on obtaining file meta data. Now, we are carrying on from where we left off, so we still have our person dot TXT file that we had before and we have our main dot pi file. What I want us to do is to go ahead and open our file in mode, for example. I'm going to say person, file equals open, and I'm going to open up person dot TXT. And we're going to set this for now in write mode, so the mode will be W. Great. Let's grab some information and I'm going to output this as well. I'm going to say print and I'm going to add in some textures, I'm going to say name. What I want to do is I want to get the name of my file. To do so, I can just say person file. Since we have assigned that variable to the value here of the file contents, I can then say dot name. Now, dot name here is going to be an attribute that we are utilizing. Okay. The next thing that I want to do is I want to check if the file is in the opening or closing state, and this will return a Bool value or Boolean value. So I'm going to say print, and I'm going to check if it's closed. I'm going to say is closed. Okay, so at the comma. Again, we need to reference the file, so I'll say person file dot, and the attribute for this would be closed. So we're going to check if it's closed. And if it's closed, if the file is closed here, it's going to return true. If it's not closed, it will return false. So we're checking if it is closed, which it isn't. It is open. Next thing we want to do is we want to check the mode. So I'm going to say print, and here, I'm going to say current mode. Space, and we need to refer to the file, person file dot, and we're going to say mode. So let's go ahead and predict what we'll have. The name of the file here, we're referring to the attribute of the file, which is going to be person dot TXT. And we're going to check if it's closed. We can see the last thing we did was open it. By saying it's closed, is going to result in false, so it's not going to be true. Then we have person file dot mode here. The current mode is W for right. Let's go ahead and run this code here we can see the name is person not TXT. These closed status, we can see it's false and the current mode is W. But let's go ahead and change this. Let's set the mode to A. All right. And what we want to do now is we want to go ahead and close the file. So I'm going to say person file dot, close. So let's run the code. And we can see the name here is person Dtxty is closed, is true because I went ahead and closed the file by utilizing the close message. And the current mode is A for append and the name, of course, has still stayed the same. So this is very useful if you want to obtain some metadata from your files. So it is still quite on the surface level, but that's how you can go ahead and reference according to various attributes that are available to you to just get some metadata on your files. So that's it for this lab exercise, very simple and to the point. Let's go ahead and just delete that file so I can right click. And delete. There we go. Make sure you still have your main dot pi file intact and that's all that we need for now. That's it for this exercise. 35. Parameters and arguments: Hi, everyone, and welcome to the next lesson, which is going to be focused on parameters and arguments. So let's go ahead and get started. Right, so parameters and arguments. Now, a parameter can be seen as a placeholder that's going to define what inputs a function expects. Now, on the other hand, arguments are the actual values that you pass into a function when calling it. So let's go ahead and take a look at a simple analogy so that we can differentiate between a parameter and an argument more coherently. Right, so let's take a look. Now, let's say that you are at a restaurant and the waiter or server comes to you and asks you a few questions as to what you would like to have at the restaurant. So he may ask you a few questions like, what would you like for your starter. Then he may ask, what would you like for your main course and if you would like any kind of dessert after your main course. So let's say, for example, you're quite hungry and you tell the server or waiter, yes, I would like for my starter to be composed of some garlic bread. For my main course, I want a pizza, and for dessert, I would like to have some ice cream. Let's go ahead and dive deeper. Now, in this particular example, with looking at parameters and arguments, you could treat the parameters as in this case, the blanks on an order form, I E, the starter, the main course, the dessert. So in this case, they define what can be ordered but don't have specific values yet. On the other hand, with our arguments, these are the actual choices that a customer makes. In other words, garlic bread, pizza, ice cream, and these fill in the blanks when placing the order. This is how you can differentiate between your parameters and your arguments. Right? So let's apply this in a simple Python program, for example. So using the exact same example here, for example, as you can see, we have a function and our parameters that are placed within this function in between the parenss include starter, main course, and dessert. And this is going to define what inputs the function expects. So these are the parameters. Then as you can see, we have a print statement here which is going to say ordered, and it's then going to take in the values that will be tied to the starter parameter, the main course parameter, and the desert parameter. That's going to output a specific result. Now, to call this function, what we're going to do is refer to the function name which is place order. Then within parentheses, what we're going to be doing is calling the function with argument. These are the values that's essentially going to be tied in with the parameters that we have. Here you can see we have garlic bread, we have pizza, and we have ice cream. Essentially, what's going to happen now is we are going to input values, these argument values, where our parameters are. Garlic bread is going to be in place of starter. Pizza will be in place of main course and our dessert, in that case, we're going to have ice cream in line with dessert. Then, of course, since we are calling the function, it's then going to run whatever we've defined in the function. In this case, the print statement is going to up at the end, you ordered garlic bread. Pizza and ice cream for dessert. That is how we can rationalize via an analogy, how we can make use of parameters and arguments with our functions in pyson. Now, we are going to go very deep into this with how you can utilize functions and how you can more specifically utilize arguments parameter should I say, was in PySon. But anyway, that is the gist of it so that you have the general idea between what's the difference between a parameter and argument and in a context. 36. Differentiating between parameters and arguments - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on parameters and arguments. So in this lab exercise, I'm just going to teach you the fundamentals of parameters and arguments so that you can at least understand the general idea of it before we delve deeper into parameters and arguments in the next set of lessons. So let's get started. Okay, so let's say, for example, I want to create a simple function, which is going to be focused on someone ordering a particular set of foods from a restaurant. So let's say they want to have some lunch and they decide I want a starter, a main course, and a dessert. Let's go ahead and see where we can take it from there. So the first thing that we would typically do is define our function. So I'm going to say Dev and I'm going to say place underscore order, and that's going to be my function name. And within my function within the parenessT be more specific, I need to define my parameters. In this case here, since we are having a starter, a main course and dessert, this would be appropriate for the parameters. That's going to define the inputs that our function will expect. So let's go ahead and do just that. We'll have starter. We will have main underscore course, and we're going to have dessert. Right. Now, once we have the associated values plugged into starter main course and dessert, we want to output some sort of functionality. So in this case, here, I just want to print the order itself. So here I'm going to say print, and I'm going to say ordered space, and I'm going to use string concatenations, I'll say plus, and I'm going to add in the starter. Then I'm going to add in a comma and a space, and then we will add in the main course, right? And what I'm going to do is just zoom out a bit here of clarity plus and then add in my comma and say and space, and then I'll have a dessert. Very simple. I was just going to say ordered, is going to say the dessert, the main course, and of course, what we have accordingly here. Great. Now, outside of that function, we of course, want to call it and execute that line of code. So what we're going to want to do is call that function, and to do so, you would refer to the function name itself, which is place order. And here was in parentheses is where you will call the function by plugging in the arguments. Essentially, the arguments here are going to be substituted where you've defined your parameters. Let me go ahead and give you an example. Now if I put in garlic bredge, then I put in pizza. And I put in ice cream. These are going to be my arguments and it's going to be plugged in accordingly. Garlic bread will be in place of starter, pizza will be in place of main course. Ice cream will be in place of dessert. Then you could see it as the following will then have the values of garlic bread, pizza, and ice cream, that's going to be brought down to whatever is within the function here. Starter will then become garlic bread, main course will become pizza and ice cream will become dessert. Those values will pass down into our function. And the end result is going to be you ordered, garlic bread, pizza, and ice cream. Okay, so let's go ahead and run this code. Okay. And there you can see the output. So you ordered garlic bread, pizza, and ice cream. All right, so that is a simple way in which you can practically see the difference between parameters and arguments and how they work together. All right. So there we have it. Now, let's say we want to go a little bit more in GitL. So the best way is to get some more practice, and let's look at another example. So let me zoom in. And let's go ahead and work on a second example. All right, so let's go ahead and work with our second example. So again, I'm going to define a function, and this is going to be called death and I'm going to say location. Very simple. Then I'm going to place in two parameters. So namely, I'll have city, and then I'll have country as my parameters. And here in my print statement, I'm going to say print. I'm going to say you are from add in the colon space, add in, of course, a plus for string concatenation, I'll say city plus and then I'm going to go ahead and add in a set of quotes and then I'll add in a colon here, and then I add the space and then string concatenation for the country. Now I would need to call the function, so I would say location. And with inferences, I will add in the arguments. Here I'm going to say, the first parameter would be in the first sort of how can I say in the first definition that we make here. I'm going to say Capetown, and in my comma then the second argument is going to pertain to the country and be binded to and I'll say South Africa. Now I can go ahead and run this code. As you can see, it says now you are from Capetown, South Africa. What I can do actually is just move. Okay, there we go. That looks a little bit cleaner. Oh you could also do is maybe a comma might look nicer. So I'm just on the little deles here. So, excuse me. You're from kitchen. There we go. A lot cleaner. All right. So that is how we can integrate parameters and arguments very simple. So again, I will reiterate what we define here within our parentheses. Okay? That is going to be our parameters. Then our parameters, we can also call them within the function itself. However, what we would then need to do is add in the arguments here that are going to you could say substitute our parameters within our functions penses, which are then going to be passed down to any logic that we have within the designated function. Right, guys, that is it for this practical lab exercise on parameters and arguments. 37. Positional and keyword arguments: Hi, everyone, and welcome to the next lesson, which is going to be focused on positional and keyword arguments. So let's take a look. Okay, so let's differentiate between the two. Positional arguments are passed in a specific order with their position determining which parameter they are assigned to. Now, if you were to change the order, that's going to change the meaning. Now, we also get keyword arguments, and keyword arguments use names to assign values, so the order doesn't matter. So let's go ahead and take a look at another analogy as an example, and then I'm going to show you how you can apply both positional and keyword arguments. So let's take a look. All right. So let's say that we want to buy a car, and we're going to a car dealership, and let's say we want to buy, I don't know, a Ford, a Tesla, or a Mercedes. So we go to the car dealership and we meet with a car dealer there and we're inquiring about buying a new car. Now, after we've met the persons, of course, going to ask us a few questions. He's going to ask us what brand would you like? What model would you also like and what color? We say, I would like a Mercedes. I want to buy the S class and it needs to be black. Let's see how we would apply this in a PySon program in a very simple way. So with applying that particular scenario, we can create a program as following by utilizing positional argument. So as you can see here, we're defining our function that is by car. We have the parameters, brand, model, and color. And then our print statement here to execute the function is going to say you bought A and then we'll add in sage values associated with it. Now, as we can see here, positional arguments, what I mentioned before, the order matters. So as we can see here, we have Mercedes, we have S class, and we have black. Now, Mercedes is going to be substituted into brand, S class, into model and black into color. So at the end, it's going to say you bought and it's going to say you bought a black Mercedes S class. Okay, so that is how this is going to work in the process. So you can see here positional arguments, the order matters because if you were to change the Mercedes here with S class, and replace the two, you're then going to get the brand as S class, and you're going to get, for example, how can I say the model as Mercedes? There can be some confusion. So positional arguments, the position matters. So Mercedes, of course, goes to brand, S class to model, and black to color. Okay. What you define here was string concatenation, that's entirely different. That's a different sort of use case. So that doesn't really matter. But positional arguments, what values you put on here matters because it's going to match the order that you define your parameters. Okay. So let me show you another example to solidify this knowledge. If we were to change this up, use the same scenario and use keyword arguments, you're going to notice here that we have a bit of a difference. The model is set to S class, brand is set to Mercedes and color is set to black. Now, in this case, you can now see that I changed the parameter order, it says brand, model, and color. Here with the arguments you can see, the order doesn't matter because what I'm doing here, I'm explicitly defining the keyword argument by saying, Okay, the model is going to be an S class, the brand is going to be Mercedes and the color is going to be black. It's automatically going to assume the parameters. How can I say in a very sort of gradual and dynamic way? Brand is automatically going to know that this is a Mercedes. Color is automatically going to be set to black and model is automatically going to be set to S class. You can see here, technically the order is different in a way, but it doesn't matter because we are explicitly assigning the parameters as we can see here according to the labels. So this would be seen as keyword arguments where the order doesn't matter. Unlike before, if we go back, we had positional arguments where what values you could say hard code or the order in the pattern matters. So remember, we have positional arguments and we have keyword arguments. Okay. So that's just something that I wanted to mention and go over with you in terms of a theoretical overview. We are going to practice this in the practical lab exercises, so stay tuned for that. 38. Map positional & keyword arguments - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on differentiating between positional and keyword arguments from a practical perspective. Now, in the previous lab exercise, we focused on understanding the core concept of parameters and arguments. Now indirectly, you'll have noticed that we utilize positional arguments if you can get your head around the previous lesson which was on gaining a seriatal overview over positional and keyword arguments. So with positional arguments, you plug in the arguments directly when you are calling S function. All right. So the first part in this exercise is going to kind of be like a revision activity because you are going to understand the default way in which we handled positional arguments earlier on. Anyway, let's go ahead and get started. I'm going to create a function and I want to say deaf person underscore info. My function name is going to be person info. Then I want to pass through a few parameters. I'll have let's say name, I'll have city, and I'm going to have country. Those will be my parameters. Then I want to set out a print statement and I'm going to say print, and I'm going to start off by saying, I'm and I'll say, I'll say IM and then I'll use string concatenation and say name plus. Then, of course, in quotes, I'm going to add a space and say, so you'll say IM and for example, nor and I'm from. And then what I can do is go ahead and say plus, and then we can say Siti plus, and then we can go ahdge and add in a comma and say country. There we go. So that's going to be the statement. Now, we would need to pass through some arguments. But first of all, we need to call our function, the first thing we would need to do is say person underscore info, and that is, of course, the function that we've defined here, the function name, and then we can pass through our arguments. Okay, so first, I'll have the name, so it's going to be honor, city I can say Capetown, and then country, I'm going to say South Africa. These are seen as my positional arguments. Name city and country, as we know, are our parameters. Now, with positional arguments, the position of your arguments needs to match the order or position of your parameters. In other words, name is going to, of course, be substituted in place of honor. Nor is going to be name, Capetown will be city. South Africa will be country, and then it will be utilized as the program is in terms of the functionality here where it's going to take in the values that are passed to it. Now, the important thing that I want you to see in this whole sort of structures positional arguments is that if you define your positional arguments here and you kind hard code them, so they're going to be binded to your parameters. So see it this way. Argument one belongs to parameter one. Argument two, parameter two, argument three, parameter three. So let me go on ahead now and run this function. I'll call this function. It's going to say, I'm Ono, I'm from Cape Town South Africa. As you can see, it's going to output the following what I'm going to do actually is go on a hedge and just put a full stop and we can put a full stop there space from Capetown there we go. Just the punctuation change there. All right, there we go. Now let me, for example, change something. If I were to switch the first value here was Cape Town and the second value. So my second argument, should I say no, and I run this. It's going to say I'm Capetown, I'm from Anno So Africa. So you can see the issue here. So this is why positional arguments matter, Okay, because you can see, of course, Capetown is the first argument, and it's now belonging and attached to the first parameter which is name. Arno, which is the second positional argument belongs to city now, and of course, so Africa and country are still the same. But in our print statement, you can see here the difference that it's now saying I am Cape toown I'm from Arno because Arno is technically binded to city. You can see the issue here and why it's important that when you are defining your positional arguments that the order matters. The order of your arguments need to match the order of your parameters in your function. That is a deeper dive into positional arguments. Now I want to move it back. And we can do that. There we go. I'm Ano. I'm from Capetown, South Africa. Perfect. Positional arguments. Now, let's say we want to make use of keyword argument. Unlike positional arguments where order matters, keyword arguments do not. What you would essentially do here is when you are defining your arguments, you can assign it to your parameters here directly. So we have name, city, and country, but we can assign it here directly. And in that case, the order is not going to matter. So no matter if I were to go on ahead and switch the first argument here with, for example, Cape Down, second Anno, and leave the *** of Africa, it's not going to matter because you're going to assign the parameters here beforehand. So the order here is not going to be of any consequence. Let me show you what I mean by that. If I were to just zoom out for now and let me set it up as follows. Anno is, of course, going to be name. I can say name equals, and then Arno. Then of course, we're going to have Cape Town. We need to say city equals Cape Town and South Africa. We can say country equals South Africa. Okay. Now, if I were to run this code now and run, as we can see here, it's going to say, I'm no, I'm from Cape Town South Africa. It works exactly as it should be. This is how you can switch it with keyword arguments, but we're not actually seeing the difference here as the order, it doesn't matter because technically, one could argue that Ono is here and that's the name, Capetown is the second argument, and so Africa third and it's separated by the commerce. That's what one could argue. But let me show you something. Let me switch now city in the first place of the argument. Let me do that. Okay, let me remove that and just switch it around. Now, technically speaking, you would think, Cape Town is in the first place that should be name. The second here is no and that should be on setting. Technically, in order was the positions. But this case, it's still going to work as it should. If I run the code, it's still going to say, I'm Arno. I'm from Capetown South Africa. Even though technically we have switched order around, you can see the order does not matter at all. So we are defining the parameter values itself. Instead of substituting directly into the parameters defined within the function, we are stating the value ahead of time. So the parameter will automatically look for what has been defined right here in this argument in this argument call that we are setting. So that's how we can go on ahead and define your keyword arguments. So the order is not going to matter. Okay. Now, I did not mention it in strict detail in the theoretical lectures, so you're probably wondering, Okay, we have country equals, name equals and city equals. So what do we call this in how do we call this in Payson? Because we know South Africa, Arno, and Cape Town is essentially the argument, but what do we call the rest? Now, there isn't an actual term in pyson for these forms of declarations. Okay, so there isn't an actual name for it. But the closest name that would be the most accurate would be keyed to your parameter names. So we have city equals, name equals, country equals. So you can call these parameter names, okay, which is essentially what you have here parameter names. So that's kind of how you can really call it directly. You can also refer to it as parameter labels. That's another term that I've also heard before. So it's really kind of up to us how you want to rephrase it. But parameter names is quite clean here. And all you can really see here is you're strictly associating your parameter with your arguments. That's how you can look at it as to what you're doing here with keyword arguments. Okay. So yes, that is how we can utilize positional and keyword arguments. Okay. So what I'm going to do is also switch this around. I'm going to move country here and I'm going to move that to the front now just to show you the difference here. So if I run the code, still going to run the same. But now, let me go ahead and change this, and we're not going to set this up as keyword arguments anymore. Okay? We're now going to set it as positional arguments. So remember the format in this format here, these are seen as keyword arguments. If we were to just add in the values as is, this would be seen as positional arguments. So remember the structure between the two. So now if I run my code here, it's going to go all crazy here because South Africa is named, Cape town is city, and nu is the country. Okay, so positional and keyword arguments. Now, what I want us to do is to go ahead and work on another example just to practice so that we can get a better idea of positional and keyword arguments. Alright, so let's continue and get some more practice in. Okay. So let's start off with the function that's going to focus on positional arguments and then we'll work on keyword arguments. Okay. So I'm going to say Def, and this is going to be a function that is called watch underscore movie. Very simple. It's going to take in two parameters. We'll first have the movie name. So I'm going to say movie, and then I'm going to say the person. So who am I watching the movie with in my colon, and then I'm going to say Print. I went to watch and then space, and I'm going to add the plus, and then I'm going to have the movie, space, and then I'm going to say whiz and plus and then we'll have person. Okay. So there we have it, so I'll have wits like that. I might adjust it. I went to watch you can say, for example, Star Wars with Jane. Just very simple. Then going to call this function, and I'm going to say watch underscore movie, and positional arguments. First, I'm going to have the movie name. So here I'm going to say Star Wars. Second argument, I'm going to say Jane. Very simple. So it should go on ahead and pass stars into movie, Jane into person. So it's going to printer. I went to watch Star Wars with Jane. So let's go ahead and run this code. Sometimes we just need to re run it. There we go. I went to watch Star Wars with Jane. And that's going to output it for you accordingly, like so. Okay, so that's positional arguments. Now, let's say I were to change the position, say Jane, Star Balls, and I accidentally make a mistake and I run that program. I go to say, I went to watch Jane with Stars. That makes no sense. So how can keyword argument solve this problem for us? Now, if we code it this way, we don't need to change it. We can just use a keyword argument. So refer to the parameter name. So explicitly say, Okay, person is Jane. And movie equals Star Wars. Now, this way, if I run the code, Let me save if I run it, I went towards Starwars with Jane. That way, it's going to help you to solve any sort of issue that you may have with positional argument, and you can just adjust without having to make a breaking change here. So that adjustment is going to be made. So now we've replaced it with key word arguments. Now, even though previously I mentioned that these we can refer to as our parameter names, another reason which I also want to add into this process here being known as keyword arguments is that you can also treat these parameter names here that's being declared as keywords. So that is also why in Python, they call it keyword arguments. So just remember that the reason I don't want to focus too much on calling these keywords is because they are essentially our parameters here. Okay, so I just want you to keep a good sort of an open mind and perspective on the logic and the formatting here. So the best way to really solidify your knowledge here is to look at the format. If you are defining your parameter names and saying equals to an argument, that means that this is seen as keyword arguments. If you directly add in arguments so you hard code values, that is going to be positional arguments. Alright, guys. So I know that was a little bit in detail, but I just wanted to go a little bit deeper into it so that you understand the process. Now, I am going to do a bonus lab exercise, but she's going to be focused on mixing argument types. So that's going to be purely practical. We're not going to look at the theoretical side because we've covered that technically. So I feel it's best for you to learn visually on mixing argument types. So that's going to be an optional upcoming exercise which we're going to do. So I'm not going to remove the code or anything just yet. It's too be continued. But if you want to go ahead and skip ahead to the next official lesson, which is going to be on default arguments, you can do so. So it's just something I wanted to mention so that you're aware of it. So for those that want to learn more on mixing argument types, it's going to be a sole lesson, but it's not going to be as formal. You can just keep on with me as is. If not, you can just delete the code that you have and then skip on to the next official lesson. 39. Mixing argument types - [Optional lab]: Hi, everyone. Welcome to the next practical lab exercise, which is going to be an optional bonus lesson you could see has, and we are essentially going to be learning how to mix argument types. In this example, we're going to mix our positional arguments and keyword arguments when we are calling a particular function. Where we left off was how we can map positional and keyword arguments. This time, I'm going to show you how you can mix and match both. However, there are a set of rules that you're going to need to follow and such. Okay, so let's get started with the previous example and where we last left off. As you can see here, I have this function that says, I went to watch, and then it's going to say the movie and the person. Now if I run this cody it's going to say I went towards stars with Jane. Now, the positions here. So as we can see, we have Jane and Starwars, and the parameter is expecting person, first movie, and then person. The reason that this code works is because we're using keyword arguments and we are explicitly stating the parameter name and assigning the associated value. This is the use of keyword arguments in the format of things. Now, if I were to remove these keyword arguments and replace it with the raw positional arguments, in other words, if I were to say stones and let's say Jane, and run the code. I went to watch Jane with Sows, which makes no sense because now the default positional arguments functionality is in place. So Jane goes to movie and Stows goes to person. Okay, so that was the reason why we went ahead and used our keyword arguments to change it up and to go ahead and sent person Okay, as Jane and then movie as Star Wars. And then when we run this, it's going to fix it for us because the keyword arguments adjust and assigns the value here directly for us, so it's going to adjust nicely and look for the parameter name where it has been defined argument in this function call, where we specify the arguments. Now, we can also mix argument times, which is not something I'd recommend you do. I'd recommend you either stick to positional arguments or keyword arguments as they are. But it's good to have a greater sense of additional functionality as well. Okay. Now there are rules unfortunately to this. Now, the idea of the whole positional argument and the keyword arguments is that you can only do it in certain ways. If for example, here I were to change one of the options here, one of these keyword arguments to positional, it's going to work in some cases, in some cases, it's not going to. As we know now, person is linked to the second parameter here and movie is linked to the first parameter. If I were to remove the keyword argument. In the second in the second, how can I say state in the second set? You can see there will be an error that says positional argument cannot appear after keyword argument. So now we have this keyword argument here, and we have this positional argument, so you can never have a positional argument after a keyword argument. You're always going to have to at least have your positional arguments first, and then later on you can have your keyword arguments. Okay. Now, another thing I want to mention is if you did it the other way around and let's say I switched this out for, of course, it was movie, equals teles, that's fine. Now let me do what it said before. Now I'm going to have Jane, for example, that's my positional argument, and then I have my keyword argument. Now, technically speaking, you would say, this works perfectly fine. That is what one would assume. But if we go ahead and save and run this code, we're going to get an error saying that Watch movie got multiple values for argument movie. That's the issue we're having. Now, here is the reason for that. Here we have Jane and Jane is following, of course, the rule of positional argument, that's going to be assigned to movie, but we also have movie here. We need to assign something to person. That's where the whole trick in this area starts. Okay. So for you to effectively mix these argument times, you need to do some maneuvering here. So the first rule which I mentioned is your positional arguments, okay, must always be first, and then you can use a keyword argument. And secondly, you need to watch what you were assigning here. What we're going to have to do in this situation is change what we had before and make it make sense. So here we would need to say Star Wars, so it satisfies the movie first. And then here, we're going to want to change it to the person's name. And we need to set this to person so that it is adjusted here accordingly. So now if I were to save this and run my code, it says, I went towards stalls with J. Okay? Now, this is how you would integrate both of your argument types. So stalls goes to movie and person goes to J. And that's how that process would work. Okay? Now, something I do want to mention here in the result here is you're going to have to always follow your arguments in this sort of fashion if you want to integrate both of them. So let's go ahead and work on another example completely different. Let me go ahead and remove this code. Right. So let's go ahead and continue with the next example. Okay, so let's say I define a function that is called sequence. I say De sequence. I have A, B, and C. I can then just print the associated values in the print statement and say, A, B, C, Then I want to call the function sequence, so I can say sequence. Then I can pass through some valley. Let's do a simple check here. I want to say one, two, three. Here I'm using positional arguments. Let me save and run that code. Outputs one, two, and three. Now, let me go on ahead and switch this for keyword arguments now. I'm going to just switch the positions. I'm going to go ahead and say, let's say, A equals two, C equals three, and B equals one. Save Zach, runach I get two, one, three because we can see that A is, of course, going to be two. B is going to be one and C equals three, and the order here is A, B, and C, it's going to be two, as you can see, one and three. There we have the keyword arguments. Let's go ahead and set this back to position one, two, three. Let's see how we can mix these argument times. With the rules that I mentioned before, remember, you cannot have a keyword argument in front of a positional one. If I set this to A equals one, we're going to see two and three will have an issue because positional arguments cannot appear after keyword arguments. Remember that you cannot have these keyword arguments first, always position, always positional. So we need to have one as the positional argument. Then what we can do is we can technically set B equals to two, but then we have to make C equals to three, because we cannot have the positional argument on its own. So if I were to run this, it's going to run the same thing and that's one way in which we can mix our argument times. But you'll notice here that by doing this is a bit, how can I say unnecessary? Because you're adding extra code for something you can achieve with positional arguments. Because technically, one, two, and three already matched the order. If you just remove them, you would have had the result you wanted. You're just adding in extra code here where it's not really helping you out. So if you put B and C, it's just extra code, and it's technically in the same order. The only usefulness in the keyword argument phase is if you want to switch them around. So you can technically go ahead and switch the value. We know C equals three and B equals two. What you can technically do is just switch the order around. Just like that. Then if you run it, of course, you're going to get one, two, and three again. So you're still following the same rules that were mentioned. Okay? Right, guys. So that is it on this extra practical lab exercise on how you can go ahead and mix your argument types together. Right, guys. So that's it. 40. Default arguments: Hi, everyone, and welcome to the next lesson, which is going to be focused on default argument. So let's take a look. All right, so you're probably wondering, Okay, what on earth is a default argument? So a default argument is a parameter with a predefined value in a function definition that is used when no value is provided during the function call. Now, I know the sounds a little bit confusing, but don't worry. I promise you, it will make sense. Now, an important thing to know is that default arguments must be placed at the end of the parameter list, meaning you cannot have a default argument and then have your regular parameters straight afterwards. It must always be after your regular parameters. In other words, your parameter list. Now, this will make more sense when we work in the practical exercises, so don't worry about that just yet. Okay, so let's go ahead and take a look at a simple example. Again, we're going to refer to a typical example here of someone buying a car. We'll have a function here that says buy car and that's going to take in the following parameters. We have brand, we have model, and then we have a default argument, which is known as color equals black. Okay. Now, if you will have a look at the function that is being Cladie, so we're calling the function and only plugging in two arguments instead of three. So we are adding in Mercedes, which will substitute the brand parameter and S class, which will substitute the model parameter. And instead of adding in a SRD argument to reference the color directly, we are instead utilizing a default argument which we assign, which is setting the color to black. Now this result is going to output the following statement with the print statement in regard that says, You bought a Black Mercedes S class. So this is one way in which you can utilize a default argument in the sense of omitting the direct argument that you define within the function that you're calling and instead just setting it up at the parameter level you can say. So you define this as a default argument. Okay. Right. Now, something I also want to mention, it's very similar to a keyword argument. It's kind of just backwards, you could say. So instead of having it in the function call, you have it in your regular parameter list within the parentheses of your function itself. So just a quick way to kind of reference it in a way to try and have a better understanding of it. So this is called a default argument itself. Right now, another situation that I want to show you is what happens if, for example, you have your default argument like before, but you change your function call to include the argument list. So you have Mercedes, you have S class, and you have red. So now, technically speaking, you wouldn't actually have a need for this default argument, which is color equals black because you have a full set of arguments in your call function here, and you have your parameters as is. You're probably going, Okay, what's going to happen now? Is there going to be a conflict? Is there going to be an error? Well, the result is as follows, is going to output in the code, you bought a red Mercedes a class. Now, the argument that you define was in your calling function is essentially going to supersede or override the default argument that you specify along with your parameters in the parameter list. That's a very important thing to keep in mind when you're working with your default arguments that there is a preference at hand here that's going to be utilized. All right guys. Let's say on the theoretical side of default arguments, we are going to go into more detail, and there are a few more things I do want to mention in terms of the parameter less than where you can define default arguments and if there's any sort of order or preference that you need to follow. But this is the main part that I've just gone over in terms of the main core in terms of theory for the default arguments. 41. Working with default arguments - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on a default arguments. So let's get started. So let's define our functions. I'll say Df by underscore car. Then I want to pass through my parameters. So I'm going to say brand, model. And for now, I'm just going to keep it simple. I'm not going to use a default argument just yet. I'm going to say color. Then what I'm going to do is I'm going to say print, and I'm going to go ahead and say or A, and then I'm going to say plus. It's adding the color here and in the quotes plus. Then I want to add in branch plus space, and we can then add in the model at the end. There we go. Then I want to call the function. I'm going to say by underscore car, and I want to pass through the following argument. I'll have Mercedes and then I'll have S class and then I'll have black. We have that set. Let's run our code now. It says, You bought a black Mercedes S class. Mercedes went to brand, S class to model, black to color, and then we brought them over into our print statement. Okay. Perfect. So there we have a default function with the regular positional arguments and parameters. Now let's see where a default argument can become useful. So let's say you don't want to explicitly state a argument here. It was in your function that you're calling. You can just remove this. What you can then use is a default argument instead and you can just say color equals, and in quotes, you can say black. Now if you were to run your code, it's now going to say, still, you bought a black Mercedes a class. That is how you can use a default argument. You can just simply go on ahead and set up the following as you can see. All you're doing here is basically explicitly specifying your parameter here within your parameter list of this function. Now, this can be useful, for example, if you don't have a particular argument that you want to pass through your function gesto and you are okay with a default value in the meantime. Okay. Now, the helpful thing here that you want to keep in mind here is that if you then provide an argument itself within the function call, you can still keep your default argument here without any sort of conflict occurring. So if I were to explicitly put in the argument for the third parameter, which is technically color, although it's already been assigned black. If I were to run this, it's going to say red Mercedes S class. Now the reason for that is that any argument that is defined within the function qual is going to override any default argument that's defined here within this parameter list, should I say. So that's something important that you want to keep in mind when you're working with this. Now, another thing I also want to mention is the rules of placing default arguments at the end of the parameter list. So this is kind of what I mean by this. If I were to go ahead and let's say I set this to black, and I remove this default argument, I cannot at the start here, for example, of the parameter list, go ahead and say brand, and if I were to say, let's say, more SDs. So it's going to run into an issue. So you can see if I hover over the parameter here on model here, it says non default arguments, non default argument follows default argument. So what you can see here is that you have a regular parameter or non default argument that follows a default argument. So you cannot have this in the order, even though if we were to run this code, Okay, it is technically still going to show Mercedes here. And if I were to put this ford, for example, just as a simple test for the default argument, it's not going to go on a hedge and how can I say still persist to say Mercedes, even though we've defined a default argument, like I mentioned before, you cannot have this default argument in front of any other how can I say argument in place here. I will show you a way in which it will work. So it's very similar to if you watched the practical lab exercise and you follow along with mixing argument types, you can kind of have something similar here with your parameters. So I'll show you what I mean by that. If I were to just move this back to brand, we have the color and we run this. Okay? That's fine. What you can do is you can set default arguments. Okay? If you are working with how can I say anything after your initial parameter. So you must make sure that you always have your first parameter for good measure to not have a default argument. You mustn't start with a default argument when you're setting up your how can I say your parameters? Unless you are only working with one parameter. But if you're working with multiple ones, it's not going to work so well. All right. So let me show you what I mean. So we can set defaults here, so I can set the color to ridge and the model to F class. And I can remove these arguments, save the code, and I can run it. I'm going to say you bought a red Mercedes F class. So here it's using default arguments, as you can see, and it's just replacing them as you can see right there and grabbing all of the necessary values and such. Okay, so that is how we can use default arguments into place. Now, I just want to show you a few more extra things. So let's go ahead and do that. Let's say I define another function, I'm going to say death and I'll say person, and it's just going to take in one parameter which is name. I'm just going to say print name. I want to call the function and it's say no. So this is very simple for the function, let's run the code. It outputs no. Now, what I can do is I can set a default argument here to say, I'm just going to say John. And before I can actually put in my I'm going to put John Dove, actually. And let's say I don't add in a particular argument here in the call. It's going to output John Doe. So in this case, it will work to have a default argument here in place. Okay? But it cannot be the start of your parameter list. When you have other parameters, like you saw earlier, it cannot follow a situation where you're going to have a non default argument afterwards. So it will only work if you have, should I say one situation where you only have one parameter, but it's usually not the case in Python, usually it will have a majority of parameters that you work with. That's why I mentioned in this example here where you can have it permissible. Let's continue. What I'm going to do is give you another example. Let's create a simple function. I'll say deaf person underscore info, which will take in two parameters. I'm going to say name and country. I'm going to say print and I'm going to say I'm and that's going to be for the name. Then I'm going to say, and I'm from, and then I'm going to say country. Very simple. Then I want to call that function person under square info, and we can pass through honor and we can say South Africa, very simple. Let's save that and run our code. It says, I'm honor and I'm from South Africa, very simple. Okay, perfect. So we've got that in place. Now, let's use a default argument. So we can go ahead and set the default here, for example, and I'll say country is South Africa, and I can run the code, and it's going to execute I'm from South Africa using that default argument. Now, let's say that that is not the case, and I'm actually from the UK. And here I would just adjust. Actually, that wouldn't make sense fully. Say, England. Here we go. Save that and run, and it says, I'm honor and I'm from England. So it's now taking in the explicitly defined argument that's being used in the call. Now, let's say I don't want to add in any arguments explicitly. So what I can do is I can remove everything here. I can just call the function, and I'll set this to honor. And I can run the code, and he says, I'm on it, and I'm from a Africa. So you technically don't need to even put in any arguments specifically here. You can just utilize default arguments instead. So that is something you can go ahead and do and add that predefined value in. And again, just remember what I said before in terms of the rule in terms of where default arguments are placed. So if I wanted to go on a hedge and define it in a different way and just set it as having my argument, if I were to set the argument in a different fashion and start off with the default argument, you're going to see if I remove this. Okay, we're going to have an error of sorts. Okay. So remember, non default arguments, okay? They cannot follow default arguments. So again, just remember that rule. All right, guys. So that is it for default argument. I hope this was a valuable lab exercise for you and that you learned a lot. Okay, so that's it. 42. Variable length arguments: Hi, everyone, and welcome to the next lesson, which is going to be focused on variable length argument. So let's get started. Right, so what are variable length arguments? All right. Variable length arguments let a function except more arguments than those that are explicitly defined, and this allows for greater flexibility in the number of inputs that are passed. Now, there are two types of variable length arguments that we get in Pierson, namely arcs. So it is an asterix, and then denoted by arcs. And this lets you pass a variable number of positional arguments without specifying the exact count. Then we get to quarks, and this is defined by two asterixs beforehand and then quarks. And this allows you to pass a dictionary of keyword arguments in a key value pair form with no fixed limit. All right let's simplify arcs and quarks. Args is used when you don't know how many positional arguments might be passed to the function, and this collects extra positional arguments into a tuple. Then we have quarks, which is used when you don't know how many keyword arguments might be passed, and this collects extra keyword arguments into a dictionary. Remember the key points. When you see arcs, it collects extra positional arguments in a tuple and Quarks collects extra keyword arguments into a dictionary. Remember the difference between the two. Go ahead and look at an analogy. So let's say, for example, we are setting up ingredients. We can create a function called ingredients. We can then pass multiple positional arguments such as flour, sugar, and butter, as we call them within our function call here. And we can just simply instead of going ahead and putting in particular parameters, we can just add in the asterix followed by arcs and then pass that through into the function where we want to use it, such as in the print statement and say args. Notice, when we are passing through arcs or quarks, we don't add in the asterixs. We only add in the asterixs when we are passing it as a parameter in our function, something important to know. Edits have a look at how we can do so with quarks. Now, I just want to also show you beforehand the output so you can see the ingredients here. It's going to be output in a tuple, as I mentioned before, so we can see flour, sugar, and butter. Okay. So that would be your output. So you would see ingredients, and then arc remember will be in a tuple. Now, the other example is if we are working in terms of using quarks. So here we want to pass multiple keyword argument. So here we have drink is coffee, size is large, milk is almond. Okay? And what we would do then is in the parameter list, we will just add in the double asterixs and then pass through quarks. After which we will print out the order details and go on ahead and pass through quarks without the asterixs that's going to lead in the following output, which is going to be order details, which will be in a dictionary format. So that's going to correlate with what I mentioned before, if you want to simplify the whole idea of utilizing args and quargs. Alright, guys, so that is it in terms of the theoretical explanations of utilizing variable length arguments. So remember again, if you're using variable length arguments, you're going to use asterix quarks and double asterix quarks. 43. Utilising variable length arguments - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on variable length argument. So let's get started. Okay. So let's create a simple function. So I'm going to say deaf and it's going to be called ingredients. Then what you're going to want to do is if you want to output everything in a tuple, you want to use Asterix args. Okay? So that's going to output all of the data that you pass through to arcs as a tuple. Then you need to add in your colon, Demican say print. And I'm going to say, for example, in dience add in Y colon, then you will need to add in your comma and then you can say args. Now, if you want to output and you want to use args within your function, you can then just remove that asterix within, but you need to keep it in this parameter list. Okay. Now, we want to pass multiple positional arguments. Let me go ahead and call the function so I can say ingredients, and here I can pass through, for example, flour. Remember, you can either put it in single quotes or double quotes, it doesn't matter, sugar and see butter. You can put in a variety even. We can go ahead down and run the code, and we can see the output here is going to be in flour, sugar, and butter, and this is all within a tuple. And the benefit here with using args is that you can pass as many arguments as you would like, as many positional arguments, should I be clear on that note as you would like? So if I were to just only pass through one particular argument, it does just that. And if I were to put in multiples, sugar, butter, milk, O, save and run. It will output that all within a tuple. Let's do another example. Let's say death and I'm going to say personal info. I'm going to have arcs print. I'm going to say info colon, add in a comma and then I'm going to say arcs. Let's call these functions. I'll say personal info. And here I can pass everything in. I'm wanting to say John Doe. Let's say DOB. Then, for example, I'll say 140295, for example, as a string, and then I'll just say South Africa. Just as an example, let's go ahead and run this code, and here we can see it prints out the info to John Doe, DOB for date of birth, 140295 South Africa. And all of that, again, as you can see, is being output as a tuple and they are all positional arguments. So think of positional arguments, arcs, keyboard arguments, quarks. So let's now on that note, have a look at quarks. Okay. So another example, and that's going to be on quarks. So I'm going to say, Jeff, and here let me go ahead and say order, I to score details, and I'm going to pass through double asterix for quarks. Colon print. And here we can say order details, colon quark. So now we are going to utilize quarks and just omit the asterixis, since we only use that within the definition here, and then we can go ahead and call our function. And we're going to now use keyword arguments, and we can pass through as many keyword arguments as we'd like. I'm going to say drink equals, and in quotes, I'm going to say coffee. Size large and milk almond. So let's go ahead and save and output this. So here we can see the output will be in a dictionary, and we utilize the multiple keyword arguments to utilize quarks to output everything within a dictionary. Okay. So that is how we can do so. And again, it doesn't matter how many we have. Now it's very helpful that this is being output in a dictionary and it also plays a closer role here with what you're defining. Here where we're defining you could say the parameter names, we have drink signs and milk. That forms as the keys in your dictionary where the values are the arguments themselves, as you can see, it's being output here. If you can refer back to beginner friendly lessons on dictionaries, you can see the combination here and how it all links together with the referencing. If I were to change drink here to beverage, save that and run it. You're going to see that the key here in this dictionary output is going to change. Just remember that structure. Great. That's quarks. Let's do another example for quags. Let's go ahead and set it for buying a car, again, so let's say deaf and buy car is the function. We are then going to pass through quarks, and this is going to be within a dictionary. So that's why we're saying quarks and I want to say print. We couldn't say order details. We can say that even as well, order details, and we want to pass through quargs naturally. Then we can go ahead and call the function, and we can go ahead and specify the following. I want to first of all, say I'd say branch, and that's going to be equals to Ford. And we can then say model F class, and then we can say, so it's going to be Ford F class, and we can say color. That's going to be blue. There we go. So let's go ahead and save and run this program. So we can see here it's going to return a dictionary because we are dealing with quarks. We've added in the key word arguments and multiple keyword arguments, and it's going to output the following as we can see. So the brand, forge, model F class, color blue. Again, if I were to only add in one argument and run the code, it's going to do just that. Remember, there is no limitation here, so you can pass multiple keyword arguments. Ch. So there we have it. That is how you can essentially go on a hedge and work with variable length types. Again, I will say it again just so that you're aware. Remember with args, you work with positional arguments that transforms into a tuple quarks, you work with keyword arguments that transform into a dictionary after output in both cases. And you define the asterix with arcs and the double asterix with quarks only when you are within your function definition within the parameter list. When you are outputting it within the functions functionality, for example, you just remove those asterixs. Right, guys. So that is it for this practical lab exercise. 44. Container unpacking: Hi, everyone, and welcome to the next lesson, which is going to be focused on container unpacking. So let's get started. Okay, so you're probably wondering, what on Earth is container unpacking? So simply put container unpacking allows you to pass elements of a list tuple or dictionary as separate arguments to a function using asterix for lists and tuples or double asterix for dictionaries. So let's take a look here, even simpler. So Asterix unpacks a list or two into positional arguments and double Asterix unpacks a dictionary into keyword arguments. Okay, so that's just something that you may need to go over again just for clarity. But in any case, let's go ahead and see how we can visualize this entire process. Alright, so let's say I have myself, for example, and I were to create a program to describe myself as a simple example. So I would have my function that would say describe person. I would have three parameters, such as name, age, and city. I would have a print statement that says name and then is age. And then, of course, all of the following years old and lives in followed by city. Now, what I can do is I can add all of this data and store it in a tuple, and then I can unpack the tuple into function arguments. So technically, what I would do then would be to utilize the single asterix and then refer to the tuple, which is person info. And that's going to unpack, you could say, all of those arguments into name, age, and city as long as they are in the same order. So here we can see the actual arguments, and this is how we would essentially call the function and plug in those arguments. And that will give us the output of no is 29-years-old and lives in Capetown. So essentially, as long as we have everything in that particular order, such as no 29 Capetown, and that references the parameter order here, which is name agent city, it's going to be called within this describe person function and it's going to be seen as Asterix person underscore info since it is in a tuple. And in the order that it was in the tuple will reflect the order that we will substitute within the parameters of this function. So once we unpack it here by Asterix person info, the order that we had in the tuple will go to the parameters. So no is first, then age 29 second and then cert Capetown is SRT. So no would go to name. Since it's in the same position, 29 would go to age and Cape Town will go to city. Okay. So that is how we can see it. Alright. Now, let's say we're focusing on something to do with education or university as an example in terms of a program. So someone that's gone to university or graduated. Our program would be a little bit different. So in this case here, as you can see, we have a function that says degree information or degree info. It takes in the parameters of name, degree, university and graduation year. Then we have a print statement that just goes ahead and mentions a person and that they earn a degree from which university in the graduation year, and the data will then be stored in a dictionary. You can see the education details, here it will be in key value pairs because remember a dictionary works in key value pairs. So we'll have the name, the degree, the university graduation year as keys, and then the values on BSC information technology, University of Cape Town, 2019. Then we will unpack the dictionary into function arguments. Essentially, we will then make sure that we add in a double asterisks this time because we're working with a dictionary, as you can see right here, and then all of the values will be plugged in to the parameters, as you can see here. So name, degree, university and graduation year will be added in. Okay. So that is how we would go ahead and do so. And output, of course, you'll see will be earned a BSE in information technology from the University of Capetown, 2019. Now, you'll also notice here that name is going to coincide with the name parameter, degree with degree parameter, university university parameter, graduation year, graduation year, set up with that parameter, and then the values here will be plugged in to the associated parameters that we have set up here. Guy. I know that might be a bit to take in, but not to worry, we are going to have a lot of practice in the practical lab exercises. So let's get to it. 45. Performing container unpacking - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on container unpacking. Let's get started. Let's define our function. I'll say deaf and I want to call this describe underscore person. That's going to be my function. Then I want to pass in three parameters. I'll have name. Age and city, add in my colon. Then I'll add in my print statement, and I'm just going to say name this time, I'm just going to use simple commas. I'm not going to use string concatenation just to vary bit, add in the comma, then I'll say is age, and then I'll say years old and lives in city. We've got everything that's being passed accordingly. Now, let's go ahead now and define a tuple and we want to store all of our data that we want to substitute for name, age, and city. Let's go ahead and define a tuple. I'll say person underscore info outside of the function equals and tuple I'm going to say RNO that's going to substitute name. 29 that's going to substitute H and Capetown, that's going to substitute city. Next, what we need to do is call our function so we can say describe underscore person, which will be our function, and then we want to unpack the data in the tuple which is right here into the function parameters here. So we can just simply say, remember, since it is a tuple, we can go ahead and add in an asterix, and we can say person underscore info which correlates here accordingly. Okay, so that is how we can go ahead and define the following. So the output at the end should be no is 29-years-old and lives in Cape Town. So let's go ahead and run this program. There we have it. Anu is 29-years-old and lives in Cape Town, so we can see we've now got that designated result that we want. Okay, perfect. All right, so that is how we can go ahead and do the following. So let's go ahead and do some more practice again. All right. And let me go ahead and remove all of this. Let's think of another example. Let's say we are focusing on one with let's say lunch, for example, at a restaurant. So here I'm going to say death place, underscore order, and we're going to pass through some parameters. I'm going to say starter. Main course and dessert. I can then just say print, and I'm going to say here, I'm just going to pass through to keep it simple to say starter. I'm going to use string concatenation, main course. And dessert. All right, we can maybe just tighten that up. Great. So now we would need to put in the information. So let's say food underscore info, and that will be in a tuple. So I'm going to put in the arguments here. So for the starter, let's say we have garlic bridge. Main course would be pizza and dessert. We can just say ice cream. Now we want to unpack this tuple into function argument. I'm going to call the function, which is place underscore order. Then within parentheses, we'll add in the star and then we'll say food, underscore info, and that's going to plug it into these parameters and output it in this print statement. Now we can run our code, and it says garlic bread, pizza, and ice cream. Perfect. What we can do to clean this up actually, is just add in a comma between them. There we go. This necessary output. All right, so that's how we can go on ahead and utilize container unpacking when we are utilizing the single asterix to unpack a list or tuple into positional arguments. So here we were utilizing a tuple. Okay, so that's the first part. Next is how we can unpack unpack a dictionary into keyword arguments. Now, before we continue with that, one last thing I want to mention, remember when we are using this singular star here asterix, other than the fact that it unpacks the listal tuple, remember the key thing that it does it into positional argument. So you need to be aware of the fact that what you put in here, the values or the arguments that you put in here, once we add in the asterix to the tuple here when we're defining it, it's going to go in the order that you specified originally in your tuple hence making it a positional argument. Now we need to do it for keyword arguments. So we can go ahead and remove this. All right, so let's continue. So let's define our next function to continue with container unpacking. So we want to transform our data in a dictionary into keyword arguments. So I'm going to define my function as death and I'm going to say degree underscore info, and then I'm going to pass through various parameters. I will have name, degree, UNI, and I'll say grad underscore year for graduation year. Then we want to have the print statement, and I'm just going to keep it simple. I'm going to literally output name, and I'll say plus and add in the coma then I'll have degree I'll have UNI and grad Perfect. We've got that all set up. Now let's go ahead and store our data in a dictionary. I'm going to call my dictionary education underscore details, and that's going to be within my curly braces. Now, this is where the keyword arguments comes into play. The keys of the dictionary are going to be your parameter names which are going to be the same as name, degree, uni, and grad year. We're going to want to say here name. For starters, and that's going to be equivalent to you could say the value or in our case, the argument. So I'll say no, comma. Then next, we'll have degree, since that is what we have next in the list here, and that is going to be set to BC in IT, we can say. Then the next parameter here will be the university, so we can say UNI that's going to be equals to for city of Capetown, and then finally, we have grad underscore, which is going to be equivalent to 2019. Right. Now, since 2019 is an int and we're using string concatenation, the rule is we need to cast it to a string here. You need to say plus STR so you may need to do a little bit of casting, just like that. We are going to be able to manage this integer. Just a small adjustment that you need to make. I'll just zoom out there for you. Remember when I said that this is going to focus into keyword arguments. Name in the dictionary, this would be seen as our keys and what we associated is our values, as you can see right here. Now, when we're working with keyword arguments, it's going to be treated like name, degree, UI, and grad under square year will be the parameters. These will be parameter names and they're going to be equal to the how can I say the arguments which would be Ano BSEty University of Cape toown 2019. Try to visualize that process at hand. Okay. So once you're happy with all of that, you can go ahead and call your function. So at the end, we can go ahead and do just that. So the function here is degree under square info. So I'll say degree under square info, and then we want to call it. Remember to unpack the dictionary, you need to add in two asterixs and then refer to the dictionary name, which is education under Square details. Like that. And once you're happy with everything, you can go on ahead and run that code. There we have it. We can see it says honor BSE and IT University of Capetown, 2019. Well done. That is how you can go on a hedge and unpack a dictionary into keyword arguments. Let's do another example. We can go ahead and remove all of that. Another way in which we can go on a hedge and get all of this started is we can set something up for order details as an example. I'm going to set the following. I'll say DF Order underscore details. And we can say, let's go ahead and put in I'll have drink. Size and milk. We can have a type of milk, for example. We can have cow's milk, almond milk, et cetera. Perfect. Now, the print statement. What I'm going to go ahead and do here is I'm just going to say order details, and we can go on ahead and pass in what we need. Here I'm going to say drink Add in the quotes, I'll have quotes and milk. Great. Now, what we can do is we can now go on ahead and define our dictionary. So I'm going to go ahead and say, let's call this drink drinking items. Okay, there we go. Call it that. So first, remember, we are using key word arguments, so drink, size, and milk. So we need to refer to the parameter names. So we'll have drink colon, and that's going to be let's say coffee. Size, large and milk. I'll say almond. There we go. So we have drinking items. We can also just remove some space either side. Okay, now we need to call our function, so I can go ahead and say order, underscore details. And within parenses, okay, you're going to say Asterix asterix, drink King, underscore items. That's going to go ahead and assign it as drink equals coffee, size equals large, milk equals Almond. Okay, so that's how all that will fit in and we can run the program. We can see here all the details, coffee, large elms. So you might need to stir that space. There we go. And there we have it. So we can also make this bit cleaner. All right, there we are. So we can now see it's a little bit clearer. All right, guys. So that is essentially it. That is how we can unpack our container. So you can see it's a very useful way if you want to simplify managing your arguments and passing it through to your function, et cetera. All right, guys. So that is it for these practical lab exercises. 46. Local and global arguments: Hi, everyone, and welcome to the next lesson, which is going to be focused on local and global argument. So let's take a look. Right. So and global arguments refer to where a variable is accessible in a program. Now, let's take a look, first of all, at local arguments. Now, these are essentially variables that are created inside a function. They can only be used within that particular function and nowhere else, and they disappear after the function finishes running or executing. Global arguments on the other hand, these are variables that are created outside of the function or a function. They can be used inside and outside of functions and they persist throughout the program. We can see there are a lot more advantages to global arguments as we can see here. However, it's all going to depend on your project requirements and needs. Now, let's take a look at analogy to further simplify this for us. Now, I want you to think of a city as local scope and a country as global scope. Let's say we choose the city of Cape Town as the local scope example and the country South Africa as the global scope. So Cape Town, in general, which is a city, so a city can receive its own local funds from the mayor, and this can be deemed as function arguments. Now, these funds belong only to that city, and okay, it doesn't affect the national budget. Now, if we look at a country, for example, we can imagine the country provides a national budget to all cities and that every city has access to this budget, but if a city modifies it, it affects the whole country as a result. So hopefully this analogy helps to give you a bit of a better understanding with local and global arguments. We are going to focus on the practical exercise on this. It is quite a simple concept to grasp. I may also add an additional practical exercise with it as well, but that's just something I wanted to mention in terms of the analogies. 47. Analysing the scope of arguments - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on local and global arguments. So let's get started. First, we want to start with global. Okay. Now, global and local arguments are essentially part of working with variables. So we would define something known as a global variable in terms of global arguments. So if I were to define a variable and say name equals, I want to say, This can be seen as a global variable. If we go ahead and call it within our function. So if I now define a function, very simple, that is defined by def Grit. So the function is Grit. I can say print. I can say hello. And then I can just use string concatenation and say plus name, and that's going to go ahead and grab this variable which is name and utilize it directly in my function. And that is how we can access a global variable. Then when we call the function, just by saying greet, it's going to say hello and then RNO. Now, if I go ahead and run this code, it's going to say hello RNO. So that is how we can go on a hedge and define a global variable. So the global variable is accessible inside a function unless it is being modified in some way. Now, let me show you how a local variable is run. So you'll just remove this right here, and let's make some adjustments. Okay. We can keep our Greet function for now. And it was in our function, we can say message equals hello aro. And I can say print message. The message here, there is a variable was in my function that says message and the value is hello honor and we're saying print message. So when I greet, it's going to output hello nor because the print, how can I say the print functionality is within the function, and we're using this variable locally within the function. It's not outside. So if I were to run this program, it's going to give the same result. But for clarity, I can just change this so you can actually see the change. Hello, John, it's going to say hello, John. But if I wanted to output this message and I wanted to access it outside of my function, if I were to say print, message. You're going to see here when I highlight it, it says, message is not defined. So this is what I mean by local and global. This is now a local variable. Local variables exist only inside the function and cannot be accessed outside. The reason why we're getting an area here by saying print message is because the message variable, of course, is local. Right. That's how we can go ahead and see the differences in terms of local and global arguments. These refer to where a variable is accessible in a particular program. You can see the difference there, we have global and we have local. Remember, anything you define within that function as a variable stays in the function. Anything outside that's, for example, variable will be accessible everywhere. Remember there is a scope to it as to where it can be utilized and such. Right. That's it for this practical lab exercise. I know it was quite short and brief, but it's quite a simple topic really to grab your head around. But anyway, wanted to cover it, so that's such. 48. Utilising the global keyword - [Optional lab]: Hi, everyone, and welcome to the next practical exercise, which is going to be focused on utilizing the global keyword in functions. Now, this is a bonus, should I say practical lamp exercise. You don't have to do it, but it's something extra that I was thinking about and I saw might be helpful to add in, but it's definitely something that does come up sometimes in PySon on an intermediate spectrum. So let's take a look. So the global keyword. So let me show you on default if we just want to utilize a global variable just for reading. Okay? So what I mean by that is as follows. If I were to say count equals five, a number, for example. Then I were to define a function and say show, underscore count. In my colon. Then let's say I have a print statement and I say count is, and I just add in count there, and then I call the function by saying show count. It's going to execute this line, which is going to say count is and the value of count is five and we'll see that when we call this function. Okay. Now, this, of course, is using a global variable because we are referencing it outside and we can utilize it within this function. Let me go ahead and run this code. And it says count is five. Okay. Right. So that is that part. Now, the global keyword is utilized if you want to modify your variable. So if we were to amend this code, let's say, I want to adjust this value that's attached to this variable. What I can do is within the function here, I can say, global. And that's the key word we need. And I'm going to attach that to count because count is treated as a global variable, so we say global count, and this is needed because we are changing count explicitly. And what we want to do is increment. We just want to add one to it, so I can say count, and space plus equals one. So it's going to take the current value and add one to it to append it. So it will then be, of course, how can I say it will then be six. Okay. So what we can do then is we can show the count now, and then it's going to output six here. Okay? So that will be the count that we have adjusted here within this function. So if I were to run this code, we can now see the count is six coming from this function. So we went ahead and grabbed that particular variable, added one to it, and printed the result by carrying over that global variable and adjusting it. So if we want to modify a global variable within a function and not only just read it, we would need to explicitly specify this global keyword, and that is the whole point of it to modify a global variable within a function, and that is usually restricted if we do not have that. So if, for example, I decide to do it without saying Global, and I just take this out. And say count plus equals one and then count, you'll see, if I run this, it's going to show an error here. Unbound local error. It's now treating this as a local variable in a sense because that's what the assumption is because we're making some an adjustment here at play. We're just saying count plus plus equals one and it cannot read where this count is coming from. That's why you would need to go on ahead and explicitly state global count, and that's going to allow you to go ahead and get the designated output. All right guys. That is it in terms of this bonus exercise. So just a little bit extra onto the whole global and local scope perspective. So go ahead and take that up. All right. 49. Sending variables as arguments: Hi, everyone, and welcome to the next lesson, which is going to be focused on sending variables as arguments. So let's take a look. All right. Now, you don't always have to set a hard coded value with our function calls. We can also pass through variables instead, so it's a very simple concept. So let's take a look at what we've done earlier on in the course. So previously, we have been defining our functions, setting a parameter. So for example, name, and then adding in the argument directly to the function that we're calling. In this case, for example, greeting. We are passing in no with a hard coded value to then substitute the name parameter and then get grabbed into the print statement where we say hello there in the name, which will be nu. What you can also do is define a variable outside. So you can create a program like this where all that you do is you define a variable outside of your function, and then you set that value. And instead of putting in no directly as we can see here, we just pass through that particular variable, which is first on the square name, which is going to substitute name here as rno. That's why I had the comment there, and it's going to print the exact same results. So this is just something I want to mention so that you're aware. You can just simply pass through variables as long as you have assigned them beforehand. It's going to execute the same programs, the same output, exactly similar to the one I showed you just here on the left hand side, which was hard coded. Just something on to mention, it's a very easy and simple thing to learn and understand. That's just something that's important that I feel you should know, and that is how we can send variables as arguments. 50. Working with variables as arguments - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on sending variables as arguments in functions. So let's get started. So this is going to be quite a simple exercise, so it's not going to be that extensive. So let's go on ahead and just practice a bit. So let's define a simple function. I'm going to say deaf greeting. I want to set my parameter name as name. Then I want to output the following statement which says hello and then we can add in comma and pass through name. Now, what we are used to doing is calling the function and then directly adding in the value. We can, for example, just put in, let's say, Katie run the code and it says hello Katie. Now, let's say we don't want to add in the values directly, but instead we want to go on a head and assign it to a variable first. What you can do is say, for example, first name, and we can go ahead and set this to let's say Katie. Then here where you are calling your argument, you just put in first name, again I just want to set that up. Now if you run your code's going to show the exact same results. Let's say you can go on ahead and send your variables as arguments. Let's do another example. Say deaf and I'm going to say here, favor drink I'm going to pass through here drink print statement, and I'm going to say, I like to drink. And we'll put in drink. Then outside, I can go ahead and say favorite underscore drink, call the function, and I can plug in there, for example, Run the code. It says, I like to drink Okay. Let's go ahead and change this around. Let's define a variable outside and let's set this as we can even say this as drink equals. We define it just here and then we can pass through drink itself. That's going to go on a hedge and substitute what we have right here in the parameter and if we were to run the code, I like to drink too. Okay. So that is another way in which we can go on ahead and do it. So even if the names are set here, so drink here is going to take into account the variable here, substitute drink here, which is a parameter, and that's very important because sometimes you run into code and various programs and chess where they keep it the same just to test your knowledge. So remember, the drink in here is a parameter, o, and that's going to output said value. Drink here is a variable. Remember if you highlight, you can see variable and parameter. Do keep that in mind. But what you can do to help you distinguish, especially if you're getting started, you can clearly differentiate between the two so that you know that, this is my variables, these are my parameters. Again, of course, if I run like to drink tea. That is just a little bit more practice on sending arguments as our arguments. That's on that exercise. 51. Parameter passing by value or reference: Hi, everyone, and welcome to the next lesson, which is going to be focused on parameter passing by value or reference. So let's take a look. All right. Now, when you pass a variable to a function, Pyson handles it in one of two ways. Pass by value or pass by reference. Now, let's take a look at each of these starting with pass by value. Now, with pass by value, the function gets a copy of the original variable, and changes inside the function do not affect the original variable. Now this works for immutable data types, and for that, we have int, so integer, float, SDR, for string, and tuple. So very important to remember that when you're passing by value, it's going to work for immutable data types and necessarily these four data types. Then we have pass by reference. Now, in this case, the function gets a reference or a memory address of said variable, and any changes inside the function will affect the original variable that was defined. Now this works for immutable data types, not immutable, but mutable data types, which will include a list, dict, and a set. That would be in terms of pass by reference. Guys. That's it for the theoretical overview. Let's go ahead and dive in to the practical. 52. Explore parameter values & references - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on parameter passing by value or by reference. So the first thing we're going to do is we're going to focus on passing by value, which is going to be focused on immutable data types, such as integers and strings. So immutable, meaning cannot change the value once it has been set up and passed through and assign. Okay, so let's get started. So what I want to do is define a functions. I'll say Def, change underscore number. That will be my function name. Then I want to pass through X or set X as my parameter. Then I'm going to say print. And I'm going to add some text to say inside function, colon. Then I'll add in space, comma, and then X. Then I want to call my function and say change underscore number. And what I'm going to do is I'm going to pass through a hard coded values. I'm going to say five, for example. Then when I go ahead and run this code, it's going to say inside function five. So we can see this argument was passed, and it substituted X, and then X was then collected and added to the print function here, and I output five in the end. Great. Now, let's go ahead and set this as a variable for now. Set num equals to five, and now I'm going to pass I'm now going to pass a variable here into a variable as an argument to substitute the parameter. Now what I can do is go ahead and run the code inside function five and we can see that has been passed through as it should have been. Perfect. Here is where the interesting part comes into play. Now, let's say, for example, I head on over to my function and I say X is now going to be ten. Thinking to yourself as to what's going to occur. Remember what I said, Immutable, no change. So if I were to go on ahead and set this up and run the code, it's going to say ten. Now, what's happening here is the num value here that's being set is being how can I say it's being passed over to the parameter X, but then we're redefining X and setting it to ten. So the value that will be kept in the local function will always be ten. Now, the part that I'm going to mention in immutable is that the original is going to remain unchanged. So what I mean by that is if I say print and I go out side function, and I go on ahead and say num you're going to see that the outside function doesn't change. So this is going to be immutable, so it doesn't change outside, no matter what we do here was in the function itself locally. It's not going to make any change. So there's no effect on num outside of the function. So this is immutable. Now, if we were to set this up into such a way that it would become mutable, so the changes will be affected outside. What we can do is we can test this, for example, with a list. So now I'm going to show you how we can pass by reference to the mutable type. So let's do that now. So the keynote to see here is that it didn't change outside the num value irrespective of what adjustment we made in the function, it didn't change. So let me show you where it's going to change by a mutable type such as a list. So the changes will affect the original result. Let me go ahead and define a new function, def ad on the score item, and I'm going to set the parameter as my list. Okay, what I'm going to do for now is I'm just going to say prints inside function inside function. Con then I'm going to have my score list, and we just want to add in that comma. Then we want to call this particular function, but we need to add in some information to a list. So I'm going to say numbers, equals, and I'm going to say one, two, three. Then we can see add under square item, and we're going to say numbers. So we're going to pass through that particular list right here to my list here, and then it's going to just go ahead and output what is being ran within the function. So we can go ahead and run this now, it says inside function one, two, three. That's exactly what we pass. I also want to show you what it shows outside. So if I say print, outside function. And if I were to say numbers, Inside function one, two, three, outside function one, two, three. So let me go on ahead and modify the original list within the function. So what I can do is I can grab my list, which I'm grabbing here from the parameter, which has assigned value set in numbers as one, two, three, and I can append to this list, for example, I can use a pen method, so I can say dot pen and pass through four. So that means that the function now is going to change to one, two, three, four, but we want to see if it changes outside. If I run this, G to three now that the inside function is now 1234 and the outside function is 1234. So even though we are setting up this list within the function, it's going to have outside consequence as well. So in other words, as you can see that the list is modified outside of the function. As it is also was in the function. So this makes it mutable. So changes affect the original. So the original was numbers one, two, three. As we went on before and looked at the end, you couldn't change it because it's immutable. All right. So hopefully, this gives you a great understanding of what I mean by mutable, immutable in terms of changes and how they are all going to gather into play. Right. Now, let's do some more examples. Okay, now the next one I want to do is going to be an immutable type this time. So it means no change, and that's going to be a string. So I'm going to say deaf, change, underscore text, just a function. Going to pass through text. And I'm going to say for now print side function. Text. Then I can say change, underscore text. And what I'm going to do for now is just say hi. Okay, there we go. That's the basics. Let's now assign a variables. I'll say message. Hello. Now I'm going to pass through a variables through the argument. Run that now. Hello. Good. I'm doing this in increment so that you can just learn from each part how I'm setting this all up. Now the outside functions, so I'm going to first of will say print, outside function. And that will be message. Now what I want to do is make an update was in the function, but before I do that, let me just run this code again. So you can see inside function, hello, outside function, hello. Now, if I were to make a change here was in the local function and say, Okay, text is now going to be good Bye. So it's now going to go on a hedge and be goodbye. So that is going to be the change, and I go on ahead and run this code. You're going to see it'll be goodbye in the inside function, and outside, it's going to be hello. So you can see, changing text within the function, and the original that we had right here, of course, remains unchanged and there is no impact or change on it at all. So you can see here that there is a difference in the sort. Gretch. Rich. Now, let's go ahead and pass by reference again. So mutable type, and one of them is a dictionary. That is a mutable type. So let's go ahead and define our functions. I'll say Def, update under school dict. And we can just go on ahead and define the parenses and we can put in here, we can go ahead and put in the primeter of M dict for my dictionary. Then we can say print for now, and I want to say inside function, colon, and we're going to pass through my dict. Now what I want to do is refer to update dict and go ahead and keep this open for the time being the parenses and then I can define a dictionary. I'll say person, equals, and I'll set the key value here, the key value pairs, is singular. I'll say name colon Alice. Did I want to pass this through. So I'm going to say person, and person is going to substitute my dict, and it's going to say inside function, and then my dicta will be person, which will show name Alice within the function. Let's run this. Inside function, name Alice. Perfect. Right, then let's make our adjustments. So outside function, I'm going to say print, outside function. C on space. I have person. See it's the same inside and outside because we haven't made any adjustment. The functionality of the print statement is just reading from outside of my code. Let me go ahead and make a difference within the function itself and say my underscoreject, here, I'm going to add in a new key value pair. I'm going to set age and I'm going to set that to 28. Now we'll have a new key value pair added on to name Alice. We'll also have age and 28 and that's going to adjust and change the inside function and this result is also going to affect what we see on the outside function. So let me go ahead and run the code. And there we go, we can see that that change is, as you can see mutable, changes after changes affect the original. So person the list of person has been changed. As we can see outside of the function, it has also changed. All right, so there we have it. That is how you can pass by value and pass by reference and the difference between mutable and mutable types. Remember, mutable changes affect the original and immutable changes do not affect the original. All right. So there we have it. 53. The asterisk operator: Hi, everyone, and welcome to the next lesson, which is going to be focused on the Asterix operator. So let's go ahead and take a look. Right, Asterix operator. Now, the asterix operator, as we can see, denoted by an Asterix is a special operator that has different uses depending on where and how it's used. Now, of course, in this course, and if you have ever done a beginner friendly PySon course before, you may have seen this operator when you are, for example, multiplying and such, and we've also learned a little bit more in terms of arcs and quarks how we can utilize this operator. But I just want to give you a few more use cases and the scenarios of where it's used and how it's used, et cetera. So let's go ahead and dive in. Now, I'm just going to give you a list of the most common ways. So here are the most common ones in a simple way. So we can use asterix for multiplication, so in math, we can use it packing with lists and tuples, for example. Can use Asterix arcs for multiple function arguments. We can use double asterix quarks for named arguments in functions and we can use a single asterix and a double asterix for passing lists and dictionaries to functions. As you can see, there are a lot of use cases in which we can utilize asterixs. Right. I just wanted to give you a bit of a rundown, so you have an overview. We are going to have an exercise on the asterix operator, that's going to be a little bit more diverse and integrated just for some practice and such. But that's all I wanted to mention on the asterix operator. 54. Applying the asterisk operator - Pt. 1 - [Lab]: Hi, everyone. And welcome to the next practical lab exercise, which is going to be focused on applying the Asterix operator to multiple use cases in Pyson. Now, of course, there are endless use cases available. However, I am going to cover most of the common ones that you will face, and I'm also going to add an extra single or two in as well in terms of extra bonus content that's a little bit out there. So let's get started. First of all, the most common use case in mathematics is multiplication. So we can say, for example, result equals, and I can say four multiplied or this is the asterix by two. So in mathematics, the asterix symbol means multiplier. I can say print, result. And I get eight. Great. Now, let's go a bit further. Let's say I have num one equals say four, num two, five. Then I can just say final result equals number one, multiplies by num two. And let's go ahead and print final result. And it's run this 20. Okay, that's another way we can do it. What we can also do is do it based on a result basis to get a final result. So what I can say here is result one, and that's going to entail four multiplied by four. Result two is going to entail three multiplied by three, and then the final result is essentially going to be result one and then again, multiply it by result two. So we're going to get this result, store it in this variable result one. We're going to get this result, store it in variable result two. Then we get another variable and multiply the results from what we have there. Save this and run the code. Oh, I need to say print, excuse me. Print, final result. And we get 144. So that is how we can go on a head and do it with mathematics for multiplying numbers. What we can also do is we can repeat strings and lists as well. So for example, if I say text equals high, John. Outside, I can add in the asterisk and say three. Then I can say print Text. So now if I go ahead and run this code, it's gonna say, Hi, John, hi, John. Hi, John. Okay. So that is what we can do in this regard. Now, what I want to do is actually add a space there. Here we go. Hi John, Hijohn a little bit clearer to see now. And it's just going to multiply it by three. Now, since we're working with strings, it's just going to repeat it three times. That's how this asterix applies with strings. Unlike with numbers, it is actually going to perform the functionality itself in terms of raw multiplication. Now, we can adjust this actually. So text one is high. Ext two is John Doe. And we can say final result equals. And what I'm going to do here is say times two times two. And then I'm going to say text one plus ext two. So we're using string concatenation here, and this will work nicely because we're currently dealing with strings. So text one is going to have the result of high high times two, and then John Doe, John Doe times two. And then we just combine them both together. And we can just print this out, so I can say print final result and run this code. High, high, Jon Do, Jon. So that's how we can deal with repeated strings. Right. Now, we can also work with repeated lists as well. So if I say numbers equals, and in my list, I have one, two, I can say times three, then print the list and you'll notice if we run this it has one, two, one, two, one, two. So instead of creating you could say three separate lists, it's going to modify what is in the list three times and still keep it in a singular list as we can see here. So that's what the multiplication will do for you. Now, we can make this a little bit more complex, should I say? We can have numbers two, and let's just put here, for example, four, five times two. And then we can say final result again, equals. And since we're dealing with a list, we need to cast it to a string first, so we can say SDR, numbers, plus, so we're doing string concatenation, cast a string, numbers two. And now, if we were to print final result, we get one, two, one, two, one, two, four, five, four, five. Now, we can see it's all here together, but it is separate in this case. So when you're using the string concatenation between the two lists, you'll notice in this case, it's going to be separate. So unlike when you are doing it singly. So if I were to print numbers as you saw earlier and I have this result, it's going to multiply and add Well, in this case, multiply by three, so it's going to show one, two, one, two, and one, two, three times. If we were to perform string concatenation on it, what's going to happen is it's going to separate into its two entities and it's going to perform its separate sort of functionalities into its own list. Right. So there we have that. So multiplication done and mass, repeating strings and less is done. Right, next, unpacking lists and tuples. So this is quite a simple one. So a lot of the things we'll also see now we've also covered, so it'll be a bit of nice revision for you too. Let's say I have a few numbers and I have one, two, one, three and four. Okay. Let's say I say print, and what we can do is we can add in the asterix, and this is going to unpack our list for us. So I'm going to say numbers. So remember, when you're unpacking your list, you will add in the single asterix. And we can go ahead and say run code, and we have one, three, and four. Now, this also applies if you're working with tuples as well. So if I gradually switch this to tuples, add in the singular, the singular asterisk, excuse me, and say run code. It's also going to return the same. So that's how you would unpack your lists and tuples. So expanding your list elements from printing or passing to functions, this is where it will be really useful. Now, let's say I want to collect multiple arguments using the Asterix args notation. So what we can do to achieve this goal is we can create a function, so I want to say death show numbers and I'm going to pass in Rx colon and print arcs. Then I want to call my function, and I'm going to just go ahead and pass them in one, two, and three. And that's all going to be put together within the args parameter and it's going to be output here in args without that asterisk. This would be how we can also utilize it in a function perspective with arcs. So we can go ahead and run the code. We have one, two, three, and this time it's in a tuple format as you can see how it's been output. Right. So that's how we can do that. That's how we can take the multiple arguments and store them as a tuple. Now, we can also collect keyword arguments, and we can store them as a dictionary by utilizing quarks. So we can remove that and say deaf, show, underscore info. And here I can just say quarks, ad in the colon, and remember when I say print, quarks, and then we want to call our function. So we're going to say show and underscore info, and within the pareneses we can go ahead and pass in. Remember, keyword arguments this time since you're working with car quarks, I'm going to say name equals, no, and we can say age equals, and we can go on ahead and say, let's go for 29, and we can go ahead and run this code. There we see that dictionary output. So we have the name key of honor and the age key of 29. So there we have it. That's how we can utilize it with quarks, as well. So here we have double asterixs that we need to apply. Great. Now, the next thing is something quite new that we haven't looked at. This is how we can unpack with the asterisk symbol. And for example, if we want to skip middle values in list, for example. So if I were to say first and I can add in my asterix for middle, Then I can add in last. I can assign that to a list that has one, two, three, four, and five. Now, if I were to print each of these variables, first, middle, and last, you'll see what will get output. If I say print, first, print, and I want to say middle, print, last. It's run this. We're going to see here we have one, and then we have two, three, four and five. This asterix here being applied to middle is going to collect all middle values. If you look here, one is first s, five is at the end, two, three, and four will be in the middle. It's going to collect all the middle values of the list, leaving first and last as separate variables, and then as we can see when we are printing it, it's going to be within a list itself and the separate numbers here, in this case will just be integers on their own. So that's how we can unpack with the asterix in a given context like so. Right. Now, let's go on ahead and apply this to last. And we run this. Now we can see the first value here, one and middle, which stretches across to two. The last option here is now going to dictate that it's going to be three, four and five. It's going to be a little bit different here if you set this for the last option here. It is going to change a little bit. It's going to go with last values and it's going to take that after the first two have been assigned, you could say. First, technically, you would say is going to be paired with one. Middle, of course, would be paired with the next one and last, of course, will be the last set of values in a list. Right. Next, let's go ahead and merge lists, and we're going to ensure that we also unpack them in a list. So I'm going to, for example, say list one equals, and within the list, I'll have one, two, List two, we're going to have three, four, and then we can merge them. So I'm going to say merge equals, and we would create one sort of list here, you would say, add in your arithmetic operator, and you can say List one and then add in arithmetic operator and say list two. And then when you go ahead and print merged you're going to see now that it's all been merged into one list. So this asterix before the list, as you can see, separated by the comma in one list here will merge it together in one list for you. So that's how you can merge your list and then at the end, unpack them out in a list here, so it's all in one together. Okay. So that's how you can combine your list very easily. Now, let's say you want to merge dictionaries, you would, of course, also go ahead and follow the same process. However, it's just slightly different. You would need to add two asterixs this time instead of one to merge dictionaries. So let me go ahead and say dict one. And here, I'm going to assign, of course, a key, so A is, of course, going to be one, died two. We're going to have B, and we can set that as two. Then we can say merged equals, and within parenss we can just put in double asterixs and say jct one, comma, dict two. And now if we were to say print and you say merged, we get A one, B two, so we can see that that has merged together into one dictionary, so we have two key value pairs here. So two instances. So A one and B two has been output. So that's how we can merge dictionaries. So remember. If you want to merge a list, other than the list being within square brackets, you will only do one asterix for the merging with a dictionary, you will have two asterixs. So remember that key distinction when you are working wisdom. H. Next thing that we want to do is we want to pass, for example, our lists or tuples to functions. This is something that we want to look at now. Let's say we want to go ahead and add values, for example, in our functions. If I say D, add, and we're expecting A and B, and we're going to say return A plus B. What we can do is go ahead and set the values in a tuple. So I'm going to say nums for numbers equals, and in a tup I'll say three and five. Then I'm going to say print. And in this case, I'm going to refer to I'm going to call this function add here. I'm having the print statement outside instead of using the return inside. I can then go on ahead and just pass through and say nums, and that's going to automatically go ahead and associate with A being three, and B was five, since it operates on positional argument since we're working with just a singular asterix. So now we can go ahead and say run code, and it returns eight. But what I can do here just for simplicity, I can just say add nums. And we don't want to return. We can just say print, and I'm going to actually say A plus, let's put final result equals A plus B, and then I want to print, final result. Okay, so you can do it that way as well. So it's going to go in ahead and get the same result there we go. So just another way of doing it. So that's how we can pass, for example, to a list or a tuple to a function. Now, let's say we go ahead and do this with a tuple. So let's go ahead and set it in that way. But this time, what I'm going to do is not do it with mass here. I'm just going to do some joining in a particular way, so let's close it up, and let's focus on the list. 55. Applying the asterisk operator - Pt. 2 - [Lab]: Right. So what we can do is define our function, say def ad and we'll have A and B. Then I want to say print, A and B. I then define my dictionaries, I'll say words. And here in the list, I'll say hello, ad in the comma space, and then a comma for the next part, which is going to be world. Then I can call the function, which is Add, and then we need to add in a singular asterix here and we can say words. So we're going to pass through the dictionary key value pairs to AB, and then we're going to print AB. Then if we run this code, we need to get hello world. So that's how we can go ahead and pass the list to our functions. Now we want to learn how we can pass dictionaries to functions, so let's do that. Or revise, should I say? So I'm going to say DF, create. Name and age as my parameters. Then I'm going to say print. This time, I'm going to use F strings and utilize placeholders here. I'll have name and then we'll say is age years old. Then I can specify my data for the dictionary. Here I'm going to simply say name. Colon, no, and then comma and then age, colon and then 29. Then I can call the GET function and pass through the following, which will be double asterix for the dictionary here. So now we can run this code, and we get nos 29-years-old. So I've defined my function here. I'm using an F string to act as a placeholder for the values that's coming in. So data here is a dictionary. Are passing the dictionary here to the parameters, name and age, and essentially we're just printing out what the values have been set as such as name and age. And then to get this data from the dictionary to our function, we're adding double asteris to substitute it accordingly. Rich. So that's how we can go ahead and get that started as well. Perfect. Right. So that is how we can get started and set all of that up. Now, another thing that I also want to show you is how you can go ahead and use the asterix to ignore values, or if you want to skip multiple values as well, and this can also work in tangent with an underscore as well. Right, so let's say we want to extract only the first element in the list. What we can do, for example, is say A, and then we would add in the asterix with the underscore and say equals. And in the list, let's say we have ten, 20, 30, and 40. We would say print A, and it outputs ten. What happens here is that A is going to be associated to the first item in the list, and the combined usage of the asterisk and underscore is going to ignore all of the additional values that are available here. Okay. What we can also do is extract perhaps the first two elements. So what we can do to do that is we can just say add in B now and we can say print A, B. So A is going to be associated to ten. B is going to be associated to 20, and the output will be ten and, of course, 20. And Asterix underscore will help to ignore 30 and 40. So if I run this, have ten, and we have 20. Let's say you can extract the first two elements. Let's say we want to get the last element, which is 40 here. Let's go ahead and change what we are defining here and ignore everything at the start and then we can say, add a variable that's last and add last year, and that means that the asterix and underscae here will ignore 1020 and seti and only 40 will be preserved for the last variable and output that. If I run this, we get 40. Let's say you can extract the last item. Let's say we want to go on a hedge and extract the first and last element. So what we can do in this case is say first add in your asterix and underscore and say last equals. And here, let's say we have one, two, three, and four. We can then say print first and last. So then we only get one and we get four with all the middle values ignored by the asterix followed by the underscore. Now, let me give some more information into the asterix and underscore. So the underscore is essentially a placeholder, okay, and you could see this as an ignored sort of variable. The asterix that we have here, right? That makes underscore collect multiple ignored values or elements, you could say, from the list. And if we do not have the asterix, okay, this underscore is only going to hold a single value instead of a list itself. So that's just an extra thing that we can do when we want to ignore values and such. We can combine the asterix operator with the underscore. All right, so there we have it. There are a bunch of use cases that you can now apply to with the Asterix operator. 56. Lambda functions: Hi, everyone, and welcome to the next lesson, which is going to be focused on Lambda functions. So let's take a look. So you're probably wondering, Okay, what on Earth is Lambda function? So a Lambda function is a short, anonymous function that takes multiple arguments, but contains only a single expression, meaning that you will define your Lambda function on a single line. Unlike regular functions, where, of course, you would at least need to have a few lines to get everything started up and running. But with a Lambda function, it's going to contain a single expression in terms of its order and pattern. And a lambda function is often used for short simple operations where defining a full function is unnecessary. So if you are thinking to yourself, okay, I need to make a function, but it's going to be a rather short function. Then this is where the value comes in of utilizing a Lambda function. If, however, you have a function that is quite lengthy with a lot of requirements, a lot of arguments, parameters, and functionality that you need to add into place or a function that's just generally more complex in your general use case, then stick with functions. But like I said, anything short and quick or anything that you just don't need a lot of functionality in place, then then the functions are your best way to go, and I would highly recommend that you utilize them because they can be quite useful in certain situations. Yes, in any case, that's all I have to mention theoretically wise in terms of Lambda functions. We are then going to focus on the practical lab exercises where I'm going to start off gently and ease you into it and just teach you the difference between a function and a Lambda function, especially and mainly, should I say in its syntax. But we'll get to that in the lab exercises. But anyway, that's all for the theoretical overview. 57. Perform operations with Lambda - [Lab]: Hi, everyone. Welcome to the next practical lab exercise which is going to be focused on utilizing Lambda functions in PySon. Now, of course, to keep this very simple in the beginning, I'm going to show you how you can compare regular functions to Lambda functions so that you can understand the syntax and how you can utilize Lambda functions properly and from the get go. Let's get started. First of all, let's define a regular function. I'm going to just add in a comment and say regular function. So you would, of course, start with your keyword, which is Jeff. Then you would define your function name, which would be, say, underscore hello, for example. Then on the next line, we can just say print and we can say hello world as an example. So that will be what the function will output once it's called. Then we can call our function, which is say underscore hello, and that's going to call this function and print out hello world in the terminal. So if I save that and run the code, it's going to say hello world. Perfect. Now let's see how we can apply this when we are working with a Lambda function. What I'm going to do is not remove this code, but I'm just simply going to comment it out so that you can understand the syntax and the logic more smoothly. I'm going to add a comment here that says Lam D function. And the first thing you want to do is define your function name. Now, with Lambda functions, what you would do is set it equals to Lambda. So, for example, in this case, you can say, say underscore hello, and that's your function name in Lambda, very similar to what we had in the regular function where we say say underscore hello. Same thing. This is how you define a function in Lambda, and then you say equals and set it to Lambda. And then I want to know that Lambda here equals is the expression for setting up a Lambda function very much similar to saying death for a regular function. Try to see it as the same thing. Then we can add in our colon, and we want to define what we want to do. So in this say hello function, we defined that we wanted to print hello world. But we did that within the function. With Lambda function with Lambda function, we're doing it on the same line. So this print lo world will just be here on the same line as the Lambda function. This is what I meant in the theoretical lectures when I mentioned that with Lambda, it's going to be a single expression. So we can just say print and say hello world. There we go. Then we want to call our function, that's going to be exactly like our regular function that we had here and also we'll have the parentheses, so we can just say underscore, hello. So now we can run this code, and we can see here it outputs hello world. So well done, that is how you can utilize a Lambda function, and hopefully that makes sense with the synchex and usage in comparison to a regular function. But don't worry, we're going to go through a few examples here and we're going to go through another direct comparison between a regular and a Lambda function. Right. So let's remove everything here except the comment above, and we now want to add two numbers. So a regular function for doing so and a Lambda function. Now, something I do want to mention is when you're working with Lambda functions, it's typically not suited to defining variables within a Lambda function. Now, I know in regular functions, you can do that with local variables, but it's not really a sing really in Lambda. So you would often if you want to return a result, you'd often want to say return instead of defining a variable and then printing it out. So just something I want to mention in advance. Okay, that's the final regular functions. I'll say Def add underscore numbers. We're going to work with parameters this time. I'll have X and Y, for example, and then I'm going to have a simple return statement that says return X plus Y. Then I want to utilize the print statement outside and say print, and then I want to wrap around the function name which is add on the square numbers, and then we need to put in the arguments that we want to send to the parameters of X and Y so that we can return the result via the print function of what X plus Y is. Here I'm just going to say five and seven. It's going to return five plus seven, and that's going to be printed out as the output, that should be 12. Let's go ahead and run that code. So we can see 12. So there we go. That's how we can define a simple regular function for adding numbers. Now, let's apply this function here as a Lambda function or re transform it. So I'm going to add a comment and say Lambda function. So all you need to do remember again, you need to refer to your Lambda function name. So here we use add numbers for the regular function. We can do the same. You then want to say equals and Lambda. Now what you want to do is right next to Lambda, you want to ensure that you go ahead and add in your parameters. Here we have X and Y, and all we need to do is add a space next to Lambda and say X, Y, and that's your parameters. Then next to that, you want to add in your colon. So it's very similar to what we have here. So we have X, Y, but here we don't have parentheses and we add in the colon at the end, and we do the same thing with our Lambda function. You want to define what you actually want to do in your Lambda function. So in our regular function, we're saying return X plus Y. So here, all we need to do is say what we actually want to do directly. I'll say X plus Y, just like that. Then we're going to say print like we did before, and then you want to pass through your function name. So in our case, it add underscore numbers. And just like when you are sending in your arguments, it's going to be exactly the same sort of style as regular functions. You're going to have your pareneses and in the position or keywords, you put in what you want to return. I'm going to say five and seven. So we've got that in place. So now if we run our code, we get 12. Right, perfect. There we go. So that is how you can utilize a Lambda function, and most importantly, how you can utilize the syntax of regular function to help you to quickly learn Lambda functions and how to utilize them in comparison to the workings of a regular function. Right. Perfect. So we can remove this pen. Alright, so that is the first part in utilizing Lambda functions. We are going to work on a few more extra sort of how can I say activities and exercises. So don't worry. We got more coming up. All right. So now let's work with Lambda, since we are quite confident now with understanding the definition of how we use a syntax and all. So I'm going to work on creating a few programs. So first, noticing to ourselves, Okay, how can I create a small program that will be useful and be quick to solve with a Lambda function that might be tedious with a regular function. So let's say we want to square a number. We need to define the function names. I'm going to say square equals. Then we need to say that this is going to be a Lambda function. We need to decide, I'm going to put in any values. I'm going to put in one value so that would equal one parameter. I can just set the parameter as let's say Num. What do I want to do? Do I want to return something? What I want to do is actually return whatever num multiply it by NUM is. Then I'm going to ensure that I print this out the results. I'll say print and I want to plug in the function name which is square and then put in the argument which is going to be passed to the parameter here as NUM and then I'm going to take that number associated and multiply it by itself. So four times four. Now, if we run the code, we can see if we get 16, and that's exactly how we can square a number with a Lambda function. Right, let's do another one. Let's say we want to double a number. So we would create a function and we can call this double, for example, and this is going to be a Lambda function, so we need to define that accordingly. We are going to take in one parameter here. So I'm going to set this as X, for example. And what do I want to do? I want to return, whatever the result is of X multiplied by two. Okay. Then I want to print this out, I'll say print and I want to print whatever the result is of the function, so I need to call the function for that to occur and then pass through the argument, which will substitute X and then X is going to go and go to the next code within the Lambda function and say X times two. In this case, six times two. Now we can run this code. And we have 12. Perfect. That's doubling a number. Let's change it up. Let's go into the list. Now, let's say we want to get the first element of a list. Let's go ahead and define our function name, you could say. I'm going to set this as, I'd say first equals, that will be my function name. It's going to be a Lambda function. We are going to expect one parameter, so I can just call this LST list, for example, in the colon. And what do I actually want to do? What do I actually want to return? So I want to return the first element in the list. And now remember in PySon list start at zero. So I'll say, Okay, the list here, and I want to look at zero. Okay. Then what I want to do is I want to say print, refer to the first function name, and within parencs I want to define a list as is. I'm going to say within the list ten, 20, 30. Now, what's going to happen is I'm going to pass through this list here, which is right here defined within my excuse me, it's defined here within the argument here. I have ten, 20 and 30, first is going to house all of that. It's going to be passed through to the parameter. This whole list that I've defined within first. Then what's going to happen is we're going to call the list and look for the first item, which will be ten, and that's going to be output. If I run this code, we're going to see it outputs ten. We're just passing through this list as an argument itself within the first function. Okay, so that's how we can do just that. Now, let's say we want to get the second element of a list. In other words, that's going to be zero, one. So we can say second equals Lambda, and we can say list again, colon, and then we can say list, and the result we want to return is the first. It's the second element, technically of the list, but denoted by one. We can say print, pass through the function and the arguments for the function, we're going to set as a single list with items of 15, 21, 87. So it should now print 21, so we'll pass this list here, into the list here as the parameter, and then we're going to query it in the processing and look for the second element, which is going to be 21. So let's run this. And then we get 21. Perfect. Alright, guys. So that is essentially it on introducing ourselves to Lambda functions and how we can use it and most importantly, how we can distinguish it between a regular function. Now, we're not done with Lambda functions, there are a few more embedded functions that I want to use with Lambda functions that are quite popular to many developers, and I want to dive more into Lambda function, so we are going to do just is the general idea of Lambda functions and how you can integrate it. Now you can practice and utilize it to the basics at least so you know how to pass through the parameters, how you can output data and such. That is it for this practical lab exercise. 58. Apply lambda functions to other functions: Hi, everyone, and welcome to the next lesson which is going to be focused on applying Lambda functions to other functions. So we can embed functions within our Lambda functions depending on what we would like to do. But let's take a look. So Lambda functions work well with built in functions such as the map function, and this essentially applies a function to each element in an iterable, hence returning a new iterable with modified values. We also have the filter function and this selects elements from an iterable based on a function that returns either true or false, so we can see a bold situation of two states. Finally, a very popular function to utilize with Lambda is the reduce function. This repeatedly applies a function to combine all elements in an iterable into a single value. So there you have it. So Lambda functions can work with other types of built in functions as well. However, these are the most common ones that most developers would use when they are working with Pison, the map function, the filter function, and the reduced function with a Lambda function, it is typically embedded within it to execute a certain query of code that is added into place. All right, guys. So that's it for the theoretical overview. We are going to now focus on integrating these functions within our Lambda functions and piecing everything together. 59. Embed lambda with other functions - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on utilizing the map filter and reduce functions within the function itself. We're going to integrate everything together. Let's go ahead and get started with the map function. That's the first thing that we're going to want to go ahead and get started with. Let's go ahead and do just that. Now, the first thing that we're going to want to do is to define a list of numbers. I'm going to say numbers. Equals, and I'm going to say one, two, three, four and five. Now, the whole point of us utilizing the map function in this use case is because we want to modify each item in a list and then we want to return a modified list that's going to perform some functionality. So what we can do next is go on a hedge and set up the following. So we're going to go on a hedge and define a variable here. So I'm going to say result equals, and we're going to set that to our map function. And we're going to use map to apply a function to each element in our list, namely one, two, three, four, and five independently each time. And within our map function, we're going to add in the Lambda function. So we're going to say am D and we're going to pass through one parameters. I'll have X, for example. And then the action that I want to perform, I want to multiply each item by two in the list. I'll say X asterisk two or multiply it by two. And to do so, we're going to make use of the numbers list. So we're going to be going to go on ahead and refer to the variable numbers. Okay, so we've got that into place. Perfect. So let me give you a visualization of what's going to happen. So we have one, two, three, four, five. We are now going to apply numbers here to this Lambft function, and essentially, you should see it as one is coming from numbers. So one will substitute X, and then one times two is going to be two, and that will be stored, and processed with our logic here that we have in place with map and Lambda function, and that's going to be stored until we can later on output it into a list. Then we're going to go to the next item in the list, which will be two, two will be from numbers, and then we're going to substitute X was two and then say two times two, and that's going to be four. We do the same thing for the rest of the numbers so that it will eventually be the result of two, four, six, eight, and ten. Then what we want to do is we want to go on a hedge and convert our map object. This is going to be our map object, which we store in the variable result. We can create a variable here now called doubled numbers, and we're going to convert the list of the final result that we get here. The output process result that we get from this functionality. Result now in this case is not a Lambda function like we went ahead and demonstrated or referenced as in the previous hands on activity on Lambda functions because when you're dealing with functions that are embedded with Lambda, such as map reduce and filter, the variable that you assigned to it, such as in this case, result here isn't going to be the function. It's essentially just going to be variable that's going to store. The value that's been processed since everything is executed right here and not in a separate Lambda function. Any case, we'll then store the results here in the list so that we can convert the map object which we have now into a list so we can see the modified values. So to do so we can now say print and refer to doubled numbers. All right, perfect. Now we can run this code, and we can see if we get the output two, four, 6810. Perfect. That is how we can go ahead and set this up as it should. Right. Now, let's go ahead and look at the filter function. So yet again, we're going to have a few numbers. I'll just add let's say an extra number, and we're then going to go ahead and utilize the filter function. Now we plan to use the filter function to keep only even numbers. So let's go ahead now and define a variable, which will be results so we can store the result here that we have of our value here of the filter object. So we're going to store the result of the filter object. And we're going to say filter and embed the Lambda function. And again, we'll have a parameter, which we can call X. What we want to do is we want to use a am defunction to check if each number or X is divisible by two to, in other words, keep only some items from a list. In other words, we should output even numbers. We can go ahead and do so by saying X, and then we can add in our percentage symbol, say two, an equivalent to zero, and we're going to be working with the numbers variable, which is essentially the list that we'll work with. We're going to keep on plugging in here. We're going to grab one. Then we're going to pass substitute one into X and then we're going to go ahead and check here if one is divisb by two, if for some reason, the number is not going to be even, we're just going to omit it from the list that we're going to output and then only save what is going to be even and divisible by two. Okay. After that process, and again, like the map function, we're going to check each item or element you could say each time and then store the necessary results as we go. Then we want to convert our filter object into a list so we can see our filtered values, so we can then find a variable known as even numbers, for example, then use a list to cast results here, that variable. And then what we can do is go ahead and print the filtered list. So we can say print and we can just say even underscore numbers. And that we'll print 24 and six, which is exactly what we want as the result. So that is how we can go on ahead and ensure that we are able to filter so we can only keep some items from our list. Right, perfect. Now, the last function that we want to look at is how we can utilize the reduce function. So essentially, what we want to do is we want to combine all the items that we have into one value, so we are going to sum it up so add it, you could say. And to do so, we need to import the reduced function, and that comes from the funk tools module. So it is built in. So we can say from funk tools, which is the module, I want to import the reduced function. Now, we want to also have a list of numbers that we want to work with. So I'm going to say numbers, and I'm going to have one, two, three, four, and five. Then I am going to ensure that I utilize reduce to sum all the numbers together. And again, we need to have a variable so we can store the result, of course, so it's necessary to call it result. And we can then use the reduce function, which is going to embed Lambda. And again, we're going to have this time two parameters because we're summing, we're adding numbers together. So we'll have X and Y. And then the action that we want to perform and what we want to return is the result of X and Y here. And what are we going to base that off? What are we going to get our information that we want to add from from the numbers variable here, which we can just associate, like so. Okay, so the and function, we'll take in two numbers, X and Y from numbers, and it's going to add them, and then it's going to keep on adding it till we get the final result. So with numbers here, what's going to happen is we're going to go ahead and add the numbers accordingly together till we get that final result. So it's going to be one. So it was X and Y, it will be one plus two equals three. Three plus three equals six, six plus four equals ten, and then ten plus five equals 15. And that's how we will go ahead and see the sequence of operations as we go. Now, the final result, of course, should be 15, but let's go ahead and print the result so that we can clarify. There we go 15 and there we have it. That's how we can combine all the items into one value as a sum example. All right, guys. That's it for this practical lab exercise. I know this might have been a little bit tough, but this is how we can go on ahead and move forward if we want to combine different functions and utilize it with our Lambda function together. Now an important thing that I also want to just reiterate on. Just remember when we are using functions with lamb such as map reduce and filter, previously when we were working with functions, you could dictate and you can refer to what we associate with the Lambda function as the function name, you could say. But in this case here, this is simply just going to be a variable to store the result of what's occurring. Whether that result is going to specifically be a filter object or if it's going to return a specific value of sorts or if it's going to return the map object, that is something that we are utilizing it for, not as a function name. All right. So there we have it. So the last thing I want to mention is just remember as well, one more thing, that when we are working with the map object, we're going to be storing. When we're working the map function, we're storing the map object, when we're working with the filter function, we're storing a filter object and when we're working, of course, with reduce and specifically in this case, the reduced function, we are storing a specific value that we of course are going to be outputting if we want to print it out. Okay, go. That's it. That is how we can integrate other functions with Lambda. 60. What is object oriented programming?: Hi, everyone. Welcome to the next lesson, which is going to be focused on looking at what object oriented programming is. Now, this lesson is going to be part of a series of lessons, so it's all going to be connected together. There will be a little bit spread out throughout the next set of lessons, but just now it's all together and part as one. So object oriented programming is a programming approach that is centered around the concept of classes and objects. So your next question is probably what are classes and objects? So this is what we're going to discuss in detail in the next lesson, which is going to focus on looking at classes and objects from a definition perspective and also from an analogy perspective. Going to differentiate between the two and see overall how this goes in the hand in hand focus of object oriented programming as a whole. So stay tuned for the next lesson, we're going to dive into classes and objects. 61. Classes and objects: Hi, everyone. Welcome to the next lesson, which is going to focus on classes and objects. Let's take a look. What is a class and an object? Simply put, a class is a blueprint for creating an object, while an object is a specific instance of that particular class. Now, I know that might be a bit confusing at first, but let's look at an analogy to better illustrate this. So let's say that we have a person. We can call a person a class. Now, a person has a set of attributes. So a person will, for example, have a first name. They will have a last name. They will have their age, their nationality. So these are seen as attributes in PySon where the person themselves, like the structure, the person is the class. Now we can go a little bit further on that and take a look at objects. Now, objects, like I mentioned, are, of course, the instances themselves. We can, for example, have an object which is going to pertain to one unique person and that unique person, for example, can be called Lucy Johnston, ages 22 and her nationality is German. She's from Germany. Let's say we have another object, another specific instance. So we have another unique person. This person is Mark Smith. He's 21 and he's from Austria. So this is how it all ties in together with the class, the blueprint, the attributes to go ahead and describe this class here, and then the objects which are the specific instances. Let's have a look at another analogy to solidify our understanding of classes and objects. Let's say we have a car. Now the car can be seen as a class and as a blueprint. Now, a car is going to have several attributes such as the brand, the color, the model, the model year, for example, and it's going to have a set of unique instances in terms of the objects. We can have one particular unique car that's the brand of GMC. The color Sage, it's the GMC E two model and the model Y is 2007. Then we also have another specific instance, which is going to be that of a BMW, for example. The color is blue, is the BMWX three, and the model E is 2011. All right. So this is how I want you to understand the process of object oriented programming when we are working with our class, the associated attributes of that class and the objects which are specific instances that are correlated together. Ch. So try to see it all together as Zach. And what I'd also recommend if it's also getting a little bit confusing, just go over it a few more times to the analogies and with the definition that I gave and try to link it together. But don't worry. Once we practice this in the practical lab exercises, you'll see how easily you'll pick up on it. And this is how I want you to see it as we work with object oriented programming and specifically with the classes and the objects at hand. 62. Creating our first class and object - [Lab]: Hi, everyone. Welcome to the next practical lab exercise, which is going to be focused on classes and objects. Let's get started. Now, the first thing that we need to do is we need to define our class. Now, remember, a class is like a blueprint, we going to create a class of a person. I'm going to say class person. Next, we can go to the next line and indent. And the next thing that we're going to want to do is we're going to want to define our innit method. Now, the innit method is essentially a special method, otherwise known as a Dunder method, and it is called when a new object is created, and it helps to initialize the attributes of our object. Now, the attributes include, for example, the person's ID, their first name, their last name, their age, their nationality, et cetera. So what we can do is we can go ahead and say D double underscore init. And within our parenss we need to pass through, first of all, self, and self will represent the instance of our class, and it allows access to instance attributes and mesods if we had any mesods of course, as well. Now, we want to define our parameters. Now, this is going to include, for example, the person's information, so their first name, last name, Asian nationality, et cetera. And we're first going to set it up as parameters, okay? So this is going to be temporary, and then it's going to be assigned as a permanent variable with self, but we'll get to that in a moment. So we can go ahead and define, for example, ID. We'll have first underscore name, we'll have last underscore name, we'll have age and nationality. All right. So let me zoom out here for clarity. And then we just want to add in a colon, and let's continue. Alright. Now the next thing that we're going to want to do is we want to assign our parameters to our instance attributes. So what we're going to do is say self dot ID. Equals ID. So what we're doing right here is we are essentially assigning, for example, the ID parameter to the instance attribute of self dot ID. And this is essentially going to be the unique ID for the person, and we do the same for the rest, the same sort of process. We'll say self dot, first underscore name. That's going to equal first underscore name. Then we'll do self dot, last underscore name, equals last underscore name. And you can see it being set up accordingly as it is being used. Then we can see self dot g equals age. Self dot nationality equals nationality, just like that. We've got that all instantiated. Now, just to give a little bit more clarity here with the self keyword that we're using. Remember, it is a reference to the current instance of this class, and it's going to allow us to access and modify our attributes that are specific to each object that we have. Just remember that. Then when we have here, self dot ID, self dot first name, self, the last name, self dot age, and self nationality. You can see these as attributes, and each attribute is a variable that stores data that is specific to the object. So here, of course, it's going to be the D of the person, their first name, their last name, their age, and their nationality. So that is essentially what we're doing there. Now, the next thing that we need to do is we need to create an instance of our object of the person class. So let's do that. And we need to ensure that we adjust where we're doing this. So it needs to be in the same line as our class here. So let's create an object of the person class. So we can give this variable name anything we want. I'm going to say person one equals, and then we need to reference the person class. And within that class, we essentially are going to go ahead and add in our values or arguments, you could say, of the attributes that we have. Okay, so we can go ahead and put in the value. So first, we'll have ID, first name, last name, age, and nationality. I'm going to pass them over. I'll say one for the ID. Then we have first name. I'll say Ono then we have the last name, I'll say Pretorius and then we're going to have age, LLC, 29, and then we'll have nationality, says of Africa, just like that. So that is how we can create an object of the person class. Then we want to print the person's attributes. So remember, we have our attributes set up accordingly. So ID, first name, last name, age, and nationality. So now we want to print them, so I'll show you how we can do that. We can then, for example, say print then we want to refer to that variable that we set here that's assigned to the following, and we can just say person one and you can just say dot and then followed by the attribute. So we can say ID for now, print person one dot first, underscore name. And print person one dot and we had last underscore name. That's going to go ahead and print out the value that was assigned for our attribute. We have one, we have Arno and Pretors and that's what's going to be printed out in our output. Let's go ahead and output and run this code. Let's do that. There we go, so we get one, we get honor and we get Pretorius. That is how we can go on a hedge and ensure that we have that output as it should be. Let's just make that a bit clearer so you can see, we can see the ideals output, the first name and the last name. That is how we can essentially create our class, how we can define our innit method, set up our parameters, and how we can go on a hedge and set up the rest into place and how our parameters essentially become attributes. All right. That is it for this practical lab exercise, well done on creating your very first class and also defining your very first object here and also outputting all of the necessary data by referencing by saying dot followed by the attribute name and then obtaining all of the data that has been linked to S object. So that's it. I am going to add in an extra practical lab exercise here, which is more going to be focused on explanation. So I'm just going to explain a little bit more, and we can do a little bit practice, a little bit more practice as well. So you can stay tuned for that next exercise, or you can move on to the next lesson. It's really up to you as to what you want to do. But that is it, I will say, for this particular lab exercise. 63. Deep-dive on classes and objects - [Optional lab]: Hi, everyone. And welcome to the next practical lab exercise, which essentially is going to be an optional one as well. So if you want to skip a hedge you're more than welcome to do so and head on to the next lesson. Otherwise, what we're going to be doing is we're just going to be continuing with classes and objects in more detail. Right, so I want to mention a little bit more about parameters and attributes. So we can see the important fields that we've defined that we want to utilize, such as ID, first name, last name, age, nationality. Now, in this, how can I say, in the parentheses here of the int method, these are seen as our parameters, and they only exist inside this int method temporarily. Then utilizing self dot. What we're doing here essentially is we are setting up our attributes such as ID, firstname, last name age and nationality by saying self dot and then referring accordingly to nationality age, last name, first name and ID, and these belong to the object and can be accessed later. Our attributes belong to our object and can be accessed later. Then of course, as we know, we are creating an object, also known as creating our instance. And what we're doing here afterwards with our print statements here is that we are accessing our attributes because they are now stated in our object. Another thing also to mention here with the parameters that we've defined here is that they do not exist outside of our innit method. Only our attributes, which we've defined will remain and will be callable outside of our class. So just something that I wanted to mention so that you're aware with what we are setting up. Okay, and a final thing, just know that our parameters here, again, are temporary and they exist only while innit runs, and our attributes, which we defined using self dot, they are permanent and they'll live within our object. All right. So that's all I wanted to go on ahead and mention so that you have a deeper understanding of how we can utilize both options. All right. Now the next thing we're going to do is just do another practical exercise. So I'm just going to show you how we can create another class, so we just get more practice with it. All right, so let's go ahead and get some more practice. So now we want to define another class, set up our attributes, create our object, et cetera. So I'm going to delete this and let's get started. So I want to say class, and we're going to work with a car, for example. Then we want to go ahead and set up our innit message. I'll say de double underscore init, pass through self, and then what we're going to be working with and what we want ultimately as our attributes in the end. So we'll have brand, model year, and color. At the colon. Then we have defined our parameters which are temporary. Now we want to set up our attributes, which will be stored in our object. So to help us, we will utilize self and say self dot brand, equals brand. Then we'll have self dot model, equals model, self dot here equals here, and self dot color equals color. There we go. So we've defined that accordingly. Now we want to create our object or our instance of our car class, and we need to make sure we do this in line with our class, and not within this init method. So I want to make sure I'm in line with class here. Then what I'm going to do is a car one, for example, set a variable. Then I'm going to create this object of my car class. I want to refer to the class, then I can pass through the values. Here I'm going to say, for example, Ty Yota. Then I'm going to have Cola and then I can say 2021. And we can see blue. You can see that that matches. First, of course, we can see we have brand, so that will be Toyota, Corolla, we'll have model, year 2021 and color blue. We've got that all defined. Now we want to access the attributes of our object. I'm going to scroll down now and let me actually zoom out here. And let's say print, and we want to refer to that variable. So we'll say car one dot, and we can just refer to the attribute, which will be brand. Then we can say print car one dot, and then we can say model, print car one dot, and we will have, and then print car one dot, and that will be color. So we'll eventually be outputting the values that we have here. Dot brand will be Toyota, dot model will be Corla, dot will be 2021, and dot color will be blue. Let's go ahead and run this code. And here we can see we get the following result here as expected. All right. So that is how we can go on ahead and work with our classes, our objects, parameters, and our attributes, and how we can put that all together. But ultimately, this was mainly focused on classes and objects. All right, guys. So that's it. I saw I'll just go a little bit extra so we can get some more practice and such, but that will be it for this particular lab exercise, so we can just move that and that's it. 64. Custom methods: Hi, everyone, and welcome to the next lesson, which is going to be focused on custom method. Let's take a look. The programj what is a custom method? Simply put, it involves methods which we can define ourselves within a class to determine the actions that its objects can perform. So if we were to take an analogy, let's utilize one that we were working with earlier on. So we previously created a class that was based on the person blueprint. The attributes that we have, of course, would include ID, first name, last name, age, nationality, and with our objects, for example, we can create as many objects as we want. But, for example, here we have two objects, and they pertain to each unique person. What we can also do is to these objects, we can add in method. So in this case, appropriate methods would include, for a person class, eat, study, and sleep. For example, if you had a car class, it would probably make sense to have methods like service car, drive car, mileage or some sort of method or action, should I say. In any case, you could treat the message as an action that you can include in the use case for the nature of your class and its associated objects that you create. All right. So that's it for the theoretical overview. We are now going to head on over and work in the lab exercises and apply this logic to a given class. 65. Integrating custom (Instance) methods - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on utilizing custom methods with our classes and objects. Let's get started with the basics first with defining our class, setting up our structure, and then creating our object. We're going to choose a more familiar example just so that we can ease into the idea of custom methods a lot easier. So first of all, let's define our class. So we're going to use person again. Then what we want to do is go on ahead and define our init method along with the parameters that are required. Then we're going to say defunds init, followed by a double underscore again. Then we need to pass through self, then ID. First underscore name, last underscore name and then we'll have age and nationality. Let's just zoom out here and in our k at the end. All right. Now we can use self to store the values in our object. So now we want to set up our attributes. So I'm going to say self dot ID equals ID, self dot, first underscore name equals first underscore name, then self dot, last underscore name equals last underscore name. Then self dot age equals age and self dot nationality equals nationality. Perfect. We've got that setup. Now, outside of our method here in line with our class, we need to create our object. I'm going to say person one equals, then refer to the person class. Then I can pass through my values. I'll have one. John, then Doe, then age 28 and nationality, we can just say USA. Okay, there we have it. So we have everything defined. There's ID, first name, last name, age, and nationality. Now, let's go ahead and print these values according to the attributes that we reference. So what I'm going to do is scroll down a bit and we can say print. Refer to person one, dot, and then that's attribute. We will have, of course, first underscore name, and then we can say print person one, dot, and we can say nationality, for example. Now we can go ahead and run this code. There we go at outputs, as we can see John and USA. We've got our basic class defined. We've created an object as well and output the values that we want according to the attribute that's been defined, and it's grab the values from first name and from nationality accordingly. Perfect. Custom message time. Make sure you've got this in place and that you've understood it. We had lots of practice now with classes and objects. Now let's apply the message. For the time being, we can just remove the print statement and now let's go ahead and define our mesods. Right. Let's continue. Now, when you are setting up your methods, they need to be in line with your innit mesod. It's going to be within your class in line with the innit message. As you can see here, there is a line with indentation. I would need to do the following. Be in line with your init method, and then you can define your method. I'm going to say death and I'm going to call this introduce. I'll be an introduction mesod you could say. Then I need to pass in self here as the parameter. And we're using self so that we can access our stored attributes. So we have, as you can see, first name, last name, age and nationality. And what we want to do next is go ahead and set up a simple print statement that's just going to say hello. My name is colon space, and then I'm going to use string concatenation, because we are going to be dealing with a string value. So I'm going to say self dot first underscore name. Right. That is how we can define a method simple as that. Now self dot Fn is going to look for the attribute and the value that has been set up for the object that is linked to that attribute. In this case, it's going to be John is going to be output in the end. Now, all we want to do now is call that method. Now that method is called introduce we're going to apply it to person one, which of course is set to this particular This is set as an object with the value of John as the first name. So that's how we'll be able to say Seles first name, and it's going to be linked to this object here that we're creating and that object that we've created first name attribute, which is John. So to do that, we need to invoke it, and to invoke this function, you can just go ahead and say person one. Dot and intro juice, opening and closing parencs. And here, what's going to happen is we're going to use self access our first name, and this is going to print out this statement since we are calling this mesod. And what we can do now is go ahead and run the code. And it says, Hello, my name is John. Okay, so it's simple like that. So that is how we can simply go ahead and create a method. All right. Now let's go ahead and create another method. I want to create one that says happy birthday. We can see John Doe is currently 28, so I need to create a new method. Let me scroll down. I'm going to say this one will be DF and it will be have underscore birthday the mess a name. I'm going to pass through self so we can access the attributes, and then we need to add in some functionality. So we can say self dot age plus equals one, and that's going to update the age attribute that's stored in the object and add one to it. John will then be 29 technically. So now let's go ahead and print this out though. I'm going to say print. Happy birth day, and I'm going to say comma space, string concatenation. I'm going to say self, and I'm going to say self dot first underscore name. So it says happy birthday. And I'm also going to go ahead and say, at the end here, I'll say you are now. And then what I want to do is I want to go ahead and cast because remember, the g here is treated as an integer, so I need to cast it to a string here, and that is since we're using some string concatenation. I want to say string. We need to say plus here. And it's going to be self dot H. And that's going to say are now. And the reason I add in the plus here is because we're using string concatenation and we are going to cast to a string. Okay? And that will work. If I didn't add in the plus, then it's going to get an error, so we need to make sure that we added in as follows here. Now I can just call that message so I can then say person one dot and it is have underscore birthday, and we can open and close the pareneses that's going to say, happy birthday, John, you are now and it's going to go on a hedge and get the age and remember we're adding it plus one, so it's going to get the age and add plus one to it, so it'll be 29, it should print out that full structure. Now if I run the code, we can now see that we have it as follows. It looks a bit ugly because I didn't add the space. I can just add the space there. There we go. There we go a lot cleaner now. You can now see that it says, Hello, my name is John. Happy birthday, John, you are now 29. Right. So that is how we can create and utilize methods within our classes and our objects and also how we can call message. So remember, it would depend on the use case that you are using. So here's the full code so you can see. So it'll depend on the use case that you're utilizing and the message would be appropriate based on that. So in this case, here, we had introduce and have birthday as our message because that is appropriate to a person to introduce a person and to say happy birthday to the person as well. Right. That is it for this particular lab exercise. I am going to add in another lab exercise which is going to be focused on methods, but a little bit more detail and we'll get into that in the next practical lab exercise. But this is the basics for utilizing custom methods. 66. Working with static & class methods - [Lab]: Hi, everyone. Welcome to the next practical lab exercise, which is going to continue to focus on methods. Now, something I want to mention is that earlier on we were learning how to utilize custom methods. These are otherwise known in the sphere of classes and objects as instance methods, since we are working with self to work with our objects attributes. Now there are also two other methods that we get. These are known as static methods and also class methods. We're also going to work and emphasize on that as well. Right, so let's get started with static methods. Okay. So a static method does not use self because it does not interact with our objects attributes, and it behaves very similarly to a regular function, you could say, but it is inside our class just to be better organized. And we can call it without having to create an object. So let's go ahead and create a simple static method. Right. Okay. So here we have our custom methods introduced and have birthday, otherwise, commonly referred to as instance methods. Let's define a static method and it's going to have a decorator upon it as well. We need to be inside our class, of course, and in line yet again with our init method, and we need to ensure that we are set like so. We need to add some space. And I'm going to create a static message that's going to check if the person is an adult or not. So I'm going to say death is underscore adult. And what we can do is go ahead and pass through the attribute directly itself, which is going to be age. So we can just say age as is. And remember, we do not use self, okay? And this is going to ensure that we will have access to the attributes in a direct fashion. Okay. Now, after we've gone ahead and defined that, we need to add in our Cerlon and then we want to perform the functionality. So we're going to say I age greater equals to 18, then we can say return true, else, return false. And remember, to make this a static mesod at the end, you need to add in the decorator, which is at static method. And now we have now set up our very first static method. Okay. Now, another thing I wanted to mention here about the static method that we've created is that it belongs to the class but doesn't access our instant attributes. Okay? So just something that I want to mention. And what we simply doing here is we're passing through age, and we're going to check if the person is an adult based on their age. So now we can call this method is adult and we can apply this on to a particular class. And in our case, our class is person. So we can scroll down. Okay, adding some space. Now what we want to do is we want to say print and we're going to call the static mesod and we're going to refer to the person class, and you want to say dot is underscore adult and we're calling the static message here as you can see, then here we can pass in a particular value. So here I'm going to say 25, for example, and it's going to check if the person is an adult or not. So we can run this code. And here we can see it says true here at the bottom. If I go up here, we can see that has been the output as true. Okay. And let's go ahead and do another one. Let's say person is adult, and let me put in 17. And we can see we get false here at the bottom, right? So that is how we can go on a hedge and call our static method and how we can sit it. So it was just a very simple explicit I check that we utilized. Okay. So that's just something that I wanted to mention just for clarity. Okay. Now, the next thing that we want to look at is a class method. Okay, so we have our static method. Now, a class method works with the class itself, okay, not with an individual object, you could say. And it uses CLS instead of self to refer to our class, and we can use it to create our objects in a different way. In other words, what we can actually do is add in default values. So it's very similar in a way if you're following along to default arguments in a sense, and you'll see what I mean in just a moment. Okay? So let's first of all, define a class method. I'm going to create it just below here, static method. And what we're going to do is we can start with the decorator, and I'm going to go ahead and say class method. Okay. And we can then say death. And I'm here. I'm going to specify the method name as WIS, underscore default, underscore nationality. Okay. And what we want to do then is pass through CLS, as the first thing. And remember, CLS refers to the class object to the class itself, and we're creating a new object with it. Okay. And essentially what we want to ensure is that instead of asking for a nationality, it's automatically going to set it to a specific value which will set as unknown. Okay. So what we then going to pass through is we're going to go on a hedge and pass through our fields. So we'll have ID. We'll have first underscore name. We're going to have last underscore name, and we will have age omitting, of course, nationality for now. Then what we want to do is we want to, like I mentioned, create a person with unknown as the nationality. I can say return CLS, and then we are going to return ID, first underscore name, last underscore name, age, and then for the nationality block we can put in unknown if there isn't a particular value that has been added in. Now what we can do is we can create an object using our class message. So this is going to be very specific. So for now, I'm going to remove this for now, and you'll see here, I'll call this person two equals, and we're going to say person dot. And we're going to utilize this class message. So here I'll say W underscore default underscore nationality. Okay. And within that, I'm going to pass through my values. Here I'll set ideas two, name, I'll say Jane Smith, I'll say 24. You're going to see I will omit the nationality now. So let me go ahead and run this accordingly and check the results. I'll say print, refer to person two, the variable, say dot, and then I'm going to simply say first underscore name, and I say print person two, and it's just what's that here, Dot and I'm going to say nality. Now you can see I didn't put in a particular nationality, so it's going to revert to the output. Now let's run this. And here we have Jane and unknown. And as you can see, that is the case when I went ahead and referred to the nationality attribute, but I didn't set a value here, so it went and changed this mesod. And as you can see here, I am returning the first name, last name, age, ID, but I'm leaving the nationality as unknown here. Okay? So this can be very useful class message, and in this case, we wanted another way to create an object. So this is another way in which you can create an object. And for example, if you want to set a default value, if a user doesn't provide a certain value itself, such as the nationality, as you can see, Okay. And this is very helpful if we want to modify our class level attributes themselves. All right. So this is the simple ways in which you can use your static methods and also your class methods themselves. Okay. Now, the last thing that I'm going to, of course, do is I just want to have another sort of deep dive in this particular exercise. I'm just going to spend some time explaining more about the static method and the class message just a little bit more detail just to solidify your knowledge so you learn properly, should I say? So we're going to go and explore a little bit more into that. Right. So the next thing that I want to explain is here with our static method, we have age. Now, age here is just acting as a normal parameter, and we are passing in as we did before that particular value. So if I were to go ahead and reiterate, if I say print, I'm going to go ahead and refer to it accordingly by saying person dot is underscore adult, and we're going to put in, for example, 19. To run the code, and we have here true. Essentially, it's very similar to how we would have functions, but you could treat the static method as a function within a class, you could say in terms of its organization. We're calling here the static method and we're just returning the argument or value you could say, which is going to be passed here and substituted for age here, which is acting as the parameter which we are in fact checking. That's just something I wanted to mention for clarity here. Trying to see static methods is functions that are just defined inside a class. That's how I want you to see it. Okay. Now, the person dot p here. So person is actually that kind of touch that I mentioned is because this is kind of a function because this is a function within a class here, and we are referring to the class. That's how we would need to refer to it first. We refer to the class first, and then of course, the mesodname. Okay, now, a bit more clarity on the class method here. So essentially, what is going on here with our class method, of course, in this case, we are using CLS instead of self is what we are doing here, and that refers to the person class itself. And then ID first name, last name H is essentially just the parameters that we need to create a person. As we can see, nationality is not passed because we want to set it unknown by default when we are performing the return statement. Okay? Right. As we can see afterwards, we returning CLS, what we are essentially doing here is we are going ahead and calling the constructor class, which is def init here, and it's going to assist us to create a new person object with the given details and essentially those details we can see we add in here when we are calling the class mesod and in the functionality on the default, the nationality is going to be set to unknown, so we don't need to worry about having to set an extra value that we want to pass in when we are setting up the parameters here accordingly. All right guys. Just a little bit more detail on that, just to explain a little bit more. But in other words, guys, that I would say, is it. We've learned now how to use custom methods, in other words, instance methods, static methods, and also how to utilize class methods as well. That is it for this particular lecture, and we're going to then focus in the next lesson on inheritance. 67. What is inheritance?: Hi, everyone, and welcome to the next lesson, which is going to be focused on inheritance. So let's take a look. Rich. Inheritance allows us to create a child class that inherits all of the attributes and methods from a parent class. So let's take a look at this visually. So we have a parent class, and then we have two child classes, for example, and those child classes are essentially going to inherit both attributes and methods from that parent class. Now let's take a look at an analogy to cement our knowledge on inheritance. So let's say we have a parent. So let's say we have a mother and she has two children. Now, we could say that with genetics and with reproduction and all that the children will inherit, for example, let's say blonde hair and green eyes. Let's say the child, the male inherits the blond hair, and the female, the girl inherits green eyes. So this is inheritance. Let's say that the parent or the mother also teaches them how to talk and how to walk. So the children are now inheriting those methods of talking and walking. And that would solidify the whole concept between inheritance in Python. So we would have the parent class and we would have the child classes. All right, guys. So that is it on inheritance in terms of the theoretical overview. We're now going to dive in into the practical lab exercise. 68. Utilising Inheritance - [Lab]: Everyone, and welcome to the next practical lab exercise, which is going to be focused on inheritance. Let's get started. The first thing that we need to do is create our parent class or base class, you could say. Let's go ahead and utilize an example that we are already familiar with just to ease us into the whole concept of inheritance. Right. First of all, I'll define my class as person. Then we want to define our innit method, otherwise known as a constructor method, and this is going to be called once a new person object is created, and it is then going to initialized attributes and instance variables of our class. So we can say De underscore init, double underscore. Then we're going to pass through self IGF underscore name, last underscore name, age, and nationality. Great. Right now we want to define and associate our attribute. So ID, first name, last name age and nationality with self. So I can say self dot ID equals ID. Then I can say self dot first underscore name, and that's going to be first underscore name, self dot last name. Okay, and then self dot g and self dot nationality. Right, perfect. Great. Now, what I also want to do is also create a message so that you know how you can inherit messages as well along with attributes. Right, so in line with your init message, I'm going to say death and again, introduce. Going to pass through self cut on. And remember these custom methods that we are creating are instance message. So when we're dealing with self, it's going to be an instance method. So you could technically say custom method. Right. So this instance mesod is going to allow the person to introduce themselves, and we want to return a string with the person's name, with the person's name it's perfectly fine. So we can say return. And we're going to use F strings this time just to change it up a bit, and I'm going to say hi. I am, and then I'm just going to put in my placeholders for the strings of self first underscore name, and then we will have self dot last underscore name, just like that. And at the end. There we have it. There is our method as well binded to this particular class. I just want to. There we go. Let's make it a bit cleaner. All right, so we've got that set. Now, the next thing we want to do is define our child class. So here we have our person class, and that child class is going to be the derived class from essentially the person class, okay. And it's going to inherit all of the existing attributes and all of the existing methods. So we can see our attributes here, and we can see this method introduced. Okay, so when you are working with inheritance, you're going to inherit from your parent class, and it needs to be something that makes sense. So you can't have, for example, a child class that is car, and you have a parent class in place that is person. It doesn't make sense. Person and car. It's a little bit confusing. So a suitable example in this case would be employee. So employee is derived from the person class. That makes sense. So let's go ahead and do that. Now, we're going to have to define another class now. So in line with the person class, we want to create another class. So I'll scroll down and say class. And this is going to be called employee, which is going to inherit all the attributes and all the methods from person. And we can just refer to the person class right here in parentheses to perform inheritance. And then we want to go ahead and close such, and then we need to define our init method, this is going to extend the person class, and we're also going to add in new attributes as well. It's going to retain all the attributes and mesods of the person class, and we're also going to add additional attributes. Let me show you what I mean. We can say Def, and we can say double underscore init, double underscore, and we'll say self. To make this easier, we can just go ahead and copy everything that already exists here. And you want to paste that in. Then you can add in additional attributes. For example, what I'm going to do is say job underscore title and salary, remember to add in a colon at the end there. Here are going to be the extra attributes that we add in. Okay. Great. Now we can go enter and continue. And now what we need to do is we want to utilize something known as the super function. Okay. Now, the super function is used to call the constructor of our parent class person. So this is going to be, of course, our constructor here. And what we're going to do is we're going to ensure we do so, so we don't need to redefine the attributes that already exist in person. We don't want to redefine this we're going to call our constructor of our parent class, which of course will be person. And then what we can do here is we can go on a hedge and ensure that we say super opening and closing princes, and you want to say dot double underscore in KIT, double underscore. And then what you're going to do here is you're going to pass through ID, first underscore name, last underscore name, age, and nationality. So this is going to be the inherited attributes from person. This is where you're inheriting the attributes. And then we want to define our new attributes that are specific to the employee class. And that's going to follow what we did here before with self dot, self dot, et cetera. And that's going to be, as you can see, for job title and salary. So you can see they haven't been highlighted. So what you can do is below that, you can say self, and we can say dot, and you're going to say job underscore title, equals job underscore title, and then self dot, salary equals salary, just like that. So we've now gone ahead and defined our attributes that are unique to this employee class. Right now we can go ahead and define a function that is only for the employee class. Here in line with your init method, what you can do is a depth work underscore info, and you want to pass through self, and we're going to go ahead and provide this method so it can give us job related information about the employee, and we're going to return a string stating their job title. So I'm just going to say return, and we're going to go ahead and utilize an F strings, I'll say F, and I'm going to say I work as A, and then for the parameter to be passed, self dot job, underscore title, and dot there. All right, so there we have it. So there is the message that only pertains to the employee. Right. So we've got that now we can go ahead and create an instance or object of employee. So let's do that. Again, this is going to be in line of the class here on the first line. So just like that so we can see it's in line as it should be. I just want to add in some space. Okay. Now we can just create a variable and call this employee one equals. We want to call and utilize the employee class. Which inherited person and all of the attributes. So now we can pass through the values, okay, which pertain to ID first name, last name, age, and nationality, along with ID, job title and salary as well. So what I'm going to do is I'm going to open my prenses and I'm going to say ID will be one. Name John Joe, and then we'll have age. I'll say 28 and I'll say nationality, it will be USA, and then we would have the job title. I'll say software engineer, and then I'm going to set the salary. I'll say 80,000. There we go. We have that all in place. So, you can see the extra values that will be set to the associated attributes and then all of the values that are going to be set for the attributes that have been defined in the class person. Okay. So here we have that object and we can see we inherited the first few and we have the last that are native to inherit our class that's going to inherit from person, so employee. Now what we can do is say print and we can say employee one and we can say first name, that will be from the parent class essentially and then we can say print, employee one dot, and here we can say job underscore title. That is going to be native to the employee class. Right, so let's go ahead and run this code. Then we get John, and of course, we get software engineer. So there we go. So well done if you got to this point, you successfully set up inheritance and configured it nicely. Now we want to call the methods that we defined. So the first method, which is going to be introduced from the class person, and then the work info method from the employee class. So what we can do down here, is we can just say print, and you're going to say employee one, dot, and you can say introduce, and then print employee one dot, and you can say work, underscore, info, opening, closing parencs. Right, so there we have that, and I'm just going to comment out the first two for now. And we can run the code. Here, it says, Hi, I'm John Doe. I work as a software engineer. The first method has been called. Hi, I'm John Doe, and then I work as a software engineer, which comes from the work info method that we defined. We can see by referring to the variable there that is essentially creating that object. We can refer to it and then call those methods that are unique to each class and we can see we've inherited the method from the person class that is because we can access it and make use of this function accordingly. Alright, guys, so there you go. So as you can see, this shows how you can utilize inheritance, and it's also very helpful, as you can see, you don't need to rebuild the will and define separate classes and all. You can really save yourself a lot of time by utilizing this super function that we have here to automatically configure the attributes for us from the previous class that we have and then to go on a head and essentially allow us to assign our own attributes that are dependent on the newer class, which is native to that class only. Okay. Perfect. All right guys. That is it. Let's go ahead and remove this. That is all for this particular practical lab exercise on inheritance. 69. Abstraction: Hi, everyone, and welcome to the next lesson, which is going to be focused on abstraction. Let's take a look. You're probably wondering what on earth is abstraction. Abstraction is simply the process of hiding unnecessary details and showing only the important parts. This helps to simplify complex systems by focusing on what something does rather than how it works. Now, if we were to utilize this in OOP, object oriented programming, abstraction is simply going to mean creating simple user friendly interfaces while hiding all of the complex implementation details. Now, if I were to give you a simple analogy to help illustrate my point on abstraction, it would be one as simple as this. Let's say we have a TV remote and we want to watch TV. Now, in order to change the channel, we would need to click on the remote, and then that is going to send a signal to the TV to say, Okay, I want you to go to this channel. I want you to go to that channel. And that is how I want you to try and rationalize the whole point of abstraction. So to sum that up, basically, we don't need to understand or know about how the remote changes the channel or why. We just want to watch TV. Now, if we were to apply this to abstraction, the whole idea is that we don't need to understand how something works internally, just like an abstraction. We just use it to get the result that we want. All right. All right, guys. So that is it on the lesson of abstraction in terms of a theoretical overview. We are going to dive deeper into applying it to the practical lab exercises. So let's go ahead and get straight into that. 70. Working with abstraction - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on abstraction. Let's get started. Now, the first thing we need to do is we need to call the ABC module. And from the ABC module, we're going to import ABC and caps, which stands for the abstract base class. So we're going to use an abstract base class and also the associated abstract method. Now, to import an abstract method, you need to just add in a comma and say Appstrct mesode just like that. Okay, perfect. Now we want to create an abstract class. Now, I'm going to say class and I'll refer to this as person. Then within the parentheses, you want to pass through ABC, which stands for abstract base class. Now, the key thing here with abstraction is if you deem a class to be an abstract class, it cannot be instantiated. In other words, you cannot create an instance here. You cannot create any objects. That is the key thing here that I'm also going to test near the end of this lab exercise to prove to you what I mean by this. Right. Now, since we're creating a class, we're going to do the same thing as before. We're going to define our init method with our parameters and then set up and store our more permanent variables which are, of course, going to be attributes. So I'm going to say Deere inner score, we'll pass through self, name and age. Then we want to say self dot name equals name and self age equals age. Very simple. Then in the same line, we want to define our abstract method. Now I wondering what is an abstract method? The abstract method is essentially a method which is going to be utilized as a decorator and be attached to a particular method and it's going to enforce that all subclasses or child classes, should I say, must implement said method. It is a mandatory method that you set for all of your sub or child classes. What I'm going to do is say DF and I'm going to say job underscore description is going to be my abstract mesod and we're going to pass through self. What you need to do is right above it, you need to add in your decorator and say app abstract method. That is based on what we imported here from the ABC module. Right, perfect. Now, this method, like I mentioned, must be implemented by all of our classes, and we're not going to define how it's used. We're just going to make it mandatory. In each class that we now create, the subclasses that we create, okay? Essentially, what's going to happen is we can add in our own functionality to it, but the method itself, needs to be utilized. That's really the key thing here with abstract methods. Now, as you can see here, I have a red line and this means, of course, we're going to get an error. We cannot just leave this method empty. What you're going to want to do is pass through the pass keyword, quite ironic, actually, just so that there's no error and this means that there's no implementation in our abstract class. Right now the next thing we want to do is we want to define a regular message here. So one that we can call and utilize, which we will, but it's not going to have any sort of strict notion on it in terms of abstract message. So it's going to be very simple and I'm just going to say de and I'm going to say introduce as the name of the mesod. We want to pass through self, and we're going to put in a fixed sort of statement. I'll say return F, and I'm going to say here is my string, my name is and zen parentheses, I'm going to say self dot name. And I am and we can say self age we can pass through years old. Let me some out here. This is going to be a standardized method which we're going to utilize when we invoke our created objects in our subclasses. Okay. Right now in the same line here as class person, we want to define our first child or subclass. So what I'm going to do is go ahead and say class, and I'm going to call this teacher, and this is going to inherit the abstract class known as person now. So we're performing some inheritance now and I'm going to go ahead and say person. Come on. And then like before, we need to define our innit message, pass through self, name age, and then we can put something unique to this class, which will be subject. So name and age are going to be inherited from the person class. Okay, now what we want to do is we want to go ahead and call the person constructor. So we want to ensure that we call this. And what we're going to do to do that is utilize Super, and then we can say super dot blond score, D blond score. And then we're going to pass through here in parentheses what we're going to inherit. So we'll inherit name and age. Okay? And you're going to see here that subject is native to the teacher class. Right. Now we can just say self dot subject equals subject. So just regular defiance here, regularly defining, should I say the attribute that's native to this class. A. Next thing you want to do is now go ahead and call that abstract method that we defined here that we need to utilize, and we're also going to go ahead and define it ourselves in this case. So what I'm going to do here is say def, job underscore description through self. Now we can go ahead and add in our own specific job description, for example, for a teacher. I'm going to go ahead and say return, use S strings, I'm going to say I teach self dot subject at a school. Very simple. Right, there we go. So we got that set. Now we can go ahead and create our second class here. So we have class teacher and let's create another one class, and we can go ahead and call this doctor, for example. So you can see the pattern here, we have people or persons, and then we have job roles that we're analyzing with subclasses. Now, we want to pass through and inherit all of the attributes from person, namely name and age. So we can pass that through like so. And then we want to define our innit method. Let's just see the structure. Yeah, we add space there. Say, Def, double underscore, nit, double underscore, and we're going to have self name and age still, but what will be unique to this particular class will be spect. There we go. And then we'll pause Superterscore, NTblescore. So we can grab in and inherit the name and age accordingly that we have set in our person class, just like we did with the teacher class. Okay. Right. Now we want to store the doctor speciality as an attribute, so we can say self dot, spatiality equals spatiality. Okay, there we go. So we've got that set now in the same line. We need to refer to the method job description. So I can say def job underscore description. All through yourself. And what do we want to do here? We can say return F. I'm going to say, I am a doctor specialized in and we can say here in our placeholders self dot speciality. Just like that, and we're going to put it dot at the end. So that is how we can call this description. Alright, so there we have it. So make sure you've added in everything as follows. So we've now gone ahead and added everything nicely. I'm also just going to tidy up the code, make it a little bit cleaner. All right, so that is what we need to get everything started. All right. So let's continue and let's perform some tests so that we can really understand the value of abstract classes and how everything is working together. So let's go ahead and I'm going to dive quite deep in this. So let's get to it. Alright. So at the bottom now, we can just refer to our two classes. So we have teacher and we have doctor, so our subclasses, should I say? I'm going to create instances and I'm going to test them. I'm going to say teacher one equals, teacher, that's the name of the class and I want to pass through the values that I'm going to set as my attributes. Here I'll have Ale, and then I'll have 28, and then I'm going to say Msmatics. Then I'll have doctor one that links to the doctor subclass. Here I'm going to put in Bob and he is 31 and he's just a GP, a general practitioner. Okay. So now what I want to do is I want to go ahead and print according to that introduction method that I defined before. And what I want to do is I want to see how it gets applied to the teacher and to the doctor. So what I can do is say print and we can refer to teacher that teacher instance dot intro DoS Then I can do the same and say print, doctor one introduce. Let's go ahead and run this you get My name is Alis and I'm 28-years-old. My name is Bob and I'm 31-year-old. So essentially what happened here is we called this introduce method, which is going to expect you to grab in the name and age wherever you went on ahead and defined it. Now, we went ahead and set up our values here in this instance that we set up. Then we teach one and doctor one. Then applied this particular method to each of those objects and then ran that function to collect according to the values that were set in this particular object, namely the name and the age of them. That's a very helpful way in which you can grab in your introduced method. Okay? Right, perfect. Now the next thing I want to show you is the job description part. So let's go ahead and see that. So now I want to call my abstract method, which I have utilized in both my doctor and teacher class. So we can just say print. And again, we want to refer to our instances. So teacher one, dot, job underscore description, opening and clothing parenses. Then I want to say print, doctor one dot, job underscore description. And we can comment these out just for the meantime. And run. I teach mathematics at a school. I am a doctor specialized in GP, so general practitioning, et cetera. All right, so there we have it. So we can now see that it's outputting what we need, as you can see now. Right. That is how we can utilize abstraction. Now, I'm going to go in a little bit more detail so we can just understand the whole point of what we're doing here. Let's start it up at the top here. The person class is an abstract class, so that means we cannot directly instantiate it. What I mean by that is you cannot create an object of person. I'll show you what I mean. Here we're creating objects of the teacher and the doctor. If I were to say person one equals and I say person and I were to put in what values that we have here, we had name and age. I'll say John and 24. You're going to notice if I were to go ahead and say print person one dot name, you'll see we'll get an error now. I just want to comment out this for now. And run the code. You can see here we get a trace back where it says you can't instantiate abstract class person without an implementation for the abstract method, which is job description. This is what we utilize before we utilize our job description here, an abstract method, so we could essentially go ahead and utilize it in our subclasses. You cannot create an instance, as you can see of an abstract method. If I were to remove this abstract method and just keep it as a regular class, or if it were a subclass, it would be perfectly fine. This is one of the key things here that I want to mention here with abstraction here. You cannot go ahead and just do such a thing. Now, another thing that I want to mention here is that as you can see, we mandatory need to use job description here. These two methods. Now, the good thing here about having job description in both these methods and utilizing the abstract method here is that it enforces structure with our child slash sub classes. It's telling us that they must implement these methods. As you can see. Now, if you were to omit, for example, the methods in your classes, you're going to run into an error. So just keep that in mind. You have to ensure that you have these abstract classes you referred to within your subclasses. Okay, so that is very important to keep that in mind. Now, another thing that you're probably wondering is, why is this whole process abstraction? Where do you actually see it? Other than the fact that with the class person here, just going on a hedge and throwing an arrow if you try to instantiate a class, why is this abstraction? Now, a thing to keep in mind here is that the user does not need to know how the job description works internally. Okay? So this is where the point I was trying to make in the theoretical lessons is that your user doesn't need to know how the job description works internally. Okay? So as you can see here, we're passing we're not passing any information or functionality. We're just saying, I want a job description, teacher class, doctor class, do it yourselves. Okay? And this is the point that I was trying to make the analogy with the TV remote and the TV here, okay? You don't need to know the extra details and everything. So you can see an abstract class tries to make everything a lot easier to manage without all the extra details. So you can see it simplifying it for us by utilizing an abstract method. All right. Now, another thing I also want to mention that's important is our users, of course, when we are defining our objects here and creating the instances, should I say? They are only going to interact with our introduce method, and our job description method here without having to worry about all those implementation details. You can see even here for the introduce method. We have gone ahead and set it up here already. It's not using an abstract method, but we have already added it into an abstract class, which you could be seen as a starter code or code that is formatted to get you ready without having to do it yourself. You can see here, we didn't have to put this manually in each of these classes. They were already done for us. Again, to sum up abstraction. Hiding complexity while enforcing a very clean structure. Okay. Right. Okay, guys, so that is it in terms of how you can utilize abstraction in PySon. All right, so what we can do now is we can go ahead and copy this and take it off. And there we have it. 71. Collections: Hi, everyone, and welcome to the next lesson, which is going to be focused on collections. So let's take a look. You're probably wondering, what on earth are collections? The module provides access to specialized data types in PySon. You could see collections as a particular module, and that's going to allow you to access these specialized data types. Now, unlike the built in data types that we're already familiar with, such as SDR for string, It bull list set, and dit, these must be imported before use, and they are going to, in turn, offer enhance functionality beyond our standard data structures. Now, some of the key specialized data types include counter named Tuple order dit, default dit, and DQ. So let's have a look at this graphically to make more sense, basically. So what data types do we get? Now, we get, as I mentioned before, SDR for string, Tuple, int, set, float range, bull, dict, and list. Now, these are known as the built in data types within PySon. These are the common datatypes that we use day to day and all the time. Then we get counter name tuple, order dict, default dict, and DQ these are seen as our specialized data types which need to be imported so that they can be utilized. These are the differences. Try to visualize the difference between the two and group them together. When we're working with collections, we are going to be able to import these specialized data types. Now, let's have a deep dive into the data types that we get. Counter. No counter is essentially a tool that's going to count how often each item appears in a given list. We then have named tuple. Now, this is a special type of tuple where the elements will have names for easier access. Then we have ordered dict. Now, ordered dict is essentially a dictionary that's going to maintain the order in which items were added. We then have a default dit. Now, default dict is essentially a dictionary that's going to provide a default value for any missing keys that are out there. And finally, we have DQ. So this is kind of like a list like structure, you could say, that's going to allow fast additions and removals from both ends, right. So just a little bit of insight into the theoretical concepts of the following specialized data types. 72. Explore the collections module - [Lab]: Hi, everyone. And welcome to the next practical lab exercise, which is going to be focused on utilizing the specialized data types that come from the collection's module. All right. Now, I also want to mention in advance here that these specialized data types are typically utilized in the form of a class or a function. So that's just something I wanted to mention so that you're aware before we start. Okay. Now, we're going to first of all, utilize the counter class. In this particular example, I'm going to show you how you can use the counter class, for example, to count how many times each item appears in a list. We need to say from the collections module, I want to import the counter class. I want to define a list and I'm going to define a list of fruits for example. I'll say fruits equals. In a list here, I'm going to add in a few items. I'll have Apple I'll have pear. And I'm also going to add in the same should I say items? I'm going to add in two apples or two pears or two oranges, et cetera. I am going to repeat a few things so that we can count the number of occurrences in with all of the items here. So I'm going to also add another apple, orange, and pair. There we go. So that is good for now. Next thing I want to do is create a counter object to count the occurrences of each fruit. So I'm going to just define a variable that says fruit underscore counts, equals, and I'm going to utilize a counter class, and this will be appended to the fruits list. Now what I'm going to do is print the counter dictionary, which is going to show the count of each fruit. So if I were to say print, fruit underscore counts and run the code, let's go a bit lower. We're going to see here it says counter apple two, pair two, orange one. You can see it counts the occurrences. I can see have two apples, one, two pairs, and one orange, and that was counted for me in the output as you can see here. We can see it is output as a counter dictionary as we can see right here. Now, let's say, for example, I want to access individual counts, right? And to do so, what I can do is go ahead and say print, and we can say fruit underscore counts. And then here, we can just add the square brackets and refer to the specific item. So here I want to say Apple. So now if we run this you can see here we get the previous result, and then we can see Apple here. Okay, we can see that the output here is two because Apple appeared twice. Okay, so that is how you can get the direct value for how many repetitions they're were there or how many times it was called in the list. So for pair, of course, it's two as well, but orange, there's only one occurrence, so let's see if it is going to be one, which it should be. And we can see it's one. Perfect. All right. There we go. So that is how you can utilize the counter class. Now the next thing that we want to do is we want to utilize the named tuple. Now, named tuple is essentially a function, and we can use it to create a very lightweight class with named attributes. So this is why we're doing collections now, so you're already comfortable with classes. This should help you to get a better understanding of it. Okay, so again, from the collections module, I want to import the named tuple function. I want to create a named tuple person with named fields or attributes, you could say. I'm going to say person equals, named tuple will pass through person, in your comma. Then here, we're going to have, for example, name, age, and city. Now, this is very similar to attributes you could say, but we refer to them here as fields, but it's very similar to the attributes we define in our class. Right, there we go. Now we want to create an instance of person. So I'll say person one equals person. Then we can just go ahead and say name equals John. Age equals 24 and city equals Cape town, just like that. That is how you would then associate the values and create that instance. Now, let's say we want to access the values using the names. What we can do is say, for example, print, and I'm going to say person, dot, name, and I'm also going to say print person one dot city. I'll just move that up then. Let's go ahead and see the output. So we have John and Cape down. So that refers to the value associated for the name and the value associated for the city. All right. So you can see, it's very, like I mentioned, a very easy way to create a lightweight class, you could say with named attributes. Okay. Perfect. Right. Now, what you can also do is you can go on a hedge and output in a different way. So name tuples also behave like a normal tuple, as well. So I can change this and say print person one. And within prints, I can put in zero and then person one, and I can put in one. And if I run that, it's going to say John and 24. So it's going to act very similar in a sense to the behavior of a tupur or a list, you could say, by printing the first value of as we can see the instance. So we have John here, and then we have 24. If I want to get the last value here that's covered in the parenthes, I can just switch that to two. And then it outputs cape down for me. Guys. That is how you can utilize a named tuple. Great. We've got that set up. The next thing that we're going to want to go on ahead and do is we're going to want to go ahead and utilize ordered dict. Now we can just remove this and we can just say import or we can say, I believe it is encapsiaO dict. There we go. Then we want to create an ordered dict, let's go ahead and do that. I want to say ordered unsca data, just a variable. We're going to assign it to the class here of ordered dict. Then what I'm going to do is I'm going to set the associated values here and this ordered dictionary, you could say. Ordered nscoed data, and we'll say A will be equal to one, and we can just compass that and just set it for B equals two. And see is. Now we want to print the order dict the keys are going to be in the order of insertion. First, A was one, B is two, and C is three. It's not going to print in a different order. So now I can say print. Ordered underscore data. So now if I run this, it's going to say order dict A one, B two, C, and three. Okay. So that is how you can go ahead and utilize the ordered dict class. Now, let's say, for example, you want to add a new key, we have the three keys here, but you want to add a new one, so you want to say D equals four. What you can do, it's quite simple is you can just go ahead and say, or underscore data. G equals four, and we're going to say print ordered the school data. Okay. I want to also for better learning purposes, I'm also going to leave this. Let's set that as. There we go. Okay, so now you'll see the difference now. Okay, so we can see here before we had A one, b2c3, and then we added accordingly, added a new key that D equals four, and you can see now that it's appended D D is equivalent to four. Okay. So that is how we can go ahead and utilize an ordered dict. So this would be a specific class. Right. Next thing that we want to do is we want to have a look at the default dict. Now, this provides a default value for missing keys and default will automatically provide a default value for any missing keys instead of raising an error, so you can see where the use would be. From the collections module, I want to import default dict. It just defined like so. All right. And then what we can do is create a default dict where missing values will be integers, and of course, the default is going to be zero. So we can say fruit, underscore counter equals, default dict, and we can just say int now. Then we want to add some fruits. So I'm going to say fruit underscore counter, and that's going to be apple. And we can say plus equals one. Then we can say fruit underscore counter, and then we're going to say pair plus equals one. Now we want to print our existing keys, so it should go on a hedge and output one and one for both of us. So if I say print, fruit underscore counter, and I were to refer to Apple we can run this, and we can see it outputs one, and the same should occur if I go ahead and say pair. Same thing should happen. Save the code, run, we get one. But let's go ahead and differentiate it. S three and two, and we're going to keep it at pair. We get two for pair, and with appn we should get three. We get three, just as it should be. Perfect. Now, let's say, this is the important part. Let's say, for example, I want to access a missing key, and I want to access orange, for example, which you can see here doesn't exist. If I were to say print, fruit underscore counter, and I say orange, you can see, it's just going to have the default here of zero. If there's any missing integer and we put in tier to ensure that we are, of course, going to be working with our integers and we can see it's got zero. It's not going to raise an error, so you can see how useful default dig can be. If you're working with a program and you haven't necessarily got error handling in place and you just want a shorter or simpler solution, you can utilize default dickie as you can see to allow you to provide a default value in case you have a missing key. As you can see, there was assignment before, but orange doesn't exist at all for a key at all. Right. Great. Now, the final class that I want to show you is going to be DQ. We would say Import D Q, about like that. Okay. Essentially, this is going to allow us to quickly add and remove from both ends of a Q, DQ is short for double ended Q, it's going to allow us to quickly add and remove from both the left and right of our Q. All right. So let's create a DQ with some numbers. I'm going to say D equals DQ, and within pareneses we're going to add in a lister, so I'll have one, two, and three. Then I want to append to the right, the same as list append, you could say. I want to say D append add in that, and let's say I put in four, and let's say I print D. Let's go ahead and see the output. It's going to have one, two, three, and four. So we can see that this a pen method will append the number to the list that we have designated here, let's say we also want to append to the left. Okay. Now, essentially, DQ here, as we can see, is we have assigned a special way of dealing with lists as we can see here. Now, what isn't possible with lists, of course, on their own, is you cannot append to the left. So let me demonstrate. If I were to say Dt, append left, and I say zero, and I say print D, you can just see we now have zero, one, two, three, and four. Okay. And that is very useful to go on ahead and adjust accordingly. Let's say we want to now remove from the right. Okay? So let's do that. So I can say Dt Pop, Ar and we can then say print G. So let's see where we're at. So now we have zero, one, two, and three from that latest pop, so that we remove from the right hand side. Now, let's say we want to remove from the left I can simply say D don't pop left, and then print D. All right, there we go. We can see now we don't have zero anymore. We have one, two, and three. Right, so there we have it. That is how you can utilize DQ as well. All right, guys, that's it in terms of utilizing these specialized data types from the collections module. So as you can see, they're very helpful and they are very useful. But yes, guys, that is all for this practical lab exercise. 73. Itertools: Hi, everyone. Welcome to the next lesson, which is going to be focused on IR tools. So let's take a look. So what are IR tools? Now, the Iter tools model offers functions for working with iterators. Now, I can put this in a simple way, and that is that iterators are data types that can be used in a follow with list being the most common example. Now, here are some of the key functions that you can import from the IR tools module and they include. Product permutations, combinations, accumulate, group, and infinite iterators. Now, let's look deeper into these key functions. Right. So we have product. Now, product calculates the Cartesian product of input iterables, generating all possible combinations, permutations. This creates all possible orderings of elements in an iterable. Then we have combinations. This generates unique sets of elements from an iterable without any repetition. Then we have accumulate, and this computes cumulative sums or applies other binary functions to an iterable. Then we have group i, and this groups consecutive elements in an iterable based on a key function. Right. So that's it for the theoretical overview. Let's dive deeper into the practical lab exercise. 74. Working with Itertools - [Lab]: One, and welcome to the next practical lab exercise, which is going to be focused on working with IR tools and the associated functions that can be utilized from it. Right. Now, the first thing that we want to do is we want to go ahead and utilize the product function from Iter tools. So we can just say from iter tools, we can say import product, just like that. Just to elaborate a bit more that I tools is essentially a module with tools for working with iterators. And we are going to make use specifically now of the product function. Now, in our case, what we want to do is we want to generate all possible pairs of elements from two lists in this use case for the product function. So I'm going to define two small lists. I'm going to say A equals one and two, B equals three and four. Right now, in our case here, what we're going to do is define a variable and call this prod equals. Then we're going to say list because we want to output a list in the end and we can wrap that around the product function, which is going to take in A and B. Now, product A and B will generate an iterator that creates all pair combinations and we're wrapping it around a list that's going to convert it into a list so we can see all the values at once. Now if I were to say print prod, and run this. I can now see I have what I intended, one, three, one, four, two, three, two, four. Have a look here, one to three, one to four, two to three, two to four. That's how we can utilize the product function. Right. Now, we still want to make sure that we are utilizing iter tools, but this time what we want to do is we want to utilize permutation. We want to create all possible orderings of elements. I'm going to say import permutations. Okay. And let's define a list. I'll say nums equals, and I'll have one to three, for example. All right. Now I'm going to define a variable. I'll just call this perm. Again, I want to have list and put in permutations and apply this to my list called nums. Again, permutation nums. We're going to add in the list here and we're going to generate an iterator that will produce all the possible orders of our items. As you can see, again, we are wrapping it around in a list, and that's going to turn, of course, the output into a list. So let's go ahead and output perm. And we can now see a whole list of permutations. We can see one, two, three, one, three, two, two, one, three, two, three, one, three, one, two, three, two, one. We can see we have all variations here. Now, this is, I guess, a little bit out of scope, but it is helpful, especially in areas of statistics or if you're working with lots of data and you need to work with the permutations function, and such. Right. Next thing I want to show is how you can make use of the combinations module, the combinations function, excuse me. This is used to select unique groups of elements or items, should I say, and the order does not matter in which it does this. We can just say combinations. From the itertools model, we want to import the combinations module. Again, I want to define a list and I'll set this as one, two, and three, for example. Again, I will define a variable. I'll say C and we want to convert the output into a list. We're going to wrap it with the combinations function, and we're going to plaster in nums and two. Combination nums and two. This will allow us to generate an iterator and this iterator is going to pick all the two number combinations. We can see again it's wrapped around in our list, so we can get that list output like we did before. We can say print C. Let's run the code. And here we can see we get the designated combinations that we have set. So we have two here in each set. If we were to do one, we would just get one in separate sets. And if we were to say three, we're going to get the whole set into one. Right. So that's how we can utilize combinations here. Okay. Now, if we were to run this, we can see we got the same results, so we're generating correctly. Great. All right. Now the next thing we're going to look at is accumulate. Now, this is an interesting one. We can, for example, perform cumulative addition. This is something that we've looked at some point earlier in the course, but let me show you how you can do it with the accumulate function. This is a very useful one, so you can import the accumulate function. Then what you want to do is define a list of numbers. I'll say one, two, three, and four. Then what you want to do is, again, just define a variable, add your list so you can convert it and you can convert the output of the accumulate function and plaster in nums here for your accumulate function, and the output will be in a list associated with AC. So I'm going to say print A and go. Now we can see we have one, three, six, and ten. Now what accumulate. I'll explain what happens. We start off with the first item or element in our list, then we say one plus two equals three. That's the next part in this given list. Then we have three plus three, that gives us six. Then we have six plus four, that gives us ten. This is the process of accumulation, how we can accumulate accordingly. If I were to switch this now to two, three, four, 25, four, eight, for example, code, we're going to get the following. So you start off at two. Two plus three gives you five. Five plus five gives you ten, ten plus eight gives you 18. All right, so on and so on and so on. You can see it's a very helpful function. I like this one out of most of the Iter tools because it's extremely simple and very useful. Right. Now, what we're going to do now is focus on the group by function. So I'm going to move the following and we can start off with Group B. Okay. Now with group B, essentially, what we're going to do again is again, create an iterator, and it's going to generate groups one by one. Okay, so let's go ahead and get started with the process. Right. And another thing I also want to mention is by utilizing the group B function, we're going to group essentially items based on a key. But this is going to be sorted before we actually do that. First of all, we need to set up a list of tuples with categories, grouping the key and the associated values. We can say data, and we're going to put this in a list. I'm going to have, for example, A will be one. Then the next one, we can have A, and that will be two. Then we can have another one that is B, and three. Then we can have, for example, B and four, and then we can have a and six. There we go. Perfect. So we've now got that setup. Now we want to sort by the first value, this is going to ensure that the group by function works properly. So I'm going to say data dot SOT, with this method within it, I'm going to say K, going to be equals to Lambda. We will use Lambda here with a parameter of X, and then it's going to have X and zero here. Okay. Okay, so there we have it. Now the next thing that we want to do is we're going to define a variable and we can call this group and set it to group B. That's the group B function. Here we're going to pass through that data that's been sorted, and we're going to say K equals Lambda. X, X, and zero. So what we're doing now is essentially inside what we are doing is we are going to ensure that we're able to group our elements accordingly. According to the Lambda function that we have stipulated according to the key. Now we can go on a head and set up a loop. So we're going to see four key group in grouped Okay. And then we can say print, key, and then we want to convert the list to group. Okay. Right. So inside this loop, essentially, we're going to convert inside the loop, we're going to convert each group into a list to see all elements at once. So let's go ahead and run this code. And here we can see for the categories. We can see for A, we have A one, A two, A six, for B, we have B three and B four. All right, so that is how we can go on ahead and group our categories, as you can see. Okay. So there we have it essentially in place. Now, I also want to mention here with us defining and sorting according to Lambda here. We are essentially going to add in the values accordingly through our Lambda function in order to sort it, and then we're going to group it, and then afterwards, we're going to print each iteration, and it's going to appear as follows in the group by. Okay. So that is the group by function that we have utilized. Okay? Now, I do want to mention a little bit more and more detail, especially with the Lambda function. So we're going to talk a little bit more about that and then we're going to look at the final set of iterators in terms of the functions of count, cycle, and repeat. So we'll get to that soon, but let's just finish on group B. Right, so let's go ahead and go into more detail here. W data sort. Now we know already that data is a list of tuples, and of course you surrounded that within a list format. Then we want to sort the data here essentially that we have set, essentially, the dot sort method is going to sort the list in place based on our key function. Okay. We have K equals Lambda X, colon and then X and zero here. What we're going to do is we're going to take each tuple and of course, that's going to be substituted, as you can see for X. Each tuple, of course, for example, can be A one, A two, P three. We're going to go ahead and substitute that. Then we're going to extract the first element right here, which is going to be either an A or a B and then we're going to sort the list based on the first element. Okay. Then next, what we're going to do, as you can see here that we have grouped equals group B. We are just defining a variable to assign the result of the group B function here, and group is essentially going to group the consecutive numbers that have the same key. Okay? Then we have, of course, the key function right here, which is going to extract the first element. So A or B. It's not going to sort the data in this case here, okay? Just going to assume you could say that the similar items or elements are next to each other, which is why we sort it first. Next, we have the four loop here that we are working with, and as we know that the group by function that we have here is going to return pairs of key and group where the key is the group's key. A or B in this case, we have group, right? And that is an iterator of the items that belong to the group. Okay. All right. Then what we're going to essentially do is go ahead and ensure that we convert group to our list. So we can print all of the items at once, right. So that was the deeper exposure of how we can utilize this group by function. Now, this one is a bit tricky, so don't really worry too much about this. It's a little bit far fetched, but it's good to at least have context into what you're doing and working with. All right. That's group B. Okay, so let's go on ahead and continue with the rest of the functions that we've been working with. So now what we can do is we can go ahead and work with the infinite iterators. So these iterators keep generating values forever, and they need to be, of course, stopped manually. Okay. So we have count cycle, and repeat. So let's go ahead and import the mols, count, cycle and repeat. Count it's going to keep counting forever like a four loop that never ends. For example, we can say four I in count, and here we can say five. Now, what I recommend you do is just watch me do this. I don't want you to be in a situation where you're going to have a program that keeps on looping and never ends and if you get into that problem, so please I advise you just to look at what I'm doing for this part. We're going to start counting from five. Then we can say print I. Then what we want to do is we want to say I I is equals to ten, then I want to manually stop the loop. I'm going to say break. Let's run this. So we can see here we go all the way 5-10, and then we said break, and that stops the loop from running. If I do not go on ahead and have break in, o, what can happen is we can have a interesting situation with the loop going on forever and ever. So that's how you can use the count function. Okay, so it keeps counting forever and it keeps going and it's not going to stop unless we have a rake in place. We also have the cycle function, so that's to repeat a list infinitely as you could say. Let's go ahead and set count to zero, and we can say four item in cycle, and we're going to pass in a list of items or elements, you could say. And we want to add in the colon. Then we want to print each item. We then going to say plus equals to one, and it's going to keep on looping and going around. And if we reach the count of six, it's going to break. Go ahead and run the cycle. Here we have A, B, C, A, B, C. That is how we can go ahead and utilize the cycle function. Okay. The last one we're going to go through is going to be repeat. Okay? So we want to repeat a value, a specific number of times. Okay, so we can say REP, for example, as a variable. We want to say list because we want to convert the output to a list. We want to wrap within the repeat function. And here I want to say hello, and three. Then I want to say print, ap. Okay. So if I were to run this, it says hello, hello, hello. We are choosing to repeat the first value that we put here in the parses and on the right is where we define how many times we want to repeat what we've defined on the left hand side here. The first parameter you could say is, of course, what you want to repeat. The second parameter you could technically say is how many times you want it to be repeated. If I were to say, I like mass, and I want to repeat that five times. It's going to repeat I like mass five times. And because we convert it into a list that output that we get here from this repeat function here, it's going to put it in a list and output the data within the list and we've just printed it. So that's how we can use a repeat function. Now obviously, I would say count and cycle are okay, but I would say repeat is more useful as one of the iter tools. All right guys. That is it. We went into detail of the functions that you can utilize with Iter tools. 75. Context managers: Hi, everyone, and welcome to the next lesson, which is going to be focused on context managers. So let's take a look. So you're probably wondering what on Earth is a context manager. So a context manager in Python handles resource setup and cleanup automatically such as opening and closing files using the WI statement. Now, the WI statement simplifies resource management, making our code safer and more readable. So let me show you a difference here in terms of managing files manually, like we have learned earlier in the course and how you can do it more how can I say more simply, more efficiently, should I rather say was a context manager. Here is basic file IO being performed. We are opening a file known as car dot TXT and we want to write to it. Hence the W mode is in place. Then we will refer to that particular file object, and we're going to say car file dot right and then we'll say my favorite cards are Forward and a Tesla, and then we need to close our file. However, we can simplify this a Context manager, which is going to open and write to our file. As you can see, it's a lot simpler, less lines of code. So we have WIS Open, car dot txt, the same mode, and we're going to set it as car file. That would be what we would set it as in terms of setting up the variable. And then we'll say car file, right, and write like normal. Now, a good thing you can see here is that you don't need to close your file after writing, and this can solve a big pain point. Also a little bit more smoother in terms of how it is written. You don't have to be so simplified and define a variable and say dot write dot close. It's a little bit cleaner and more efficient. Also, what you can do is you can go on ahead and apply this in this next example where we're opening a file again to append to it. So here we have car file equals open cartxT then A, and we can see we're writing and closing the file, we can go on ahead and with our Context manager, we can just simplify this to replace it with W open and then say as car file, would be the definition. All right, guys. So this is just a bit of insight for you, so you can see how context managers would save us at least the trouble of having to close the file, and it's a lot more smoother and cleaner to utilize context managers, especially when you are performing file ILO with file input and output. 76. Working with context managers - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on utilizing context manager. Let's get started. Now, the first thing that I want to do is I just want to do some revision with all of you and just go through basic file IO again, manual weight without using a context manager. Right, by following it this way, you'll learn to see the differences and learn how to apply both cases. We want to define a variable and I can call this car file, and we're going to assign it to our file object, essentially, which is created by utilizing our open function and we'll pass in carxts the file that we want to open or create if it doesn't exist, and we want to write to that file hence the mode being W. Next, we want to refer to our variable called file and add in the write message, we want to write to the file. Here I want to say I like red cards. Then we want to close the file and say carflet close. Let's run the code. Let's go to our directory. And here you can see that the dot TxDFle has been created in our project's directory. If I can click on that, I can see that it outputs I like red cars as it should. All right, perfect. Now, what I'm going to do next is I'm going to comment out this code, so you can see and learn the differences between regular file handling and how to do it with a Context manager. So I'm going to right click on car dot TXT and delete it. And move that to the recycling bin. Great. So now the context manager, we would say Wi open, and utilize open function and we want to create a car dot txt file with the intention of writing to the file, and this is going to be stored as car file. And that's the variable we assign this file object to. Then we can say carfle dot right under it, and that's going to be the exact same message that we used before. And here I want to say I like blue cars and it's run this code. Let's go to our directory. Here we can see we have Card at TXT that now says, I like blue cars. Perfect. Hopefully now you can see the distinction between the two of them. Now before we go ahead and test this out with append mode, what I want to do is go through another example with you with writing files so that you can begin to learn the distinction between both methods. We can remove this let's go ahead and do the next example and then append. All right. Now what I'm going to do is base this on a person. I'll say person file equals, and I'll say open. This is going to create a file called person dot GXT and I want to write to this file. Now I'm going to say person file dot R, and I want to write Hi. I am Auto. Then I need to close the file by saying person file dot close. Let's go ahead and run the code. Go to the directory. And here we can see we have person dot TXT. If we click on that, we can see, Hi, Amano. Great. So now I can still see we have the cart TXT files. So what I'm going to do is I'm going to go ahead and delete both files from now. Then we can comment this code out for the moment. And we're going to do the exact same thing for a person file. So I'm going to use the context manager now and I'm going to say Wi I'm going to say open. And here, what I'm going to do is create a person dot TXT file with the intention of writing to it as a person file. I'm going to say person file dot right, and I'm going to write Hi IMOu. Let's run code now. Can see a person at TXT files created that says hi I'm no. Simple. There we have it. We now have that fundamental practice in place now. Now the next thing we want to do is now that we have that person on TXT file, let's actually go on ahead and open it and append to it by using basic file IO. We know that this exists, so we can go ahead and remove everything. Keep that file. Now let's open it. As of this moment, it just says, Hi I am Ro. What we can do is we can open that file again and append to it. I'll call it person file. See open, and this is called person dot txD and our intention is to append to it. That's the mode we'll set. Then we want to go ahead and say person file dot right, and I want to add a space and I want to say hi Ana was what it said, and I like movies. Very simple. And we can say person file dot close. Let's go ahead and run this code. Let's go to directory, prison f It says, Hi, I'm no, and I like movies. Perfect. So we can see that's how we can utilize a pen method with basic file IO. Let's go ahead and set this up with a Context manager. So it says, and I like movies, let's go ahead and adjust this. So I'm going to comment this out. We're going to append again to that file. We want to see WIS open here within Parenss I'm going to refer to that file, which is called person dot TXT. My intention is to append to that file as a person file. Then we can write to it. I'll say person file dot, right. Let's see what we have at this moment. Hi, I'm and I like movies. Then I'm going to say something outside that says, I am from South Africa. That should append afterwards, and I want to put in a space here. There we go. So let's go ahead and see if it appends to it. So if I run the code, Go to person dot TXT, and there we go. We can see Hi, I am Ano and I like movies. I am from South Africa. There we go. Simple. So that is how we can utilize context managers when we are working with our files. So you can see it is very effective if we want to simplify and to omit any fear of closing our files after rewriting them because it can be a bit tedious and you can forget and you can run into errors. But with context managers, it handles everything for you. Alright guys. So that is it on this practical lab exercise on context managers. 77. Built-in vs custom context managers: Hi, everyone, and welcome to the next lesson, which is going to be focused on comparing built in versus custom context manager. So let's take a look. All right. Now, with the built in context manager, you would typically use with open, and we would use the Wi statement with the open function to open a file. Okay. Now, this is a built in context manager that automatically manages our resources like files in order to open and to close them, and this is what we have been working with like in the previous lesson. We also have a custom context manager. An example of how this would be utilized is that a custom context manager is basically a class that you create that will define enter and exit methods within the class to execute and manage resources or actions when we enter or exit a certain block of code. Now what we are going to do is we're going to go on ahead and work with a custom context manager. We already have experience with a built in context manager, which we've been working with in the previous practical lab exercise, but now we're going to create our own custom context manager. I'm going to show you how you can manage everything with your files, for example, if you are going to work with a given class. So let's get straight to it. 78. Create a custom context manager - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on creating a custom context manager for file handling. Let's go ahead and get started. Now, we already have experience with classes, so we are going to make use of a class. The first thing that we want to do is define our class names. I'm going to say class and I'll call it file manager. Then I need to go on ahead and define my init message. I'll say Derescore then we need to pass through our parameters, so we will have self, file name, and mode. We now want to initialize our file manager class and what we're going to do is we are going to specify the attributes. We're going to say self dot file name equals, and that's going to be file name. Then we're going to have self mode, and that's going to be equal to mode. We're going to store the file name here with self dot file name and we're also going to store the mode as mode and that can either be R for reading, it can be W for, of course, writing and it can be A for append. Okay. Next, what we want to do is we want to define our methods. Remember with messages, they need to be in line of your init method. I'm going to first of all, say Defunderce enter, double underscore, and here we'll pass through self. Essentially, what we want to do is we want to enter the runtime context related to our object, and this method is going to be called when execution enters the Wispblock which we'll define later on, and it opens the file and returns the file object. Okay. So what we want to do then is say self dot file equals open. We're going to say self dot file name and self dot mode. So we want to open the file in the designated mode that's given. Then we want to say return, self dot file. Okay. Now, self file here is, of course, going to be our file object, and that will be the open file which can be used in the WIS block. So that is what we're going to do here. And as we can see, this is assigned to as variable in wits. Okay? Next, what we need to do is go ahead and specify our exit method, and that's going to exit the runtime context and clean up the resources. This method is called when the execution leaves the With block. I'm going to just say Jeff, double underscore exit, and double underscore. Going to pass through quite a few parameters. First, we will have self. Then we're going to have EX underscore type. That's the exception type if an exception occurred. Otherwise, it's just going to return none. Then we have EXC underscore value. This is the exception instance if an error occurred, and of course, if nothing occurs, it's just going to be none. Then we're going to have trace back. That is the traceback object that contains error details. We can go ahead and close the following. Right now, what we want to do is we want to first of all, check if the file is opened. I'll say I self dot file. So if that file is opened, and in that case, if it has been, then what I want to do is close the file to free up resources. So this is on exiting. So we're going to check Is the file initially open, and when this exit if this exit method runs, then we can close that particular file. Okay? Because you can't close something that isn't already open. Okay. So the exit method is going to be called when we want to go ahead and exit our file and close it. Then the method is going to check if that file is actually open at the moment, if there's something too close, and then it's going to close it. So we would say self dot file, dot close. So we're going to close the file up, and that's going to help to free up resources. Okay. Perfect. Now what we want to do is we want to go ahead and right here outside of our class file manager, what we want to do is we want to use our custom context manager. That's going to be what we've used before with the logic that we've been utilizing earlier on. We're going to go on ahead and say, Whiz, we're going to call our class here, which is file manager. And then we're going to like before, define what we want to open or create. So here, I'm going to say car dot TXT, and then I want to write to it, so I'll put in the W mode, and I'm going to say as CarFle. Go on. Okay. So as we can see here, we have this is statement here, and that's going to go a hag and call our file manager method, which is Enter, which is going to open the file and return it, and the return file object will be assigned. To car file and it's used inside the block. Then what we want to go ahead and do is ensure that we are writing to our file. To here, I'm going to say carfle dot. Here I'm going to say, I like Honda. Okay, so we written into the file. So the file now that it is open, it's going to also write to the file. And automatically when we have performed the necessary action, when the block finishes, in other words, with the WIS statement that we have set up here, it's going to call the file manager in terms of its exit method that is designated right here and it's going to automatically call it to close the file. Okay. That is the process here and the execution with what we are setting up here. I'll just zoom out here. So you can see, we defined our class, add it in the necessary parameters and statements. And then right here at the end outside, we are just calling our class and then to go on a hedge and create a file and then to run into it. We can actually go ahead and test this out. So what I'm going to do now is I'm going to test it. So if I run my code, there won't be an output, but if I go right here, I can see that I have this card dot TXT file that says, I like Honda. And you can see that was all managed automatically for us and as it should be. All right, good. That is how you can go on ahead and essentially create a custom context manager for file handling, and most importantly, we're using it via Visa via class here, as you can see, called file manager. Okay, so the whole process, as you can see, works very similar to the regular way in which we went ahead and worked with our classes. Okay. That is it for the main part. What I'm going to do now is just go ahead and analyze more and show you what else you can do. All right. Let's continue. Now the next thing that we're going to want to do is we're going to want to go ahead and customize further within our enter and except methods. Now before we continue, what I want to do is just do a bit of a cleanup. I'm going to go to Explorer and I want to delete these files that I have except the main dot pi file. The person dotXT and car dotxT. There we go. Just make sure you didn't delete the main dot file. That's what we're working with. What we can do now is we can go ahead and do a little bit of some customization within our interim method. What I want to do is once afile is opened, I want to output some text to say the file name that was opened and also to go ahead and output the mode that it was opened. In this case here, I want to print out that CdTXT was opened or created and the writing mode mode was enabled for it. So here it was in my Enter message. Let's move that there. I can say print. I'll use S strings to say the file. And here I'll put in my place order itself file name. So it's going to call the file name, which will be called at txt, and then the mode, which will be W. I want to say the file name is the file, so and so is open, and the mode is, and then I can say self dot mode. Go. Now, let's say I want to add in a statement just before the file closes, so I can utilize the exit method for that and adjust it. I can say print. The file is about to be closed. Have it. Now I'm going to recreate that TXT file that I had before and it will appear here. Let's go ahead and run the code, but we should now see output in our console the output being displayed. Let's go ahead and save and run this code. There we go. As we can see here, it says, the file card TXT is about to open and the mode is W and the file is about to be closed. We can see our enter method ran and printed out the following statement, which was the first here, with our exit method it printed the file is about to be closed and output the following as we can see right here. Perfect. Well done. That is how you can go ahead and add in extra functionality to your methods. Right. Now, let's go ahead and perform error handling. Now, let's say we have an error on exiting our file. For example, here, I want to go on ahead and override this file that we currently have, and I'm just going to change some text to say I like for it as an example. Then I'm just going to, for example, call Afle. I'm going to say here carfle dot random. Okay, and that's going to be random message, something random here. So let's say we want to call a random method, something that doesn't exist, it's going to have an error upon closing the file because remember, when we are opening the file, okay, we are going to ensure that we are able to access it, which we can do, and we can write to it, which we can do right here. And we're going to write to the file upon opening it, and it's going to be written. And then it's only going to be closed when we are running the exit message. So after we have written to the file, going to close the file, but before it can be closed, we then go ahead and add in this invalid method, which is going to trigger an error in this exit method because that's where we are in the current stage of the program. Essentially, what I want to do is I want to go on a hedge and print out an exception. So what I'm going to do, I'm going to keep it very simple, and I'm going to go and state that if I were to have an exception, I'm going to say here, if my exception underscore chip is not none. So if I have an exception, I then want to temporarily print out exception being handled All right, just like that. And the next thing that I want to do is just say exit here outside, and I want to return true. Okay. Now, let me elaborate what I'm doing here. So this print statement here says exception being handled means I want to print a message if an exception occurred. So this exception type says, I exception type is not none, which means if there is an exception, I want to print out exception being handled. Okay? All I'm doing here outside of that I statement is I'm saying print exit. That's going to print this message irrespective of whether there was an exception or not. Return true here, it's very important because that's going to suppress any exception that occurred inside the WIS block here. It's going to ensure that no further errors output. I'm going to show you what it's going to look when I'm handling the exception first. I'm doing it the other way around. So if I were to run this code, we can see, Okay, it's open. We can see it's being closed. Then we can see exception being handled and exit. Now, let's say I were to remove that exception handling, and let me go on a hedge and just comment to sound and remove that. And now what I'm going to do is I'm going to run the exact same thing and say run code. Okay. And we can see here the file is about to be closed and exit. Now, the thing you'll see here is that it's still not throwing arrows, and that's because I have return true here, and that suppresses your exceptions within the wispblock. So what you're going to want to do is to add in your hashtag here and just add it in the comment, and we can go ahead and run the code. Now you can see that traceback error occurs. We can see now we have this error, so it's an attribute error and the object has an attribute random mesod we can see where that error occurred according to the traceback. We can see carfle dot random message, and this is where that error occurred. That is something I wanted to mention. That's the error you'll get if you don't have the error handling in place. Now, if you want it to be a little bit more concise and you want it to be specific, what you can essentially do is the following. We're going to say return true. We want to get that exception type. But within this statement here, we want to see the details more concise. We don't want the default exception handler. We want to style it ourselves. I want to see the exception type and the exception value, and I want to see the traceback all here in this print statement. What I'm going to do is I'm going to go ahead and add them in. I'm going to say, exception type. What I'm going to do is I think I'll use F strings, so I can just simply revert to it. I'm going to say exception type. Then we'll have value and I want to see the trace back. I will change the text as well. This is to have my own custom error messages. Traceback. Now, let's run this. Then I get my own custom error messages, and this is really helpful. Exception type, we can see attribute error, exception value, we can see has no attribute random mesod that is pertaining to this and we can see also a traceback in terms of the traceback object there. That is the error there. There we go. I feel that is a more useful way if you want to handle error handling as well, you would just go ahead and calmly check if the exception type is not none, and then you'll return true so that you can suppress any exception that will occur, of course, like I mentioned, within the Wistblock it also will ensure that it doesn't trigger the default error within the console, and by handling it yourself by manually looking at the type, the value of traceback can be very effective too, because as you can see, it's in a very clean sort of output as well. Alright, so that is how you can also handle error handling when you're dealing with your custom context manager. So another very useful point to mention here is when you're working with context managers, you have more options to change how you want, for example, the file handling process to go. All right, guys. So that is it for this lab exercise on utilizing custom context managers with file handling in this particular case. 79. Generators: Hi, everyone, and welcome to the next lesson, which is going to be focused on generators, let's get started. All right, so you're probably wondering what on earth is a generator. A generator is essentially a unique function that retains its state and yields a sequence of values one at a time, rather than returning them all at once. Now, you're probably wondering, that's good to know, but how do they actually work? Instead of return, generators use the yield keyword. Now, this means that they don't run all at once, but pause at yield. And this makes generators memory efficient, since they don't store the entire output in memory. Now, the effects that you see is not something that you will see right away. You won't really see it in the code, but it is in terms of the backend processing. Okay? This is how you would measure efficiency, but I do have a lesson on that we're like where I will explain it to make more sense on memory efficiency. Anyway, let's continue and focus on generators. But now what I want to do is I want to explain a simple analogy so that you can better understand generators, and this analogy is going to be focused on watching Netflix. So in the concept of yield in generators, we can compare it in Netflix to the Pause button. So yield is the pause button. After finishing an episode, Netflix pauses instead of playing everything at once. Netflix also has an option to click on the Next button to go next. And when we are working with generators, we tend to sometimes use the next function. So next is a play button. So when you're ready, you press Play to watch the next episode, and that also can occur with generators. We can utilize the next function to go to the next result that is being yielded. Now, another important thing is that it saves wherever you left off. You don't have to start from the beginning each time of an episode in Netflix. It always remembers where you last went off. Same thing with utilizing generators and utilizing yield. It's going to remember where you last were. Okay. Now, let's apply this to a program. So I create a function, which is a Netflix show, and then I'm going to yield, for example, three episodes. So yield episode one, Episode two, and Episode three. Then I'm going to go ahead and store this Netflix show function into a variable, and this variable will ultimately be a generator object that's being stored because we're utilizing the yield keyword. Then what we can do is we can print out each episode in order by utilizing the next function. We can say print next and then encapsulate the episode. That's going to print Episode one. Then we utilize the next next function, and we put in the episode and that's going to output episode two. It's going to remember the state. It's not going to print out Episode one, two, and three. If you just go ahead and display episode, we would need to say next and it's going to do it in iteration. Okay. Now, that is going to be the case if we're doing manual skipping, just like in Netflix, if we are manually skipping an episode. Okay? We would keep on using the next function each time to do so. Now, what we can also do is we can automate this to make it go a bit faster. We can use a four loop. Okay? So start the TV show and loop through the episodes. So we use a four loop by saying four episode in Netflix show, print episode, and this is going to print everything in the designated order. Okay. And that would be auto skipping. Right. That is how we can apply and utilize generators. We are going to practice and we are going to go on ahead and do some practical lab exercises to work on generators. Stay tuned. 80. Working with Generators - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on generators. Now, like I mentioned in the theoretical lessons that I mentioned, a generator is a unique function that retains its state and yields a sequence of values one at a time, rather than returning them all at once. Now, I just want to show you and prove to you that a generator isn't just a regular function and that it is a unique function. So let's go ahead and define a normal function to start with. I'm going to just say death and we're still going to have the same call that we had before. I'm going to say Netflix underscore show as the function name, either side, empty parentheses. I'm just going to, for example, go a hedge and say Print episode one, and that's all. Then I'm going to get a variable and I'm going to say episode equals Netflix underscore show. Then if I say print episode, we're going to see here that it returns none. That's just a very simple test to see if we are dealing with a function. But if I were to remove print and say yield, use the yield keyword and I want to say episode one, and I do the same thing and run, it's going to output a generator object. So this is an indication to show that by adding in yield, we're telling Pison that we want to transform this function as a generator, in other words, a unique function. So just something I wanted to mention there just so we can have some clarity on the difference. So let's head on back. We anyway need to define a function. It's going to be Netflix show, and then we want to yield some results. So I'm going to yield, first of all, episode one, and it's going to be going to say something random, the mill. Yield. Now I'll say episode two. The ban and yield Episode three villa. Now, you can add in some space here if you want, or you can keep it tight. It's really up to you as to what you want to do, but make sure you have three yield statements. Next, we want to associate the function here, Netflix show, which is now a generator to a variable so that our variable will then contain this generator object. So I'm going to say episode equals, and it's going to be Netflix underscore show. And we've assigned that generator object. Perfect. Now we can go ahead and print the episodes one by one. So if I say print, I can use the next function, and I can just say episode. And let's go ahead and run this. And you can see here it says Episode one the Mill. Let me run the code here. Episode one the ML. So it's not going to go on and output every single episode that we have. It's going to do it in segments. So for me to see the next episode, I'm going to have to utilize the next function again, so I go to episode two, then episode three, and so on. So let me do that. You can just go ahead and output the print statement three times. So episode one will be printed first. Episode two next, and episode three shared. So let's go ahead and run this. And as you can see now, it's now outputting Episode one. To answer in order. It's not just going and outputting all of them so suddenly. Okay? So that's how we can go ahead and set up a simple generator. Now, let's say we want to automate this. We don't want to have to constantly use the next function each time. So what we can do is we can go ahead and remove this. All right. And we want to remove that as well and we can say four episode in Netflix. Underscore Show Colon, and we want to say print episode. And if we run this, we're going to get episode one, the Mill, Episode two, the barn and Episode three, the Vella. Now, you're probably wondering to yourself, Okay, what is so unique about the whole process, that has to do with the behind the scenes efficiency of generators, and this is not something you'll see inherently in your code, but it's something that will happen in the background. And like I mentioned, that's a lesson I'm going to cover in the next lesson, should I say, on going ahead with that process. But in any case, let's go on ahead and just do another simple example of a generator, and let's do that. All right. Next, I'm going to say D and then I'm going to say, let's go with let's say DF and I want to say rosary underscore items would be my function. Now, to turn this into a generator, I'll need to say yield, at least have one statement. Here I'm going to say apple. Yield milk. Yield, and we can say meat. There we go. Now we want to go on ahead and assign our generator to a variable, our generator object. I'm going to go ahead and can say product equals, and we're going to say grocery underscore items. Now product now is now a generator object. So now let's go ahead and test the process. So if I were to say print, I can say next, use the next function, and then I want to add in that generator object, so product. So now if I run this, it's going to output Apple. And if I keep on running it, it's not going to go further in, it's just going to do the next particular value that's set here. I would need to do that for the number of times that I have that particular items if I run apple, milk and meat. Perfect. Let's automate this. So let's remove the following. We can just simply go aheage and add a flop. So I'm going to say for product in grocery underscore items. And we can just print the product. So each particular statement that we have here, and it's run that. And here we have apple, milk and meat. All right, so there we go. That is how we can simply go on ahead and utilize a generator in Bison. I will go through the next lesson now, the memory efficiency part so that you can understand the actual benefit of the generators. Alright, guys. So that is it for particular this particular lab exercise. 81. Generator memory efficiency: Hi, everyone. And welcome to the next lesson which is going to be focused on understanding memory efficiency in terms of gener ors. All right, so understanding memory efficiency. A regular function stores all values in memory at once, which can be inefficient for large datasets. On the other hand, a generator is going to yield one value at a time without retaining previous ones, and this makes it a lot more memory efficient. So let's say, for example, we're working with a regular function. And in this regular function, we define a function known as Netflix show. We are returning a list of episodes, and then what we are doing essentially is we're going to go on ahead and assign those episodes to that particular function here, and that entire list is going to be created in memory, and then we can later on go ahead and loop these episodes, very similar to what we did with the genera. However, this is where the issue comes into play. The problem is that the function creates installs the entire list in memory before looping. For example, if there were millions of episodes, it would take up a lot of memory. Now a regular function, if it is going to be returning, for example, lists composed of lots of values, it's going to load everything into memory at once. That is the issue that we have here with a regular function. However, a generator can solve this problem. If we look at a generator in this example, we are just yielding, as you can see, our values. Yield episode one, yields two, yield episode three. You're probably wondering why is this better? As you can see, only one episode, as you can see, is kept in memory at a time. As soon as an episode is printed, it's discarded, and that helps to free up memory. So the generator function, we have yield, unlike with a regular function we'll have return by utilizing yield, it's going to load one value at a time, and this helps to keep your memory usage low. All right. So hopefully now that gives you a better understanding with understanding memory efficiency with generators, and this is how you can see the value of using generators with the yield keyword. So like I said, I know in the first lesson and with the practical lab excise, it didn't seem like there was much to it because this is essentially something that occurs behind the scenes and it helps with your memory. This is where it's going to be helpful if you're dealing with applications later on or currently now and you want to watch your memory usage, generators can really help out in this regard. 82. Shallow and deep copying: Hi, Ron. Welcome to the next lesson, which is going to be focused on shallow and deep copying. Let's take a look at the difference between the two. A shallow copy, essentially, creates a new object, but retains references to the original elements, meaning that changes to nested objects affect both copies. We also have a deep copy, and in this case, a deep copy makes a fully independent duplicate, including all the nested objects, ensuring that changes in one copy don't impact the other. So here are the differences between shallow and deep copy, and we are going to do a practical lab exercise on them so that you can see how this seri is going to be applied to the lab exercises. So that's it on the definitions of shallow and deep copy, let's dive into the lab exercises. 83. Utilise shallow and deep copy - [Lab]: Hi, everyone. And welcome to the next lab exercise, which will be focused on shallow and deep copying. So we're going to work with a few examples so that we can better cement our knowledge on copying. So let's go ahead and get started. Now in this first example, we're going to learn how we can assign without copying. So we're not making a copy just yet, just to delve into the whole idea of it. So first, I want to define a list. I'm going to say original underscore list. Going to say one, three, and five is in the list. I want to assign it to another variable. I'll say new underscore list equals original list. And with this all I'm doing, like I mentioned, is assigning the original list here to a new variable called new list, and I'm not actually making a copy. I'm just assigning it. Now, let's say I wanted to modify the new list and say new list, and I'm going to say at zero, I want to set that to 99. Now what I want to do is print post list. I'm going to say print, and I'm going to say here original list. And Is that in and then I want to say print new list, and then we can pass through the new list. Let's run this. We can see here at the original list, we have 99 and we have three and we have five. Then in the new list, we have 99, we have three and we have five here. Now, let's go ahead and understand the process here at hand. Now here we can see that the new list is not a copy of the original list. Both variables point to the same list in memory. When we change new list, as we can see here, zero, the original list also changes because they are the same object. As you can see here, 993-59-0935. That is how we can simply assign a list that does not create a copy. Right. That's the first thing I want to mention. Now what we're going to do is delve into shallow copy. That is copying only the outer list. With a shallow copy, it will create a new object, but it does not copy nested objects, we'll dive into that in the moment. So let's go ahead and do just that. Make sure that you're comfortable with what we just went through. All right. So let's go on ahead and focus on shallow copy. Remember, a shallow copy creates a new outer list, but the inner lists remain the same. They are not copied, only reference, let's get started. To do so we need to import the copy module. Okay. Then we want to first of all, create an original list with nested lists. So we can say original lists are variable, and here we're going to have a list, and then we're going to have a list in a list that's going to have one, two, three, add in a comma, and then we want to have four, five and six. Okay. So now we have a list with nested lists. So a list in a is Okay. Now we want to create a shallow copy. I'm going to assign this to my variable called shallow copy to create that shallow copy, you would need to call the copy module and the copy module has a function called copy, and we can just place in the original list within that. That's going to create a shallow copy for us. Now we want to modify the inner list which both lists share. To do so, we would say shallow underscore copy. We would say zero, zero, and we can set that to 99. What that is going to essentially do is it's going to go on a hedge and change the value of the inner list first element. Here, you could treat this as the list that we have outside, and that's going to be this list here, and we would then denotes this list here as zero, and this list here as one. So we're saying zero, that means we want to work with this one. And then within that list, it comes second it comes the second argument here. We want to go ahead and reference the first element of that list, this one right here. That's going to change and go to 99, and that's going to be reflected in both of our original list and in our shallow copy as well. So let's go ahead and print the statement so we can see this. I'll say print. I'm going to say original ist. And then shallow copy. Shallow copy. There we go. So now let's go ahead and we want to print our list. There we have it. We have 99, two, three, four, five, six, and we can see we had a change here in the original list and of course, the shallow list by default, of course, would have taken 99. But you can see that the original list also changed along with it, and that is because the original list here by zero, and of course in our shallow copy at zero in terms of the element position, refers to the same list in memory. This proves that shallow copies only copies the outer list and not the nested objects inside. That's the reason why we're getting the following result. Right. Now let's go ahead and focus on deep copy, and that's going to ensure that deep Copy has a fully independent copy that doesn't alter the original list itself. So what we want to do is go on a hedge and remove what we have here and we're going to switch this out for deep copy, and we're going to call the copy module, and we're going to say deep copy, utilize that function. Then we want to pass through the original list. And that's going to create a deep copy. Then we want to modify the inner list in the deep copy, so we can say deep underscore copy, and 00 is the same thing as we did before. And we can say print, and we're going to say original list. Followed by deep, deep copy. There we go. So we've now got that into place, and let's run this. And there we go. So now you can see that the original list here, was kept intact, so we still have one, two, three, four, five, six. And at that positioning, the effect didn't take place in the first element here. I stayed the same. However, in deep copy, that change was adjusted. You can see here that 99 is now in the place of where one used to be. So you're probably wondering, Okay, why did original list this time remain unchanged? Because deep copy was zero, okay? And original list in zero, as well, okay, are not the same list anymore. Deep copying fully duplicates everything, so changes in deep copy doesn't affect the original list. Okay. So that's just something very important to remember. So remember, you are using assignment, like I showed you previously, and if you're using the copy function, changes will affect the original in terms of the list. But if you're using deep copy, it's going to be fully copied to the other list, for example. All right guys. That is shallow copy, deep copy, and the general assignment in terms of how you would assume copying would work. All right guys. That is it for this practical lab exercise. 84. Logging: Hi, everyone, and welcome to the next lesson, which is going to be focused on logging. So let's take a look. So what is logging? Logging is the practice of capturing events, messages, or errors within an application. Now, it helps developers debug, track issues, and also to monitor system behavior. Now, logs can also be stored in files, databases, or external services, and they are also categorized by logging levels. So let's have a look at these levels of login that we get. So we get the following levels. They include TBug which provides detailed diagnostic information for troubleshooting. Then we have info, which provides general operational messages confirming normal information. Warning. This is going to be under any indications of potential issues that may require attention. Then we get error, which of course is focused on outputting information on any significant problems that affect the application functionality, and we get critical, and critical, of course, is going to output information that indicates that there are severe errors leading to system failure or instability. So these are the levels that we get in login. Debug, info, warning, Eror and critical. All right. So now that that's done, let's go ahead and dive into the practical. 85. Implement logging messages - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on logging. So the first example that we're going to look at is how we can implement basic logging, and this is helpful for replacing the print function. Now, you're probably wondering, Okay, the print function is great. It really can help us to output certain statements depending on where we put it in our code. While that is true, we can instead use logging, which can track our program events more efficiently with its functions and structures and all. So let's go ahead and get started. First, we want to import the logging module. Now we want to configure basic logging. So we're going to define our function. So we need to refer to our module, say logging dot. Then we're going to refer to the function which is called basic config. Now, this is a function that sets up logging. It configures how the logs behave. And within that, we want to say level equals logging dot info, right? So level is essentially a parameter that sets the lowest log level to record, and that's going to be, of course, info and above. Then we have it being assigned to logging dot info, and this is an attribute or constant that represents the info level. Okay. Now what we want to do is we want to log an informational message. So I'm going to say logging dot info. And then here it was in parentheses. Okay. I want to go ahead and say the program has started. Okay, so this logs a message with the info level. Okay. So that's just something important that I feel is important to get your head around. All right. Now, this is the particular function that we're using the info function so that we can go ahead and run the following statement. So if I run this, going to the info route, the program has started. So well, done, this is the most basic way in which we can integrate logging. Okay, so that is how we can go on ahead and get started with that. Right. Now that we are comfortable with info, we want to now learn how we can log errors with traceback. So this can help to debug errors without stopping our program. So we're going to adjust the following. Again, we are going to make use of the logging module. But this time we want to configure logging to show errors and above. In other words, error and critical. So I'm going to go ahead and call the logging module. Then I want to run basic config. I want to add that in, so that's the function I want to use. I'm going to set the level to logging dot error. Okay, so it's the exact same process that we did before. All we're doing now is we are going to want to output and show the error of error, should I say? No info or anything of the sort. Now we can just create a simple program. I'm going to say try and I'll say result equals 10/0. This is going to cause a zero division error. What I want to do then is say except and what I'm going to say is logging dot E. And here I'm going to say you tried to divide by zero. Then at the end, I want to say exception E XC, underscore info is going to be true. Okay. So let's go ahead and have a look here. So we are defining the log in module, and we're going to use the error function to output a message that says you try to divide by zero, and we want to provide an exception information here on that error. So logging dot error, of course, that is this is essentially the function that logs an error message. And then when we have EXC underscore info equals true, that is the parameter that adds our traceback details for us. Okay. So let's go ahead and run this code. And here we go. We can see error root. You try to divide by zero, so we can see that coming up as we can see as it follows, and we can see we're getting a trace back here so we can see EXC screen in focals true. So this is the trace back that I mentioned, and it gives us all these details here. It says zero division error division by zero. So that is how you can enable the traceback as well. Right. So that's what we need to ensure that we have, and this can be very useful for debugging. All right. Okay, perfect. So that is how we can go on ahead and focus on logging error messages. Wrench. Now the next thing that we are going to want to focus on is how we can log warnings for potential issues. This can be very helpful because, of course, developers want to be alerted on potential problems before they break the code. So it's not going to break a code, but it's just kind of a warning to let us know. Okay. So what we're going to want to do is say logging, dot, and we're going to say basic config, and now we want to set the level, and that's going to be logging warning. Okay. Now we're going to create a program. I'm going to say age equals and I'll say minus five. That's going to be an invalid age, of course. Then I want to check for invalid input. I'm going to say I age less than zero. I want to then go ahead and say logging dot warning use the warning function here and it's going to say age cannot be negative. Then I want to say received. I'll add in percentage symbol and D here, and then I'll add I'm just adding in some formatting so that the age will be appended here to the string itself. We have logging warning here, essentially, what's going to happen here is it's going to log warning messages. Then here this percentage symbol and the G here is the format specifier that's going to insert the integer value of age, which of course, in this case, we sent to minus five. What we can do is go ahead and run this code. Here we get a warning saying warning, age cannot be negative received minus five. That is how we can log warnings for potential issues that we may receive. Right. Great. Now the next thing I think you're going to like, it's really quite interesting, should I say, that is how we can save logs to a file. We can keep a permanent record of logs instead of just printing them as you can see here. Now, this will be very beneficial, especially if you work for a company that likes to keep track of logs and do auditing or anything of such. We can go ahead and remove everything as it is. Now we're going to learn how to save logs to a file. All right. So what we want to do like before, we want to configure login to write to a file. So what we're going to do is we're going to say logging and we need to say basic config, first of all, then we're going to specify a file name, and that is essentially going to be the parameter that sets the file name. So I'm going to say file name. That's the parameter. And then here I will call it app dot log. Okay. And then the next thing I want to do is set to level. So I'm going to say level equals and I'm going to say logging dot info. I'll add in a comma and then I just want to say Enter to go to a new line here. I'm just going to say format, and I'm going to specify the format that I want to set it as. This format here is essentially going to be the parameter that defines the log format. In other words, the timestamp, level, and message, and this is how we're going to want to do it. We're going to want to add in our quotes, presented symbol and then here, we can just add in our parenses and say ask time. And that's going to be S, and then when you say Dasher, and then centid symbol, inferences we want to add in the level name. And we can say S and we can then add in the percentage symbol and we can have the message also be put here with S as well. Let me zoom out so you can see and we can just put this back and that is now all in one line for you. All right. Great. We've got that set up now. We want to log an informational message. I'm going to say logging dot info here I want to pass through the program started successfully. Oh. There we go. Now we want to check the file app log for the logs and then we'll see the example log entry. So let's go ahead and do that. Now, before we do that, I just want to mention here we have file name app log. Again, I just want to explain so that you're aware. This is a parameter that's going to set the file to save our logs. Then we have level equals logging dot info. We're then just defining the level that we are going to utilize here. It's going to be at the info level. So again, just reiterate level is the parameter that sets, of course, in this case, the lowest level to record, which is going to be info. Okay. And remember, logging dot info is going to be the attribute that represents the info level that we're defining. Right. Okay, so let's go ahead and run our code. So we run it, and now you want to go to your directory. And here we have an app dot log file that was created. It's going to show the date, the time, and it's also going to show the info that says the program started successfully. So this is how we can go ahead and ensure that we save our logs to a file. Okay. So that is how we can do that. Perfect. So we've got that setup. Now we can just move everything here and continue. Well done. Now the last thing that we want to look at is how we can add time and log levels for debugging. We need to make sure that we have the logging module imported and we're going to configure logging with timestamps and severity levels. We also have, how can I say debug. That is very useful for when we want to as you would say debug our code. Let's go ahead and get started. Now, the first thing we want to do is we want to say logging. And we want to define the basic config. The level here, we're going to say level equals logging, and we're going to set this to T bug. Okay. So that's a parameter that allows for all log messages, debug and above. Okay. Right. So now what we can go ahead and do is we can just add in our comma and now we need to add in our format. So here I'm just going to say format, add in my quotes percentage symbol, and we want to encapsulate the log message format. So we want it to show SKT first. Could add in the S. Then we want to add in our percentage symbol, and we want to also output level name. So this is what you would typically see in the file, for example, and then s, go to the next one percentage symbol, inferences message, and then S there we go. So now we've got that format in place. Let me move that here. So you now know how to define that. Right. Perfect. That is the log message format that now we want to log messages with different severity levels. Let's do that. Okay, so I'm going to say logging dot and we'll have Dbug first. I'm going to say this is a D Bug message. Then I'll say logging dot info then I'm going to say everything is running smoothly. I'm going to say logging dot, and I'm going to say warning. This is going to say watch out for potential issues. Then we can say logging dot error here I'm going to say something went wrong. Then we can say logging, critical. I want to say critical failure. There we go. So now let's go ahead and get our output, save that file, run the code, and here we have it. We can see here that we have configured the time. We have configured the level name, and we've also configured the message, and that is all in one, two, and three sections. So that's going to encapsulate. You can treat this as the centurd symbols parenss with the format that we are setting it as. We can treat these as our placeholders for each segment that we are referring to. Now, the level name is going to be coming from debug, If the function that we have clarified here, as you can see, and the message is going to come from what you declare in that function. And that is how everything was output. And we can see the format is in ASC time, so that's going to show the year, the months, the day, and then the time that it went ahead and logged, according to debug info warning error and critical. All right, so there we have it. That is how we can implement logging. Go. That is it for this lesson on utilizing logs and how we can output various logs depending on our situations. 86. JSON: Hi, everyone, and welcome to the next lesson, which is going to be focused on JSO. Let's take a look. JSON stands for JavaScript Object Notation, and it is a lightweight format for storing and exchanging data. Now, it also uses key value pairs in a structured human readable way and it is also widely used in web APIs and applications. And another important thing to note here is that JSON supports several data types, such as strings, numbers, arrays, objects, and also booleans. So we're going to focus on JSON and how we can apply it in Hisen. So let's get started. 87. Working with JSON - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on JSO. So I'm going to show you three examples of how you can best implement JSON within PySon. Now, the first one is going to be focused on converting a dictionary to a JSON string. Then we're going to learn how to convert a JSON string to a PySon dictionary. And the final thing that we'll do is we're going to save JSON to a file and read JSON from a file. And that's going to be the really important one, since we're also going to use context managers here to carry out that process. Right, so let's go ahead and get started. So we're going to start off very simply and convert a dictionary to a JSON string. First, we need to import the JSON module, and then we need to create our dictionaries. I'm going to say data, and my dictionary is going to have the following key value pairs. First, we'll say name as the first key, and that's going to be set to honor. The second key value pair will consist of the He's the key, and the value 29, then we'll have the city, and I'll set that to ape um, right. So there we have it. There we have our dictionary. Now, what we can do is we can go ahead and convert this dictionary to a JSON string. And to do so, we need to first define a variable so we can assign the result that we'll get at the end from the conversion. I'm going to say JSON string equals. Then I'm going to refer to the JSON module, say dot and then I'm going to use the dumps method, and that is going to convert my dictionary to a JSON string. So I just need to pass through the data, it will convert it for me, and all I need to do is say print and then I'm going to say JSON underscore string. And that's going to output accordingly into a JSON string for me. So now I can do is I can go ahead and run my code, and there we have it. So now it is in a suitable JSON format. Right. Perfect. So just remember that JSON is always in double quotes and not in traditionally single quotes. And this can be very useful if you want to send your JSON data to a web API or to store JSON as text. Right, so that's how we can go ahead and set it up. You can see here the full code that was utilized. You can see how you can go on ahead and convert your dictionary to a JSON string. The next thing that we're going to do is to go ahead and convert your JSON string to a Python dictionary. All right, let's go ahead and do that. So what I'm going to do is can remove this code. We want to utilize the JSON module still. But what we're going to do now is we want to specify our JSON data as a string formatted as JSON. I'm going to say JSON under scare string into equals, and what we're going to want to do is first of all, add in single quotes. We need to add in single quotes and then within that, we can define our dictionary with our JSON data. This is just how the string needs to be if you want to convert it to a dictionary. I'm going to define the key value pair so we will have name. And that's going to be RNO, then we're going to have age, colon and that's going to be 29, and then we'll have city, and then that's going to be Capetown. There we have it. There is our JSON string. Just remember the quotes at the end are very important and make sure you got everything set up. There we go. We're good. Okay, now we want to convert the JSOString into a dictionary. And what we're going to do is just store this all in the data variable. We're going to refer to the JSON module and then the loads message that comes from it, and we're going to pass through JSON string. Okay, so JSON that loads, is going to allow us to convert that JSOMString now into a dictionary. So that's what's going to happen now. We've passed through that JSON string, and it's going to be converted into a dictionary. So all that we want to do is now print the data, first of all, I'm going to say print data. And run this code. Here we can see we have a regular dictionary in PySon as you can see. Now, key detail to this is you can now see that it is in single quotes. While in PySon technically, you could go ahead and set up your dictionary in terms of double quotes. You can do that, but generally the default with PySon is in single quotes and that's a good test to see that it's now in PySon and it's been configured correctly. Can do now is we can access individual values from the dictionary, so you don't need to go ahead and say data as is. You can just add in your square brackets and you can pick from it. It would be your keys that you would refer to, and then you will get the value back. If I want to get my actual name value of no, I would need to put a name here and run code. The outputs directly for me name. If I want to get city, which is Capetown, and I run this, it will output Capetown. Right there we go. That is how you can convert a JSON string to a Python dictionary. Now, the important one of the lot and the most fun one, I would say, that's to save JSON to a file and read JSON from a file. Let's get started and create a dictionary, first of all. I'm going to say data equals, and going to open this up, add in my key value pair, name. Con no. Then we will have age, colon, 29. Then we're going to have city colon. We're going to have Capetown, and there is all of our data within this dictionary. Now, next thing that we want to do ascie. We want to save our data to a file, of course, and we're going to say Wi open, then the file that we want to create. I'm going to say in quite data dot JSON. And I want to write to this file. So the mode is going to be W. And I'm going to say as file, I'll call this as. So it's also going to open the file in write mode. And then we want to refer to JSON and we want to use the dump method here. JSON dump is a message that is going to write the JSON data to a file. And to do so, we need to pass through data and then the file because we want to grab this data and we want to write it to our file. And that's going to write the JSON data to the file itself. Okay. So let's go ahead and write it to the file first, check our directory, then we can read it afterwards. So we can now run the code. Let's go to our Explorer. And here you can see we have data JSON, and we can see it's been saved to our data dot JSON file. So we can see name on age 29, study Capetown, and there we have it all saved. Now, let's say we want to read this data back from the file and read it in the terminal, for example, so right here on the output terminal. Close this, go to our next statement, and we can go ahead and say, Wiz, open. We want to open that file. The file that we want to open is called data dot JS on, and we want to read it. In our curtesy, we will say R, we'll say as file, and we can then just define a variable called loaded underscore data, and we're going to set that to JS dot load. We're using the dot load method, and that is going to allow us to read JSON data from the file, and it's also going to be converted to a dictionary. I'm going to say file. Okay. Then all we want to do at the end is print that loaded data. I'm going to say print loaded underscore data. Let's go ahead and run this code. There we go. We can see we've got the data and also back in the default version for dictionaries in PySon. Like I said earlier on, it's going to be in single quotes and that is a good indication that it has been converted into a dictionary for us for Python equivalents. Right guys, that is essentially it. That's how we can utilize JSO. All right. There we have it. I'll just go ahead and remove this code. All right. There we go. 88. Queues: Hi, everyone. Welcome to the next lesson, which is going to be focused on es. So let's get started. So what is a Q? A Q is essentially a data structure that follows the first in first out principle. You may have heard before of a principle known as FIFO, so that is standing for first in first out, and that is what a Q follows. Now, it can be very useful if you're focusing on char scheduling, buffering, handling, sequencion data, and it can also be implemented using qt iss or collections dot dq. Now the key operations include NQ. This is for adding and DQ, which is removing, and this is going to pertain to certain elements. Let's go ahead and take a look at example here, so an analogy and then look at the associated PySonPgram for a Q. Right. So let's say we have a lot of people standing in a queue to vote. So everyone is standing in the queue and you could see it as a FIFO system. So first in, first out. So the person that first stood there at 3:00 in the morning in front of the voting booth was the first out. The second person, of course, eventually became the first person, and they went out as well. So a queue. If we were to create a Python program, we would create something bearing the following where we would go ahead and grab the Q module. Then we can import the Q class. Then we can create a Q, so we create an instance of a Q. Voting Q is going to be equal to Q. Then if people join the Q, which is NQ, we can just refer to our instance and say dot put, we can utilize the dot method, which is essentially going to perform NQ. And add people to the queue. And that's going to be in the order. So Alice, Bob and Charlie. And then let's say those people have casted their votes. They're going to leave the Queue, that's going to be an act of DQ so then we can print out the order they're in. So we can refer then to the instance that we created of Q and utilize the dot get method. And that's going to then output in order who was first in and who was first out, and it's going to go in order of Alice, Bob Charlie, whoever was first in, and it's going to output exactly the same there when we say so and so casted their vote. Right. So that's a very simple analogy that we can utilize to understand the concept of cues. So that's on the theoretical overview. 89. Querying queues - [Lab]: Hi, everyone. Welcome to the next practical exercise lab, which is going to be focused on Qs. Let's get started. The first program that we're going to make is going to cement our knowledge on how we can create a basic Q and most importantly, how we can utilize the put and the message to NQ to add to a Q and DQ to remove from a Q. The first thing I want to do is I want to obtain the Q modules. I'm going to say from Q, and I want to import the Q class from that module, and it needs to be a capital Q here that indicates it's the class. Then what I want to do is I want to create an instance of my Q. I'm going to define a variable called voting underscore Q. I'm going to set that to the class Q with opening and closing parentheses. Next, I want to add to my Q. I'm going to say voting underscore Q dot PUT. Then here within the pareneses I'm going to add to the Q I'm going to say on and voting underscore Q dot p, I'm going to put John and then voting underscore Q dot p. I'll put Sarah. There we go. Now what I want to do is I want to go on ahead and deque. So I want to remove from the queue and see what I'm obtaining each time in the queue, who is being removed. So I would add in a print statement, and I can just say, voting understore Q. I want to refer to that particular variable here that we have that we created an instance of the Q class. Then what I want to do is say dot G. I'm using the G method. After I have set the G method, I can add in a comma and then I want to say cast their vote. Essentially, what's going to happen is it's going to get to whatever value of the person that was first put on the Que which is Ro it's going to get no it's going to say no case vote. If I were to go ahead and run this, it's going to say a care vote. But even if I were to repeatedly run it, it's going to keep on saying ono car say vote because you need to explicitly keep on printing and running the dot get message here three times or the total amount of times that you have put in the queue. Hence, you can see the first in first out sort of logic. So now if I go ahead and copy the first statement second time, I was going to say no Cars vote, then John Cars vote. And I would need to do it a SRT to get the last person, so that will be Sarah. And we can see Ana Cars vote, John Carsey vote and Sarah Cars vote. There we have it, and that is performing DQ. Alright, so there we go. So that is how you can perform the basics of queuing with putting and getting. Right. Okay, now let's go ahead and explore the other methods that come with a Q. So what I'm going to do is remove the following and here by voting Q, I'm just going to adjust this to has Q. And you can set a parameter in your Q here. Okay. And I'm going to set this as max size, and this is where you determine the max size that your Q can be. Now we want to add items to the Ques, I'm going to say task underscore Q, and I'll say dot put, and I'll set here task one. I'm going to copy that two more times. And we can say two, and we can have three. We have three items in our Q or three tasks. Let's say I want to get the size of my task here. What I can do is say print and I can say Q size colon space here, then I want to refer to task Q and use the dot Q size method that's going to output how many tasks I have. I'm going to say run code. I can see Q sizes right now. This isn't going to print the max size. It's going to be the size of your que that you set up here. If I were to remove a task and run it, it's going to say que sizes too. I analyzes how many items have been put in the queue by using the PUT method. Right, there we go. Now, let's say I want to check if the Q is full. I can just go ahead and say print, and I'll say is the Q full. I can say task underscore, Q, and I want to go ahead and say dot full. Okay. And it's run. And here, the queue size is three and the Q is full because the max size has been reached of three. But if I were to remove an item and to run it, Q size is two and the Q is not full, it is false, so it is not. All right. So when you are calling task, Q here, when you are calling it, it's going to automatically recall what you have in your and how many items you have in your u. So this variable is going to keep track of that, and all we're doing is we queering it by looking and applying these methods towards it. Ch, that's perfectly fine, and I just want to put back the final que. Now, what I want to do is I want to remove and process tasks. I'm going to say print. Task underscore q dot Get. We're using the Get message and I'm going to say is completed, right next to that. It's essentially going to get whatever we put as the first item here in the put messag, that's task one. So it's going to be Task one is completed. Then if we get the next one, it's going to say Task two is completed. I'm going to do that for the first two. Okay. And then what I want to do is I want to go ahead and check if the queue is empty. So I can say print and we can say, is the Q empty. I'm going to add the comma, and I'm going to refer to task q dot And let's go ahead and run this. And here we can see Task one is completed. Task two is completed, and is the Qu empty false? Because it has all of the items have not been completed in the queue. Only the first two, task one and two. We haven't done three. That's why it's not empty and it's returning false. Right, so what we can do is then just use the following statement for task three to be completed. And now if we run this, we can see task three is completed. So now we can go ahead and check again by using the empty method. Save this and run. Now we can see task three is completed before it was false because it wasn't completed. Now the queue is empty because all of the tasks have been completed and it is empty and it is available. There we have it. Just a few more methods for you to utilize. Remember on top of do and dot g you get dot empty to check if a queue is empty. You also get dot four to check if a Q is full, queue size to output the current queue size. You can also set the parameter here of the maximum size of your queue that you want to set. All right. So that is a little bit more on Qs. So let's go ahead and remove that following. All right, guys. So that is it on Qs. 90. Recursion: Hi, everyone, and welcome to the next lesson which is going to be focused on recursion. Let's take a look. Recursion. Recursion is essentially a technique where a function calls itself to solve smaller sub problems. Now it repeats until a base case is reached, and this helps to prevent infinite calls from occurring. Now, important thing to note here is that recursion can be applied in many contexts. I mean, you can utilize in tree reversal, factorial computation, and also in various search algorithms. Right. So that's on the theoretical overview, let's dive deeper into the lab exercises. 91. Performing recursive calls - [Lab]: Everyone. And welcome to the next practical lab exercise, which is going to be focused on recursion. So let's get started. Okay, so with recursion, usually we will have a base case, and that is what we are going to be evaluating within a function, and then we'll have our recursive case, or our recursive call. And this is what we're going to go on ahead and evaluate against it. So we're going to utilize the base case and equate it to the recursive core. Okay, so let's go ahead and get started. Let's create a simple program to begin with, and we're going to call this function count down. We're going to have N as a parameter. And I'm going to put this in comments so that you start to learn. So we'll have a base case, and that is going to be in this case, if N is equals to zero. I'm going to print let's say blast off. Then once it prints blast off, I want to stop the functions, I'm going to say return and that's going to execute and prevent the function from continuing. Then I want to define my recursive call. Essentially here I want to print my current number. I also want to call the function again with N minus one. To do so I can just refer to the function here and say N minus one. Then I need to pass through an argument outside by calling the function, so I can say count down and I can pass through five, and this is what's going to happen. I'm going to take five as an argument, pass through as a parameter by N. Check the base case, which is if N is equals to zero, print blast off, and then return and stop the function. However, it is not the case, so it's going to not execute this if statement and instead print N, whatever the associated argument is, which is five, then it's going to call the function again, countdown and say five minus one, which is going to be four. Then it repeats the whole process again and goes four, four is not equal to zero. Then it's going to print four, countdown, four minus one, that's going to be three, is now three. If three equals to zero, which is not, print N, which is three, count down three minus one, two, go back. N is, of course, going to be two, then what it's going to do is say I N equals two, no's going to then print N, which is going to be two, countdown, two minus one, that's going to be one, and then we're going to go all the way until we get zero and once it's zero, it's going to say print blast off and then end the function. That is how a basic recursive program works. You have your base case and you have your recursive call. Now let's go ahead and save this and run. So you can see here we have five, four, three, two, one, and then blast off. So you can see here when it says print N, that's going to be each time it is a number after it has been subtracted. So first, it will be five, five minus one is going to be four. Start the evaluation with four, four, and then four, print it out, and just keep on with that same process until we get to blast off and return to exit set function. So that is essentially how this program works. Edge. So that is the essentials of recursion. All right. Now we're going to do a few more examples so we can build up our knowledge of recursion. All right. Now the next program here, what I'm going to do is set up a count up function. So let's go ahead and do just that. I'm going to say Def count up, and we can actually put in underscore here, and it's going to take in Well, it's going to have one parameter that's taking in, but we're also going to have a default argument set here, and I'm going to set that as current equals to one. Okay. Then my base case, I want to say if the current is greater than N, I want to say print done. So when we reach N, I want to print done, and then I want to return, which is going to stop the function. So now I'm going to say print current, and I'm going to call the function, which is count up, and I'm going to pass through N, and I'm going to say current plus one. Okay. So here what we're doing is we are calling the function again with current plus one and we need to pass through an argument to start off with count up, I'll say five. We're going to have five and remember this is our recursive call. I'm passing five is an argument. We have five here and we have current which is set to one if current greater than N, we have five. It is not the case, we're going to go to the recursive call. We're going to print current current of course, is going to be one. Then what we're going to do is we're going to still pass through five here. Then we're going to say current plus one, which means it's going to essentially be two. Now, nothing happens to the N value here because essentially the N value is going to still be five. But current, of course, is now going to be two. So current is going to be two and the value here of current will now be two. So if two greater than N, print, it's not. So we're going to print current, and it's going to be two counts up. We're going to still have five and current plus one, it's now going to go ahead and repeat, and current is going to be three, and it's going to be three here, and it's going to always be five and then current plus one, we're going to now have four, and until it is six, okay, it's going to then print done all the way when it is up to six. I also want to print N for you so you can see that this remains at five. So if I were to say print N, you'll see that result as well. So maybe I should put in some texture to make it easier. So let me set this in an F string, actually. And I'm going to say current is. And I'm going to go ahead and just just it and NN is and there we go. So let's go ahead and run this. Okay, so we can see here. Current is one because that's what we said at the default N is five. Going to get added to one. Current is two and is five, current is three and is five, current is four and is five and done. Okay. So when we have six, okay? So if the current is six, which is greater than N, it's going to print done. So it's not going to have a chance to print down here to show current is five. So technically speaking, we can actually call this and say here, the final current was. And if we run this, you can see here it says the final current was six. That's where it got to in the end as it was greater than five. If it was greater than equal to, that would have been another story. But that is how we can also use a base case, set up our recursive call, and how we can go ahead and create a program that counts up. That's another way we can do it. Now, let's go ahead and do another example and that is to repeat a message with recursion. We'll define our function, which is repeat underscore message, and we're going to pass through two parameters, message and N, and our base case. If N equals to zero, I want to return. I'm going to stop when N reaches zero. That's all I'm going to do. Then my recursive call is to print the message, and we want to call the repeat message function, and we want to repeat this, and we're going to call the function again with message and minus one. So now we call the function outside, repeat message, and we pass through our argument, so we will have hello that goes to message, and then we're going to have three, which goes to N. So let's work this out. So hello is the message. N is three. If N equals zero, return. It's not the case. So we're going to print message, so it's going to be hello. Then we perform the recursive call and pass through the message, which is hello. And then we say minus one. Okay. So what we have now is three is now going to become two. So then we evaluate. If N equals zero, return, print hello, repeat message. Going to say you pass through hello and minus one. That is going to then go to one. Return, repeat the function again, execute it again, print the message, hello again. Execute the function again, then it's going to start again at the base case. Then it's eventually going to get to a point where it's zero. Then it's going to return, and you'll see here that the message hello will be printed three times here, we said minus one, and we've just repeated the function to go again and again and again. All right. So that is how we can use that recursive call in this case. Right. Okay, so that's it on recursions, as you can see, you will have your base case and you'll have your recursive call. And these and implementation of recursion, like I said, it has a lot of fields in which you can utilize and use cases, but it's very helpful if you want to repeat your function and to execute it until a certain case is reached. Right, guys. So that's it on recursion. 92. Comprehensions: Hi, everyone. And welcome to the next lesson, which is going to be focused on comprehension. So let's take a look. All right. So we get two types of comprehensions. We get list comprehensions, and a list comprehension is essentially a shorthand or short way of creating a new list in a single line by transforming or filtering the elements or items from an existing iterable. Now, the syntax will be as follows. You'll have your expression, then you will have four HM in your itchb then of course, you can also have an if condition as well. You can see it's all written in a line for you. You don't have to go on a head and define, for example, your four loop, your if statement and do that all in a sequential fashion. You can now go ahead and put this all in a single expression. We also have dictionary comprehensions and a dictionary comprehension is going to work in a similar way and it's going to generate key value pairs in a single line while applying filters or transformations. Now, it has a similar syntax. You'll have your key expression, your value expression, and that's going to be four item in its, you'll have your loop as well and the optional if statement as well in terms of the I condition that you want to utilize. Comprehensions. You can almost try to compare it in the sense of how Lambda is to functions. We can see comprehensions with dictionary and list comprehensions. We can see that it's also going to be a simpler approach when we want to have single lined expressions where we want to apply for loops and if statements and to also make sure that we can generate that by setting it up as a list or a dictionary in the process. 93. Using list comprehensions - [Lab]: Hi, everyone. Welcome to the next practical lab exercise, which is going to be focused on list comprehension. Remember, list comprehension, we have our expression, then we have our fol, which is going to be for the item in the iterable, and then we can also add in an if condition, which is also something that you can add in if you want to add in some filtering. Okay. So the expression part, that's going to modify or transform each item and usually into a list. And then the four item in each part, that's going to loop through the list. And that's going to provide the values for our expression. Right. So let's go on ahead and get started with a few examples. Let's say I have a list of numbers, and I have one, two, three, four and five. Then I want to create a new list where each number is squared. So I'm going to go ahead and define this variable called squared numbers, which is going to essentially be the new list. And to do so, let's perform some list comprehension. Now, the first thing we need to do is define the expression. So what do we want to do? I want to say Num multiplied by Num. So I want to multiply two numbers. This is going to come from the items in the numbers list by the four loop which says four num in numbers. That's how we're going to obtain our values or items. We're going to run this four loop and Num of course, is going to as the output goes, grab each value and then we can utilize it in our expression here, which is going to store each value with each iteration in the list at a time. Let me show you what I mean. In a comment here. So we have one, two, three, four and five. So four num in numbers. First, we're going to grab one. That's going to be the first number that's going to be looped. Then we're going to take one and say one multiplied by one. It's going to be one. Then we're going to loop to the second item, which is going to be two. So we've grabbed two here from this four loop, and then we can say, with the expression here on the left, two multiplied by two, that's going to give us four. Then we go ahead and look at it again. Then we have three, and we've looped through and we've collected three, and now we're going to say three multiplied by three, it's going to give us nine. Then we move on to four since that's the next item in the four loop, we're going to grab four and say four multiplied by four. That's going to give us 16. Then with our four loop we're going to loop through it and we're going to grab five. Then we can say five multiplied by five, that gives us 25. If we were to print squared numbers, which is now going to be a list based on the result that we've set accordingly here, we can go ahead and run the code and here we get one, four, nine, 16, and 25. That is the simplest way in which you can perform list comprehension. To elaborate again, on the left, we have our expression and that's going to square each number as we saw on the right hand side, we have our iterators that we are defining was our four loop to pick numbers one by one and the result is all stored in the squared numbers variable, which is essentially going to be of a list data type, and then we print out the output and all of that is going to be stored one by one in the new list. Let's do another example. Let's say we have words and we have hello, we have world, and we have pyson. Let's go ahead and create a list where each word needs to have an explanation point at the end. I'll just define a variable called excited words. We need to first define our expression, which I prefer to do first. I'm going to say word plus and we put the explanation point. This is going to be based on the loop, which is going to loop through all the words for word in words. Okay, so here we go again. So we're going to run this for loop, and we're going to temporarily store hello and then we're going to grab it and utilize it here in our expression and say hello, plus, and then the explanation point. That's going to then store it in a new list that's going to say hello. Then we're going to run this program again for word in words and then we're going to grab well. It's going to be stored in the variable word word, and then we can just say word plus, and that's going to be as follows. Then we're going to run our four loop again. Word is going to be stored in PySon. We can then just say PySon plus and that's going to be as follows. Let's run our list now. Excited words has a new list. That's going to say hello, world and PySon. That should there we go. And that's going to be your output. You should be able to get an idea for the pattern here. Okay, great. Now let's go ahead and do another one. This one is going to be to convert to uppercase. I'll have fruits and I'm going to have apple Pare orange. Now I want to go ahead and create a new list. So I'm going to call this upper case underscore fruits. Alright. So we can go ahead and define what our expression would be, I would say fruit dot upper. And our loop would be four fruit in fruits. So let's have a look at what we're doing here. So four fruit and fruits, we're going to go through each of the items independently. So apple, we're going to store apple, and then we're going to say apple dot upper with this dot upper mesod and that's going to change it into apple which we'll store in our list. Then we continue for fruit and fruits. Fruit is going to then be stored as pear pair dot upper, that's going to be pear. Run our four loop again and then we're going to grab orange, that's going to be stored in our variable, and then we can say orange and upper. It's going to be orange. Now if we print upper case underscore fruits and run this, we can see we get apple, pear, and orange all in caps in our new list. That's the simplest way in which we can go ahead and get started with list comprehension. Remember left side is your expression. Right side here is going to be your four loop. Right. So we've got that into place. Now, the next thing that we're going to want to do is we're going to want to work with an if statement in this regard. So let's go ahead and look at that. Right, so let's add in a spanner in the works. So we want to work now with our if conditionals, as well. So let's define a list of numbers, and I'll say one, two, three, four, five, six, seven, eight, nine, ten. Now we want to only keep numbers that are even so we can define our new list by the variable even numbers. And we're going to go ahead and say num, num in this case is just going to act as a placeholder to be passed to our list in terms of the final result per iteration that is calculated. So we're going to say four num in numbers. If num, and we're going to add modulus two is equals to zero. So we want to check for even numbers is what we're doing here. Okay, so let's go ahead and branch in ahead how we're doing this. We have all the items here in our list here and we're going to say four num in numbers, and we're going to look for one. We have one here and we're going to then check this if conditional. If one is, of course, an even number, then what we're going to do is store it in the placeholder here of num and then we will add it to the list. That is the process here this time, the expression here on the left is acting more like a place order, I was before, but before we went ahead and performed actual actions and then stored the final result, but it's like a place order now for storing the final result that we will pass over to our list. So in this case here, it's not the case, so we're not going to store anything in NUM at all because it is going to fail. If it is true, then it's going to store the result you could say in NUM which is then going to be passed as a list, but in this case, it's not going to happen. So we go to the next one. So two. So four number numbers, we have two. Then we're going to check if two is an even number and it is, so we can store it in num and say two. Then we go to four, and we're going to say four number numbers, and we're going to then we're going to go to three, excuse me. Then we're going to check if three is an even number. If it is not, it's going to fail, and then it's just going to re run our follop again, which it isn't. Then we're going to look at four, and we're going to say if four an even number. It is store in the result for num. We can say four. We have five and we keep on doing the same result until we get four, six, eight, and ten. We're going to do the same pattern. Let's go ahead and print this out to see if were correct. I can say print even underscore numbers and it's run this. There we go in our list, we have two, four, six, eight, and ten. That's how we can go ahead and utilize it. Now, let's say we want to make this more interesting and we only want to keep words as more than five letters. I can define a list of words. I'm going to say Apple and I'm going to say banana and kiwi and grape and pine apple. And pair. So we have quite a lot there in our list. Now we want to define a new variable that's going to essentially be a list. We want to only keep words that have more than five letters in this case. So we're going to have word as our expression for word in words. So we're going to loop through all of these items, store it temporarily as word here. And then what we're going to do is we're going to check if the length with the function here of the word is greater than five, and if it is, we're going to refer to word here as the placeholder and then add to our list. All right, so let's go ahead and get started with our tests. Four word in words. We have Apple. If the length of the word is greater than five, we can then go ahead and store it in we can utilize word here as a place soldier for storing it to our list. Apple is one, two, three, four, and we're going to have five. So it's not greater than, we move on to the next one, banana. Four word in words. Next, banana. If the length of the word is greater than five, you can use Word as a place soldier and we can put it in, so one, two, three, four, five, greater than, but non. KV is four, so that's not going to work. Grape. That is going to be five, not going to work, pineapple. Four word and words, we go through each one and if they fail, we don't go ahead and use Word as a placeholder to store it in our list. Let's go ahead and look at pineapple. Yes, that's going to be greater than five. Use word as a placeholder and we can put it in mix. Then we have pair, which isn't only going to have in our output the following. If I say print long underscore words, that's going to output banana and pineapple and that's what the result will get at the end. Right, perfect. So there we have it. That is how we can also utilize an if conditional as well if we would like if we want to perform list comprehension. So there we have it. There are the examples the expression, our four loop, the iterable, and our if conditional. Alright. So that's how we can perform list comprehensions. 94. Using dictionary comprehensions - [Lab]: Hi, everyone. And welcome to the next practical lab exercise, which is going to be focused on utilizing dictionary comprehensions. So we are also going to follow the same structure like we did with list comprehensions to start off with our expressions and our for loop first, and then later on utilizing an if statement as well. All right, so let's keep it simple and get started. So first, I'm going to find a list of words. So I'm going to say hello. Good. Bye. And I'm going to say, welcome. Then I want to define my dictionary. I'll give it the variable name of word Links dict. So essentially, what I'm going to be doing is I am going to create a dictionary with word inks. Okay? So we'll have our dictionary open as follows. We're going to have our key value pair, and then we'll have our for loop. Now I'm going to say my key will be word. Then I'm going to use the Lang function to get the total length of characters of the word, and this is going to be completed after we have run our for loop as follows. So again, I'm going to put in an option here so we can track everything. So here are other items or elements you can refer to them as in our list. So we're going to run, first of all, for word in word. So we have word here and we're going to temporarily store hello. Then we're going to move hello here to the key, and that key is going to go into our new dictionary and it's going to be as hello. Then the colon here to separate the value. So we're going to get the length or the lengths of hello in characters, that's going to be five characters. Run our loop again. Word. We're going to grab goodbye, store it as word, and we can then permanently store this in our list. We're going to send it to our expression here. Our expressions here are essentially the placeholders. We are going to grab it from the four loop here, store it in word temporarily and then move it to our expressions, we will then move it to our dictionary in this case. Here in our placeholder, we're going to have goodbye before we move it to our list. Here we can say good why? Then what is the length of goodbye? It's going to be seven characters. Then for word and words, we're going to then grab welcome and then we're going to move it to our placeholder of word, which is then going to be welcome. Then we're going to plug it here for the value of the lengths of welcome, which is going to be seven. Now if we say print, we underscore lengths, underscore object. We get this dictionary here, this new dictionary, hello five. Goodbye, seven. Welcome, seven. So it's in key value part. So the keys being hello, goodbye and welcome. And the value is being five, seven and seven. Right. So that's a simple way for how we can do it. Let's go ahead and get some more practice. Let's say we want to go on ahead and do a number to string representation, for example. So I'm going to have a list of numbers. And I'll have one, two, three, four and five. Then I'm going to create a dictionary where the numbers are keys and the values are strings. Okay. So let's do this. I'm going to say number underscore words, and we'll have a dictionary of that. So we'll first have the key. That's going to be num and then we're going to convert to string, the number itself, and we're going to say four num in numbers. Okay, so let's take a look here. Four number numbers. These are all as we can see integers in integer format. We're going to say four number numbers and we're going to collect Num, pass it over to num here and we're going to store it in our dictionary, just as is. We will have one as our key. Then the value here is also going to technically be one, but we're going to cast it to a string, it means it's going to be in quotes that value. Then we have four num numbers. Go to the second result, which is two, take two, pass it to the place holder so we can store it in our new dictionary. It will be two. Then we're going to convert it here to a string for the value and that's going to just be in quotes two. We do the same thing for three, so let's go ahead and do that. So for number numbers, next, we have three, grab three, pass it over to our place holder here, and that's going to be three is the key. Then we're going to plug it here in the value, so we want to convert it to a string, and then we get three. I think you get the idea now, and we're going to do the same thing for four and five. So when we go ahead and print number underscore words, we get this dictionary, as you can see here on the following, one, one, two, two, three, three, 44, five, five, with the key remaining as an integer in its raw form and the values are converted to a string handset being within quotes. That's how we can go ahead and set that up. Okay, now let's go on ahead and do another example here, and here we want to map numbers to their cubes. Okay, so let's go ahead and do that. So numbers, equals, and we're going to have one, two, three, four, and five. Okay, now we want to create a dictionary where the keys are numbers and the values are their cubes. So I'll define a variable as cube dict. Okay. And that's going to be a dictionary. We're going to have num as the key and then num and then double asterisks here. So that's going to go ahead and ensure that we have the cubed result, and it's going to be two, three, four, num in numbers. Okay. So let's go ahead and do just that. For num in numbers, we need to make sure we have our how can I say explanation format? A four number numbers. First, we have one, grab one. Then we're going to pass it here to num and that's going to be one as the key. And one to one cubed is going to essentially give us the result of one. All right. Then for num in numbers, okay, we're going to have two. So we have two here, transported there as the key, two, and the value there. So two cubed is essentially going to give us the result of eight as the value. Go again, four number numbers. We're going to work with three now. Take three, move it to the placeholder, so we can prepare it for our dictionary. We take it there and that's going to essentially give us three and then we're going to say three, of course, cubed and that's going to give us 27. That's going to go ahead and do the same result for four and five. We can get the final output by saying print, cube dink there we get the following. We had one, eight, 27, and of course, we have 64 and 125, five cubed, four cubed, et cetera, and that's how we can map numbers to their cubes. Right. I think now we should be confident with the idea that on the left, we have our expression and on the right, we have our for loop and the iterable and we're just going to utilize our expressions after we have a result. If we have to perform some calculation, that final result will go into our dictionary, in this case or if we're working with lists into the list. If we don't need to perform a calculation, we can just simply go ahead and slide it in. Right. Perfect. Okay, so that's good. Now, the next thing that we're going to do is work with our if conditions. So let's get started. So I'm going to go ahead and say words, and we're going to have apple, pear, orange strawberry. And grep. There are all the items in my list. Now I want to create a dictionary where the keys are words and the values are their length, but only for words longer than five letters. Let's define that dictionary. I'll call it long words, equals here within my dictionary, we're going to have word as the key and then the lengths here of the word would be the value, and that's going to be for word in words if the length of the word is greater than five. Okay, so let's go ahead and work on this process. So first, we need to look at our four loop. So four word in words. So we're going to loop through all of these items in the list. So first, we have Apple. Apple, we can see is one, two, three, four, five. We can see that it is five characters. So if the length of the word is greater than five, then we can go ahead and make use of this particular expression. If it is not the case, if it's false, then we just move on to the next item in the loop. Okay, so false, we don't continue. If it's true, we only add true to our new dictionary in this case. We move to pair. We can just see pair is not five, so we can skip orange, one, two, three, four, five, six, orange. For word and words, we have orange. If the length greater than five, it's six. Then we're going to set that we're going to substitute that or send it over to word as the placeholder to pass through our new dictionary that we're creating and that is going to essentially be in quotes. We're going to have orange. Colon. And then we need the length of the word there. So in our case here, it's going to be six. Then we can add in our comma. Then we go to strawberry. We can already see that's greater than five, so we can see one, two, three, four, five, six, seven, eight, nine, ten. So four word and words. We're now on strawberry. It's greater than five, it's ten. So that particular word, we're going to take over here to word here, and now we can actually add the word to our dictionary, strawberry. And the value here, the length of it is ten characters, so we can say ten. Right, let's con chin. Then we have grape, and grape is only five, so that's not gonna work. So we'll only have these two items. So we can say print. Long words. And there we have it. We have our new dictionary with our key value pair, our key here being orange, value six, key being strawberry, value ten. All right, there we have it. Okay, let's go ahead and do another one. And that's going to filter even numbers and double them. So we'll have a list of numbers one, two, three, four, five, six, seven, eight, nine, and ten. Then we want to set up a dictionary where even numbers are keys and the values are double their value. So I'll set the variable as double evens. This is going to essentially be a dictionary, so we'll have Num. Then we'll have Num multiplied by two for the value, and then our loop will be four num in numbers if num add the modulus two double equals zero. We're going to check if it is, of course, even as well. That's the filter at the let's go ahead and do the calculations. Four num in numbers. Let's go through them. We have one. Now, if num is even, we can go to the expression, but it is not so we can skip. Four num in numbers, we're going to two. If the number is even, it is, it's two, so we can move on here. The num will be two, that will be the key because we're working with a dictionary, and that's going to be two, two times two, that's going to give us four. Eight. Let's go to the next one. Three, three is not even even. So what you can do is you know that if you look at the I conditional, you can automatically just check there quickly to see if it's going to match a certain case, and if it doesn't don't need to worry about completing everything and assigning it. Four is going to be even. Four nomen numbers, we've checked three, we're going to look at four. It is even according to our if conditional. We're going to place four as the key. Then we're going to say four times two. That will be the final result that we store here and there we have four. Five is odd, six is even. We can say four num in numbers. If number is even, six is. Then we can move six here to the placeholder of num, which means we can put it into our new dictionary, which is going to be six as the key. Then we would say six times two, and that's going to give us 12. Okay, so that is a process that we follow on and on and on. We only have eight and ten then to evaluate. So let's go ahead and print this out to see the result. So double evens. And let's go ahead and run this. And here we can see we've got that result. So we did the first up to six here, and then we have eight, 16, ten and 20. So we could see that eight and ten are going to be sent to the place order of Num passed into the new dictionary, and then 16 and 20 as well. Okay, so 16 and 20, we can see it was derived by multiplying eight by two and then ten by two as well. Right, guys. That is it. That is how we can utilize dictionary comprehension. As you can see, it's quite a simple process and how we can utilize it. That's it. 95. Threads and processes: Hi, everyone, and welcome to the next lesson, which is going to be focused on threads and processes. So let's take a look. Right, so the first thing that we need to understand is what is a thread. So a thread is essentially a lightweight unit of execution that runs independently while sharing memory with other threads. So you can try to think of a thread as a worker on an assembly line where each thread handles a task and multiple threads can work simultaneously to speed up processing. Now let's take a look at the benefits of threads. So threads within a process used the same memory. They consume fewer resources and are efficient. They are also very ideal for specific tasks that require waiting on input or output. And another important thing to know is that starting a thread is quicker than launching a process. Now let's take a look at the limitations of shreds. Now, threads take turns running due to the global interpreter lock commonly referred to as the GIL. Threads can't be forcibly stopped once started, so that's the unfortunate thing where threads are concerned, unlike a process which can be stopped. Once started, a thread cannot. And an important thing to know here is that shared data can cause unpredictable issues. In other words, raise conditions which can occur if data is being shared. Now, there is also no speed improvement for any CPU intensive work that is occurring with threads. Now, let's take a look at processes. So a process. A process is an active program with its own memory and resources. Now, a simpler way of looking at a process is to think of it like a separate app on your computer or a specific background sort of utility, where each one runs independently without sharing memory with others. Now, in terms of the apps here, I'm referring to, for example, let's say you have Microsoft Word open, that would be counted as an app, or if you have also like an application like Discord open or if you were to have Spotify open or steam or Google Chrome or anything like that, you can kind of see it in that sort of regard. Now there are quite a lot of benefits of processes, so let's take a look. So they can fully utilize multiple CPUs and cores. Each process has its own memory, so this helps to keep its data separate. It is also very ideal for tasks that require heavy CPU processing unlike threads. Important thing to note is that processes can run independently without relying on each other. And they can be stopped or interrupted at any time, which is one of the best benefits that you could have in regard to processes. Each process has its own gel, GIL, avoiding Pythons threading limits that are imposed. Now there are also, of course, some limitations of processes too. We can see that processes use more system resources in comparison to threads who use less. Also, if you want to go ahead and create a process, it's going to take longer than starting a thread. Another thing that's unfortunate is that each process requires more memory since they don't share it. Communication between processes is quite complex and it requires extra handling, unfortunately. And the last thing I want to mention on a limitation of processes is that to switch between processes can be quite slow, and this will have an impact on performance due to overhead. Guys. So that's it for the theoretical overview. I just wanted to take you through the theoretical oversight in terms of what threads are, what processes are, and to give you some information on their benefits and limitations. And as you can see, it's almost as if where one suffers, the other thrives, you could say. But in any case, that's all for this lesson. 96. Multi-processing: Hi, everyone, and welcome to the next lesson, which is going to be focused on multiprocessing. So let's take a look. Right, so multiprocessing enables a program to run multiple processes independently, each with its own memory and resources. Now, it also maximizes CPU usage by distributing heavy computations across multiple cores for better performance. 97. Multi-threading: Hi, everyone, and welcome to the next lesson, which is going to be on multi threading. So let's take a look. Right, so multi threading is a system that enables a program to run multiple threads within the same process so that you can share your memories and also your resources. It also allows tasks to run concurrently without the overhead of creating separate processes. All right. So let's go on ahead and dive into the practical on multi shreading. 98. Integrate multi-processing - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on utilizing multi processing. So let's get started. First, we want to import the multi processing module. Then we want to import the time module so we can utilize the sleep function. Next, we want to define the function that's going to run in a separate process. I'm going to say deaf worker, it's going to be a function. All I'm going to do is call the time module and I want to define my sleep function and I want to keep the process alive for at least 20 seconds so that we can see it in task manager or in our activity manager. Right now the next thing we need to do is we need to ensure that the code only runs when this file is executed directly, and that's going to be seen as a process. And to ensure that that is going to be the case, we can utilize this if statement that says I double underscore name, double underscore is equalt or equivalent to double underscore main, double underscore. Okay, let me explain. So you're probably wondering what is double underscore name. So this is a special built in variable that we get in Python that's going to hold the name of our script or our module. Then we have underscore main double underscore. And this is going to check if the script is being run directly and that it's not imported as a module. Right. So it's very important that we have this without this check that we're performing here, the script could go ahead and keep creating new processes indefinitely and crash in the end. So it's very important that we have it. This will be seen as our first process, our Python script, and then our second process will be this worker function. So we can define that already. I'll say process one. And we can say this as process. Let's continue. Now, the next thing that we're going to want to do is to create a new process that's going to run our worker function. I'm going to say process equals, and I'm going to say multi processing. We're going to refer to that module dot, and we're going to refer to the process class and we then going to pass through the parameter target and set it to worker. Let's take a look here. Now process here is a class from the multiprocessing module, and it's going to be used to create a new process which it is currently doing by looking for a target, which is going to be worker as the chosen process that's going to be undertaken. Now, arget as I mentioned before, is a parameter, and that's going to specify the function that should run in the new process, which is going to be worker. They probably wondering, if this is a function, why don't we call it or add in the parentheses? So we are passing this worker function without parenses because we want to pass the function itself and not the result of actually calling it. Okay. Now, this process here that we have defined is going to be stored in this variable called process. Okay. Now what we want to do is we want to go ahead and start the process. I'm going to say process dot starch using the starch method, and that's going to start the process, and that's going to make it run in the background. Now, as soon as that process is started, we want to just add in a print statement to tell us that the process has started and that we need to check task manager because remember, we are only going to see it for 20 seconds. All right. So what we can do is we can just say print, and we're going to say process started. Then we can say check task manager. And if you are utilizing MacOS, it will be called Activity Manager, which you can check. Right next, we need to say process dot join, and this is a join method, and that's going to wait for the process to finish before continuing. So it will block any further code execution at the end, we want to say print process finished. There we go. All right, so that's all that we need to have into place here. So we'll have our default process in the background for Python script, and then the process that we actually created now, which is going to be a function that we are setting here accordingly. All right, so that is what we have here in place and ready to go. All right. Now, if you are in Windows, you can just open up your task manager. You can just search for it task manager, and you can open that up. Already have it open, and what you can do is make sure you're clicking on processes here on the left, and you can just type in Pierson and press Andrew. Now, as of now, is not going to show anything because we haven't executed our script once we have the script here is going to run as a process, and then it's also going to create a new process here by adding in this particular function. All right, so make sure you're good with all of that, and then we can go ahead and continue. Right. Now we can go ahead and run our code. Here it says process stated check task manager. You can see we have one background process and two processes here running and each of them, of course, are part to the Python script and this function that we created as well has also been put into place and we can also see some information here in terms of how much is being used in terms of megabyte. You can see it stopped, but we can just rerun it again. And go back and we can just go ahead and see how much is being used. So we saw that CPU for a moment there usage was like 0.2%, so it's very, very low and it went away. And we can see some information here in the memory section here in terms of how much megabyte is being used and overall for the background processes and them separately as well. Right. So there we have it. That's how we can utilize multiprocessing in pyson. All right, so that's that. 99. Integrate multi threading - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on multithreading. Now, of course, what I'm going to do is just adapt to the code that we had before for multiprocessing. A lot of the program that we're creating here is going to have similarities to when we utilize multiprocessing. We're going to make some adjustments and I'm going to tell you the new things here that is going to make threading distinct. You can just go ahead and keep your code the same as is and what we're going to do is just adjust it. Of course, we're going to work with multi threading now. We can just remove this module on multiprocessing and we can replace it with the threading module. This is going to allow us to create threads. Again, we're going to make use of the time module so that we can utilize the sleep function. Going to have a worker function like before, and we're going to ensure that we set the sleep timer to 20 seconds. Of course, we're going to still make use of our underscore name underscore, our special built in variable, should I say? A going to utilize that. Again, we're going to utilize double underscore main double underscore and that's going to like I mentioned before, make sure that the script is running and overall just going to make sure with this if statement that we don't have any crashers or anything of the sort. Next thing that we want to do is create a thread. Instead of saying process, we're going to say thread, and we're going to go ahead and replace multiprocessing with the threading module that we have. Then what we're going to do is replace the process class with a thread class. In this line of code, we're going to do the same thing, but we're going to create a new thread that runs the worker function as we did before. Then instead of starting the process, we're going to start the thread. We're going to say read starch here at the end, we're also going to go on a hedge and say shred dot join as well. We can just change here the text to say thread started. And thread finished. Okay, so that's the adjustments we have here, and we can just remove what we have here. All right. And we've got that out of the way now. So we've got everything as is. Now, there isn't really much different here, so with thread dot start, just to reiterate, it's going to start the thread. It's going to run in the background. And with thread dot join here, okay, essentially, we're just going to wait for the thread to finish before we just continue with the rest of our code. Okay. Now, another thing that I also want to go ahead and mention here is a little bit in detail with these message dot start and dot Join. Now, dot Start, is very important to be in place because if we do not specify dot Start, the thread will begin running. If we don't have dot join, then the program is going to exit before the thread completes its task. These are the reasons why we need it in this particular use case. Okay. And what we can do now is we can go on a hedge and run the code and see the output as it goes. All right. So let's go ahead and run this and see what occurs. Now, I want to make this a bit longer, so I'm going to set this for 30 seconds. I'm going to run the code. Check. As you can see, we only have one process here running. That is a good indication that we're using shredding because remember in the theoretical lesson, I said that when you are working with multi shreadingO threading, as a result, there is only going to be one process only and that threads share a process. Even though we have two threads here, I have one that we have defined with our function and our default script one with all Python scripts itself is going to be included as one. That is what is the reason for that. Just go ahead and run that's why we have it. We can see, of course, we have some memory here in terms of 3.9 megabyte as well and we can see it's not very heavy on the CPU, the disk or the network as this moment with this particular process. As you can see, that is how this is going a important thing here to remember, since we only have one process at going to share memory with the main process so this can be efficient. The reason why we only in place of one process only is because of the fact that Pison is using the gel, the GIL that I mentioned before. That is the global interpreter lock. That's going to ensure that only one thread runs at a time in a single PySon process. Even though we have multiple threads here, we have two of them, they're not going to appear as a separate process in the task manager. As you saw within that process, they're going to share the same memory space and work within the same PySon process. That's how we can differentiate as well the difference between our threads and our processes with multi processing and multi threading. All right. What we want to do now is just clean our resources so we can just highlight all the code here and delete that. What we can also do is just delete any other files that we have except for main dot pie, so we can go ahead and just clear them out. Okay. And the last one. There we go. Until we have main doppie. So if you have anything else, go ahead and clean it up. We're just performing a course sort of resource cleanup in the meantime. There's more to come, but we just want to clean everything up that we have here. All right, so that is it. 100. Unit tests: Hi, everyone. Welcome to the next lesson, which is going to be focused on unit tests. Let's take a look. Unit tests. In Python, unit testing involves testing individual components of code to verify that they function as expected. Now, a unit is typically a function or method that performs a specific task. And the next question that we're probably wondering is, why should you perform these unit tests? So I have a few reasons as to why we should do so, and they include to catch bugs early to improve code readability and also to make code changes much safer, guys. So that's just a bit of a theoretical overview in terms of unit tests, unit testing. And now on the practical lab excis which is going to come up, we're going to dive deeper into how we can actually apply this. 101. Perform standard unit testing - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on unit testing. Now, the first thing that we're going to do before diving too deep into unit test is we are going to go ahead and create a very standard unit test just to see how the process works, right. All right. Now, the first thing you want to do is you want to import the unit test module, which is a built in module that is used for testing. Then we want to define the function that we want to test. This function is going to be a simple add function to add two numbers. It's going to take in two parameters and it's going to return A plus B once it has been called. Now, this function will add two numbers and it's going to return the sum of A and B. We want to test this function. Now to do so, what we would need to do is to create a test class for unit testing. We can say class, test. Mass. Now, every chess case must inherit from the unit test chess case. To do so, we would need to go on ahead and pass through unit chest, dot, chest case, this is essentially a built in pyson class that we would utilize. That's going to essentially be inherited from unit test test case. We've got that now into place. The next thing we need to do is we need to define a test method now. Within this class, we need to say deaf and we can say chest, underscore ad. Now, something that you need to keep in mind here with your test messages underscore needs to always be the first part of the declaration here is your function at all times. What you put on afterwards, it's really up to you what you want to do. We are going to pass through self. Now, this is going to be a test method that will check if the add function is working correctly and the function name, like I mentioned, needs to start with chest and underscore for our unit test to recognize it as a chest. That is the reason why we need to add it like so. We have self again here because that's going to represent the instance of our test case class and it's going to give access to all the methods that are provided by the test class that we are inheriting here. Next thing that we want to do is we now want to go on ahead and set our method here by saying self dot, and we're going to use a special method known as assert equal, and we are going to pass through the function, which is going to be called add that we're going to play through here two and three as a sample, and then we want to have five. So what we're going to put here in the pareneses is going to be what we actually want to expect, and then outside is going to be the actual result. Okay. So the self assert equal method is going to check expected and actual result to check if the values are equal. In this case here, with what is being expected, we have two and three, for example, and two plus three equals five, and the actual is going to be five. That's what it should be. Okay. Now, if at two and three, returns five, then the chest passes. If it returns something else, then the chest is going to fail. Okay. All right. So let's go on ahead and continue. So we've got that setup. Now the next thing we need to do is right here on the left hand side, we want to go on ahead and run the chess. So to do so, we need to ensure that the script runs only when we have executed it directly. So to do so, we're going to say I double underscore name. Score is equals to, in double underscore main Okay. Now, what we're doing here is we're checking if there was this line here, we are essentially going to check that we are utilizing this Pierson script, and it is not a module or anything that we are importing, anything of the like, and it is seen as a special condition that we typically utilize in pyson. And it is something that we also utilize with processing and threading if we're dealing with multi processing and threading as well. It's going to ensure that the unit test main runs only when the script is executed directly like I mentioned before, and that's why we need to do so. Now, what we can do after that is we can define unit test, and we need to refer to it as main here, and that is going to be a built in function that we need to use, and that's going to find all of the test methods that we have defined. It's going to run them by one by one and it's going to specifically look for the test message that start with chest and underscore. Then it's going to report which test pass and which failed. This main message that we're adding onto unit test is just a simple method of the unit test module that we have here that starts the test runner. So that's essentially what's going on here. So we can just zoom out so we can see the full code and save this file. Let's go ahead and run it. Here we can see we have dot, the lines and ran one test, and I'm going to move this up, and it says, Okay, so let's go ahead and debug how this is actually working. So what we have here is a dot and the jot means that the chest was passed. Ran one test here, means that one test case was executed. So we went ahead to test this simple message here on the mathematics. Then Okay here means that all assertions were successful. We have an assertion here, for example, and it goes to prove that it was a success. All right, so that's the simplest way in which you can go on a hedge and run your tests in Python. So we are going to do a few more examples. So let's go ahead and do just that. We are going to need to make sure that we utilize the unit test module, so let's get stuck in. All right. So what we're going to do now is we're going to test a function to check if a number is even. Let's go ahead and do that. I'm going to say D is underscore even. We're going to pass through the number parameter, and we want to return true if the number is even, otherwise false. We're going to say return number, and in the modulus two, double equals to zero. Even numbers have no remainder when they are divided by two. That is essentially what's going on here to check for a number that's even. Let's do our chess cases. Again, we need to define a class and we're going to call this test even numbers. We need to pass through unit test dot test K we need to pass through that class from the module. That's going to create a test case class. Then we need to define our chess cases. Here I'm going to say deaf, chest, underscore even, underscore number, and here we'll say self. And then we need to add in our assertions. I'll say self jot assert true, and here we'll pass through our function, which is going to be is underscore even, and we'll say four, for example. Then we want to test an odd number to see if it fails, so it should fail. You can say de, test underscore odd number, and then here we'll pass through self. And we're going to say self dot a search. True, and we'll pass through is underscore even the function and five. Then we're going to say de test underscore zero. Through self, we can say self dot search. True. And then we want to check the function if we pass through zero. Then what we do in line with the classier that we've defined, we want to run the test when the script is executed, so we can say I double underscore name, double underscore, equals to main. So we're utilizing this particular script. We can then run unit test. Dot main, and that's going to execute everything that has the start of chest underscore appendage to the message within our class. As we can see here, by passing in four, we're going to get a sat pass by adding in five, which is odd, we're going to get a failed chest and then by passing in zero, which will be even, we'll get a pass as well. We've got that all in place here. Let's go ahead and run our code. All right, so we get a variety. Now, let's analyze output. So we get here dot F dot. So that F is going to indicate failed test. Okay. And that means that the first chest with a pass, the second test with a fail, and the third chest with a pass. So that is how you can analyze it. And we can see here what the fail was and test odd number, we can see here that it failed because we passed through five here. Which you can see here is going to fail because when we pass five and check if it's an even number, it's essentially going to not run correctly and output a trace back error as we can see here, we can see that the session error false is not true. We ran three tests. We had one failure, and that was the second one. You can see it's very nice here. It outputs that we have failed here by putting in F, but it also shows by position which one. Dot is one, F is second and third is passed. Guys. So that is how we can also utilize our test cases so that we can go on a hedge and check for passes and fails in terms of our tests. That is how we can implement the basic unit testing in Python. You can apply this to your functions, for example, if you want to check out your code and see if everything works and if it works as intended. For example, in this particular use case, if you're setting functionality to test at something is even, it is very helpful to add in test cases here as we're doing here to prove the fact that it's doing what it should do. This is where the value comes in with unit testing. Right, so we can go ahead and close thatch and there we have it unit testing. 102. Virtual environments: Hi, everyone. Welcome to the next lesson, which is going to be focused on virtual environment. Let's take a look. Right, a virtual environment, you're probably wondering what is a virtual environment. Simply put, a virtual environment is an isolated Python workspace or environment that allows you to install and manage your packages or dependencies separately for each project. Now this ensures that your different projects don't interfere with one another package wise or cause conflicts. That's all I want to mention on virtual environments. It is quite a straightforward process, so we are going to dive deeper into that into the practical lab exercises, so stay tuned. 103. Creating a virtual environment - [Lab]: Hi, everyone, and welcome to the next practical lab exercise, which is going to be focused on working with virtual environments. Now, virtual environment is very helpful because, of course, you learn good practices by stalling all of your packages within a virtual environment instead of installing it globally on your system. That really helps to ensure that each of your projects have their own virtual environment with their own packages and dependencies. It just helps to keep things smooth and accurate and functional. I'm going to show you how you can create your virtual environment, how you can activate it, and also how you can deactivate it. I'm going to show you for both Windows and MCO Linux. I'd recommend that you watch me first before you follow along directly because I'm going to demonstrate how you can set it up for both devices. Let's get started. Now, the first thing that I want to mention is you need to switch now to run a PySonFle you can click on the dropdown arrow, say Run PySonFL and you can just clear this log here. And the first thing we want to do is understand the concept of packages globally on our system. When we type in PIP List, that's going to list all the packages that we've installed via PIP. For example, when we went ahead and install loama or PWGen or Emoji or all of the packages that were installed in the relevant packages lesson. That's going to all appear globally on our system when we type PIP list. You'll see a list of all the packages that you've installed. Here, for example, I can see Colorama, Emoji, I can see Num Pi, I can see PEP, I can see P at WGN, that's all been installed globally in our system. Now, PEP itself, of course, something that needs to be globally installed, but everything else, you can see it is in the case that it's everywhere. We want it to only be installed within a virtual environment, not globally like we see here. So to do so, we can create a virtual environment to address this. Right. So again, like I said, just watch what I do before you do it. I'm going to show the Windows way first, and to create a virtual environment for Windows, you would type in your terminal, Python, VNV. That means we want to create a virtual environment for ENV. The name of your virtual environment, you can give it any name now, but I'm going to also call it VENV and you can press Enter, and that's going to create your virtual environment for you. You just need to be patient and once it's been created, it should indent on a new line. Let's just wait for that process. Afterwards, I will show you the command for installing it on MacOS or Linux. Let's just be patient. Alright, so well done. So we can see that was a success, and we invented on a new line. So that means our virtual environment was created. Now, what you can also do is go ahead and check in your directory in Explorer and you can see now we have this Virtual Environment folder here within my project, so you can see it's situated here. And all of our packages from now on, once we've activated, our virtual environment will be stored within here. And that's also going to show even if you're on MacOS. For MacoWS to create a virtual environment, you want to type in PySon three M, VNV VENV exactly like we did before. You just want to add PySon three. That's the distinction for setting it up on a Macaws device. You can go on ahead and do so if you are on MacOMS. Right. Let's clear this up. Now we want to activate our virtual environment. On Windows, you'd refer to the name of your virtual environment in the second option. I had VE NV, then we can say backslash, scripts, backslash activate and this activates your virtual environment. You can now see on the left hand side the name that you gave your virtual environment in parens here and we can see it's nice and green in our case. So you should always run your programs now. When you have activated your virtual environment, then you can run Pip install, or you can go ahead and run your PySonFle. So say Python main dot pie, in this case, you should always do it within your virtual environment. Okay, now, if you want to activate it on a MacOS device, what you're going to do is you're going to say Source VE NV, forward slash pin, forwards Activate. This is the command, you need to activate it on your MacOS device. Source VNV forwards pin, forward slash Activate. That's MacOS. Right. We've got that in place now and it's clear this up. If you want to deactivate your virtual environment to turn it off, it's going to be the same on Windows and MacOS, so you just need to say deactivate that will do it for both and you'll see you'll be out of it and it is now gone. Right. So another distinction I want to mention is if we activate our virtual environment, so it's activated. And let's say I say PIP list now, you'll see in the environment of your virtual environment that we only have PIP, which is, of course, the general package that will be within your virtual environment, but we don't have those other packages that you see globally, like I showed earlier on, and that's because it is not within the virtual environment. And this is why and how I mentioned, everything needs to be separated in a virtual environment for your project and not globally on your machine. So you can see here the difference. Okay. We can say clear now. All right, so there we go. This is how you should always install your packages and libraries. For example, if I want to utilize the Colama package, I can copy match. So Pep install Clarama All right. You can see it's being installed, and there we have it. So let's go ahead and check where it is installed. So if I say Pip LLS, we can now see that we have installed it within our virtual environment. So here is Clarama. Perfect. So now we can clear this up. And now what we want to do is we want to go on ahead and grab the Colama modules. I'm going to say from color ma. Want to import the four class. Then I'm going to say print, and I'm just going to say that I want to sech the four colors, four dot and red being the attribute. I want this to be set to red. I'm going to say this is red checks. I will be my output and my terminal color will also follow. Then here within the virtual environment, I can just say Pison main dot pi. You can see that works perfectly fine. All right. There we have it. And we can say clear. We can just rerun this and say white. That will give us a default. And there we go. All right, so that is how we should, for best practices, go on ahead and utilize PySon by utilizing a virtual environment when we're installing all of our packages. So please note, again, I will mention it that when you are utilizing MacawS there is a slight difference with how you activate and create your virtual environment, but everything else is going to work just as it should, especially with deactivating of virtual environment and such. All right, guys. So that is how we can work with our virtual environments. And when you're done, you can just deactivate. But remember, always best practices to activate it, and then utilize it from there on out. Alright, guys. So that is it. That is all for virtual environments. 104. Creating your own project: Hi, everyone. Welcome to the next messon which is going to be focused on creating our own projects. Let's take a look. Much. The time has come and now that you have acquired all of these new skills, it's time for you to put all of that to use and create your very own project. The next thing that you need to do is head on over to the project and resources section of this course for further information there I'm going to detail and outline some ideas that you can go ahead and create for your project and also give you some suggestions as to how you can go about the project creation process. Oh, that's all I'm going to say for now and good luck. And I look forward to seeing your projects. 105. Thank you!: Hi, everyone. And welcome to the final lesson of this course where I just want to thank you for deciding to complete this course. It has been a pleasure teaching you and I hope that you got some valuable knowledge out of it. So thank you very much. If you have some time, I would appreciate it greatly if you would consider leaving a review. Since improving my courses and doing as best as I can is always a positive you have some time, I would greatly appreciate that. If not, that's perfectly fine as long as you had a great learning experience, and that's it for me and good luck on your development journey, and I wish you all the best. Goodbye, and thank you again.