Repeating a function a set amount of times in python - python

I am doing an intro class and they are asking me to repeat a function a certain amount of times, as I said this is an intro so most of the code is written so assume the functions have been defined. I have to repeat the tryConfiguration(floorplan,numLights) the amount of time numTries requests. any help would be awesome :D thank you.
def runProgram():
#Allow the user to open a floorplan picture (Assume the user will select a valid PNG floodplan)
myPlan = pickAFile()
floorplan = makePicture(myPlan)
show(floorplan)
#Display the floorplan picture
#In level 2, set the numLights value to 2
#In level 3, obtain a value for numLights from the user (see spec).
numLights= requestInteger("How many lights would you like to use?")
#In level 2, set the numTries to 10
#In level 3, obtain a value for numTries from the user.
numTries= requestInteger("How many times would you like to try?")
tryConfiguration(floorplan,numLights)
#Call and repeat the tryConfiguration() function numTries times. You will need to give it (pass as arguments or parameterS)
# the floorplan picture that the user provided and the value of the numLights variable.

First let me double check if I understood what you need: you have to place numTries sequential calls to tryConfiguration(floorplan,numLights), and each call is the same as the others.
If it is so, and if tryConfiguration is synchronous, you can just use a for loop:
for _ in xrange(numTries):
tryConfiguration(floorplan,numLights)
Please let me know if I'm missing something: there could be other solutions, like leveraging closures and/or recursion, if your requirements are different.

Loop in the range of numTries and call the function each time.
for i in range(numTries):
tryConfiguration(floorplan,numLights)
If using python2 use xrange to avoid creating the whole list in memory.
Basically you are doing:
In [1]: numTries = 5
In [2]: for i in range(numTries):
...: print("Calling function")
...:
Calling function
Calling function
Calling function
Calling function
Calling function

When we're talking about repeating a certain block of code multiple times, it's generally a good idea to use a loop of some kind.
In this case you could use a "for-loop":
for unused in range(numtries):
tryConfiguration(floorplan, numLights)
A more intuitive way (albeit clunkier) might be using the while loop:
counter = 0
while counter < numtries:
tryConfiguration(floorplan, numLights)
counter += 1

Related

Can't call a subroutine when within a subroutine, if and for loop. Have I done something wrong here?

So here's my code.
def bubblesort(list):
global step
global oldlist
print("""
ORIGINAL LIST""")
print(list)
for i in range(len(list)):
for j in range(len(list)-1):
if float(list[j])>float(list[j+1]):
list[j], list[j+1] = list[j+1], list[j]
if oldlist==list:
**end(list)**
else:
oldlist=list
step=step+1
print("""
STEP""",step)
print(list)
end(list)
def end(list):
global step
step=step+1
print("""
STEP""",step)
print(list)
step=0
oldlist=[]
list=[]
number=int(input("How many numbers do you want to input to sort? : "))
for i in range(1,number+1):
value=float(input("INPUT NUMBER : "))
list.append(value)
bubblesort(list)
The issue is the bit of code which I have is "end(list)" bare in mind I've included the ** to make it easier to see on here it's not actually in the code. It simply won't call the subroutine when I ask it to. I know it definitely runs through the if since if i put a "print" or "break" in they both work it just won't jump to a sub-routine. Furthermore, the time I call that subroutine later on in the code works and does go to the subroutine. So i'm a bit lost as to what I've done wrong here. Any help? Would be much appreciated :)
There are quite a few things wrong with your code, and your question. Let's go through them:
First of all, the formatting was not great (I've suggested an edit). This might not sound like a big deal ("Hey, as long as it works...") but it's actually crucial: I work with python every day, and I had trouble understanding your code
You're talking about subroutines. In python, we usually refer to those as functions, or methods.
You're using globals variables all over the place. This might work in little toy examples like this one, but it will fall apart VERY fast
As David Buck said, list is one of the basic data structures: 1 in an instance of int and [1,2,3] is an instance of list). It's a really bad idea to override it.
I'm not sure what you're trying to do with the end() function. It seems do very little, and what it does is not related to its name...
You create an oldlist list but never really do anything with it. What is it supposed to to ?
With that in mind, here is my proposition:
def main():
# I like to put the main code in a "main" function, so that it can be at the top
# of the file. We'll call main() from the bottom of the file
# Make our program pretty, with a little branding
print("===== Number Sorter 9000 =====")
# 'numbers' is not the name of anything yet, so we can use it safely
numbers = []
# This will loop forever, unless we tell it to stop. It allows us to skip the
# part where you ask the user for a number of values: Simply enter the values
# one by one, and press enter once last time when done.
while True:
value = input(f"Number {len(numbers)+1} (leave empty to continue): ")
# Decide what to do with the value we received. If it's a number,
# add it to our list, if it's empty, stop collecting numbers
if value:
# Make sure the value is a number ()
value = float(value)
# Add the number to the list
numbers.append(value)
else:
# This will get us out of the number-asking loop
break
print("Number Sorter 9000 will now sort your numbers")
sorted_numbers = bubblesort(numbers)
print("Number Sorter 9000 has sorted your numbers:")
print(sorted_numbers)
def bubblesort(numbers):
# Here I've removed things that were not doing much.
# There are some ways to improve the algorithm itself, but I'll let you do that
for i in range(len(numbers)):
for j in range(0, len(numbers)-i-1):
if numbers[j] > numbers[j+1]:
numbers[j], numbers[j+1] = numbers[j+1], numbers[j]
# We 'return' the result from the function, so that code that calls the
# bubblesort() function can use the result
return numbers
# Lastly, we call the "main" function to get everything started. Without this
# line, nothing happens: We've just explained to the computer how to do some
# stuff, but we haven't asked it to *DO* anything
main()
Well, I hope this was not too much information. I've tried to keep things simple, but feel free to ask if something is not clear

