why is the balance after depositing is = None? - python

I created this simple withdrawal and deposit machine and used a class method for depositing but there seems to be something wrong with it as I expected the return value of the deposit method to be = 20,500 but instead its = None , so what it is the problem here ? and are there any mistakes in my code ?
print("Hello !!! Welcome to Deposit & Withdrawal Machine")
class Account:
withDrawalAmount = 0
depositAmnt = 0
def __init__(self, ID=0, balance=100, annual_interest_rate=0):
self.__ID = ID
self.__balance = balance
self.__annual_interest_rate = annual_interest_rate
#setters
def setId(self, ID):
self.__ID = ID
def setBal(self, Bal):
self.__balance = Bal
def setAnnualInterestRate(self, annualIntrstRate):
self.__annual_interest_rate = annualIntrstRate
#getters
def getId(self):
return self.__ID
def getBal(self):
return self.__balance
def getAnnualIntrstRate(self):
return self.__annual_interest_rate
#special getters
def getMonthlyInterestRate(self):
self.annual_rate = self.__annual_interest_rate / 100
self.monthly_rate = self.annual_rate / 12
return self.monthly_rate
def getMonthlyInterest(self):
return self.__balance * self.monthly_rate
#other methods
def withdraw(self, withDrawalAmount):
if self.__balance >= self.withDrawalAmount:
self.__balance = self.__balance - self.withDrawalAmount
return self.__balance
def deposit(self, depositAmnt ):
if self.depositAmnt >= 1 :
self.__balance = self.__balance + self.depositAmnt
return self.__balance
client001 = Account(1122, 20000, 4.5)
print("Your Balance After withdrawal is : ", client001.withdraw(2500))
print("Your Balance After deposit is : ", client001.deposit(3000))
print("Your Account ID is : ", client001.getId())
print("Your Current Balance is : ", client001.getBal())
print("Your Monthly Intrst Rate is : ", client001.getMonthlyInterestRate())
print("Your Monthly intrst is : ", client001.getMonthlyInterest())

As John already mentioned, to rectify this you need to use the variable depositAmnt in your if statement.
def deposit (self , depositAmnt ):
if depositAmnt >= 1 :
self.__balance = self.__balance + depositAmnt
return self.__balance
right now, the attributes of your class -withDrawalAmount and depositAmnt don't have any usage (since you are inputting them as an argument in your function deposit and withdraw.
You should also change the withdraw function as:
def withdraw (self , withDrawalAmount):
if self.__balance >= withDrawalAmount:
self.__balance = self.__balance - withDrawalAmount
return self.__balance

def deposit (self , depositAmnt ):
if self.depositAmnt >= 1 :
self.__balance = self.__balance + self.depositAmnt
return self.__balance
The amount being deposited is depositAmnt, not self.depositAmnt.
So the if condition is false, therefore the function does not return anything, therefore it returns None by default.

Related

I need help to know why inheritance isn't working in this OOP example

I'm getting the error "AttributeError: 'SavingsAccount' object has no attribute '_SavingsAccount__balance'" when I run this program and I can't work out why. The error is linked to the savings.withdraw() method. Any help would be welcome. It will be clear that I am new to OOP.
import random
class Account:
def __init__(self,holderName,balance):
# generate a 4-digit PIN
self.__PIN=''
for x in range(4):
self.__PIN+=chr(random.randint(48,57))
# generate an 8-digit account number
self.__accountNumber=''
for x in range(8):
self.__accountNumber+=chr(random.randint(48,57))
self.__holderName = holderName
self.__balance = balance
def deposit(self,amount):
self.__balance+=amount
def getBalance(self):
return(self.__balance)
def setBalance(self,amount):
self.__balance = amount
def withdraw(self, amount):
self.__balance -= amount
def setAccountHolder(self,name):
self.__holderName = name
def getAccountHolder(self):
return self.__holderName
def PrintAccountInfo(self):
print('\nPIN: {}'.format(self.__PIN))
print('Account Number: {}'.format(self.__accountNumber))
print('Account Holder: {}'.format(self.__holderName))
print('Balance: £{:.2f}'.format(self.__balance))
class SavingsAccount(Account):
def __init__(self, holderName, balance):
super().__init__(holderName, balance)
self.__withdrawals = 0
def withdraw(self, amount):
if self.__withdrawals < 4:
if self.__balance - amount >= 0.00:
self.__balance -= amount
self.__withdrawals += 1
else:
print('Cannot withdraw - insufficient funds.')
else:
print('You have exceeded the number of withdrawals for this session')
def PrintAccountInfo(self):
super().PrintAccountInfo()
print('Withdrawals: {}'.format(self.__withdrawals))
# main program
main = Account('Joe Smith',400)
main.deposit(100)
main.PrintAccountInfo()
savings = SavingsAccount('Ann Brown',400)
savings.PrintAccountInfo()
savings.withdraw(200)

