From the course: Level Up: Advanced Python

Context managers: Calculator - Python Tutorial

From the course: Level Up: Advanced Python

Context managers: Calculator

(graphics warbling) (graphics chiming) - [Instructor] In this challenge, we're going to create a context manager called calculator. (screen tinkling) Now, before we get started, let's take a quick refresher of just three examples of errors available in Python. Now, there are loads more, but we'll focus on these for now. You've probably come across the type error. So if I try and add the integer 2 to the string 2, I get a type error. As I'm trying to add an integer and a string together. And I can fix this by passing the string 2 to the integer function. And so this is going to give me a result of 2, and then I can add that back to the value of 2 to get a total value of 4. If I try and pass the string A to an integer function, I get a value error because that's an incorrect data type. I need to have an integer or a string value that is numeric as the argument. And finally, if I try and divide a number by zero, I get a zero division error. So we'll stick to these three errors for now. Now as a quick refresher, a context manager is an object that can be used with a with block. So you've probably seen this used to automatically close files when you're done working with it. And context managers need a dunder enter method and a dunder exit method. And the dunder exit method accepts three positional arguments. The exception class or type, the exception object value, and a trace back object for the exception. Now in this challenge, you should be able to complete mathematical calculations in your calculator context manager, as long as there's none of these three errors. And as soon as there's an error, you need to gracefully stop without raising any exceptions. You should also be able to determine what error caused the calculator to stop working. So let me give you an example of how the calculator context manager needs to work. The calculator context manager completes the first calculation, printing a result of two, it then prints out seven for the second calculation. So that's three plus four. But because the third calculation results in the type error, it stops and it doesn't raise any exceptions. Now, if I want to determine what's causing the calculator to stop, I can do that by typing a c.error. And you can see that we've got a type error here. Now you can also test your solution using the test file. Now, head back to calculator.py, and go ahead and update it and pause the video here and I'll show you the solution I came up with. (graphics warbling) (upbeat music) So we've got a class here called class calculator with our dunder init method, our dunder enter method, and our dunder exit method. In the dunder init method, we're passing across all of the exception types. So we just use *exc_types, to accept any number of arguments. Now when you enter the calculator block, the dunder enter method gets called. We often think of the dunder enter as the time to acquire resources or to do some setup work. So we want our context manager calculator to keep track of the state, and so the dunder enter method returns self, which passes the calculator object to the variable c. And by default, the dunder exit method has passed three arguments, the class or the type of the exception, the value of the exception, and the trace back of the exception. Now, if there are no exceptions, then these just have the value none. And if an exception has been raised, then these arguments have details about the exception. Now this is important. If the dunder exit returns something that's true, the exception raised in our context calculator block will be suppressed, and that's what we want. But if something that is false is returned, the exception will go up these stack traces. We assign self.error to the value of the exception. And since the second argument of this instance accepts a class or a topple, we can pass the exception types, which is one or more of the value error, the type error or the zero division error, which are all stored in a topple here. And we can then just return the instance here, which will return true or false. So let's check this passes all our tests. And you can see that this has passed all of the four tests that we have. Now, my solution is just one way of solving this problem. You could also use context managers from the contextlib module to solve this. So go ahead and share your solution in the Q&A section. I'm really keen to see how you solve this code challenge.

Contents