Handling dependency of functions in python - python

I want to write a script for automation of sequence of events, where the execution of the next sequence depends upon the success of the previous step. There are basically 8 functions which I want to call onne by one and if one fails, I want to exit at that point. So how can i handle this in python?

Basic if, and elif statements can overcome your needs.
Say you had a function that returned a variable.
def f(z):
data = z
return data
You can analyse the result with a if. Assign a new variable to the function f:
x = f(0)
if x == 0:
#do something
So if x is equal to 0, continue with code. But what is c = 1?
import os
x = f(1)
if c != 0:
os._exit(0)
os._exit(0) quits the program.

I highly recommend taking a look at pytest (or one of the other Python testing frameworks).
This guide should get you up and running quickly:
http://pytest.org/latest/getting-started.html

Related

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.

Python (preferably 3) equivalent to INKEY$

I am using Python 3.6.4 on a Windows 7 system (I have other systems like Win 10 and Android but this is my starting point).
INKEY$, for those not familiar with BASIC (pretty much any flavor), is a function that checks the keyboard buffer, returning that data as a string or a null/empty value ("") if there was no data, and clears the buffer. The length of the returned string depends on the data in the buffer, normally 0, 1, or 2 on a single keystroke (a fast typist could fill the small buffer between checks in the old days). The Enter key was not needed (unless that was what you were looking for) or processed and the program did not pause unless programmed to do so.
Pauser:
a$=""
while a$=""
a$=inkey$
wend
Flow Interrupter:
a=0
while a < 1000
a=a+1
print a
a$=inkey$
if a$<>"" then exit while
wend
Quick parser:
a$=inkey$
if a$<>"" then
rem process input
rem like arrow keys/a w s z for directional movement
rem useful for games and custom editors
end if
I am wanting to know if Python has a simple cross platform function (ie not 10+ lines of code unless in an importable module/class) that is the equivalent to the INKEY$ function? Also, I am not wanting to import the gaming module(s), just want an INKEY$ function equivalent (simple, straight forth, small).
import inkey
a = inkey.inkey()
Update #1:
After I installed the readchar module and corrected a reported error by Python (stdout.write(a) needs to be stdout.write(str(a)) as the variable 'a' appears to be returned as a byte string from readchar() function) when using the code listed by Mr. Stratton below, I only get continuous stream of b'\xff' and console echoed characters if there where any keypresses.
Stripping it down to use only the function doesn't help either:
from readchar import readchar
from sys import stdout
import os
#I like clear screens, and I can not lie
os.system('cls') # For Windows
#os.system('clear') # For Linux/OS X
def inkey():
"INKEY$ function"
return readchar()
#let the processing hit the floor, elsewhere
b=0
step = 1
while b < 1000:
b = b + step
print(b)
#convert bytes to integers
a = int.from_bytes(inkey(), "big")
#remember I keep getting b'\xff' (255) when buffer is empty
if chr(a) == "a":
step = step - 1
a = 255 #don't stop
if chr(a) == "l":
step = step + 1
a = 255 #don't stop
if a != 255:
break
It is supposed to count b from 0 to 999, stopping on almost any keypress, 'a' decreases the step, 'l' increases it. Instead, it prints the keypress either before or after the value of b depending on timing and continues until b = 1000. Nothing I did made a difference.
While the Pauser function can be replaced with an input() (i = input("Press Enter key to continue")) the other two variants can't be changed so easily it seems.
The closest to what you’re looking for is probably the readchar library.
Here’s an example that resembles the old BASIC logic:
from readchar import readchar
from sys import stdout
a = ' '
while ord(a) not in [3,24,27]:
a = readchar()
stdout.write(a)
stdout.flush()
if ord(a) == 13:
stdout.write("\n")
Those numbers that break the loop are CTRL-C, CTRL-X, and ESC respectively. The number 13 is the carriage return; the example writes a line feed following each carriage return to avoid overwriting text.
The equivalant to the old ASC(A$) in BASIC is ord(a) in Python. (And CHR$(A$) is chr(a).)
Note that this will block on reading. If no keypress is waiting, Python will stop on the line a = readchar() until a key is pressed. To get the full effect of BASIC’s INKEY$, you’ll need to verify that some data is waiting before reading it. You can do this using Python’s select library.
from readchar import readchar
from sys import stdin, stdout
from select import select
def inkey():
if select([stdin,],[],[],0.0)[0]:
return readchar()
return ''
a = ''
timer = 0
while a != 'Q':
a = inkey()
if a != '':
stdout.write(a)
stdout.flush()
if ord(a) == 13:
stdout.write("\n")
timer += 1
if timer > 1000000:
print("Type faster, human!")
timer = 0
This defines an inkey function and returns the empty string if nothing is waiting. If something is reading, it returns readchar(). Every 1,000,000 times through the loop, it tells the human on the other end to type faster.
In this version, it quits on a capital letter “Q”, as this does not block CTRL-C, CTRL-X, and ESC from breaking out of the program altogether.
This may have trouble if you’re using Windows, as select.select at least at one time did not work on Windows. I have no means of testing that, however.
You may also want to look at pynput if you don’t need it to look exactly like BASIC. The canonical means to do this in Python is probably to set up an event that calls a function or method. Your script goes on doing its thing, and if that function (or method) is invoked, it cancels or modifies the action of the main loop.

