5.7 A Special Calculator: Part 2
In this lesson we'll finish up our special calculator by adding a method that will remove an operation from the history and reset the calculator's internal memory.
1.Introduction2 lessons, 11:32
2.Python Building Blocks6 lessons, 1:08:07
3.Controlling the Flow7 lessons, 1:20:10
4.Common Data Structures4 lessons, 46:49
5.Application Structure7 lessons, 1:15:12
6.Collections7 lessons, 46:55
7.File I/O6 lessons, 48:51
8.Networking5 lessons, 43:48
9.Connecting to Network Services3 lessons, 34:27
10.Conclusion1 lesson, 02:08
5.7 A Special Calculator: Part 2
All right, so everything seems to working now, but ultimately what I wanna be able to do is tell them, give the user the opportunity to say something like, in the calculator, like maybe remove operation, and specify an index of the operation. And then have the calculator go back through, and recalculate all of the operations that were done here, except for the one that was removed. And then, continue on from there, have the total up to date, memory up to date on all the history and all that sort of thing. So let's go ahead and see how we could do something like that. So I'm gonna kinda clear out of here. I'm gonna come back in and I'm gonna create another method here. This is gonna be another instance method. You can call it whatever you want. And I'm gonna call this remove_operation. This is gonna be an instance method. And I wanna take in the number associated with an operation so we'll call this op_number. So this is gonna be an operation number that we're going to remove. Now one thing they may want to do in this case is a little bit of defensive programming never hurt anybody so maybe you wanna check to see that at the bare minimum the value that's passed in here is not negative because we can't deal with negative indexes within our list. Or at least not in the way that, we can, but at least not in the way that you would think we'd want to do it in this case. We only wanna deal with positive from zero up to the length of the list of minus one, because remember we're doing zero indexes. So, at least in that range. So let's do something really simple to check for that, so we'll say if, and I'm going to show you a new operator here that we can put into a conditional statement that will kind of make your life a little bit easier instead of doing two if statements here. We're gonna say if and we're gonna do open close parentheses. And then we're gonna say use the or key word, and then we're gonna do open and close parentheses again. So now, within these two sets of parentheses, I can put two different things to check, two different conditional statements. So what is the first one? Well, the first one is I wanna make sure that op_number is, actually in this case, I'm gonna check to make sure if that op_number is a bogus number, and then we're just gonna break out of this particular method. So I'll say if the op_number is I don't want to have to deal with that. That's not gonna work in this particular case. Or, op_number is greater than the length of self.memory- 1. So don't forget that because, remember, we're dealing with zero-based indexes here. So if you try to use an operation number that is the same length, it's gonna be an out of bounds memory. It's gonna be beyond the index length. And then you're ultimately gonna get an error. So if any of these conditions are true, then we're just going to use the return statement and that return statement returning nothing is just gonna break us out of this method. So now we're gonna do some operations here and ultimately like I said what I wanna do is I wanna go and I wanna remove the specific operation number from memory. And then at that point I want the calculator or whatever this particular method is to rerun all of the calculations it's done to that point except for the one we're removing to kind of update the total and the memory to that point. So we'll say else. And the first thing that I wanna do is I wanna remove that operation so remember one way that we were able to delete values from a list using an index was to use the delete helper, we'll call delete self.memory. And we're gonna use the op_number here, like that. So now that is gone from our list. And we're going to reset total, so we'll say self.total is gonna be equal to zero. Now at this point I want to start to loop through the operations that we've done to this point and replay them. But the problem is if I and ultimately I'm gonna be using my methods that I've created up here but all of these methods up here will change the value of the self.memory attribute. So if I start to loop through memory, and then I start appending to it, I'm gonna really have some problems here. So what I wanna do is I want to kind of grab the current state of this memory and then I wanna clear it, because throughout all of these operations we're going to be, typically, appending to it. And that's what we want to do, but in order for me to not kind of corrupt what's going on here, I'm going to have to take a snapshot of that memory to this point. So I'm just gonna create a variable here called, new_memory, and I'm gonna set that equal to self.memory. And then after I've done that, I'll do self.memory, and I'll reset this equal to nothing. So basically we're resetting total to zero and memory to empty, just like we did in our constructor up here. So now I'm pretty free to do what I want. So all I'm gonna do here is, I'm gonna use a for statement, and I'm gonna do my little range again, so I'll say for index. In range within the length of now this is, we're using new memory now remember because self.memory is empty so I wanna go through this new memory the snapshot of the old memory that we are working with. Now within here I wanna get the operation that we're dealing with. So this is gonna be equal to new memory at index. So that's the current operation that we're working with. Now what I wanna do is I want to split these up cuz, as you see, I've kinda strategically put spaces in here. So what I can do now is I can actually grab the values outta here and I can do op.split. And by default split is gonna break on the space or any sorta whitespace. And so we're gonna get these values here. So we'll get value zero is going to be the operation, and then value one is going to be whatever number was passed in. So we'll just break those out into two variables, we'll say first is gonna be equal to values, zero. And second is gonna be equal to values . And now I want to check to see what that first is is it an addition, multiplication or a division? So we'll say if first is == to +, then in that case all I want to do is to self.add. And remember what I said before is at this point we're just kind of assuming that we're dealing with integer values here. The problem that's going to arise depending on how you're doing this with what you're passing in is right here because right now the second value here is a string. Now depending on how you wanna do your operation, you could either cast this to an integer or a float. And there are ways to actually check for that. And I'll leave that as an exercise up for you to check the Python documentation to see how can we check If we're dealing with a floating point number or an integer, or something like that. And maybe you can add that it in as a real helper function. But for now, like I said, we're just going to assume we're dealing with integers. So I'll say that I want to do add for the integer conversion or the cast of the second value. Now, we're gonna the same exact thing here for the other versions, except with we're going to change the operator that we're working with, and the method that we're using. So, I'm gonna fill those in here now, and then I'll show you when I'm done. So there we go. We have now gone through and checked to see if it's a + then wanna run add on the integer version of second. For- we wanna do subtract. For * we wanna do multiply. And for divide we wanna do divide. In this case I could've said else if first equal to the divide sign, but in this case I'm just going to assume that that's the case. So lets go ahead and save that. Now I'll go back into our shell here. And once again say, from calc I want to import Calc. And I have missed a semicolon or a colon here. So we'll set save, and we will try that again. And it works now. So now we can at this point create a new instance c equal to calc, and this point we'll go ahead and just add. Now remember, now I'm just going to pass in a single value. So I'm gonna add five. And then, I'm going to add another five. And at this point, we can check total and we still have ten, so that's good. And now we'll say a, we will subtract three. And then we will add, maybe five again, and now at this point we can check total again, we're working with 12. Which sounds about right. So at this point we can now do c.dot, and we can say I wanna see memory. I wanna see the operations we've been working with so far. So we started with + 5, + 5,- 3, and + 5. So now that we can have shown the memory here, we can you can see all these operations. Now, maybe I look back here and I say, you know what? I didn't mean to do this minus three, that was a mistake. I wanna take it out and have the calculator pretend like it never happened. So in this case we will do a c.remove_operation. And I wanna remove a particular operation. I wanna remove the operation with index (2). So let's go ahead and run that so it seems to have worked so let's see what total is. Total looks like 15 that seems promising and I can say, show_memory and then we've got rid of the -3, we're down to just the three +5s. So there we go, we've created a very simple calculator that has some unique functionality of being able to look at the history up to a point, and then saying, I wanna remove a particular operation, and then resetting everything within the calculator, including the total, as well as the history, or the memory or whatever you want to call it, back to what it would've been like should we have actually removed that operation. So there you go, there's the basic way where you can create a functionality like this. Now there's many different ways you could get from point A to point B here. But this is a good place to start, I think. So hopefully this example has been beneficial for you, and you'll be able to kind of find your way working through problems in such a way. And maybe even take some time and look at this and optimizer a bit for your particular use.