Calling a function within a function creates loop? - python

I was teaching a python intro course this morning , one of my student came with a question I could not answer
I create a function and within that function, I'm calling the same function and it is looping
def prenom():
print("Nadia")
prenom()
Why?

This is called recursion with no base-case.
You call a function, it (recursively) calls itself and so on. There's no stopping condition, so it will loop forever. This is how infinite loops are created in assembly.

Obviously it will loop.
You haven't set a terminating condition.
Set exit() before calling the function again and you will terminate it successfully (and by termination I mean you will end the program).
Alternatively you may use an if-else condition

Related

Modify a python variable which is inside a loop

I have been trying to make a code that requires modification of a variable that is inside a loop.
a = 1
b = 2
while a<b:
print(b)
now I want to change the value of b while the loop is running.
I have tried to find an answer but could not do so.
Can it be possible that I use this loop with an initial value of b and terminate this loop automatically and start a new one when variable b is modified to something else?
How would that be possible?
Note: I want to modify the var b from outside.
Further Explanation:
The code should be designed in such a way that a variable used to check the condition of the while loop can be modified when the loop is already running.
Let's say a user wants to use this while loop as a function, he passes variables in the function to start the loop. Now he wants to change the variable value (in the above case var b), which is used in the while loop condition.
def start_loop(a,b):
while a<b:
#more codes will be included here
print('The loop is running infinitely')
#call the function
start_loop(1,2)
Consol: The loop is running infinitely....
The loop is running infinitely since the loop is already running I can not ask the while loop to change the value of var b.
I am looking for a solution that can handle this situation.
How a user can modify "var b" from outside as the loop is already running?
Or how can I call the same start_loop() function with the modified value of var b? Doing so should result in the termination of the older loop and the start of this new loop.
I hope I'll find the answer here :)
Thanks.
If you want to do what you said at the same time as running the loop, maybe the content of this link will help you pytho.org.
If the solution is published, visit these links: eval(), exec()

Python keyboard listener

I have used this code and it runs fine. However, there is something weird about it, it's like it's not Python!
The e variable in print_event is used in a way I haven't seen before. It's a regular function that prints whatever is passed to it, but the problem is how it's used, even the event variable that's supposed to be passed as an argument to the parameter e
If you don't pay attention, it seems like the append function returns added values to print_event, instead of appending them, like what the append does in Python.The whole function gets appended to the list of handlers once and then it keeps running until the program terminates,like it's a while True loop.
The code basically starts a keyboard listener and keeps recording key pressed keys, but what happens to the keys is the quesion. The for loop in low level listener doesn't make sense, why iterate through the handlers if it's supposed to record the keys, not read them. Besides, why pass the event? Handlers is a list, not a function, i'm only aware of the assignement operator for initializing variables
Also, if handlers is initialize empty, how does it assign values to items and through them if their memory space isn't allocated and doesn't exist?
I don't seeing any buffer function being called, so how's it working? Python shouldn't look like that
What i'm trying to do is to access the handlers list in real time and process the events
An explanation would be appreciated. Thanks in advance
Are you asking about Function Variables?
If yes, you can pass around functions like any other variable, and call them later by a different name.
EG:
def hi(string):
print(string)
fns = [hi, hi]
for fn in fns:
fn('hello')
If that remains puzzling, perhaps you could step through it with a debugger to make the idea seem more concrete.

Why doesn't exec("break") work inside a while loop

As the question asks, why doesn't the below code work:
while True:
exec("break")
I am executing the above in pycharm via python 3.5.2 console.
I initially thought it was a context issue but after reading the documentation, I haven't come closer to understanding why this error ocurs.
SyntaxError: 'break' outside loop
Thanks in advance :)
EDIT: I understand that it works without exec() by the way, I'm curious why it won't work with exec (as my circumstances required it) - comprehensive answers welcome.
This is because exec() is ignorant to your surrounding while loop. So the only statement that exec() sees in your example is break. Instead of using exec("break"), simply use break as is.
The only access the exec() function has to its surrounding scope, is the globals() and locals() dictionaries. The documentation for exec() provides some insight into how exec() works:
This function supports dynamic execution of Python code. object must be either a string or a code object. If it is a string, the string is parsed as a suite of Python statements which is then executed (unless a syntax error occurs). [1] If it is a code object, it is simply executed. In all cases, the code that’s executed is expected to be valid as file input (see the section “File input” in the Reference Manual). Be aware that the return and yield statements may not be used outside of function definitions even within the context of code passed to the exec() function. The return value is None.
In all cases, if the optional parts are omitted, the code is executed in the current scope. If only globals is provided, it must be a dictionary, which will be used for both the global and the local variables. If globals and locals are given, they are used for the global and local variables, respectively. If provided, locals can be any mapping object. Remember that at module level, globals and locals are the same dictionary. If exec gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.
If the globals dictionary does not contain a value for the key builtins, a reference to the dictionary of the built-in module builtins is inserted under that key. That way you can control what builtins are available to the executed code by inserting your own builtins dictionary into globals before passing it to exec().
The exec statement runs a bit of code independently from the rest of your code.
Hence, the line:
exec("break")
is tantamount to calling break out of nowhere, in a script where nothing else happens, and where no loop exists.
The right way to call the break statement is:
while True:
break
EDIT
The comment from Leaf made me think about it.
Actually, the exec statement does not run the code out of nowhere.
>>> i = 12
>>> exec("print(i)")
12
A better answer, as far as I understand, is that exec runs a piece of code in the same environment as the original code, but independently from it.
This basically means that all the variables that exist at the moment exec is called can be used in the code called by exec. But the context is all new, so return, break, continue and other statements that need a context, will not work, unless the right context is created.
By the way, I kept the word "statement" when talking about exec, but it has become a function in Python3, the same way print did.
exec() is a function. Assuming for simplicity that a function call constitutes a statement of its own (just like in your example), it may end in one of the following ways:
the function returns normally - in this case the next statement according to the control flow is executed;
an exception is raised/thrown from the function - in this case the matching except clause on the call stack (if any) is executed
the entire program is terminated due to an explicit call to exit() or equivalent - there is nothing to execute.
Calling a break (as well as return or yield) from inside exec() would modify the program execution flow in a way that is incompatible with the described aspect of the function call semantics.
Note that the documentation on exec() contains a special note on the use of return and yield inside exec():
Be aware that the return and yield statements may not be used outside
of function definitions even within the context of code passed to the
exec() function.
A similar restriction applies to the break statement (with the difference that it may not be used outside loops), and I wonder why it was not included in the documentation.
exec is a built in function ,
Python insists that break should happen inside the loop,not inside a function
What is happening in your code is you are putting break inside a function which is exec you can't break out of a loop by executing a
break within a function that's called inside the loop.
For Ex
>>> def func():
break
SyntaxError: 'break' outside loop
>>>
Try break without exec():
while True:
break
exec function runs code inside a code and that means it runs out of nowhere! So, your while loop doesn't catch it. Your file is <stdin>. exec runs on another file called <string>. it doesn't recognize it where are you trying to break a loop where there is not a loop. So, your code is this:
while True:
exec("break")
It should be like this:
while True:
break

