For loop in python initializes an outer variable on each iteration - python

I can't understand why the following codes gives different results:
from datetime import datetime
def foo():
return {datetime.now() : True}
a = {}
a.update(foo())
a.update(foo())
a.update(foo())
And:
a = {}
for i in xrange(3):
a.update(foo())
In the former a ends up with three elements, while in the later a ends up with just one element (from the last iteration).

Just your luck. The second code is likely to execute in a single millisecond (or microsecond, depending on your OS), and give three identical datetimes, first is less likely to do so (on your system/your way of executing code). Keep trying, you might end up with two elements. Don't write code that depends on luck.

The number of elements you end up with will depend on how many calls to foo Python executes within the granularity of datetime.now().
If you're running this in an interactive console then between statements executed at the prompt the console will perform housekeeping (for example, displaying the >>> prompt) that will significantly delay the next statement, whereas for the for loop the loop will be executed in its entirety before the console does anything.

Related

Add time delay between every statement of python code

Is there an easy way to execute time delay (like time.sleep(3)) between every statement of Python code without having to explicitly write between every statement?
Like in the below Python Script which performs certain action on SAP GUI window. Sometimes, the script continues to the next statement before the previous statement is complete. So, I had to add a time delay between every statement so that it executes correctly. It is working with time delay, but I end up adding time.sleep(3) between every line. Just wondering if there is a better way?
import win32com.client
import time
sapgui = win32com.client.GetObject("SAPGUI").GetScriptingEngine
session = sapgui.FindById("ses[0]")
def add_record(employee_num, start_date, comp_code):
try:
time.sleep(3)
session.findById("wnd[0]/tbar[0]/okcd").text = "/npa40"
time.sleep(3)
session.findById("wnd[0]").sendVKey(0)
time.sleep(3)
session.findById("wnd[0]/usr/ctxtRP50G-PERNR").text = employee_num
time.sleep(3)
session.findById("wnd[0]").sendVKey(0)
time.sleep(3)
session.findById("wnd[0]/usr/ctxtRP50G-EINDA").text = start_date
time.sleep(3)
session.findById("wnd[0]/usr/tblSAPMP50ATC_MENU_EVENT/ctxtRP50G-WERKS[1,0]").text = comp_code
time.sleep(3)
session.findById("wnd[0]/usr/tblSAPMP50ATC_MENU_EVENT/ctxtRP50G-PERSG[2,0]").text = "1"
time.sleep(3)
session.findById("wnd[0]/usr/tblSAPMP50ATC_MENU_EVENT/ctxtRP50G-PERSK[3,0]").text = "U1"
time.sleep(3)
session.findById("wnd[0]/usr/tblSAPMP50ATC_MENU_EVENT").getAbsoluteRow(0).selected = True
time.sleep(3)
return "Pass"
except:
return "failed"
The right way to do what you asked for is almost certainly to use the debugger, pdb.
The right way to do what you want is probably something completely different: find some signal that tells you that the step is done, and wait for that signal. With problems like this, almost any time you pick will be way, way too long 99% of the time, but still too short 1% of the time. That signal may be joining a thread, or waiting on a (threading or multiprocessing) Condition, or getting from a queue, or awaiting a coroutine or future, or setting the sync flag on an AppleEvent, or… It really depends on what you're doing.
But if you really want to do this, you can use settrace:
def sleeper(frame, event, arg):
if event == 'line':
time.sleep(2)
return sleeper
sys.settrace(sleeper)
One small problem is that the notion of line used by the interpreter may well not be what you want. Briefly, a 'line' trace event is triggered whenever the ceval loop jumps to a different lnotab entry (see lnotab_notes.txt in the source to understand what that means—and you'll probably need at least a passing understanding of how bytecode is interpreted, at least from reading over the dis docs, to understand that). So, for example, a multiline expression is a single line; the line of a with statement may appear twice, etc.1
And there's probably an even bigger problem.
Sometimes, the script continues to next step before the previous step is fully complete.
I don't know what those steps are, but if you put the whole thread to sleep for 2 seconds, there's a good chance the step you're waiting for won't make any progress, because the thread is asleep. (For example, you're not looping through any async or GUI event loops, because you're doing nothing at all.) If so, then after 2 seconds, it'll still be just as incomplete as it was before, and you'll have wasted 2 seconds for nothing.
1. If your notion of "line" is closer to what's described in the reference docs on lexing and parsing Python, you could create an import hook that walks the AST and adds an expression statement with a Call to time.sleep(2) after each list element in each body with a module, definition, or compound statement (and then compiles and execs the result as usual).
Anything you want to happen in a program has to be explicitly stated - this is the nature of programming. This is like asking if you can print hello world without calling print("hello world").
I think the best advice to give you here is: don't think in terms of "lines", but think in term of functions.
use debugging mode and watch each and every line executing line by line.

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.

Python Print Order

This is probably a dumb question, but I'm new to programming and I have a recursive function set up that I'm trying to figure out. For any print function in Python, is it necessarily true that lines are printed in the order that they are written in the script OR for larger outputs, is it possible that smaller length outputs can get printed first in the console even though the print statement is later in the code (maybe due to some memory lag)?
Example:
def test_print():
#don't run this, but was meant for scale. Is there any chance the 1 would print before the list of lists?
print([[i for i in range(10000)] for j in range(10000)])
print(1)
Print statements pile output into stdout in the order the code was written. Top to bottom. It isn't possible any other way because that's the way the code is interpreted. Memory lag doesn't play any role here because the output to your console is a line for line rendition of the data that was piled into stdout. And the order the data was written to it can't change, so you'll maintain chronology. Of course, you can always play around with the how the print function itself works. But I wouldn't recommend tampering with standard library functions.
As said above, print() function is executed in the order which they are in your code. But you yourself can change the order in which you want it executed, after all you have every right to instruct the code to do whatever you want.
You'll always get the same order in the output as the order you execute print() functions in Python.

Ignore pycharm breakpoint for first N hits

I'm trying to ignore a specific breakpoint in pycharm for the first N times it hits. Since I'm looking to set it to something like 10k, manually doing this is not an option. I found the expanded options for breakpoints, including the condition field, but I'm not sure how I can craft a condition which takes into account how many times the breakpoint has been hit. Thanks.
You can just create a variable in Python specifically for the breakpoint counting purpose, which you increment every time you you go past the break point line. Then just use that variable in your break point condition (i.e. breakpoint_count == 10000).
Update
If you can't add new code into the real python code you can use the breakpoint condition:
eval("exec('try:\\n x += 1\\nexcept NameError:\\n x = 1') or x == 10000")
What this does is execute a try statement which increments a variable or creates it if it doesn't exist. Then evaluates that along with a statement checking if the variable has been incremented enough times yet with that being your ending condition. Note, the exec is required to run the try, but the eval is needed to "return" the condition to PyCharm. This is absurdly hacky, but it works for your case!

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