Return values from subprogram - python

I've created a subprogram called DEVICE_ON in which I've defined some of these statements
if j == 2:
print('shutdown')
# Run command.
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(shutdown)
var_colonna_2=data_array[i][j]
return var_colonna_2
var_colonna_2 is a string value (could be "X" or "V") and in this subprogram I have 8 return value (one for each var_colonna)
Now in the main programm I'm calling another subprogramm defined as:
CHECK_TEST(var_colonna_1, var_colonna_2, var_colonna_3, var_colonna_4,
var_colonna_5, var_colonna_6, var_colonna_7, var_colonna_8)
this CHECK_TEST of course is executed after the DEVICE_ON.
So basically In the main programm I have something like:
DEVICE_ON(ssh,data_array, i, j)
CHECK_TEST(var_colonna_1,var_colonna_2, var_colonna_3, var_colonna_4,
var_colonna_5, var_colonna_6, var_colonna_7, var_colonna_8)
I was expecting that, since in DEVICE_ON, I've defined the return value for var_colonna_x (x=1 to 8), automatically the value of each var_colonna was updated and received from CHECK_TEST for internal computation,but right now it always sees 0.
I've also tried with the debug.It seems that the values are passed, but I still don't get why they are not seen in the next subprogram.

I've understand where my mistake was.
Basically the retur function is ok but in the main I was missing something like:
var_colonna_1=CHECK_TEST(var_colonna_1, var_colonna_2, var_colonna_3, var_colonna_4, var_colonna_5, var_colonna_6, var_colonna_7, var_colonna_8)

Related

How do I run a conditional statement "only once" and every time it changes?

I might be asking a simple question. I have a python program that runs every minute. But I would like a block of code to only run once the condition changes? My code looks like this:
# def shortIndicator():
a = int(indicate_5min.value5)
b = int(indicate_10min.value10)
c = int(indicate_15min.value15)
if a + b + c == 3:
print("Trade posible!")
else:
print("Trade NOT posible!")
# This lets the processor work more than it should.
"""run_once = 0 # This lets the processor work more than it should.
while 1:
if run_once == 0:
shortIndicator()
run_once = 1"""
I've run it without using a function. But then I get an output every minute. I've tried to run it as a function, when I enable the commented code it sort of runs, but also the processing usage is more. If there perhaps a smarter way of doing this?
It's really not clear what you mean, but if you only want to print a notification when the result changes, add another variable to rembember the previous result.
def shortIndicator():
return indicate_5min.value5 and indicate_10min.value10 and indicate_15min.value15
previous = None
while True:
indicator = shortIndicator()
if previous is None or indicator != previous:
if indicator:
print("Trade possible!")
else:
print("Trade NOT possible!")
previous = indicator
# take a break so as not to query too often
time.sleep(60)
Initializing provious to None creates a third state which is only true the first time the while loop executes; by definition, the result cannot be identical to the previous result because there isn't really a previous result the first time.
Perhaps also notice the boolean shorthand inside the function, which is simpler and more idiomatic than converting each value to an int and checking their sum.
I'm guessing the time.sleep is what you were looking for to reduce the load of running this code repeatedly, though that part of the question remains really unclear.
Finally, check the spelling of possible.
If I understand it correctly, you can save previous output to a file, then read it at the beginning of program and print output only if previous output was different.

Recalling a function iteratively

I have a question about recalling my function within a loop.
Below is my code:
List_new = myfunction()
for items in List_new:
if(my condition is TRUE):
Execute some commands
if(my condition is FALSE):
recall myfunction()
My problem is that I am loading "List_new" using myfunction(). How can I change "List_new" iteratively when my condition is False. I want to reload the function especially when the condition is FALSE. This means I keep calling the function until it is false and then execute the final output from myfunction().
Thank you in advance for your help.
I am going to assume the list generated by myfunction() is a constant size.
You can use a while loop:
List_new = myfunction()
index=0
while index < len(List_new):
items = List_new[index]
if(my condition is TRUE):
#Execute some commands
i+=1
if(my condition is FALSE):
List_new = myfunction()
Keep in mind that this solution will have an infinite loop if myfunction() continuously generates false values. If you can guarantee that all values will eventually be True then it should always terminate.

