Call atribute of class object in class function - python

class client:
def __init__(self):
self.name = str(input("Name: "))
self.surname = str(input("Surname: "))
self.year = str(input("Year of birth: "))
self.id =(self.name[0] + self.surname[0] + self.year)
self.balance = 0
def Transfer(self):
balance = self.balance
action = int(input("How much would you like to transfer ?"))
if action > balance:
print("Not enough money")
else:
id = str(input("choose user you want to send money to:"))
self.balance = balance - action
#call id of crated client here to choose him as reciever of transfer
print(f"Succesfully transfered {action}$, your balance right now is {self.balance}$ have a nice day !!")
def Balance(self):
print(f"Your account balance is: {self.balance}")
Task : Send money between users
Problem : i have no idea how to call specific ID of class object that will be created

Related

How to print new balance after adding amount to the initial one?

I'm learning Python and went with a simple ATM code. I've tested it and everything works DownStream - what I mean by this is:
I have a few options when the class is initialized - Balance, Deposit, Withdraw, Exit.
When I run Balance I receive the amount set.
2.1. I go with Deposit - it shows the new amount the person has in their account
2.2. When I use Withdraw I get correct amount as well
Question - When I Deposit and then type Balance I'm getting the initial Balance of the user - that is expected. How can I change the code so after Depositing Money and select Balance to show me the new Balance?
Is this possible to be performed without much complicating the code?
The code:
class User:
def __init__(self):
self.fname = input('Enter your first name: ')
self.lname = input('Enter your last name: ')
self.age = input('Enter your age: ')
def user_details(self):
print('Details:')
print(f"First Name: {self.fname}")
print(f"Last Name: {self.lname}")
print(f"User age: {self.age}")
def deposit_money(self):
self.deposit_amount = 100
return self.deposit_amount
def withdraw_money(self, withdraw_amount):
self.withdraw_amount = withdraw_amount
return self.withdraw_amount
class ATM:
atm_balance = 10000
def __init__(self):
self.machine_balance = self.atm_balance
def user_bank_balance(self):
self.user_balance = 300
print ('Your current balance is ${}'.format(self.user_balance))
def deposit_atm(self, user):
self.total_savings = 0
deposit_m = float(input('How much do you want to deposit? '))
if deposit_m > user.deposit_money():
print('You do not have enough money to deposit')
elif deposit_m == user.deposit_money():
print('Amount deposited: ${}'.format(deposit_m))
self.total_savings = self.user_balance + deposit_m
print('Total amount in your account: ${}'.format(self.total_savings))
def withdraw_atm(self):
savings_left = 0
sum_to_withdraw = float(input('How much do you want to withdraw? '))
if self.atm_balance > sum_to_withdraw and self.user_balance > sum_to_withdraw:
savings_left = self.total_savings - sum_to_withdraw
print("You have withdraw {}".format(sum_to_withdraw))
print('You balance is {}'.format(savings_left))
elif self.atm_balance > sum_to_withdraw and self.user_balance < sum_to_withdraw:
print('Daily limit eceeded')
else:
print('ATM out of service')
class ATMUsage:
#classmethod
def run(cls):
print('Bulbank ATM')
instructions = print("""
Type 'Balance' to check your current balance,
Type 'Deposit' to deposit amount into your account,
Type 'Withdraw' to withdraw from your account,
Type 'Exit' to exit from your account,
""")
active = True
user1 = User()
atm1 = ATM()
user1.user_details()
while active:
selection = input("What would you like to do: 'Balance', 'Deposit', 'Withdraw', 'Exit': ")
if selection == 'Balance'.lower():
atm1.user_bank_balance()
elif selection == 'Deposit'.lower():
atm1.deposit_atm(user1)
elif selection == "Withdraw".lower():
atm1.withdraw_atm()
elif selection == 'Exit'.lower():
print('Thanks for passing by. Have a good one!')
break
else:
print('Wrong selection. Please, try again')
ATMUsage.run()
That's because every time you call the user_bank_balance method, you set the user_balance attribute to 300. So it wouldn't matter what updates you did on the user_balance, whenever you call the user_bank_balance method, you'll get 300
class ATM:
atm_balance = 10000
def __init__(self):
self.machine_balance = self.atm_balance
self.user_balance = 300
def user_bank_balance(self):
print ('Your current balance is ${}'.format(self.user_balance))

