Reputation: 151
I've started self learning Python and need some advise on the below problem which I'm working on currently.
How should I decorate each method of the calculator class, with a custom method that logs the arguements.(using a custom logger method)
Something like below:
The Input Values are : '10' '21' and '15'
# if *args were 10, 21 & 15
Operation : Multiply
My unfinished code.
import logging
class Calculator:
def add(self, *args):
total = 0
for val in args:
total += int(val)
return total
def subtract(self, *args):
total = 0
for val in args:
total -= val
return total
def multiply(self, *args):
total = 1
for val in args:
total *= val
return total
def divide(self, *args):
total = 1
for val in args:
total /= val
return total
Below operations gives incorrect values:
print(Calculator.multiply(10, 2, 4))
print(Calculator.subtract(10, 2, 4))
print(Calculator.add(10,2,4))
print(Calculator.divide(10,2,4))
8
-6
6
0.125
Upvotes: 1
Views: 225
Reputation: 5630
There's two problems.
The first problem is, that you create a class so you you have to instantiate an object before using it:
calculator = Calculator()
print(calculator.multiply(10, 2, 4))
print(calculator.subtract(10, 2, 4))
print(calculator.add(10,2,4))
print(calculator.divide(10,2,4))
if you type Calculator.add(10,2,4))
then the 10 will be passed as self
and only 2
and 4
will be passed as args
, so args
would have been [2, 4]
instead of your expected [10, 2, 4]
The second problem is, that for substract
and divide
you have to treat the first parameter differently.
So following should work:
import logging
logger = logging.getLogger(__name__)
class Calculator:
def add(self, *args):
logger.info("calc add %s", args)
print("calc add ", args)
total = 0
for val in args:
total += int(val)
return total
def subtract(self, *args):
logger.info("calc subtract %s", args)
print("calc substract ", args)
if len(args) == 0:
return 0
total = args[0]
for val in args[1:]:
total -= val
return total
def multiply(self, *args):
logger.info("calc multiply %s", args)
print("calc multiply ", args)
total = 1
for val in args:
total *= val
return total
def divide(self, *args):
logger.info("calc divide %s", args)
print("calc divide ", args)
if len(args) == 0:
return 1
total = args[0]
for val in args[1:]:
total /= val
return total
# Let's assume, that's the main function
logging.basicConfig(filename='example.log',level=logging.DEBUG)
calculator = Calculator()
print(calculator.multiply(10, 2, 4))
print(calculator.subtract(10, 2, 4))
print(calculator.add(10,2,4))
print(calculator.divide(10,2,4))
I added print statements for debugging. You had to remove them of course for 'production'
I configured the logging to write all logs with level DEBUG, INFO, WARNING, ERROR and critical for all modules into a log file.
To setup logging as you wish can be rather complex depending on your use case.
https://docs.python.org/3.8/library/logging.html is very complex and gives you a lot if freedom. This is perhaps better treated in a separate question
Addendum:
Concerning the __init__
function as you asked in one comment.
you might want to have a calculator, that remembers the last calculated
IN this case you would change your code slightly.
You would add an __init__()
method
def __init__(self):
last_result = 0 # just some value
Then you had to change multiply
, subtract
, ... to store the last caclulated result.
e.g.
def add(self, *args):
logger.info("calc add %s", args)
print("calc add ", args)
total = 0
for val in args:
total += int(val)
self.last_result = total # no you remember the last result.
return total
And if you wanted you could check now the last result. with
print(calculator.last_result)
What might really make sense for a calculator?
Perhaps the last n
calculations (operation + parameters + result).
Perhaps a memory and a command to add or subtract the last result to that memory.
Upvotes: 2