'''
Your task is to implement a simplified version of a banking system.
Initially, the banking system does not contain any accounts, so implement operations to allow accounts creation as well as making deposits.
Operations:
CREATE_ACCOUNT
Should create a new account with the given identifier if it doesn't already exist.
Returns "true" if an account was successfully created,
Returns "false" if an account with accountId already exists.
DEPOSIT
Should deposit the given amount of money to the specified account accountId
Returns the total amount of money in the account after the query has been processed.
If the specified account doesn't exist, it should return -1.
TRANSFER
This should transfer the given amount of money from account with fromId to account with toId.
Returns the balance of fromId if the transfer was successful, or -1 otherwise.
Returns -1 if fromId or toId doesn't exist.
Returns -1 if fromId and toId are the same.
Returns -1 if funds on the account fromId are insufficient to perform the transfer.
TOP_ACTIVITY
This should return the identifiers of n most active accounts in descending order of financial activity indicator, In case of a tie, sorted alphabetically by accountId in ascending order.
The returned value should be an array of identifiers in the format
<accountId_1>(<activity_indicator_1>),
<accountId_2>(<activity_indicator_2>),
...,
<accoundId_n>(<activity_indicator_n>)
Financial activity indicator is defined as the sum of all transactions for an account including the money deposited and/or successfully transferred. Unsuccessful transactions are not included.
If less than n accounts exist in the system, then return all their identifiers (in the described format).
operations = [
["CREATE_ACCOUNT", "account1"], # true
["CREATE_ACCOUNT", "account1"], # false
["CREATE_ACCOUNT", "account2"], # true
["DEPOSIT", "non-existing", "2700"], # -1
["DEPOSIT", "account1", "2700"], # 2700
["TRANSFER", "account1", "account2", "2701"], # -1
["TRANSFER", "account1", "account2", "200"], # 2500
["TRANSFER", "account1", "account2", "2500"], # 0
["DEPOSIT", "account2", "300"], #3000
["CREATE_ACCOUNT", "account3"], # true
["DEPOSIT", "account3", "4000"], #4000
["TOP_ACTIVITY", "3"], #[account1(5400), account3(4000), account2(3000)]
["DEPOSIT", "account2", "1000"], # 4000
["TOP_ACTIVITY", "2"], #[account1(5400), account2(4000)]
["TOP_ACTIVITY", "5"] #[account1(5400), account2(4000), account3(4000)]
]
'''
class BankingSystem:
def init(self):
self.accounts = {} # dictionary to store account balances
self.activity = {} # dictionary to store financial activity
def create_account(self, accountId):
# if account already exists (edge case)
if accountId in self.accounts:
return False
# otherwise create account with 0 balance
self.accounts[accountId] = 0
self.activity[accountId] = 0 # initialize financial activity to 0
return True
def deposit(self, accountId, amount):
# if account does not exist, return -1
if accountId not in self.accounts:
return -1
# add the amount, if it exists:
self.accounts[accountId] += int(amount)
self.activity[accountId] += int(amount)
# Return the output balance
return self.accounts[accountId]
def transfer(self, fromId, toId, amount):
# check if both account exist
if fromId not in self.accounts or toId not in self.accounts:
return -1
# check if fromId and toId are the same
if fromId == toId:
return -1
# check if funds on the account fromId are insufficient
if self.accounts[fromId] < int(amount):
return -1
# Do the tranfer operation
self.accounts[fromId] -= int(amount)
self.accounts[toId] += int(amount)
# adding the financial activity for both accounts
self.activity[fromId] += int(amount)
self.activity[toId] += int(amount)
return self.accounts[fromId]
def top_activity(self,n):
# sorting in descending order the activity indicator, then by accountId in acscendting order
sorted_accounts = sorted(
self.activity.items(),
key=lambda x: (-x[1], x[0]) # sorts the activity by desc, then accountId by ascending asc
)
# format the result
result = [f"{accountId}({activity})" for accountId, activity in sorted_accounts[:n]]
return result
operations = [
["CREATE_ACCOUNT", "account1"], # true
["CREATE_ACCOUNT", "account1"], # false
["CREATE_ACCOUNT", "account2"], # true
["DEPOSIT", "non-existing", "2700"], # -1
["DEPOSIT", "account1", "2700"], # 2700
["TRANSFER", "account1", "account2", "2701"], # -1
["TRANSFER", "account1", "account2", "200"], # 2500
["TRANSFER", "account1", "account2", "2500"], # 0
["DEPOSIT", "account2", "300"], #3000
["CREATE_ACCOUNT", "account3"], # true
["DEPOSIT", "account3", "4000"], #4000
["TOP_ACTIVITY", "3"], #[account1(5400), account3(4000), account2(3000)]
["DEPOSIT", "account2", "1000"], # 4000
["TOP_ACTIVITY", "2"], #[account1(5400), account2(4000)]
["TOP_ACTIVITY", "5"] #[account1(5400), account2(4000), account3(4000)]
]
banking_system = BankingSystem()
for op in operations:
if op[0] == "CREATE_ACCOUNT":
print(banking_system.create_account(op[1]))
elif op[0] == "DEPOSIT":
print(banking_system.deposit(op[1], op[2]))
elif op[0] == "TRANSFER":
print(banking_system.transfer(op[1],op[2], op[3]))
elif op[0] == "TOP_ACTIVITY":
print(banking_system.top_activity(int(op[1])))
# -----
# # Modifications
# self.acccounts = {
# "accountId": {
# "balance" : 0,
# "activity" : 0
# }
# }#------
"""
Design a credit card account management application.
The application should represent a bank with the opportunity to apply for credit cards,
manage credit cards, manage payments, and report usages.
Features that need to be supported:
Process a credit card application
Create a credit card online account / access online portal
Provide API to authorize credit card transactions
Pay credit card balance using a third-party payment service
The st*pid interviewer thought I was interviewing
for a managerial positiion and started asking me all the
management based questions .. What a bummer !!
Round 4:
Asked me what quick replying model.
Capital One has a model "Eeno", which is a quick replying model.
Told me about it and asked my suggestions on how to improve it:
Q- what types of data will be useful for this kind (Eeno) of model
Then asked me to tweak the following code:
import calendar
import time
class RetrieverQ:
def init(self, store):
self.store = store
def retrieve_recent(self, customer_id, curr_time):
result = []
# Retrieve data for the last 5 minutes including the current minute
for index in range(0, 5):
val = self.store.retrieve(customer_id, curr_time - 5 + index)
if val is not None:
result.append(val)
return resultclk_retriever = RetrieverQ(clk_store)
trx_retriever = RetrieverQ(trx_store)
cid = 1
curr_time = int(calendar.timegm(time.gmtime()) / 60) # minutes
clk_recent = clk_retriever.retrieve_recent(cid, curr_time)
trx_recent = trx_retriever.retrieve_recent(cid, curr_time)
--- Data -----
#NOTE: Minute is sequential number of minutes since the Epoch (1/1/1970)
--- Clickstream Data ---
#CID - MINUTE - CLICK EVENT
#1 - 25853654 - Confirm
#1 - 25853653 - Schedule Payment
#1 - 25853652 - View recent
#1 - 25853651 - Login
#1 - 25853650 - Enter password
#1 - 25853649 - Enter user name
#1 - 25853648 - Login
#1 - 25853649 - Login
#1 - 25853650 - Recover Login
--- Transactions Data ---
#CID - MINUTE - TRANSACTION
#1 - 25853652 - Krogers 5
#1 - 25853653 - Geddy's Music 45
#1 - 25853598 - Starbucks 45.00
#2 - 25851945 - OSU Bookstore 222
#2 - 25851002 - Neil's Drums $1340
Questions Asked:
"""