Error checking inside a class - python

I'm supposed to create an Account class which uses some of the functions defined in the class above it. I'm having trouble with error checking in my withdraw class.
def withdraw(self, amount):
if amount > self.money:
return 'Error'
self.money -= amount
>>> a = Money(5,5)
>>> b = Money(10,1)
>>> acct1 = Account('Andrew', a)
>>> print(acct1)
Andrew's account balance is $5.05
>>> c = Money(3,50)
>>> acct1.deposit(c)
>>> print(acct1)
Andrew's account balance is $8.55
>>> acct1.withdraw(b)
>>> print(acct1)
Andrew's account balance is $-2.54
The output should be Error, but instead it just calculates and gives me back a negative balance.
The entire code is here:
class Money:
def __init__(self, dollars = 0, cents = 00):
'constructor'
self.dollars = dollars
self.cents = cents
if self.cents > 99:
self.dollars += 1
self.cents = self.cents - 100
def __repr__(self):
'standard representation'
return 'Money({}, {})'.format(self.dollars,self.cents)
def __str__(self):
'returns a string representation of ($dollars.cents)'
if self.cents < 10:
return '${}.0{}'.format(self.dollars, self.cents)
else:
return '${}.{}'.format(self.dollars, self.cents)
def __add__(self, new):
'Adds two money objects together'
d = self.dollars + new.dollars
c = self.cents + new.cents
return Money(d,c)
def __sub__(self, new):
'Subtracts two money objects'
d = self.dollars - new.dollars
c = self.cents - new.cents
return Money(d,c)
def __gt__(self, new):
'computes greater then calculations'
a = self.dollars + self.cents
b = new.dollars + new.cents
return a > b
class Account:
def __init__(self, holder, money = Money(0,0)):
'constructor'
self.holder = holder
self.money = money
def __str__(self):
return "{}'s account balance is {}".format(self.holder, self.money)
def getBalance(self):
return self.money
def deposit(self, amount):
self.money = self.money + amount
def withdraw(self, amount):
if amount > self.money:
return 'Error'
self.money -= amount

Actually it is because you don't compute the "balance" inside your __gt__ correctly.
The dollars should be multiplied by 100:
def __gt__(self, new):
a = self.dollars * 100 + self.cents
b = new.dollars * 100 + new.cents
return a > b
Optional: Instead of returning 'Error' you should consider raising an Exception:
def withdraw(self, amount):
if amount > self.money:
raise ValueError('Not enough money')
self.money -= amount

Related

Why do I cannot use __repr__ data outside of a class

I started Python and struggle on using __repr__ data outside of a class. Printing the data outputs a list with lists (exactly what I wanted to do), example:
print(test) leads to:
[['Food', '-10.15', '-15.89', '-50'], ['Clothing', '-25.55'], ['Auto', '-15']]
My problem is:
print(test[0]) leads to unexpected outputs, not:
['Food', '-10.15', '-15.89', '-50']
rather than some data like:
*************Food*************
initial deposit 1000.00
groceries -10.15
restaurant and more foo -15.89
Transfer to Clothing -50.00
Total: 923.96
***********Clothing***********
Transfer from Food 50.00
-25.55
Total: 24.45
*************Food*************
initial deposit 1000.00
groceries -10.15
restaurant and more foo -15.89
Transfer to Clothing -50.00
Total: 923.96
None
.***********Business***********
deposit 900.00
-10.99
class Category:
def __init__(self, category):
self.category = category
self.balance = 0
self.ledger = []
def __repr__(self):
b = []
b.append(self.category)
for obj in self.ledger:
if str(obj['amount'])[0] == "-":
b.append(str(obj['amount']))
return str(b)
def __str__(self):
lengthTop = int((30 - len(str(self.category))) / 2)
output = "*" * lengthTop + self.category + "*" * lengthTop
for entry in self.ledger:
if len(entry['description']) > 23:
x = slice(0, 23)
output += "\n" + entry['description'][x] + ("{:7.2f}".format(entry['amount']))
else:
output += ("\n" + entry['description'] + (" " * (23 - int(len(entry['description'])))) + ("{:7.2f}".format(entry['amount'])))
output += "\n" + "Total:" + ("{:7.2f}".format(self.balance))
return output
def check_funds(self, amount):
if amount > self.balance:
return False
else:
return True
def deposit(self, amount, description=""):
self.balance += amount
self.ledger.append({"amount": amount, "description": description})
def withdraw(self, amount, description=""):
if self.check_funds(amount) == True:
self.balance -= amount
self.ledger.append({"amount": -amount, "description": description})
return True
else:
return False
def get_balance(self):
return self.balance
def transfer(self, amount, newcategory):
if self.check_funds(amount) == True:
self.withdraw(amount, "Transfer to " + newcategory.category)
newcategory.deposit(amount, "Transfer from " + self.category)
return True
else:
return False
def create_spend_chart(categories):
test = categories
print(test)

