Updating the method references on VS code - python

I am having a hard time figuring out how to update selected references of a method from vscode. Right-clicking on the method name doesn't give the options to choose and update the references. New to Python and vscode and trying to figure out the nuances around it. Can some help me with this please!
Here are the classes - I have a class Player_Account
class Player_Account:
def __init__(self,owner,balance):
self.owner = owner
self.balance = balance
def deposit(self,balance):
self.balance += balance
return "Amount added to players pot !"
def withdraw(self,amount): # I need to update this method name to withdraw_amount
if self.balance<amount:
return "Funds Unavailable"
else:
self.balance -= amount
return "Money added to hand !"
def __str__(self):
return f"Account owner : {self.owner} has outstanding balance of {self.balance}"
Another class Player
class Player:
def __init__(self,name):
self.name=name
self.hand = []
self.player_account:Player_Account = Player_Account(name,0)
def initial_money(self,amount):
self.player_account.balance = amount
def player_won_the_hand(self,amount):
self.player_account.deposit(amount)
return True
def player_betting_amount_for_the_round(self,amount):
value = self.player_account.withdraw(amount) # I need this reference to be automatically updated as well
if value == 'Funds Unavailable':
return False
else:
return True

I just tried.
set cursor on def withdraw
press F2 (rename symbol)
change name to withdraw_amount and press Enter
it takes a few seconds but both are changed
I use PyLance.

Related

Cannot append objects to a list

I'm having some troubles with my code. This is a budget app in which you can add categories and for every category you can deposit/withdraw money. The problem is that I have to save all the transactions in the format {"amount": x, "description":y} and to do this I create an object of class Amount which is defined in the code, but when I try to append the new Amount object to the list every single element of this list changes to the last object. I understood that when I add an object, all the other elements in the list refer to the same object, and that's probably the problem, but I cannot solve this. Can you help me? Thank you very much
(This bug happens in the methods deposit and withdraw)
class Amount:
tot={"amount":0,"description":""}
def __init__(self,am,descr=""):
self.tot["amount"]=am
self.tot["description"]=descr
def getTot(self):
return self.tot
class Category:
title=""
deposit_list=list()
balance=0
def __init__(self,name):
self.title=name
def __str__(self):
final_string=""
length=int((30-len(self.title))/2)
for i in range(0,length):
final_string+="*"
final_string+=self.title
for i in range(0,length):
final_string+="*"
final_string+="\n"
for x in self.deposit_list:
y=x.getTot()["description"]
y=y[0:23]
z=float(x.getTot()["amount"])
final_string+=y
l=len(y)
if l<23:
for i in range(l,23):
final_string+=" "
z=str(z)
l=len(z)
if l<7:
for i in range(l,7):
final_string+=" "
final_string+=z
final_string+="\n"
final_string+="Total: "
final_string+=str(self.balance)
return final_string
def get_balance(self):
return self.balance
def getTitle(self):
return self.title
def deposit(self,amount,description=""):
if description!="":
description=str(description)
dep=Amount(amount,description)
self.deposit_list.append(dep)
self.balance+=dep.getTot()["amount"]
def withdraw(self,amount,description=""):
if description!="":
description=str(description)
wd=Amount(-1*amount,description)
if self.check_funds(amount):
self.deposit_list.append(wd)
self.balance+=wd.getTot()["amount"]
return True
else:
return False
def transfer(self,amount,dest):
descr_dest="Transfer from "
descr_dest+=self.getTitle()
descr_src="Transfer to "
descr_src+=dest.getTitle()
if self.withdraw(amount,descr_src)==True:
dest.deposit(amount,descr_dest)
return True
else:
return False
def check_funds(self,amount):
if amount>self.balance:
return False
else:
return True
def create_spend_chart(categories):
return
Edit:
I'm sorry, here is a test you can run
import budget
from unittest import main
food = budget.Category("Food")
food.deposit(1000, "initial deposit")
food.withdraw(10.15, "groceries")
food.withdraw(15.89, "restaurant and more food for dessert")
clothing = budget.Category("Clothing")
food.transfer(50, clothing)
print(food)
It should print this:
*************Food*************
initial deposit 1000.00
groceries -10.15
restaurant and more foo -15.89
Transfer to Clothing -50.00
Total: 923.96
I also have to say that it should print only the first 23 characters of the description, but this shouldn't be important for the question.
#frno that was an attempt to avoid the problem described in the question, I edited the code as it was before that update
Thank you!

