This question already has answers here:
How can I use `return` to get back multiple values from a loop? Can I put them in a list?
(2 answers)
Closed 8 months ago.
I have been working on this assignment for school and I just can't figure out what why I cant get this program to work properly. I am trying to get the program to allow the user to enter three animals. It is only allowing me to enter one. I know it has to do with my placement of the return statement in the make_list function but can't figure out how to fix it.
Here is my code:
import pet_class
#The make_list function gets data from the user for three pets. The function
# returns a list of pet objects containing the data.
def make_list():
#create empty list.
pet_list = []
#Add three pet objects to the list.
print 'Enter data for three pets.'
for count in range (1, 4):
#get the pet data.
print 'Pet number ' + str(count) + ':'
name = raw_input('Enter the pet name:')
animal = raw_input('Enter the pet animal type:')
age = raw_input('Enter the pet age:')
#create a new pet object in memory and assign it
#to the pet variable
pet = pet_class.PetName(name,animal,age)
#Add the object to the list.
pet_list.append(pet)
#Return the list
return pet_list
pets = make_list()
Your problem is, precisely, that you're putting the return statement inside the for-loop. The for-loop runs each statement in it for however so many times.. if one of your statements is a return, then the function will return when it hits it. This makes sense in, for example, the following case:
def get_index(needle, haystack):
for x in range(len(haystack)):
if haystack[x] == needle:
return x
Here, the function iterates until it finds where the needle is in the haystack, and then returns that index (though there's a builtin function to do this, anyways, list.index()).
If you want the function to run for however many times you tell it to, you have to put the return AFTER the for-loop, not inside it. That way, the function will return after the control gets off the loop
def add(numbers):
ret = 0
for x in numbers:
ret = ret + x
return ret
(though again, there's a builtin function to do this as well, sum())
You just need to return the pet_list outside of the for loop, so it will happen after the loop has finished running.
def make_list():
pet_list = []
print 'Enter data for three pets.'
for count in range (1, 4):
print 'Pet number ' + str(count) + ':'
name = raw_input('Enter the pet name:')
animal=raw_input('Enter the pet animal type:')
age=raw_input('Enter the pet age:')
print
pet = pet_class.PetName(name,animal,age)
pet_list.append(pet)
return pet_list
You have the return statement at the incorrect level of indentation. It should be at the same depth as the for statement. Having the return within the loop causes it to break out of the loop.
Remove one indent before the return.
You notice the for loop runs only once because the return statement is inside the if statement, within the loop
I've had a similar problem right now with my code:
Return the number of even ints in the given array. Note: the % "mod" operator computes the remainder, e.g. 5 % 2 is 1.
count_evens([2, 1, 2, 3, 4]) → 3
count_evens([2, 2, 0]) → 3
count_evens([1, 3, 5]) → 0
def count_evens(nums):
summary = 0
for i in nums:
if i % 2 == 0:
summary += 1
return summary
count_evens([2, 1, 2, 3, 4])
if you go to visualize execution and paste in my code http://www.pythontutor.com/visualize.html#mode=edit
Once I unindented it 8 spaces (same depth as the for statement), it ran multiple times and gave the correct output.
Your spacing is off. return pet_list is in the scope of the for loop.
Related
This question already has answers here:
How can I use `return` to get back multiple values from a loop? Can I put them in a list?
(2 answers)
Closed 8 months ago.
I have been working on this assignment for school and I just can't figure out what why I cant get this program to work properly. I am trying to get the program to allow the user to enter three animals. It is only allowing me to enter one. I know it has to do with my placement of the return statement in the make_list function but can't figure out how to fix it.
Here is my code:
import pet_class
#The make_list function gets data from the user for three pets. The function
# returns a list of pet objects containing the data.
def make_list():
#create empty list.
pet_list = []
#Add three pet objects to the list.
print 'Enter data for three pets.'
for count in range (1, 4):
#get the pet data.
print 'Pet number ' + str(count) + ':'
name = raw_input('Enter the pet name:')
animal = raw_input('Enter the pet animal type:')
age = raw_input('Enter the pet age:')
#create a new pet object in memory and assign it
#to the pet variable
pet = pet_class.PetName(name,animal,age)
#Add the object to the list.
pet_list.append(pet)
#Return the list
return pet_list
pets = make_list()
Your problem is, precisely, that you're putting the return statement inside the for-loop. The for-loop runs each statement in it for however so many times.. if one of your statements is a return, then the function will return when it hits it. This makes sense in, for example, the following case:
def get_index(needle, haystack):
for x in range(len(haystack)):
if haystack[x] == needle:
return x
Here, the function iterates until it finds where the needle is in the haystack, and then returns that index (though there's a builtin function to do this, anyways, list.index()).
If you want the function to run for however many times you tell it to, you have to put the return AFTER the for-loop, not inside it. That way, the function will return after the control gets off the loop
def add(numbers):
ret = 0
for x in numbers:
ret = ret + x
return ret
(though again, there's a builtin function to do this as well, sum())
You just need to return the pet_list outside of the for loop, so it will happen after the loop has finished running.
def make_list():
pet_list = []
print 'Enter data for three pets.'
for count in range (1, 4):
print 'Pet number ' + str(count) + ':'
name = raw_input('Enter the pet name:')
animal=raw_input('Enter the pet animal type:')
age=raw_input('Enter the pet age:')
print
pet = pet_class.PetName(name,animal,age)
pet_list.append(pet)
return pet_list
You have the return statement at the incorrect level of indentation. It should be at the same depth as the for statement. Having the return within the loop causes it to break out of the loop.
Remove one indent before the return.
You notice the for loop runs only once because the return statement is inside the if statement, within the loop
I've had a similar problem right now with my code:
Return the number of even ints in the given array. Note: the % "mod" operator computes the remainder, e.g. 5 % 2 is 1.
count_evens([2, 1, 2, 3, 4]) → 3
count_evens([2, 2, 0]) → 3
count_evens([1, 3, 5]) → 0
def count_evens(nums):
summary = 0
for i in nums:
if i % 2 == 0:
summary += 1
return summary
count_evens([2, 1, 2, 3, 4])
if you go to visualize execution and paste in my code http://www.pythontutor.com/visualize.html#mode=edit
Once I unindented it 8 spaces (same depth as the for statement), it ran multiple times and gave the correct output.
Your spacing is off. return pet_list is in the scope of the for loop.
I am trying to find the max of the "rollList" and everything I have tried isn't working.I'm not very good with coding and the instruction my teacher gave me isn't very clear. I also have to reset "rollList" back to empty for each player and I am very confused.Please someone help.
import random
class Player:
def __init__(self,name ):
self.name = name
self.dice = []
def __str__(self):
return self.name
def roll_Dice(self):
rollDice = random.randint(1, 6)
return rollDice
rounds = 1
rollList = []
newplayer = []
newplayer.append(Player("CAT:"))
newplayer.append(Player("DOG:"))
newplayer.append(Player("LIZARD:"))
newplayer.append(Player("FISH:"))
for rounds in range(1,4):
print("-----------------")
print("Round" + str(rounds))
for p in newplayer:
print(p)
for x in range (4-rounds):
rollDice = random.randint(1, 6)
rollList.append(rollDice)
print(rollList)
max.pop(rollList)
print(rollList)
rollList.clear()
len(rollList)
The line max.pop(rollList) is fairly meaningless. It attempts to call the pop method of the built-in max function, which doesn't exist.
You can get the maximum by just calling max itself:
maxRoll = max(rollList)
If you want to remove that roll, you can (although it doesn't seem necessary, since you'll be clearing the list):
rollList.remove(maxRoll)
If you want to append the maximum to another list:
anotherList.append(maxRoll)
You can find the maximum of a list using max() function:
mylist = [1,2,4,5,6,7,-2,3]
max_value = max(mylist)
Now max_value is equal to 7. You can add this to a new list using append() method:
new_list = []
new_list.append(max_value)
then new_list will be [7]
I report some suggestions to resolve the error I suppose you have: AttributeError: 'builtin_function_or_method' object has no attribute 'pop'
Just change max.pop(rollList) to max(rollList).
Then you have a list of only one element because you are calling methods inside the for rounds in range(1,4): loop, without letting the list populate with other elements. You are calling also clear at each loop.
Also, the for x in range (4-rounds): it is not required, it's a nested loop.
You are printing the list of names without assign to each person the value of roll dice, so who's the winner?
Finally, you defined roll_Dice() as instance method of Person, so why not use it?
So, why not rollList.append(p.roll_Dice()) instead of:
rollDice = random.randint(1, 6)
rollList.append(rollDice)
Hope this can help.
I am trying to create a function called "odd_even" which takes my already created list (named "nums") and determines the number of odd and even numbers, and then returns the variables to me. However when I run this code I get:
NameError: name 'odd' is not defined
How do I fix this? If you can give me any useful pointers on the "return" function that would also be greatly appreciated.
import random
def main():
nums = []
for x in range(10):
nums.append(random.randrange(1,26))
def odd_even(given_list):
odd = 0
even = 0
for x in given_list:
if x % 2 == 0:
even += 1
else:
odd += 1
return odd
return even
odd_even(nums)
print("List had ", odd, "odds and ", even, "evens.")
main()
You are doing 2 things wrong.
First, you are trying to return two values but on different lines. You cant do this, to do this, do so as a tuple:
def odd_even(given_list):
odd = 0
even = 0
for x in given_list:
if x % 2 == 0:
even += 1
else:
odd += 1
return odd, even
Second, you call the function but dont store the value(s) of return. So you need change:
odd_even(nums) to odd, even = odd_even(nums)
By trying to execute:
print("List had ", odd, "odds and ", even, "evens.")
The main() is looking for variables odd and even, but they dont exist in main(), they exist locally in odd_even() (hence why you are calling return as to return them to the calling function. The reason you only see an error with respect to odd is because it is the first variable in that print() that the interpreter encounters an error on.
The only way around this without correct use of return is to declare them as global. But that is a bad idea so don't do that, keep things local on the stack!
You have some syntactic errors. Python...unlike many programming languages is whitespace conscious. This means you need to be careful with your indentation and spacing. More traditional languages like Java and C use brackets {} to define a scope, and semicolons ; to figure out line termination.
Perhaps you copied it poorly, but from what I see, it appears as though you are defining the function odd_even() within the function main(). That is, the definition of odd_even() is tabbed to the right, which means that its definition is within the function main. I assume that you want main to call the function odd_even(). Thus, you must tab it back over to the left so that it is at the same indentation level as main().
For this reason I use horizontal lines (see below) to clearly outline the scope of functions. This is good for me when I write in Python because otherwise it can be very unclear where one function ends, and where another begins.
Also, it appears as though you have 2 return statements. If you want to return 2 values, you should encompass it within an object. To get around this, there are two simple solutions that come to mind. You can make the odd_even() function access global variables (not recommended)...or you can return an array (any number of values back) or a tuple (exactly 2, but this is python specific).
Below is an implementation of both:
import random
# Declare global variables outside the scope of any function
odd = 0
even = 0
#-------------------------------------------------------------------------------
def main():
nums = [1,2,3,4,5,6,7,8,9,10]
return_value = odd_even(nums)
# Get the individual values back
o = return_value[0]
e = return_value[1]
# You can use the global variables
print("List had ", odd, "odds and ", even, "evens.")
# Or you can get the array back
print("List had ", o, "odds and ", e, "evens.")
#-------------------------------------------------------------------------------
def odd_even(given_list):
# This means we are referencing the variables odd and even that are global
global odd
global even
# Loop through the array
for x in given_list:
if x % 2 == 0:
even += 1
else:
odd += 1
return [odd, even]
#-------------------------------------------------------------------------------
main()
Sometimes I get confused as to where to use the return statement. I get what it does, it's just that I don't get its placement properly.
Here's a short example of the same code.
Correct way:
def product_list(list_of_numbers):
c = 1
for e in list_of_numbers:
c = c * e
return c
Wrong way (which I did initially):
def product_list(list_of_numbers):
c = 1
for e in list_of_numbers:
c = c * e
return c
Can someone clarify what's the difference between the two and where should the return be when using a loop in a function?
return in a function means you are leaving the function immediately and returning to the place where you call it.
So you should use return when you are 100% certain that you wanna exit the function immediately.
In your example, I think you don't want to exit the function until you get the final value of c, so you should place the return outside of the loop.
You're putting too much emphasis on the impact of return on controlling the behaviour of the for loop. Instead, return applies to the function and happens to terminate the for loop prematurely by primarily bringing an end to the function.
Instead, you can control the behaviour of the for loop independently from the function itself using break. In addition, you can have multiple return statements in a function depending on what action should be taken in response to particular criteria (as in my_func1). Consider the following:
import random
def my_func1(my_list, entry):
'''
Search a list for a specific entry. When found, terminate search
and return the list index immediately
Return False if not found
'''
print "\n Starting func1"
index = 0
for item in my_list:
if item != entry:
print "Not found yet at index: {}".format(index)
index += 1
else:
print "found item, at index {}".format(index)
print "Terminating function AND loop at same time"
return index
print "########### ENTRY NOT IN LIST. RETURN FAlSE #############"
return False
a = my_func1(['my', 'name', 'is', 'john'], 'is')
b = my_func1(['my', 'name', 'is', 'john'], 'harry')
def my_func2(my_list):
''' Iterate through a list
For first 4 items in list, double them and save result to a list that will
be returned, otherwise terminate the loop
Also, return another list of random numbers
'''
print '\n starting func2'
return_list = []
for i in range(len(my_list)):
if i < 4:
print 'Value of i is {}'.format(i)
return_list.append(my_list[i] * 2)
else:
print 'terminating for loop, but ** keep the function going **'
break
other_list = [random.randint(1, 10) for x in range(10)]
print 'Returning both lists'
return return_list, other_list
c = my_func2([x for x in range(10)])
So as the title hopefully suggest, this is for an example in said book.
I'm still new to programming and having difficulty debugging. With that said any criticism is welcomed, specially if it shows a more efficient way of coding; just keep in mind that I'm still new so there's a good chance i might not know what you're referring to if you toss me a new built-in function or something.
So the point of this exercise is to write a function, giving it three arguments, to determine if those three arguments form a triangle. Here's my code:
def is_triangle(a,b,c):
num_list = [a,b,c]
biggest = max(num_list)
other_two = num_list.remove(biggest)
sum_of_two = sum(other_two)
if sum_of_two > biggest:
print 'Congrats, %d, %d, and %d form a triangle!' % (a,b,c)
elif sum_of_two == biggest:
print 'That forms a degenerate triangle!'
else:
print 'That does\'t make any sort triangle... >:['
def sides():
side1 = raw_input('Please input side numero Juan: ')
side2 = raw_input('Now side two: ')
side3 = raw_input('...aaaannnd three: ')
import time
time.sleep(1)
print 'Thanks >:]'
side1 = int(side1)
side2 = int(side2)
side3 = int(side3)
is_triangle(side1,side2,side3)
sides()
Whenever i run it, however, i get the following:
Traceback (most recent call last):
File "A:/Python/is_triangle.py", line 27, in <module>
sides()
File "A:/Python/is_triangle.py", line 25, in sides
is_triangle(side1,side2,side3)
File "A:/Python/is_triangle.py", line 5, in is_triangle
sum_of_two = sum(other_two)
TypeError: 'NoneType' object is not iterable
My guess is the sum_of_two line but i don't know what's wrong with it. Could someone help me debug this?
I spend a good hour rewriting it with out the built_in function (in various ways, bunch of ors everywhere). But it looked terrible and I'd rather learn to write this way.
The problem is the fact that remove modifies the underlying list - it doesn't return a new list. Change it to:
num_list.remove(biggest)
sum_of_two = sum(num_list)
To see exactly why this happens, try the following in IDLE:
>>> x = [1,2,3,4,5]
>>> x.remove(1)
>>> x
[2,3,4,5]
Sincenum_list.remove(biggest) returns None, Consider this instead
other1, other2, biggest = sorted(num_list)
sum_of_two = other1 + other2
It looks like the if block needs to be indented too
def is_triangle(a, b, c):
num_list = [a, b, c]
other1, other2, biggest = sorted(num_list)
sum_of_two = other1 + other2
if sum_of_two > biggest:
print 'Congrats, %d, %d, and %d form a triangle!' % (a,b,c)
elif sum_of_two == biggest:
print 'That forms a degenerate triangle!'
else:
print 'That does\'t make any sort triangle... >:['
You just made a very common mistake, a simple one. In Python, when a function causes a change in a data structure, it does not return the changed structure. Usually it returns None. If the function gets a new data structure or new value, it returns it.
So, str.lower() doesn't actually change a string; it returns a new string where the characters are lower-case. If you have some list named lst and you run sorted(lst), it doesn't change the list; it returns a new list that is sorted. But lst.sort() sorts the list in-place, so it doesn't return a reference to the list; it returns None.
In the comments below, #lvc pointed out that list.pop() removes a value from a list and returns the value. So, this is an example of a function that changes a data structure and returns something other than None, but it still definitely does not return a reference to the changed data structure.
The list.remove() function changes a list, and it returns None. All you need to do is change your function to use the same list for everything: first use the list to find the max, then remove the max value from the list, then pass the list to sum().
The reason Python does things this way is to obey the "Command/Query Separation" principle.
http://en.wikipedia.org/wiki/Command%E2%80%93query_separation