pdb step into a function when already in pdb mode

When in pdb mode I often want to step into a function. Here is a situation that illustrates what I might do. Given the code:
def f(x):
print('doing important stuff..')
result = g(x) + 2
return result
def g(x):
print('some cool stuff going on here, as well')
0 / 0 # oops! a bug
return x + 5
Now, assume I set a breakpoint between the print('doing important stuff...') and result = g(x) + 2. So now, f(x) looks like this:
def f(x):
print('doing important stuff..')
__import__('pdb').set_trace() # or something similar..
result = g(x) + 2
return result
And then I call the function f(x) with x=5, expecting to get a result 12. When called, I end up in an interactive pdb session on the second line in f. Hitting n will give me the error (in this case a ZeroDivisionError). Now, I want to step into the g(x) function interactively to see what the error might be. Is it somehow possible to do that while not "moving" the breakpoint in g(x) and re-running everything? I simply want to enter the function g on the first line while still being in pdb mode.
I've searched for previous SO questions and answers + looked up the documentation and still haven't found anything that addresses this particular situation.
You're probably looking for the s command: it s-teps into the next function.
While in debugging mode, you can see all available commands using h (help). See also the docs.

How to test while-loop (once) with nosetest (Python 2.7)

I'm pretty new to this whole "programming thing" but at age 34 I thought that I'd like to learn the basics.
I unfortunately don't know any python programmers. I'm learning programming due to personal interest (and more and more for the fun of it) but my "social habitat" is not "where the programmers roam" ;) .
I'm almost finished with Zed Shaws "Learn Python the Hard Way" and for the first time I can't figure out a solution to a problem. The last two days I didn't even stumble upon useful hints where to look when I repeatedly rephrased (and searched for) my question.
So stackoverflow seems to be the right place.
Btw.: I lack also the correct vocabular quite often so please don't hesitate to correct me :) . This may be one reason why I can't find an answer.
I use Python 2.7 and nosetests.
How far I solved the problem (I think) in the steps I solved it:
Function 1:
def inp_1():
s = raw_input(">>> ")
return s
All tests import the following to be able to do the things below:
from nose.tools import *
import sys
from StringIO import StringIO
from mock import *
import __builtin__
# and of course the module with the functions
Here is the test for inp_1:
import __builtin__
from mock import *
def test_inp_1():
__builtin__.raw_input = Mock(return_value="foo")
assert_equal(inp_1(), 'foo')
This function/test is ok.
Quite similar is the following function 2:
def inp_2():
s = raw_input(">>> ")
if s == '1':
return s
else:
print "wrong"
Test:
def test_inp_2():
__builtin__.raw_input = Mock(return_value="1")
assert_equal(inp_1(), '1')
__builtin__.raw_input = Mock(return_value="foo")
out = StringIO()
sys.stdout = out
inp_1()
output = out.getvalue().strip()
assert_equal(output, 'wrong')
This function/test is also ok.
Please don't assume that I really know what is happening "behind the scenes" when I use all the stuff above. I have some layman-explanations how this is all functioning and why I get the results I want but I also have the feeling that these explanations may not be entirely true. It wouldn't be the first time that how I think sth. works turns out to be different after I've learned more. Especially everything with "__" confuses me and I'm scared to use it since I don't really understand what's going on. Anyway, now I "just" want to add a while-loop to ask for input until it is correct:
def inp_3():
while True:
s = raw_input(">>> ")
if s == '1':
return s
else:
print "wrong"
The test for inp_3 I thought would be the same as for inp_2 . At least I am not getting error messages. But the output is the following:
$ nosetests
......
# <- Here I press ENTER to provoke a reaction
# Nothing is happening though.
^C # <- Keyboard interrupt (is this the correct word for it?)
----------------------------------------------------------------------
Ran 7 tests in 5.464s
OK
$
The other 7 tests are sth. else (and ok).
The test for inp_3 would be test nr. 8.
The time is just the times passed until I press CTRL-C.
I don't understand why I don't get error- or "test failed"-meassages but just an "ok".
So beside the fact that you may be able to point out bad syntax and other things that can be improved (I really would appreciate it, if you would do this), my question is:
How can I test and abort while-loops with nosetest?
So, the problem here is when you call inp_3 in test for second time, while mocking raw_input with Mock(return_value="foo"). Your inp_3 function runs infinite loop (while True) , and you're not interrupting it in any way except for if s == '1' condition. So with Mock(return_value="foo") that condition is never satisfied, and you loop keeps running until you interrupt it with outer means (Ctrl + C in your example). If it's intentional behavior, then How to limit execution time of a function call in Python will help you to limit execution time of inp_3 in test. However, in cases of input like in your example, developers often implement a limit to how many input attempts user have. You can do it with using variable to count attempts and when it reaches max, loop should be stopped.
def inp_3():
max_attempts = 5
attempts = 0
while True:
s = raw_input(">>> ")
attempts += 1 # this is equal to "attempts = attempts + 1"
if s == '1':
return s
else:
print "wrong"
if attempts == max_attempts:
print "Max attempts used, stopping."
break # this is used to stop loop execution
# and go to next instruction after loop block
print "Stopped."
Also, to learn python I can recommend book "Learning Python" by Mark Lutz. It greatly explains basics of python.
UPDATE:
I couldn't find a way to mock python's True (or a builtin.True) (and yea, that sounds a bit crazy), looks like python didn't (and won't) allow me to do this. However, to achieve exactly what you desire, to run infinite loop once, you can use a little hack.
Define a function to return True
def true_func():
return True
, use it in while loop
while true_func():
and then mock it in test with such logic:
def true_once():
yield True
yield False
class MockTrueFunc(object):
def __init__(self):
self.gen = true_once()
def __call__(self):
return self.gen.next()
Then in test:
true_func = MockTrueFunc()
With this your loop will run only once. However, this construction uses a few advanced python tricks, like generators, "__" methods etc. So use it carefully.
But anyway, generally infinite loops considered to be bad design solutions. Better to not getting used to it :).
It's always important to remind me that infinite loops are bad. So thank you for that and even more so for the short example how to make it better. I will do that whenever possible.
However, in the actual program the infinite loop is how I'd like to do it this time. The code here is just the simplified problem.
I very much appreciate your idea with the modified "true function". I never would have thought about that and thus I learned a new "method" how tackle programming problems :) .
It is still not the way I would like to do it this time, but this was the so important clue I needed to solve my problem with existing methods. I never would have thought about returning a different value the 2nd time I call the same method. It's so simple and brilliant it's astonishing me :).
The mock-module has some features that allows a different value to be returned each time the mocked method is called - side effect .
side_effect can also be set to […] an iterable.
[when] your mock is going to be
called several times, and you want each call to return a different
value. When you set side_effect to an iterable every call to the mock
returns the next value from the iterable:
The while-loop HAS an "exit" (is this the correct term for it?). It just needs the '1' as input. I will use this to exit the loop.
def test_inp_3():
# Test if input is correct
__builtin__.raw_input = Mock(return_value="1")
assert_equal(inp_1(), '1')
# Test if output is correct if input is correct two times.
# The third time the input is corrct to exit the loop.
__builtin__.raw_input = Mock(side_effect=['foo', 'bar', '1'])
out = StringIO()
sys.stdout = out
inp_3()
output = out.getvalue().strip()
# Make sure to compare as many times as the loop
# is "used".
assert_equal(output, 'wrong\nwrong')
Now the test runs and returns "ok" or an error e.g. if the first input already exits the loop.
Thank you very much again for the help. That made my day :)

Forcing a callback to be executed first

I've got the following codesnippet in a program using secure multiparty computation:
c = self.runtime.open(b) # open result
c.addCallback(self.determine)
j = self.compute(i)
return j
Now the function determine sets a boolean to either false or true, depending on the value of c. This boolean is then used by the function compute.
I thought that callbacks are always executed first, before the rest of the program is. However, I'm getting an error from compute that the boolean is undefined.
How can I force the callback to be executed before compute is executed?
Because I'm working within a secure multiparty computation framework, I have to work with callbacks since the value for c is a shared secret. However, the problem would also appear without secret shares I think. The language is Python.
The code for determine and compute would be something like this:
def determine(c):
global computeB
computeB = False
if c == 1:
computeB = True
else:
computeB = False
return c
def compute(i):
if computeB:
do this
else:
do this
return result
The callback gets executed when it gets executed. There is no point in "making" it execute earlier.
I guess you are dealing with twisted so heres a tutorial http://krondo.com/?page_id=1327 but it is helpfull even for understanding async programming in general, which you obviously need.
I'm not a pro in async but I think you want to yield your first function and tell your routine to wait before it goes on.
yield self.runtime.open(b) # open result
j = self.compute(i)
return j

Categories

Resources