Python: multiplying 'for i in range(..) iteration' - python

So I have an assignment where I am required to return inf by multiplying x by 10 multiple times using a:
for i in range(...)
so the main part of my code is:
def g(x):
x = 10.*x
for i in range(308):
return x
and if I enter
>>> g(3.)
>>> 30.0
I expected it to iterate it 308 times to the point where I get inf. Is there a line I can use that uses the number in the for i in range(..) to iterate the equation that many times? For example:
def g(x):
x = 2.*x
for i in range(3):
# the mystery line I need for it to work
return x
>>> g(4.)
>>> 16.0
but it doesn't give me that. Rather it returns 8.0
Another way I did it that actually made it work was using print. But I don't think it's valid using a print statement in an assignment asking to return inf.

I think you have the right parts, just not arranged correctly. Try something like this:
def g(x):
for i in range(308):
x = 10.*x # because we've moved this line into the loop, it gets run 308 times
return x # since we've unindented this line, it runs only once (after the loop ends)
The part you want to be repeated needs to be indented after the line with the for statement. Stuff you don't want repeated (like the return, which can only happen once), should not be in the loop.

The reason it isn't iterating like you expect is because of the return statement. return exits from whatever procedure/function that you are running immediately and returns the value given to it. Here is a walk through of your first function, assuming it was called with the value of 4 as in g(4.).
# the start of the function
# x = 10
# this line sets x = 100. I think you can see why.
x = 10. * x
# this sets i = 0 and begins to loop
for i in range(308):
# this IMMEDIATELY returns from the function with the value
# of x. At this point, x = 100. It does not continue looping!
# Without this line, i would be set to 1, 2, 3, ..., 307 as
# you loop through the range. This is why it worked with print.
return x
What you want instead of this is something that will accumulate the value of the repeated multiplications. You don't want to return anything at all within the loop, assuming you want every iteration to run. I will not give you the exact answer because this is homework but I will give a hint. You probably do not want return to be indented, as it is in the second bit of code you provided. You probably want something more like this:
def g(x):
x = 2 * x
for i in range(3):
# { your code here }
# You want to accumulate the value!
return x

Related

How to repeat a function till its return value matches its previous return value?

I have a Python function that returns a value.
def population_gen(P)
...
return fittest
Now, I need to write a piece of code that compares the "fittest" with last iteration of the function call population_gen(P) that returned "fittest" and stops when the current fittest becomes equal to the previous one.
What I have tried is the following:
def population_gen(P)
...
return fittest
gen_count = 0
max_gen_count = 10
while gen_count <= max_gen_count:
population_gen(Pop)
gen_count += 1
I can run this any number of times (11 in this case) and make sure that my code is working. But, I do not want to it run 11 times, rather keep the while loop running till the aforementioned condition is met. I also wanted to mention that this function generates a population from a given initial population. Then, I feed this function again with the population that it generates and successfully keep it running for as many times I want. But I cannot implement the condition of comparing the "fittest" value.
Please help. Thanks in advance!
I assume that you want to keep iterating through the loop if the current and last values of the function returned is not equal.
Theory:
You can declare two variables, one inside loop and one outside. The work of inside one is to get the value of function returned by the function, and the outside one will be used to keep check of the previous value, so that it doesn't get lost (I mean the previous value here).
Now, you know, how simple it is, let's implement it. First, for the example, I would be creating a function that returns a random value from a list.
import random # Importing random module for help in choosing random value
def foo():
_list = [1, 2, 3]
return random.choice(_list)
Now, we have our example function, let's create a loop to keep check. NOTE: The type of loop you are using can be used, but the more efficient one is to use for loop, as you can use range function there as suggested by #Jab.
It's time to declare variables and the loop:
var = None # Outside the loop, will be used as a container for previous returned value
for _ in range(1, 12): # range(min. value, max. value [not included])
a = foo() # Creating a variable 'a', that would be holding current returned value from the function
if var is not None and a == var: # For first iteration, it would be None but the value will be assigned to 'var' in for it's next iteration and checking it whether the prev. and current values are equal or not
break # Break the loop
var = a # Assigns 'var' the value if the loop is still running
Now, the above example can be used as the answer. But, what if you want to check it? So, following is the code provided with the example for debugging purposes:
import random
def func():
l = [1, 2, 3]
val = random.choice(l)
print(val) # Printing the value, for debugging purposes
return val
var = None
for x in range(1, 12):
a = func()
if var is not None and a == var:
print(f'\nSame values after {x} iterations') # It will show, after how many iterations the loop stopped
break
var = a
Now, I ran the above code 3 times, the following is the output:
OUTPUT:
>>> 3
>>> 3
>>>
>>> Same values after 2 iterations
>>> 2
>>> 3
>>> 2
>>> 2
>>>
>>> Same values after 4 iterations
>>> 2
>>> 2
>>>
>>> Same values after 2 iterations
I hope you understood the concept.
Use a new default variable set as maximum in the arguments. Like -
def population_gen(P, prev_fit = 99999): if prev_fit < population_gen(P): return prev_fit
Assuming you want to call the function population_gen until it's last two invocations return the same value. The output of population_gen becomes the input in the next iteration.
import random
def population(limit: int) -> int:
return random.randint(1, limit)
prev = None
cur = population(10)
while prev != cur:
prev = cur
cur = population(prev)
print(prev)