How to update values within class

I'm trying to write a class separate from the main class and I want it to keep track of balance and number of items I buy coming from the main class. However, I'm having trouble updating the Num and balance every time I make a transaction and it keeps giving me 0 and 2000 when I print balance and num.
class Wallet:
def __init__(self, Num = 0, balance = 2000):
self.Num = Num
self.balance = balance
def addNum(self, c, d):
if d > self.balance:
return print(f'You have insufficient balance to buy {c}')
else:
self.balance -= d
self.Num += c
return Wallet().print()
def print(self):
print(f'You have {self.Num} of {self.balance}')
Wallet().addNum(3, 30)
Replace Wallet().print() with self.print(), otherwise you are creating a brand new Wallet every time you try to print it.

Trying to create a checking account class but running into issues

Write a class named “CheckingAccount” that contains the current
balance of the account (an int) and the following methods:
init - takes a “balance” parameter to initialize the data (balance)of the object. Remember, the method init is implemented as
___init__.
withdraw - takes an input parameter “amount” and modifies the data by reducing the balance. If “amount” results in an overdraw,subtract
an extra 20 dollars. This method should return the balance.
deposit - takes an input parameter “amount” and modifies the data by increasing the balance by “amount”.
I'm trying to do the above problem but I'm kind of lost and this is the best I've got so far (updated code today):
# write your code here
class CheckingAccount:
balance = 0
amount = 0
def __init__(self, balance = 0):
self.balance = balance
def withdraw(self, amount = 0):
if self.amount > self.balance:
self.balance -= 20
else:
self.balance -= 1
def deposit(self, amount = 0):
self.amount += amount
return amount
an = CheckingAccount(80)
an.withdraw(40)
print("Your old balance was {}. Your new balance is now {}.".format(an.balance))
I'm getting closer but my old balance shows as 79 instead of 80 and my new balance shows as 0 when I think I was expecting 40. I feel like I'm missing something.
class CheckingAccount:
balance = 0
oldbalance = 0
#amount = 0
def __init__(self, balance = 0):
self.balance = balance
def withdraw(self, amount = 0):
self.oldbalance = self.balance
if amount < self.balance:
self.balance -= amount
print("Amount withdrawn {}".format(amount))
else:
self.balance -= amount + 20
print("Amount withdraw ${} with penalty of $20".format(amount))
def deposit(self, amount = 0):
self.oldbalance = self.balance
self.balance += amount
return amount
an = CheckingAccount(80)
an.withdraw(10)
print("Your old balance was {}. Your new balance is now {}.".format(an.oldbalance, an.balance))

Python 2.7 code does not give correct answer

For some reason it seems like the code doesn't deduct from the right object and only adds to the receiver in my code, how can I fix this so the receiver gets the right amount added to his balance
class BankAccount:
def __init__(self, balance):
self.balance = balance
self.tamout = 0
def withdraw(self, amount):
self.balance -= amount
return self.balance
def deposit(self, amount):
self.balance += amount
return self.balance
def transfer(self, name, c):
self.balance -= c
name += c
return name
David = BankAccount(400)
John = BankAccount(200)
print "David balance is", David.balance
print "john balance is", John.balance
John.transfer(David.balance, 20)
print John.balance
print David.balance
The result is
David balance is 400
john balance is 200
180
400
Shouldn't the last print be 420?
This should fix your issue
class BankAccount:
def __init__(self, balance):
self.balance = balance
self.tamout = 0
def withdraw(self, amount):
self.balance -= amount
return self.balance
def deposit(self, amount):
self.balance += amount
return self.balance
def transfer(self, receiver, c):
self.balance -= c
receiver.deposit(c)
return receiver
if __name__ == '__main__':
David = BankAccount(400)
John = BankAccount(200)
print "David balance is", David.balance
print "john balance is", John.balance
John.transfer(David, 20)
print John.balance
print David.balance
By using David instance and use the deposit method on it
Your current transfer function receives a copy of the receiver's balance, not the original property.
Try this instead:
def transfer(self, name, c):
self.balance -= c
name.balance += c
return name
John.transfer(David, 20)

Class not printing entire variable

