Function to transfer values in dictionary Python - python

I am new to Python and trying to make a function for an assignment that will transfer money from a checking to a savings account,. We were given this initial code:
class portfolio:
def __init__(self):
self.checking = {}
self.saving = {}
self.credit = {}
self.stock = {}
And then the start of this code to make the function to transfer the money:
def invest_in_savings_account(self, account_id_savings, amount, account_id_checking):
I've tried numerous code, but none will pass the test cases. Can someone explain to me why this won't work?
def invest_in_savings_account(self, account_id_savings, amount, account_id_checking):
try:
self.checking[account_id_checking] -= amount
self.saving[account_id_savings] += amount
except:
return None
If the account id doesn't exist or if there are no funds in the checking account, the function is to do nothing.
Any suggestions would be greatly appreciated! I've worked on this all day and haven't been able to solve it.
This is the test case it must pass:
myportfolio.invest_in_savings_account('discover_saving_3785', 1000, 'discover_7732')
if (myportfolio.saving == {'chase_saving_4444': 0, 'discover_saving_3785':1000}) and (myportfolio.checking == {'chase_6688': 100, 'discover_7732':5500}):
print('Pass')
else:
print('Fail')

There are a few things going on here, most simple first, always start a class with a capital letter, it isn't necessary but it's good practice:
def class Portfolio:
After reading your comments it appears you need this to work without money in the accounts. You can write the code but you won't be able to test it, so really you need to make functions to create accounts and to add / remove money. If you haven't created any accounts your dictionaries will always come back empty. If you don't put money into them then the function will never do anything, I'm confused as to how you would go about moving something that doesn't exist.
Try something like this:
def create_checking_account(self,account_id):
self.checking[account_id] = None
def add_funds_checking(self,account_id,amount):
self.checking[account_id] += amount
def invest_in_savings(self, account_id_savings, amount, account_id_checking):
if self.checking[account_id_checking] >= amount:
self.checking[account_id_checking] -= amount
self.savings[account_id_savings] += amount
else:
print('error')

Related

How to change variable value from another class?

So I am working on a project which basically is to program a Monopoly. I want to be able for a player to pay X amount to the bank and have the bank properly receive and add that amount to its own. I am working the player on a Tkinter interface in a different class to the bank. I have done the following:
In Class Card1, import the Bank class from bank.py
Program a function pay_bank() where I get the amount entered in the Entry field and discount it from the player's available money and send it to bank.
-Create a function receive_payment() in the Bank class where it receives the player's money and adds it to its own.
For some reason, it is not working so I need your help. Code below:
Class Card1:
def __init__(self):
self.amount = 1500
self.properties = {}
#nested functions to handle interface and it's events
def manage_player1_card(self):
def pay_bank():
to_bank = int(payBox.get())
if self.amount > to_bank:
payBox.delete(0, END)
self.amount -= to_bank
Bank().receive_payment(to_bank)
class Bank:
def __init__(self):
self.bank_total = 14580
def receive_payment(self, pay):
self.bank_total += pay
*Indentation might look wrong due to copy-pasting but it is just fine in my code. What do you see I am doing wrong?
Basically, the self.bank_total amount is not adding up every time I enter the amount. For example: if I enter 500, it should go up to 15180, but it stays the same at 14580. I have debugged but it doesn't change. How can I fix this? Thanks!
Try something like this:
def pay_bank(bank: Bank):
...
bank.receive_payment(to bank)
That way you are passing the bank as a parameter.

How to sum a list of sets? with strings and integers in a class?