How to calculate variable declared in a method from inside python class function

need help about my code (python):
class Account:
def __init__(self, money):
self.money= money
def __str__(self):
return f'Money in the bank: {self.money} dollar'
def withdraw(self,withdraw):
self.withdraw = withdraw
money = self.money-self.withdraw
return money
print(Account.withdraw(20000,1000))
What I want from code above is the code will print my remaining money (19000), but I always got error
'int' object has no attribute 'withdraw'.
I have tried a lot of things for 4 hours but got no satifying result.
This is my first question in this forum, i am sorry if the formatting is not right.
Thank you in advance :)
Below I have made some small changes in your code and it is working as you expect.
Defined new variable withdrawMoney to track the withdraw amount.
Some changes in string format.
Returned the updated amount every time.
class Account:
def __init__(self, money):
self.money= money
self.withdrawMoney = 0
def __str__(self):
return "Money in the bank: {} dollar".format(self.money)
def withdraw(self,withdrawMoney):
self.withdrawMoney = withdrawMoney
self.money = self.money-self.withdrawMoney
return self.money
acc = Account(20000)
print(acc.withdraw(1000)) # 19000
print(acc.withdraw(1000)) # 18000

How to store attributes of class instance in empty dictionary in Python?

I am making a custom class that performs basic banking functions.
class Account():
'''
A class to perform some basic banking functions
'''
UserList = {} #Empty dictionary to store (UID: name) for each new instance
def __init__(self, name, balance=0.0, uid=None):
self.name = name #The name of the account holder
self.balance = balance #The initial balance
self.uid = uid #User ID number chosen by account holder
#classmethod
def new_account(cls):
'''
New user can specify details of account through this class method via input()
'''
return cls(
input('Name: '),
int(input('Balance: ')),
int(input('UID: ')),
)
def withdraw(self, amount):
if amount > self.balance:
raise RuntimeError('Amount greater than available balance.')
else:
self.balance -= amount
return print("After a withdrawl of {}, {}'s current balance is {}".format(amount, self.name, self.balance)) #printing balance after withdrawl
def deposit(self, amount):
self.balance += amount
return print("After a deposit of {}, {}'s curent balance is {}".format(amount, self.name, self.balance)) # printing balance after deposit
Basically, a new user is created by creating an instance of the Account() class and it accepts a name, initial balance, and a user ID. I added a class method to take this data in through user input when Account.new_account() is called. What I am now looking to do is store the User ID and name for each instance(account) in an empty dictionary. I have been playing around with this for a few hours, and what I was thinking was something like this
def add_user(self, uid, name):
UserList[int(self.uid)] = self.name
inserted somewhere but I tried implementing this in a few places in my code and it continued to just return an empty dictionary. Could someone help point me in the right direction. Also, the two other things I am trying to implement along with this is a way to prevent users from selecting the same UID and a way to require the UID to be exactly 5 numbers. I am relatively new to Python. Thank you.
You can define a dict as a class variable as you already did, but add the UID as a key to the dict in the __init__ method instead of a separate add_user method so that you can always validate the UID when an object is instantiated, no matter how:
class Account():
users = {}
def __init__(self, name, balance=0.0, uid=None):
if uid in self.users:
raise ValueError("UID '%s' already belongs to %s." % (uid, self.users[uid].name))
if len(uid) != 5 or not uid.isdigit():
raise ValueError("UID must be a 5-digit number.")
self.name = name
self.balance = balance
self.uid = uid
self.users[uid] = self
First noticed that you cant to a "return print(...", remove print.
You can do something like this
class Account():
'''
A class to perform some basic banking functions
'''
UserList = {} #Empty dictionary to store (UID: name) for each new instance
def __init__(self, name, balance=0.0, uid=None):
self.name = name #The name of the account holder
self.balance = balance #The initial balance
self.uid = uid #User ID number chosen by account holder
self.add_user(uid, name)
#classmethod
def new_account(cls):
'''
New user can specify details of account through this class method via input()
'''
return cls(
input('Name: '),
int(input('Balance: ')),
int(input('UID: ')),
)
def withdraw(self, amount):
if amount > self.balance:
raise RuntimeError('Amount greater than available balance.')
else:
self.balance -= amount
return "After a withdrawl of {}, {}'s current balance is {}".format(amount, self.name, self.balance) #printing balance after withdrawl
def deposit(self, amount):
self.balance += amount
return "After a deposit of {}, {}'s curent balance is {}".format(amount, self.name, self.balance) # printing balance after deposit
def add_user(self, uid, name):
self.UserList[int(uid)] = name
a = Account("new user", 100, 1)
a.add_user(2, "new user")
a.add_user(3, "new user")
print(a.UserList)
this will output {1: 'new user', 2: 'new user', 3: 'new user'}
Reference the static variable from the class name:
class Account():
user_list = {}
def __init__(self, uid):
self.uid = uid
Account.user_list[uid] = self
a = Account('uid')
print(a.user_list)
# {'uid': <__main__.Account object at 0x1043e7b38>}
For what it's worth, I think a better approach would be to use 2 classes (for convenience, I'm also using dataclasses to auto-generate some functionality - it doesn't affect the core logic). Then you don't have to worry about static variables at all.
import dataclasses
from typing import Dict
#dataclasses.dataclass
class Account:
uid: str
#dataclasses.dataclass
class Bank:
accounts : Dict[str, Account] = dataclasses.field(default_factory=dict)
def add_account(self, account):
if account.uid in self.accounts:
raise ValueError(f'UID : {account.uid} already exists!')
self.accounts[account.uid] = account
b = Bank()
a1 = Account('a1')
b.add_account(a1)
print(b)
# Bank(accounts={'a1': Account(uid='a1')})

