Returning items from a function in python - python

How can I return the commented out line below the print statement at the end of this function? Also, when I run the function with the return un-commented, I get one result, but when I run the function with the return commented, I get 7 results and I'm not sure why this is happening.
What I would like to do is call track['name'] after I call the function. When I do, I get this error Traceback (most recent call last):
File "spot.py", line 25, in
track['name']
NameError: name 'track' is not defined
import requests
import json
message = "if i can\'t let it go out of my mind".split()
size = len(message)
def decrementList(words):
for w in [words] + [words[:-x] for x in range(1,len(words))]:
url = 'http://ws.spotify.com/search/1/track.json?q='
request = requests.get(url + "%20".join(w))
json_dict = json.loads(request.content)
track_title = ' '.join(w)
num_words_removed = len(words) - len(w)
new_message_length = size - num_words_removed
new_message = message[new_message_length:size]
for track in json_dict["tracks"]:
if track["name"].lower() == track_title.lower():
print track["name"], " | ", track["href"], " | ", track_title, " | ", num_words_removed
#return track["name"], track["href"], track_title, num_words_removed
decrementList(message)

A return statement causes the function to stop executing and return the value you have specified, whereas with a print statement it just causes something to be output to the terminal, and the function continues to execute.
In order to use the value that is returned from the function, you must do something with it, like assign it to a variable. For example:
track = decrementList(message)
but in that case, you would want to return the track:
for track in json_dict["tracks"]:
if track["name"].lower() == track_title.lower():
return track

Related

Pset7 numb3r; failed check50

I am doing problem set 7; my code output True or False as per instruction but it didn't pass check50.
check50 returned:
Traceback (most recent call last):
File "/tmp/tmp2vk2c_gh/test_correct_ipv4_localhost/testing.py", line 3, in \<module\>
print(validate(input("IPv4 Address: ")))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/tmp2vk2c_gh/test_correct_ipv4\_...
Kindly assist.
Here is my code
import re
def main():
# prompting use for IPV4
ip = input("IPv4 Address: ")
numbers = get_num(ip)
print(validate(numbers))
def get_num(ip):
# search for a valid IPV4 sequence in a string
m = re.search(r"^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$", ip)
if m:
# convert each group in a sequence to an int
number1 = int(m.group(1))
number2 = int(m.group(2))
number3 = int(m.group(3))
number4 = int(m.group(4))
# return a list of numbers
return [number1, number2, number3, number4]
# if no match found return None
else:
return None
# validate ip address
def validate(numbers):
# if there was a match
if numbers:
for number in numbers:
# check if each number in
if 0 <= number <= 255:
number = number
else:
return False
return True
else:
return False
if __name__ == "__main__":
main()
Now that I look at the traceback more closely and compare to the code above, I see why the error occurs. I will explain.
The last line of the traceback displays the line with the error. It is:
Traceback (most recent call last):
...
print(validate(input("IPv4 Address: ")))
This is what the Python interpreter was trying to execute when the error occurs. It also tells you this is line 3 in file testing.py. So, the error isn't in your code (per se), but when testing.py calls your code.
Now, look at your main() function (code snippet below):
ip = input("IPv4 Address: ")
numbers = get_num(ip)
print(validate(numbers))
Notice how input() returns ip. You then call get_num(ip) which returns numbers, and THEN it calls print(validate(numbers)). You have an extra step between input() and validate() that is not in the testing code. That's not how your program is supposed to work. You should get the input and call validate() directly -- no intermediate functions. That's why it doesn't work when called from testing.py.
I assume you fixed the error by migrating get_num() into the validate() function?

Difficulties with an unruly program