Python: break out of for loop calling a function [duplicate]

This question already has answers here:
Break out of a while loop using a function
(3 answers)
Closed 7 years ago.
I need to break out of a for loop according to the result obtained after calling a function. This is an example of what I'm after (does not work obviously):
def break_out(i):
# Some condition
if i > 10:
# This does not work.
return break
for i in range(1000):
# Call function
break_out(i)
Of course this is a very simple MWE, my actual function is much bigger which is why I move it outside of the for loop.
This answer says it is not possible and I should make the function return a boolean and add an if statement inside the for loop to decide.
Since it's a rather old question and it didn't get much attention (also, it's applied to while loops), I'd like to re-check if something like this is possible.
No, it's not (reasonably) possible. You could raise an exception, I suppose, but then you'll have to catch it with a try/except statement outside the loop.
Since OP has expressed curiosity about this, I'm going to explain why Python doesn't allow you to do this. Functions are supposed to be composable elements. They're meant to work in different contexts.
Allowing a function to break out of a loop has two separate problems:
Client code might not expect this behavior.
What if there is no loop?
For (1), if I read some code like this:
import foo # some library I didn't write
while condition:
foo.bar()
assert not condition
I reasonably assume the assertion will not fire. But if foo.bar() was able to break out of the loop, it could.
For (2), perhaps I wrote this somewhere else:
if condition:
foo.bar()
It's not clear what that should do if foo.bar() tries to break out of the loop, since there is no loop.
Rather than return break, return a value that forces a break condition. To extend your example:
def break_out(i):
# Some condition
return i > 10 # Returns `True` if you should break from loop.
for i in range(1000):
# Call function
if break_out(i):
break
# Insert the rest of your code here...

Python question on threads

I am trying to run two thread concurrently on two function like the ones listed below :
import threading
def functionA():
for i in range(5):
print "Calling function A"
def functionB():
for i in range(5):
print "Calling function B"
t1 = threading.Thread(functionA())
t2 = threading.Thread(functionB())
t1.start()
t2.start()
Results :
Calling function A
Calling function A
Calling function A
Calling function A
Calling function A
Calling function B
Calling function B
Calling function B
Calling function B
Calling function B
But unfortunately after trying out several times. I am not able to get the result
The Desired results :
Calling function A
Calling function B
Calling function A
Calling function B
Calling function A
Calling function B
Calling function A
Calling function B
Calling function A
Can someone guide me so that the two threads can run concurrently at the same time and produce the desired results. Thanks in advance.
You're calling the functions and pass the result to the Thread constructor instead of passing the function. Also, you must use the target argument (instead of the unused group which comes first). Just use Thread(target=functionA) and Thread(target=functionB). Note the lack of parens after the functions.
Note that you still won't get multithreading in CPython, but that's a different question.
#delnan already answered how to use Thread correctly, so I'm going to focus on what you want the desired output to be.
You will most likely NOT be able to get the desired output that you want. The timing of when threads execute is not guaranteed, especially in Python. The OS scheduling can impact when each thread gets to run. When running two threads like this, you're effectively saying "these two pieces of work do not depend on the order of each other and can be run at the same time".
You could get output like this:
a,a,b,b,a,a,b,b,a,b
Or:
a,b,b,b,b,b,a,a,a,a
It will change on every execution of your program. Do NOT rely on the order of thread execution!
Threading in Python is a dangerous beast. No two threads are ever running within Python at exactly the same time. Read up on the Global Interpret Lock for more information.
You are writing a new thread, the operating system takes care of how threads use the processor. That's why the sorting isn't regular. You should use another varible to define which function has turn. But still a bad idea.
It will be great if python 3.2 is release as looking at the link below there are built in libraries that can help me achieve my goals.
http://docs.python.org/dev/library/concurrent.futures.html
But nevertheless will look into the alternative provided by other helpful memebers. Thanks for the help provided once again.

Categories

Resources