Classes and Instances

I am new to OOP and practicing by writing a budget class as asuch:
class Budget:
category_record = []
def __init__(self, category = '', balance = 0):
self.category = category
self.balance = balance
Budget.category_record.append(self)
def deposit(self, amount):
self.balance += amount
print(f"You have deposited {amount} into your {self.category} Budget, your balance is {self.balance}")
return
def withdraw(self, amount):
if amount > self.balance:
print('Insufficient Balance, unable to withdraw')
else:
self.balance -= amount
print(f"You have withdrawn {amount} from your {self.category} Budget, your balance is {self.balance}")
return
def category_balance(self):
print(f'Your balance is {self.balance} for your {self.category} budget')
IM trying to keep a record of all instances of the budget class as a method(Forgive me if my terms are wrong, still getting used to them)
# Instantiate Food budget
food = Budget('food')
# deposit 200 into food budget
food.deposit(200)
# withdraw 100 from food budget
food.withdraw(100)
#instantaite rent budget
rent = Budget('house', 5000)
# check balance of rent budget
rent.category_balance()
Such that when I call a record method on the budget class I can get a list of ['food', 'rent']
or if possible a dictionary with the key as category and value as balance {'food':100...}
To elaborate on my #classmethod comment:
class Budget:
category_record = []
def __init__(self, category = '', balance = 0):
self.category = category
self.balance = balance
Budget.category_record.append(self)
def deposit(self, amount):
self.balance += amount
print(f"You have deposited {amount} into your {self.category} Budget, your balance is {self.balance}")
return
def withdraw(self, amount):
if amount > self.balance:
print('Insufficient Balance, unable to withdraw')
else:
self.balance -= amount
print(f"You have withdrawn {amount} from your {self.category} Budget, your balance is {self.balance}")
return
def category_balance(self):
print(f'Your balance is {self.balance} for your {self.category} budget')
#classmethod
def budget_list(cls):
if len(Budget.category_record)== 0:
print("No budgets created")
else:
print("Budget Categories:")
for budge in Budget.category_record:
print(budge.category)
#classmethod
def full_report(cls):
if len(Budget.category_record)== 0:
print("No budgets created")
else:
print("Budget Balances:")
for budge in Budget.category_record:
print(f"{budge.category} : {budge.balance}")
# Instantiate Food budget
food = Budget('food')
# deposit 200 into food budget
food.deposit(200)
# withdraw 100 from food budget
food.withdraw(100)
#instantaite rent budget
rent = Budget('house', 5000)
# check balance of rent budget
rent.category_balance()
Budget.budget_list()
Budget.full_report()
If you want to get a list of all of the instances of the Budget class, your method can just return the category_record list in which you have already been storing all instances as they are created. However, it seems you want the list to contain the names (identifiers) of the variables to which you are assigning the instances. The Budget class will have no way to access those names, so instead, I recommend you try and use the category names as that will be recorded in your category_record variable.
From your question I'm assuming you want the method to be called record. The best way to do this is to use a class method with the built-in classmethod decorator. These methods act on the class itself, and not an instance, and thus take a cls parameter instead of a self parameter (both of those names are only the convention, however I strongly advise against straying from the convention as it will make your code unnecessarily complex for everyone else). For example:
class Budget:
...
# other code
....
category_record = []
#classmethod
def record(cls):
return [budget.category for budget in cls.category_record]
# If you are unfamiliar with this syntax, search up "list comprehensions"
# Access the list
print(Budget.category_record)
If you want a dictionary instead, you can replace that method with this:
class Budget:
...
# other code
...
category_record = []
#classmethod
def record(cls):
return {budget.category:budget.balance for budget in cls.category_record}
# If you are unfamiliar with this syntax, search up "dictionary comprehensions"
# Access the dictionary
print(Budget.category_record)

Why do I get typeerror when I use variable in class python?

