Defining lists and calling functions in Python - python

I am using Python 3. This is for a homework project for a class, but I'm not looking for something to do the problem for me! I was just wondering if someone could help point out exactly where I've gone wrong, or what I need to look into to make my code work.
def main():
taxPayersList = []
incomesList = []
taxesList = []
taxPayersList, incomesList = inputNamesAndIncomes(taxPayersList, incomesList)
taxesList = calculateTaxes(incomesList)
displayTaxReport(taxesList, incomesList, taxPayersList)
def inputNamesAndIncomes(taxPayersList, incomesList):
print('Welcome to Xanadu Tax Computation Program')
print('')
confirmation = input('Do you have income amounts? y/n ')
index = 0
try:
while confirmation == 'y' or confirmation == 'Y':
taxPayersList[index] = input('Enter a tax payer name: ')
incomesList[index] = float(input('Enter income amount: '))
confirmation = input('Are there more income amounts? ')
index += 1
except:
print('An error occurred. Please only enter numbers for income amount.')
return taxPayersList, incomesList
def calculateTaxes(incomesList):
index = len(incomesList)
while index < len(incomesList):
if incomesList[index] >= 0 and incomesList[index] <= 50000:
taxesList[index] = incomesList[index] * .05
elif incomesList[index] >= 50000 and incomesList[index] <= 100000:
taxesList[index] = 2500 + ((incomesList[index] - 50000) * .07)
elif incomesList[index] >= 100000:
taxesList[index] = 6000 + ((incomesList[index] - 100000) * .09)
index += 1
return incomesList
def displayTaxReport(taxesList, incomesList, taxPayersList):
print('2018 TAX DUES FOR XANADU STATE')
print('')
print('Name\t\tANNUAL INCOME\tTAXDUE')
for n in incomesList:
print(taxPayersList,'\t\t',incomesList,'\t',taxesList)
main()
Right now, I can enter a name into the first input, but as soon as I hit enter it just prints out my error code and then print out the final function like below.
Welcome to Xanadu Tax Computation Program
Do you have income amounts? y/n y
Enter a taxpayer name: Susan
An error occurred. Please only enter numbers for income amount.
2018 TAX DUES FOR XANADU STATE
Name ANNUAL INCOME TAXDUE
I know this is a total mess but any help at all would be so appreciated!

There is an IndexError: list assignment index out of range for the line
taxPayersList[index] = input('Enter a tax payer name: ')
You didn't see it because you excepted all errors and didn't print them. I suggest using
name = input('Enter a tax payer name:')
taxPayersList.append(name)
etc. Note that I append it to the list. I also suggest a different strategy of handling errors.
Alternatively, you might wish to use a dictionary instead of using two lists, since you want to associate an income with a name,
name = input('Enter a tax payer name:')
income = float(input('Enter income amount:'))
incomes[name] = income

