I'm creating a program to match a particular year to an Olympic location.
I.e. if the user inputs a year, it finds the location where the Olympic games took place that year (1904 - Athens, Greece..) etc.
It keeps telling me i have positional errors in my code, however:
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module> findLocation()
TypeError: findLocation() missing 3 required positional arguments:
'yearList', 'locList', and 'year'
Here is my program:
def getData():
print("All the events")
print("")
yearList = []
locList = []
readFile = open('olympics.txt', 'r')
for line in readFile:
year, loc = line.split("\t")
loc = loc.replace("\n", "")
yearList.append(year)
locList.append(loc)
return yearList,locList
def findLocation(yearList, locList, year):
i=0
location=""
while i<len(locList):
if yearList[i] == year:
year = yearList[i]
elif yearList[i] !=year:
return print ("That was incorrect")
i += 1
return location
Getting data works successfully, but my findLocation function seems to be out of whack and i dont know how to fix it.
Here is an excerpt of the text file containing the Olympic events.
1896 Athens, Greece
1900 Paris, France
1904 St. Louis, Missouri USA
1906 Athens, Greece*
1908 London, England
1912 Stockholm, Sweden
1916 Not held**
1920 Antwerp, Belgium
Can someone help me please?
The reason findLocation does not yield a result is because you are iterating over all the years/locations, and if the first one is incorrect you return from the function (return print ("That was incorrect"))
UPDATE: Included an example main method describing how to call the functions
Something like this should work better:
def getData():
print("All the events")
year_to_location = {}
with open('olympics.txt', 'r') as f:
content = f.readlines()
for line in content:
year, loc = line.split("\t")
year_to_location[year] = loc.strip()
return year_to_location
def findLocation(year_to_location, year):
if year in year_to_location:
return year_to_location[year]
else:
print("That was incorrect")
if __name__ == '__main__':
year_to_location = getData()
print(findLocation(year_to_location, "1900"))
Note: I replaced the year_list and loc_list with a dictionary year_to_location instead and simplified the findLocation quite a bit. I also added a with open('olympics.txt') as f statement which is a slightly better way of handling files (it assures that the file handler gets closed when done)
You could also just remove return from return print ("That was incorrect") and your code should work as is.
but my findLocation function seems to be out of whack
You are right about that. Your logic needs to be changed there. However, next time, please add a little more information of what you expected and what you got. That will help us. Now on to the logic:
def findLocation(yearList, locList, year):
i=0
location=""
while i<len(locList):
if yearList[i] == year:
return locList[i]
elif int(yearList[i]) > int(year):
print "That was incorrect"
return
i += 1
print "Year was incorrect"
return
Now this function needs to be called with three arguments. Two from your getdata and one from the user to print the location:
year_list, loc_list = getData()
year = raw_input("Enter the year to search:")
findLocation(year_list, loc_list, year)
Having said that your code is non idiomatic and that it could be rewritten in a shorter, clearer way, let's try to analyze your problem.
Your error is motivated by a mismatch between the function signature and your usage, but even if it was called correctly it won't return the correct location... this is your code
def findLocation(yearList, locList, year):
i=0
location=""
in the line above you set location, and it is never reassigned, so you're going to return the null string, irrispective of the rest of your code
while i<len(locList):
if yearList[i] == year:
year = yearList[i]
the test above is tautological, if two objects are equal (i.e., their values are equal) you assign one's value to the other object... you've not changed anything
elif yearList[i] !=year:
return print ("That was incorrect")
the test above is not what you want, because 1. you don't want to exit from your function until you've tested all the possible Olympyc years and 2. return print(...) returns the value returned by the print function, i.r., None.
i += 1
return location
Staying close to your coding style, I'd go like this
def find_location(y_list, l_list, year):
i = 0
while i<len(y_list):
if year == y_list[i]:
# the following statement exits the function,
# returning the Olympics location for the year
return l_list[i]
i = i+1
return ''
If you know about the zip builtin, the following is more compact and expressive
def f(y_l, l_l, year):
for y, l in zip(y_l, l_l):
if year==y: return l
return ""
The real solution of your problem is to use a different data structure instead of the paired lists, namely a dict but it seems to me that you were not introduced to it...
Related
#Please help me
def computepay(h, r):
if h>40:
reg=40*r
otp=(h-40.0)*1.5*r
else:
pay = h*r
return pay
hrs = input("Enter Hours:")
rate= input('enter rate per hour: ')
fh = float (hrs)
fr = float (rate)
p = computepay(fh, fr)
print("Pay", p)
If I understand your code correctly, your code is not pasted well, if h > 40 pay is not assigned any value, pay only is assigned a value in the else
That's why you get that error
To answer the the question about "pay" being referenced before being assigned, your code is running through the if statement portion of the line where you define computepay(). You never add reg and otp into a variable called pay, which is what I assume you're trying to do.
Also, in your else statement, you make pay = hr, which does not exist, since python will parse hr as one variable and not two, be sure to use asterisks for everything to parse correctly.
How I would type out the computepay() definition would look like this:
def computepay(h, r):
if h>40:
reg=40*r
otp=(h-40.0)*1.5*r
pay=reg+otp
else: pay = h*r
return pay
The main function below return pay is fine, though. This should run perfectly, good luck!
I need my results to be saved separately so that I can run the rest of my code.
Basically, I have to do a project on loans and each type of loan would have a different monthly repayment amount. The problem now is that each user might have a different number of different loans. For example, one user might only have home loan (HL) while one user might have 3 different loans. In my codes, I need to include this which would return the monthly repayment amount for that particular type of loan:
def meet_criteria(account_no):
if getsaving(account_no) in ["HL"]:
HLmonthly()
else:
if getsaving(account_no) in ["RL"]:
RLmonthly()
else:
if getsaving(account_no) in ["EL"]:
ELmonthly()
I also need to sum up the repayment amount like this:
total_monthly_debt = repay1 + repay2 + repay3
However, right now, I can't to proceed with above codes as I am unable to separate the results to get the 'HL', 'RL' and 'EL' that I need to call the meet criteria(). In order to get all the results to show, I am using a loop like so:
def getsaving(account_no):
query = """\
select SUBSTRING(LoanID, 1, 2)
from Account_Delinquency
where Account_Number = '{}'
""" .format(account_no)
return (execute_read_query (conn, query))
a = getsaving(account_no)
mylist = []
for i in a:
mylist.append(i)
I tried to put it in a list so that I could separate it but obviously, it doesn't work that way. This was a method I learnt to check if a list is empty but as expected, it can't check if parts of the list is empty and would return error. It also involves a little hardcoding which is not ideal.
if mylist[1][0]:
loan1 = mylist[1][0]
else:
pass
Hence, I am asking to see if there are any other methods I can use so that I can get a result of, for example, Loan1 = HL, Loan2 = nothing, Loan3 = RL etc. I would also appreciate any suggestions for changes to my code as I know it is not the most ideal. Thank you!
meet_criteria seems incorect (no return value)
def meet_criteria(account_no):
if getsaving(account_no) in ["HL"]:
HLmonthly()
else:
if getsaving(account_no) in ["RL"]:
RLmonthly()
else:
if getsaving(account_no) in ["EL"]:
ELmonthly()
could be
def meet_criteria(account_no):
if getsaving(account_no) == "HL":
HLmonthly()
elif getsaving(account_no) == "RL":
RLmonthly()
elif getsaving(account_no) == "EL":
ELmonthly()
Btw. I haven't fully understood your question, but I think that you want meet_criteria to return something, (I would know for sure if you provided how you use this function).
So instead do
def meet_criteria(account_no):
if getsaving(account_no) == "HL":
return HLmonthly()
elif getsaving(account_no) == "RL":
return RLmonthly()
elif getsaving(account_no) == "EL":
return ELmonthly()
Further improvements:
if mylist[1][0]:
loan1 = mylist[1][0]
else:
pass
The else branch doesn't do anything. Also, if you haven't defined loan1 before and you are using it later, you would get NameError: name 'loan1' is not defined.
To remove else branch:
if mylist[1][0]:
loan1 = mylist[1][0]
To not get NameError
if mylist[1][0]:
loan1 = mylist[1][0]
else:
loan1 = 0 # if it is suposed to be integer, maybe you want None of False
def trip_cost(city,days,spending_money):
days = input("Enter amount of days for car hire")
city = input("City name")
days = input("Nights staying")
spending_money = input("Spending money")
return hotel_cost(days) + plane_ride_cost(city) + rental_car_cost(days) + spending_money
print((trip_cost(city,days,spending_money)))
I keep getting an error saying that city is not defined. I am new to Python so I am sorry if this is question that is easy to answer. All the variables already have their set functions. Here is city's one just in case it helps
def plane_ride_cost(city):
if city=="Charlotte":
return 183
elif city=="Tampa":
return 220
elif city=="Pittsburgh":
return 222
elif city=="Los Angeles":
return 475
else:
return input("Please try again")
Also this is an altered code from Code Academy
def trip_cost():
days = int(input("Enter amount of days for car hire"))
city = input("City name")
nights = int(input("Nights staying"))
spending_money = int(input("Spending money"))
return hotel_cost(nights) + plane_ride_cost(city) + rental_car_cost(days) + spending_money
print(trip_cost())
Get rid of the parameters; you do not need them since you will get it from user input via the input() function.
I used the int function to convert the input of numbers which are strings to integers.
In your print((trip_cost(city,days,spending_money))) call, where is city coming from? It looks like it is outside any of the functions so you need to declare it somewhere as something. And even when you do so, you will get the same error for days and spending_money. These need to be declared before they are printed.
Either that or actually pass in values to your trip_cost call in the print statement :)
Also, looking at the code more closely, it looks like your trip_cost method does not even need any arguments. you are creating the variables when asking for input so it looks like they are redundant as parameters.
def getValidSeason( ):
season = input ( "Enter a season between 1980 and 2016: " )
while season < 1980 or season > 2016:
season = input ( "Enter a season between 1980 and 2016: " )
return season
def getValidDriver( ):
driver = input ( "Enter a driver's name: " )
# This is where the first problem is
# I want to be able to use the value of season from getValidSeason( )
# in the getValidDriver( ) function
while getValidSeason( ) != 1980 and driver != "Steve Park" or driver != "Jamie McMurray"
driver = input ( "Enter a driver's name: " )
return driver
def printResults( ):
# Basically the same as before, I want the value of the driver
# variable defined in the getValidDriver( ) to be used in the print results( ) function
print ( "The driver being selected is",getValidDriver( ) )
def main( ):
# I don't believe my question has anything to do with what you put in the main function , but I might be wrong.
I looked around and could not find help with my problem. I am sorry if there is already a solution out there, but I couldn't find anything. Maybe I was wrong. I'm struggling with programming. I did find a question on this website that was basically the same question but it involved an earlier version of Python, and they were talking about stuff that is no longer used in the current version of Python.
Thanks for the help.
Your code is very close (although I don't understand the condition of the while loop). I cleaned up the formatting such as lowercase R in return and spacing conventions in function calls. I changed the inputs to convert to ints in getValidSeason() since you are trying to get strings. I also added some print lines in the while loop for my own benefit.
Also importantly, you don't need a main here (although it would be ok), but you do need to call your printResults() function to get the code running (the very last line of code). Let me know if you have questions about something I did or didn't explain.
CODE:
def getValidSeason():
season = int(input("Enter a season between 1980 and 2016: "))
while season < 1980 or season > 2016:
season = int(input("Enter a season between 1980 and 2016: "))
return season
def getValidDriver():
driver = input("Enter a driver's name: ")
season = getValidSeason()
# This is where the first problem is
# I want to be able to use the value of season from getValidSeason( )
# in the getValidDriver() function
#EDIT: Not sure what logic you actually want here
while season != 1980 and driver != "Steve Park" or driver != "Jamie McMurray":
print('Last driver selected was: '+str(driver))
print('Last season selected was: '+str(season))
driver = input("Enter a driver's name: ")
season = getValidSeason()
return driver
def printResults():
# Basically the same as before, I want the value of the driver
# variable defined in the getValidDriver() to be used in the print results() function
valid_driver = getValidDriver()
print ("The driver being selected is",valid_driver)
printResults()
EDIT:
#This is Function "func1"
#It takes the variable "name" as its one and only argument
# and it adds '_1' to the end of it before returning name
def func1(name):
print('In func1 you passed in the name: '+name)
print('Adding "_1" to the end of the name')
name = name+'_1'
print('In func1 your new name is: '+name)
print('')
return name
#Just like func1
def func2(name):
print('In func2 you passed in the name: '+name)
print('Adding "_2" to the end of the name')
name = name+'_2'
print('In func2 your new name is: '+name)
print('')
return name
#Function that will ask the user for a name
#Doesn't take any arguments
#Returns the name
def get_name():
name = 'Steve' #<-- just set to always be steve for now (you can replace this w/ an 'input()')
print('Your original name was '+name)
print('')
name_f1 = func1(name) #<-- original name w/ '_1' added to the back
name_f2 = func2(name) #<-- original name w/ '_2' added to the back
name_f1_f2 = func2(name_f1) #<-- orig name w' '_1_2' added to the back
name_f2_f1 = func1(name_f2) #<-- orig name w' '_2_1' added to the back
return name
#Call the get_name function which will then call func1 and func2
get_name()
You probably want to save the functions' return value in a variable in the other function. Here's an example for printResults:
def printResults():
driver = getValidDriver()
# you can now use the 'driver' variable
print("The driver being selected is", driver)
Python Course Shows that you simply need to add the global flag if you want to declare the variable as global inside a function. to further quote Python Course :
"The way Python uses global and local variables is maverick. While in many or most other programming languages variables are treated as global if not otherwise declared, Python deals with variables the other way around. They are local, if not otherwise declared."
I am not sure if this will resolve your issue completely since you are returning the variable back out. Thats simply the first thing I noticed about your code.
"I believe I understood the code you just put up. I'm getting my new keyboard in a couple days so I can't type the code yet, but I think I understand what is going on there. I don't think it answered my question though, unless I am missing something. Let's say in get_name( ) it asks the user to type in a name, and the user types in Tom. The variable that stores this is called name1. Now I want to use the variable name1 in multiple different functions, but I want the value of name1 to automatically be = to the user input defined in get_name( ) without the user having to type it again.
I think I could ask the user the question by using a global variable to ask it, but isn't it proper coding to have it inside a function? Functions are supposed to do 1 thing each and be used to break the program up. Putting the question outside of a function I think you aren't supposed to do. "
I read your comments on the comment section. I posted them above. I think the only thin you can do is call the function or created a global variable.
I have a couple of functions that are being called recursively inside nested loops. The ultimate objective of my program is to:
a) loop through each year,
b) within each each year, loop through each month (12 total),
c) within each month, loop through each day (using a self generated day counter),
d) and read 2 files and merge them together into a another file.
In each instance, I am going down into the directory only if exists. Otherwise, I'm to just skip it and go to the next one. My code does a pretty good job when all the files are present, but when one of the files is missing, I would like to just simply skip the whole process of creating a merged file and continue the loops. The problem I am getting is a syntax error that states that continue is not properly in the loop. I am only getting this error in the function definitions, and not outside of them.
Can someone explain why I'm getting this error?
import os, calendar
file01 = 'myfile1.txt'
file02 = 'myfile2.txt'
output = 'mybigfile.txt'
def main():
#ROOT DIRECTORY
top_path = r'C:\directory'
processTop(top_path)
def processTop(path):
year_list = ['2013', '2014', '2015']
for year in year_list:
year_path = os.path.join(path, year)
if not os.path.isdir(year_path):
continue
else:
for month in range(1, 13):
month_path = os.path.join(year_path, month)
if not os.path.isdir(month_path):
continue
else:
numDaysInMth = calendar.monthrange(int(year), month)[1]
for day in range(1, numDaysInMth+1):
processDay(day, month_path)
print('Done!')
def processDay(day, path):
day_path = os.path.join(path, day)
if not os.path.isdir(day_path):
continue
else:
createDailyFile(day_path, output)
def createDailyFile(path, dailyFile):
data01 = openFile(file01, path)
data02 = openFile(file02, path)
if len(data01) == 0 or len(data02) == 0:
# either file is missing
continue
else:
# merge the two datalists into a single list
# create a file with the merged list
pass
def openFile(filename, path):
# return a list of contents of filename
# returns an empty list if file is missing
pass
if __name__ == "__main__": main()
You can use continue only plainly inside a loop (otherwise, what guarantee you have that the function was called in a loop in the first place?) If you need stack unwinding, consider using exceptions (Python exception handling).
I think you can get away with having your functions return a value that would say if operation was completed successfully:
def processDay(day, path):
do_some_job()
if should_continue:
return False
return True
And then in your main code simply say
if not processDay(day, path):
continue
You are probably getting that error in processDay and createDailyFile, right? That's because there is no loop in these functions, and yet you use continue. I'd recommend using return or pass in them.
The continue statement only applies in loops as the error message implies if your functions are structured as you show you can just use pass.
continue can only appear in a loop since it tells python not to execute the lines below and go to the next iteration. Hence, this syntax here is not valid :
def processDay(day, path):
day_path = os.path.join(path, day)
if not os.path.isdir(day_path):
continue # <============ this continue is not inside a loop !
else:
createDailyFile(day_path, output)enter code here
Same for your createDailyFile function.
You may want to replace it with a return ?