Note:
1. All 3 Questions are must to attempt in Python.
2. Time Slot :90 min
Q1.Write a decorator for logging the function. The decorator also consumes an optional
argument which denotes the file path to write logs. If it is not provided, print it to
console.
It should log below details related to the function it was attached:
a. function name
b. function arguments
c. output of the function
d. time took to execute the function
E.g.
from time import time
def myDecorator(func):
'''Decorator to print function call details - parameters names and effective
values'''
def wrapper(*func_args, **func_kwargs):
print("Method - " + func.__name__)
args = list(func_args) if len(list(func_args)) > 0 else None
kwargs = list(func_kwargs) if len(list(func_kwargs)) > 0 else None
print("Arguments -", args)
print("kwargs -", kwargs)
start = time()
retval = func(*func_args,**func_kwargs)
print("Output -", retval)
print("Time taken -",time() - start, "seconds")
return wrapper
@mydecorator('/tmp/output.log')
def subtract(a, b):
return a - b
result = subtract(10 , 2)
In the '/tmp/output.log', you should see below details:
Method - subtract
arguments - [10, 2]
kwargs - None
Output - 8
Time Taken - 0.2086548805236816 seconds
@mydecorator()
def add(a, b=1):
return a + b
result = add(a=10)
In the output console, you should see below details:
Method - add
arguments - None
kwargs - {'a': 10}
Output - 11
Time Taken - 0.2086548805236816 seconds
Q2.Write unit tests (no integration tests) for singleton design pattern implementation in
python.
# Singleton Borg pattern
class SingleTonClass:
__shared_state = dict()
# constructor method
def __init__(self):
self.__dict__ = self.__shared_state
self.state = ‘Apple’
def __str__(self):
return self.state
# main method
if __name__ == "__main__":
value1 = SingleTonClass()
value2 = SingleTonClass()
value3 = SingleTonClass()
value1.state = 'Mango' # person1 changed the state
value2.state = 'Melon' # person2 changed the state
print(value1) # output --> Melon
print(value2) # output --> Melon
value3.state = 'Grape'
print(value1) # output --> Grape
print(value2) # output --> Grape
print(value3) # output --> Grape
Q3.Build a inter process communication between two python processes where:
a. Process 1 can send a new dictionary to process 2 and gets an
ID along with saved dictionary in response.
b. Process 1 can replace dictionary for a given ID and gets the same ID along with
replaced dictionary in response. In case no dictionary exists before, an error
message is sent.
c. Process 1 can update partial content of the dictionary for a given ID and gets
the same ID along with updated dictionary in response. In case no dictionary
exists before, an error message is sent.
Example
Data from P1 to P2: {'data': {'a': {'c': 3}}, 'action': 'create'}
Response from P2 to P1: {'data': {'a': {'c': 3}}, 'id': 45}
Data from P1 to P2: {'data': {'a': {'b': 4}}, 'id': 45, 'action': 'replace'}
Response from P2 to P1: {'data': {'a': {'b': 4}}, 'id': 45}
Data from P1 to P2: {'data': {'a': {'d': 10}, 'e': 15}, 'id': 45, 'action': 'update'}
Response from P2 to P1: {'data': {'a': {'b': 4, 'd': 10}, 'e': 15}, 'id': 45}
Data from P1 to P2: {'data': {'a': {'b': 4}}, 'id': 15, 'action': 'replace'}
Response from P2 to P1: {'error': 'No data is present for id 15.'}
Data from P1 to P2: {'data': {'a': {'d': 10}, 'e': 15}, 'id': 15, 'action': 'update'}
Response from P2 to P1: {'error': 'No data is present for id 15.'}
allData = {}
def doAction(data):
if(data['action'] == 'create'):
temp = {}
temp[data] = data['data']
while(1):
randInt = random.randint()
if randInt not in allData:
break
temp['id'] = randInt
allData[randInt] = temp
return temp
if(data['action'] == 'replace'):
key = data['id']
if(key not in allData):
print("Key does not exist for {}".format(key))
else:
allData[key] = data
if(action['action'] == 'update'):
key = data['id']
if(key not in allData):
print("Key does not exist for {}".format(key))
else:
f