You can't just assign into a non-existant index for a list to add items to it:
>>> a = []
>>> a[0] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
Instead you should look at using the .append() method for lists.
(The reason you aren't seeing the IndexError debugging details is because your except clause prevents it from being displayed. Bare except clauses are often considered an antipattern because they mask unexpected errors like this and make it harder to tell what went wrong - they catch any exception, not just ones due to bad user input.)

Related

Nesting an if condition within an if condition gone wrong? +(Investment and Bond Repayment Calculations in Python)

I am working on my first project where I ask users if they are want to calculate an investment or bond. Within this I've tried to nest another if/elif/else statement after they input investment or bond to get the user to input the necessary information for either for me to make the calculation but Python is registering an error for when I want to ask users about the bond calculation. I've tried to make it as clear as possible below:
import math
#Menu Option for Users
print("Investment: Calculate the amount of interest you'll earn on your investment")
print("Bond: Calculate the amount you'll have to pay on your home loan")
type = input("Please input either Investment or Bond to proceed:")
#casefold removes case sensitivity so user can input with or without caps.
#Investment Calculation
if type.casefold() == "Investment":
#if user inputs investment, they need to input the following information
money = input("Please input your deposit amount: ")
ir = input("Please input your interest rate as a percentage: ")
time = input("Please input how long you plan to invest for in years: ")
interest = input("Please input if you would like simple or compound interest: ")
#initialisations
simple_ir_calc = 0
comp_ir_calc = 0
if interest.casefold() == "simple":
simple_ir_calc = money (1 + ((ir/100) * time))
print(f"You will make {simple_ir_calc} on your investment")
elif interest.casefold() == "compound":
comp_ir_calc = money * math.pow((1+ (ir/100)), time)
print(f"You will make {comp_ir_calc} on your investment")
else:
print("Error. Either enter simple or compound.")
#Bond calculation
elif type.casefold() == "Bond":
#user inputs info needed to calc bond
pv = input("Please enter the present value of your property: ")
ir_b = input("Please input the interest rate as a percentage: ")
time_m = input("Please enter the number of months needed to repay the bond: ")
repayment = 0
repayment = ((ir_b/12) * pv) / math.pow(1 - (1 +(ir_b/12)), (-time))
print(f"You will have to pay {repayment} each month.")
else:
print("Error. Either input investment or bond.")
I tried to fix the indentations - so now the only 2 problems that python highlights is the expressions on line 34 and 44.
Also as a sidenote the bond repayment formula is meant to be X = (ir.pv)/(1-(1+ir)^(-time))
I just included -time at the end but I have no idea if my formula works within python
I know this is probably riddled with errors, so if you see anything else please let me know! I am very new to both python and stackoverflow so sorry for so many questions within one :(
I think this sorts out the indentation but only you know your intentions. A general comment - the code all fails if the user does not enter precisely one of your expected answers. You should pick up input errors. This might be easiest using 'Enter 1 for A, 2 for B etc'.
import math
#initialisations
simple_ir_calc = 0
comp_ir_calc = 0
#Menu Option for Users
print("Investment: Calculate the amount of interest you'll earn on your investment")
print("Bond: Calculate the amount you'll have to pay on your home loan")
choose = input("Please input either Investment or Bond to proceed:")
#casefold removes case sensitivity so user can input with or without caps.
print(choose.casefold())
#Investment Calculation
if choose.casefold() == "investment":
#if user inputs investment, they need to input the following information
money = input("Please input your deposit amount: ")
ir = input("Please input your interest rate as a percentage: ")
time = input("Please input how long you plan to invest for in years: ")
interest = input("Please input if you would like simple or compound interest: ")
if interest.casefold() == "simple":
simple_ir_calc = money (1 + ((ir/100) * time))
print(f"You will make {simple_ir_calc} on your investment")
elif interest.casefold() == "compound":
comp_ir_calc = money * math.pow((1+ (ir/100)), time)
print(f"You will make {comp_ir_calc} on your investment")
else:
print("Error. Either enter simple or compound.")
#Bond calculation
elif choose.casefold() == "bond":
#user inputs info needed to calc bond
pv = input("Please enter the present value of your property: ")
ir_b = input("Please input the interest rate as a percentage: ")
time_m = input("Please enter the number of months needed to repay the bond: ")
repayment = ((ir_b/12) * pv) / math.pow(1 - (1 +(ir_b/12)), (-time_m))
print(f"You will have to pay {repayment} each month.")
else:
print("Error. Either input investment or bond.")
Looks like indents are totally messed.
It should look like that:
# Condition
if a == 0:
b = 1
elif a == 1:
b = 2
else:
# Nested conditions
if c:
b = 3
else:
b = 9

Python declare winner using dictionary and loop

This is the output of the code I am trying to write. I have seen this done for C++, but not python with a dictionary. The key here is the dictionary is not optional. I need to use it to fulfill the assignment.
ID Candidate Votes Received % of Total Vote
1 Johnson 5000 55.55
2 Miller 4000 44.44
Total 9000
and the winner is Johnson!
I need to use a dictionary and a loop to create this. However, I am stuck on 3 points.
1.The percent- current code returns the percent before it has the whole total ex: first candidate always has 100%.
2. Declare a winner- code finds the max votes and returns the number value but I need it to return the name.
3. How to format the dictionary values so it lines up under the header. I don't think is possible, but it must be a requirement to use a dictionary for a reason. I am thinking I need to make a copy of the dictionary and format that?
Here is what I have so far:
totalVotes=[]
dct = {}
i = 1
while(True):
name = input('Please enter a name: ')
if name == '':
break
votes = input('Please enter vote total for canidate: ')
totalVotes.append(votes)
totalVotesInt= map(int, totalVotes)
total = sum(totalVotesInt)
dct[i] = {name,votes,int(votes)/total*100}
i += 1
header='{:>0}{:>10}{:>10}{:>20}'.format('ID','Name','Votes','% of Total Vote')
print(header)
print("\n".join("{}\t{}".format(key, value) for key, value in dct.items()))
print('Total '+str(total))
print('The Winner of the Election is '+max(totalVotes))
Which returns:
Please enter a name: Smith
Please enter vote total for canidate: 100
Please enter a name: Frieda
Please enter vote total for canidate: 200
Please enter a name: West
Please enter vote total for canidate: 10
Please enter a name:
ID Name Votes % of Total Vote
1 {'Smith', '100', 100.0}
2 {'Frieda', 66.66666666666666, '200'}
3 {3.225806451612903, '10', 'West'}
Total 310
The Winner of the Election is 200
You add the number of each candidates votes at the same time you calculate the percent vote for each candidate. You need to find the total votes first, then divide each candidates votes by the total
You are returning the max of a list of integers. Obviously you aren't going to get a string. You need some way to connect the number votes with the candidate.
Don't bother. You can try to figure out how many tabs you need to get the whole thing lined up, but from experience, it is basically impossible. You could separate them with commas and open it in excel as a csv, or you could just make the user figure out what number goes with what.
The other answer uses data tables, so I will take another, more vanilla and cool approach to getting what you want.
class candidate():
def __init__(self, name, votes):
self.name = name
self.votes = int(votes)
def percentvotes(self, total):
self.percent = self.votes/total
def printself(self, i):
print('{}\t{}\t\t{}\t\t{}'.format(i, self.name, self.votes, self.percent))
def getinput():
inp = input('Please enter your candidates name and votes')
return inp
candidates = []
inp = getinput()
s = 0
while inp != '':
s+=1
candidates.append(candidate(*inp.split(" ")))
inp = getinput()
for c in candidates:
c.percentvotes(s)
candidates.sort(key = lambda x:-x.percent)
print('ID\tname\t\tvotes\t\tpercentage')
for i, c in enumerate(candidates):
c.printself(i+1)
I have added very little changes to your code to make it work:
I have mentioned the changes as comments in the code.
Edit: It's more efficient to use objects for each candidate if you require scaling in the future.
totalVotes=[]
dct = {}
i = 1
while(True):
name = input('Please enter a name: ')
if name == '':
break
votes = input('Please enter vote total for canidate: ')
totalVotes.append(votes)
totalVotesInt= map(int, totalVotes)
total = sum(totalVotesInt)
# I change it to a list so it's much easier to append to it later
dct[i] = list((name,int(votes)))
i += 1
# I calculate the total percent of votes in the end and append to the candidate
maxVal = 0
for i in range(1, len(dct) + 1):
if dct[i][1] > maxVal:
maxInd = i
dct[i].append(int((dct[i][len(dct[i]) - 1]) / total * 100))
header='{:>0}{:>10}{:>10}{:>20}'.format('ID','Name','Votes','% of Total Vote')
print(dct)
print(header)
print("\n".join("{}\t{}".format(key, value) for key, value in dct.items()))
print('Total '+str(total))
print('The Winner of the Election is '+ dct[maxInd][0]))
I believe that this is the solution you are looking for. Just change the input statements in case you are using Python 2.x. Using Dataframe, the output will be exactly how you wanted.
import pandas as pd
import numpy as np
df = pd.DataFrame(columns=["Candidate", "Votes Received","Percentage of total votes"])
names=list()
votes=list()
while True:
name = str(input("Enter Name of Candidate."))
if name=='':
break
else:
vote = int(input("Enter the number of votes obtained."))
names.append(name)
votes.append(vote)
s=sum(votes)
xx=(votes.index(max(votes)))
myArray = np.array(votes)
percent = myArray/s*100
for i in range(len(names)):
df1 = pd.DataFrame(data=[[names[i],votes[i],percent[i]]],columns=["Candidate", "Votes Received","Percentage of total votes"])
df = pd.concat([df,df1], axis=0)
df.index = range(len(df.index))
print (df)
print ("Total votes = ",s)
print ("The man who won is ",names[xx])

How to make a chatbot that takes input and summarizes + calculates the average before terminating and printing the results?

I'm very new to programming, just started working my way through a Python course. I've been looking through the course material and online to see if there's something I missed but can't really find anything.
My assignment is to make a chatbot that takes input and summarizes the input but also calculates the average. It should take all the input until the user writes "Done" and then terminate and print the results.
When I try to run this:
total = 0
amount = 0
average = 0
inp = input("Enter your number and press enter for each number. When you are finished write, Done:")
while inp:
inp = input("Enter your numbers and press enter for each number. When you are finished write, Done:")
amount += 1
numbers = inp
total + int(numbers)
average = total / amount
if inp == "Done":
print("the sum is {0} and the average is {1}.". format(total, average))
I get this error:
Traceback (most recent call last):
File "ex.py", line 46, in <module>
total + int(numbers)
ValueError: invalid literal for int() with base 10: 'Done'
From searching around the forums I've gathered that I need to convert str to int or something along those lines? If there are other stuff that need to be fixed, please let me know!
It seems that the problem is that when the user types "Done" then the line
int(numbers) is trying to convert "Done" into an integer which just won't work. A solution for this is to move your conditional
if inp == "Done":
print("the sum is {0} and the average is {1}.". format(total, average))
higher up, right below the "inp = " assignment. This will avoid that ValueError. Also add a break statement so it breaks out of that while loop as soon as someone types "Done"
And finally I think you are missing an = sign when adding to total variable.
I think this is what you want:
while inp:
inp = input("Enter your numbers and press enter for each number. When you are finished write, Done:")
if inp == "Done":
print("the sum is {0} and the average is {1}.". format(total, average))
break
amount += 1
numbers = inp
total += int(numbers)
average = total / amount

Python Budget Code Issue

I am having an issue with the following code. When the user selects N I keep getting an error message:
budget = input("please enter the budget amount for given month\n ")
sum_ = 0
expense = 0
i = 0
print("Please enter the expenses for the given month:")
while (1):
expense1 = input("Please enter expense number " + str(i + 1) + " \n")
sum_ = sum_ + int(expense)
c = input("If you want to enter more expense press y else n \n")
if c == 'y':
i += 1
continue
else:
break
if sum_ > budget:
print("You went over budget")
else:
print("You are under budget")
Bug 1. When I run this with Python 3, I get
If you want to enter more expense press y else n
n
Traceback (most recent call last):
File "C:\Programs\python34\tem.py", line 16, in <module>
if sum_ > budget:
TypeError: unorderable types: int() > str()
You should have looked at the error message. It says that sum_ is an int and budget is a string. The obvious fix is to make budget an int with int(budget). If you really could not figure this out, you should probably look at the tutorial more. In any case, you should have posted it as Kevin suggested.
Bug 2. You initialized expense to 0. This masked the bug of calling the entered expense expense1. So you only add int(0) to the initially 0 sum_. The fix is to drop the initialization and correct the misspelling. You should also print the sum at the end to so you can check that it is correct.
Buglet 3. Having to say y/n to enter another expense is really annoying. Just stop when the user does not enter anything.
Two pieces of your code to give you a hint:
budget = input("please enter the budget amount for given month\n ")
expense1 = input("Please enter expense number " + str(i + 1) + " \n")
sum_ = sum_ + int(expense)
Notice some difference?
Also, do not use str(i + 1). "Please blah blah {0} blah\n".format(i + 1).

Python error calculating program

Ask the user to enter payroll information for the company. Set up a loop that continues to ask for information until they enter “DONE”. For each employee ask three questions:
name (first & last)
hours worked this week (only allow 1 through 60)
hourly wage (only allow 6.00 through 20.00)
VALIDATE the hours worked and the hourly wage, and make sure a name is entered.
Calculate each employee’s pay, and write it out to a sequential file. Be sure to include file I/O error handling logic.
Include only the weekly pay
Weekly pay is calculated:
For (1-40 hours) it is hourly rate * hours worked
For (41-60 hours) it is (hours worked – 40) * (hourly rate * 1.5)
+ hourly rate * 40
After all the employees are entered, read in the sequential file into a list named PAY for the weekly pay of each employee. Sort the list. Now print the lowest, highest, and average weekly pay for the week.
I am having obvious problem with this code
while len(eName)>0:
eName=raw_input("\nPlease enter the employees' first and last name. ")
hWork=raw_input("How many hours did they work this week? ")
hoursWork=int(hWork)
if hoursWork < 1 or hoursWork > 60:
print "Employees' can't work less than 1 hour or more than 60 hours!"
else:
pRate=raw_input("What is their hourly rate? ")
payRate=int(pRate)
if payRate < 6 or payRate > 20:
print "Employees' wages can't be lower than $6.00 or greater than $20.00!"
if hoursWork <=40:
grossPay=hoursWork*payRate
else:
grossPay=((hoursWork-40)*(payRate*1.5))+(40*payRate)
lsthours.append(grossPay)
print grossPay
print lsthours
ePass=raw_input("Type DONE when finished with employees' information. ")
ePass.upper() == "DONE"
if ePass == "DONE":
break
else:
continue
There's several problems with this code:
The indentation is all over the place. For example, the while loop ends at that first if statement
The test for the while loop is almost certainly false (since eName isn't initialised), so the loop never enters
the code at ePass.upper() == "DONE" is trying to set the ePass variable, which means that test won't work. You need:
if ePass.upper() == "DONE":
break
try this:
lsthours = list()
eName = "start" # initialize to something to start the loop
while eName:
eName = raw_input("\nPlease enter the employees' first and last name. ")
if not eName:
break #loop will exit also when blank name is inserted
hWork = raw_input("How many hours did they work this week? ")
hoursWork = int(hWork)
if hoursWork < 1 or hoursWork > 60:
print "Employees' can't work less than 1 hour or more than 60 hours!"
continue #skip
pRate = raw_input("What is their hourly rate? ")
payRate = int(pRate)
if payRate < 6 or payRate > 20:
print "Employees' wages can't be lower than $6.00 or greater than $20.00!"
continue #skip
if hoursWork <= 40:
grossPay = hoursWork * payRate
else:
grossPay = ((hoursWork - 40) * (payRate * 1.5)) + (40 * payRate)
lsthours.append(grossPay)
print grossPay
print lsthours
ePass = raw_input("Type DONE when finished with employees' information. ")
if ePass.upper() == "DONE":
break
It still lacks exception checking but should work.
The "data error" checks should just short-circuit the main loop, it's simpler, but you can have a more involved code and put them into their own loop.
A few errors as has been pointed out:
In python, indentation decides the code blocks
while loop:
while logic_test:
# this is inside while loop
....
# this is outside while loop
Certain functions on string does not replace the string in place, they return another string via return value
upper:
>>> a = "done"
>>> a.upper()
'DONE'
>>> a
'done'
>>>
Always initialize your variables.
If you are using sequence methods, the variable should have been defined as sequence earlier.
>>> t.append('ll')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 't' is not defined
>>> t = []
>>> t.append('ll')
>>>
Make your scope explicit
lsthours = []
while len(eName)>0:
........
lsthours.append(grossPay)
Yu can do something as this:
grossPay = 0.0
lsthours = []
eName=raw_input("\nPlease enter the employees' first and last name (type 'PASS' to exit): ")
while eName.upper() != "PASS":
hWork=raw_input("How many hours did they work this week? ")
hoursWork=int(hWork)
if hoursWork < 1 or hoursWork > 60:
print "Employees' can't work less than 1 hour or more than 60 hours!"
else:
pRate=raw_input("What is their hourly rate? ")
payRate=int(pRate)
if payRate < 6 or payRate > 20:
print "Employees' wages can't be lower than $6.00 or greater than $20.00!"
if hoursWork <=40:
grossPay=hoursWork*payRate
else:
grossPay=((hoursWork-40)*(payRate*1.5))+(40*payRate)
lsthours.append(grossPay)
print grossPay
print lsthours
eName=raw_input("\nPlease enter the employees' first and last name. (type 'PASS' to exit): ")

Categories

Resources