Return Dictionary in using str in python

I have a bank account OOP project I am working on. And I can't seem to figure out this one bug. In brief, I would like to return a users bank account after they have added it. I have included all the code because I've solved this in an object-oriented way. The str() method seems to be the problem.
from enum import Enum
class AccountType(Enum):
SAVINGS = 1
CHECKING = 2
class BankAccount():
def __init__(self, owner, accountType):
self.owner = owner
self.accountType = AccountType(accountType)
self.balance = 0
def withdraw(self, amount):
if amount > self.balance:
raise Exception('Your balance is' + self.balance + 'cannot take this much money!')
else:
self.balance -= amount
def deposit(self,amount):
self.balance += amount
def __str__(self):
return "Owner: {}. Account type is: {} ".format(self.owner, AccountType(self.accountType).name)
def __len__(self):
return self.balance
#This class is responsible for returning information about the user and their account type.
class BankUser():
#initialize an accounts dictionary.
accounts = {}
def __init__(self, owner):
self.owner = owner
def addAccount(self, accountType):
if self.accounts.get(accountType) != None:
raise Exception('Cannot have more than 1 ' + AccountType(accountType).name + ' account!')
self.accounts[accountType] = BankAccount(self.owner, accountType)
#test if user inputs an account, otherwise throw an error
def getBalance(self, accountType):
return len(self.accounts[accountType])
def deposit(self, accountType, amount):
if (accountType in self.accounts and isinstance(self.accounts[accountType], BankAccount)):
self.accounts[accountType].deposit(amount)
else:
raise Exception(self.owner + ' does not have a ' + AccountType(accountType).name + ' account!')
def withdraw(self, accountType, amount):
self.accounts[accountType].withdraw(amount)
def __str__(self):
return "Your account is {}".format(AccountType(accountType).name)
user = BankUser("David")
user.addAccount(1)
print(user)
#OUTPUT
TypeError: __str__() missing 1 required positional argument: 'accountType'
I would like to return a users account. How do I do that? Everything I have tried has ended up with this error.
You will need to move the accounts dictionary to be owned by a single bank user instance, not the bank user class (move to the __init__)
Then, all your methods have accountType except __str__, so you cannot just access it as a variable, but you could return the whole dictionary instead.
class BankUser():
def __init__(self, owner):
self.owner = owner
#initialize an accounts dictionary.
self.accounts = {}
...
def __str__(self):
return "Accounts: {}".format(self.accounts)
Or you can do [AccountType(type).name for type in self.accounts]

An exercise from fundamentals of python [duplicate]

