Monthly credit card payment calculator shows Syntax Error - python

This program is supposed to calculate the credit card balance after one year if a person only pays the minimum monthly payment required by the credit card company. When I try to run it, it shows a SyntaxError, and I'm not sure why. Here's my code:
def ccb(balance, annualInterestRate, monthlyPaymentRate):
monthlyInterestRate = annualInterestRate / 12.0
month = 0
for calc in range(12):
minMonthlyPaymentRate = balance * monthlyPaymentRate
unpaidBalance = balance - minMonthlyPaymentRate
interest = monthlyInterestRate * unpaidBalance
print ("Month | Balance | Unpaid Balance | Interest")
print (month + " | " + round(balance) + " | " + round(unpaidBalance) + " | " + Interest)
balance = unpaidBalance + Interest
month += 1
print ("Remaining balance: " + round(balance))

A few things (though none appear to throw SyntaxError - seconding Andrew in the comments, if it's a SyntaxError - share the full message):
1) You can't implicitly make an integer a string, you need to cast it. Ex:
str(round(balance))
instead of
round(balance)
2) 'Interest' is never defined, but 'interest' is.
With those fixed, it runs fine.
Also, this might be relevant ;)

Related

How to use a class to print out elements of a list that contains transactions?

I'm trying to write a script that acts as a crypto program that generates a pseudo price of bitcoin, saves the bitcoin into a wallet, and monitors buying/selling transactions done by the script into a ledger, all via a menu. I've already created other classes (Wallet, MyDate, GetLive) that work to store bitcoins, display the live date and time, and generate a random live price for bitcoin per activity (buy/sell/deposit). For the Ledger class, I set up an empty list, trans, that acts as an empty list that will store each transaction done via the append statement, and have the history() function set up so that it prints out each transaction in the trans list. When I try to perform this, all it prints out is just the statement "Transaction History" and not the list of the buy/sell transactions, but when I use the print statement within a for loop to print out the list, things come out twice, which confuses me. I even tried replicating this in the "buy" and "sell" options, and they correctly show how I want the transactions to show up. I think there's something I'm not understanding properly, as I feel the solution is likely simple for this. Does anyone know the best way to go about setting up the Ledger class to properly print out the transaction history?
I have my whole coding displayed below for the crypto program:
from datetime import datetime
import random
balance = 75000 # This provides the user with $75,000 to invest.
num_coins = 0 # This is the amount of BTC the user starts out with.
z = 0 # This initializes the seed value for the random price for bitcoin that is determined by the GetLive() class.
trans = [] # This will be the empty list to which the buy/sell transactions will be added to.
class Wallet: # This class will 1) store the ticker symbol for the bitcoin 2) store how many coins the user has
# 3) prints the information out, including ticker symbol (BTC) for the coin and number of coins currently in wallet,
# and 4) use a setter function to add coins to wallet and a getter function to fetch number of coins in wallet.
symbol = "(BTC)"
def getinfo(self):
print(self.symbol, " : ", self.num_coins)
def set_coins(self, x):
self.num_coins = x
def get_coins(self):
return self.num_coins
class MyDate: # This class returns both the date and time.
def __init__(self):
self.now = datetime.now()
def dmy(self):
self.now = datetime.now()
dt = self.now.strftime("%m/%d/%Y")
print("Date:", dt)
return dt
def hms(self):
self.now = datetime.now()
t = self.now.strftime("%H:%M:%S")
print("Time:", t)
return t
class GetLive: # This class generates a random, live price for Bitcoin.
def price(self): # This method will as a pseudo random price for bitcoin (between 55-65K)
random.seed(z) # This sets the initial random seed that will be used to generate a random price for bitcoin
return random.randint(55000, 65000) # Returns a random live price for bitcoin
class Ledger: # This class defines the Ledger as a class that will store buy/sell transactions and print the history.
def __init__(self):
self.trans = []
def add(self, tran):
self.trans.append(tran)
def multiadd(self, *tranargs):
self.trans.extend(tranargs)
def multiadd2(self, tranargs):
self.trans.extend(tranargs)
def getTrans(self):
return self.trans
def history(self): # This prints the history of the buy and sell transactions, including date & time.
d = MyDate()
print("\nTransaction History\n")
for i in self.trans:
for buy in i:
print("On", d.dmy(), " at ", d.hms(), ", you bought " + str(buy), "" + Wallet.symbol, "for $",
buy_amount)
for sell in i:
print("On", d.dmy(), " at ", d.hms(), ", you sold " + str(sell), "" + Wallet.symbol, "for $",
sell_amount)
# Here, this is where the main section of the Bitcoin program is to be run.
while True:
current_price = GetLive()
L = Ledger()
print("********* Menu ************")
print(" 0 - Price of Bitcoin", Wallet.symbol)
print(" 1 - Buy ")
print(" 2 - Sell ")
print(" 3 - Deposit cash")
print(" 4 - Display # of bitcoins in my wallet")
print(" 5 - Display balance")
print(" 6 - Display transaction history")
print(" 7 - Exit")
i = int(input("Please enter your choice: "))
if i == 0:
print("\nCurrent price of Bitcoin", Wallet.symbol, "= $", current_price.price(), "\n")
elif i == 1:
buy = float(input("\nEnter how much BTC you want to buy: "))
buy_amount = int(current_price.price()) * (float(buy))
print("\nThe total cost for " + str(buy) + " " + Wallet.symbol + " is $", buy_amount, ". Transaction complete."
"\n")
if buy_amount < balance:
d = MyDate()
balance -= float(buy_amount)
num_coins += float(buy)
z = z + 1 # This changes the random seed value so that the GetLive class will generate a new random price
trans.append([d.dmy(), d.hms(), ", you bought", buy, Wallet.symbol, "for $", buy_amount])
print("On", d.dmy(), " at ", d.hms(), ", Bought " + str(buy), "" + Wallet.symbol, "for $", buy_amount)
else:
print("\nError: you have an insufficient balance...\n")
elif i == 2:
sell = float(input("\nEnter how much BTC you want to sell: "))
sell_amount = int(current_price.price()) * (float(sell))
print("\nThe total value for " + str(sell) + " " + Wallet.symbol + " is $", sell_amount, ". Transaction "
"complete.\n")
if num_coins > 0:
d = MyDate()
balance += float(sell_amount)
num_coins -= float(sell)
z = z + 1 # This changes the random seed value so that the GetLive class will generate a new random price
trans.append([d.dmy(), d.hms(), ',', "you sold", sell, Wallet.symbol, "for $", sell_amount])
print("On", d.dmy(), " at ", d.hms(), ", Sold " + str(sell), "" + Wallet.symbol, "for $", sell_amount)
else:
print("\nError: you have insufficient coins...\n")
elif i == 3:
cash = float(input("\nEnter how much cash you want to deposit: $"))
balance = float(balance) + cash
z = z + 1 # This changes the random seed value so that the GetLive class will generate a new random price
print("\nYou deposited $", cash, ". Your new balance is $", balance, "\n")
elif i == 4:
print("\nYou currently have", num_coins, Wallet.symbol, "in your wallet.")
elif i == 5:
print("\nCurrent Balance: $", balance, "\n")
elif i == 6:
for y in trans:
print(" >> ", trans)
# L.history() This is supposed to display the list of buy and sell transactions
elif i == 7:
exit(0)
else:
print("Wrong input")
And this is what comes out as I attempt each option, including the Ledger class in option 6:
********* Menu ************
0 - Price of Bitcoin (BTC)
1 - Buy
2 - Sell
3 - Deposit cash
4 - Display # of bitcoins in my wallet
5 - Display balance
6 - Display transaction history
7 - Exit
Please enter your choice: 0
Current price of Bitcoin (BTC) = $ 61311
********* Menu ************
0 - Price of Bitcoin (BTC)
1 - Buy
2 - Sell
3 - Deposit cash
4 - Display # of bitcoins in my wallet
5 - Display balance
6 - Display transaction history
7 - Exit
Please enter your choice: 1
Enter how much BTC you want to buy: 0.5
The total cost for 0.5 (BTC) is $ 30655.5 . Transaction complete.
Date: 12/19/2021
Time: 22:28:25
Date: 12/19/2021
Time: 22:28:25
On 12/19/2021 at 22:28:25 , Bought 0.5 (BTC) for $ 30655.5
********* Menu ************
0 - Price of Bitcoin (BTC)
1 - Buy
2 - Sell
3 - Deposit cash
4 - Display # of bitcoins in my wallet
5 - Display balance
6 - Display transaction history
7 - Exit
Please enter your choice: 2
Enter how much BTC you want to sell: 0.2
The total value for 0.2 (BTC) is $ 11440.2 . Transaction complete.
Date: 12/19/2021
Time: 22:28:33
Date: 12/19/2021
Time: 22:28:33
On 12/19/2021 at 22:28:33 , Sold 0.2 (BTC) for $ 11440.2
********* Menu ************
0 - Price of Bitcoin (BTC)
1 - Buy
2 - Sell
3 - Deposit cash
4 - Display # of bitcoins in my wallet
5 - Display balance
6 - Display transaction history
7 - Exit
Please enter your choice: 6
>> [['12/19/2021', '22:28:25', ', you bought', 0.5, '(BTC)', 'for $', 30655.5], ['12/19/2021', '22:28:33', ',', 'you sold', 0.2, '(BTC)', 'for $', 11440.2]]
>> [['12/19/2021', '22:28:25', ', you bought', 0.5, '(BTC)', 'for $', 30655.5], ['12/19/2021', '22:28:33', ',', 'you sold', 0.2, '(BTC)', 'for $', 11440.2]]
Transaction History
********* Menu ************
0 - Price of Bitcoin (BTC)
1 - Buy
2 - Sell
3 - Deposit cash
4 - Display # of bitcoins in my wallet
5 - Display balance
6 - Display transaction history
7 - Exit
Please enter your choice: 7
Process finished with exit code 0