I'm new to programming with python and I'm working on the python 4 everybody course. For that I need to build a budget app. In specific, this is the first two tasks:
Complete the Category class in budget.py. It should be able to instantiate objects based on different budget categories like food, clothing, and entertainment. When objects are created, they are passed in the name of the category. The class should have an instance variable called ledger that is a list. The class should also contain the following methods:
A deposit method that accepts an amount and description. If no description is given, it should default to an empty string. The method should append an object to the ledger list in the form of {"amount": amount, "description": description}.
A withdraw method that is similar to the deposit method, but the amount passed in should be stored in the ledger as a negative number. If there are not enough funds, nothing should be added to the ledger. This method should return True if the withdrawal took place, and False otherwise.
My attempt for now is the following:
class Category:
def __init__(self):
self.ledger = []
Total = 0
def deposit(self, amount, *description):
self.ledger.append({"amount": amount, "description": description})
return self.ledger
def withdraw(self, withdrawal):
for x in self.ledger:
if x == int():
return sum
self.ledger.append({"withdrawal": withdrawal})
return self.ledger
I think I have multiple questions:
What is a list with {} as one Item? Is it a 5.4. "Set"?
How can I now implement the requirement of the withdraw method "If there are not enough funds, nothing should be added to the ledger." I think I need to sum up all the integers of the list self.ledger, but idk how to grab those from it and sum it up. I tried as you can see a for loop, but I think that is incorrect syntax?
I really appreciate every help and am grateful for also some background knowledge!
Thanks in advance!
Lukas
{} is en empty dict. An empty set is set()
This should do for the withdraw function :
def withdraw(self, amount, description):
balance = sum(transaction["amount"] for transaction in self.ledger)
if balance >= withdrawal :
self.ledger.append({"amount": -amount, "description": description})
return True
else :
return False
return self.ledger
This use a generator as an argument for the builtin sum function. This may be a bit advanced if you are just starting python so you can also compute the balance with more beginner friendly code :
balance = 0
for transaction in ledger:
balance = balance + transaction["amount"]
# you can shorten the line above to
# balance += transaction["amount"]
This is roughly equivalent to what the sum and the generator syntax do.
Out of curiosity, is the * in front of description argument in your deposit function a typo ?
So, some things for clarification.
self.ledger = []: The [] makes the ledger a list, and the self. part makes it an instance variable, only applicable to a specific instance of the class Category
As stated in the comments, {"key": "value"} is a dict object. Using self.ledger.append({"key": "value"}) adds the dict object {"key": "value"} to the ledger list.
Normally if you want to keep track of a number inside a class, you create an instance variable and update it when it gets changed. See the usage of self.total below.
Recalculating the total can also be done, see the method update_total() below.
I added some testing below.
class Category:
def __init__(self):
self.ledger = []
# total also needs the "self." to make it an instance variable, just
# as the ledger above
# if you omit the "self."" it's a localized variable only available
# to the __init__ method itself.
self.total = 0
def deposit(self, amount, *description):
self.ledger.append({"amount": amount, "description": description})
# add the amount to the total
self.total += amount
return self.ledger
def withdraw(self, withdrawal):
# make the withdrawal negative
if abs(withdrawal) == withdrawal:
withdrawal = 0 - withdrawal
# check if there's enough in the total
if abs(withdrawal) <= self.total:
# update the total
self.total += withdrawal
# add to the ledger
self.ledger.append({"withdrawal": withdrawal})
else:
# you could return an error message here
pass
return self.ledger
def update_total(self):
total = 0
for item in self.ledger:
# need to check if the amount key is in the dict object
if "amount" in item:
total += item["amount"]
# this check below is not needed but it ensures future compatability
elif "withdrawal" in item:
total += item["withdrawal"]
# just because, you can check if the totals match
if self.total != total:
print(
f"""Difference in totals found. Someone is cheating :-|
Instance total: {self.total}
Calculated total: {total}"""
)
# set the instance variable to the local variable
self.total = total
return self.total
from pprint import pprint
nr1 = Category()
nr2 = Category()
for i in range(10):
nr1.deposit(i, f"deposit - {i}")
pprint(nr1.ledger)
print(f"Total: {nr1.total}")
nr1.withdraw(10)
print(f"Total: {nr1.total}")
nr1.withdraw(-10)
print(f"Total: {nr1.total}")
nr1.withdraw(99999)
print(f"Total: {nr1.total}")
pprint(nr1.ledger)
print(nr1.update_total())
nr1.total = 123
print(nr1.update_total())
# just to show that the above only updated the values inside the nr1 instance.
print(f"Total for nr2: {nr2.total}")

Menu for a turn based game