I have been working on this code for a couple of hours now, and I am rather unsure what the problem is.
import random#imports random
import os#Imports os
print("Welcome to the maths quiz") # Welcomes user to quiz
score = (0)
def details():
plr_name = input ("Please Input Name:") # Asks user for name
plr_class = input("Input class number: ") # Asks the user for class numer
return (plr_name, plr_class)
def Q():
while qno < 10: # loops while qno is under 10
ran_num1 = random.randint(1,99) # Generates the first random number
ran_num2 = random.randint(1,99) # Generates the second random number
ran_fun = random.choice("X-+") # Picks a random function
print(ran_num1,ran_fun,ran_num2,"=") # Prints the Sum for the user
if ran_fun == "X":
sum_ans = ran_num1 * ran_num2 # Does the sum if it is a multiplication
if ran_fun == "+":
sum_ans = ran_num1 + ran_num2 # Does the sum if it is a addition
if ran_fun == "-":
sum_ans = ran_num1 - ran_num2 # Does the sum if it is a subtraction
plr_ans = int(input()) # Gets the user's answer
if plr_ans == sum_ans:
print("Correct!") # Prints correct
score = score + 1 # Adds 1 to score
else:
print("Incorrect!")
qno = qno + 1 # Adds 1 to qno
def plr_list_make(lines, listoreder):
index = 0
plr_names =[]
plr_scores =[]
for line in lines:
if listorder == 1:
column =0
rev = False
else:
column = 1
rev = True
return sorted(zip(plr_names, plr_scores),key = lambda x:(x[column]),reverse = rev)
def fileUP(plr_name, score, line ):
found = False
index = 0
for line in lines:
if line.startswith(plr_name):
line = line.strip("\n") + ","+str(score+"\n")
lines[index] = line
found = True
index = index + 1
if not found:
lines.append(plr_name+"|" +str(score)+"\n")
return lines
def save (plr_name, plr_class, score):
filename = "QuizScore_"+plr_class+".txt"
try:
fileI = open(filename)
except IOError:
fileI = open(filename, "w+")
fileI = open(filename)
lines = fileI.readlines()
fileI.close
lines = FileUP(plr_name, score, lines)
fileO = open(filename, "w")
fileO.writelines(lines)
fileO.close
def disp_list(): ## intialise_list
student_list=[]
filename = "QuizScore_"+plr_class+".txt"
try:
## open file read into list "lines"
input_file = open(filename)
lines = input_file.readlines() ## read file into list "lines"
input_file.close
student_list = create_student_list(lines, listorder) ### update "lines" with student list as requested by user
## output sorted list
for counter in range(len(student_list)):
print ("Name and Score: ", student_list[counter][0], student_list[counter][1])
except IOError:
print ("no class file!!!")
def menu():
print ("1 Test")
print ("2 Alphabetical")
print ("3 Highscore")
print ("4 Avg Score")
def Run():
selection = 0
while selection != 5:
menu()
option = int(input("Please select option: "))
if option == 1:
name, plr_class = details()
save(name, plr_class, Q())
else:
plr_class = input("input class ")
disp_list(plr_class, option-1)
Run()
Errors:
Traceback (most recent call last):
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 117, in
Run()
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 113, in Run
save(name, plr_class, Q())
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 74, in save
lines = FileUP(plr_name, score, lines)
NameError: global name 'FileUP' is not defined
Line 110:
name, plr_class = details()
But the details function does not return anything - so Python tries to assign the default return value None to the tuple name, plr_class. It can't do this, because None is not an iterable (you can't assign two things to it). To fix it, add the following line to your details function:
return (plr_name, plr_class)
(I haven't tested this.)
I like your game but it's buggy as a mofo :P
score and qno aren't properly defined. Define them in the functions that need them, define them globally or pass them to the relevant functions as arguments.
details() doesn't return anything but you still attempt to use its output to define two other variables. Add return (plr_name, plr_class) to details()
Every time you cast user input to int without checking its value, your program will crash if an int can't be cast. This applies here:
option = int(input("Please select option: "))
here
plr_ans = int(input())#Gets the user's answer
and elsewhere.
Since your program is input-heavy you could make a a function to which you pass the expected datatype and an optional string to display to the user. This way you wouldn't have to write try/except 10 times and your program wouldn't crash on unexpected input.
In def fileUP(plr_name, score, line ): you have for line in lines: but lines isn't defined. Thus, the save() function that calls FileUP() also fails. Also, FileUP and fileUP are not the same thing. You call the function with a capital "f" but the defintion of the function calls it fileUP with a lower case "f".
While we're at it, the file handling in def save (plr_name, plr_class, score):looks weird. The standard way of opening files for simple reading and writing in Python is via with open().
disp_list() should take one or two arguments but it doesn't at the moment so this error is raised:
TypeError: disp_list() takes 0 positional arguments but 2 were given
These 2 positional arguments were given here:
disp_list(plr_class, option-1)

How to run one function and then another function within the main()

So I am just learning Python and am working on an online exercises to get use to the language and software itself. Right now I am working on making one function (getData()) run and then the results from that function to run into another function (getStats()) that is all with a main(). Each one works individually but I am having a problem with the main(). I can get my first getData() to run and make my list but I can't get that list to run directly into getStats(). It actually runs the getData() again and then comes back with an error message when I put in an input . Does anyone have any suggestions for me to not get that error message and then to actually run my getStats()?
def getData():
import math
pop = []
while True:
user = raw_input("Please enter a population number (-1 to quit): ")
pop.append(user)
if user == '-1':
break
if user <= '0':
print "Population not valid, please input a value higher then 0"
new_pop = map(int, pop)
pop2 = filter(lambda x:x >=1, new_pop)
print "Your population list is: ", pop2
return
def getStats():
i = ""
asc = sorted(i)
print "The collected data in the asecending order", asc
dec = sorted(i, reverse = True)
print "The collected data in the descending order", dec
maxi = max(i)
print "The maximum of the collected data is", maxi
mini = min(i)
print "The minimum of the collected data is",mini
def getMean(i):
aver = round(sum(i), 2)/round(len(i), 2)
print "The average of the collected data is %.2f" % aver
getMean(i)
def getStdev(i):
aver = sum(i)/len(i)
var = sum(pow(user-aver,2) for user in i)/len(i)
stdev = math.sqrt(var)
print "The standard deviation of the collected data is %.2f" % stdev
return
def main():
getData()
getStats(getData())
main()
The variables inside each function cannot be accessed by other functions variable/function scope.
One way to use them is to have the function return those values. Here is a simplified example:
def get_data():
data = raw_input('Ask for data')
return data
def get_stats(data):
sorted_data = sorted(data)
print 'Sorted:', sorted_data
data = get_data() # get_data will point 'data' to the value returned
get_stats(data) # call get_stats, and pass 'data' as an argument
Some other thoughts:
You don't really need the main() function. It's not doing anything.
What is more common, is adding a conditional statement to only run this if you are running the file itself, but not when it's imported as a module:
if __name__ == '__main__':
data = get_data()
get_stats(data)
Check out PEP 008
Usually your imports should be at the beginning of the file (Imports)
Function names are camel_case

Python - Random baby name generator issues - (duplicating input, calling variables)

I've been looking at this all afternoon and can't figure out why the gender input is repeating itself despite only appearing to be called once. It's not part of a loop that I can see either.
I've tried adding variables to act as a counter and tried using an if statement to only run the input if the counter variable is less than 1, but can't figure it out.
Edit: Thanks to the great feedback here, I found out that get_full_name was causing the duplicating gender input in get_first_name - but now I'm running into issues when trying to output the randomly generated first & middle names.
I figured setting the setFirst, setMiddle and setLast variables as globals, but then I get a NameError. I also tried creating a new function to display them, but that wasn't working either. I tried adding "self." (without the quotes) either directly in the function() or one of the indents beneath it.
I'll display the error first, then the full code.
Error:
Traceback (most recent call last):
File "init.py", line 100, in
main()
File "init.py", line 92, in main
print displayName(setFirst, setMiddle, setLast)
NameError: global name 'setFirst' is not defined
I also get name errors trying to concatenate setFirst, setMiddle and setLast into another variable for the full name.
Here's the code:
from os.path import abspath, join, dirname
import random
full_path = lambda filename: abspath(join(dirname(__file__), filename))
FILES = {
'first:male': full_path('dist.male.first'),
'first:female': full_path('dist.female.first'),
'last': full_path('dist.all.last'),
}
def get_name(filename):
selected = random.random() * 90
with open(filename) as name_file:
for line in name_file:
name, _, cummulative, _ = line.split()
if float(cummulative) > selected:
return name
def get_first_name(gender=None):
global determine
global setFirst
print ("First name... Enter 1 for Male, 2 for Female or 3 to be surprised! ")
determine = input()
if determine == 1:
gender = 'male'
if determine == 2:
gender = 'female'
if determine == 3:
print ("You want to be surprised!")
gender = random.choice(('male', 'female'))
return get_name(FILES['first:%s' % gender]).capitalize()
setFirst = get_first_name()
print setFirst + " "
def get_middle_name(gender=None):
global setMiddle
if determine == 1:
gender = 'male'
if determine == 2:
gender = 'female'
if determine == 3:
gender = random.choice(('male', 'female'))
return get_name(FILES['first:%s' % gender]).capitalize()
setMiddle = get_middle_name()
print setMiddle + " "
def get_last_name():
global setLast
#We will implicitly pass a Last Name until other issues are fixed
return “Smith”
setLast = get_last_name()
print setLast
def get_full_name(gender=None):
return u"%s %s %s" % (get_first_name(gender), get_middle_name(gender), get_last_name())
#def displayName(setFirst, setMiddle, setLast):
# print setFirst + " " + setMiddle + " " + setLast
def main():
#print u"%s %s %s" % (setFirst, setMiddle, setLast)
#print displayName(setFirst, setMiddle, setLast)
f = open('output', 'a') #append output to filename output
f.write(get_full_name() + '\n') #and add a line break after each run
f.close()
if __name__ == "__main__":
main()
Even if I try passing the variables to main() like:
def main(setFirst, setMiddle, setLast):
It still gives the NameError about not being defined. What am I doing wrong?
I added this right under "import random", but now I'm getting some rogue "None" displays - which leads me to believe there is a leak in the code somewhere. Thoughts?
setFirst = None
setMiddle = None
setLast = None
Here is the function I created to try to track it:
def displayName(setFirst, setMiddle, setLast):
if setFirst == None:
print ("Random Baby Name Generator")
else:
print setFirst
print setMiddle
print setLast
if setMiddle == None:
print ("Double check the middle name variable.")
if setLast == None:
print ("Double check the last name variable.")
You are calling get_full_name() twice, you need to save the results:
def main():
full_name = get_full_name()
print(full_name)
f = open('output', 'a') #append output to filename output
f.write(full_name + '\n') #and add a line break after each run
f.close()
You also have a few indentation issues as well, plus your use of globals is a bit inefficient. Ideally, functions should do one - and only one - task; this makes them easier to debug.
Try this different version of your code:
from os.path import abspath, join, dirname
import random
full_path = lambda filename: abspath(join(dirname(__file__), filename))
FILES = {
'first:male': full_path('dist.male.first'),
'first:female': full_path('dist.female.first'),
'last': full_path('dist.all.last'),
}
GENDER_MAP = {'1': 'male', '2': 'female'}
def get_gender():
result = input('Select a gender: 1 for Male, 2 for Female or 3 to be surprised')
if result not in ('1', '2', '3'):
print('{} is not a valid choice, please try again'.format(result))
return get_gender()
if result == '3':
return random.choice(('1', '2'))
return result
def get_name(filename):
selected = random.random() * 90
with open(filename) as name_file:
for line in name_file:
name, _, cummulative, _ = line.split()
if float(cummulative) > selected:
return name
def get_name_from_file(name_type='first', gender='male'):
if name_type in ('first','middle',):
name = get_name(FILES['{}:{}'.format(name_type, gender)]).capitalize()
else:
name = get_name(FILES['last']).capitalize()
return name
def get_full_name():
gender = get_gender()
gender_file = GENDER_MAP.get(gender, '')
first_name = get_name_from_file('first', gender_file)
middle_name = get_name_from_file('middle', gender_file)
last_name = get_name_from_file('last')
return '{} {} {}'.format(first_name, middle_name, last_name)
if __name__ == '__main__':
name = get_full_name()
print(full_name)
with open('output', 'a') as f:
f.write('{}\n'.format(full_name))
print('Done')
get_full_name is being called twice, probably, and this result in other functions referenced by get_full_name being called twice as well. Unfortunately this means double input and confusing the user.

python code problem

i have this code:
class Check(webapp.RequestHandler):
def get(self):
user = users.get_current_user()
be = "SELECT * FROM Benutzer ORDER BY date "
c = db.GqlQuery(be)
for x in c:
if x.benutzer == user:
s=1
break
else:
s=2
if s is 0:
self.redirect('/')
to check whether the user is registered or not.
but it gives me an error:
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/__init__.py", line 511, in __call__
handler.get(*groups)
File "/Users/zainab_alhaidary/Desktop/الحمد لله/check.py", line 23, in get
if s is 0:
UnboundLocalError: local variable 's' referenced before assignment
what should i do???
Define s before to assign it a value (also, change the test on s):
user = users.get_current_user()
be = "SELECT * FROM Benutzer ORDER BY date "
c = db.GqlQuery(be)
s=0 # <- init s here
for x in c:
if x.benutzer == user:
s=1
break
else:
s=2
if s == 0: # <- change test on s
self.redirect('/')
Why exactly are you loading all users, then looping through them, just to find one? Use a where clause:
be = "SELECT * FROM Benutzer WHERE benutzer=:1"
c = db.GqlQuery(be, user)
user_from_db = c.get()
if user_from_db is not None: # found someone
dostuff()
else:
self.redirect('/')
You're using 's' before you assign something to it. Add an 's = 0' in the appropriate location.
You want to set s to 0 before the for loop starts. If the query returns zero items, your for loop doesn't loop even once, so s is undefined.
Also, you should use if s == 0: instead of if s is 0:. In CPython, they are both equivalent, but you shouldn't rely on the fact. See: the documentation for PyInt_FromLong and "is" operator behaves unexpectedly with integers.
Your problem is that if c is an empty list then the code in the for loop is never run and s never gets set, hence the error:
UnboundLocalError: local variable 's' referenced before assignment
What the error is telling you that you're referencing - i.e. using - s before it has any value - i.e. before a value has been assigned to it.
To fix this you just ensure s always is assigned a value:
s = 0
for x in c:
if x.benutzer == user:
s = 1
break
else:
s = 2
In the case that c is empty the if statement in the loop never gets executed
you should set s=0 before the for loop
I don't know why you are doing this, but if I understand your code correctly, you have s=1 when x.benutzer == user, and s=2 otherwise (shouldn't this be s=0 if you are going to check against 0?).
for x in c:
if x.benutzer == user:
s=1
break
else:
s=2
if s is 0:
self.redirect('/')
Anyway, here's my solution:
if not any(x.benutzer == user for x in c):
self.redirect('/')

Categories