This question already exists:
Closed 11 years ago.
Possible Duplicate:
Fundamentals of Python Chapter 8 project 3
Hi I am a newbie programmer who just started to learn about python.
I have recently posted this same question before and I have solved it but my answer is not exactly what the question is asking.
I need help on why I need to implement a new method even though I could do the other way.
thanks
Question:
The __str__ method of the Bank class returns a string containing the
accounts in random order. Design and implement a change that causes
the accounts to be placed in the string by order of name.
[this is the part where I don't understand]
(Hint: You will also have to define a new method in the SavingsAccount class.)
class Bank(object):
def __init__(self):
self._accounts = {}
def __str__(self):
"""Return the string rep of the entire bank."""
pTemp =[]
for i in xrange(len(SavingsAccount.temp)-1):
if self._accounts.get(SavingsAccount.temp[i]).getName() >= self._accounts.get(SavingsAccount.temp[i+1]).getName():
temp = SavingsAccount.temp[i]
SavingsAccount.temp[i] = SavingsAccount.temp[i+1]
SavingsAccount.temp[i+1] = temp
for i in SavingsAccount.temp:
pTemp.append(self._accounts[i])
return '\n'.join(map(str, pTemp))
def add(self, account):
"""Inserts an account using its PIN as a key."""
self._accounts[account.getPin()] = account
def remove(self, pin):
return self._accounts.pop(pin, None)
def get(self, pin):
return self._accounts.get(pin, None)
def computeInterest(self):
"""Computes interest for each account and
returns the total."""
total = 0.0
for account in self._accounts.values():
total += account.computeInterest()
return total
class SavingsAccount(object):
"""This class represents a Savings account
with the owner's name, PIN, and balance."""
RATE = 0.02
temp = []
def __init__(self, name, pin, balance = 0.0):
self._name = name
self._pin = pin
self._balance = balance
SavingsAccount.temp.append(self)
def __str__(self):
result = 'Name: ' + self._name + '\n'
result += 'PIN: ' + self._pin + '\n'
result += 'Balance: ' + str(self._balance)
return result
def getBalance(self):
return self._balance
def getName(self):
return self._name
def getPin(self):
return self._pin
def deposit(self, amount):
"""Deposits the given amount and returns the
new balance."""
self._balance += amount
return self._balance
def withdraw(self, amount):
"""Withdraws the given amount.
Returns None if successful, or an
error message if unsuccessful."""
if amount < 0:
return 'Amount must be >= 0'
elif self._balance < amount:
return 'Insufficient funds'
else:
self._balance -= amount
return None
def computeInterest(self):
"""Computes, deposits, and returns the interest."""
interest = self._balance * SavingsAccount.RATE
self.deposit(interest)
def main():
bank = Bank()
bank.add(SavingsAccount("Zelda","1003",5000.00))
bank.add(SavingsAccount("Wilma","1001",4000.00))
bank.add(SavingsAccount("Fred","1002",1000.00))
print bank
main()
I think the question expects you to define ordering in the SavingsAccount class, that is, be able to determine whether an instance of SavingAccounts comes after or before another instance of SavingAccount. I don't want to write any spoiler here, but tell me if my hint is not enough ;).
UPDATE
Also, a common source of errors in Python with string ordering : a comes before z which comes before A which comes before Z ...
UPDATE2
more hints ;)
What you really want here is to sort a list of instances of SavingAccount according to a given criteria. There are 2 way to do this kind of thing. You can either :
have the one doing the sorting take care of it
or you can have the instances stored in your list taking care of it.
The second option is usually better because "the class to be sorted" should know better than anybody else how to sort itself (it's about encapsulation : not letting people outside control how your class works). Even though the question is not really clear, and the example is not very good (in my opinion), this is the option they would like you to chose.
The idea is that the Bank should just do something like this :
class Bank(object):
def __str__(self):
"""Return the string rep of the entire bank."""
#get a sorted copy of the list
#using default SavingAccount comparison
pTemp =sorted(self._accounts)
return '\n'.join(map(str, pTemp))
And SavingAccount contains information about how to sort.
You may want to have a look at this article from the PythonInfo Wiki.
Also: http://docs.python.org/reference/datamodel.html#object.__lt__

Categories