How to initialise an inherited class in Python

I'm having a hard time understanding how to initialize an inherited class in python OOP.
I cannot figure out what arguments need to be passed when I initialize it. These are the classes I'm using:
class BankAccount: #parent class
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
def withdrawal(self, withdraw):
if withdraw > self.balance:
raise RuntimeError('Sorry, Insufficient Funds!')
else:
print('Withdrawal accepted.')
self.balance -= withdraw
show_balance = input('See account balance? enter y or n: ')
if show_balance == 'y':
print(self.balance)
def deposit(self, amt):
self.balance += amt
print('Deposit Accepted')
show_balance = input('See account balance? enter y or n: ')
if show_balance == 'y':
print(self.balance)
class MinimumBalanceAccount(BankAccount): #child class
minimum_balance = 100
def __init__(self):
BankAccount.__init__(self)
def withdrawal(self, withdraw):
if self.balance - withdraw < self.minimum_balance:
print('Error, balance cannot go below minimum value: {}'.format(minimum_balance))
else:
self.balance -= withdraw
But when I try to initialize the child class:
acc2 = MinimumBalanceAccount('Milind', 1000) # I am not sure what to pass as arguments here
Python gives me this error:
TypeError Traceback (most recent call last)
<ipython-input-9-85e55fb15340> in <module>
----> 1 acc2 = MinimumBalanceAccount('milind', 1000)
TypeError: __init__() takes 1 positional argument but 3 were given
What do I pass in as the arguments?? What's going wrong?
You need to pass the required arguments to the subclass, and to the superclass:
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
def withdrawal(self, withdraw):
if withdraw > self.balance:
raise RuntimeError('Sorry, Insufficient Funds!')
else:
print('Withdrawal accepted.')
self.balance -= withdraw
show_balance = input('See account balance? enter y or n: ')
if show_balance == 'y':
print(self.balance)
def deposit(self, amt):
self.balance += amt
print('Deposit Accepted')
show_balance = input('See account balance? enter y or n: ')
if show_balance == 'y':
print(self.balance)
class MinimumBalanceAccount(BankAccount):
minimum_balance = 100
def __init__(self, owner, balance):
super().__init__(owner, balance)
self.minimum_balance = MinimumBalanceAccount.minimum_balance
def withdrawal(self, withdraw):
if self.balance - withdraw < self.minimum_balance:
print('Error, balance cannot go below minimum value: {}'.format(minimum_balance))
else:
self.balance -= withdraw
acc2 = MinimumBalanceAccount('Milind', 1000)
In this case, as pointed out by #Deceze in the comments, you can omit __init__ entirely:
class MinimumBalanceAccount(BankAccount): #child class
minimum_balance = 100
def withdrawal(self, withdraw):
if self.balance - withdraw < self.minimum_balance:
print('Error, balance cannot go below minimum value: {}'.format(minimum_balance))
else:
self.balance -= withdraw
You need to add the initializing parameters also to your child Class when you define the __init__ function and pass it to the parent.
class MinimumBalanceAccount(BankAccount): #child class
minimum_balance = 100
def __init__(self, owner, balance):
BankAccount.__init__(self, owner, balance)
class MinimumBalanceAccount(BankAccount): #child class
minimum_balance = 100
def __init__(self,owner, balance):
BankAccount.__init__(self,owner,balance)
def withdrawal(self, withdraw):
if self.balance - withdraw < self.minimum_balance:
print('Error, balance cannot go below minimum value: {}'.format(minimum_balance))
else:
self.balance -= withdraw

python. Unable to run program