Our teacher has assigned us an assignment for doing a turned based game.
This only included name.strip() but this does not prompt player to input unique name:
def start():
print("\nNew game started...Setting up Player 1's team...\n")
for total_characters in range (1,4):
name = input('Enter a unique name for unit #'+str(total_characters)+'==> ')
if not name.strip():
print('Cant be blank name,please provide a unique name')
return start()
else:
role_selection()
def role_selection():
for total_characters in range (1):
role = input('Select unit #'+str(total_characters)+' type: (W)arrior, (T)anker, or Wi(Z)ard ==> ')
total_characters+=1
if role.upper() == 'W':
pass
elif role.upper() == 'T':
pass
elif role.upper() == 'Z':
pass
else:
print("I don't understand what are you typing.")
return role_selection()
There are things that doesn't make sense :
You have the exact same function twice :
def set_up(team_size)
def set_up(name)
You are doing :
for total_units in range(team_size):
[...]
invalid = True
[...]
while invalid: # Infinite loop
set_up() # What's this function ?
As you can see from the comments in the code above, you never set invalid to False, leading to the infinite loop.
Note: My recommendation is that you should check out some tutorial on python before moving on coding a complex project, because your homework is not that easy.
Edit :
From the new code you've posted, you could do something like this :
def new_game():
names = []
for unit_id in range(1,4):
print(f'Enter a unique name for unit #{unit_id} ->')
empty = True
while empty:
name = input('>')
if name == "":
continue
empty = False
if name in names:
print('Unit name must be unique.')
else:
print('Name looks good!')
names.append(name)
python menu
At first glance, this stood out to me:
if not name.strip():
print('Unit name could not be blank.')
invalid = True
Remember in python the indentation matters. You are setting invalid to True regardless of the if condition. Further down you have a while loop that checks it.
The other if conditions have invalid=True inside the condition. Plus you don't have invalid=False anywhere as far as I see, so you'll get an error if you don't declare it somewhere so it's always on the path before the while.
this doesn't seem like a specific problem, more an ask for general guidance for going about this kind of problem?
One thing to note is that your above script only uses functions (which store behaviour) whilst really for something like the turn based game, you need to store behaviour (attacks etc) and information (how much health is left etc).
I won't write the script for you, but here's an example of how you might define an rpg like entity, capable of attacking, being attacked by another entity etc:
class Entity:
"""Abstract class for any combat creature"""
def __init__(self, name, health):
self.name = name
self.health = health
self.is_alive = True
def attack(self, other):
dmg = random.randint(7, 12)
other.be_attacked(dmg)
def be_attacked(self, dmg):
self.health = self.health - dmg
if self.health <= 0:
self.die()
def die(self):
self.is_alive = False
def check_life(self):
return self.is_alive
You can then initialise a bunch of these to make up the 'team' you where talking about:
one_person = Entity('Lee', 34)
another_person = Entity('Someone Else', 21)
etc. Hope that helps a bit. Good luck with your project and have fun!

How to create and access dynamic variable names a template function?