What's happening when I indent 'return' incorrectly

This is the code that returns the value I expect:
python
def function1():
highest = 0
for x in range(100):
for y in range(100):
if x+y > highest:
highest = x+y
return highest
print(function1())
This code prints "198".
Now, if I indent the return statement under the if statement, like this:
def function1():
highest = 0
for x in range(100):
for y in range(100):
if x+y > highest:
highest = x+y
return highest
print(function1())
The code prints "1".
Why? What's happening behind the scenes?
Sorry if this is a trivial question, but don't know the basic structure and stuff, I'm only learning by experimenting...
it is terminated in the second step of the second loop.
highest = 0
x = 0
y = 0
if 0+0 > 0 (false):
increment y to 1:
the second run:
highest = 0
x = 0
y = 1
if 0+1 > 0 (true)
highest = 1
return # return command is called and therefore the execution of the function ends
A return statement ends the execution of the function call and "returns" the result.
The return statement stops a loop at the point when you call it. So in the first example it goes through the whole for loop and then returns the value of highest. In the second example it returns on the first entry of the for loop, so it doesn't go through the whole for loop.
A return statement ends the function. If you put it inside the if statement, the function stops as soon as the condition is true. So it will return the first value of x+y that's more than 0, which happens when x = 0 and y = 1, rather than continuing to look for higher values.
In the first example, the return statement is below both for loops, but is also indented outside of both of them. That means that it isn't reached until the nested for loop expression is evaluated for every possible combination of x and y.
On the other hand, in the second example, return is indented inside the if statement. Once the if statement is reached, the Python interpreter reads all lines indented at that level, including return highest. So the first time x+y > highest (which is when x+y==1, the if statement runs, and the function returns 1. The return acts as an early break, so even though there will be more values that it could process, it doesn't matter because you explicitly told it to return early.

How does the code prints 1 2 6 24 as output and not 24 6 2 1

def recurr(k):
if (k>0):
result =k*recurr(k-1)
print(result)
else:
result=1
return result
recurr(4)
Output:
1
2
6
24
Because you're printing result after you recurse.
When you call recurr(4), the first thing it does is call recurr(3). This calls recurr(2), then recurr(1), and finally recurr(0). This last one is the base case, so it returns 1.
After that returns, you calculate result = k * 1, which is result = 1 * 1, then it prints that, so it prints 1 and then returns 1.
Then the previous recursion calculates result = k * 1, which is result = 2 * 1, then it prints that, so it prints 2 and returns it.
This repeats through all the recursions.
Its because you were printing result everytime you called it inside function instead of print what first call of function returned.
def recurr(k):
if (k>0):
return k*recurr(k-1)
return 1
print(recurr(4)) # -> 24
Because in every call of the function recurr() the print() function is executed.
If you want to print 24 that's the code:
def recurr(k):
if (k>0):
result =k*recurr(k-1)
else:
result=1
return result
print(recurr(4))
The recursion stack will print your message multiple times. This snippet may clarify why:
def factorial(k):
if (k>0):
print(f'factorial({k}) calls factorial({k-1})')
result = k*factorial(k-1)
else:
print(f'factorial({k}) is the base case')
result=1
return result
print(factorial(4))
you have to remove the print part in your function. Instead, you should write the code like this at the end of the code:
print(recurr(4))
The point is, the function is calling itself, and each time the function is called and processes the "if" block, it throws out a print. as for the order, the function evaluates the brackets inside out. As stated by #timgeb in comments,
recurr(4) --> 4*recurr(3*recurr(2*recurr(1*recurr(0))))
This evaluates recurr(0), which then successfully evaluates recurr(1) and so on.
The recursion in your code occurs on line 3, and the print statement occurs on line 4, after the recursion. When executing recurr(4), the entire code for recurr(3) (including the print statement for recurr(3)) is executed before the print statement for recurr(4).
Get 4 friends. Label them 1!, 2!, 3! and 4!. Tell them that if asked what their value is they must ask (n-1)! for their value, and then multiply by n, write it on a bit of paper and hand to the asker. All asking, must also be done on a bit of paper.
Now ask 4! for their value, when you get it shout it out.
Next tell them to do the same but whenever they pass a bit of paper to someone, they mast also shout out the value. Record what happens.
Which of the shouters is the one to keep?
When you use recursion, you build up a set of operation on the way down to the last call. Then you unroll them from the last, backwards up out to the first.
In this toy, you build up your result from the highest number, by putting your operation (k*next_value) at the bottom, and build it up. Then you get the result of each operation, from the top to the bottom.

Python 'for' function

I am trying to write a code that returns every prime palindrome with three digits. Here is my code:
def digpalprim():
for x in range (100,1000):
if prime(x)=='prime':
if str(x)==str(x)[::1]:
return x
I've already defined the prime(x) function, it works well, that stage just determines whether x is prime or not. All in all the code works, except that it only gives me the first such a palindrome. I don't really understand why, shouldn't the program consider all the numbers between 100 and 1000? Please help?
Your function returns as soon as it finds the first such palindrome; return exits a function.
Collect your finds in a list and return that:
def digpalprim():
palindromes = []
for x in range (100,1000):
if prime(x)=='prime':
if str(x)==str(x)[::1]:
palindromes.append(x)
return palindromes
or you can make your function a generator by replacing the return with a yield statement:
def digpalprim():
for x in range (100,1000):
if prime(x)=='prime':
if str(x)==str(x)[::1]:
yield x
Now you'll have to iterate over this function or use list() to 'pull' all values out:
all_palindromes(digpalprim())
or
for palindrome in digpalprim():
print(palindrome)
You are returning the function the first time you encounter one.
def digpalprim():
palprimes = []
for x in range (100,1000):
if prime(x)=='prime':
if str(x)==str(x)[::1]:
palprimes.append(x)
return palprimes
This creates a list at the start of the function and appends each valid palindrome prime to that list, then returns the entire list (after completing all loops) instead of returning just the first one encountered.
Just remember, if Python hits a return statement, it's going to stop function execution right there and return that value regardless of any additional loops or code you may intend to be executed.
The function returns and ends as soon as the first result is found.
You may wish to add the results to a list and then print out the list.
return x This statement causes the program to return to the calling function once this statement is encountered. To return all you may put it in an list. For e.g:
you can have a list called values and append it to it, and finally return it at the end
For such small tasks, I prefer using list comprehensions:
palindromes = [x for x in range(100, 1000) if (prime(x) == 'prime') and (str(x) == str(x)[::1])]
Or (equivalently):
condition = lambda f: prime(f) == 'prime' and str(f) == str(f)[::1]
palindromes = [x for x in range(100, 1000) if condition(x)]

I need help wrapping my head around the return statement with Python and its role in this recursive statement

No this isn't homework but it is on our study guide for a test. I need to understand the role the return statement plays and the role recursion plays. I don't understand why the function doesn't break after x = 1.
def thisFunc(x):
print(x)
if x>1:
result=thisFunc(x-1)
print(result)
return x+1
Sorry, I understand how elementary this is but I could really use some help. Probably why I can't find an explanation anywhere...because it's so simple.
edit: Why does it print out what it does and what and why is the value of x at the end? sorry if I'm asking a lot I'm just frustrated
When you enter the function with a value n>1 it prints the current value, and then calls it's self with n-1. When the inner function returns it returns the value n - 1 + 1 which is just n. Hence, the function prints out the value n twice, once before the inner recursion and once after.
If n == 1, which is the base case, the function only prints 1 once and does not call it self again (and hence does not get result back to print). Instead it just returns, hence why 1 is only printed once.
Think of it like an onion.
calling thisFunc(n) will result in
n
# what ever the output (via print) of thisFunc(n-1) is
n
I don't understand why the function doesn't break after x = 1.
But it does:
>>> ================================ RESTART ================================
>>> x = 1
>>> def thisFunc(x):
print("Function called on x-value: ", x)
if x > 1:
result = thisFunc(x-1)
print(result)
return x+1
>>> thisFunc(x)
Function called on x-value: 1
2
>>>
edit: Why does it print out what it does and what and why is the value of x at the end?
Well, it prints it out because you're telling it to. Try following the value of x as you go through the function ("x is one, one is not bigger than 1; return 1+1. Ok. [new case] x is two, two is bigger than 1..." and so on).
return and recursion are part and parcel of programming; return statements designates the end of a function (even if you might have several lines more of code) and they also pass data back to whatever asked them for it. In your case you're asking "what happens when x is 1, given these rules?"; the returned data is your answer.
Recursion is simply the matter of letting the function call itself, should it (you) need to. You simply tell the program that "hey, as long as x is bigger than 1, call this function [that just so happens to be the same function initially called] on it and let it do its thing". To get a better understanding of your function I'd suggest that you add the line "Function called on x-value: " to the first print statement inside the function, or at least something that lets you identify which printed line is x and which is result.
For a more in-depth explanation on recursion, I recommend Recursion explained with the flood fill algorithm and zombies and cats

Categories

Resources