I'm new to Python programming.
I was trying to achieve the following output:
Account c
Account count = 1
Successful transaction! Balance = 10000
Successful transaction! Balance = 9000
Not enough balance
My code:
class Account:
accountCount = 0
def __init__(self, name, accountNo):
self.name = name
self.accountNo = accountNo
self.balance = 0
Account.accountCount += 1
print ("Account " + self.accountNo)
print ("Account count= " +str(Account.accountCount))
def withdraw (self, amount):
self.balance -= amount
return self.balance
def deposit (self,amount):
self.balance += amount
return self.balance
myAccount = Account ("c", "c123")
myAccount.deposit(10000)
myAccount.withdraw(500)
myAccount.withdraw(10000)
I get the following error
line 1, in <module>
line 20, in Account myAccount = Account ("c", "c123")
NameError: name 'Account' is not defined
Your problem is with indentation. Moving your code logic to the beginning of the line will execute your code.
class Account:
accountCount = 0
def __init__(self, name, accountNo):
self.name = name
self.accountNo = accountNo
self.balance = 0
Account.accountCount += 1
print("Account " + self.accountNo)
print("Account count = " + str(Account.accountCount))
def withdraw(self, amount):
self.balance -= amount
return self.balance
def deposit(self, amount):
self.balance += amount
return self.balance
account_c = Account("c", "c123")
account_c.deposit(10000)
account_c.withdraw(500)
account_c.withdraw(10000)
Output:
Account c123
Account count = 1

python unittest error indicating No overdrafts