python How to while loop while true , run multiple functions together

def function():
while True:
...omission...(this function is repeated permanently)
i =0
while i < 4:
driver.execute_script("""window.open("URL")""")
driver.switch_to.window(driver.window_handles[-1])
time.sleep(1)
function()
time.sleep(1)
i += 1 #open new tab and run function.
it doesn't work because while true loop is repeated permanently. Is there any ways to run multiple functions together?
https://imgur.com/a/4SIVekS This picture shows what I want
According to your picture, what you want is to launch the function a set number of times (4?), and run those in parrallel.
On a single core, as is the normal behavior, straight up parallel processing is impossible. You need to access other cores and manage a decentralized processing. while is useless there. I'm worried the level of difficulty is over your current skills, but here we go.
The overall flow that you (probably, depends on the actual memory safety of your functions) need is:
- to create a thread pool with the set number of threads for the number of runs you want.
- indicate the function you need to run
- start them, making sure the start itself is non-blocking.
- ensure one functions's processing doesn't impact another's results. race conditions are a common problem.
- gather results, again, in a non-blocking way.
You can use several methods. I highly recommend you read up a lot on the following documentations.
Threading:
https://docs.python.org/3/library/threading.html
Multiprocessing:
https://docs.python.org/3/library/multiprocessing.html
I don't understand your question because I don't understand what your function is supposed to do.
while True:
will always create an infinite loop. "while" is a command that tells python to loop through the following block so long as the expression following it evaluates to True. True always evaluates to True.
It seems like you want to use a conditional, like you do in "while x < 4".
x < 4
...is an expression that evaluates to true when x is less than 4, and false if x is not less than 4. Everything below the line:
while x < 4:
will then run if x is less than 4, and when it's done running that code, it will go back and evaluate if x is less than 4 again, and if it is, run the code again. To include another while loop inside of that loop, that new loop also needs an expression to evaluate. If you want to evaluate the same expression, write it out:
while x < 4:
# do something
while x < 4:
#do more things
# do even more things
# change x at some point, or else you're in an infinite loop.
However, there's no reason to do that specifically, because you're already doing it. All of the code is only running when x < 4, so checking that condition again right there is redundant, and doing it in another loop doesn't make sense. If the inside loop is also incrementing x, then the outside loop won't loop and doesn't need to increment x.
Also, if you want a function to check a condition based on a variable outside the function, you'll want to pass things to that function.

how to use the display command of pdb python module?

