python. Unable to run program - python

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

Related

Use class variable inside a method of this class

I'm trying to update the value of a class variable when someone deposits money in my bank.
My code
class Bank_account():
bank_balance = 0
def __init__(self, name_holder, id, balance):
self.name = name_holder
self.id = id
self.balance = balance
bank_balance += balance
def cash_in(self, cash):
self.balance += cash
bank_balance += cash
def with_draw(self, draw):
if self.balance < draw or bank_balance < draw:
print('Error')
else:
print('Here your money!')
John = Bank_account('John', 123456, 2.10**6)
Smith = Bank_account('Smith', 111111, 3.10**6)
Michael = Bank_account('Michael', 123123, 4.10**6)
Bank_account.bank_balance
My result
UnboundLocalError Traceback (most recent call last)
<ipython-input-30-0a83e2bc19e8> in <module>
19 print('Here your money!')
20
---> 21 Quang = Bank_account('Quang', 123456, 2.10**6)
22 Kien = Bank_account('Kien', 111111, 3.10**6)
23 Trung = Bank_account('Trung', 123123, 4.10**6)
<ipython-input-30-0a83e2bc19e8> in __init__(self, name_holder, id, balance)
7 self.id = id
8 self.balance = balance
----> 9 bank_balance += balance
10
11 def cash_in(self, cash):
UnboundLocalError: local variable 'bank_balance' referenced before assignment
Could anyone tell me how to use class variables and explain my error?
class Bank_account():
def __init__(self, name_holder, id, balance,bank_balance=0):
self.name = name_holder
self.id = id
self.balance = balance
self.bank_balance = balance
def cash_in(self, cash):
self.balance += cash
self.bank_balance += cash
def with_draw(self, draw):
if self.balance < draw or bank_balance < draw:
print('Error')
else:
print('Here your money!')
John = Bank_account('John', 123456, 2.10**6)
Smith = Bank_account('Smith', 111111, 3.10**6)
Michael = Bank_account('Michael', 123123, 4.10**6)
print(John.bank_balance)
I think this is what you are trying to do.
If you absolutely have to, try the following:
(Notice I have added: Bank_account.bank_balance because that initializes the class variable as well. Verify that the output produced is what you want)
class Bank_account:
bank_balance = 0
def __init__(self, name_holder, id, balance):
self.name = name_holder
self.id = id
self.balance = balance
Bank_account.bank_balance += balance # change is here
def cash_in(self, cash):
self.balance += cash
bank_balance += cash
def with_draw(self, draw):
if self.balance < draw or bank_balance < draw:
print('Error')
else:
print('Here your money!')
John = Bank_account('John', 123456, 2.10**6)
Smith = Bank_account('Smith', 111111, 3.10**6)
Michael = Bank_account('Michael', 123123, 4.10**6)
print(Bank_account.bank_balance)
class Bank_account():
bank_balance = 0
def __init__(self, name_holder, id, balance):
self.name = name_holder
self.id = id
self.balance = balance
self.bank_balance += balance
def cash_in(self, cash):
self.balance += cash
bank_balance += cash
def with_draw(self, draw):
if self.balance < draw or bank_balance < draw:
print('Error')
else:
print('Here your money!')
John = Bank_account('John', 123456, 2.1-**6)
Smith = Bank_account('Smith', 111111, 3.10**6)
Michael = Bank_account('Michael', 123123, 4.10**6)
print(John.bank_balance)
Since code inside a class, but outside of methods/functions is not executed, the variable is not declared in the momory. So, the solution would be to declare it in the init method in the following way:
class Bank_account():
def __init__(self, name_holder, id, balance):
# This has been changed
bank_balance = 0
self.name = name_holder
self.id = id
self.balance = balance
bank_balance += balance
def cash_in(self, cash):
self.balance += cash
bank_balance += cash
def with_draw(self, draw):
if self.balance < draw or bank_balance < draw:
print('Error')
else:
print('Here your money!')
John = Bank_account('John', 123456, 2.10**6)
Smith = Bank_account('Smith', 111111, 3.10**6)
Michael = Bank_account('Michael', 123123, 4.10**6)
Bank_account.bank_balance
Or if you want to access the bank balance detached from each bank_account object, just add a line saying global bank_balance in the following manner:
class Bank_account():
def __init__(self, name_holder, id, balance):
# This has been changed
global bank_balance
bank_balance = 0
self.name = name_holder
self.id = id
self.balance = balance
bank_balance += balance
def cash_in(self, cash):
self.balance += cash
bank_balance += cash
def with_draw(self, draw):
if self.balance < draw or bank_balance < draw:
print('Error')
else:
print('Here your money!')
John = Bank_account('John', 123456, 2.10**6)
Smith = Bank_account('Smith', 111111, 3.10**6)
Michael = Bank_account('Michael', 123123, 4.10**6)
Bank_account.bank_balance
But I strongly recommend to add self before the bank_balance variable

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 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"

Manipulating items of array of class objects in Python

For the code below, I create an array of class objects using a for loop. However, I'm not able to access and modify the objects in the list. What do I have to change to make this work?
def main():
class BankAccount:
def __init__(self,nameOfCustomer,balanceOfCustomer):
self.name = nameOfCustomer
self.balance = balanceOfCustomer
print "\nNew customer created in system with name " + self.name + " and initial balance of $" + str(self.balance)
def get_balance(self):
print "The current balance for " + self.name + " is: $" + str(self.balance)
return self.balance
def deposit(self,amount):
self.balance += amount
print self.name + " just deposited $" + str(amount)
return self.balance
def withdraw(self,amount):
self.balance -= amount
print self.name + " just withdrew $" + str(amount)
return self.balance
customerList = {"Eric": 10000,
"Tom": 20000,
"Bill": 25000,
"Casey": 40000}
individualAccountList = []
for key, value in customerList.iteritems():
individualAccountList.append(BankAccount(key,customerList[key]))
for i in individualAccountList:
print i
if __name__ == '__main__':
main()
it works:
for i in individualAccountList:
print i.name
gives:
Casey
Bill
Eric
Tom
than:
individualAccountList[0].name = "name changed"
print individualAccountList[0].name
>> name changed

Categories

Resources