How to get the the "Error" message printed in this situation because the "else" statement doesn't work?

Write the program that reads in input three integers a, b and c. If the integer c is equal to 1, then the program displays on output (prints) the value of a + b; if c is 2 then the program displays the value of a-b; if c is equal to 3 then the output will be the value of ab. Finally, if the value 4 is assigned to c, then the program displays the value of a^2 + ba. If c contains another value, the program displays the message "Error"
a = int(input())
b = int(input())
c = int(input())
if c == 1:
print(a + b)
if c == 2:
print(a - b)
if c == 3:
print(a * b)
if c == 4:
print(a**2 + b*a)
else:
print('Error')
Seems like you got it, just make use of elif instead of a chain of ifs, you can also add a message inside input('Here') that will be printed when prompting for an input
a = int(input("Enter a number: ))
b = int(input("Enter a number: ))
c = int(input("Enter a number: ))
if c == 1 :
print(a + b)
elif c == 2 :
print(a - b)
elif c == 3 :
print(a * b)
elif c == 4 :
print(a**2 + b*a)
else:
print('Error')
Your ifs work, but you have somewhat misaligned the logic.
Use if elif and else
if c==something:
print("this")
elif c==something_else:
print("that")
else:
print("error")
After the first if statement, you should use elif, which is short for "else if". There is no error message because there is no error, you just have your logic wrong. The compiler is treating every if statement independently, so else runs as long as c is not 4.
You're nearly there. The main problem with your program is your if statements are independent, where the problem statement suggests they should not be. Change them for elif statements, which will mean your Error branch only executes when c evaluates to an integer which is not in the set {1, 2, 3, 4}.
Problem 1: program has (possibly) poor control flow
In most programming languages, the if statement is a basic construct used to execute a block of code conditionally if an expression is true. In the following Python-like pseudocode, the code behind the if block is only executed if the value obtained by evaluating EXPRESSION is true:
if EXPRESSION:
# Do something only if EXPRESSION is true
# Execution continues here after the "if" block irrespective of
# whether EXPRESSION was true and the body of the "if" statement
# was executed.
You can augment if statements with else branches. In this case, we execute the body of the if statement if EXPRESSION evaluates to true, and we execute the other arm of the branch (the else branch) if the condition does not evaluate to true (by law of the excluded middle, it's false):
if EXPRESSION:
# As before, control is passed here if EXPRESSION is true.
else:
# If EXPRESSION was false, control is passed to this arm.
# After executing either the "if" arm or the "else" arm, control
# returns to the outer scope outside the "if" statement.
A more complex construct uses an else-if construct to allow you to nest "if" statements. For example, suppose we were implementing a simple call controller which tries to reach someone on their fixed telephone, calls their portable telephone if they are unavailable, and sends an email otherwise. Using the knowledge from above, we might write:
if answers(fixed_telephone):
# Connect to the fixed telephone to communicate
else:
if answers(portable_telephone):
# Connect to the portable telephone to communicate
else:
# Not available on either telephone. Send an email.
As you can imagine, this logic will become complex quickly if there are many nested "if" conditions, which is not unusual in real-world scenarios. Most programming languages provide a construct to pull the nested "if" statements to the top-level. In Python, this is elif, and the equivalent code to the above is:
if answers(fixed_telephone):
# ...
elif answers(portable_telephone):
# ...
else:
# ...
(comments elided for brevity).
In your code as currently written, each of your if statements will be executed independently except the last if c == 4, which will fall to the else branch if c is not equal to 4. As you want the tests of c to be mutually exclusive, i.e. you don't want anything to happen if an earlier case passed, and you only want to print an error if none of the cases were executed, you should use nested if statements, which are best implemented using the above elif language construct.
Problem 2: program assumes well-formed integers
Your program also assumes the values read from STDIN for a, b and c are well-formed integers. If you enter a value which cannot be parsed as an integer, it will crash on the integer conversion in the int(...) call, and will not fall through to reach your print('Error') line. This is an example of Python raising an exception because a problem has been encountered which the interpreter cannot itself recover from. Control flow will not begin executing the if blocks, so the print statement will never be executed.
If you want to fix that issue, you'll need to catch the error returned by the int(...) method when it cannot parse the provided value as an integer. This means learning to catch exceptions, which you can find out more about in the Python docs.
(Hint: Python will raise an built-in exception of type ValueError when the input to int cannot be parsed, so you need to wrap the calls which populate the three variables a, b and c with a try... catch block which catches such an error:
try:
a = int(input())
catch ValueError:
# Implement logic to handle this error, which may include
# returning an error from your function, setting a default
# value, or taking some action. You can optionally take
# some action locally, such as print a log message, and then
# re-raise the exception so it propagates to this method's
# callers (using the "raise" keyword).

If statement called, ignore after even if condition has been met

I have a simple if statement in my code
if len(bootstrap_node_list_recieved_no_dups) >= min_node_to_complete_boot_strap:
print "recieved required nodes"
Basically I want to know if have enough nodes, I only want this to occur once, as the code will still carry on and be run repeatedly so currently this if statement is run every time as I would expect.
Is there a way to code it so the if statement is run, but after it completes once it is never run again?
The >= is required as the input is not a constant.
I hope this is clear, as it's a bit hard to describe.
Update,
i have tried to implement the suggestions but am getting the error
UnboundLocalError: local variable 'flag' referenced before assignment
full code below:
flag = False
def number_of_duplicates_in_list():
number_recieved = len(bootstrap_node_list_recieved)
bootstrap_node_list_recieved_before = len(bootstrap_node_list_recieved_no_dups)
" this method works in O(n^2) time and is thus very slow on large lists"
for i in bootstrap_node_list_recieved:
if i not in bootstrap_node_list_recieved_no_dups:
bootstrap_node_list_recieved_no_dups.append(i)
assert len(bootstrap_node_list_recieved_no_dups) >= bootstrap_node_list_recieved_before
if len(bootstrap_node_list_recieved_no_dups) >= min_node_to_complete_boot_strap and flag is False:
print "recieved required nodes"
flag = True
You could have some flagging variable that is changed when the if statement is first triggered. The below code is a minimal example which will only print the 'Triggered' statement once, even though all numbers above 3 would trigger the statement if the flag was not also being checked.
flag = False
for x in xrange(10):
if x > 3 and flag is False:
print 'Triggered'
flag = True
# Do something else
If you want to do this inside a function, you need to move the flag initialisation into the function as well. Note that re-running the function will reset the flag:
def test_func():
flag = False
for x in xrange(10):
if x > 3 and flag is False:
print 'Triggered'
flag = True
# Do something else
test_func()
To be able to run the function multiple times but only trigger the if statement and change the flag once, you need to link the flag to the function calls. A simple method of doing this is to pass and return the flag on each call:
flag = False
def test_func(flag):
for x in xrange(10):
if x > 3 and flag is False:
print 'Triggered'
flag = True
# Do something else
return flag
flag = test_func(flag)
flag = test_func(flag)
Here, the flag is define outside of the function and passed to each function when called. If not triggered, it passes through without change. If triggered, it is changed and its state passed back outside the function.
Other approaches could be defining a global variable or building a class with the flag as an object variable and accessing it via self.
Define flag to be global within number_of_duplicates_in_list. Otherwise, you can only read it.

"else" statement executed before "if" statement after `undo` is used in Python

I have created the following function that allows the user to change the shape of the Python turtle to an image he/she selects from a file dialog file dialog that pops up when a specific button is pressed:
def TurtleShape(iop = None):
# "iop" is supposed to be an image path
try:
manipulateimage.config(state = NORMAL)
flipButton.config(state = NORMAL)
mirrorButton.config(state = NORMAL)
originalButton.config(state = NORMAL)
resetturtle.config(state = NORMAL)
rotateButton.config(state = NORMAL)
global klob
# The following "if-else" statement uses the "iop" argument's value as the value for "klob" if `iop` is NOT `None`
if iop != None:
klob = iop
print("lmcv")
else:
klob = filedialog.askopenfilename()
print("klobby")
global im
im = Image.open(klob)
pictures.append(im)
edited.clear()
print(im)
im.save(klob + '.gif', "GIF")
register_shape(klob + '.gif')
shape(klob + '.gif')
update()
except:
pass
The above function is also supposed to use the iop argument's value as the turtle's image if it is not None.
Now, consider this situation; you draw a bunch of things, set the turtle to an image, and just when you are about to stamp the image, you accidentally press the button that resets the turtle to its normal shape (yes, that button exists in my program). Oh no! How would you get it back without going through all the steps to open and edit it again? Well, that is where my undoHandler function (shown below) comes in. It just essentially undoes the last function called using many stacks, which I created as deques. It is pretty straightforward if you are proficient in Python:
def undoHandler():
if len(function) > 0 and draw.drawing == True:
undoHandler.handling = True
if not hasattr(undoHandler, "counter"):
undoHandler.counter = 0
undoHandler.counter += 1
# clear the canvas
Clear()
# Pop a point object from function deque
function.pop()
penup()
goto(-200, 100)
pendown()
try:
# Execute everything up to point before last function called
for i in function:
# Set canvas and turtle to previous state
tsd = i.recieveshape()
shape(tsd)
mndf = i.recieveheading()
setheading(mndf)
hk = i.getletterheight()
global letter_height
letter_height = hk
rk = i.getletterwidth()
global letter_width
letter_width = rk
milk = i.getspacewidth()
global space_width
space_width = milk
hw = i.getwidth()
width(hw)
op = i.getcolor()
try:
color(op)
except:
for g in colors:
cp = g.getcolor2()
colormode(255)
color(cp)
# Get function wrapped in Point object and execute it
j = i.getfunction()
j()
# Following is the code block where the issue occurs. Basically, if the function being run is equal to `TurtleShape`, then do the following...
if j.__name__ == "TurtleShape":
# `hfl` is a deque that holds all of the `pictures` deque's contents as it is cleared when the turtle is set to its default state
pictures.extend(hfl)
lmcv = pictures.pop()
pictures.append(lmcv)
try:
# Resize image to previous size if user changes it. Otherwise, skip this.
bun = picwidth.pop()
picwidth.append(bun)
mun = picheight.pop()
picheight.append(mun)
clob = lmcv.resize((int(bun), int(mun)), Image.ANTIALIAS)
except:
clob = lmcv
clob.save(klob + str(undoHandler.counter) + ".gif")
# Use the `clob.save` output from above as source image in `TurtleShape` function (this is where issue occurs)
TurtleShape(klob + str(undoHandler.counter) + ".gif")
print("Undone!")
else:
pass
except:
pass
Basically what happens here is that it takes the function (wrapped in a Point object) from a queue through which the main functions go through as they are called. The functions then get appended to the function deque, after which, when undoHandler is called by the user, the screen gets cleared, and latest value is popped from the function deque so that all the other actions except the last one will be executed again. This issue I am facing occurs specifically in the if j.__name__ == "TurtleShape": code block. Basically, for some reason, when the user chooses to undo the resetting of the turtle to its original shape, it works as it should until the TurtleShape function is executed by the undoHandler. For some reason, when the undoHandler executes the TurtleShape function, even when I give a valid argument for the iop attribute of the TurtleShape function (as you can see in the if j.__name__ == "TurtleShape": code block), the else statement is executed first (i.e. the file dialog comes up instead of continuing from the if statement). Only if the user clicks cancel in that dialog will the turtle get set to the previous image.
What is wrong in my code that is leading to this occurrence, and how would I stop this from happening? I have tried changing the klob attribute in the function where the output is saved in the undoHandler function to, for example, "SaveImage", but still no luck. I have also tried to add an if-elif statement in the TurtleShape when it is supposed to choose between iop or a file dialog as the value for klob, but still the issue occurs. Apparently, it executes the elif statement even when it is not necessarily true. Therefore, any help is very much appreciated in remedying this issue! :)
It's happening here:
j = i.getfunction()
j()
If the function you've just gotten is the TurtleShape() function, then you're calling it once with its default arguments (i.e., iop = None). Then you go into your big if j.__name__ == "TurtleShape": statement and call it again inside the if block.
Move that j() call into the else: block of your big if j.__name__ == "TurtleShape": statement, and your problem should go away.
Does that brief explanation make enough sense for you to understand why the problem is happening? Or do you need me to explain a bit more in-depth how calling j() is calling TurtleShape with the parameter iop = None?

Categories