display expression: prints out the value of an expression each time it gets changed. This is useful for monitoring the value of variables that get changed in loops. So, suppose the following is the code:
for i in range(100):
for j in range(100):
a=f(i,j)
I know something is wrong with the execution of a=f(i,j) for certain values of i and j. Then, how to use the display command from pdb module to find out the values of i and j when it does not work? I suppose when you use display command, it will display the value of i and j automatically, right? Do I need to combine the c command and b command from pdb module also? Many thanks for your time and attention.
display sets a "watch", so that each time execution stops (whether by completing a next, a step, or an until, or breaking on a continue ), if the value has changed, it will print a message showing the old value and the new value.
Since you know something is wrong with your f function, your easiest solution is to put a break on that function, and set display of the inputs inside that scope. Since you have shown us nothing about f, I don't know what the input variables will be called at that level, but it's likely that it won't be "i" and "j", so set the display appropriately.
I find display most useful for when I'm stepping through code that involves loops, using n or s or c. It keeps track of variables for me, and saves me from having to print the variables I'm interested in. If you know your problem is in f, you'll have to step through the code there yourself, and check all the variables at all the interesting statements. If you find yourself checking a variable repeatedly, that's where you use display.

how can I detect infinite loops in python

I am learning Python 3 and working on an exercise that calls for writing a Python program which simulates/reads a BASIC program as input. I am stuck on writing the part of the Python program that should detect infinite loops. Here is the code I have so far:
def execute(prog):
while True:
location = 0
if prog[location] == len(prog) - 1:
break
return "success"
getT = prog[location].split()
T = len(getT) - 1
location = findLine(prog, T)
visited = [False] * len(prog)
Here, prog is a list of strings containing the BASIC program (strings are in the form of 5 GOTO 30, 10 GOTO 20, etc.).
T is the target string indicated in prog[location].
If the BASIC program has an infinite loop, then my Python program will have an infinite loop. I know that if any line is visited twice, then it loops forever, and my program should return "infinite loop".
A hint given by the tutorial assistant says "initialize a list visited = [False] * len(prog) and change visited[i] to True when prog[i] is visited. Each time through the loop, one value updates in visited[]. Think about how you change a single value in a list. Then think about how you identify which value in visited[] needs to change."
So this is the part I am stuck on. How do I keep track of which strings in prog have been visited/looped through?
I'm not sure I agree that visiting a line twice proves an infinite loop. See the comments under the question. But I can answer the actual question.
Here's the hint:
A hint given by the tutorial assistant says "initialize a list visited = [False] * len(prog) and change visited[i] to True when prog[i] is visited. Each time through the loop, one value updates in visited[]. Think about how you change a single value in a list. Then think about how you identify which value in visited[] needs to change."
This is saying you should have two lists, one that contains the program, and one that contains true/false flags. The second one is to be named visited and initially contains False values.
The Python code is just like the hint says:
visited = [False] * len(prog)
This uses the * list operator, "list repetition", to repeat a length-1 list and make a new list of a longer length.
To change visited[i] to True is simple:
visited[i] = True
Then you can do something like this:
if visited[i]:
print("We have already visited line {}".format(i))
print("Infinite loop? Exiting.")
sys.exit(1)
Note that we are testing for the True value by simply saying if visited[i]:
We could also write if visited[i] == True: but the shorter form is sufficient and is customary in the Python community. This and other customary idioms are documented here: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html
For a program this small, it's not too bad to keep two lists like this. For larger and complex programs, I prefer to keep everything together in one place. This would use a "class" which you might not have learned yet. Something like this:
class ProgramCode(object):
def __init__(self, statement):
self.code = statement
self.visited = False
prog = []
with open(input_basic_program_file, "rt") as f:
for line in f:
prog.append(ProgramCode(line))
Now instead of two lists, we have a single list where each item is a bit of BASIC code and a visited flag.
P.S. The above shows an explicit for loop that repeatedly uses .append() to add to a list. An experienced Python developer would likely use a "list comprehension" instead, but I wanted to make this as easy to follow as possible.
Here's the list comprehension. Don't worry if it looks weird now; your class will teach this to you eventually.
with open(input_basic_program_file, "rt") as f:
prog = [ProgramCode(line) for line in f]
I know of no automatic way of infinite loop detection in Python, but by using divide and conquer methods and testing individual functions, you can find the offending function or block of code and then proceed to debug further.
If the Python program outputs data, but you never see that output, that's a good indicator you have an infinite loop. You can test all your functions in the repl, and the function that does "not come back" [to the command prompt] is a likely suspect.
You can write output under a debug variable of some sort, to be shut off when everything works. This could be a member variable of a Python class to which your code would have to have access to at any time, or you could have a module-scoped variable like Debug=1 and use debug levels to print varying amounts of debug info, like 1 a little, 2 more, 3, even more, and 4 verbose.
As an example, if you printed the value of a loop counter in a suspected function, then eventually that loop counter would keep printing well beyond the count of data (test records) you were using to test.
Here is a combination I came up with using parts of J. Carlos P.'s answer with the hints that steveha gave and using the hint that the instructions gave:
def execute(prog):
location = 0
visited = [False] * len(prog)
while True:
if location==len(prog)-1:
return "success"
findT = prog[location].split()
T = findT[- 1]
if visited[location]:
return "infinite loop"
visited[location] = True
location = findLine(prog, T)