I have this program to bank account with a class. It is supposed to deposit a balance into the account as you can see at a1.deposit(1000) and then update the balance on the account.
class BankAccount:
def __init__(self,first_name,last_name,number,balance):
self.first_name = first_name
self.last_name = last_name
self.number = number
self.balance = balance
def deposit(self,amount):
self.balance += amount
def withdraw(self,amount):
self.withdraw -= amount
def print_info(self):
first=self.first_name
last=self.last_name
number=self.number
balance = self.balance
s=f'{first} {last}, {number}, balance: {balance}'
print(s)
a1= BankAccount('Gang', 'Land', '19371554951', '20000')
a1.deposit(1000)
print(a1.balance)
I dont understand whats wrong because I get only type error:
self.balance += amount
TypeError: can only concatenate str (not "int") to str
I believe your error is with this line :
a1= BankAccount('Gang', 'Land', '19371554951', '20000')
if you are wanting to increase the value of the balance, then you need to initiate that variable as an integer or float. So just remove the '' around the 20000 and try again.

NameError: throwing error as name 'self' is not defined

class Account():
def __init__(self,owner,balance):
self.owner = owner
self.balance = balance
def __str__(self):
return "Account owner : {}\nAccount balance: {}".format(self.owner,self.balance)
def deposit(amount):
print ("How much you want to deposit")
amount = int(input())
self.balance = (balance) + (amount)
return "Deposit Accepted\nThe new balance is {}".format(self.balance)
def withdraw(amount):
if (self.balance >= amount):
self.balance = self.balance - amount
return "Withdrawal Accepted\nThe new balance is {}".format(self.balance)
else:
return "Insufficient funds!!"
Account_1 = Account("sammy",500)
print(Account_1)
Account_1.owner
Account_1.balance
Account_1.deposit()
Account_1.withdraw(650)
Account_1.withdraw(300)
while executing this code i am getting error as "NameError: name 'self' is not defined"
i dont understand why i a getting this error since 'self' is used as 'self reference'for a class and i've done it already.
this code is just a simple problem which i got to solve while studying classes and methods.
self should be the first argument to any method in a class that uses self (e.g. self.balance), so your withdraw and deposit methods are missing a self:
def deposit(self,amount):
print ("How much you want to deposit")
amount = int(input())
self.balance += amount
return "Deposit Accepted\nThe new balance is {}".format(self.balance)
def withdraw(self,amount):
if (self.balance >= amount):
self.balance = self.balance - amount
return "Withdrawal Accepted\nThe new balance is {}".format(self.balance)
else:
return "Insufficient funds!!"
Note that you're missing the amount in your self.deposit() statement. There's also a missing self in self.balance in your deposit method.
deposit and withdraw are member functions. So member functions should have first argument as self.
Then deposit function do not need an argument in the function definition. Here is the corrected code. Also it would be helpful if you post the stack trace for the error. That would help to zero in on the issue fast.
class Account():
def __init__(self,owner,balance):
self.owner = owner
self.balance = balance
def __str__(self):
return "Account owner : {}\nAccount balance: {}".format(self.owner,self.balance)
def deposit(self):
print ("How much you want to deposit")
amount = int(input())
self.balance = self.balance + amount
return "Deposit Accepted\nThe new balance is {}".format(self.balance)
def withdraw(self, amount):
if (self.balance >= amount):
self.balance = self.balance - amount
return "Withdrawal Accepted\nThe new balance is {}".format(self.balance)
else:
return "Insufficient funds!!"
Account_1 = Account("sammy",500)
print(Account_1)
Account_1.owner
Account_1.balance
Account_1.deposit()
Account_1.withdraw(650)
Account_1.withdraw(300)

How to call functions from one subclass to another subclass