calculate mortgage in python?

so i have this program that calculate that calculates the total amount that Dave will have to pay over the life of the mortgage:
# mortgage.py
principal = 500000.0
rate = 0.05
payment = 2684.11
total_paid = 0.0
while principal > 0:
principal = principal * (1+rate/12) - payment
total_paid = total_paid + payment
print('Total paid', total_paid)
and later the exercise ask me Suppose Dave pays an extra $1000/month for the first 12 months of the mortgage?
Modify the program to incorporate this extra payment and have it print the total amount paid along with the number of months required.
what can i modify to make the changes to the program ? I am lost
principal=500000.0
rate= 0.0
payment = 2684.11
total_paid = 0.0
extra_payment = 1000.0
num_periods = 0
while principal > 0:
if num_periods < 12:
principal = principal * (1+rate/12) - (payment+extra_payment)
total_paid += payment + extra_payment
else:
principal = principal * (1+rate/12) - (payment)
total_paid += payment
num_periods += 1
print('Total paid: $', total_paid)
Total paid = 929965.6199999959,
but principal = -1973.205724763917
You have overpayed the final payment
remember to add 'principal' to 'total_paid' to get the actual amount:
927992.414275232
Also, the numbers are not rounded to 2 decimal places
you can round them by using:
def twoDecimalPlaces(answer):
return("%.2f" % answer)
twoDecimalPlaces(927992.414275232)
>>> 927992.41
Here you need to ask again to the user "Do Dave has paid anything extra in principal amount?" if Yes then create new variable for updated principal
update_principal = principal + dave_paid_extra
and then re run the code with same eqaution.