Return continuous result from a single function call

I have got stuck with a problem.
It goes like this,
A function returns a single result normally. What I want is it to return continuous streams of result for a certain time frame(optional).
Is it feasible for a function to repeatedly return results for a single function call?
While browsing through the net I did come across gevent and threading. Will it work if so any heads up how to solve it?
I just need to call the function carry out the work and return results immediately after every task is completed.
Why you need this is not specified in the question, so it is hard to know what you need, but I will give you a general idea, and code too.
You could return in that way: return var1, var2, var3 (but that's not what you need I think)
You have multiple options: either blocking or non-blocking. Blocking means your code will no longer execute while you are calling the function. Non-blocking means that it will run in parallel. You should also know that you will definitely need to modify the code calling that function.
That's if you want it in a thread (non-blocking):
def your_function(callback):
# This is a function defined inside of it, just for convenience, it can be any function.
def what_it_is_doing(callback):
import time
total = 0
while True:
time.sleep(1)
total += 1
# Here it is a callback function, but if you are using a
# GUI application (not only) for example (wx, Qt, GTK, ...) they usually have
# events/signals, you should be using this system.
callback(time_spent=total)
import thread
thread.start_new_thread(what_it_is_doing, tuple(callback))
# The way you would use it:
def what_I_want_to_do_with_each_bit_of_result(time_spent):
print "Time is:", time_spent
your_function(what_I_want_to_do_with_each_bit_of_result)
# Continue your code normally
The other option (blocking) involves a special kind of functions generators which are technically treated as iterators. So you define it as a function and acts as an iterator. That's an example, using the same dummy function than the other one:
def my_generator():
import time
total = 0
while True:
time.sleep(1)
total += 1
yield total
# And here's how you use it:
# You need it to be in a loop !!
for time_spent in my_generator():
print "Time spent is:", time_spent
# Or, you could use it that way, and call .next() manually:
my_gen = my_generator()
# When you need something from it:
time_spent = my_gen.next()
Note that in the second example, the code would make no sense because it is not really called at 1 second intervals, because there's the other code running each time it yields something or .next is called, and that may take time. But I hope you got the point.
Again, it depends on what you are doing, if the app you are using has an "event" framework or similar you would need to use that, if you need it blocking/non-blocking, if time is important, how your calling code should manipulate the result...
Your gevent and threading are on the right track, because a function does what it is programmed to do, either accepting 1 var at a time or taking a set and returning either a set or a var. The function has to be called to return either result, and the continuous stream of processing is probably taking place already or else you are asking about a loop over a kernel pointer or something similar, which you are not, so ...
So, your calling code which encapsulates your function is important, the function, any function, eg, even a true/false boolean function only executes until it is done with its vars, so there muse be a calling function which listens indefinitely in your case. If it doesn't exist you should write one ;)
Calling code which encapsulates is certainly very important.
Folks aren't going to have enough info to help much, except in the super generic sense that we can tell you that you are or should be within in some framework's event loop, or other code's loop of some form already- and that is what you want to be listening to/ preparing data for.
I like "functional programming's," "map function," for this sort of thing. I think. I can't comment at my rep level or I would restrict my speculation to that. :)
To get a better answer from another person post some example code and reveal your API if possible.

Categories

Resources