I have been working on a test and each time I run my code it displays the error code below:
test_savings_account_cannot_withdraw_more_than_current_balance Failure
in line 48, in
test_savings_account_cannot_withdraw_more_than_current_balance
self.assertEquals(message, 'Cannot withdraw beyond the current account
balance', msg='No overdrafts') AssertionError: No overdrafts**
class BankAccount:
def withdraw(self):
pass
def deposit(self):
pass
class SavingsAccount(BankAccount):
def __init__(self, balance=500):
self.balance = balance
def deposit(self, amount):
if (amount <= 0):
return "Invalid deposit amount"
else:
self.balance += amount
return self.balance
def withdraw(self, amount):
if(amount <= 0):
return "Invalid withdraw amount"
elif(self.balance <= 500):
return "Cannot withdraw beyond the minimum account balance"
elif(amount > self.balance):
return "Cannot withdraw beyond the current account balance"
else:
self.balance -= amount
return self.balance
class CurrentAccount(BankAccount):
def __init__(self, balance=0):
self.balance = balance
def deposit(self, amount):
if (amount <= 0):
return "Invalid deposit amount"
else:
self.balance += amount
return self.balance
def withdraw(self, amount):
if (amount <= 0):
return "Invalid withdraw amount"
elif (amount >= self.balance):
return "Cannot withdraw beyond the current account balance"
else:
self.balance -= amount
return self.balance
and the unittest is
import unittest
class CurrentAccountTestCases(unittest.TestCase):
def setUp(self):
self.ca = CurrentAccount()
def tearDown(self):
del self.ca
def test_current_account_is_instance_of_bank_account(self):
self.assertTrue(isinstance(self.ca, BankAccount), msg='CurrentAccount is not a subclass of BankAccount')
def test_current_account_can_deposit_valid_amounts(self):
balance = self.ca.deposit(1500)
self.assertEquals(balance, 1500)
def test_current_account_cannot_withdraw_more_than_current_balance(self):
message = self.ca.withdraw(1500)
self.assertEquals(message, 'Cannot withdraw beyond the current account balance', msg='No overdrafts')
def test_current_account_can_withdraw_valid_cash_amounts(self):
self.ca.deposit(23001)
self.ca.withdraw(437)
self.assertEquals(self.ca.balance, 22564, msg='Incorrect balance after withdrawal')
class SavingsAccountTestCases(unittest.TestCase):
def setUp(self):
self.sa = SavingsAccount()
def tearDown(self):
del self.sa
def test_savings_account_is_instance_of_bank_account(self):
self.assertTrue(isinstance(self.sa, BankAccount), msg='SavingsAccount is not a subclass of BankAccount')
def test_savings_account_can_deposit_valid_amounts(self):
init_balance = self.sa.balance
balance = self.sa.deposit(1500)
self.assertEquals(balance, (1500 + init_balance), msg='Balance does not match deposit')
def test_savings_account_cannot_withdraw_more_than_current_balance(self):
message = self.sa.withdraw(1500)
self.assertEquals(message, 'Cannot withdraw beyond the current account balance', msg='No overdrafts')
def test_savings_account_can_withdraw_valid_amounts_successfully(self):
self.sa.deposit(2300)
self.sa.withdraw(543)
self.assertEquals(2257, self.sa.balance, msg="Incorrect balance after withdrawal")
Because your default balance is 500, and your amount is 1500, so the string you it would return is "Cannot withdraw beyond the minimum account balance" and not the one you expect "Cannot withdraw beyond the current account balance"

Python Class Issue

This code is giving me this error.
class Bank:
line 117, in Bank
main()
in main
format(z, '10.2f'), format(bank.MakeWithdrawal(self,amount)))
AttributeError: 'float' object has no attribute 'MakeWithdrawal'
Any idea where I'm going wrong?
Thanks in advance!!!!
class Bank:
def __init__(self,incomingAcctNum,incomingBalance):
self.__acctNum = incomingAcctNum
self.__balance = incomingBalance
self.__totalDeposits = 0
self.__DepositCount = 0
self.__totalWithdrawals = 0
self.__WithdrawalCount = 0
def MakeDeposit(self,amount):
self.__balance = self.__balance + amount
self.__totalDeposits = self.__totalDeposits + amount
self.__DepositCount = self.__DepositCount + 1
def MakeWithdrawal(self,amount):
if (self.__balance >= amount):
self.__balance = self.__balance - amount
self.__totalDeposits = self.__totalDeposits + amount
self.__DepositCount = self.__DepositCount + 1
return True
else:
return False
def DisplayBalance(self):
self.__balance = self.__balance
self.__totalDeposits = self.__totalDeposits
self.__DepositCount = self.__DepositCount
def getAcctNum(self):
return self.__acctNum
def getBalance(self):
return self.__balance
def getTotalDeposits(self):
return self.__totalDeposits
def getDepositCount(self):
return self.__DepositCount
def getTotalWithdrawals(self):
return self.__totalWithdrawals
def getWithdrawalCount(self):
return self.__WithdrawalCount
def main():
a = input("Enter bank account ID #1: ")
b = eval(input("Enter balance for bank account #1: "))
c = input("Enter bank account ID #2: ")
d = eval(input("Enter balance for bank account #2: "))
infile = open("trans","r")
x = (infile.readline().strip())
y = (infile.readline().strip())
z = eval(infile.readline())
print()
print(format("Acct", '15s'), format("Trans Type", '20s'),
format("Amount", '15s'), format("Balance", '10s'))
print("------------------------------------------------------------")
while x != "X":
bank = (z)
if y == "W":
print(format(x, '15s'), format("Withdrawal", '15s'),
format(z, '10.2f'), format(bank.MakeWithdrawal()))
elif y == "D":
print(format(x, '15s'), format("Deposit", '15s'),
format(z, '10.2f'), format(bank.MakeDeposit(self,amount)))
else:
print(format(x, '15s'), format("Balance", '25s'),
format(bank.DisplayBalance(self)))
x = (infile.readline().strip())
y = (infile.readline().strip())
z = eval(infile.readline())
print("-------------------------------------------------------------")
print()
print(format("ABC123, Deposits: ", '15s'))
print(format("ABC123, Withdrawals: ", '15s'))
print(format("ABC123, Ending Balance: ", '20s'))
print()
print(format("DEF456, Deposits: ", '15s'))
print(format("DEF456, Withdrawals: ", '15s'))
print(format("DEF456, Ending Balance: ", '20s'))
main()
Your bank in this case is a float, I don't think that is right.
bank.MakeWithdrawal() needs an amount to withdrawal. i.e bank.MakeWithdrawal(amount)
in
if y == "W":
print(format(x, '15s'), format("Withdrawal", '15s'),
format(z, '10.2f'), format(bank.MakeWithdrawal()))
The same goes for bank.Makedeposit(). bank.DisplayBalance() doesn't need an input bank is the self when called. i.e. bank.DisplayBalance()
Also make sure that your indentatation is correct, I don't know if it is a copy/paste error or not, but it looks like your def main() is a method in the Bank class.
You first say that z is a float by the line z = eval(infile.readline()).
Then you say that bank is z since bank = (z).
Make bank an instance of Bank instead, possibly in a main loop outside of the class.
create an object of Bank class and call bank methods on it replace line bank=(z) with bank=Bank(inComingAcctNum,incomingBalance) .
and also keep main out of the class.

Categories

Resources