How do I condense my code? (formatting & calculations

sorry I am new to coding so I apologise if this is an amateur question. An exercise has asked that I create code that calculates the 4% interest on an investment for 1,2 and 3 years. I have duplicated a lot of code and would like to know how I could do it differently: in a more condensed way.
For example, is it possible to convert every year in one like such as this float(year1, year2, year3) as appose to having multiple lines of code?
startingBalance = input("Please enter your starting bank balance: ")
startingBalance = int(startingBalance)
year1 = (startingBalance * 1.04)
year2 = (year1 * 1.04)
year3 = (year2 * 1.04)
year1 = "{0:.2f}".format(year1)
year2 = "{0:.2f}".format(year2)
year3 = "{0:.2f}".format(year3)
print("Starting Balance: " + str(startingBalance) + "\n" + "Year 1 Balance: " + year1 + "\n" + "Year 2 Balance: " + year2 + "\n" + "Year 3 Balance: " + year3)
answer=str(input("would you like to withdraw your profits? Y/N: "))
if answer in ['Y', 'y']:
startingBalance = float(startingBalance)
year1 = float(year1)
year2 = float(year2)
year3 = float(year3)
year1Profit = year1 - startingBalance
year1Profit = "{0:.2f}".format(year1Profit)
year2Profit = year2 - startingBalance
year2Profit = "{0:.2f}".format(year2Profit)
year3Profit = year3 - startingBalance
year3Profit = "{0:.2f}".format(year3Profit)
str(year3Profit)
print("Year | Balance | Profit " + "\n" + "Year 1 " + str(year1) + " " + year1Profit + "\n" + "Year 2 " + str(year2) + " " + year2Profit + "\n" + "Year 3 " + str(year3) + " " + year3Profit)
elif answer in ['N', 'n']:
print("Goodbye")
else:
print("Invalid Entry")
Technically this is one line:
year1, year2, year3 = float(year1), float(year2), float(year3)
But I think it would be clearer if you didn't change the type of your variables after initialisation. You can keep them as floats all the time change your print line to:
print("Starting Balance: " + str(startingBalance) + "\n" + "Year 1 Balance: " + "{0:.2f}".format(year1) + "\n" + "Year 2 Balance: " + "{0:.2f}".format(year2) + "\n" + "Year 3 Balance: " + "{0:.2f}".format(year3))
This saves you from converting to string and back again.
This question might be more appropriate in Code Review but:
year1 = "{0:.2f}".format(year1)
Can be replaced by:
year1 = round(year1, 2)
You use .format and print("foo" + bar) in the same code I recommend using one type:
F-strings if Python3.6 or above
print(f"Starting Balance: {startingBalance}\nYear 1 Balance: {year1}\nYear 2 Balance: {year2}\nYear 3 Balance: {year3}")
.format if Python2 or 3 < 3.6
print("Starting Balance: {}\nYear 1 Balance: {}\nYear 2 Balance: {}\nYear 3 Balance: {}".format(startingBalance, year1, year2, year3))
No need to put str() here :
answer=str(input("would you like to withdraw your profits? Y/N: "))
The input() always returns a string.
Use "\t" when you want (i'm guessing) tabulations instead of a bunch of spaces (ugly):
print("Year | Balance | Profit " + "\n" + "Year 1 " + str(year1) + " " + year1Profit + "\n" + "Year 2 " + str(year2) + " " + year2Profit + "\n" + "Year 3 " + str(year3) + " " + year3Profit)
Same thing here use f-strings or .format to format your string.
To avoid writing the same code, you can create a function to compute the final balance and the profit. Then you can use the others answers to know how to format your variable and return them
def compute_year(starting_balance, number_of_year):
return (startingBalance * 1.04 ** number_of_year, startingBalance * 1.04 ** number_of_year - startingBalance)
year1, year1Profit = compute_year(startingBalance, 1)
year2, year2Profit = compute_year(startingBalance, 2)
year3, year3Profit = compute_year(startingBalance, 3)
Yes, it is very much possible!
When you find yourself writing repeating lines of code, try using functions!
In that way you only have to define an expression once!
example:
year1 = (startingBalance * 1.04)
year2 = (year1 * 1.04)
year3 = (year2 * 1.04)
Can be change to
def interest(balance):
return balance * 1.04
year1 = interest(startingBalance)
year2 = interest(year1)
But this still seems repetitive, right?
Now try using a for-loop aswell:
current_balance = startingBalance
for year in range(4):
current_balance = interest(current_balance)
print(current_balance)
Now in each loop, you can print the value of the new balance!
Finally add in the line printg for a pretty output, and you could get something like this:
def interest(balance, years):
return balance * (1.04 ** years)
def print_gains(balance, year):
header = 'Year | Balance | Profit '
print(header)
print('-' * len(header))
for year in range(1 + year):
new_balance = interest(balance, year)
print('%5d| %10.2f | %10.2f' % (year, new_balance, new_balance - balance))
print()
def main():
print_gains(10000, 5)
main()
resulting in the following output:
Year | Balance | Profit
-----------------------------
0| 10000.00 | 0.00
1| 10400.00 | 400.00
2| 10816.00 | 816.00
3| 11248.64 | 1248.64
4| 11698.59 | 1698.59
5| 12166.53 | 2166.53
I hope this helps you!

MIT opencourseware - stuck on a basic issue, credit card minimum payment over a year calculation

Basically I'm pretty stuck on this issue, I've linked the question below, it's part 'b' I'm stuck on, or the second question in the document:
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00sc-introduction-to-computer-science-and-programming-spring-2011/unit-1/lecture-4-machine-interpretation-of-a-program/MIT6_00SCS11_ps1.pdf
If I'm honest it's just got to the point where I'm totally confused! I've put my code below:
balance = float(raw_input('Vot is the outstanding balance? '))
InrAn = float(raw_input('Vot is the annual interest rate as a decimal? '))
month = 1
monthPay = 10
monthInr = InrAn/12.0
newBalance = balance
while balance > 0:
newBalance = newBalance * (1 + monthInr) - monthPay
month +=1
if month > 12:
month = 1
newBalance = balance
monthPay += 10
This does essentially nothing, I know, and it's not yet complete. If I add a 'print month' statement it just seems to show that the code just goes up to 12, then starts at 1 again. Any tips/prods in the right direction?
monthly_payment = 10.0
while True:
current_balance = start_balance
for month in range(1, 13):
current_balance = current_balance * (1. + monthly_rate) - monthly_payment
current_balance = round(current_balance, 2)
if current_balance <= 0.0:
break
if current_balance <= 0.0:
print("RESULT")
print("Monthly payment to pay off debt in 1 year: {}".format(int(monthly_payment)))
print("Number of months needed: {}".format(month))
print("Balance: {:0.2f}".format(current_balance))
break
monthly_payment += 10.0

Not getting right output...logic correct

My code is giving right results except for balance=3926. Lowest Payment: 370 whereas it should be 360.The program should print lowest monthly payment for given annual interest rate .Given an initial balance, code should compute the balance at the end of the year. we are trying our initial balance with a monthly payment of $10. If there is a balance remaining at the end of the year, we write code that would reset the balance to the initial balance, increase the payment by $10, and try again (using the same code!) to compute the balance at the end of the year, to see if this new payment value is large enough
annualInterestRate = 0.2
balance = 3926
monthlyinterestrate = annualInterestRate/12.0
remainingBalance = balance
month = 1
total = 0
payment = 10
def CheckMinimumPayment(payment,balance):
"Checking if payment is in correct balance"
while(payment*12 < balance):
payment += 10
return payment
payment = CheckMinimumPayment(payment,balance)
while(month <= 12):
remainingBalance = remainingBalance - payment + (annualInterestRate / 12.0) * (remainingBalance - payment)
month += 1
total += payment
payment = CheckMinimumPayment(payment,total+remainingBalance)
print("Lowest Payment: " + str(payment))
The problem is that you're not re-iterating through the interest loop (what you have as while(month <= 12)) each time you try a new payment. Write that loop into a function, and call it each time you try a new payment. The total owed balance depends on the payment, since a larger payment each month means less interest added each month. Here's what I used:
annualInterestRate = 0.2
init_balance = 3926
monthlyInterestRate = annualInterestRate/12.0
init_payment = 10
def owedBalance(payment,balance):
""" Calculate total owed balance after one year
given an initial balance and montly payment"""
for month in range(12):
balance = (balance - payment) * (monthlyInterestRate + 1)
return payment*12 + balance
def CheckMinimumPayment(payment,balance):
"Checking if payment is in correct balance"
while (payment*12 < owedBalance(payment, balance)):
payment += 10
return payment
min_payment = CheckMinimumPayment(init_payment,init_balance)
print("Lowest Payment: {}".format(min_payment))

Categories

Resources