class Acct:
def __init__(self, deposit):
self.balance = deposit
def balance(self):
print("Your balance is $",self.balance)
def getDeposit(self, deposit):
self.balance = self.balance + deposit
print("Your new balance is $",self.balance)
def getWithdraw(self, withdraw):
self.balance = self.balance - withdraw
print("Your new balance is $",self.balance)
class ChkAcct(Acct):
def __init__(self, deposit):
super().__init__(deposit)
class SavAcct(Acct):
def __init__(self, deposit):
super().__init__(deposit)
savings_account_starting_balance = float(input("Enter a starting balance for your savings account :"))
savings_account = SavAcct(savings_account_starting_balance)
savings_account.balance()
checking_account_starting_balance = float(input("Enter a starting balance for your checking account :"))
checking_account = ChkAcct(checking_account_starting_balance)
checking_account.balance()
savings_account.getDeposit(float(input("Enter a deposit ammout for savings account :")))
checking_account.getDeposit(float(input("Enter a deposit ammout for checking account:")))
savings_account.getWithdraw(float(input("Enter a withdraw ammout from savings:")))
checking_account.getWithdraw(float(input("Enter a withdraw ammout from checking:")))
I need to make 2 classes ChkAcct and SavAcct. Each class should have a balance property. Each class should have a deposit method. Each class should have a withdraw method. Each class should also have a transfer method that calls its own withdraw method and invokes the deposit method from the other class.
I can't seem to figure out how to make the transfer methods.
There are many ways to implement this.
Here's one:
class Acct:
def __init__(self, deposit):
self.balance = deposit
# Try to avoid same names for methods and properties, unless you have a good reason for it
# Otherwise you may end up with an error like this: "TypeError: 'float' object is not callable",
# when you try to call your original balance() method
# So I renamed it to getBalance()
def getBalance(self):
print("Your balance is $",self.balance)
def getDeposit(self, deposit):
self.balance = self.balance + deposit
print("Your new balance is $",self.balance)
def getWithdraw(self, withdraw):
self.balance = self.balance - withdraw
print("Your new balance is $",self.balance)
# Transfer 'amount' from current instance to 'destination' instance
def transfer(self, amount, destination):
self.getWithdraw(amount)
destination.getDeposit(amount)
class ChkAcct(Acct):
def __init__(self, deposit):
super().__init__(deposit)
class SavAcct(Acct):
def __init__(self, deposit):
super().__init__(deposit)
# Set up the accounts and fund them
print("1. Setting accounts")
savings_account = SavAcct(100.00)
checking_account = ChkAcct(200.00)
savings_account.getBalance()
checking_account.getBalance()
# Now do the transfer
print("2. Transferring money")
savings_account.transfer(50.00, checking_account)
The output will be this:
# 1. Setting accounts
# Your balance is $ 100.0
# Your balance is $ 200.0
# 2. Transferring money
# Your new balance is $ 50.0
# Your new balance is $ 250.0
The other way is to have a standalone function for this:
def transfer(amount, origin, destination):
origin.getWithdraw(amount)
destination.getDeposit(amount)
And then call it:
transfer(50.00, savings_account, checking_account)
class Acct:
def __init__(self, deposit):
self.balance = deposit
def getBalance(self):
print("Your new "+str(self.__class__.__name__)+" balance is $",self.balance)
def getDeposit(self, deposit):
self.balance = self.balance + deposit
print("Your new "+str(self.__class__.__name__)+" balance is $",self.balance)
def getWithdraw(self, withdraw):
self.balance = self.balance - withdraw
print("Your new "+str(self.__class__.__name__)+" balance is $",self.balance)
def getTransfer (self, account, destination):
self.getWithdraw(account)
destination.getDeposit(account)
class ChkAcct(Acct):
def __init__(self, deposit):
super().__init__(deposit)
class SavAcct(Acct):
def __init__(self, deposit):
super().__init__(deposit)
savings_account_starting_balance = float(input("Enter a starting balance for your savings account :"))
new_savings_account = SavAcct(savings_account_starting_balance)
new_savings_account. getBalance()
checking_account_starting_balance = float(input("Enter a starting balance for your checking account :"))
new_checking_account = ChkAcct(checking_account_starting_balance)
new_checking_account. getBalance()
new_savings_account.getDeposit(float(input("Enter a deposit ammout for savings account :")))
new_checking_account.getDeposit(float(input("Enter a deposit ammout for checking account :")))
new_savings_account.getWithdraw(float(input("Enter a withdraw ammout from savings :")))
new_checking_account.getWithdraw(float(input("Enter a withdraw ammout from checking :")))
new_checking_account.getTransfer(float(input("Enter a transfer ammount from checking to savings :")),new_savings_account)
new_savings_account.getTransfer(float(input("Enter a transfer ammount from savings to checking :")),new_checking_account)
thanks to a friend I ended up with this. I like the added touch of calling back the class name in the output to help the user differentiate account balance

Categories

Resources