I am failry new to coding so I've been trying to figure out how to get the entire output variable to print to the terminal. Right now the first 5 methods print when I print self.output with an instance of Change maker as gregs_vending_machine.
Notes: The round method is going to cause my numbers to get thrown off when I get to the pennies so my plan is to multiply change due by 100 and go from there.
Once I solve the way above I will refactor to solve with one method utilizing a global class dictionary for my values.
Code is Below:
class ChangeMaker:
def __init__(self, total_price, amount_paid):
self.total_price = total_price
self.amount_paid = amount_paid
self.change_due= self.change(self.total_price,self.amount_paid)
self.output = (f'For an item that costs ${self.total_price} with an amount paid of ${self.amount_paid} your change due is ${self.change_due}. Given in{self.hundreds_sentence_generator()}{self.fifties_sentence_generator()}{self.twenties_sentence_generator()}{self.tens_sentence_generator()}{self.fives_sentence_generator()}{self.dollars_sentence_generator()}\n{self.quarters_sentence_generator()}{self.dimes_sentence_generator()}{self.nickels_sentence_generator()}{self.pennies_sentence_generator()}')
self.change_output = (f'{self.quarters_sentence_generator()}{self.dimes_sentence_generator()}{self.nickels_sentence_generator()}{self.pennies_sentence_generator()}') def change(self, total_price, amount_paid):
return round(int(amount_paid) - int(total_price),2)
def hundreds_sentence_generator(self):
hundreds_due= self.change_due//round(100.00,2)
self.change_due -= round(100.00,2) * hundreds_due
if hundreds_due == 1:
return f' {int(hundreds_due)}: $100 Bill, '
elif hundreds_due > 1:
return f' {int(hundreds_due)}: $100 Bills, '
else:
return ""
def fifties_sentence_generator(self):
fifties_due= self.change_due//round(50.00,2)
self.change_due -= round(50.00,2) * fifties_due
if fifties_due == 1:
return f'{int(fifties_due)}: $50 Bill, '
elif fifties_due > 1:
return f'{int(fifties_due)}: $50 Bills, '
else:
return ""
def twenties_sentence_generator(self):
twenties_due= self.change_due//round(20.00,2)
self.change_due -= round(20.00,2) * twenties_due
if twenties_due == 1:
return f'{int(twenties_due)}: $20 Bill, '
elif twenties_due > 1:
return f'{int(twenties_due)}: $20 Bills, '
else:
return ""
def tens_sentence_generator(self):
tens_due= self.change_due//round(10.00,2)
self.change_due -= round(10.00,2) * tens_due
if tens_due == 1:
return f'{int(tens_due)}: $10 Bill, '
elif tens_due > 1:
return f'{int(tens_due)}: $10 Bills, '
else:
return ""
def fives_sentence_generator(self):
fives_due= self.change_due//round(5.00,2)
self.change_due -= round(5.00,2) * fives_due
if fives_due == 1:
return f'{int(fives_due)}: $5 Bill, '
else:
return ""
def dollars_sentence_generator(self):
dollars_due= self.change_due//round(1.00,2)
self.change_due -= round(1.00,2) * dollars_due
if dollars_due == 1:
return f'{int(dollars_due)}: $1 Bill, '
elif dollars_due > 1:
return f'{int(dollars_due)}: dollars, '
else:
return ""
def quarters_sentence_generator(self):
quarters_due= self.change_due//round(0.25,2)
self.change_due -= round(0.25,2) * quarters_due
if quarters_due == 1:
return f'{int(quarters_due)}: Quarter, '
elif quarters_due > 1:
return f'{int(quarters_due)}: Quarters, '
else:
return ""
def dimes_sentence_generator(self):
dimes_due= self.change_due//round(0.10,2)
self.change_due -= round(0.10,2) * dimes_due
if dimes_due == 1:
return f'{int(dimes_due)}: Dime, '
elif dimes_due > 1:
return f'{int(dimes_due)}: Dimes, '
else:
return ""
def nickels_sentence_generator(self):
nickels_due= self.change_due//round(0.05,4)
self.change_due -= round(0.05,2) * nickels_due
if nickels_due == 1:
return f'{int(nickels_due)}: Nickel, '
else:
return ""
def pennies_sentence_generator(self):
if self.change_due == round(0.01,2):
return f'1: Penny, '
elif self.change_due > round(0.01,2):
return f'{int(self.change_due*100)}: Pennies, '
else:
return ""
gregs_vending_machine = ChangeMaker(1.01, 190.88)
print(gregs_vending_machine.output)''
I believe your issue may be that you are casting amount_paid and total_price as integers. This will cause decimals to be truncated. If I change your change method to the following, I seem to get correct results.
def change(self, total_price, amount_paid):
return round(amount_paid - total_price, 2)
Your self.change() method is using int, so your change_due will never include any coins. So just change your self.change() to:
def change(self, total_price, amount_paid):
return amount_paid - total_price
and I think it will all work.

Categories