I wound up having three extremely similar functions in my code, which were to take separate user inputs for their birth year, month, and day. I want to use the best practices I can even though the code is extremely basic, which is why it's a bit overkill. So right now I have a function that acts as a template and takes three args dateType, typeStr, and typeFormat. I'm trying to use these args to name variables in the three functions that I'll create using the template so that I can later print out the birth date of the person. I'm aware of scope, but I've tried making things global etc etc and it hasn't worked. I don't know if I'm even creating variables that are persistent or if it all gets unassigned once the function is done, and if I am creating variables I can't figure out what they're called as I've tried every possibility.
def makeTemplateInput(dateType, typeStr, typeFormat):
def templateInput(dateType, typeStr, typeFormat):
print('You\'re using the template function. Please input your birth {} in the format {}.\n$ '.format(dateType, typeFormat), end='')
while True:
try:
dateType = input()
typeStr = dateType
dateType = int(dateType)
if dateType > 0:
if len(typeStr) != len(typeFormat) and isinstance(dateType, int):
print('Your input doesn\'t have {} digits, please use the format {}.\n$ '.format(str(len(typeFormat)), typeFormat), end='')
print('strlen: ' + str(len(typeStr)))
continue
break
else:
print('Your input is not a positive integer!\n$ ', end='')
continue
except ValueError:
print('Your input is not a valid number, please use the format {} where {} is an integer.\n$ '.format(typeFormat, str(typeFormat[:1])), end='')
print(dateType)
def yearInput1():
makeTemplateInput('year', 'yearStr', 'YYYY')
yearInput1()
print('Your birthdate is: {}/{}/{}'.format(yearInput1.year, monthInput.monthStr, dayInput.dayStr))
I'm sure it's a mess that misunderstands fundamental things about Python, but I really don't understand what's gone wrong.
A few online classes or some good books can help with some of this confusion. I've created some sample code to hopefully answer your question. Thank you.
class Calendar:
def __init__(self, day, month, year): #This can be initialised with the day/month/year
self.day = day
self.month = month
self.year = year
def displayDate(self): #This will display the dates from the object created/set
print('day:{} month:{} year:{}'.format(self.day, self.month, self.year))
def setNewDate(self, otherDay, otherMonth, otherYear): #this sets the class attributes to something else
print('This was the old values day:{} month:{} year:{}'.format(self.day, self.month, self.year))
self.day = otherDay
self.month = otherMonth
self.year = otherYear
print('The new values are day:{} month:{} year:{}'.format(self.day, self.month, self.year))
cal = Calendar(6,11,2020)
cal.displayDate()
cal.setNewDate(3,4,2099)

Python elevator simulation problem

I have a homework assignment that's really baking my noodle. It involves an elevator simulation that takes user inputs for the number of floors and the number of people using the elevator. the people's starting floor and destination floors are random numbers within the floors.
I realize that my code is very sparse and that there's quite a few gaps, but I really don't know where to go from here.
I need help within the building class, such as how to make the run() and output() sections work. any other tips would be greatly appreciated and helpful. Note that i am not looking for someone to do the code for me, but to kind of hold my hand and tell me which way to go. Classes seem to be completely mystifying to me.
import random
floors=raw_input('Please enter the number of floors for the simulation:')
while floors.isalpha() or floors.isspace() or int(floors) <=0:
floors=raw_input('Please re enter a digit for number of floors:')
customers=raw_input('Please enter the number of customers in the building:')
while customers.isalpha() or customers.isspace() or int(customers) <0:
customers=raw_input('Please re enter a digit for number of customers:')
count = 1
class building:
def num_of_floors():
num_of_floors = floors
def customer_list():
customer_list = customers
def run(self):
def output(self):
print elevator.cur_floor
class elevator:
def num_of_floors():
building.num_of_floors
def register_list():
register_list = []
def cur_floor(building):
cur_floor = 1
def direction(self):
if elevator.cur_floor == 1:
direction = up
if elevator.cur_floor == floors:
direction = down
def move(self):
if elevator.direction == up:
cur_floor +=1
if elevator.direction == down:
cur_floor -=1
def register_customer(self, customer):
register_list.append(customer.ID)
def cancel_customer (self, customer):
register_list.remove(customer.ID)
class customer:
def cur_floor(customer):
cur_floor = random.randint(0,int(floors))
def dst_floor(customer):
dst_floor = random.randint(0,int(floors))
while dst_floor == cur_floor:
dst_floor = random.randint(0,int(floors))
def ID():
cust_id = count
count+=1
def cust_dict(cust_id,dst_floor):
cust_dict = {cust_id:dst_floor}
def in_elevator():
in_elevator = 0
if customer.ID in register_list:
in_elevator = 1
def finished():
if customer.ID not in register_list:
pass
You need to understand the self
parameter to all methods.
You need to understand __init__,
the constructor.
You need to understand self.varible
for your member variables.
You need to understand how to setup a
main function.
You need to understand how to
return a value from a function or
method.
You need to understand how to assign to global variables from within a function or method.
Maybe your building class should start like this.
class building:
def __init__(self, floors, customers):
self.num_of_floors = floors
self.customer_list = customers
self.elevator = elevator()
You should definately spend some time on Python Tutorial or Dive into Python.
The first parameter of every method is a reference to the object and is usually called self. You need it to reference instancemembers of an object.
Second, referencing global variables from inside a class is considered a bad idea. You can better pass them to a class via the constructor or parameters.

Categories